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

# White Label API

> Manage your reseller platform's customers programmatically — list, register, mint tokens, log in, log out, and transfer credits

If you run a white-label reseller workspace, the White Label API lets you manage your own end-customers programmatically instead of through the dashboard — build your own admin console, automate onboarding, run custom auth flows on your own domain, or wire credit top-ups into your billing system.

<Note>
  Every endpoint on this page requires an API key created in your white-label workspace with the `platform:read` / `platform:write` scopes, plus a live owner/admin membership in that workspace. Platform admins acting from their own root workspace get the same endpoints automatically, scoped to direct platform customers instead of a reseller's — never another reseller's customers.
</Note>

## Get platform users

`GET /platform/users` lists the customers in your scope, newest first. Paginate with `limit` / `offset` (see [pagination](/api-reference/introduction#pagination)) and search by name or email with `q`.

```bash theme={null}
curl "https://your-domain.example/api/v1/platform/users?limit=20&q=jane" \
  -H "Authorization: Bearer fam_XXXXXXXXXXXX"
```

## Register a platform user

`POST /platform/users` creates a new customer account and workspace on your behalf. Two modes:

* **`invite` (default)** — no password required. The account is created without credentials; pair it with a login or token call below to actually get the customer (or your own frontend) into it.
* **`password`** — you choose an initial password (8+ characters) for the customer up front.

```bash theme={null}
curl https://your-domain.example/api/v1/platform/users \
  -X POST \
  -H "Authorization: Bearer fam_XXXXXXXXXXXX" \
  -H "Content-Type: application/json" \
  -d '{"name": "Jane Doe", "email": "jane@customer.example", "mode": "invite"}'
```

An email that's already registered anywhere on the platform fails with `409` — the message never reveals whether that account is inside or outside your own scope.

## Log in a platform user

`POST /platform/users/login` authenticates a customer with their own email and password and mints them an access token on success — use it to build your own login form / custom auth flow on your white-label platform instead of sending customers to the hosted login page. Login is rate-limited per IP + email, and every failure — unknown email, wrong password, an email that belongs to someone outside your scope — returns the exact same generic `401`, so a caller can never use the response to guess which accounts exist.

```bash theme={null}
curl https://your-domain.example/api/v1/platform/users/login \
  -X POST \
  -H "Authorization: Bearer fam_XXXXXXXXXXXX" \
  -H "Content-Type: application/json" \
  -d '{"email": "jane@customer.example", "password": "correct horse battery staple"}'
```

<Warning>
  This is the one White Label API operation with no MCP equivalent — credentials should never travel through an MCP tool call.
</Warning>

## Create a user token

`POST /platform/users/{user_id}/token` mints an API key for a customer without needing their password at all — the right call for a dashboard you're building, an onboarding email sequence, or any automated workflow acting on the customer's behalf.

```bash theme={null}
curl https://your-domain.example/api/v1/platform/users/USER_ID/token \
  -X POST \
  -H "Authorization: Bearer fam_XXXXXXXXXXXX" \
  -H "Content-Type: application/json" \
  -d '{"name": "Onboarding token", "expires_in_days": 90}'
```

The plaintext key is returned exactly once — store it immediately, it cannot be retrieved again. It belongs to the customer, not you: an omitted `scopes` grants full access for that customer, not just the scopes your own operator credential happens to have.

## Log out a platform user

`POST /platform/users/{user_id}/logout` revokes every active API key and OAuth token the customer holds across the workspace(s) in your scope — the way to force a sign-out, for example after an account is compromised or your relationship with that customer ends. It's idempotent: logging out an already-logged-out customer just returns zero counts.

```bash theme={null}
curl https://your-domain.example/api/v1/platform/users/USER_ID/logout \
  -X POST \
  -H "Authorization: Bearer fam_XXXXXXXXXXXX"
```

## Transfer balance

`POST /platform/users/{user_id}/balance` moves signed credits between your own workspace wallet and a customer's:

* **Positive `credits`** — grants credits from your wallet to the customer (the standard way to provision a customer account).
* **Negative `credits`** — reclaims credits back from the customer into your wallet.

Either direction requires the source wallet to cover the amount — a wallet balance never goes below zero, and an attempted reclaim that exceeds the customer's balance fails outright instead of partially applying.

```bash theme={null}
curl https://your-domain.example/api/v1/platform/users/USER_ID/balance \
  -X POST \
  -H "Authorization: Bearer fam_XXXXXXXXXXXX" \
  -H "Content-Type: application/json" \
  -d '{"credits": 50, "note": "Onboarding credit"}'
```

## Manage API keys

Every workspace — including the customer workspaces you provision through this API — can manage its own API keys self-service under `/api-keys`, the same endpoints that power **Settings → API Keys** in the dashboard.

```bash theme={null}
curl https://your-domain.example/api/v1/api-keys \
  -X POST \
  -H "Authorization: Bearer fam_XXXXXXXXXXXX" \
  -H "Content-Type: application/json" \
  -d '{"name": "CRM integration", "scopes": ["calls:read", "leads:write"]}'
```

A key can never mint another key with broader access than itself: `scopes` on a new key must be a subset of the calling credential's own scopes (a credential with unrestricted access may grant any scope, and an omitted `scopes` defaults to the caller's own). `GET /api-keys` lists a workspace's keys without ever exposing the secret; `DELETE /api-keys/{id}` revokes one and is idempotent.

## MCP

Everything above is also available as MCP tools, grouped in the **`platform`** toolset (plus `list_api_keys` / `create_api_key` / `revoke_api_key` in the `settings` toolset). Connect with the toolset selector:

```text theme={null}
https://your-domain.example/mcp?toolsets=platform
```

| Tool                         | Maps to                                  |
| ---------------------------- | ---------------------------------------- |
| `list_platform_users`        | `GET /platform/users`                    |
| `get_platform_user`          | `GET /platform/users/{user_id}`          |
| `register_platform_user`     | `POST /platform/users`                   |
| `create_platform_user_token` | `POST /platform/users/{user_id}/token`   |
| `logout_platform_user`       | `POST /platform/users/{user_id}/logout`  |
| `transfer_platform_credits`  | `POST /platform/users/{user_id}/balance` |

There's no `login_platform_user` tool — logging in stays REST-only, for the reason above. The MCP tools accept either a `user_id` or an `email` to identify the target customer; REST always takes `user_id` from the URL path.
