MethodPathSummaryAuth
GET/v1/account/api-keysList API keys owned by the current tenant userSession
POST/v1/account/api-keysCreate and activate an API key for the current tenant userSession
GET/v1/account/api-keys/{key_id}Get API key metadata owned by the current tenant userSession
PATCH/v1/account/api-keys/{key_id}Update API key metadataSession
POST/v1/account/api-keys/{key_id}/activateActivate a pending API key and issue its secretSession
POST/v1/account/api-keys/{key_id}/revokeRevoke an API keySession
POST/v1/account/api-keys/{key_id}/rotateRotate an active API key secretSession
GET/v1/account/balanceRead the active tenant CNY balanceSession
GET/v1/account/inboxList the tenant member's in-app messages (站内信), newest firstSession
POST/v1/account/inbox/read-allMark all the caller's in-app messages read (audited admin.inbox.read_all); read messages older than 180 days are prunedSession
GET/v1/account/inbox/unread-countUnread message count for the header badgeSession
POST/v1/account/inbox/{message_id}/readMark one message readSession
GET/v1/account/ledgerList immutable entries for the active tenant CNY balanceSession
GET/v1/account/messagesList the current user's in-app messagesSession
POST/v1/account/messages/{event_id}/deliveredMark an in-app message deliveredSession
POST/v1/account/messages/{event_id}/readMark an in-app message readSession
GET/v1/account/mfaRead the authenticated account's current MFA stateSession
POST/v1/account/mfa/disableDisable active MFA after strong reauthenticationSession
POST/v1/account/mfa/enrollmentsBegin TOTP enrollmentSession
POST/v1/account/mfa/enrollments/{credential_id}/activateActivate a pending TOTP credentialSession
POST/v1/account/mfa/resetReset active MFA after strong reauthenticationSession
POST/v1/account/mfa/step-up-proofsCreate a short-lived bound step-up proofSession
GET/v1/account/notification-messagesList the current user's own event messagesSession
GET/v1/account/notification-subscriptions/{event_type}Read the current user's event subscriptionSession
PUT/v1/account/notification-subscriptions/{event_type}Update the current user's event subscriptionSession
GET/v1/account/ordersList tenant consumption recordsSession
POST/v1/account/passwordRe-authenticate and change the current tenant user's passwordSession
GET/v1/account/profileGet the current tenant user's profileSession
PATCH/v1/account/profileUpdate the current tenant user's profileSession
GET/v1/account/statementList the caller's merged consumption statement (orders, recharges and balance ledger entries)Session

Contract file:api/openapi/v1/control.yaml api/control-announcements.openapi.yaml api/control-mfa.openapi.yaml api/control-notifications.openapi.yaml api/control-account-orders.openapi.yaml

Operation details

GET /v1/account/api-keys

List API keys owned by the current tenant user

operationId
listSelfAPIKeys
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Session-only endpoint requiring api_keys.self.manage. CdncaKey credentials are rejected. Each item includes the exact persisted IP allowlist; secret material is never returned.

Parameters

listSelfAPIKeys Parameters
NameInTypeRequiredDescription
limitqueryintegerNo—
statusquerystring: pending_activation / active / revokedNo—
namequerystringNo—
key_idquerystringNo—
cursorquerystringNo—
offsetqueryintegerNoPage-number access (canonical non-negative integer, 0-10000). Cannot be combined with cursor; an offset past the end returns empty items with total.
usablequerystring: trueNoOnly `true` is accepted. Keeps keys that can authenticate at the page snapshot: status active and expires_at absent or later than snapshot_at. An expired key keeps its active lifecycle status as history, so status=active alone does not mean usable. Combinable only with status=active or no status. Clients judge expiry against the response Date header (server clock), not their own clock.

Responses

listSelfAPIKeys Responses
StatusDescription
200API key metadata only; secret material is never returned.

Fields:items: array<APIKey> next_cursor: string has_more: boolean total?: integer

400Malformed JSON, UUID, revision, CIDR, duplicate or overlapping prefix, or more than 32 prefixes. Validation params expose only field indexes and counts, never any submitted CIDR, secret, digest, or matching prefix.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

POST /v1/account/api-keys

Create and activate an API key for the current tenant user

operationId
createSelfAPIKey
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Session-only endpoint requiring api_keys.self.manage. The secret is returned in this response only. A replay with the same identity, request, and Idempotency-Key deterministically returns the same secret. An unknown result must be retried with the unchanged body, If-Match revision, and Idempotency-Key.

Parameters

createSelfAPIKey Parameters
NameInTypeRequiredDescription
Idempotency-KeyheaderstringYes—
If-MatchheaderstringYesCollection creation precondition. Must be the quoted revision zero value.

Request body

application/json · Required:Yes

createSelfAPIKey Request body
NameTypeRequiredDescription
namestringYes—
scopesarray<string>Yes—
ip_allowlistarray<string>NoCanonical network CIDRs only: no host bits, zones, IPv4-mapped IPv6, duplicate prefixes, or overlaps. Empty means unrestricted.
expires_atstring(date-time)NoMust be in the future and no more than 366 days from the server clock.

Responses

createSelfAPIKey Responses
StatusDescription
201Active key and its one-time secret.

Fields:key: APIKey secret: string(password)

400Malformed JSON, UUID, revision, CIDR, duplicate or overlapping prefix, or more than 32 prefixes. Validation params expose only field indexes and counts, never any submitted CIDR, secret, digest, or matching prefix.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
409The requested state conflicts with an existing resource or idempotency fact.
503A required dependency is unavailable.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

GET /v1/account/api-keys/{key_id}

Get API key metadata owned by the current tenant user

operationId
getSelfAPIKey
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Session-only endpoint requiring api_keys.self.manage. The exact persisted IP allowlist is returned; secret material is never returned.

Parameters

getSelfAPIKey Parameters
NameInTypeRequiredDescription
key_idpathstring(uuid)Yes—

Responses

getSelfAPIKey Responses
StatusDescription
200Current API key metadata.

Fields:id: string(uuid) key_id: string key_prefix: string scope_id: string(uuid) tenant_id: string(uuid) user_id: string(uuid) name: string scopes: array<string> unavailable_scopes?: array<string> ip_allowlist: array<string> status: string: pending_activation / active / revoked pending_expires_at?: string(date-time) expires_at?: string(date-time) last_used_at?: string(date-time) activated_at?: string(date-time) revoked_at?: string(date-time) revision: integer(int64) created_at: string(date-time) updated_at: string(date-time)

400Malformed JSON, UUID, revision, CIDR, duplicate or overlapping prefix, or more than 32 prefixes. Validation params expose only field indexes and counts, never any submitted CIDR, secret, digest, or matching prefix.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
404The requested resource was not found.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

PATCH /v1/account/api-keys/{key_id}

Update API key metadata

operationId
updateSelfAPIKey
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Session-only endpoint. Revoked keys cannot be updated. An unknown result must be retried with the unchanged body, If-Match revision, and Idempotency-Key.

Parameters

updateSelfAPIKey Parameters
NameInTypeRequiredDescription
key_idpathstring(uuid)Yes—
Idempotency-KeyheaderstringYes—
If-MatchheaderstringYes—

Request body

application/json · Required:Yes

updateSelfAPIKey Request body
NameTypeRequiredDescription
namestringYes—
scopesarray<string>Yes—
ip_allowlistarray<string>NoCanonical network CIDRs only: no host bits, zones, IPv4-mapped IPv6, duplicate prefixes, or overlaps. Empty means unrestricted.
expires_atstring(date-time)NoMust be in the future and no more than 366 days from the server clock.

Responses

updateSelfAPIKey Responses
StatusDescription
200Updated metadata.

Fields:id: string(uuid) key_id: string key_prefix: string scope_id: string(uuid) tenant_id: string(uuid) user_id: string(uuid) name: string scopes: array<string> unavailable_scopes?: array<string> ip_allowlist: array<string> status: string: pending_activation / active / revoked pending_expires_at?: string(date-time) expires_at?: string(date-time) last_used_at?: string(date-time) activated_at?: string(date-time) revoked_at?: string(date-time) revision: integer(int64) created_at: string(date-time) updated_at: string(date-time)

400Malformed JSON, UUID, revision, CIDR, duplicate or overlapping prefix, or more than 32 prefixes. Validation params expose only field indexes and counts, never any submitted CIDR, secret, digest, or matching prefix.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
404The requested resource was not found.
409The requested state conflicts with an existing resource or idempotency fact.
503A required dependency is unavailable.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

POST /v1/account/api-keys/{key_id}/activate

Activate a pending API key and issue its secret

operationId
activateSelfAPIKey
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Session-only endpoint for the key owner. Only an unexpired pending_activation key can be activated; the secret is returned in this response only. The body carries the exact persisted IP allowlist. An unknown result must be retried with the unchanged body, If-Match revision, and Idempotency-Key.

Parameters

activateSelfAPIKey Parameters
NameInTypeRequiredDescription
key_idpathstring(uuid)Yes—
Idempotency-KeyheaderstringYes—
If-MatchheaderstringYes—

Request body

application/json · Required:Yes

activateSelfAPIKey Request body
NameTypeRequiredDescription
ip_allowlistarray<string>YesCanonical network CIDRs only: no host bits, zones, IPv4-mapped IPv6, duplicate prefixes, or overlaps. Empty means unrestricted.
grant_all_scopesbooleanNoRotate only. When true, the rotation also replaces the key scopes with every permission the current session may grant to an API key (the simple-mode "reset key"). It is part of the idempotency binding. Other operations reject true with 400 invalid_request.

Responses

activateSelfAPIKey Responses
StatusDescription
200Activated key and one-time secret.

Fields:key: APIKey secret: string(password)

400Malformed JSON, UUID, revision, CIDR, duplicate or overlapping prefix, or more than 32 prefixes. Validation params expose only field indexes and counts, never any submitted CIDR, secret, digest, or matching prefix.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
404The requested resource was not found.
409The requested state conflicts with an existing resource or idempotency fact.
503A required dependency is unavailable.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

POST /v1/account/api-keys/{key_id}/revoke

Revoke an API key

operationId
revokeSelfAPIKey
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Session-only endpoint. Revocation immediately prevents future API key authentication. The body carries the exact persisted IP allowlist. An unknown result must be retried with the unchanged body, If-Match revision, and Idempotency-Key.

Parameters

revokeSelfAPIKey Parameters
NameInTypeRequiredDescription
key_idpathstring(uuid)Yes—
Idempotency-KeyheaderstringYes—
If-MatchheaderstringYes—

Request body

application/json · Required:Yes

revokeSelfAPIKey Request body
NameTypeRequiredDescription
ip_allowlistarray<string>YesCanonical network CIDRs only: no host bits, zones, IPv4-mapped IPv6, duplicate prefixes, or overlaps. Empty means unrestricted.
grant_all_scopesbooleanNoRotate only. When true, the rotation also replaces the key scopes with every permission the current session may grant to an API key (the simple-mode "reset key"). It is part of the idempotency binding. Other operations reject true with 400 invalid_request.

Responses

revokeSelfAPIKey Responses
StatusDescription
200Revoked key metadata.

Fields:id: string(uuid) key_id: string key_prefix: string scope_id: string(uuid) tenant_id: string(uuid) user_id: string(uuid) name: string scopes: array<string> unavailable_scopes?: array<string> ip_allowlist: array<string> status: string: pending_activation / active / revoked pending_expires_at?: string(date-time) expires_at?: string(date-time) last_used_at?: string(date-time) activated_at?: string(date-time) revoked_at?: string(date-time) revision: integer(int64) created_at: string(date-time) updated_at: string(date-time)

400Malformed JSON, UUID, revision, CIDR, duplicate or overlapping prefix, or more than 32 prefixes. Validation params expose only field indexes and counts, never any submitted CIDR, secret, digest, or matching prefix.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
404The requested resource was not found.
409The requested state conflicts with an existing resource or idempotency fact.
503A required dependency is unavailable.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

POST /v1/account/api-keys/{key_id}/rotate

Rotate an active API key secret

operationId
rotateSelfAPIKey
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Session-only endpoint. The previous credential becomes invalid when the transaction commits. The body carries the exact persisted IP allowlist. An unknown result must be retried with the unchanged body, If-Match revision, and Idempotency-Key.

Parameters

rotateSelfAPIKey Parameters
NameInTypeRequiredDescription
key_idpathstring(uuid)Yes—
Idempotency-KeyheaderstringYes—
If-MatchheaderstringYes—

Request body

application/json · Required:Yes

rotateSelfAPIKey Request body
NameTypeRequiredDescription
ip_allowlistarray<string>YesCanonical network CIDRs only: no host bits, zones, IPv4-mapped IPv6, duplicate prefixes, or overlaps. Empty means unrestricted.
grant_all_scopesbooleanNoRotate only. When true, the rotation also replaces the key scopes with every permission the current session may grant to an API key (the simple-mode "reset key"). It is part of the idempotency binding. Other operations reject true with 400 invalid_request.

Responses

rotateSelfAPIKey Responses
StatusDescription
200Updated key and one-time replacement secret.

Fields:key: APIKey secret: string(password)

400Malformed JSON, UUID, revision, CIDR, duplicate or overlapping prefix, or more than 32 prefixes. Validation params expose only field indexes and counts, never any submitted CIDR, secret, digest, or matching prefix.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
404The requested resource was not found.
409The requested state conflicts with an existing resource or idempotency fact.
503A required dependency is unavailable.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

GET /v1/account/balance

Read the active tenant CNY balance

operationId
getAccountBalance
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Requires billing.account.read in a tenant scope. A platform identity cannot use this tenant endpoint.

Responses

getAccountBalance Responses
StatusDescription
200Current cached balance and optimistic revision. The balance is reconstructable from immutable postings.

Fields:id: string(uuid) scope_id: string(uuid) tenant_id: string(uuid) tenant_name: string currency: string balance_minor: integer(int64) available_minor: integer(int64) refunding_minor: integer(int64) revision: integer(int64) created_at: string(date-time) updated_at: string(date-time)

401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
404The requested resource was not found.
500The request could not be completed because of an internal failure.

What to do on failure

  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

GET /v1/account/inbox

List the tenant member's in-app messages (站内信), newest first

operationId
listAccountInbox
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Tenant in-app notices addressed to the caller in the session's tenant scope (attack escalation security.escalate.blackhole once the blackhole is in force, security.escalate.cname_change_required). Written whatever the platform email/SMS settings say. Tenant-scope sessions only (platform sessions use /v1/admin/inbox). params holds the event's public template values; the console renders the text per language.

Parameters

listAccountInbox Parameters
NameInTypeRequiredDescription
unreadquerystring: trueNo—
page_sizequeryintegerNo—
cursorquerystringNo—

Responses

listAccountInbox Responses
StatusDescription
200One page.

Fields:items: array<object> unread: integer total: integer next_cursor: string unread_only: boolean page_size: integer

401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.

What to do on failure

  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.

↑ Back to list

POST /v1/account/inbox/read-all

Mark all the caller's in-app messages read (audited admin.inbox.read_all); read messages older than 180 days are pruned

operationId
markAllAccountInboxMessagesRead
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Responses

markAllAccountInboxMessagesRead Responses
StatusDescription
200Number of messages marked.

Fields:marked: integer

↑ Back to list

GET /v1/account/inbox/unread-count

Unread message count for the header badge

operationId
getAccountInboxUnreadCount
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Responses

getAccountInboxUnreadCount Responses
StatusDescription
200Count.

Fields:unread: integer

401Authentication failed or the session is invalid.

What to do on failure

  • 401 Check the credential format and whether it expired or was rotated.

↑ Back to list

POST /v1/account/inbox/{message_id}/read

Mark one message read

operationId
markAccountInboxMessageRead
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Parameters

markAccountInboxMessageRead Parameters
NameInTypeRequiredDescription
message_idpathstring(uuid)Yes—

Responses

markAccountInboxMessageRead Responses
StatusDescription
204Read.
404admin_inbox_message_not_found (not the caller's message).

What to do on failure

  • 404 The resource does not exist or belongs to another tenant.

↑ Back to list

GET /v1/account/ledger

List immutable entries for the active tenant CNY balance

operationId
listAccountLedger
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Requires billing.account.read and always derives scope from the authenticated tenant principal.

Parameters

listAccountLedger Parameters
NameInTypeRequiredDescription
pagequeryintegerNo—
limitqueryintegerNo—

Responses

listAccountLedger Responses
StatusDescription
200Newest-first tenant ledger page.

Fields:items: array<BillingLedgerEntry> total: integer(int64) page: integer limit: integer

400The request body or parameters are invalid.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

GET /v1/account/messages

List the current user's in-app messages

operationId
listAccountMessages
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Parameters

listAccountMessages Parameters
NameInTypeRequiredDescription
limitqueryintegerNo—
cursorquerystringNo—
offsetqueryintegerNoPage by position (page-number pagination). Cannot be combined with cursor.
filterquerystring: read / unreadNo—

Responses

listAccountMessages Responses
StatusDescription
200Inbox page

Fields:items: array<InboxMessage> next_cursor?: string total?: integer

400Stable API error
401Stable API error
403Stable API error
500Stable API error

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

POST /v1/account/messages/{event_id}/delivered

Mark an in-app message delivered

operationId
markMessageDelivered
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Parameters

markMessageDelivered Parameters
NameInTypeRequiredDescription
event_idpathstring(uuid)Yes—
Idempotency-KeyheaderstringYes—
If-MatchheaderstringYes—

Request body

application/json · Required:Yes

markMessageDelivered Request body
NameTypeRequiredDescription
expected_revisionintegerYes—

Responses

markMessageDelivered Responses
StatusDescription
200Inbox state

Fields:event_id: string(uuid) delivered_at?: string(date-time) read_at?: string(date-time) revision: integer replayed?: boolean

400Stable API error
401Stable API error
403Stable API error
404Stable API error
409Stable API error
415Stable API error
500Stable API error

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

POST /v1/account/messages/{event_id}/read

Mark an in-app message read

operationId
markMessageRead
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Parameters

markMessageRead Parameters
NameInTypeRequiredDescription
event_idpathstring(uuid)Yes—
Idempotency-KeyheaderstringYes—
If-MatchheaderstringYes—

Request body

application/json · Required:Yes

markMessageRead Request body
NameTypeRequiredDescription
expected_revisionintegerYes—

Responses

markMessageRead Responses
StatusDescription
200Inbox state

Fields:event_id: string(uuid) delivered_at?: string(date-time) read_at?: string(date-time) revision: integer replayed?: boolean

400Stable API error
401Stable API error
403Stable API error
404Stable API error
409Stable API error
415Stable API error
500Stable API error

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

GET /v1/account/mfa

Read the authenticated account's current MFA state

operationId
getMyMFAStatus
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Returns only inactive, enrollment_pending, or active plus non-sensitive credential metadata. No account label, seed, ciphertext, recovery code, or proof material is returned.

Parameters

getMyMFAStatus Parameters
NameInTypeRequiredDescription
X-Request-IDheaderstringYes—
TraceparentheaderstringYesCanonical W3C version 00 traceparent; the non-zero trace ID is used for correlation.

Responses

getMyMFAStatus Responses
StatusDescription
200Current non-sensitive MFA state.
400Request metadata, path, query, body, or input is invalid
401Bearer session is absent, malformed, expired, revoked, or disabled
403Live principal, tenant, permissions, or proof binding changed
405Request method is not allowed.
408Request was canceled
503MFA, encryption, identity, IAM, or PostgreSQL dependency is unavailable
504Request deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

POST /v1/account/mfa/disable

Disable active MFA after strong reauthentication

operationId
disableMyMFA
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

A TOTP or unused recovery code is consumed in the same transaction as the immutable terminal fact and audit event. A same-payload Idempotency-Key retry is safe after an unknown commit result and returns 204 without re-consuming authentication evidence.

Request body

application/json · Required:Yes

disableMyMFA Request body
NameTypeRequiredDescription
authenticationAuthenticationYes—
reasonstringYes—

Responses

disableMyMFA Responses
StatusDescription
204Terminal fact already exists or was committed by this request.
400Request metadata, path, query, body, or input is invalid
401Bearer session is absent, malformed, expired, revoked, or disabled
403Live principal, tenant, permissions, or proof binding changed
405Request method is not allowed.
409Idempotency, lifecycle, code replay, or bounded-use conflict
412Active MFA is required
413Request body exceeds the configured limit
422MFA code or proof is invalid
408Request was canceled
503MFA, encryption, identity, IAM, or PostgreSQL dependency is unavailable
504Request deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 412 The revision changed: read the latest ETag, decide again, then send the new If-Match.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

POST /v1/account/mfa/enrollments

Begin TOTP enrollment

operationId
beginMyMFAEnrollment
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

A first successful response contains the seed and provisioning URI. A same-payload Idempotency-Key replay returns only credential_id, expires_at, and replayed=true; the service does not decrypt or reconstruct setup material during replay.

Parameters

beginMyMFAEnrollment Parameters
NameInTypeRequiredDescription
Idempotency-KeyheaderstringYes—
X-Request-IDheaderstringYes—
TraceparentheaderstringYesCanonical W3C version 00 traceparent; the non-zero trace ID is used for correlation.

Request body

application/json · Required:Yes

beginMyMFAEnrollment Request body
NameTypeRequiredDescription
account_labelstringYes—

Responses

beginMyMFAEnrollment Responses
StatusDescription
201Enrollment created; secret and provisioning_uri are present exactly once.

Fields:credential_id: string(uuid) secret: string provisioning_uri: string(uri) expires_at: string(date-time) replayed: const false

200Enrollment replayed; secret and provisioning_uri are absent.

Fields:credential_id: string(uuid) expires_at: string(date-time) replayed: const true

400Request metadata, path, query, body, or input is invalid
401Bearer session is absent, malformed, expired, revoked, or disabled
403Live principal, tenant, permissions, or proof binding changed
405Request method is not allowed.
409Idempotency, lifecycle, code replay, or bounded-use conflict
413Request body exceeds the configured limit
408Request was canceled
503MFA, encryption, identity, IAM, or PostgreSQL dependency is unavailable
504Request deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

POST /v1/account/mfa/enrollments/{credential_id}/activate

Activate a pending TOTP credential

operationId
activateMyMFAEnrollment
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Recovery codes are returned only by the first successful activation. They are omitted entirely from a same-payload Idempotency-Key replay.

Parameters

activateMyMFAEnrollment Parameters
NameInTypeRequiredDescription
credential_idpathstring(uuid)Yes—
Idempotency-KeyheaderstringYes—
X-Request-IDheaderstringYes—
TraceparentheaderstringYesCanonical W3C version 00 traceparent; the non-zero trace ID is used for correlation.

Request body

application/json · Required:Yes

activateMyMFAEnrollment Request body
NameTypeRequiredDescription
codestringYes—

Responses

activateMyMFAEnrollment Responses
StatusDescription
201Enrollment activated; recovery_codes are present exactly once.

Fields:credential_id: string(uuid) recovery_codes: array<string> activated_at: string(date-time) replayed: const false

200Activation replayed; recovery_codes are absent.

Fields:credential_id: string(uuid) activated_at: string(date-time) replayed: const true

400Request metadata, path, query, body, or input is invalid
401Bearer session is absent, malformed, expired, revoked, or disabled
403Live principal, tenant, permissions, or proof binding changed
405Request method is not allowed.
409Idempotency, lifecycle, code replay, or bounded-use conflict
410Enrollment or proof expired
413Request body exceeds the configured limit
422MFA code or proof is invalid
408Request was canceled
503MFA, encryption, identity, IAM, or PostgreSQL dependency is unavailable
504Request deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

POST /v1/account/mfa/reset

Reset active MFA after strong reauthentication

operationId
resetMyMFA
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Reset has the same atomic authentication, terminal-fact, audit, idempotency, and unknown commit semantics as disable. Account recovery without a TOTP or recovery code is a separate audited workflow and is not represented by this operation.

Request body

application/json · Required:Yes

resetMyMFA Request body
NameTypeRequiredDescription
authenticationAuthenticationYes—
reasonstringYes—

↑ Back to list

POST /v1/account/mfa/step-up-proofs

Create a short-lived bound step-up proof

operationId
createMyMFAStepUpProof
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

The proof is bound server-side to the authenticated user, scope, session, live permissions, tenant, audience, and action. The opaque token is returned only once and is omitted from replay. There is no client-accessible proof consume operation.

Request body

application/json · Required:Yes

createMyMFAStepUpProof Request body
NameTypeRequiredDescription
tenant_idstring(uuid)Yes—
audiencestringYes—
actionstringYes—
authenticationAuthenticationYes—
ttl_secondsintegerYes—
max_usesintegerYes—

Responses

createMyMFAStepUpProof Responses
StatusDescription
201Step-up proof created; token is present exactly once.

Fields:proof_id: string(uuid) token: string method: string: totp / recovery_code issued_at: string(date-time) expires_at: string(date-time) max_uses: integer replayed: const false

200Step-up proof replayed; token is absent.

Fields:proof_id: string(uuid) method: string: totp / recovery_code issued_at: string(date-time) expires_at: string(date-time) max_uses: integer replayed: const true

400Request metadata, path, query, body, or input is invalid
401Bearer session is absent, malformed, expired, revoked, or disabled
403Live principal, tenant, permissions, or proof binding changed
405Request method is not allowed.
409Idempotency, lifecycle, code replay, or bounded-use conflict
410Enrollment or proof expired
412Active MFA is required
413Request body exceeds the configured limit
422MFA code or proof is invalid
408Request was canceled
503MFA, encryption, identity, IAM, or PostgreSQL dependency is unavailable
504Request deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 412 The revision changed: read the latest ETag, decide again, then send the new If-Match.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

GET /v1/account/notification-messages

List the current user's own event messages

operationId
listOwnNotificationMessages
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Subscribable operational events (package, traffic, protection, certificate, site) delivered to the caller in the caller's own scope. Scope and recipient come from the session; announcements stay in the announcement inbox and system-required messages are excluded. site_id and package_id are facts recorded when the event was raised and remain after the resource is deleted.

Parameters

listOwnNotificationMessages Parameters
NameInTypeRequiredDescription
typequerystringNo—
site_idquerystring(uuid)No—
package_idquerystring(uuid)No—
sitequerystringNoEvent-time site by exact display ID or case-insensitive substring of its current domain; events whose site no longer exists never match.
packagequerystringNoUser subscription by exact display ID or case-insensitive substring of the package name; events whose subscription no longer exists never match.
limitqueryintegerNo—
offsetqueryintegerNo—

Responses

listOwnNotificationMessages Responses
StatusDescription
200The caller's own event messages, newest first.

Fields:schema: string items: array<OwnMessage> total: integer

400Stable error envelope. Clients map code through locale resources and do not render message directly.
401Stable error envelope. Clients map code through locale resources and do not render message directly.
403Stable error envelope. Clients map code through locale resources and do not render message directly.
405Stable error envelope. Clients map code through locale resources and do not render message directly.
500Stable error envelope. Clients map code through locale resources and do not render message directly.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

GET /v1/account/notification-subscriptions/{event_type}

Read the current user's event subscription

operationId
getNotificationSubscription
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Parameters

getNotificationSubscription Parameters
NameInTypeRequiredDescription
event_typepathstringYes—

Responses

getNotificationSubscription Responses
StatusDescription
200Current user's subscription or an identical natural replay.

Fields:event_type: string sms_enabled: boolean email_enabled: boolean sms_supported: boolean email_supported: boolean inbox_enabled?: boolean email_bound?: boolean phone_bound?: boolean revision: integer(int64) changed: boolean

400Stable error envelope. Clients map code through locale resources and do not render message directly.
401Stable error envelope. Clients map code through locale resources and do not render message directly.
403Stable error envelope. Clients map code through locale resources and do not render message directly.
404Stable error envelope. Clients map code through locale resources and do not render message directly.
405Stable error envelope. Clients map code through locale resources and do not render message directly.
500Stable error envelope. Clients map code through locale resources and do not render message directly.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

PUT /v1/account/notification-subscriptions/{event_type}

Update the current user's event subscription

operationId
updateNotificationSubscription
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Parameters

updateNotificationSubscription Parameters
NameInTypeRequiredDescription
event_typepathstringYes—
If-MatchheaderstringYes—
X-Request-IDheaderstringNoCorrelation identifier and retry key for this write. Reusing the same value for the same authenticated actor and operation requires the exact original path, revision, and body; an exact retry replays the original response, while changed semantics return 409.

Request body

application/json · Required:Yes

updateNotificationSubscription Request body
NameTypeRequiredDescription
sms_enabledbooleanYes—
email_enabledbooleanYes—
inbox_enabledbooleanNoTicket events only (546): keep the in-app message-center copy. Omitted keeps the stored choice; any other event answers 400.

Responses

updateNotificationSubscription Responses
StatusDescription
200Current user's subscription or an identical natural replay.

Fields:event_type: string sms_enabled: boolean email_enabled: boolean sms_supported: boolean email_supported: boolean inbox_enabled?: boolean email_bound?: boolean phone_bound?: boolean revision: integer(int64) changed: boolean

400Stable error envelope. Clients map code through locale resources and do not render message directly.
401Stable error envelope. Clients map code through locale resources and do not render message directly.
403Stable error envelope. Clients map code through locale resources and do not render message directly.
404Stable error envelope. Clients map code through locale resources and do not render message directly.
405Stable error envelope. Clients map code through locale resources and do not render message directly.
409Stable error envelope. Clients map code through locale resources and do not render message directly.
415Stable error envelope. Clients map code through locale resources and do not render message directly.
500Stable error envelope. Clients map code through locale resources and do not render message directly.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

GET /v1/account/orders

List tenant consumption records

operationId
listAccountOrders
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Requires billing.account.read. Callers with billing.order_records.read (tenant_owner) see all tenant users; other callers are restricted to their own user ID. Tenant rows are never editable.

Parameters

listAccountOrders Parameters
NameInTypeRequiredDescription
pagequeryintegerNo—
limitqueryintegerNo—
typequerystring: recharge / deduction / upgrade / purchase / renewal / package_changeNo—
statusquerystring: paid / unpaidNo—
searchquerystringNoExact-page substring search over source-local display ID, UUID, user ID, username, email, or phone.
created_fromquerystring(date-time)No—
created_toquerystring(date-time)NoExclusive upper bound.

Responses

listAccountOrders Responses
StatusDescription
200Consumption record page

Fields:items: array<AccountOrder> total: integer page: integer limit: integer can_manage: boolean

400Invalid request fields
401Authentication is required
403Required permission is absent
503Account order service unavailable

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

POST /v1/account/password

Re-authenticate and change the current tenant user's password

operationId
changeAccountPassword
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Success revokes every existing session, including the session used for this request.

Request body

application/json · Required:Yes

changeAccountPassword Request body
NameTypeRequiredDescription
current_passwordstring(password)Yes—
new_passwordstring(password)Yes8 to 1024 printable ASCII characters (no space) with at least two of upper case, lower case, digits and symbols; otherwise password_policy_unmet.

Responses

changeAccountPassword Responses
StatusDescription
204Password changed and all sessions revoked. The client must sign in again.
400The request body or parameters are invalid.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
409The requested state conflicts with an existing resource or idempotency fact.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

GET /v1/account/profile

Get the current tenant user's profile

operationId
getAccountProfile
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Responses

getAccountProfile Responses
StatusDescription
200Current profile.

Fields:id: string(uuid) username: string display_name: string email: string(email) | null(email) phone: string | null revision: integer(int64) created_at: string(date-time) updated_at: string(date-time)

401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
500The request could not be completed because of an internal failure.

What to do on failure

  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

PATCH /v1/account/profile

Update the current tenant user's profile

operationId
updateAccountProfile
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Changing email or phone requires current_password. A display-name-only update remains compatible without reauthentication.

Parameters

updateAccountProfile Parameters
NameInTypeRequiredDescription
Idempotency-KeyheaderstringYes—

Request body

application/json · Required:Yes

updateAccountProfile Request body
NameTypeRequiredDescription
expected_revisioninteger(int64)Yes—
display_namestringYes—
emailstring(email) | null(email)Yes—
phonestring | nullYes—
current_passwordstring(password)NoRequired when the normalized email or phone differs from the current profile.

Responses

updateAccountProfile Responses
StatusDescription
200Profile updated, or an identical idempotent request replayed.

Fields:id: string(uuid) username: string display_name: string email: string(email) | null(email) phone: string | null revision: integer(int64) created_at: string(date-time) updated_at: string(date-time)

400The request body or parameters are invalid.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
409The requested state conflicts with an existing resource or idempotency fact.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

GET /v1/account/statement

List the caller's merged consumption statement (orders, recharges and balance ledger entries)

operationId
listAccountStatement
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Requires billing.account.read in the caller's own tenant scope. Merges manual order records, package and traffic-package orders, recharge orders and balance ledger postings that have no order row (manual adjustments, migration import credits, refund/void reversals, reseller sale/wholesale) into one newest-first page. Order-like rows are restricted to the caller's own user unless the caller holds billing.order_records.read; ledger rows belong to the tenant balance and follow the same visibility as GET /v1/account/ledger. Ledger operations that already have an order row (checkout debit, provider payment, recharge payment) are not repeated.

Parameters

listAccountStatement Parameters
NameInTypeRequiredDescription
pagequeryintegerNo—
limitqueryintegerNo—
typequerystring: recharge / deduction / upgrade / purchase / renewal / package_change / traffic_package / refund / incomeNo—
statusquerystring: paid / unpaidNo—
created_fromquerystring(date-time)No—
created_toquerystring(date-time)NoExclusive upper bound.

Responses

listAccountStatement Responses
StatusDescription
200Statement page

Fields:items: array<AccountStatementEntry> total: integer(int64) page: integer limit: integer

400Invalid request fields
401Authentication is required
403Required permission is absent
503Account order service unavailable

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list