Connect FlutterFlow to Zocdoc using a FlutterFlow API Group pointed at a Cloud Function proxy that holds your Zocdoc partner credentials and forwards requests to the Zocdoc API at api.zocdoc.com/v1. Access is partner-gated — you must apply and be approved before any API call is possible. Because appointment and patient data is protected health information, all credentials and PHI must stay server-side; the Cloud Function proxy is not optional.
| Fact | Value |
|---|---|
| Tool | Zocdoc |
| Category | Health & Fitness |
| Method | FlutterFlow API Call |
| Difficulty | Advanced |
| Time required | 60 minutes |
| Last updated | July 2026 |
Building a Booking App with FlutterFlow and Zocdoc
Zocdoc is the dominant US platform for finding and booking doctor appointments online. If you're building a practice management app, a patient-facing scheduling tool, or a healthcare concierge service in the United States, Zocdoc's partner API gives you access to provider availability, appointment slots, patient bookings, and reviews — the same data that powers Zocdoc's own consumer product.
The critical thing to understand upfront is that Zocdoc's API is not self-serve. There is no public developer portal where you register and receive an instant key. You must apply to the Zocdoc partner program, go through a vetting process (typically reviewed by a Zocdoc partnership team), and sign an agreement before credentials are issued. This is standard practice for healthcare data APIs in the US because appointment and patient records constitute PHI under HIPAA. Budget time for the approval process before your launch timeline.
Once approved, the integration architecture for FlutterFlow has two layers. The first is a Cloud Function proxy that holds your Zocdoc partner credentials server-side and forwards GET/POST requests to api.zocdoc.com/v1. The second is a FlutterFlow API Group that calls your proxy — never Zocdoc directly. Two-way operations (reading availability AND writing new appointments) both go through the proxy. Appointment change webhooks from Zocdoc land on a separate Cloud Function endpoint that writes updates to Firestore, which your Flutter app listens to in real time. This architecture keeps all PHI and credentials on your server infrastructure and off the client device.
Integration method
Zocdoc exposes a provider partner API at https://api.zocdoc.com/v1 for reading appointment availability, syncing schedules, and managing bookings. Because access is restricted to approved US healthcare partners and the data involves PHI (protected health information), all API credentials are secrets that must live in a Firebase Cloud Function or Supabase Edge Function proxy — never in FlutterFlow Dart code or API Call headers. FlutterFlow's API Group points at the proxy URL, and the proxy injects Zocdoc credentials and forwards the request. Appointment change webhooks also land on the Cloud Function, which writes updates to Firestore for the Flutter app to read via a real-time listener.
Prerequisites
- Approved Zocdoc partner API credentials — apply through Zocdoc's provider/partner program before building
- A Firebase project with Cloud Functions enabled (Blaze plan required for outbound network calls from functions)
- A FlutterFlow project on a paid plan with Firebase configured as the backend
- Basic familiarity with deploying Firebase Cloud Functions in Node.js
- An understanding of HIPAA data handling obligations if you're processing PHI in your app
Step-by-step guide
Apply for Zocdoc partner API access
Before writing any FlutterFlow code, you need approved Zocdoc partner credentials. Visit zocdoc.com and navigate to their provider or partner resources — the specific URL for partner API applications may change, so search for 'Zocdoc API integration partner program' and use the official contact form or provider portal. When applying, be specific about your use case: whether you're a healthcare provider practice syncing your schedule, a software vendor building practice management tools, or a concierge healthcare service. Zocdoc evaluates partners based on their US healthcare context and data handling practices. The more clearly you describe how you'll handle PHI and what HIPAA safeguards you have in place, the smoother the approval process. Once approved, you'll receive partner API credentials — these may take the form of an OAuth client ID and secret (for a client credentials flow), an API key, or a combination. The exact credential format is provided by Zocdoc and may vary by partner tier. You will NOT be issuing these credentials yourself — they come from Zocdoc's partnership team. During the wait for approval, you can begin building the FlutterFlow UI screens and the Cloud Function scaffold — just use mock data for testing. When credentials arrive, you'll configure them as environment variables in the Cloud Function and replace mock responses with real API calls.
Pro tip: If you're a healthcare software vendor (not a direct provider), mention in your application that you're building a FlutterFlow-based mobile app for practices and that your architecture routes all API calls through a server-side proxy — Zocdoc partners appreciate PHI-conscious architecture.
Expected result: You have submitted a Zocdoc partner API application and understand what credentials you will receive. Your FlutterFlow project is open and you have a Firebase project ready with the Blaze plan enabled.
Deploy a Cloud Function proxy for Zocdoc
Your Zocdoc partner credentials are secrets. Putting them in a FlutterFlow API Call header compiles them into your app binary and exposes them to anyone who downloads and decompiles the APK. Beyond security, appointment and patient data is PHI — keeping credentials server-side is a basic HIPAA hygiene requirement for any US healthcare application. Deploy a Firebase Cloud Function that holds your credentials and proxies requests to api.zocdoc.com/v1. The function receives requests from your FlutterFlow app, adds authentication headers, and forwards to Zocdoc. It also sets CORS headers so the integration works when your FlutterFlow app is published to web. Here's a scaffold for the proxy function: ```javascript const functions = require('firebase-functions'); const axios = require('axios'); exports.zocdocProxy = functions.https.onRequest(async (req, res) => { res.set('Access-Control-Allow-Origin', '*'); if (req.method === 'OPTIONS') { res.set('Access-Control-Allow-Methods', 'GET,POST'); res.set('Access-Control-Allow-Headers', 'Content-Type,Authorization'); return res.status(204).send(''); } const path = req.query.path || '/'; const zocdocBase = 'https://api.zocdoc.com/v1'; try { const response = await axios({ method: req.method, url: `${zocdocBase}${path}`, headers: { 'Authorization': `Bearer ${process.env.ZOCDOC_API_TOKEN}`, 'Content-Type': 'application/json' }, data: req.body }); return res.json(response.data); } catch (err) { return res.status(err.response?.status || 500).json({ error: err.message, details: err.response?.data }); } }); ``` Set `ZOCDOC_API_TOKEN` (or whatever credential format Zocdoc provides) as a Cloud Function environment variable in the Firebase console. If Zocdoc issues an OAuth client credentials flow, add a token-minting step before the proxied request. Deploy the function and note its HTTPS URL.
1const functions = require('firebase-functions');2const axios = require('axios');34exports.zocdocProxy = functions.https.onRequest(async (req, res) => {5 res.set('Access-Control-Allow-Origin', '*');6 if (req.method === 'OPTIONS') {7 res.set('Access-Control-Allow-Methods', 'GET,POST');8 res.set('Access-Control-Allow-Headers', 'Content-Type,Authorization');9 return res.status(204).send('');10 }11 const path = req.query.path || '/';12 const zocdocBase = 'https://api.zocdoc.com/v1';13 try {14 const response = await axios({15 method: req.method,16 url: `${zocdocBase}${path}`,17 headers: {18 'Authorization': `Bearer ${process.env.ZOCDOC_API_TOKEN}`,19 'Content-Type': 'application/json'20 },21 data: req.body22 });23 return res.json(response.data);24 } catch (err) {25 return res.status(err.response?.status || 500).json({26 error: err.message,27 details: err.response?.data28 });29 }30});Pro tip: Use Firebase Secret Manager (instead of environment variables) to store Zocdoc credentials for production — Secret Manager encrypts secrets at rest and provides versioning, which is better for HIPAA-adjacent infrastructure.
Expected result: Your Cloud Function is deployed and responds to GET and POST requests. Test by calling it with a path query parameter pointing to a Zocdoc API endpoint like /availability. The function returns Zocdoc data without exposing credentials in the response.
Build the Zocdoc API Group in FlutterFlow
Open your FlutterFlow project, click API Calls in the left navigation panel, click + Add → Create API Group. Name it 'Zocdoc'. In the Base URL field, paste your Cloud Function URL — e.g. `https://us-central1-YOUR_PROJECT.cloudfunctions.net`. This is the only URL that appears in FlutterFlow; Zocdoc's actual domain never appears in the client. Now add individual API Calls to the group: **getAvailability** — GET, endpoint `/zocdocProxy?path=/providers/{providerId}/availability`. Add `providerId` and `date` as Variables (Strings). Add a `date` variable and use it as a query parameter. **getAppointments** — GET, endpoint `/zocdocProxy?path=/appointments` with a `date` query param for today's date. **createAppointment** — POST, endpoint `/zocdocProxy?path=/appointments`. Body: JSON with `providerId`, `patientId`, `slotId`, `reasonForVisit` as Variables. For each API Call, go to Response & Test, paste a sample Zocdoc response JSON (use mock data while waiting for credentials), and click Generate JSON Paths. For availability, key paths include `$.slots[*].startTime`, `$.slots[*].slotId`, `$.slots[*].isAvailable`. For appointments: `$.appointments[*].id`, `$.appointments[*].patientName`, `$.appointments[*].startTime`, `$.appointments[*].status`.
1{2 "api_group": "Zocdoc",3 "base_url": "https://us-central1-YOUR_PROJECT.cloudfunctions.net",4 "calls": [5 {6 "name": "getAvailability",7 "method": "GET",8 "endpoint": "/zocdocProxy",9 "query_params": {10 "path": "/providers/{{ providerId }}/availability",11 "date": "{{ date }}"12 },13 "json_paths": {14 "slotIds": "$.slots[*].slotId",15 "startTimes": "$.slots[*].startTime",16 "available": "$.slots[*].isAvailable"17 }18 },19 {20 "name": "createAppointment",21 "method": "POST",22 "endpoint": "/zocdocProxy",23 "query_params": {24 "path": "/appointments"25 },26 "body": {27 "providerId": "{{ providerId }}",28 "slotId": "{{ slotId }}",29 "patientId": "{{ patientId }}",30 "reasonForVisit": "{{ reasonForVisit }}"31 }32 }33 ]34}Pro tip: Use FlutterFlow's test panel with mock JSON responses during development so you can build and style the UI before your Zocdoc partner credentials arrive. Paste realistic sample data to generate accurate JSON paths.
Expected result: Your FlutterFlow API Group shows the Zocdoc calls, variables are configured, and JSON paths are generated from sample data. No Zocdoc credentials appear anywhere in FlutterFlow.
Build the availability and booking UI
With the API Group in place, build the patient-facing or staff-facing booking screens. For a scheduling UI, add a new page called 'Book Appointment'. Add a DatePicker widget at the top so the user can select a date, and a variable `selectedDate` to store it. On the same page, add a ListView widget. Set its data source to a Backend/API Call using the `getAvailability` call, passing the provider's ID (from App State or the page's route parameter) and `selectedDate` as variables. Bind each list tile to display the slot's `startTime` and an 'Available' / 'Booked' badge based on `isAvailable`. For each available slot tile, add a 'Book' button. On the button's action: first show a BottomSheet widget with a form asking for reason for visit (a TextField). Then trigger the `createAppointment` API Call, passing `providerId`, `slotId`, `currentUser.uid` as `patientId`, and the text field value as `reasonForVisit`. After success, show a SnackBar confirmation and re-trigger the availability call to refresh the list. For the appointment list screen (staff view), trigger `getAppointments` on page load using an On Page Load action. Bind a ListView to the results, showing patient name, time, and status. Add a pull-to-refresh by connecting a RefreshIndicator widget to re-trigger the API Call. Important: writes (creating appointments) need idempotency handling. If the same booking is submitted twice (e.g. double-tap or network retry), you should not create duplicate appointments. Send a unique idempotency key in the `createAppointment` call body — generate it from a UUID custom function in FlutterFlow.
Pro tip: Show a loading spinner while the availability API Call is in progress — the Zocdoc partner API may have higher latency than a typical public API, and users need visual feedback that something is happening.
Expected result: The booking screen shows available time slots for the selected date. Tapping Book opens a form, submitting the form creates the appointment via the proxy, and a confirmation message appears. The staff schedule screen refreshes on pull-to-refresh.
Add a webhook receiver for appointment changes
Zocdoc pushes appointment change events (cancellations, reschedules, new bookings from the Zocdoc consumer app) to a webhook URL you register in the partner portal. FlutterFlow has no server endpoint, so the webhook receiver must be a separate Cloud Function that Zocdoc calls directly. Deploy a second Cloud Function named `zocdocWebhook` that receives POST requests from Zocdoc, validates the payload (check any signature header Zocdoc provides to confirm authenticity), and writes the appointment update to a Firestore collection. Your FlutterFlow app then listens to that Firestore collection using a real-time StreamBuilder/Firestore backend query — when the Cloud Function writes, the app updates instantly. Here is the webhook receiver scaffold: ```javascript exports.zocdocWebhook = functions.https.onRequest(async (req, res) => { if (req.method !== 'POST') return res.status(405).send('Method Not Allowed'); const event = req.body; // Validate Zocdoc signature if provided (check partner docs for header name) const db = admin.firestore(); await db.collection('appointmentUpdates').add({ appointmentId: event.appointmentId, status: event.status, providerId: event.providerId, updatedAt: admin.firestore.FieldValue.serverTimestamp(), raw: event }); return res.status(200).json({ received: true }); }); ``` Register this function's HTTPS URL in your Zocdoc partner portal as the webhook destination. In FlutterFlow, add an On Page Load action that queries the `appointmentUpdates` collection ordered by `updatedAt` descending to surface the latest changes to staff. You can also use Firestore's real-time snapshot listener (FlutterFlow supports this natively via the Firestore backend query with streaming enabled).
1const admin = require('firebase-admin');2const functions = require('firebase-functions');34exports.zocdocWebhook = functions.https.onRequest(async (req, res) => {5 if (req.method !== 'POST') return res.status(405).send('Method Not Allowed');6 const event = req.body;7 // Validate Zocdoc signature if provided (check partner docs for header name)8 const db = admin.firestore();9 await db.collection('appointmentUpdates').add({10 appointmentId: event.appointmentId,11 status: event.status,12 providerId: event.providerId,13 patientId: event.patientId || null,14 updatedAt: admin.firestore.FieldValue.serverTimestamp(),15 raw: event16 });17 return res.status(200).json({ received: true });18});Pro tip: Return 200 immediately from the webhook function and do any slow processing asynchronously — Zocdoc (and most webhook senders) will retry if they don't receive a 200 quickly, leading to duplicate writes if your function is slow.
Expected result: The webhook receiver is deployed and its URL is registered in the Zocdoc partner portal. When an appointment changes in Zocdoc, a new document appears in Firestore and the FlutterFlow staff screen updates in real time.
Common use cases
Practice scheduling screen for front-desk staff
A FlutterFlow app used by medical office staff to view today's appointment schedule, check provider availability for specific time slots, and confirm bookings — all synced with Zocdoc in real time via Firestore. Push notifications alert staff when a new booking arrives or an appointment is cancelled through Zocdoc.
Build a FlutterFlow screen that shows a list of today's appointments for a provider, grouped by time slot, with the patient name, appointment type, and status — pulling data from a Firestore collection that a Cloud Function syncs with Zocdoc.
Copy this prompt to try it in FlutterFlow
Patient-facing appointment booking flow
A white-label patient app that shows a provider's available slots by day, lets patients select and confirm a booking, and sends the write request through the Cloud Function proxy to Zocdoc's create-appointment endpoint. A confirmation screen shows the booked time and a calendar add button.
Build a FlutterFlow booking UI that shows available appointment slots from Zocdoc (via a proxy API call), lets the user select a slot, fill in their reason for visit, and confirm — then shows a booking confirmation card with the doctor's name and time.
Copy this prompt to try it in FlutterFlow
Provider review and rating viewer
A healthcare concierge app that pulls a provider's Zocdoc patient reviews and star ratings via the partner API, displays them in a scrollable card list, and lets users filter by rating or appointment type. Useful for helping patients choose between providers in a curated network.
Build a FlutterFlow provider detail screen that shows the doctor's photo, specialty, average Zocdoc rating, and a scrollable list of recent patient reviews fetched from a Cloud Function proxy call.
Copy this prompt to try it in FlutterFlow
Troubleshooting
API call returns 401 Unauthorized from the Cloud Function
Cause: The Zocdoc partner credentials stored in the Cloud Function's environment variables are missing, expired, or incorrectly formatted. If Zocdoc uses an OAuth client credentials flow, the access token may have expired and needs to be refreshed.
Solution: Verify that ZOCDOC_API_TOKEN (or your credential variable) is correctly set in the Cloud Function's environment configuration. If Zocdoc uses OAuth, add token refresh logic to the proxy: before each request, check if the current token is expired and re-mint it using the client credentials grant. Log the Zocdoc response body in the Cloud Function for debugging — the error detail from Zocdoc usually specifies what's wrong with the auth header.
XMLHttpRequest error in FlutterFlow Test Mode or web publish
Cause: FlutterFlow's Test Mode uses a FlutterFlow proxy that can mask CORS issues. Once published to web, browser CORS rules apply. If your Cloud Function is not returning Access-Control-Allow-Origin headers, web calls fail with a network CORS error.
Solution: Ensure your Cloud Function sets `res.set('Access-Control-Allow-Origin', '*')` and handles OPTIONS preflight requests with a 204 response. For production, replace the wildcard with your specific app domain. Confirm the error in the browser console (F12 → Network tab) — CORS errors show as blocked requests with no response body.
Appointment write creates duplicate bookings on retry
Cause: Network retries or double-taps on the Book button submit the createAppointment call more than once. Without idempotency handling, Zocdoc may create two appointments for the same slot.
Solution: Generate a unique idempotency key per booking attempt (a UUID in a FlutterFlow Custom Function) and include it in the request body or as a header. On the Cloud Function side, check a Firestore collection of submitted idempotency keys before forwarding to Zocdoc — if the key already exists, return the previous response instead of resending. Also disable the Book button immediately after the first tap using a Boolean App State variable.
Zocdoc webhooks are not arriving or arrive with a delay
Cause: The webhook URL registered in the Zocdoc partner portal may be incorrect (a development URL instead of the deployed Cloud Function URL), or the webhook receiver is returning a non-200 response that causes Zocdoc to retry with backoff.
Solution: Confirm the deployed Cloud Function URL in the Firebase console and update the webhook registration in the Zocdoc partner portal. Add a Firebase Functions log statement at the top of the webhook handler so you can see in the Cloud Functions logs whether Zocdoc is calling the endpoint at all. Ensure the function returns 200 immediately before doing Firestore writes — move slow operations to a async sub-function if needed.
Best practices
- Apply for Zocdoc partner API access before writing any code — the approval process takes time and affects your build timeline
- Store Zocdoc credentials exclusively in Firebase Secret Manager or Cloud Function environment variables — never in FlutterFlow API Call headers or Dart code
- Return 200 immediately from webhook handlers and process data asynchronously to avoid Zocdoc retry storms
- Add idempotency keys to appointment creation requests to prevent double-booking on network retries or double-taps
- Use Firestore real-time listeners to surface webhook-delivered appointment changes instantly without polling the Zocdoc API
- Set CORS headers in your Cloud Function proxy so the integration works on web builds as well as iOS and Android
- Gate the proxy endpoint behind Firebase Auth — require a valid Firebase ID token in the request header so only authenticated users of your app can call Zocdoc through your proxy
- Log all PHI access (patient IDs, appointment data) in a structured audit log in Firestore as a basic HIPAA hygiene measure
Alternatives
Practo serves the India healthcare market with a similar partner-gated booking API — the better choice if your practice management app targets Indian providers rather than US-based Zocdoc partners.
If your health app focuses on wellness and activity tracking rather than clinical appointment booking, Fitbit's self-serve OAuth 2.0 API is much easier to access without a partner approval process.
For iOS apps that need to read a patient's health records stored on-device (appointments, medications, lab results via Apple Health), HealthKit provides a Custom Action path without needing a partner API at all.
Frequently asked questions
Is Zocdoc's API available to any developer, or do I need to be a healthcare provider?
Zocdoc's API is a partner program, not a public developer API. You must apply and be approved before receiving credentials. Both US healthcare providers (medical practices, clinics) and healthcare software vendors building tools for providers can apply. Consumer apps or non-healthcare use cases are generally not approved. Budget several weeks for the vetting and approval process.
Does handling Zocdoc appointment data make my app subject to HIPAA?
If your app processes appointment data and patient identifiers for US healthcare providers, you are very likely operating as a Business Associate under HIPAA and need a Business Associate Agreement (BAA) with Zocdoc and with any cloud services you use (Firebase/GCP offers BAAs on its healthcare tier). Consult a healthcare compliance attorney before launching. The proxy architecture described here is a good start — credentials and PHI server-side — but HIPAA compliance involves more than just API key security.
Can I test the Zocdoc integration before receiving partner credentials?
Yes. Build your Cloud Function proxy and FlutterFlow API Group using mock JSON responses that match the expected Zocdoc API structure. Use FlutterFlow's test panel with static JSON data to build and style all screens. When credentials arrive, replace the mock responses with real Cloud Function calls — the UI and data binding require no changes if you designed to the correct JSON structure.
Why can't I just put the Zocdoc API token in a FlutterFlow App Constant?
FlutterFlow App Constants are compiled into the app binary. Anyone who downloads your app and uses a tool like jadx (for Android APKs) or a Flutter decompiler can extract all App Constant values in minutes. For a Zocdoc partner token that grants access to patient appointment data, a leak would be a serious HIPAA breach in addition to unauthorized API access. The Cloud Function proxy keeps the token on Google's infrastructure, where it is never transmitted to the client device.
What happens to real-time appointment changes if a user's phone is offline?
Firestore has offline persistence enabled by default in FlutterFlow's Firebase integration. Appointment data cached before the device went offline remains accessible. When the device reconnects, Firestore automatically syncs any changes that arrived via webhook during the offline period. For critical clinical workflows, add a visible 'Last synced at' timestamp so staff know when the displayed data was last confirmed fresh.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation