The QualifyBase API gives clinics and partners programmatic access to leads, availability, appointment booking, and webhook events. It uses the same booking engine that powers the dashboard and AI agent, so external systems do not drift from the operational source of truth.
Quick Facts
| Base URL | https://www.qualifybase.com/api/v1 |
|---|---|
| Authentication | Bearer token using a clinic-scoped qbk_live_* API key |
| Rate limit | 120 requests per minute, per API key |
| OpenAPI | /api/v1/openapi.json |
Security Model
- API keys are created inside the dashboard by an authenticated clinic user.
- The full key is shown only once. QualifyBase stores a hash, not the raw key.
- Each key is scoped to one clinic and cannot access another clinic's data.
- Send keys only in the
Authorization: Bearerheader. - Do not put API keys in query strings, frontend code, analytics tools, or public repositories.
Quickstart
- Create an API key in the dashboard under Setup → API keys.
- Store the full
qbk_live_...key in your server environment asQB_KEY. - Set your app URL as
QB_HOST, then call the REST API from your backend.
# Check availability
curl -s "$QB_HOST/api/v1/availability?from=2026-04-26&preference=morning&limit=5" \
-H "Authorization: Bearer $QB_KEY"
# Book an appointment
curl -s -X POST "$QB_HOST/api/v1/appointments" \
-H "Authorization: Bearer $QB_KEY" \
-H "Content-Type: application/json" \
-d '{
"lead_id": "c3e8a1d4-...",
"scheduled_at": "2026-04-26T09:00:00Z",
"ends_at": "2026-04-26T09:30:00Z",
"title": "Consultation"
}'Zapier Native App Coverage
The QualifyBase Zapier integration uses only production /api/v1 endpoints over HTTPS. Zapier users authenticate once with a QualifyBase API key in Zapier's Authentication screen; the integration does not ask for API keys inside trigger or action fields. The connection label is returned by GET /api/v1/me as the clinic name.
The current native Zapier app exposes these user-facing capabilities:
- Triggers: New Appointment, Updated Appointment, Cancelled Appointment.
- Triggers: Qualified Campaign Contact, Not Interested Campaign Contact, Exhausted Campaign Contact, Callback Requested Campaign Contact.
- Trigger: Campaign List, used as the dynamic dropdown for campaign actions.
- Actions: Add Contact to Campaign, Block Calendar Slot, Unblock Calendar Slot.
These are the API endpoints used by that Zapier app:
| Method | Path | Used for |
|---|---|---|
GET | /api/v1/me | Validates the API key and returns the clinic connection label used by Zapier. |
GET | /api/v1/campaigns | Populates the campaign picker for the Add Contact to Campaign action. |
POST | /api/v1/campaigns/{id}/contacts | Adds one contact to an outbound campaign. |
GET | /api/v1/campaigns/contacts | Provides recent sample rows for campaign-contact triggers. |
GET | /api/v1/appointments | Provides recent sample rows for appointment triggers. |
POST | /api/v1/webhooks | Subscribes Zapier hook URLs to lead, appointment, and campaign-contact events. |
DELETE | /api/v1/webhooks/{id} | Unsubscribes a Zapier hook URL when a Zap is turned off or deleted. |
POST | /api/v1/availability/blocks | Blocks an external calendar event so QualifyBase will not book over it. |
DELETE | /api/v1/availability/blocks | Removes a previously synced external calendar block. |
What You Can Build
- Lead sync: push web form leads into QualifyBase or pull qualified leads into your CRM.
- Availability checks: show real clinic availability in an external app.
- Appointment booking: create, reschedule, and cancel appointments from a custom workflow.
- Webhook automation: receive lead and appointment events in your CRM, Zapier, Make, or internal systems.
- Outbound campaign automation: add campaign contacts from CRM rows, forms, spreadsheets, or ad-platform lead events.
- External calendar sync: mirror Google Calendar, Outlook, Cal.com, or another calendar as busy blocks in QualifyBase.
Endpoint Reference
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/me | Return the authenticated clinic and API-key metadata. |
GET | /api/v1/leads | List leads for the authenticated clinic. |
POST | /api/v1/leads | Create or update a lead from an external source. |
GET | /api/v1/agents | List agents (filter by direction) — e.g. to pick the outbound agent a lead is assigned to. |
GET | /api/v1/availability | Find open appointment slots. |
POST | /api/v1/appointments | Book an appointment for a lead. |
GET | /api/v1/appointments | List appointments, with optional status and date filters. |
GET | /api/v1/appointments/:id | Fetch one appointment. |
PATCH | /api/v1/appointments/:id | Reschedule or update an appointment. |
DELETE | /api/v1/appointments/:id | Soft-cancel an appointment. |
GET | /api/v1/campaigns | List outbound campaigns for campaign-contact automation. |
POST | /api/v1/campaigns/:id/contacts | Add one contact to an outbound campaign. |
GET | /api/v1/campaigns/contacts | List campaign contacts across campaigns, optionally filtered by status. |
GET | /api/v1/webhooks | List webhook endpoints created by the calling API key. |
POST | /api/v1/webhooks | Create a webhook endpoint and receive its signing secret once. |
DELETE | /api/v1/webhooks/:id | Delete a webhook endpoint owned by the calling API key. |
POST | /api/v1/availability/blocks | Upsert a busy block from an external calendar event. |
DELETE | /api/v1/availability/blocks | Delete a busy block by external source and external ID. |
Leads
POST /api/v1/leads creates or updates a lead from any external source — web forms, CRMs, ad platforms, or no-code tools like Make and n8n. At least one of phone or email is required. Optional fields include full_name, country, city, language, treatment_interest, notes, and source (one of website, instagram, whatsapp, facebook, tiktok, referral, email, paid_ads, other).
Pass external_source + external_id together to make the call idempotent — re-running the same payload updates the existing lead instead of creating a duplicate. Free-form external_metadata (JSON object, up to 4 KB) is also accepted for round-tripping CRM context.
Routing a lead to a specific outbound agent
Pass agent_id in the body to pin the lead to a specific outbound agent. The lead will then appear under that agent’s Leads tab in the dashboard. The agent must belong to the authenticated clinic and have direction outbound — inbound agents are rejected with 400 invalid_input.
To find an agent’s ID, open the agent in the dashboard and go to the Settings tab. The ID is shown as a copyable chip beneath the page header. You can also list agents programmatically with GET /api/v1/agents?direction=outbound — useful for building an agent dropdown instead of hard-coding an ID.
curl -s -X POST "$QB_HOST/api/v1/leads" \
-H "Authorization: Bearer $QB_KEY" \
-H "Content-Type: application/json" \
-d '{
"full_name": "Alex Smith",
"phone": "+14155551212",
"email": "alex@example.com",
"treatment_interest": "implants",
"country": "US",
"city": "San Francisco",
"source": "paid_ads",
"agent_id": "4315bd15-3bcf-4685-9430-09afc83e8e5a",
"external_source": "make_facebook_lead_ads",
"external_id": "fb_lead_987654321"
}'The response echoes the saved row back, including agent_id so you can confirm the routing took effect. A new lead returns 201 Created; an idempotent update of an existing lead returns 200 OK.
Wiring this into Make
In Make, use the HTTP → Make a request module with POST, URL $QB_HOST/api/v1/leads, headers Authorization: Bearer YOUR_API_KEY and Content-Type: application/json, and a JSON body mapping the trigger’s fields to the field names above. Hard-code agent_id to the UUID copied from the agent’s Settings tab. If your upstream tool provides a stable record ID, set both external_source (e.g. make_facebook_lead_ads) and external_id to that record ID so re-runs update the same lead rather than creating duplicates.
Campaigns and Contacts
Campaign endpoints are used by the native Zapier app to send new CRM, form, or spreadsheet rows into outbound calling campaigns. GET /api/v1/campaigns returns campaign rows with id, name, status, agent_id,target_country, total_contacts, and created_at.
POST /api/v1/campaigns/{id}/contacts requires name,phone, interest, and city. Optional fields arecountry, email, language, and notes. The endpoint returns the created contact with validation status, attempts, and timestamps.
curl -s -X POST "$QB_HOST/api/v1/campaigns/8a0b71f5-2f1d-4a30-a6d5-14fb4d9d9f17/contacts" \
-H "Authorization: Bearer $QB_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Alex Smith",
"phone": "+14155551212",
"interest": "implants",
"city": "San Francisco",
"country": "US",
"email": "alex@example.com"
}'External Calendar Blocks
Calendar block endpoints let Zapier mirror external calendar events into QualifyBase so the booking engine treats them as busy. POST /api/v1/availability/blocks is idempotent on external_source plus external_id. Re-running the same Zap updates the existing busy block instead of creating duplicates.
curl -s -X POST "$QB_HOST/api/v1/availability/blocks" \
-H "Authorization: Bearer $QB_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_source": "google_calendar",
"external_id": "evt_abc123",
"starts_at": "2026-05-15T11:00:00Z",
"ends_at": "2026-05-15T11:30:00Z",
"title": "External consultation"
}'To remove a block, call DELETE /api/v1/availability/blocks withexternal_source and external_id query parameters. Deleting is idempotent and returns 204 No Content even if the block was already gone.
Webhooks
Webhooks notify external systems when appointment and campaign-contact events happen. Payloads should be verified on your server before you update external systems.
appointment.createdappointment.updatedappointment.cancelledcampaign.contact.qualifiedcampaign.contact.not_interestedcampaign.contact.exhaustedcampaign.contact.callback_requested
Public API webhook subscriptions are managed with GET /api/v1/webhooks,POST /api/v1/webhooks, and DELETE /api/v1/webhooks/{id}. The create response includes signingSecret once. Deliveries includeX-QualifyBase-Signature, X-QualifyBase-Event, andX-QualifyBase-Delivery headers.
{
"id": "evt_5b1f...",
"type": "appointment.created",
"created": "2026-05-14T12:00:00.000Z",
"data": {
"appointment": {
"id": "2b7c9f2a-...",
"lead_id": "c3e8a1d4-...",
"assigned_to": null,
"status": "confirmed",
"scheduled_at": "2026-05-15T11:00:00.000Z",
"ends_at": "2026-05-15T11:30:00.000Z"
}
}
}OpenAPI Spec
The machine-readable API contract is available at /api/v1/openapi.json. Import it into Postman, Insomnia, or an OpenAPI client generator. It includes the same production endpoints used by the native Zapier integration.
What Is Not Public
Call recordings, full conversation transcripts, lead scoring internals, follow-up scheduling internals, agent configuration internals, billing, and cross-clinic data are not exposed as stable public API contracts.