# Practo

- Tool: FlutterFlow
- Difficulty: Intermediate
- Time required: 3-4 hours
- Last updated: July 2026

## TL;DR

Connect FlutterFlow to Practo by building an API Group that calls your Firebase Cloud Function proxy, which holds your Practo Ray partner API credentials and forwards requests to api.practo.com. Practo API access is gated behind a provider or business account — not a public self-serve key. Because appointment and patient data is health information, credentials and PHI must always stay server-side and never appear in Dart or FlutterFlow API Call headers.

## Practo Ray in FlutterFlow: Provider Credentials, Proxy Architecture, and PHI

Practo has two sides: the patient-facing app (where users find doctors) and Practo Ray — the clinic management system used by doctors, clinics, and hospitals to manage appointments, patient records, and consultation queues. The API at `api.practo.com` is the Practo Ray API, and access requires a Practo Ray subscription or a formal Practo business account. This is not a developer-tier API you can sign up for with an email address and a credit card — it is tied to an operational healthcare business.

The most common FlutterFlow use case for Practo is building a custom front-desk or patient-scheduling screen on top of a clinic's existing Practo Ray data. For example, a clinic might want a branded mobile app for their patients that shows available appointment slots and lets patients check their queue position — data that all lives in Practo Ray. Your FlutterFlow app does not replace Practo Ray; it surfaces Practo Ray data in a custom UI.

The proxy architecture is non-negotiable here. Your Practo API credential is effectively the access key to a healthcare practice's appointment and patient data. Putting it in a FlutterFlow API Call header ships it inside the compiled Flutter app binary, where it is extractable by anyone who decompiles the APK or IPA. A Firebase Cloud Function proxy holds the credential securely on the server. Additionally, any web-published version of your FlutterFlow app calling `api.practo.com` directly will fail with CORS errors, because Practo's API does not include the required browser headers. The proxy solves both problems at once. India-region latency should be considered in your architecture — Cloud Functions deployed in asia-south1 (Mumbai) will give the lowest latency to Practo's servers.

## Before you start

- Active Practo Ray subscription or Practo business account with API access — contact Practo business support to request API credentials
- Firebase project with Cloud Functions enabled (Blaze plan required for outbound HTTP from Cloud Functions)
- FlutterFlow project on a paid plan with API Calls access
- Node.js knowledge for deploying the Firebase Cloud Function proxy
- Awareness that appointment and patient data is health information requiring appropriate privacy and security measures

## Step-by-step guide

### 1. Obtain Practo Ray partner API credentials

Practo's API is not available at a self-serve sign-up page. Access is tied to a Practo Ray clinic management subscription or a formal Practo business integration agreement. If your clinic or client already uses Practo Ray, the API credentials are available through the Practo Ray admin panel or by contacting Practo's business support team at api-support@practo.com (verify current contact details on practo.com). When you request API access, you will typically receive an API key (and possibly a client ID or secret depending on the authentication method in use for your account tier). You will also need to confirm the current API endpoint base URL — `https://api.practo.com` has been the primary endpoint, but Practo may update endpoint paths, so always verify against the official API documentation provided with your credentials. Store the received credentials immediately in Firebase environment configuration (`firebase functions:config:set practo.api_key=YOUR_KEY`) or in Google Cloud Secret Manager — never write them into code, Dart files, or FlutterFlow App Constants. While awaiting credentials, design your FlutterFlow UI screens (appointment ListView, slot picker, queue display) using hardcoded sample data so you can plug in the real data source once access is granted. Also confirm the rate limits and any usage restrictions in your Practo API agreement, as India-region healthcare APIs sometimes have conservative call quotas.

**Expected result:** You have received a Practo API key (and any other required credentials) and stored them securely in Firebase environment configuration, not in any code file.

### 2. Deploy a Firebase Cloud Function proxy for Practo

Create a Firebase Cloud Function that acts as a secure proxy between your FlutterFlow app and Practo's API. The function receives requests from your FlutterFlow app, adds the Practo API credential in the header, forwards the request to `api.practo.com`, and returns the response. Initialize Firebase Functions in your project with `firebase init functions` (choose JavaScript or TypeScript) if you have not already. In your `index.js` (or `index.ts`) file, create an HTTPS function that: reads the Practo API key from `functions.config().practo.api_key`, accepts the endpoint path and any query parameters from the incoming request body or query string, makes an HTTP request to `https://api.practo.com/{endpoint}` using the `axios` npm package, attaches the credential in the Authorization or API-key header (verify the exact header name from your Practo API documentation), and returns the response body. Add CORS headers to the response so that web-published FlutterFlow apps can call the function from the browser without CORS errors. Install dependencies with `npm install axios cors` in the functions directory before deploying. Set your Practo API key in Firebase environment config: `firebase functions:config:set practo.api_key=YOUR_KEY`. Deploy with `firebase deploy --only functions`. Note the deployed HTTPS URL — this is what you will enter as the Base URL in your FlutterFlow API Group. For lower latency to Practo's India-based servers, deploy the function to the `asia-south1` (Mumbai) region.

```
// index.js — Practo API proxy Cloud Function
const functions = require('firebase-functions');
const axios = require('axios');
const cors = require('cors')({ origin: true });

exports.practoProxy = functions.region('asia-south1').https.onRequest((req, res) => {
  cors(req, res, async () => {
    const apiKey = functions.config().practo.api_key;
    const endpoint = req.query.endpoint || 'appointments';
    const practoUrl = `https://api.practo.com/${endpoint}`;

    try {
      const response = await axios({
        method: req.method,
        url: practoUrl,
        headers: {
          'Authorization': `Bearer ${apiKey}`,
          'Content-Type': 'application/json',
          'Accept': 'application/json',
        },
        params: req.query,
        data: req.body,
      });
      res.status(response.status).json(response.data);
    } catch (error) {
      const status = error.response ? error.response.status : 500;
      const data = error.response ? error.response.data : { error: error.message };
      res.status(status).json(data);
    }
  });
});
```

**Expected result:** The practoProxy Cloud Function is deployed and accessible at its HTTPS URL. Calling the URL manually with a valid endpoint query parameter returns appointment data from Practo's API.

### 3. Create the Practo API Group in FlutterFlow

In FlutterFlow, click API Calls in the left navigation panel and then + Add → Create API Group. Name it 'Practo' and set the Base URL to your deployed Cloud Function HTTPS URL — for example, `https://asia-south1-your-project.cloudfunctions.net/practoProxy`. Do not enter `api.practo.com` here — all calls must go through your proxy. You do not need to configure authentication headers in the API Group because the proxy handles credential injection. Now add individual API Calls within the group. Click + Add Call → Create API Call and name it 'GetAppointments'. Set the method to GET and leave the endpoint path empty (the proxy uses the `endpoint` query parameter). In the Variables tab, add a variable named `endpoint` (String, default value `appointments`), a variable named `date` (String for date filtering), and a variable named `doctorId` (String). These become query parameters sent to your Cloud Function. In the API Call's Response & Test section, paste a sample Practo appointment JSON response and click Generate JSON Paths to create extractors for the appointment fields you need (patient name, appointment time, status, doctor name, etc.). Create a custom Data Type in FlutterFlow for appointments with matching fields. Add additional API Calls for other Practo endpoints you need — for example, GetSchedule and GetQueueStatus with appropriate endpoint values. Test each call using the Test Request button with your real doctorId and today's date.

```
// Sample FlutterFlow API Call configuration
{
  "name": "GetAppointments",
  "method": "GET",
  "base_url": "https://asia-south1-YOUR_PROJECT.cloudfunctions.net/practoProxy",
  "endpoint": "",
  "query_params": {
    "endpoint": "appointments",
    "date": "{{ date }}",
    "doctor_id": "{{ doctorId }}"
  },
  "json_paths": {
    "appointments": "$.appointments",
    "first_patient_name": "$.appointments[0].patient_name",
    "first_appointment_time": "$.appointments[0].appointment_time"
  }
}
```

**Expected result:** The Practo API Group appears in FlutterFlow's API Calls panel with configured appointment and schedule calls. Test requests return real Practo data and generate JSON paths successfully.

### 4. Bind appointment data to a ListView and trigger on page load

With the API Group working, connect it to your UI. Add a ListView widget to your appointments page. Select the ListView and open its Backend Query panel — choose API Call → Practo → GetAppointments and fill in the variables (today's date, the logged-in doctor's ID). FlutterFlow will automatically manage the fetch lifecycle: loading state, error state, and success state. Inside the ListView's item builder, bind each field to the PractoAppointment Data Type properties — patient name to a Text widget, appointment time to another Text, status to a Container color (for example, green for confirmed, amber for waiting, grey for cancelled). Add a pull-to-refresh gesture on the ListView (Container → Actions → On Pull to Refresh → Refresh Backend Query) so front-desk staff can manually sync if the schedule changes. For On Page Load behavior, go to the page's Action Flow Editor, add an API Call action for GetAppointments, and store the result in a List App State variable of type PractoAppointment. This gives you data immediately when the page opens without waiting for a user action. Add an error state message (a Text widget visible only when the API call returns an error) so users know when the connection to Practo has failed, rather than seeing an empty list with no explanation.

**Expected result:** The appointments ListView on the page shows real Practo appointment data, refreshes on page load, and allows pull-to-refresh for manual updates.

### 5. Handle PHI, add authentication, and test in Run mode

Appointment and patient data from Practo is health information about real people. Before publishing your app, implement appropriate security measures. First, add authentication to your FlutterFlow app — only authorized clinic staff (doctors, nurses, front-desk) should be able to see patient appointment data. Use FlutterFlow's Supabase or Firebase auth to require login before accessing any Practo data pages. Second, add authentication to your Cloud Function proxy: check that the incoming request includes a valid Firebase Auth ID token before proxying to Practo. This prevents unauthorized clients from calling your proxy directly. In the function, use `admin.auth().verifyIdToken(req.headers.authorization)` to verify the caller is a logged-in user of your app. Third, do not cache Practo appointment data in App State beyond the current session — patient names, medical appointment details, and queue positions should not persist in device storage between sessions. Fourth, review your app for any UI that might display patient data on lock-screen notifications, screenshots, or previews. In FlutterFlow's Run mode (web preview), test the appointment list display, the refresh behavior, and the error state. Test the published app on a real device with real Practo data before deploying to users, and confirm that unauthenticated users cannot access the appointment screen.

**Expected result:** The app requires authentication before showing patient appointment data. Unauthenticated API calls to the proxy return 401. Patient data is displayed correctly in the UI with no PHI visible to unauthorized users.

## Best practices

- Never place Practo API credentials in FlutterFlow API Call headers, App Constants, or Dart code — they must stay in the Firebase Cloud Function environment config or Secret Manager
- Deploy your Cloud Function proxy in asia-south1 (Mumbai) to minimize round-trip latency to Practo's India-based API servers
- Gate all Practo data pages behind FlutterFlow authentication — appointment and patient data is health information that should only be visible to authorized clinic staff
- Authenticate Cloud Function calls by verifying the caller's Firebase Auth ID token in the proxy, preventing unauthorized direct calls to your proxy endpoint
- Do not cache patient names or appointment details in persistent App State or device storage between user sessions — treat PHI as session-scoped data only
- Add a friendly error state to every Practo data screen so users see a clear message if the API is unreachable or returns an error, rather than an unexplained empty list
- Verify Practo's current API endpoint paths and response schemas with each provider account update — Practo Ray's API has evolved over time and older documentation may reference deprecated endpoints

## Use cases

### Branded patient appointment booking app

Build a clinic's branded iOS/Android app that shows available appointment slots from Practo Ray, lets patients select a time, and confirms the booking. The FlutterFlow UI displays doctor profiles and real-time availability pulled from the Practo API via the Cloud Function proxy, giving patients a native app experience while data stays in Practo Ray.

Prompt example:

```
A booking screen showing a doctor's available appointment slots for the next 7 days, fetched from Practo Ray, with a Confirm Appointment button that submits the selected slot
```

### Clinic front-desk queue display

Create a front-desk tablet app that shows today's consultation queue from Practo Ray in real time — patient name, appointment time, and wait status. Refresh on a timer or pull-to-refresh, and highlight overdue appointments. This gives front-desk staff a fast native view without switching between browser tabs.

Prompt example:

```
A queue management screen showing today's scheduled patients in a ListView, sorted by appointment time, with status indicators (waiting, in consultation, done) and a pull-to-refresh
```

### Doctor schedule summary app

Build a doctor-facing summary screen that shows the day's schedule from Practo Ray — total patients, next appointment, and time gaps. Sends a push notification (via Firebase Cloud Messaging) when a patient checks in. The app replaces the need for the doctor to log into the Practo Ray web interface for a quick schedule overview.

Prompt example:

```
A daily schedule page for a doctor showing appointment count, next patient name and time, and gaps in the schedule, synced from Practo Ray
```

## Troubleshooting

### XMLHttpRequest error or CORS error when testing the Practo API Call in FlutterFlow's web preview

Cause: Direct calls from a browser to api.practo.com are blocked by CORS — Practo's API does not include the Access-Control-Allow-Origin header that browsers require. This occurs when the FlutterFlow API Group Base URL is set to api.practo.com instead of the Cloud Function proxy.

Solution: Set the API Group Base URL to your Cloud Function proxy URL, not to api.practo.com. Ensure the Cloud Function adds CORS headers using the `cors` npm package. In the proxy function, call `cors(req, res, async () => { ... })` to wrap the response with correct CORS headers. Mobile builds (iOS/Android) do not enforce CORS, but the proxy is still required to protect the API credential.

### 401 Unauthorized from the Practo proxy — authentication failed

Cause: The Practo API key is incorrectly configured in Firebase environment config, or the Authorization header format does not match what Practo expects for your account type (Bearer token vs API key header vs Basic auth).

Solution: Verify the API key is correctly set with `firebase functions:config:get` and matches the credential Practo provided. Confirm the exact authorization header format from Practo's API documentation — it may be `Authorization: Bearer {key}`, `X-API-Key: {key}`, or another format depending on your account type. Redeploy the function after updating the config.

### Appointment data returns for wrong date or incorrect doctor

Cause: The date or doctorId query parameters passed from FlutterFlow are in the wrong format, or the Practo API endpoint expects date in a specific format (e.g., YYYY-MM-DD) that differs from what FlutterFlow's DateTime variable provides.

Solution: Log the exact query string being sent by the Cloud Function to verify the parameter values and format. Add a date formatting step in the proxy function to convert ISO date strings to the format Practo expects. In FlutterFlow, use a Custom Function to format the DateTime value as a string in the required format before passing it to the API Call variable.

### High latency (2-4 seconds) for appointment data to load

Cause: The Cloud Function is deployed in a US region (us-central1) but Practo's API servers are in India, adding 150-200ms round-trip latency plus Cloud Function cold-start time.

Solution: Redeploy the Cloud Function to the asia-south1 (Mumbai) region using `functions.region('asia-south1').https.onRequest(...)`. This brings the proxy geographically close to Practo's servers and reduces latency significantly. Also implement a loading skeleton in FlutterFlow so the UI does not appear blank during the fetch.

## Frequently asked questions

### Can I access Practo's API without a Practo Ray provider account?

No. Practo's API is tied to a Practo Ray clinic management subscription or a formal business integration agreement. It is not a public developer API with a self-serve key — you must be an active Practo Ray user or have a business relationship with Practo. Contact Practo's business support team to request API access for your specific integration use case.

### Is Practo appointment data considered HIPAA-covered PHI?

Practo operates primarily in India, where health data is governed by India's Digital Personal Data Protection Act (DPDP Act) rather than US HIPAA. However, appointment data (patient name, medical appointment details, consultation notes) is sensitive personal health information regardless of jurisdiction. Always handle it with appropriate security: proxy credentials server-side, implement authentication gates, avoid caching PHI, and review Practo's data handling terms in your API agreement.

### Can I write back to Practo (create appointments) from FlutterFlow?

If your Practo API agreement includes write access, yes — you can add POST API Calls to your FlutterFlow API Group that submit new appointment requests through the same Cloud Function proxy. POST calls from FlutterFlow to the proxy work the same way as GET calls. Ensure write operations go through the proxy (never from client Dart directly) and implement idempotency handling in the proxy to prevent duplicate appointment creation on network retries.

### Will this integration work for a web-published FlutterFlow app?

Yes. The Cloud Function proxy resolves the CORS issue that would block direct browser calls to api.practo.com, so the same FlutterFlow app works across iOS, Android, and web. The web version is useful for a browser-based front-desk dashboard, while the mobile versions serve doctors and patients. Authentication via Firebase Auth works identically across all three platforms.

---

Source: https://www.rapidevelopers.com/flutterflow-integrations/practo
© RapidDev — https://www.rapidevelopers.com/flutterflow-integrations/practo
