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| Name | In | Type | Required | Description |
|---|
limit | query | integer | No | — |
|---|
status | query | string: pending_activation / active / revoked | No | — |
|---|
name | query | string | No | — |
|---|
key_id | query | string | No | — |
|---|
cursor | query | string | No | — |
|---|
offset | query | integer | No | Page-number access (canonical non-negative integer, 0-10000). Cannot be combined with cursor; an offset past the end returns empty items with total. |
|---|
usable | query | string: true | No | Only `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| Status | Description |
|---|
200 | API key metadata only; secret material is never returned. Fields:items: array<APIKey> next_cursor: string has_more: boolean total?: integer |
|---|
400 | Malformed 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. |
|---|
401 | Authentication failed or the session is invalid. |
|---|
403 | The authenticated principal is not allowed to perform the action. |
|---|
500 | The 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| Name | In | Type | Required | Description |
|---|
Idempotency-Key | header | string | Yes | — |
|---|
If-Match | header | string | Yes | Collection creation precondition. Must be the quoted revision zero value. |
|---|
Request body
application/json · Required:Yes
createSelfAPIKey Request body| Name | Type | Required | Description |
|---|
name | string | Yes | — |
|---|
scopes | array<string> | Yes | — |
|---|
ip_allowlist | array<string> | No | Canonical network CIDRs only: no host bits, zones, IPv4-mapped IPv6, duplicate prefixes, or overlaps. Empty means unrestricted. |
|---|
expires_at | string(date-time) | No | Must be in the future and no more than 366 days from the server clock. |
|---|
Responses
createSelfAPIKey Responses| Status | Description |
|---|
201 | Active key and its one-time secret. Fields:key: APIKey secret: string(password) |
|---|
400 | Malformed 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. |
|---|
401 | Authentication failed or the session is invalid. |
|---|
403 | The authenticated principal is not allowed to perform the action. |
|---|
409 | The requested state conflicts with an existing resource or idempotency fact. |
|---|
503 | A required dependency is unavailable. |
|---|
500 | The 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| Name | In | Type | Required | Description |
|---|
key_id | path | string(uuid) | Yes | — |
|---|
Responses
getSelfAPIKey Responses| Status | Description |
|---|
200 | Current 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) |
|---|
400 | Malformed 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. |
|---|
401 | Authentication failed or the session is invalid. |
|---|
403 | The authenticated principal is not allowed to perform the action. |
|---|
404 | The requested resource was not found. |
|---|
500 | The 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| Name | In | Type | Required | Description |
|---|
key_id | path | string(uuid) | Yes | — |
|---|
Idempotency-Key | header | string | Yes | — |
|---|
If-Match | header | string | Yes | — |
|---|
Request body
application/json · Required:Yes
updateSelfAPIKey Request body| Name | Type | Required | Description |
|---|
name | string | Yes | — |
|---|
scopes | array<string> | Yes | — |
|---|
ip_allowlist | array<string> | No | Canonical network CIDRs only: no host bits, zones, IPv4-mapped IPv6, duplicate prefixes, or overlaps. Empty means unrestricted. |
|---|
expires_at | string(date-time) | No | Must be in the future and no more than 366 days from the server clock. |
|---|
Responses
updateSelfAPIKey Responses| Status | Description |
|---|
200 | Updated 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) |
|---|
400 | Malformed 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. |
|---|
401 | Authentication failed or the session is invalid. |
|---|
403 | The authenticated principal is not allowed to perform the action. |
|---|
404 | The requested resource was not found. |
|---|
409 | The requested state conflicts with an existing resource or idempotency fact. |
|---|
503 | A required dependency is unavailable. |
|---|
500 | The 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| Name | In | Type | Required | Description |
|---|
key_id | path | string(uuid) | Yes | — |
|---|
Idempotency-Key | header | string | Yes | — |
|---|
If-Match | header | string | Yes | — |
|---|
Request body
application/json · Required:Yes
activateSelfAPIKey Request body| Name | Type | Required | Description |
|---|
ip_allowlist | array<string> | Yes | Canonical network CIDRs only: no host bits, zones, IPv4-mapped IPv6, duplicate prefixes, or overlaps. Empty means unrestricted. |
|---|
grant_all_scopes | boolean | No | Rotate 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| Status | Description |
|---|
200 | Activated key and one-time secret. Fields:key: APIKey secret: string(password) |
|---|
400 | Malformed 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. |
|---|
401 | Authentication failed or the session is invalid. |
|---|
403 | The authenticated principal is not allowed to perform the action. |
|---|
404 | The requested resource was not found. |
|---|
409 | The requested state conflicts with an existing resource or idempotency fact. |
|---|
503 | A required dependency is unavailable. |
|---|
500 | The 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| Name | In | Type | Required | Description |
|---|
key_id | path | string(uuid) | Yes | — |
|---|
Idempotency-Key | header | string | Yes | — |
|---|
If-Match | header | string | Yes | — |
|---|
Request body
application/json · Required:Yes
revokeSelfAPIKey Request body| Name | Type | Required | Description |
|---|
ip_allowlist | array<string> | Yes | Canonical network CIDRs only: no host bits, zones, IPv4-mapped IPv6, duplicate prefixes, or overlaps. Empty means unrestricted. |
|---|
grant_all_scopes | boolean | No | Rotate 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| Status | Description |
|---|
200 | Revoked 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) |
|---|
400 | Malformed 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. |
|---|
401 | Authentication failed or the session is invalid. |
|---|
403 | The authenticated principal is not allowed to perform the action. |
|---|
404 | The requested resource was not found. |
|---|
409 | The requested state conflicts with an existing resource or idempotency fact. |
|---|
503 | A required dependency is unavailable. |
|---|
500 | The 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| Name | In | Type | Required | Description |
|---|
key_id | path | string(uuid) | Yes | — |
|---|
Idempotency-Key | header | string | Yes | — |
|---|
If-Match | header | string | Yes | — |
|---|
Request body
application/json · Required:Yes
rotateSelfAPIKey Request body| Name | Type | Required | Description |
|---|
ip_allowlist | array<string> | Yes | Canonical network CIDRs only: no host bits, zones, IPv4-mapped IPv6, duplicate prefixes, or overlaps. Empty means unrestricted. |
|---|
grant_all_scopes | boolean | No | Rotate 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| Status | Description |
|---|
200 | Updated key and one-time replacement secret. Fields:key: APIKey secret: string(password) |
|---|
400 | Malformed 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. |
|---|
401 | Authentication failed or the session is invalid. |
|---|
403 | The authenticated principal is not allowed to perform the action. |
|---|
404 | The requested resource was not found. |
|---|
409 | The requested state conflicts with an existing resource or idempotency fact. |
|---|
503 | A required dependency is unavailable. |
|---|
500 | The 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| Status | Description |
|---|
200 | Current 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) |
|---|
401 | Authentication failed or the session is invalid. |
|---|
403 | The authenticated principal is not allowed to perform the action. |
|---|
404 | The requested resource was not found. |
|---|
500 | The 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| Name | In | Type | Required | Description |
|---|
unread | query | string: true | No | — |
|---|
page_size | query | integer | No | — |
|---|
cursor | query | string | No | — |
|---|
Responses
listAccountInbox Responses| Status | Description |
|---|
200 | One page. Fields:items: array<object> unread: integer total: integer next_cursor: string unread_only: boolean page_size: integer |
|---|
401 | Authentication failed or the session is invalid. |
|---|
403 | The 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| Status | Description |
|---|
200 | Number 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| Status | Description |
|---|
200 | Count. Fields:unread: integer |
|---|
401 | Authentication 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| Name | In | Type | Required | Description |
|---|
message_id | path | string(uuid) | Yes | — |
|---|
Responses
markAccountInboxMessageRead Responses| Status | Description |
|---|
204 | Read. |
|---|
404 | admin_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| Name | In | Type | Required | Description |
|---|
page | query | integer | No | — |
|---|
limit | query | integer | No | — |
|---|
Responses
listAccountLedger Responses| Status | Description |
|---|
200 | Newest-first tenant ledger page. Fields:items: array<BillingLedgerEntry> total: integer(int64) page: integer limit: integer |
|---|
400 | The request body or parameters are invalid. |
|---|
401 | Authentication failed or the session is invalid. |
|---|
403 | The authenticated principal is not allowed to perform the action. |
|---|
500 | The 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| Name | In | Type | Required | Description |
|---|
limit | query | integer | No | — |
|---|
cursor | query | string | No | — |
|---|
offset | query | integer | No | Page by position (page-number pagination). Cannot be combined with cursor. |
|---|
filter | query | string: read / unread | No | — |
|---|
Responses
listAccountMessages Responses| Status | Description |
|---|
200 | Inbox page Fields:items: array<InboxMessage> next_cursor?: string total?: integer |
|---|
400 | Stable API error |
|---|
401 | Stable API error |
|---|
403 | Stable API error |
|---|
500 | Stable 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| Name | In | Type | Required | Description |
|---|
event_id | path | string(uuid) | Yes | — |
|---|
Idempotency-Key | header | string | Yes | — |
|---|
If-Match | header | string | Yes | — |
|---|
Request body
application/json · Required:Yes
markMessageDelivered Request body| Name | Type | Required | Description |
|---|
expected_revision | integer | Yes | — |
|---|
Responses
markMessageDelivered Responses| Status | Description |
|---|
200 | Inbox state Fields:event_id: string(uuid) delivered_at?: string(date-time) read_at?: string(date-time) revision: integer replayed?: boolean |
|---|
400 | Stable API error |
|---|
401 | Stable API error |
|---|
403 | Stable API error |
|---|
404 | Stable API error |
|---|
409 | Stable API error |
|---|
415 | Stable API error |
|---|
500 | Stable 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| Name | In | Type | Required | Description |
|---|
event_id | path | string(uuid) | Yes | — |
|---|
Idempotency-Key | header | string | Yes | — |
|---|
If-Match | header | string | Yes | — |
|---|
Request body
application/json · Required:Yes
markMessageRead Request body| Name | Type | Required | Description |
|---|
expected_revision | integer | Yes | — |
|---|
Responses
markMessageRead Responses| Status | Description |
|---|
200 | Inbox state Fields:event_id: string(uuid) delivered_at?: string(date-time) read_at?: string(date-time) revision: integer replayed?: boolean |
|---|
400 | Stable API error |
|---|
401 | Stable API error |
|---|
403 | Stable API error |
|---|
404 | Stable API error |
|---|
409 | Stable API error |
|---|
415 | Stable API error |
|---|
500 | Stable 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| Name | In | Type | Required | Description |
|---|
X-Request-ID | header | string | Yes | — |
|---|
Traceparent | header | string | Yes | Canonical W3C version 00 traceparent; the non-zero trace ID is used for correlation. |
|---|
Responses
getMyMFAStatus Responses| Status | Description |
|---|
200 | Current non-sensitive MFA state. |
|---|
400 | Request metadata, path, query, body, or input is invalid |
|---|
401 | Bearer session is absent, malformed, expired, revoked, or disabled |
|---|
403 | Live principal, tenant, permissions, or proof binding changed |
|---|
405 | Request method is not allowed. |
|---|
408 | Request was canceled |
|---|
503 | MFA, encryption, identity, IAM, or PostgreSQL dependency is unavailable |
|---|
504 | Request 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| Name | Type | Required | Description |
|---|
authentication | Authentication | Yes | — |
|---|
reason | string | Yes | — |
|---|
Responses
disableMyMFA Responses| Status | Description |
|---|
204 | Terminal fact already exists or was committed by this request. |
|---|
400 | Request metadata, path, query, body, or input is invalid |
|---|
401 | Bearer session is absent, malformed, expired, revoked, or disabled |
|---|
403 | Live principal, tenant, permissions, or proof binding changed |
|---|
405 | Request method is not allowed. |
|---|
409 | Idempotency, lifecycle, code replay, or bounded-use conflict |
|---|
412 | Active MFA is required |
|---|
413 | Request body exceeds the configured limit |
|---|
422 | MFA code or proof is invalid |
|---|
408 | Request was canceled |
|---|
503 | MFA, encryption, identity, IAM, or PostgreSQL dependency is unavailable |
|---|
504 | Request 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| Name | In | Type | Required | Description |
|---|
Idempotency-Key | header | string | Yes | — |
|---|
X-Request-ID | header | string | Yes | — |
|---|
Traceparent | header | string | Yes | Canonical W3C version 00 traceparent; the non-zero trace ID is used for correlation. |
|---|
Request body
application/json · Required:Yes
beginMyMFAEnrollment Request body| Name | Type | Required | Description |
|---|
account_label | string | Yes | — |
|---|
Responses
beginMyMFAEnrollment Responses| Status | Description |
|---|
201 | Enrollment 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 |
|---|
200 | Enrollment replayed; secret and provisioning_uri are absent. Fields:credential_id: string(uuid) expires_at: string(date-time) replayed: const true |
|---|
400 | Request metadata, path, query, body, or input is invalid |
|---|
401 | Bearer session is absent, malformed, expired, revoked, or disabled |
|---|
403 | Live principal, tenant, permissions, or proof binding changed |
|---|
405 | Request method is not allowed. |
|---|
409 | Idempotency, lifecycle, code replay, or bounded-use conflict |
|---|
413 | Request body exceeds the configured limit |
|---|
408 | Request was canceled |
|---|
503 | MFA, encryption, identity, IAM, or PostgreSQL dependency is unavailable |
|---|
504 | Request 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| Name | In | Type | Required | Description |
|---|
credential_id | path | string(uuid) | Yes | — |
|---|
Idempotency-Key | header | string | Yes | — |
|---|
X-Request-ID | header | string | Yes | — |
|---|
Traceparent | header | string | Yes | Canonical W3C version 00 traceparent; the non-zero trace ID is used for correlation. |
|---|
Request body
application/json · Required:Yes
activateMyMFAEnrollment Request body| Name | Type | Required | Description |
|---|
code | string | Yes | — |
|---|
Responses
activateMyMFAEnrollment Responses| Status | Description |
|---|
201 | Enrollment activated; recovery_codes are present exactly once. Fields:credential_id: string(uuid) recovery_codes: array<string> activated_at: string(date-time) replayed: const false |
|---|
200 | Activation replayed; recovery_codes are absent. Fields:credential_id: string(uuid) activated_at: string(date-time) replayed: const true |
|---|
400 | Request metadata, path, query, body, or input is invalid |
|---|
401 | Bearer session is absent, malformed, expired, revoked, or disabled |
|---|
403 | Live principal, tenant, permissions, or proof binding changed |
|---|
405 | Request method is not allowed. |
|---|
409 | Idempotency, lifecycle, code replay, or bounded-use conflict |
|---|
410 | Enrollment or proof expired |
|---|
413 | Request body exceeds the configured limit |
|---|
422 | MFA code or proof is invalid |
|---|
408 | Request was canceled |
|---|
503 | MFA, encryption, identity, IAM, or PostgreSQL dependency is unavailable |
|---|
504 | Request 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| Name | Type | Required | Description |
|---|
authentication | Authentication | Yes | — |
|---|
reason | string | Yes | — |
|---|
↑ 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| Name | Type | Required | Description |
|---|
tenant_id | string(uuid) | Yes | — |
|---|
audience | string | Yes | — |
|---|
action | string | Yes | — |
|---|
authentication | Authentication | Yes | — |
|---|
ttl_seconds | integer | Yes | — |
|---|
max_uses | integer | Yes | — |
|---|
Responses
createMyMFAStepUpProof Responses| Status | Description |
|---|
201 | Step-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 |
|---|
200 | Step-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 |
|---|
400 | Request metadata, path, query, body, or input is invalid |
|---|
401 | Bearer session is absent, malformed, expired, revoked, or disabled |
|---|
403 | Live principal, tenant, permissions, or proof binding changed |
|---|
405 | Request method is not allowed. |
|---|
409 | Idempotency, lifecycle, code replay, or bounded-use conflict |
|---|
410 | Enrollment or proof expired |
|---|
412 | Active MFA is required |
|---|
413 | Request body exceeds the configured limit |
|---|
422 | MFA code or proof is invalid |
|---|
408 | Request was canceled |
|---|
503 | MFA, encryption, identity, IAM, or PostgreSQL dependency is unavailable |
|---|
504 | Request 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| Name | In | Type | Required | Description |
|---|
type | query | string | No | — |
|---|
site_id | query | string(uuid) | No | — |
|---|
package_id | query | string(uuid) | No | — |
|---|
site | query | string | No | Event-time site by exact display ID or case-insensitive substring of its current domain; events whose site no longer exists never match. |
|---|
package | query | string | No | User subscription by exact display ID or case-insensitive substring of the package name; events whose subscription no longer exists never match. |
|---|
limit | query | integer | No | — |
|---|
offset | query | integer | No | — |
|---|
Responses
listOwnNotificationMessages Responses| Status | Description |
|---|
200 | The caller's own event messages, newest first. Fields:schema: string items: array<OwnMessage> total: integer |
|---|
400 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
401 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
403 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
405 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
500 | Stable 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| Name | In | Type | Required | Description |
|---|
event_type | path | string | Yes | — |
|---|
Responses
getNotificationSubscription Responses| Status | Description |
|---|
200 | Current 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 |
|---|
400 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
401 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
403 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
404 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
405 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
500 | Stable 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| Name | In | Type | Required | Description |
|---|
event_type | path | string | Yes | — |
|---|
If-Match | header | string | Yes | — |
|---|
X-Request-ID | header | string | No | Correlation 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| Name | Type | Required | Description |
|---|
sms_enabled | boolean | Yes | — |
|---|
email_enabled | boolean | Yes | — |
|---|
inbox_enabled | boolean | No | Ticket events only (546): keep the in-app message-center copy. Omitted keeps the stored choice; any other event answers 400. |
|---|
Responses
updateNotificationSubscription Responses| Status | Description |
|---|
200 | Current 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 |
|---|
400 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
401 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
403 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
404 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
405 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
409 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
415 | Stable error envelope. Clients map code through locale resources and do not render message directly. |
|---|
500 | Stable 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| Name | In | Type | Required | Description |
|---|
page | query | integer | No | — |
|---|
limit | query | integer | No | — |
|---|
type | query | string: recharge / deduction / upgrade / purchase / renewal / package_change | No | — |
|---|
status | query | string: paid / unpaid | No | — |
|---|
search | query | string | No | Exact-page substring search over source-local display ID, UUID, user ID, username, email, or phone. |
|---|
created_from | query | string(date-time) | No | — |
|---|
created_to | query | string(date-time) | No | Exclusive upper bound. |
|---|
Responses
listAccountOrders Responses| Status | Description |
|---|
200 | Consumption record page Fields:items: array<AccountOrder> total: integer page: integer limit: integer can_manage: boolean |
|---|
400 | Invalid request fields |
|---|
401 | Authentication is required |
|---|
403 | Required permission is absent |
|---|
503 | Account 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| Name | Type | Required | Description |
|---|
current_password | string(password) | Yes | — |
|---|
new_password | string(password) | Yes | 8 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| Status | Description |
|---|
204 | Password changed and all sessions revoked. The client must sign in again. |
|---|
400 | The request body or parameters are invalid. |
|---|
401 | Authentication failed or the session is invalid. |
|---|
403 | The authenticated principal is not allowed to perform the action. |
|---|
409 | The requested state conflicts with an existing resource or idempotency fact. |
|---|
500 | The 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| Status | Description |
|---|
200 | Current 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) |
|---|
401 | Authentication failed or the session is invalid. |
|---|
403 | The authenticated principal is not allowed to perform the action. |
|---|
500 | The 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| Name | In | Type | Required | Description |
|---|
Idempotency-Key | header | string | Yes | — |
|---|
Request body
application/json · Required:Yes
updateAccountProfile Request body| Name | Type | Required | Description |
|---|
expected_revision | integer(int64) | Yes | — |
|---|
display_name | string | Yes | — |
|---|
email | string(email) | null(email) | Yes | — |
|---|
phone | string | null | Yes | — |
|---|
current_password | string(password) | No | Required when the normalized email or phone differs from the current profile. |
|---|
Responses
updateAccountProfile Responses| Status | Description |
|---|
200 | Profile 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) |
|---|
400 | The request body or parameters are invalid. |
|---|
401 | Authentication failed or the session is invalid. |
|---|
403 | The authenticated principal is not allowed to perform the action. |
|---|
409 | The requested state conflicts with an existing resource or idempotency fact. |
|---|
500 | The 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| Name | In | Type | Required | Description |
|---|
page | query | integer | No | — |
|---|
limit | query | integer | No | — |
|---|
type | query | string: recharge / deduction / upgrade / purchase / renewal / package_change / traffic_package / refund / income | No | — |
|---|
status | query | string: paid / unpaid | No | — |
|---|
created_from | query | string(date-time) | No | — |
|---|
created_to | query | string(date-time) | No | Exclusive upper bound. |
|---|
Responses
listAccountStatement Responses| Status | Description |
|---|
200 | Statement page Fields:items: array<AccountStatementEntry> total: integer(int64) page: integer limit: integer |
|---|
400 | Invalid request fields |
|---|
401 | Authentication is required |
|---|
403 | Required permission is absent |
|---|
503 | Account 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