Tenants
A tenant is whatever you would put on an invoice, and it is what you are billed on.
A tenant is whatever you would put on an invoice. It belongs to the workspace, not to a project or an environment: a customer who uses two of your APIs in both test and live is still one tenant, so they are counted once.
- You have customer organisations. One tenant per organisation. Several humans log in on the org's behalf; one tenant holds the keys, and one line appears on your invoice.
- You have only user accounts, no organisation concept. One tenant per user account.
- Never one tenant per user inside an organisation. It multiplies the bill (each tenant is a billable unit) and gives each member their own full
scope: 'tenant'rate-limit quota instead of one shared one, which is not what "Acme gets 10,000 a day" means.
Tenants → New tenant takes an external id and a name. The external id is unique per workspace and is meant to be your identifier for that customer — the org id in the first shape above, the user id in the second — so a lookup from your side never needs a mapping table: mint the tenant, then store the id the call returns on that same row, indexed and unique, one column.

curl -X POST https://api.keyringdev.com/v1/tenants \
-H "Authorization: Bearer $KEYRING_SECRET_KEY" \
-H 'Content-Type: application/json' \
-d '{"external_id":"acme-corp","name":"Acme Corp"}'{
"object": "tenant",
"id": "01a0...",
"external_id": "acme-corp",
"name": "Acme Corp"
}-- your own table, after the call above
update organizations set keyring_tenant_id = '01a0...' where id = 'acme-corp';That is true of this API call, and false of what arrives on a request — it is exactly where the sentence above misleads. "Looking a tenant up from your side" is the mint call, keyed on your external_id; a request carries req.keyring.tenantId, which is Keyring's id (01a0... above), never your external_id — the verified context has no external_id field at all. So a handler that needs your own row back looks it up by keyring_tenant_id (the column you just stored), not by re-deriving external_id from anything on the request.
What the tenant page shows
The tenant's page in the dashboard has its usage per project and environment, its keys, its settings (name and a free-form meta object), its embed sessions, and a delete control.
What a tenant is for
- Verification.
req.keyring.tenantIdis the tenant the calling key belongs to. Your handler scopes its query on it. - Rate limits with
scope: 'tenant'share one counter across every key the tenant holds, which is what "this organisation gets 10,000 a day" means and what survives a rotation. - Idempotency is scoped per
(project, env, tenant), so a retry that arrives on a freshly rotated key still finds the record the old key wrote. - Billing. The billable unit is an active tenant per month, counted from live traffic only. Test-mode traffic never enters that count.
Deleting a tenant
Deleting a tenant revokes its keys in the same transaction, the same way deleting a project does.