Authentication
The REST API takes API keys only.
Header
Section titled “Header”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.
Environment
Section titled “Environment”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.
The Key's Owner
Section titled “The Key's Owner”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
testandlive, other rolesliveonly. - 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:viewgets it masked. See Personal Data.
A key works only on its own company's host. On another company's host, it is not found.
Scopes
Section titled “Scopes”| 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.
Authentication Errors
Section titled “Authentication Errors”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.
Version Header
Section titled “Version Header”Every answer carries:
api-version: 2cache-control: no-storeA downloaded report file carries them too.