> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tera.health/llms.txt
> Use this file to discover all available pages before exploring further.

# Platform partners

> One integration for several brands: a token per brand, shared signing keys and webhooks.

A platform partner hosts several telehealth brands and switches TeraRx on for them. The partner integrates once, with one set of credentials for all its brands. A brand that integrates directly keeps its own client and needs none of this.

Each brand stays its own tenant. Its patients, enrollments, logs and reports are separate from every other brand's, including brands under the same partner. Nothing is matched or shared across brands: a person enrolled with two of your brands is two patients.

## What TeraRx sets up

TeraRx creates each brand at onboarding, with its plans, prices, retention and rule matrix, and gives you its `tenant_id`. You get:

| What | Count | Used for |
| - | - | - |
| A brand-server client | One per environment, for all your brands | Client credentials, with the scopes your brands need, plus `tenants:read` |
| Signing keys for patient assertions | One JWKS URL (or JWKS document) and one issuer | Token exchange for every brand's patients |
| A clinical client | One per environment, if you run the prescriber tooling for your brands | Clinical flags. A brand whose prescriber system is separate (for example Beluga) keeps its own clinical client |
| A webhook endpoint and secret | One, for all your brands | A brand may have its own endpoint instead |

## Tokens: one brand at a time

Every token is for one brand. Name the brand with `tenant_id` when you ask for a token:

```http theme={null}
POST /v1/oauth/token
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&tenant_id=a0000000-0000-4000-8000-000000000002&scope=enrollments:read%20enrollments:write
```

Keep one token per brand and reuse it for its hour. A call with brand A's token never sees brand B's patients; it answers `404` as if they did not exist.

| Problem | `code` | HTTP |
| - | - | - |
| No `tenant_id` | `tenant_required` | 400 |
| A brand you may not act for, or one that is not live yet | `tenant_not_permitted` | 400 |

`tenant_not_permitted` is the same answer for an unknown id and for another partner's brand. Rate limits count per brand, so one busy brand does not slow the others.

## Patient assertions

Sign every brand's assertions with the same key and issuer, and add a `tenant_id` claim naming the brand the patient is enrolled with:

```json theme={null}
{
  "iss": "https://partner.example.com",
  "sub": "brand-pt-48213",
  "aud": "https://sandbox.rx.tera.health",
  "tenant_id": "a0000000-0000-4000-8000-000000000002",
  "iat": 1793635200,
  "exp": 1793635500,
  "jti": "5f0c9a52-8a4e-4d4f-9a52-0f6e8b7c1d2e"
}
```

`sub` is the `external_patient_id` you sent on `POST /v1/enrollments` for that brand. Your ids may repeat across brands; TeraRx looks `sub` up within the brand named by `tenant_id`. An assertion without `tenant_id` is refused with `assertion_invalid`, one naming a brand you may not act for with `tenant_not_permitted`. Everything else is as in [Authentication](https://docs.tera.health/guides/authentication.md).

## Listing your brands

`GET /v1/tenants` (scope `tenants:read`) lists every brand under your partner, whichever brand the token is for, with its `id`, `slug`, `display_name` and whether it is live. Use it to check your configuration against ours. You need one brand's `tenant_id`, from onboarding, to get the first token.

## Webhooks

Events for all your brands go to your partner endpoint, signed with your secret, unless a brand has its own endpoint. Every event carries `tenant_id`: route on it. The payloads and signature are as in [Webhooks](https://docs.tera.health/guides/webhooks.md).

## Reports and invoices

`GET /v1/reports/brand` reports on the brand the token is for; ask once per brand. TeraRx sends one monthly invoice for all your brands, with a section per brand.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.