Skip to content

List active API keys

GET
/api-keys
curl --request GET \
--url 'https://example.com/v2/api-keys?page=1&limit=20' \
--header 'X-CowriePay-Key: <X-CowriePay-Key>'

Returns paginated active (non-revoked) API keys for the workspace.

page
integer
default: 1 >= 1

Page number (1-based)

limit
integer
default: 20 >= 1 <= 100

Items per page (max 100)

Paginated key list (secrets are never returned)

Media typeapplication/json
object
total

Total number of matching records

integer
page

Current page number

integer
limit

Items per page

integer
data
Array<object>
object
id
string format: uuid
label
string
key_id
string
scopes

Fine-grained scopes granted to this key. Empty means a legacy key whose access is derived from permission (READ_WRITE → all scopes, READ_ONLY → all :read scopes).

Array<string>
Allowed values: wallets:read wallets:write customers:read customers:write transactions:read withdrawals:read withdrawals:write webhooks:read webhooks:write fees:read api_keys:read api_keys:write
permission

Legacy coarse permission. Retained for display and as the fallback when scopes is empty.

string
Allowed values: READ_ONLY READ_WRITE
allowed_ips

Optional source-IP allowlist. When non-empty, a request from a source IP outside this list is rejected with 403 IP_NOT_ALLOWED (checked before the HMAC signature). Empty means no restriction. Each entry is a single IP or CIDR range (IPv4 or IPv6).

Array<string>
is_test
boolean
last_used_at
Any of:
string format: date-time
expires_at
Any of:
string format: date-time
created_at
string format: date-time
Example
{
"data": [
{
"key_id": "cpk_live_xxxxxxxxxxxxxxxxxxxx",
"scopes": [
"wallets:read"
],
"permission": "READ_ONLY",
"allowed_ips": [
"203.0.113.4",
"198.51.100.0/24"
]
}
]
}

Invalid or revoked API key / HMAC signature mismatch

Media typeapplication/json
object
error
required

Human-readable message, for display/logging. Do NOT branch on this text.

string
code
required

Stable, machine-readable error code, branch on this, not the message. Common values: VALIDATION_ERROR, INVALID_JSON, PAYLOAD_TOO_LARGE, MISSING_AUTH_HEADERS, INVALID_SIGNATURE, TIMESTAMP_EXPIRED, REPLAY_DETECTED, INVALID_API_KEY, IP_NOT_ALLOWED, API_KEY_EXPIRED, WORKSPACE_INACTIVE, INSUFFICIENT_SCOPE, NOT_FOUND, CONFLICT, UNPROCESSABLE, INSUFFICIENT_BALANCE, INVALID_DESTINATION_ADDRESS, DESTINATION_IS_INTERNAL, CHAIN_NOT_ENABLED, FAUCET_ONLY_SANDBOX, FAUCET_ADDRESS_NOT_FOUND, FAUCET_INVALID_ASSET, FAUCET_AMOUNT_OVER_CAP, FAUCET_RATE_LIMITED, FAUCET_TOO_MANY_ITEMS, FAUCET_DUPLICATE_ASSET, FAUCET_NATIVE_REQUIRES_DEPOSIT, FAUCET_NATIVE_BUDGET_EXCEEDED, FAUCET_DISPENSER_EXHAUSTED, WITHDRAWAL_NOT_CANCELLABLE, IDEMPOTENCY_CONFLICT, IDEMPOTENCY_MISMATCH, IDEMPOTENCY_KEY_INVALID, FEATURE_NOT_AVAILABLE, RATE_LIMITED, DATABASE_ERROR, INTERNAL_ERROR, UNAUTHORIZED, FORBIDDEN, UNSUPPORTED_MEDIA_TYPE, WITHDRAWALS_FROZEN, WORKSPACE_NOT_FOUND, SYSTEM_WORKSPACE_PROTECTED, FAUCET_INVALID_AMOUNT, FAUCET_NO_ASSETS, FAUCET_NOT_SANDBOX. Most failures do NOT carry a business code. 326 throw sites raise a generic one (VALIDATION_ERROR, NOT_FOUND, UNPROCESSABLE, UNAUTHORIZED, CONFLICT, FORBIDDEN) against 46 named public codes, so a generic code is the common case and a named one is the exception. Branch on code; treat error as human text that may be reworded. The full catalogue, with causes and next steps, is the Error codes guide.

string
Example
{
"error": "Insufficient balance. Available: 10.000000, Requested: 50.000000",
"code": "INSUFFICIENT_BALANCE"
}

Rate limit exceeded

Media typeapplication/json
object
error
required

Human-readable message, for display/logging. Do NOT branch on this text.

string
code
required

Stable, machine-readable error code, branch on this, not the message. Common values: VALIDATION_ERROR, INVALID_JSON, PAYLOAD_TOO_LARGE, MISSING_AUTH_HEADERS, INVALID_SIGNATURE, TIMESTAMP_EXPIRED, REPLAY_DETECTED, INVALID_API_KEY, IP_NOT_ALLOWED, API_KEY_EXPIRED, WORKSPACE_INACTIVE, INSUFFICIENT_SCOPE, NOT_FOUND, CONFLICT, UNPROCESSABLE, INSUFFICIENT_BALANCE, INVALID_DESTINATION_ADDRESS, DESTINATION_IS_INTERNAL, CHAIN_NOT_ENABLED, FAUCET_ONLY_SANDBOX, FAUCET_ADDRESS_NOT_FOUND, FAUCET_INVALID_ASSET, FAUCET_AMOUNT_OVER_CAP, FAUCET_RATE_LIMITED, FAUCET_TOO_MANY_ITEMS, FAUCET_DUPLICATE_ASSET, FAUCET_NATIVE_REQUIRES_DEPOSIT, FAUCET_NATIVE_BUDGET_EXCEEDED, FAUCET_DISPENSER_EXHAUSTED, WITHDRAWAL_NOT_CANCELLABLE, IDEMPOTENCY_CONFLICT, IDEMPOTENCY_MISMATCH, IDEMPOTENCY_KEY_INVALID, FEATURE_NOT_AVAILABLE, RATE_LIMITED, DATABASE_ERROR, INTERNAL_ERROR, UNAUTHORIZED, FORBIDDEN, UNSUPPORTED_MEDIA_TYPE, WITHDRAWALS_FROZEN, WORKSPACE_NOT_FOUND, SYSTEM_WORKSPACE_PROTECTED, FAUCET_INVALID_AMOUNT, FAUCET_NO_ASSETS, FAUCET_NOT_SANDBOX. Most failures do NOT carry a business code. 326 throw sites raise a generic one (VALIDATION_ERROR, NOT_FOUND, UNPROCESSABLE, UNAUTHORIZED, CONFLICT, FORBIDDEN) against 46 named public codes, so a generic code is the common case and a named one is the exception. Branch on code; treat error as human text that may be reworded. The full catalogue, with causes and next steps, is the Error codes guide.

string
Example
{
"error": "Insufficient balance. Available: 10.000000, Requested: 50.000000",
"code": "INSUFFICIENT_BALANCE"
}