Skip to main content
Three kinds of caller use this API, each with its own token. The tokens are not interchangeable: a brand server token cannot call patient endpoints, and a patient token cannot call brand server or clinical endpoints. Coaches use the TeraRx portal, which is not part of this contract. Each operation lists the scheme and the scope it needs. All tokens go in Authorization: Bearer <token>. A platform partner that hosts several brands holds one client for all of them and names the brand on every token request, so each token is still for one brand. See Platform partners.

Brand servers: client credentials

TeraRx issues one OAuth client per brand and environment (integration, production). The secret is shown once; TeraRx keeps only its hash. Keep it on your server, never in an app. The integration client works against the sandbox and test environments only; the production API answers it with unauthorized_client.
A brand server reads status and ids only. It never reads clinical content: messages, form answers, protocol text and log values stay with the patient and the care team.

Patients: token exchange

There are no patient passwords in the API. Your server vouches for the patient by signing a short-lived JWT with your own private key; TeraRx checks it against the public keys you registered (a JWKS URL or a JWKS document) and returns a patient token. TeraRx never holds a key that can mint patient sessions, and you can rotate keys yourself by publishing a new key in your JWKS.
  1. Your app signs the patient in with your own login.
  2. Your server signs a patient assertion (below) and hands it to the app.
  3. The app (or your server) exchanges it:
  1. The response’s access_token is valid for 15 minutes for that one patient and enrollment. There is no refresh token: sign a new assertion when it expires.

Patient assertion

A JWT (RFC 7519) signed with ES256, RS256 or EdDSA. The header names the key with kid, which must be in your registered JWKS. TeraRx allows 30 seconds of clock skew on iat and exp. The assertion carries no names or health data. If you registered a JWKS URL, TeraRx caches it for 10 minutes and fetches it again as soon as an assertion names a kid it has not seen (at most every 30 seconds). To rotate, publish the new key next to the old one, start signing with it, then remove the old one. Each problem also carries the RFC 6749 error field (invalid_grant, invalid_client, unauthorized_client …) for OAuth libraries.

Prescriber systems: clinical clients

Your prescriber system gets its own OAuth client, separate from the brand server’s, with clinical:read (read flags) and clinical:write (acknowledge and resolve). It authenticates with client credentials like a brand server. A clinical client acts for many prescribers, so every clinical write names the individual in the request body:
name is required, plus at least one of npi or prescriber_id. A write without on_behalf_of, or with an NPI whose check digit is wrong, is refused with 422 validation_failed and the field’s pointer. TeraRx stores the prescriber and the client that sent it on the flag, shows the name to coaches, and records it in the audit log.