Authentication
Most of the API can be called with no credentials. Authenticated callers unlock patient binding, one-call submission, and account management.
Anonymous
The first request your agent makes — POST /api/v1/agent/query — is fully public. There is no API key, no OAuth, no signed token to obtain. Just send the JSON body and the server creates an encounter on the fly.
The response includes two short-lived secrets your agent uses for everything that follows:
session_token— pass it back on the next/agent/querycall to continue the same encounter (for example, when the agent has gathered the missing information and wants to resubmit).encounter_token— a 64-character bearer token scoped to a single encounter. Used to drive the checkout URL and to poll the agent chat endpoints for the physician’s reply. Expires 7 days after the encounter is created.
Personal API keys
Once you have an Appendix account, you can mint a personal API key (ak_…) from your account dashboard. Send it as Authorization: Bearer ak_… (or X-API-Key) on any authenticated endpoint except account and credential management — creating, listing, or revoking API keys requires a signed-in session, so that one leaked key cannot mint its own replacements. The key is a long-lived credential tied to your user account.
Prescribing-API developer keys (ak_test_… / ak_live_…) are a different credential and are not accepted on these endpoints — a developer key on /agent/query returns 400 pointing at POST /api/v1/prescribing/query. Developer keys are managed from the developer dashboard, not the account page.
What an API key gets you
- Submit on behalf of a specific person. Pass
patient_idon/api/v1/agent/queryso the encounter is bound to your spouse, child, or yourself without picking the patient at checkout. See How to get a patient_id. - One-call submission for active subscribers. If you’re subscribed and the patient has consented and verified ID, the encounter advances directly to
submitted— no checkout URL to visit. - Manage your account. List/create patients, list and read your own encounters, submit follow-up queries on an existing encounter, read your subscription and invoices, poll the agent chat endpoints.
When auto-submit isn’t possible
If a precondition is missing, the response still returns a checkout_url and an auto_submit object whose pending_reasons field tells the agent what to fix. Possible values: patient_required, patient_not_owned, telehealth_consent_required, patient_not_id_verified, subscription_required, rate_limit_reached.
Developer API keys (Prescribing API)
If you’re building an app that submits on behalf of your own users rather than your own family, you want a developer key, not a personal one. These are a separate credential class with a separate endpoint surface, minted from the developer dashboard.
| Key | What it does |
|---|---|
ak_test_… | Sandbox. Self-issued instantly, no approval. Returns simulated decisions — never reaches a physician, never charges. Use it to build the whole integration. |
ak_live_… | Production. Issued only after your production access is approved. Reaches a real physician and bills per review. |
Send either as Authorization: Bearer ak_test_…. The two credential classes are deliberately non-interchangeable, so a mix-up fails loudly rather than silently doing the wrong thing:
- A developer key on
/agent/queryreturns400pointing atPOST /api/v1/prescribing/query. - A personal key on
/prescribing/queryreturns401— it is never quietly routed to sandbox. - Developer keys are not accepted on the patient chat endpoints. Physician conversation is part of the Appendix↔patient relationship.
The endpoints these keys unlock — patient creation, submission, outcome polling, webhooks — are documented separately under Prescribing API. The rest of this reference describes the personal-account API and does not apply to them.
Clerk session JWTs (browser sessions)
Appendix uses Clerk as its identity provider for the web app. Clerk JWTs are for use in the browser only, and are not accepted by the API for programmatic integration. Server-side and agent-side callers should use a personal API key instead.
/agent/query stays anonymous-friendly
API keys are not required to call /api/v1/agent/query. The initial submission stays available anonymously so any agent can help any user start an encounter without provisioning credentials first.
How to get a patient_id
Each person on your account has a stable UUID. List your patients with GET /api/v1/patients; the id field of each entry is the value to pass as patient_id. The relationship field (one of self, spouse, child, parent, guardian, dependent, other) lets an agent map a sentence like “this is for my wife” onto the right person without you having to type a name. Use POST /api/v1/patients to add new family members.
Rate limits
Limits apply to /api/v1/agent/query and key on, in order: the authenticated user, then the supplied session_token, then a hash of the client IP for fully-anonymous one-shots.
| Limit | Value |
|---|---|
| Queries per hour | 60 |
| Queries per day | 300 |
| Query length | 500 - 10,000 characters |
Need higher rate limits for a production integration? Contact hello@appendix.com.
Authentication errors
| Code | Meaning |
|---|---|
401 | Authorization header was provided but the token is invalid or expired. |
404 | The requested resource doesn’t exist or isn’t visible to your account. |
429 | Rate limit exceeded. |