Partner accounts
Create and fund accounts for your own customers.
A partner is an organization that creates RouterPlus accounts for its own customers. Each account is an organization of its own. The partner funds each account from its balance and earns a share of the account's spend.
To become a partner, contact RouterPlus. RouterPlus sets your revenue share and turns the partner API on for your organization.
curl https://dev2-api.routerplus.com/v1/partner/accounts \
-H "Authorization: Bearer $PARTNER_MANAGEMENT_KEY" \
-H "Content-Type: application/json" \
-d '{"external_id": "cust-1042", "name": "Acme Corp", "credit_usd": 25}'Authentication
The partner API uses a management key of the partner organization: Authorization: Bearer tm_mk_.... Create one with POST /v1/management-keys (see the management API). Every route is served under /v1/... and /api/v1/....
- A partner sees and changes only its own accounts. An account of another partner returns
404. - A management key of an organization that is not a partner returns
403 not_a_partner. - An account's own keys cannot call the partner API.
Routes
| Route | Does |
|---|---|
POST /v1/partner/accounts | Creates an account. Returns 201. |
GET /v1/partner/accounts | Lists every account. |
GET /v1/partner/accounts/{external_id} | Reads one account. |
PATCH /v1/partner/accounts/{external_id} | {"disabled": true} or {"disabled": false}. |
POST /v1/partner/accounts/{external_id}/credits | {"usd": n}. Moves credit to the account. |
POST /v1/partner/accounts/{external_id}/keys | {"name"?}. Creates another inference key. Returns 201. |
GET /v1/partner/earnings?period=YYYY-MM | Spend and revenue share per account for one month. |
Each account shows balance_usd and month_to_date_spend_usd, its spend since the start of the current UTC month.
Create an account
| Field | Type | Notes |
|---|---|---|
external_id | string | Your own id for the customer. 1 to 128 letters, digits or . _ : @ -. Unique among your accounts. |
name | string | The account's organization name, 1 to 100 characters. |
credit_usd | number | Optional. Credit to move from your balance to the account, 0 to 10,000. |
The answer is 201:
{
"data": {
"external_id": "cust-1042",
"org_id": "6c1f0d1e-2a35-4a3e-9a51-0f4c2d7b9e10",
"name": "Acme Corp",
"disabled": false,
"balance_usd": 25,
"month_to_date_spend_usd": 0,
"workspace_id": "0b8e3f52-7c41-4d55-8f0a-3e2d9a6c1b77",
"created_at": "2026-10-31T12:00:00.000Z"
},
"key": "tm_vk_...",
"key_id": "…",
"management_key": "tm_mk_...",
"management_key_id": "…"
}The account gets a default workspace and two keys:
keyis an inference key. Give it to your customer, or call models with it for them.management_keyis a management key for the account's own organization. With it the account can create keys, set guardrails and read its activity.
The answer shows each raw key once. RouterPlus stores only a hash. Keep both keys safe.
An external_id that you already use returns 409.
Move credit to an account
Send {"usd": 10} to POST /v1/partner/accounts/{external_id}/credits.
- The amount is above 0 and at most 10,000.
- RouterPlus takes the amount from your balance and adds it to the account's balance in one step. The answer gives the account, and your new balance in
transfer.partner_balance_usd. - When your balance is less than the amount, the answer is
402 insufficient_balanceand no credit moves. The same rule applies tocredit_usdon create: the account is not created. - Credit on an account cannot move back to the partner.
Create another key
POST /v1/partner/accounts/{external_id}/keys returns 201 with a new inference key in key, shown once. The key is in the account's default workspace.
Disable an account
{"disabled": true} turns off every key of the account: its inference keys and its management keys. Requests with those keys get 401. You cannot create keys for a disabled account.
{"disabled": false} turns on the keys that the disable turned off. A key that was already off before the disable stays off. A key can take up to 5 seconds to work again.
Earnings
period is a UTC month as YYYY-MM. Without it, the current month.
{
"period": "2026-10",
"revenue_share_percent": 20,
"data": [
{ "external_id": "cust-1042", "org_id": "…", "spend_usd": 412.5, "revenue_share_usd": 82.5 }
],
"totals": { "spend_usd": 412.5, "revenue_share_usd": 82.5 }
}spend_usdis the account's usage at RouterPlus prices in the month. Usage on the account's own provider keys is not in it.revenue_share_usdisspend_usdtimes your revenue share, rounded to a millionth of a dollar.totalsadds up all accounts.
If RouterPlus set a markup for you, each account also shows markup_usd, and the answer shows markup_percent and markup_note. The markup is a reporting field: the amount you can charge your customers on top. RouterPlus bills your accounts at its own prices.
Audit
Every change writes an audit row on your organization and on the account. Read your rows with GET /v1/audit.
Errors
| Status | Type | When |
|---|---|---|
400 | invalid_request | A field is missing, unknown or out of range. |
401 | unauthorized | No management key, or the key is not valid. |
402 | insufficient_balance | Your balance is less than the credit to move. |
403 | not_a_partner | The key's organization is not a partner. |
403 | partner_disabled | RouterPlus turned off the partner API for your organization. |
404 | not_found | No account with this external_id among your accounts. |
409 | conflict | The external_id is already in use. |
409 | account_disabled | You asked for a key on a disabled account. |
For agents: /docs/partners.md and /llms.txt