Skip to content

Authentication

The REST API takes API keys only.

Send the key in the x-api-key header of every request:

x-api-key: covalence_pk_<64 hexadecimal characters>

A key is covalence_pk_ followed by 32 random bytes in hex. Covalent stores only its SHA-256 hash: the key itself is shown once, when it is created, and cannot be shown again.

Create keys in the dashboard, under Developers, API keys. Each key has a name, an environment, a set of scopes and its own per-minute rate limit.

A POST, PUT, PATCH or DELETE that carries the dashboard's session cookie is refused with 403 CSRF_VALIDATION_FAILED, whatever key it carries: the API is not for browser sessions.

Each key belongs to one environment, test or live, and every request works in that environment only: it lists, creates, reads and changes that environment's records, and a record of the other environment is not found. Do not send an environment in requests; no header or parameter chooses it.

Use a test key to build and test your integration, and a live key in production.

A key acts for the member who created it, in the company whose host it is sent to:

  • Every change it makes is recorded as that member's, with the request's IP address and user agent.
  • Its scopes are cut, each time it is used, to what the member's role allows. A scope the role does not allow is a scope the key does not have.
  • The role must still allow the key's environment: administrators and compliance officers may use test and live, other roles live only.
  • The key stops working (401 KEY_REVOKED) when it is revoked, when the member leaves the company or is disabled, or when the role no longer allows its environment.
  • What the key sees of personal data follows the role: a role without pii:view gets it masked. See Personal Data.

A key works only on its own company's host. On another company's host, it is not found.

Scope Grants
customers:read List customers
customers:write Create, deactivate and reactivate customers; set a customer's Travel Rule identity
customers:erase Erase a customer's personal data
wallets:read List and read wallets
wallets:write Register, relabel and remove wallets
wallets:verify Check whether an address is a registered wallet
transfers:read List and read transfers and their information requests; VASP search; the asset catalog
transfers:write Create transfers; accept, reject and retry; act on information requests
cases:read List and read cases, their notes and history
cases:write Open, change, annotate and resolve cases
reports:read Report types, and reports with strs:read
strs:read Suspicion reports, with reports:read
strs:write Draft a suspicion report when resolving a case as rejected
rules:read, rules:write Read, and create, change and deactivate, compliance rules
thresholds:read, thresholds:write Read, and create and change, regulatory thresholds
providers:read, providers:write Read, and save, switch and test, Travel Rule provider settings
integrations:read, integrations:write Read, and save, switch and test, screening integration settings
webhooks:read, webhooks:write Read, and create, change, test and retry, webhook subscriptions
activity:read Read the activity feed
audit:read Read the audit log

Some actions need a second scope: linking a transfer to a case, or seeing a case's transfers, needs transfers:read; acting on a held transfer when resolving its case needs transfers:write; downloading a report needs transfers:read. The other scopes a key can hold (users:read, users:write, reports:write, admin:read, admin:write) are not used by any /api/v2 endpoint.

Each endpoint's scope is listed in the API Reference.

Every refusal is in the API's envelope:

{
"error": "API key required",
"code": "MISSING_KEY",
"meta": {
"apiVersion": 2,
"timestamp": "2026-10-09T12:00:00.000Z"
}
}
Status Code Meaning
401 MISSING_KEY No x-api-key header.
401 INVALID_FORMAT The key is not in the issued format.
401 KEY_NOT_FOUND No key of this company matches.
401 KEY_REVOKED The key was revoked, or its owner lost access.
403 INSUFFICIENT_SCOPE The key lacks the endpoint's scope, or its owner's role no longer allows it.
403 INSUFFICIENT_PERMISSION The owner's role lacks the permission the action needs, or the action needs a second scope.
403 CSRF_VALIDATION_FAILED A change carried the dashboard's session cookie.
429 RATE_LIMITED A rate limit was reached.
500 VALIDATION_ERROR The key could not be checked, through an internal failure.

A key over its own rate limit is refused with Retry-After, x-ratelimit-remaining, x-ratelimit-reset, and the limit's state in details:

{
"error": "API key rate limit exceeded",
"code": "RATE_LIMITED",
"details": {
"rateLimit": {
"remaining": 0,
"resetTime": "2026-10-09T12:00:42.000Z"
}
},
"meta": {
"apiVersion": 2,
"timestamp": "2026-10-09T12:00:00.000Z"
}
}

For the other limits, see Rate Limits.

Every answer carries:

api-version: 2
cache-control: no-store

A downloaded report file carries them too.