API Keys
Create, list, rotate, and revoke tenant API keys. All of these endpoints require a key with the admin scope. This is also the only way to mint narrow-scoped keys — the Settings → API Keys screen creates coarse single-scope keys, while this API accepts any combination from the full scope vocabulary. See Authentication for how the scopes expand.
Accepted scopes values:
read— coarse: read everything the coarse v1 surface exposes.commerce— coarse:readplus the cart/checkout commerce surface.admin— coarse: everything, including every narrow scope below.journeys:read— read journeys.journeys:write— create and edit journeys (impliesjourneys:read).journeys:publish— publish, deactivate, or delete live journeys (impliesjourneys:read).journeys:delete— delete draft or archived journeys (impliesjourneys:read).pages:read— read pages.pages:write— create and edit pages (impliespages:read).pages:publish— publish or unpublish pages (impliespages:read).pages:delete— delete pages (impliespages:read).components:read— read components.components:write— create and edit components (impliescomponents:read).components:delete— delete components (impliescomponents:read).
Reserved (accepted on create, no endpoint requires them yet): productsets:read/write/delete, rules:read/write/delete, catalog:read (the one narrow read that coarse read/commerce keys expand to), and catalog:write-native.
Endpoints
GET /api/v1/api-keys
Scoped secret API key — send an sk_live_… value (keys issued before the typed format carry a bare pk_<hex> prefix and are also secret; they still work). A publishable pk_live_…/pk_test_… key is browser-safe, carries no scopes, and is refused by every endpoint in this spec with publishable_key_not_allowed. Coarse scopes: read, commerce, admin (admin covers everything below). Narrow per-resource scopes: journeys|pages :read|write|publish|delete, productsets :read|write|publish|delete, components|rules :read|write|delete, context :read (read-only context tier), catalog :read|write-native. publish is never implied by write.
Max items to return (1–100, default 20)
20Number of items to skip (default 0)
0Include revoked keys in the response
falsePaginated list of API key records (no secrets)
An API key record (secret is never returned except at create/rotate time)
First 10 characters of the key for identification
GET /api/v1/api-keys HTTP/1.1
Host: api.peakcommerce.app
X-API-Key: YOUR_API_KEY
Accept: */*
Paginated list of API key records (no secrets)
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"keyPrefix": "text",
"scopes": [
"read"
],
"rateLimitTier": "standard",
"isActive": true,
"revokedAt": "2026-01-01T00:00:00.000Z",
"lastUsedAt": "2026-01-01T00:00:00.000Z",
"expiresAt": "2026-01-01T00:00:00.000Z",
"createdAt": "2026-01-01T00:00:00.000Z"
}Notes, examples, or caveats for GET /api-keys go here.
POST /api/v1/api-keys
Scoped secret API key — send an sk_live_… value (keys issued before the typed format carry a bare pk_<hex> prefix and are also secret; they still work). A publishable pk_live_…/pk_test_… key is browser-safe, carries no scopes, and is refused by every endpoint in this spec with publishable_key_not_allowed. Coarse scopes: read, commerce, admin (admin covers everything below). Narrow per-resource scopes: journeys|pages :read|write|publish|delete, productsets :read|write|publish|delete, components|rules :read|write|delete, context :read (read-only context tier), catalog :read|write-native. publish is never implied by write.
Idempotency key to prevent duplicate key creation
standardPossible values: API key created — includes one-time plaintext secret
Response from creating or rotating an API key — includes the one-time plaintext secret
Validation error
POST /api/v1/api-keys HTTP/1.1
Host: api.peakcommerce.app
X-API-Key: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 99
{
"name": "text",
"scopes": [
"read"
],
"rateLimitTier": "standard",
"expiresAt": "2026-01-01T00:00:00.000Z"
}{
"data": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"keyPrefix": "text",
"scopes": [
"read"
],
"rateLimitTier": "standard",
"isActive": true,
"revokedAt": "2026-01-01T00:00:00.000Z",
"lastUsedAt": "2026-01-01T00:00:00.000Z",
"expiresAt": "2026-01-01T00:00:00.000Z",
"createdAt": "2026-01-01T00:00:00.000Z",
"secret": "text"
},
"meta": {
"secretNote": "text",
"replacedKeyId": "text"
},
"requestId": "text"
}scopes is an array drawn from the values listed in the overview above (defaults to ["read"]). One key may hold several narrow scopes — e.g. ["journeys:read", "journeys:write", "pages:read"]. Remember publish is never implied by write: grant it explicitly only to keys that should change what is live. Narrow-scoped keys appear on the Settings → API Keys screen but are edited through this API so their grants aren't collapsed by the screen's single-scope picker.
DELETE /api/v1/api-keys/{id}
Scoped secret API key — send an sk_live_… value (keys issued before the typed format carry a bare pk_<hex> prefix and are also secret; they still work). A publishable pk_live_…/pk_test_… key is browser-safe, carries no scopes, and is refused by every endpoint in this spec with publishable_key_not_allowed. Coarse scopes: read, commerce, admin (admin covers everything below). Narrow per-resource scopes: journeys|pages :read|write|publish|delete, productsets :read|write|publish|delete, components|rules :read|write|delete, context :read (read-only context tier), catalog :read|write-native. publish is never implied by write.
API key revoked
No content
Key not found
DELETE /api/v1/api-keys/{id} HTTP/1.1
Host: api.peakcommerce.app
X-API-Key: YOUR_API_KEY
Accept: */*
No content
Notes, examples, or caveats for DELETE /api-keys/{id} go here.
PATCH /api/v1/api-keys/{id}
Grants or removes scopes on an existing key without minting a new credential, e.g. adding handoffs:redeem to a key an app already uses. Audited with the old and new scopes. A revoked key cannot be edited.
Scoped secret API key — send an sk_live_… value (keys issued before the typed format carry a bare pk_<hex> prefix and are also secret; they still work). A publishable pk_live_…/pk_test_… key is browser-safe, carries no scopes, and is refused by every endpoint in this spec with publishable_key_not_allowed. Coarse scopes: read, commerce, admin (admin covers everything below). Narrow per-resource scopes: journeys|pages :read|write|publish|delete, productsets :read|write|publish|delete, components|rules :read|write|delete, context :read (read-only context tier), catalog :read|write-native. publish is never implied by write.
The key's complete new scope list
Updated key (no secret)
No content
Validation failed
API key not found
API key is revoked
PATCH /api/v1/api-keys/{id} HTTP/1.1
Host: api.peakcommerce.app
X-API-Key: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 33
{
"name": "text",
"scopes": [
"text"
]
}No content
Notes, examples, or caveats for PATCH /api-keys/{id} go here.
POST /api/v1/api-keys/{id}/rotate
Rotate an API key — revokes the old key and creates a new one with the same name and scopes. The new plaintext secret is returned only in this response.
Scoped secret API key — send an sk_live_… value (keys issued before the typed format carry a bare pk_<hex> prefix and are also secret; they still work). A publishable pk_live_…/pk_test_… key is browser-safe, carries no scopes, and is refused by every endpoint in this spec with publishable_key_not_allowed. Coarse scopes: read, commerce, admin (admin covers everything below). Narrow per-resource scopes: journeys|pages :read|write|publish|delete, productsets :read|write|publish|delete, components|rules :read|write|delete, context :read (read-only context tier), catalog :read|write-native. publish is never implied by write.
New API key issued — includes one-time plaintext secret
Response from creating or rotating an API key — includes the one-time plaintext secret
Key not found
Key is already revoked
POST /api/v1/api-keys/{id}/rotate HTTP/1.1
Host: api.peakcommerce.app
X-API-Key: YOUR_API_KEY
Accept: */*
{
"data": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"keyPrefix": "text",
"scopes": [
"read"
],
"rateLimitTier": "standard",
"isActive": true,
"revokedAt": "2026-01-01T00:00:00.000Z",
"lastUsedAt": "2026-01-01T00:00:00.000Z",
"expiresAt": "2026-01-01T00:00:00.000Z",
"createdAt": "2026-01-01T00:00:00.000Z",
"secret": "text"
},
"meta": {
"secretNote": "text",
"replacedKeyId": "text"
},
"requestId": "text"
}Rotation preserves the key's full scope set — including narrow scopes — so it is always safe for narrow-scoped keys.
Last updated
Was this helpful?
