create_api_key

Create an API key

act entity tenant-private since 2026-10-01

Issues an API key on an org: sk_live_ reaches the org, sk_test_ its test twin. Every key belongs to an active service account of the org (service_account_id), acts as that account and takes its mode. The answer to the call that issues it carries the whole key in `secret`. The secret is never stored, by Trade HQ or by this call's idempotency record (the key's row is the record, and it holds only the key's hash), so it can never be shown again: a retry with the same Idempotency-Key and inputs answers the same key with `secret` null and `replayed` true, and creates nothing. The key is pinned to the API version current today unless `api_version` names another version this service serves. A key may do only what `grants` names (TRA-619), each a permission the issuer holds in the org and the account's role template carries, and only while that template still carries it: a key granted nothing calls nothing.

Contract

shape
entity
authority
act
evidence
none
subscription
false
permission
any one of: org.admin (carried by the caller's role template in the org `org_id`); api_key.read (carried by the caller's role template in the org `org_id`); a deactivated caller is refused first
idempotency
keyed
emits
api_key.created
MCP tool
none
decision_set
approve, reject
REST
POST https://api.containertradehq.com/v1/cap/create_api_key

Idempotency: keyed by the caller's Idempotency-Key, which is required: the same key and inputs replay the first result, the same key with other inputs is 409 idempotency_key_reused

Inputs

nametyperequiredvalidation
org_idorg_idrequiredtradehq-org-id; 1 to 20 characters
The live org the key acts for.
nametextrequired1 to 80 characters
What the key is for, such as the integration that holds it.
service_account_idtextrequired1 to 14 characters
The service account that owns the key: an active account of this org, made with create_service_account. The key acts as it.
modeone_ofoptionalone of live, test
The service account's mode, which is the default: live for an sk_live_ key, test for an sk_test_ key that reaches the org's test twin. A mode other than the account's is refused.
api_versionone_ofoptionalone of 2026-10-01
The API version to pin the key to. Defaults to the version current today.
grantspermissionsoptionalunique
What the key may do (TRA-619): org.member, role.read or api_key.read, each one you hold in the org and the service account's role template carries. Absent or empty, the key is granted nothing.
expires_in_daysintegeroptional1 to 3650
Days until the key stops working. Absent, it works until it is revoked or rotated.

Response

  • key_id · string · The key's id, its public part.
  • org_id · string · The live org it was issued on.
  • name · string · What it is for.
  • service_account_id · stringnull · The service account that owns the key and that it acts as (TRA-493); null only for a BK_ key the core issued.
  • kind · string · sk for a key this plane issued, legacy for a BK_ key.
  • mode · string · live, or test for a key that reaches the test twin.
  • status · string · active; expiring when it has an expiry still ahead, as a rotated key does in its overlap; expired; or revoked.
  • display · string · The key's prefix and id, safe to show anywhere. Never the secret.
  • created_at · string · When it was issued.
  • created_by · stringnull · Who issued it.
  • expires_at · stringnull · When it stops working, if it does.
  • revoked_at · stringnull · When it was revoked.
  • api_version · stringnull · The API version it is pinned to; null for a BK_ key, which follows the current version.
  • requests_per_minute · integernull · Its per-minute limit, or null for none.
  • requests_per_day · integernull · Its per-day limit, or null for none.
  • rotated_from · stringnull · The key it succeeded.
  • rotated_to · stringnull · The key that succeeded it.
  • grants · string[] · What the key was granted (TRA-619), in name order: the permissions it may use, each only while its service account's role template carries it. Empty for a key granted nothing and for a BK_ key.
  • secret · stringnull · The whole key, on the call that issued it and never again: it is stored nowhere, so a replay answers null.
Full JSON Schema
{
  "type": "object",
  "properties": {
    "key_id": {
      "type": "string",
      "description": "The key's id, its public part.",
      "x-data-class": "operational"
    },
    "org_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20,
      "pattern": "^[A-Za-z0-9_-]{1,20}$",
      "format": "tradehq-org-id",
      "description": "The live org it was issued on.",
      "x-data-class": "operational"
    },
    "name": {
      "type": "string",
      "description": "What it is for.",
      "x-data-class": "operational"
    },
    "service_account_id": {
      "type": [
        "string",
        "null"
      ],
      "description": "The service account that owns the key and that it acts as (TRA-493); null only for a BK_ key the core issued.",
      "x-data-class": "operational"
    },
    "kind": {
      "type": "string",
      "enum": [
        "sk",
        "legacy"
      ],
      "description": "sk for a key this plane issued, legacy for a BK_ key.",
      "x-data-class": "operational"
    },
    "mode": {
      "type": "string",
      "enum": [
        "live",
        "test"
      ],
      "description": "live, or test for a key that reaches the test twin.",
      "x-data-class": "operational"
    },
    "status": {
      "type": "string",
      "enum": [
        "active",
        "expiring",
        "expired",
        "revoked"
      ],
      "description": "active; expiring when it has an expiry still ahead, as a rotated key does in its overlap; expired; or revoked.",
      "x-data-class": "operational"
    },
    "display": {
      "type": "string",
      "description": "The key's prefix and id, safe to show anywhere. Never the secret.",
      "x-data-class": "operational"
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "description": "When it was issued.",
      "x-data-class": "operational"
    },
    "created_by": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 20,
      "pattern": "^[A-Za-z0-9_-]{1,20}$",
      "format": "tradehq-user-id",
      "description": "Who issued it.",
      "x-data-class": "operational"
    },
    "expires_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "When it stops working, if it does.",
      "x-data-class": "operational"
    },
    "revoked_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "When it was revoked.",
      "x-data-class": "operational"
    },
    "api_version": {
      "type": [
        "string",
        "null"
      ],
      "description": "The API version it is pinned to; null for a BK_ key, which follows the current version.",
      "x-data-class": "operational"
    },
    "requests_per_minute": {
      "type": [
        "integer",
        "null"
      ],
      "description": "Its per-minute limit, or null for none.",
      "x-data-class": "operational"
    },
    "requests_per_day": {
      "type": [
        "integer",
        "null"
      ],
      "description": "Its per-day limit, or null for none.",
      "x-data-class": "operational"
    },
    "rotated_from": {
      "type": [
        "string",
        "null"
      ],
      "description": "The key it succeeded.",
      "x-data-class": "operational"
    },
    "rotated_to": {
      "type": [
        "string",
        "null"
      ],
      "description": "The key that succeeded it.",
      "x-data-class": "operational"
    },
    "grants": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "What the key was granted (TRA-619), in name order: the permissions it may use, each only while its service account's role template carries it. Empty for a key granted nothing and for a BK_ key.",
      "x-data-class": "operational"
    },
    "secret": {
      "type": [
        "string",
        "null"
      ],
      "description": "The whole key, on the call that issued it and never again: it is stored nowhere, so a replay answers null.",
      "x-data-class": "operational"
    }
  },
  "required": [
    "key_id",
    "org_id",
    "name",
    "service_account_id",
    "kind",
    "mode",
    "status",
    "display",
    "created_at",
    "created_by",
    "expires_at",
    "revoked_at",
    "api_version",
    "requests_per_minute",
    "requests_per_day",
    "rotated_from",
    "rotated_to",
    "grants",
    "secret"
  ],
  "additionalProperties": false
}

Refusals

not yet declared

The platform refusals apply to every call: version, authentication, authority, validation and rate limits, each in the same envelope.

Surfaces

DesktopF
MobileD5
APIF
MCPN
VoiceN
PushF
OneBoxN
OutboundN
  • Mobile: degraded: composition
  • MCP: the answer carries a secret, which is never handed to an agent
  • Voice: the answer carries a secret, which is never read aloud
  • OneBox: no document originates an API key
  • Outbound: crosses to no counterparty

Events

Related

create_service_account, disable_service_account, get_api_usage, get_view_default, list_saved_views, save_view, set_api_key_version, set_my_view_default, set_org_view_default, update_service_account