Skip to main content
Every request is signed with HMAC-SHA256. Your credentials are a pair: an API key, sent on every request, and an API secret, which signs the request and is never transmitted. Authorization: Bearer is not accepted.

Credentials

The ak_… id on created_by and updated_by identifies the API key record, not the key value.

Access requirements

Your organization’s KYC must be approved before any endpoint will serve data. Until it is, calls return 403 with code KYC_NOT_APPROVED and details.kyc_status carrying the current state.

Scopes

Each API key carries a set of scopes, each at read or write. Write implies read. A call outside your key’s scopes returns 403 ACCESS_DENIED. Use these five scope names when creating a key or updating its scopes: Endpoint pages name the scope each one needs. Each scope covers every resource in its row, so a payout integration needs payments at write. Keys may also carry an IP allowlist, in which case a request from any other address returns 403. Scopes are set when the key is issued and cannot be changed through the API.

Required headers

string
required
The API key value.
string
required
Unix epoch seconds, within 300 seconds of server time.
string
required
A value unique to this request; a UUID is the usual choice. A nonce cannot be reused for 300 seconds.
string
required
Lowercase hex HMAC-SHA256 of the signature string, keyed with your API secret.

Signature string

Concatenate five parts with no separators:
Sign the bytes you send: serialise the body once and use that same string for the signature and the request, and keep the query parameters in the order you send them. Idempotency-Key and X-Request-ID are not part of the signature string.

Building a signed request

Test vectors

Check your signing implementation against these fixed inputs. Both use the secret test_secret_key_123. These are offline checks: the timestamps are fixed and are not valid for a live request.

When authentication fails

Every failure returns the standard error envelope. A nonce is consumed before the signature is checked, so a request that failed on its signature cannot be retried with the same nonce. Generate a fresh nonce and timestamp for every attempt.