Zocdoc's API is partner-only and not publicly available, but you can integrate Replit with Zocdoc's webhook-based event system if you have a partnership agreement. For most developers, the best approach is building a middleware server on Replit that connects Zocdoc appointment data (via their limited partner API or calendar sync) with your existing systems for notifications, CRM updates, or analytics.
Build Healthcare Booking Integrations with Zocdoc and Replit
Zocdoc is one of the largest healthcare appointment platforms in the United States, connecting millions of patients with verified providers. For healthcare practices and health tech companies, connecting Zocdoc appointment data to practice management systems, patient communication tools, EHR platforms, and analytics dashboards is a critical operational need.
Zocdoc does not publish a public developer API β access requires a formal partner agreement, typically for practice management software vendors, EHR providers, or healthcare technology companies. However, Zocdoc supports webhook-based event delivery, where your server receives real-time notifications when appointments are booked, modified, checked in, or cancelled. This webhook approach is the primary integration mechanism for most Zocdoc partners.
Replit is well-suited for building the middleware server that receives and processes these events. A Replit Autoscale deployment provides a permanent HTTPS endpoint for webhook delivery, and your server code handles appointment data transformation, HIPAA-conscious logging, and downstream integrations with tools like Twilio for appointment reminders, Salesforce for CRM updates, or your own analytics pipeline. This tutorial walks through building a complete Zocdoc webhook receiver and covers realistic integration patterns for healthcare settings.
Integration method
Zocdoc's API is a restricted partner API rather than a public developer API. Integration happens primarily through webhook events delivered to your Replit server endpoint when appointments are booked, cancelled, or updated. Your Replit server receives these webhook payloads, processes the appointment data, and triggers downstream actions like CRM updates, confirmation SMS messages, or analytics logging.
Prerequisites
- A Zocdoc partner account or an active partnership agreement that includes webhook or API access (contact Zocdoc partnerships at zocdoc.com/partners for access)
- A Replit account β Replit Core strongly recommended for healthcare integrations requiring reliability and uptime
- Your Zocdoc webhook secret (provided by Zocdoc when you set up a webhook endpoint in their partner portal)
- Basic Python (Flask) or Node.js (Express) knowledge for building the webhook receiver
- Familiarity with HIPAA considerations for handling patient appointment data in your application
Step-by-step guide
Understand Zocdoc's Integration Model
Understand Zocdoc's Integration Model
Before writing any code, it is important to understand how Zocdoc's API access works β it differs significantly from platforms like Stripe or Twilio that offer open developer APIs. Zocdoc's API is a restricted partner API. There is no public registration flow where you create an account and get an API key. To obtain API or webhook access, you need to apply through Zocdoc's partner program at zocdoc.com/partners or contact their partnerships team directly. This process involves signing a partnership agreement, HIPAA Business Associate Agreement (BAA), and technical integration review. Once you are a Zocdoc partner, you receive access to their partner portal where you can configure webhook endpoints. Zocdoc supports pushing appointment lifecycle events (appointment created, appointment updated, appointment cancelled, check-in completed) to an HTTPS endpoint you specify. You receive a webhook secret key for signature verification. For developers who need to explore Zocdoc integration possibilities before committing to the partnership process, Zocdoc also supports EHR integration via standards like HL7 FHIR for practices using supported EHR systems. Some practice management software vendors also offer Zocdoc integration that does not require direct API access. This tutorial assumes you have gone through the Zocdoc partnership process and have webhook access configured. If you are still in the evaluation phase, the code patterns here will prepare you for when access is granted.
Pro tip: Contact Zocdoc partnerships (zocdoc.com/partners) to discuss API access options. For healthcare practices specifically, ask about the Zocdoc for Healthcare Partners program which provides more direct integration options.
Expected result: You have clarity on Zocdoc's access model and either have webhook credentials or a plan to obtain them through the partnership process.
Store Webhook Credentials in Replit Secrets
Store Webhook Credentials in Replit Secrets
Once you have Zocdoc partner access, you receive a webhook signing secret. Store this in Replit Secrets along with any other credentials needed for your downstream integrations. Open your Replit project and click the lock icon (π) in the left sidebar to open the Secrets panel. Create a secret named ZOCDOC_WEBHOOK_SECRET with your Zocdoc webhook signing secret. If your integration also sends data to other services (CRM, SMS), add their credentials as separate secrets too: TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, SENDGRID_API_KEY, etc. In Python, access the secret with os.environ['ZOCDOC_WEBHOOK_SECRET']. In Node.js, use process.env.ZOCDOC_WEBHOOK_SECRET. Restart the Repl after adding secrets. For HIPAA-compliant implementations, be mindful of what patient data you log. Webhook payloads may contain PHI (Protected Health Information) including patient names, dates of birth, appointment details, and insurance information. Configure your Replit server to log only non-PHI fields (appointment IDs, timestamps, event types) and store PHI only in HIPAA-compliant storage systems.
1import os23# Verify all required secrets are present4required_secrets = ['ZOCDOC_WEBHOOK_SECRET']5optional_secrets = ['TWILIO_ACCOUNT_SID', 'TWILIO_AUTH_TOKEN', 'SENDGRID_API_KEY']67print('Checking required secrets:')8all_ok = True9for secret in required_secrets:10 val = os.environ.get(secret)11 if val:12 print(f' OK: {secret} ({len(val)} chars)')13 else:14 print(f' MISSING: {secret}')15 all_ok = False1617print('\nChecking optional secrets:')18for secret in optional_secrets:19 val = os.environ.get(secret)20 status = f'present ({len(val)} chars)' if val else 'not set'21 print(f' {secret}: {status}')2223if all_ok:24 print('\nAll required secrets loaded.')25else:26 print('\nMissing required secrets β add them to Replit Secrets (lock icon).')Pro tip: For HIPAA compliance, never log patient PHI (names, dates of birth, medical details) to Replit's console output or standard logs. Log only non-PHI identifiers like appointment IDs and event types.
Expected result: The check script prints 'All required secrets loaded' confirming ZOCDOC_WEBHOOK_SECRET is accessible in the Replit environment.
Build the Webhook Receiver
Build the Webhook Receiver
With credentials configured, build the webhook receiver server. The server listens for POST requests from Zocdoc, verifies the webhook signature to confirm the request is genuine, parses the appointment event data, and dispatches it to the appropriate handler based on the event type. Zocdoc webhook payloads typically include: event type (appointment.created, appointment.updated, appointment.cancelled), appointment ID, appointment datetime, provider information, and patient demographics. The exact payload structure depends on your Zocdoc integration agreement β review the documentation provided during partnership onboarding. The signature verification uses HMAC-SHA256, which is the industry standard for webhook security. Zocdoc signs each request with your webhook secret so your server can verify the request genuinely came from Zocdoc and has not been tampered with. Always verify signatures before processing appointment data. For HIPAA considerations: your Replit deployment should be treated as infrastructure that processes PHI. Ensure your Replit account and project are appropriately secured, access is limited to authorized personnel, and any patient data written to logs or storage is handled according to your BAA with Zocdoc and your organization's HIPAA policies.
1// Node.js Express webhook receiver for Zocdoc2const express = require('express');3const crypto = require('crypto');4const app = express();56const WEBHOOK_SECRET = process.env.ZOCDOC_WEBHOOK_SECRET;78// Raw body for signature verification9app.use('/webhook', express.raw({ type: 'application/json' }));10app.use(express.json());1112function verifyZocdocSignature(rawBody, signatureHeader) {13 if (!WEBHOOK_SECRET) return true; // skip if no secret configured14 const expected = crypto15 .createHmac('sha256', WEBHOOK_SECRET)16 .update(rawBody)17 .digest('hex');18 const received = signatureHeader?.replace('sha256=', '') || '';19 try {20 return crypto.timingSafeEqual(21 Buffer.from(expected, 'hex'),22 Buffer.from(received, 'hex')23 );24 } catch {25 return false;26 }27}2829app.post('/webhook', async (req, res) => {30 // Respond quickly to prevent Zocdoc retry31 const signature = req.headers['x-zocdoc-signature'] || req.headers['x-webhook-signature'];32 const rawBody = req.body;3334 if (!verifyZocdocSignature(rawBody, signature)) {35 console.log('Rejected webhook: invalid signature');36 return res.status(401).json({ error: 'Invalid signature' });37 }3839 const event = JSON.parse(rawBody.toString());4041 // Acknowledge receipt immediately42 res.json({ received: true });4344 // Process event asynchronously (non-blocking)45 processAppointmentEvent(event).catch(err =>46 console.error('Event processing error:', err.message)47 );48});4950async function processAppointmentEvent(event) {51 const eventType = event.event_type || event.type;52 const appointmentId = event.appointment?.id || event.appointment_id;5354 // Log non-PHI identifiers only55 console.log(`Zocdoc event: ${eventType} | Appointment ID: ${appointmentId}`);5657 switch (eventType) {58 case 'appointment.created':59 await handleNewAppointment(event);60 break;61 case 'appointment.cancelled':62 await handleCancellation(event);63 break;64 case 'appointment.updated':65 await handleUpdate(event);66 break;67 default:68 console.log(`Unhandled event type: ${eventType}`);69 }70}7172async function handleNewAppointment(event) {73 // Extract appointment details74 const appointment = event.appointment || event.data || {};75 const appointmentDatetime = appointment.datetime || appointment.start_time;76 const providerId = appointment.provider_id;77 // Add: send confirmation email, update CRM, schedule reminder SMS78 console.log(`New appointment scheduled: ${appointmentDatetime} with provider ${providerId}`);79}8081async function handleCancellation(event) {82 const appointmentId = event.appointment?.id || event.appointment_id;83 // Add: cancel reminder, update CRM, notify provider84 console.log(`Appointment ${appointmentId} cancelled`);85}8687async function handleUpdate(event) {88 console.log('Appointment updated');89}9091app.get('/health', (req, res) => res.json({ status: 'ok', service: 'zocdoc-webhook-receiver' }));92app.listen(3000, '0.0.0.0', () => console.log('Zocdoc webhook server running on port 3000'));Pro tip: Respond to webhook POST requests with a 200 status immediately, then process the event asynchronously. Zocdoc (like most webhook systems) may retry delivery if it does not receive a 200 response within a few seconds, causing duplicate event processing.
Expected result: The server starts on port 3000 and the /health endpoint returns {"status": "ok"}. The server is ready to receive Zocdoc webhook events at the /webhook endpoint.
Add Appointment Reminder with Twilio
Add Appointment Reminder with Twilio
One of the most valuable additions to a Zocdoc webhook integration is automated appointment reminders. Studies show that SMS reminders reduce no-show rates by 20-30%. When a new appointment is booked via Zocdoc, your Replit server receives the event and schedules an SMS reminder for 24 hours before the appointment time. The implementation uses Twilio for SMS delivery (store TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN in Replit Secrets) and a simple scheduling approach: calculate the reminder time from the appointment datetime, and either store it for a scheduled delivery or use Twilio's Message Scheduling feature to send at the exact right time. For compliance: only send SMS reminders if you have explicit patient consent. Zocdoc collects patient contact information for booking purposes, but your use of that data for reminders should be covered by your privacy practices and patient consent. Consult your HIPAA compliance officer and the terms of your Zocdoc BAA before sending PHI via SMS.
1# Python: appointment reminder via Twilio2# Add to requirements: twilio3import os4from twilio.rest import Client5from datetime import datetime, timedelta6import pytz78TWILIO_SID = os.environ['TWILIO_ACCOUNT_SID']9TWILIO_TOKEN = os.environ['TWILIO_AUTH_TOKEN']10TWILIO_FROM = os.environ.get('TWILIO_PHONE_NUMBER', '')1112client = Client(TWILIO_SID, TWILIO_TOKEN)1314def send_appointment_reminder(patient_phone, provider_name, appointment_dt_str):15 """16 Send an SMS confirmation and schedule a reminder.17 appointment_dt_str: ISO 8601 datetime string18 """19 # Immediate confirmation20 confirmation = (21 f'Your appointment with {provider_name} has been confirmed. '22 f'Details: {appointment_dt_str}. '23 f'Reply STOP to opt out of reminders.'24 )25 message = client.messages.create(26 body=confirmation,27 from_=TWILIO_FROM,28 to=patient_phone29 )30 print(f'Confirmation SMS sent: {message.sid}')3132 # Schedule reminder for 24 hours before appointment33 try:34 appt_dt = datetime.fromisoformat(appointment_dt_str.replace('Z', '+00:00'))35 reminder_time = appt_dt - timedelta(hours=24)36 now = datetime.now(pytz.UTC)3738 if reminder_time > now:39 reminder_body = (40 f'Reminder: You have an appointment with {provider_name} tomorrow. '41 f'Reply STOP to opt out.'42 )43 # Twilio Messaging Scheduling44 scheduled = client.messages.create(45 body=reminder_body,46 from_=TWILIO_FROM,47 to=patient_phone,48 schedule_type='fixed',49 send_at=reminder_time.strftime('%Y-%m-%dT%H:%M:%SZ')50 )51 print(f'Reminder scheduled: {scheduled.sid} for {reminder_time}')52 except Exception as e:53 print(f'Reminder scheduling failed: {e}')5455# Usage in appointment.created handler:56# send_appointment_reminder('+15551234567', 'Dr. Smith', '2025-07-15T10:00:00Z')Pro tip: Twilio Message Scheduling (the send_at parameter) requires a Twilio paid plan and must be scheduled between 15 minutes and 7 days in the future. Verify your Twilio account supports scheduling before deploying this in production.
Expected result: When a new appointment webhook arrives with patient phone and appointment datetime, the reminder function sends an immediate confirmation SMS and schedules a 24-hour-before reminder via Twilio.
Deploy on Replit Reserved VM for Healthcare Reliability
Deploy on Replit Reserved VM for Healthcare Reliability
For healthcare appointment integrations, use Replit Reserved VM rather than Autoscale deployment. The key difference is that Reserved VM keeps your server process running continuously, while Autoscale scales to zero when idle. For webhook receivers, you need the server to be instantly available whenever a Zocdoc event fires β even in the middle of the night when a patient books an appointment. To deploy on Reserved VM: click the Deploy button in the Replit editor. Select Reserved VM as the deployment type. Choose at least 0.5 vCPU and 512MB RAM β this is sufficient for a webhook receiver with moderate traffic. Set the run command to node index.js (Node.js) or python app.py (Python). Click Deploy. After deployment, Replit gives you a permanent production URL. Register this URL in Zocdoc's partner portal as your webhook endpoint. The URL format is https://your-repl-name.your-username.repl.co/webhook. Monitor your deployment's health using Replit's deployment logs (accessible from the Deployments tab). Set up uptime monitoring using a free service like BetterStack or UptimeRobot to get alerted if your endpoint goes down. For healthcare applications, every missed webhook could mean a missed appointment confirmation or failed reminder β reliability matters.
1# .replit deployment configuration2# Set in your .replit file for Reserved VM deployment34# [deployment]5# run = ["node", "index.js"]6# deploymentTarget = "cloudrun"7#8# For Python:9# [deployment]10# run = ["python", "app.py"]11# deploymentTarget = "cloudrun"12#13# [[ports]]14# internalPort = 300015# externalPort = 80Pro tip: Use Replit Reserved VM (not Autoscale) for Zocdoc webhook receivers. Healthcare booking events happen 24/7 β appointments are booked at all hours β and Autoscale's scale-to-zero behavior means your server may not be running when a late-night booking event arrives.
Expected result: Your Zocdoc webhook receiver is live on Replit Reserved VM with a permanent URL. The server stays running continuously and is ready to receive appointment events at any time.
Common use cases
Automated Appointment Reminder System
When Zocdoc delivers an appointment.created webhook to your Replit server, the server extracts patient contact information, appointment date/time, and provider details, then schedules an SMS reminder (via Twilio) 24 hours before the appointment and an email confirmation immediately after booking. This reduces no-show rates without requiring the practice to manually send reminders.
Build a Flask server that receives Zocdoc appointment.created webhooks, extracts the appointment datetime and patient phone number, then uses Twilio to schedule an SMS reminder 24 hours before the appointment and sends an immediate email confirmation via SendGrid.
Copy this prompt to try it in Replit
CRM Patient Record Sync
When a new patient books through Zocdoc for the first time, your Replit server receives the booking webhook, checks whether the patient already exists in your CRM (by email or phone), and creates a new patient record if not found. It then logs the appointment as a CRM activity. This keeps your patient database synchronized with Zocdoc bookings automatically.
Create a Node.js Express endpoint that receives Zocdoc new patient booking webhooks, checks a Salesforce CRM for an existing contact by email, creates a new contact if not found, and logs the appointment as a Salesforce activity.
Copy this prompt to try it in Replit
Practice Analytics Dashboard
Your Replit server logs every appointment event (created, modified, cancelled, no-show) from Zocdoc webhooks to a database. A dashboard served by the same Replit server shows the practice manager appointment volume, cancellation rates, no-show patterns, and busiest booking times. This analytics layer supplements Zocdoc's own reporting with custom metrics.
Build a Python Flask app that receives Zocdoc appointment webhooks, stores event data in a SQLite database, and serves a dashboard showing daily appointment volume, cancellation rates, and provider utilization for the past 30 days.
Copy this prompt to try it in Replit
Troubleshooting
Zocdoc webhook deliveries fail or show errors in the partner portal
Cause: The Replit server is not running, the URL is incorrect, or the server is not returning a 200 response quickly enough before Zocdoc's timeout.
Solution: Verify your Replit deployment is running by visiting the /health endpoint in a browser. Ensure you are using the Reserved VM deployment URL (not the editor preview URL). The webhook handler must respond with a 200 status within 5-10 seconds β move all processing to an async background task and respond immediately.
1// Respond immediately, process asynchronously2app.post('/webhook', (req, res) => {3 res.json({ received: true }); // respond FIRST4 processEvent(req.body).catch(console.error); // then process5});Webhook signature verification fails, rejecting all incoming events
Cause: The raw request body is being parsed by JSON middleware before signature verification, altering the byte representation used for HMAC calculation. Or the webhook secret in Replit Secrets does not match what Zocdoc configured.
Solution: Ensure express.raw() middleware is applied to the /webhook route before express.json(). In Flask, use request.get_data() to get raw bytes. Verify the ZOCDOC_WEBHOOK_SECRET in Replit Secrets exactly matches the secret configured in the Zocdoc partner portal, including any whitespace.
1// Parse raw body on webhook route only (before express.json)2app.use('/webhook', express.raw({ type: 'application/json' }));3app.use(express.json()); // applied to other routes4// In webhook handler: use req.body as raw BufferCannot find Zocdoc API documentation or developer portal
Cause: Zocdoc does not have a public developer portal. Their API and webhook documentation is only available to approved partners after signing a partnership agreement.
Solution: Contact Zocdoc directly via zocdoc.com/partners or their sales/partnerships team. API access requires a formal business relationship. For practices using Zocdoc for scheduling, your Zocdoc account manager can help with integration questions. This is not a self-service developer API like Stripe or Twilio.
Duplicate appointment events are processed, causing double reminders to patients
Cause: Zocdoc retries webhook delivery if your server does not respond with 200 within the timeout window, or if there was a network issue during initial delivery. Your event handler does not check for duplicate event IDs.
Solution: Implement idempotency by storing processed event IDs in a database or in-memory cache. Before processing any event, check if its ID has been seen. If yes, return 200 without reprocessing. Use a proper database (PostgreSQL, SQLite) rather than in-memory for persistence across Repl restarts.
1# Simple idempotency with SQLite2import sqlite334conn = sqlite3.connect('/tmp/processed_events.db')5conn.execute('CREATE TABLE IF NOT EXISTS events (id TEXT PRIMARY KEY, processed_at REAL)')67def already_processed(event_id):8 row = conn.execute('SELECT id FROM events WHERE id=?', (event_id,)).fetchone()9 return row is not None1011def mark_processed(event_id):12 import time13 conn.execute('INSERT OR IGNORE INTO events VALUES (?, ?)', (event_id, time.time()))14 conn.commit()Best practices
- Use Replit Reserved VM (not Autoscale) for Zocdoc webhook receivers β healthcare appointments are booked 24/7 and your server must always be online.
- Store all Zocdoc credentials and downstream integration keys in Replit Secrets (lock icon π) β never hardcode them in source files.
- Respond to webhook POST requests with 200 immediately, then process events asynchronously to prevent Zocdoc timeout retries.
- Implement idempotency for all event handlers β store processed event IDs to prevent duplicate processing from webhook retries.
- Verify webhook signatures before processing any appointment data to ensure events genuinely came from Zocdoc.
- For HIPAA compliance, log only non-PHI identifiers (appointment IDs, event types, timestamps) β never log patient names, dates of birth, or medical details to console output.
- Test your webhook endpoint with Zocdoc's test event delivery tool before going live with real patient appointments.
- Set up external uptime monitoring (BetterStack, UptimeRobot) for your Replit deployment to get alerts if the webhook endpoint goes down.
Alternatives
Mindbody targets fitness and wellness studios with a publicly accessible API and OAuth integration, making it much easier to get started compared to Zocdoc's partner-only API model.
Acuity Scheduling provides a general-purpose appointment API that is publicly accessible without a partnership agreement, making it faster to integrate for healthcare-adjacent scheduling needs.
Apple HealthKit is better for accessing individual patient health data on iOS devices rather than managing appointment scheduling at the practice level.
Frequently asked questions
Does Zocdoc have a public API I can use from Replit?
Zocdoc does not have a public developer API with self-service registration. Their API is a restricted partner API available only to companies with a formal Zocdoc partnership agreement. To get API or webhook access, contact Zocdoc's partnerships team at zocdoc.com/partners. This is different from platforms like Stripe or Twilio that offer open developer APIs.
How do I integrate Replit with Zocdoc if I have partner access?
With Zocdoc partner access, configure a webhook endpoint in the Zocdoc partner portal pointing to your Replit Autoscale or Reserved VM deployment URL (e.g., https://your-repl.your-username.repl.co/webhook). Your Replit server receives appointment events (created, updated, cancelled) and processes them to trigger reminders, CRM updates, or analytics. Use Reserved VM deployment for continuous availability.
How do I handle HIPAA compliance when processing Zocdoc data in Replit?
Processing Protected Health Information (PHI) in Replit requires that Replit is part of your HIPAA compliance framework. Replit does not offer a BAA (Business Associate Agreement) on standard plans β Enterprise plans may have different terms. For HIPAA-compliant production deployments, consider whether Replit's data processing terms meet your compliance requirements, or use Replit only for non-PHI processing and route PHI to a HIPAA-compliant cloud provider.
Can I use Replit to send Zocdoc appointment reminders to patients?
Yes, if you have appropriate patient consent and HIPAA authorization. When a Zocdoc webhook fires for a new appointment, your Replit server can trigger SMS reminders via Twilio or email reminders via SendGrid. Ensure your patient communication practices comply with your HIPAA BAAs and that you have patient opt-in consent for reminder messages.
What deployment type should I use for a Zocdoc webhook receiver on Replit?
Use Replit Reserved VM rather than Autoscale. Healthcare appointment bookings happen at all hours, including nights and weekends, and Autoscale can scale to zero when idle, meaning the server may not be ready when an appointment event fires. Reserved VM keeps the server running continuously for reliable 24/7 webhook reception. It costs more than Autoscale but is essential for production healthcare integrations.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation