Skip to main content
Five concepts explain everything in the Partner API.

Partners & API keys

A partner app represents your organization on our platform. Apps are created by the GrowDental team (invite-only) and hold your contact details, BAA status, and webhook endpoints. Each app has one or more API keys:
  • Format: gd_live_... — a prefix plus a 43-character random secret (~256 bits of entropy).
  • Shown once at creation; we store only a SHA-256 hash, so a lost key can never be recovered — only replaced.
  • Each key carries scopes (e.g. calls:read, call-requests:write) that bound what it can do.
  • Keys are rate limited individually: 600 requests/minute by default, 60/minute for bulk writes.
Kill switches exist at four granularities — app suspended, key revoked, practice grant revoked, webhook endpoint disabled — so access can be narrowed without tearing everything down.

Practices & grants

A practice is a dental office using GrowDental’s voice agents. Your app never sees all practices — it sees exactly the practices we have granted to it, typically the ones you share a business relationship with.
  • GET /practices lists your granted practices (id, name, slug, timezone, status, vertical). A grant can narrow your key’s scopes per practice, so a scope your key holds may still be refused for a specific practice.
  • Every practice-scoped request is validated against your grants. Practices you have not been granted return 404, not 403 — practice IDs cannot be probed.
The grant is the tenancy boundary of the whole API: key → app → granted practices, checked on every request.

Calls & outcomes

A call is one phone conversation between a practice’s voice agent and a person — inbound or outbound. After every call, post-call processing classifies an outcome (e.g. appointment_booked, callback_requested, voicemail, no_answer) and writes a natural-language summary.
  • GET /practices/{practiceId}/calls lists calls; GET /calls/{callId} returns one call.
  • Transcripts are PHI: the transcript field is populated only with the transcripts:read scope and a signed BAA.
  • Recordings are PHI too: GET /calls/{callId}/recording (scope recordings:read + BAA) responds with a 302 redirect to a short-lived signed URL. Raw storage URLs are never exposed — follow the redirect immediately and re-request when you need the audio again.

Call requests

A call request is how you trigger outbound calling: POST /practices/{practiceId}/call-requests with 1–50 contacts, a purpose, optional free-text context, and an optional calling window. The platform dialer takes it from there — practice-local calling hours, retry ladders, and concurrency caps all apply automatically. You influence what the agent says only through purpose and context; prompts and agent internals are not exposed. Each contact progresses pending → calling → completed | failed (or skipped), and completed contacts link to the resulting call via call_id. Track progress by polling GET /call-requests/{callRequestId} or by subscribing to the call_request.completed event.
Always send an Idempotency-Key header when creating call requests. A blind network retry without one can dial patients twice.

Webhooks & events

Instead of polling, register webhook endpoints (POST /webhook-endpoints) to receive events:
EventFired when
call.completedA call finishes and its outcome is classified
call.recording.readyA call’s recording is processed and fetchable
call_request.completedEvery contact in one of your call requests is terminal
Delivery semantics, in one breath: at-least-once, unordered, signed, PHI-minimal.
  • Every delivery carries an X-GrowDental-Signature header (t=<unix>,v1=<HMAC-SHA256>) — verify it before trusting the payload.
  • Retries use exponential backoff; endpoints that keep failing are auto-disabled until you re-enable them.
  • De-duplicate on the X-GrowDental-Delivery-Id header.
  • Payloads contain IDs, outcomes, and API links — never transcripts, recordings, or patient details. PHI moves only over authenticated API pulls.

Coming later

Phase 2 adds patient intake (batch push of patients, appointments, and treatments through canonical schemas — drafts already in the API Reference) and segment/queue read-back. A partner-facing scheduling contract for mid-call booking into your system is planned behind that. These docs will grow as each phase ships; see the Changelog.