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.
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 /practiceslists 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.
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}/callslists calls;GET /calls/{callId}returns one call.- Transcripts are PHI: the
transcriptfield is populated only with thetranscripts:readscope and a signed BAA. - Recordings are PHI too:
GET /calls/{callId}/recording(scoperecordings:read+ BAA) responds with a302redirect 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.
Webhooks & events
Instead of polling, register webhook endpoints (POST /webhook-endpoints) to receive events:
Delivery semantics, in one breath: at-least-once, unordered, signed, PHI-minimal.
- Every delivery carries an
X-GrowDental-Signatureheader (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-Idheader. - Payloads contain IDs, outcomes, and API links — never transcripts, recordings, or patient details. PHI moves only over authenticated API pulls.