Docs/Organisation Keys
Organisations

Organisation Keys

Create, list, rename and revoke Organisation Keys under /v1/orgs/{orgId}/keys.

An Organisation Key is a sapi_ key, like a personal API key, but it belongs to the Organisation. It keeps working when the person who created it leaves. Your backend uses it to:

It cannot run tasks itself. On /v1/agents/* it gets 403:

403 Forbidden · tenant_token_requiredJSON
{
  "error": "tenant_token_required",
  "message": "Exchange the Organisation Key for a Tenant token: POST /v1/orgs/:orgId/tenants/:tenantId/token."
}

Every other route answers 403 not_available_for_organisation_key.

Owners and admins manage the keys on the console's API keys page. The endpoints below are what the page calls. Like every Organisations API route, they take a signed-in member's session only.

The key object

An Organisation KeyJSON
{
  "keyId": "k_8Hq",
  "name": "backend",
  "mintedByUid": "3fA9kQ2xYz",
  "createdAt": 1790000000000,
  "lastUsedAt": 1790003600000,
  "last4": "AbCd"
}
FieldNotes
keyIdSai's id for the key. Pass it in the paths below.
name1 to 100 characters, or null.
mintedByUidThe member who created it. The key keeps working after they leave.
lastUsedAtUnix time in milliseconds of its last request, or null.
last4The key's last four characters, to tell keys apart (sapi_…AbCd). null for older keys.

The secret itself is never listed.

Create a key

Owner or admin.

Create an Organisation KeycURL
curl -s "$SAI_API_URL/v1/orgs/$ORG_ID/keys" \
  -H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "name": "backend" }'
FieldTypeRequiredNotes
namestringno1 to 100 characters.
201 Created · Organisation KeyJSON
{ "key": "sapi_...", "keyId": "k_8Hq", "name": "backend", "last4": "AbCd" }

key is returned once. Store it in a secret manager.

StatuserrorWhen
403organisation_disabledThe Organisation is disabled.
422key_limit_reachedThe Organisation has 50 keys.
429rate_limitedMore than 10 keys created in an hour.

List keys

Owner or admin.

List Organisation KeyscURL
curl -s "$SAI_API_URL/v1/orgs/$ORG_ID/keys" \
  -H "Authorization: Bearer $FIREBASE_ID_TOKEN"
200 OK · Organisation KeysJSON
{
  "keys": [
    {
      "keyId": "k_8Hq",
      "name": "backend",
      "mintedByUid": "3fA9kQ2xYz",
      "createdAt": 1790000000000,
      "lastUsedAt": 1790003600000,
      "last4": "AbCd"
    }
  ]
}

Newest first. Revoked keys are not listed.

Rename a key

Owner or admin.

Rename an Organisation KeycURL
curl -s -X PATCH "$SAI_API_URL/v1/orgs/$ORG_ID/keys/$KEY_ID" \
  -H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "name": "backend-prod" }'
FieldTypeRequiredNotes
namestringyes1 to 100 characters.

Unknown fields are rejected. 200 with the key.

StatuserrorWhen
400invalid_bodyThe body is empty or has a bad value.
404not_foundNo such key in this Organisation.

Revoke a key

Owner or admin.

Revoke an Organisation KeycURL
curl -s -X DELETE "$SAI_API_URL/v1/orgs/$ORG_ID/keys/$KEY_ID" \
  -H "Authorization: Bearer $FIREBASE_ID_TOKEN"

204 No Content. A revoked key fails with 401 on its next use. Tenant tokens it exchanged stop working within a minute (401 credential_revoked).

StatuserrorWhen
404not_foundNo such key in this Organisation.