Key format
- Keys are issued by the GrowDental team and shown exactly once at creation. We store only a SHA-256 hash — a lost key cannot be recovered, only replaced.
- Store keys in a secret manager. Never commit them, log them, or ship them to browsers or mobile apps; all calls should come from your servers.
- Only
livekeys are issued today. Thegd_test_prefix is reserved for a future sandbox environment.
Scopes
Each key carries a set of scopes. Requests that need a scope your key lacks fail with403 insufficient_scope. Practice grants can further narrow scopes per practice — a request that clears your key’s scopes can still be refused for a practice whose grant does not include that scope.
| Scope | Grants | PHI |
|---|---|---|
practices:read | List granted practices | — |
calls:read | Call outcomes, durations, summaries | — |
transcripts:read | Call transcripts | Yes |
recordings:read | Call recording audio | Yes |
call-requests:write | Create and read your call requests | — |
webhooks:manage | Webhook endpoint CRUD | — |
intake:write | Batch patient/appointment/treatment push (Phase 2) | Yes |
scheduling:manage | Mid-call scheduling integration (Phase 3) | — |
The BAA gate
Scopes marked PHI above are hard-gated in code, not just in paperwork: until a Business Associate Agreement is executed for your app, any request using them returns:Key rotation
Rotation is a coordinated, zero-downtime handoff:Request a new key
Email us (or use your admin contact) to issue a second key with the same
scopes. Both keys work simultaneously — there is no forced cutover.
Deploy the new key
Roll the new key out through your secret manager and verify traffic
succeeds with it (watch for 401s).
lastUsedAt per key and may flag long-unused keys for cleanup.
Authentication errors
| Status | error code | Meaning |
|---|---|---|
| 401 | missing_authorization | No or malformed Authorization: Bearer ... header |
| 401 | invalid_api_key | Key is unknown (check for truncation/whitespace) |
| 401 | key_revoked | Key was revoked — switch to your current key |
| 403 | app_suspended | Your partner app is suspended — contact us |
| 403 | insufficient_scope | Key lacks the required scope |
| 403 | baa_required | PHI scope used without a signed BAA |
| 404 | not_found | Resource missing or practice not granted to your app (deliberately indistinguishable) |
Rate limits
Limits are per key, per minute, on a fixed window:- 600 requests/minute for most endpoints.
- 60 requests/minute for bulk writes (call-request creation) — a separate budget, so bulk traffic never starves your reads.
429 rate_limited with a Retry-After header (seconds). Back off for at least that long; requests sent while limited still count against the window.