API conventions

Guides

API conventions

Use these cross-endpoint rules for signing, pagination, retries, errors, and request tracing.

Exact request signing

The REST canonical string has six lines:

text
METHOD
EXACT_REQUEST_TARGET
BODY_HASH
TIMESTAMP
NONCE
API_KEY_ID

EXACT_REQUEST_TARGET includes the raw path and query exactly as sent. Use the uppercase method, a Unix timestamp in seconds, a unique nonce, and a padded standard Base64 Ed25519 signature.

For requests without body bytes, the canonical body-hash line is empty. When body bytes are sent, hash the exact bytes with SHA-256 and send the lowercase hexadecimal digest as X-Api-Body-Hash. MPC initialization is a documented staging exception: use an explicit zero-length form body and omit the hash header.

Cursor pagination

Most list endpoints return:

json
{
  "items": [],
  "nextCursor": null
}

Treat cursors as opaque. Pass the exact nextCursor value to the next request and stop when it is null. Do not decode, edit, or reuse a cursor with changed filters.

Audit logs use page and limit instead. Hold snapshotAt constant while paging.

Idempotency

The current Swagger requires X-Idempotency-Key for:

  • POST /api/v1/wallets;
  • POST /api/v1/transactions;
  • POST /api/v1/mpc/initialize;
  • POST /api/v1/co-signer/intents/{intentId}/claim;
  • POST /api/v1/co-signer/sessions/{sessionId}/messages.

Generate one key per logical operation. After a timeout or unknown outcome, retry the identical request with the same key. Never reuse the key with changed body bytes, path, or parameters.

POST /api/v1/ledger/accounts does not currently document fingerprint replay handling.

Error model

Public REST errors use:

json
{
  "code": "INVALID_QUERY_PARAMETER",
  "message": "Invalid query parameter",
  "details": [],
  "requestId": "a4b2b2d6-2c9d-4a04-a630-df669f1e93a0",
  "retryable": false
}

Branch on the stable code, not the free-form message. Log requestId for support and honor retryable when deciding whether to retry.

HTTP status guidance

StatusMeaning
400Invalid request, query, cursor, date range, or idempotency header
401Missing or invalid signed authentication, clock skew, replay, or body-hash mismatch
403IP, scope, organization, or plan restriction
404Organization-scoped resource not found
409Idempotency, client-reference, account-reference, or claim conflict
413Payload is too large
422Valid JSON that fails a domain rule
500Internal error
503Required upstream service is unavailable

Retry only when the response and operation semantics allow it. For mutating operations, keep the original idempotency key.

Request tracing and language

The Swagger documents optional x-request-id, x-lang, and lang inputs. Generate a request ID at your system boundary and preserve it across logs. Do not allow the language parameter to change program logic; use code for automated error handling.