Every Partner API request authenticates with your API key in the
Authorization header:
Authorization: Bearer pp_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Key format:
| Environment | Prefix | Shape |
|---|---|---|
| Production | pp_live_ |
prefix + 48 random base62 characters |
| Everything else (test/staging) | pp_test_ |
prefix + 48 random base62 characters |
Keys are environment-bound: a pp_test_… key against production (or vice
versa) is rejected as 401 unauthorized.
The key is both your identity and your tenant: every resource you create or read through the API is scoped to the tenant the key belongs to. There is no way to reach — or even detect — another tenant's resources (see 401 vs 403 vs 404 below).
/embed-session endpoints — see the
Embed guide.When your key is rotated, the previous key keeps working for a 24-hour grace period, so you can deploy the new key without a hard cutover:
401 unauthorized).Rotation also coarsely invalidates outstanding embed session tokens
minted under the old key generation — active widgets will surface
natzar:expired and your page should mint fresh tokens (with the new key)
via refresh(token). Plan rotations accordingly if you have long-lived
embedded sessions in flight.
An API key authenticates your application. Routes that sign a clinical act with a clinician's name — replies, presence, availability, licences — need a second credential that names the person. There are three; the Physicians guide has the full recipe:
| Credential | Where | Reach |
|---|---|---|
Physician session token — Authorization: Bearer <sessionToken> in place of the key |
The clinician's browser | Only the physician-side routes, only as its own physician. Minted by your server with the key (POST /v1/physicians/{id}/session); short-lived; killed early by a key rotation. |
Cognito ID token — key + X-Natzar-Physician |
Your server or browser, for a clinician who also has a login on our portal | Every route the key reaches, acting as that clinician. |
Asserted physician id — key + X-Natzar-Physician-Id |
Your server, after your own authentication of the clinician | Same as above. Off-switchable per account (403 forbidden when off). |
{id} may be me on every /v1/physicians/{id}/… route.
| Status | Code | When |
|---|---|---|
401 |
unauthorized |
The API key is missing, malformed, revoked, from the wrong environment, or the partner account is suspended. Applies to every /v1 route. |
401 |
embed_token_invalid / embed_token_expired |
Embed surface only — the session token (not your API key) failed verification or expired. Mint a fresh one via /embed-session. |
401 |
unauthorized (physician routes) |
No physician credential where one is required ({id} = me, a reply, presence…), or a physician session that expired / was invalidated by a key rotation. |
403 |
forbidden |
A physician session calling a route outside the physician surface (provisioning, consult creation, events, minting another session…), or reaching for another physician's resources; an asserted physician id on an account with assertion switched off. |
403 |
origin_not_allowed |
Embed surface only — the embedding page's origin is not on your account's allowed-origins list. |
404 |
not_found |
No such resource in your tenant. Deliberately also returned when an id exists but belongs to another partner — cross-tenant access never yields 403, so ids are not an existence oracle. |
Two practical consequences:
404 on an id you believe is valid usually means the id is from a
different environment (test vs live) or was created under a different
partner account.403 from the REST API
itself — cross-tenant reads are 404. 403 forbidden is the answer to a
physician session stepping outside its surface.Requests beyond your rate allowance yield 429 (rate_limited when the
application layer produces it; the gateway may also throttle earlier with
a bodyless 429). Back off with jitter and retry — see
Errors & pagination for which requests are safe
to retry.