Authentication and scopes
The API uses two secret keys:
| Key | Identifies | Header | You get it |
|---|---|---|---|
| Partner key | Your organization | Authorization: Bearer thea_sk_… |
From Thea, when you sign up as a partner |
| Practice key | One connected practice | Thea-Practice-Key: thea_pk_… |
When that practice connects to you |
Send the partner key on every request. Requests about a practice’s data (patients, cases, messages, files, and its roster) also need that practice’s key:
POST /api/partner/v1/cases HTTP/1.1Host: app.theahealth.comAuthorization: Bearer thea_sk_live_…Thea-Practice-Key: thea_pk_live_…Content-Type: application/jsonA practice key only works together with the partner key it was issued to, so neither key alone can read a practice’s data. Requests that don’t need a practice key ignore one if you send it. Thea never accepts keys in query strings or request bodies.
| Requests | Keys needed |
|---|---|
GET /specialties, webhook endpoints, POST /connect/token |
Partner key |
| Everything about a practice: patients, cases, messages, files, roster, seat requests, disconnect | Partner key and practice key |
A missing, malformed, revoked, or expired partner key returns
401 unauthenticated. A missing or
unknown practice key returns
401 invalid-practice-key, and the
key of a practice that has disconnected returns
403 practice-not-connected.
Key format
Section titled “Key format”| Prefix | Key | Environment |
|---|---|---|
thea_sk_test_ |
Partner | Sandbox |
thea_sk_live_ |
Partner | Live |
thea_pk_test_ |
Practice | Sandbox |
thea_pk_live_ |
Practice | Live |
Practice keys don’t expire. Partner keys don’t either, unless Thea agrees an end date with you when issuing one. To rotate your partner key, ask Thea for a second one, switch over, and then ask us to revoke the first. To rotate a practice key, send the practice through the connect flow again: the new key replaces the old one immediately.
Treat both keys like passwords:
- Keep them server-side. Never ship a key in a browser app, mobile app, or desktop client.
- Store them in a secrets manager or an encrypted column, not in source control or logs.
- Store each practice key next to the practice it belongs to, so a request can never pair one practice’s key with another’s data.
Thea stores only a hash of each key and can’t show it to you again. Only the
first few characters (the key’s prefix, such as thea_sk_live_Xk2r9) are stored
in a form we can display, which is how support identifies a partner key.
Scopes
Section titled “Scopes”You agree the scopes your integration needs with Thea when you sign up.
When a practice admin connects your organization, they review and approve them
for that practice. The practice key carries those scopes. An
operation lists the scopes it needs in the API reference; a
request that’s missing one returns
403 insufficient-scope.
| Scope | Allows |
|---|---|
patients:read |
List and retrieve patients |
patients:write |
Create and update patients |
cases:read |
List and retrieve cases, and download their files |
cases:write |
Create, close, and reopen cases |
messages:read |
Read a case’s message thread |
messages:write |
Post messages on a case |
files:write |
Upload files to cases |
providers:read |
Read the practice’s roster |
providers:write |
Request seats for clinicians |
Uploading a file to a case needs both cases:write and files:write.
Webhook endpoints belong to your organization, so they need only your partner
key and no practice scope.

