Skip to content

API keys tools

MCP tools for API keys: api_keys_create, api_keys_get, api_keys_list, api_keys_revoke, api_keys_update.

  • api_keys_create: Create an API key
  • api_keys_get: Get an API key
  • api_keys_list: List API keys
  • api_keys_revoke: Revoke an API key
  • api_keys_update: Rename an API key

api_keys_create

Create an API key. Operation api_keys.create · Organization level · permission keys:admin · risk tier security · since M1

Creates an API key for a brand (the default), a legal entity, or the whole organization (an org management key), in the mode of the request. The response contains the key in secret. It is shown only once: only a hash is stored, so copy it to your secret manager now. prefix (the first 12 characters) identifies the key later in the console and request logs.

  • kind: "brand" needs brandId (or a brand-scoped request); the key acts on that brand only.
  • kind: "entity" needs entityId; the key acts on the entity's brands and its ledger, filings, registrations and tasks.
  • kind: "org" acts on the whole organization, including management operations such as members, brands and API keys. It needs an organization-level request.

scopes are permission scopes such as customers:read, subscriptions:write or usage:write (a restricted key for usage writers). A key can only carry scopes its kind can use, and never more than you could do yourself at that brand, entity or organization in that mode.

Live keys (or_live_…) need a live brand (go-live checklist), a plan with live mode and an active organization; otherwise the call fails with live_keys_unavailable. Creating keys needs a sign-in within the last 15 minutes in the console, and approval for agents (security tier).

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
namestringyes(1–100 characters)
kindone of org, entity, brandno(default "brand")
entityIdID (ent_…)no–
brandIdID (brd_…)no–
scopesarray of one of 98 values, e.g. org:read, org:write, org:adminyes(1–100 items)
expiresAtdate-time (ISO 8601)no–
entity_idID (ent_…)noOptional: act inside this legal entity (ent_…) instead of the whole organization.
brand_idID (brd_…)noOptional: act inside this brand (brd_…) instead of the whole organization.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Scope: the whole organization, or one legal entity or brand of it with entity_id or brand_id.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Examples

A brand key for a billing backend

Arguments:

JSON
{
  "name": "Billing backend",
  "brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
  "scopes": ["customers:write", "subscriptions:write", "usage:write"],
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "key_01m4ttwd3tesktp0hc6bpxwkpd",
  "object": "api_key",
  "kind": "brand",
  "livemode": false,
  "name": "Billing backend",
  "prefix": "or_test_acme",
  "scopes": ["customers:write", "subscriptions:write", "usage:write"],
  "status": "active",
  "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
  "entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
  "brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
  "createdBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-13T12:00:00.000Z",
  "expiresAt": null,
  "lastUsedAt": null,
  "revokedAt": null,
  "secret": "or_test_acme-app_ExampleOnlyNotARealKey000000000000000000000"
}

A restricted usage writer that expires

High-frequency usage writers only need usage:write.

Arguments:

JSON
{
  "name": "Usage ingest",
  "kind": "brand",
  "brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
  "scopes": ["usage:write"],
  "expiresAt": "2026-10-20T09:30:00.000Z",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "key_01m4ttwd3tesktp0hc6bpxwkpd",
  "object": "api_key",
  "kind": "brand",
  "livemode": false,
  "name": "Usage ingest",
  "prefix": "or_test_acme",
  "scopes": ["usage:write"],
  "status": "active",
  "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
  "entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
  "brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
  "createdBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-13T12:00:00.000Z",
  "expiresAt": "2026-10-20T09:30:00.000Z",
  "lastUsedAt": null,
  "revokedAt": null,
  "secret": "or_test_acme-app_ExampleOnlyNotARealKey000000000000000000000"
}

api_keys_get

Get an API key. Operation api_keys.get · Organization level · permission keys:read · risk tier read · since M1

Returns one API key by its ID (key_…): name, kind, binding, scopes, status, and when it was last used. Never returns the secret or its hash. Keys of another mode, or outside the brand or entity of the request, are resource_not_found.

Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (key_…)yes–
entity_idID (ent_…)noOptional: act inside this legal entity (ent_…) instead of the whole organization.
brand_idID (brd_…)noOptional: act inside this brand (brd_…) instead of the whole organization.
  • Scope: the whole organization, or one legal entity or brand of it with entity_id or brand_id.
  • Read-only: changes nothing; idempotency_key is ignored.

Errors

Example

A brand key that was used recently

Arguments:

JSON
{
  "id": "key_01m4ttwd3tesktp0hc6bpxwkpd"
}

Result output:

JSON
{
  "id": "key_01m4ttwd3tesktp0hc6bpxwkpd",
  "object": "api_key",
  "kind": "brand",
  "livemode": false,
  "name": "Billing backend",
  "prefix": "or_test_acme",
  "scopes": ["customers:write", "subscriptions:write", "usage:write"],
  "status": "active",
  "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
  "entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
  "brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
  "createdBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-13T12:00:00.000Z",
  "expiresAt": null,
  "lastUsedAt": "2026-10-20T09:30:00.000Z",
  "revokedAt": null
}

api_keys_list

List API keys. Operation api_keys.list · Organization level · permission keys:read · risk tier read · since M1

Lists the API keys you can see, newest first, in the mode of the request. Never returns secrets or hashes: keys are recognised by prefix (their first 12 characters) and name.

An organization-level request sees every key of the organization (org, entity and brand keys); an entity request sees the entity's keys and its brands' keys; a brand request sees only that brand's keys. Filter by kind, entityId, brandId and status (active, expired, revoked). Paginate with limit (1–100, default 10) and starting_after (the next_cursor of the previous page).

Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
limitintegerno(1–100)
starting_afterID (key_…)no–
kindone of org, entity, brandno–
entityIdID (ent_…)no–
brandIdID (brd_…)no–
statusone of active, expired, revokedno–
entity_idID (ent_…)noOptional: act inside this legal entity (ent_…) instead of the whole organization.
brand_idID (brd_…)noOptional: act inside this brand (brd_…) instead of the whole organization.
  • Scope: the whole organization, or one legal entity or brand of it with entity_id or brand_id.
  • Read-only: changes nothing; idempotency_key is ignored.

Errors

Examples

Active keys of a brand

Arguments:

JSON
{
  "brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
  "status": "active"
}

Result output:

JSON
{
  "object": "list",
  "data": [
    {
      "id": "key_01m4ttwd3tesktp0hc6bpxwkpd",
      "object": "api_key",
      "kind": "brand",
      "livemode": false,
      "name": "Billing backend",
      "prefix": "or_test_acme",
      "scopes": ["customers:write", "subscriptions:write", "usage:write"],
      "status": "active",
      "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
      "entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
      "brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
      "createdBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
      "createdAt": "2026-10-13T12:00:00.000Z",
      "updatedAt": "2026-10-13T12:00:00.000Z",
      "expiresAt": null,
      "lastUsedAt": "2026-10-20T09:30:00.000Z",
      "revokedAt": null
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Two keys per page

Arguments:

JSON
{
  "limit": 2
}

Result output:

JSON
{
  "object": "list",
  "data": [
    {
      "id": "key_01m4ttwd3veh9apbewxheq5xh1",
      "object": "api_key",
      "kind": "org",
      "livemode": false,
      "name": "Automation",
      "prefix": "or_test_acme",
      "scopes": ["customers:write", "subscriptions:write", "usage:write"],
      "status": "active",
      "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
      "entityId": null,
      "brandId": null,
      "createdBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
      "createdAt": "2026-10-13T12:00:00.000Z",
      "updatedAt": "2026-10-13T12:00:00.000Z",
      "expiresAt": null,
      "lastUsedAt": null,
      "revokedAt": null
    },
    {
      "id": "key_01m4ttwd3tesktp0hc6bpxwkpd",
      "object": "api_key",
      "kind": "brand",
      "livemode": false,
      "name": "Billing backend",
      "prefix": "or_test_acme",
      "scopes": ["customers:write", "subscriptions:write", "usage:write"],
      "status": "active",
      "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
      "entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
      "brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
      "createdBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
      "createdAt": "2026-10-13T12:00:00.000Z",
      "updatedAt": "2026-10-13T12:00:00.000Z",
      "expiresAt": null,
      "lastUsedAt": null,
      "revokedAt": null
    }
  ],
  "has_more": true,
  "next_cursor": "key_01m4ttwd3tesktp0hc6bpxwkpd"
}

api_keys_revoke

Revoke an API key. Operation api_keys.revoke · Organization level · permission keys:admin · risk tier security · since M1

Revokes an API key. It stops working immediately: every later request with it fails with api_key_invalid. Revocation is permanent; create a new key to replace it. Revoking a key that is already revoked changes nothing and returns it (the original revokedAt stays).

Annotations: readOnlyHint: false · destructiveHint: true · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (key_…)yes–
entity_idID (ent_…)noOptional: act inside this legal entity (ent_…) instead of the whole organization.
brand_idID (brd_…)noOptional: act inside this brand (brd_…) instead of the whole organization.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Scope: the whole organization, or one legal entity or brand of it with entity_id or brand_id.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Example

Revoke a leaked key

Arguments:

JSON
{
  "id": "key_01m4ttwd3tesktp0hc6bpxwkpd",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "key_01m4ttwd3tesktp0hc6bpxwkpd",
  "object": "api_key",
  "kind": "brand",
  "livemode": false,
  "name": "Billing backend",
  "prefix": "or_test_acme",
  "scopes": ["customers:write", "subscriptions:write", "usage:write"],
  "status": "revoked",
  "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
  "entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
  "brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
  "createdBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-20T09:30:00.000Z",
  "expiresAt": null,
  "lastUsedAt": null,
  "revokedAt": "2026-10-20T09:30:00.000Z"
}

api_keys_update

Rename an API key. Operation api_keys.update · Organization level · permission keys:admin · risk tier security · since M1

Changes an API key's name, the label you see in the console and request logs. Nothing else about a key changes after creation: to change its scopes, brand or mode, create a new key and revoke the old one. Revoked keys can't be renamed.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (key_…)yes–
namestringyes(1–100 characters)
entity_idID (ent_…)noOptional: act inside this legal entity (ent_…) instead of the whole organization.
brand_idID (brd_…)noOptional: act inside this brand (brd_…) instead of the whole organization.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Scope: the whole organization, or one legal entity or brand of it with entity_id or brand_id.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Example

Rename a key

Arguments:

JSON
{
  "id": "key_01m4ttwd3tesktp0hc6bpxwkpd",
  "name": "Billing backend (eu-west)",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "key_01m4ttwd3tesktp0hc6bpxwkpd",
  "object": "api_key",
  "kind": "brand",
  "livemode": false,
  "name": "Billing backend (eu-west)",
  "prefix": "or_test_acme",
  "scopes": ["customers:write", "subscriptions:write", "usage:write"],
  "status": "active",
  "orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
  "entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
  "brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
  "createdBy": "usr_01m4ttwd3veh9apbewxheq5xh6",
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-20T09:30:00.000Z",
  "expiresAt": null,
  "lastUsedAt": null,
  "revokedAt": null
}