Quickstart
This walk-through creates a customer, gives it an attested identity, registers its wallet, sends an outgoing transfer and follows it. Use a test key: everything it creates stays in the test environment.
1. Create an API Key
Section titled “1. Create an API Key”In the dashboard, open Developers, API keys, and create a key for the test environment with the customers:write, wallets:write, transfers:read and transfers:write scopes. The key is shown once: store it as a secret.
export COVALENT_URL="https://<company>.<app-domain>"export COVALENT_API_KEY="covalence_pk_..."COVALENT_URL is your company's host, the address your dashboard opens at. Send the key in the x-api-key header of every request; it decides the environment of the request.
2. Create a Customer
Section titled “2. Create a Customer”curl -X POST "$COVALENT_URL/api/v2/customers" \ -H "x-api-key: $COVALENT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "externalId": "cust_123", "name": "Jane Doe", "metadata": { "segment": "retail" } }'The answer is 201 with the customer, including its ID and Veriscope public key:
{ "data": { "id": "customer_id", "externalId": "cust_123", "name": "Jane Doe", "publicKey": "02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f", "environment": "test", "createdAt": "2026-10-09T12:00:00.000Z" }, "meta": { "apiVersion": 2, "timestamp": "2026-10-09T12:00:00.000Z" }}3. Set the Customer's Travel Rule Identity
Section titled “3. Set the Customer's Travel Rule Identity”Providers send a customer's attested identity to counterparties, and never its display name. Store the IVMS101 data your KYC process verified:
curl -X PUT "$COVALENT_URL/api/v2/customers/customer_id/travel-rule-identity" \ -H "x-api-key: $COVALENT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "status": "verified", "persons": [ { "naturalPerson": { "name": { "nameIdentifier": [ { "primaryIdentifier": "Doe", "secondaryIdentifier": "Jane", "nameIdentifierType": "LEGL" } ] }, "countryOfResidence": "US" } } ] }'The answer is { "id": "customer_id", "status": "verified" }. See Travel Rule Identity.
4. Register a Wallet
Section titled “4. Register a Wallet”curl -X POST "$COVALENT_URL/api/v2/wallets" \ -H "x-api-key: $COVALENT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "network": "ethereum", "customerId": "customer_id", "label": "Main wallet" }'The answer is 201 with the wallet. The customer must be in the same environment (404 CUSTOMER_NOT_FOUND otherwise) and not deactivated.
5. Create an Outgoing Transfer
Section titled “5. Create an Outgoing Transfer”Send an Idempotency-Key with every create, so that a retry never creates a second transfer.
curl -X POST "$COVALENT_URL/api/v2/transfers" \ -H "x-api-key: $COVALENT_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 8c6c1d0e-7f43-4c55-9a51-4f2c3b1e2a90" \ -d '{ "asset": "ETH", "amount": "1.25", "network": "ethereum", "originatorCustomerId": "customer_id", "originatorAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "beneficiaryAddress": "0x1111111111111111111111111111111111111111", "originator": { "originatorPersons": [ { "naturalPerson": { "name": { "nameIdentifier": [ { "primaryIdentifier": "Doe", "secondaryIdentifier": "Jane", "nameIdentifierType": "LEGL" } ] }, "geographicAddress": [ { "addressType": "HOME", "country": "US" } ] } } ] }, "isUnhostedWallet": false }'| Status | Meaning |
|---|---|
200 |
The Idempotency-Key was used before: the transfer it created, with meta.idempotent: true. |
201 |
Below the Travel Rule threshold: the transfer is completed at once. |
202 |
The transfer is queued for screening and the provider exchange. |
400 |
VALIDATION_ERROR: error says what to fix. |
503 |
TIMEOUT: retry after Retry-After, with the same Idempotency-Key. |
6. Follow the Transfer
Section titled “6. Follow the Transfer”curl "$COVALENT_URL/api/v2/transfers/transfer_id" \ -H "x-api-key: $COVALENT_API_KEY"The answer has the transfer's lifecycle state, each side's status, its compliance checks, its provider attempts and messages, and its timestamps. See Get Transfer.
7. Receive Webhooks
Section titled “7. Receive Webhooks”Instead of polling, create a webhook subscription: in the dashboard under Developers, Webhooks, or with POST /api/v2/webhooks and a key with webhooks:write. Covalent delivers signed JSON events to it:
X-Webhook-Signature: t=1760000000,alg=hmac-sha256,sig=<hex_hmac>X-Webhook-Event: transfer.createdX-Webhook-Delivery-Id: delivery_idVerify the signature against the exact raw request body. See Webhooks.