Skip to content

Testing

Build and test your integration with a test API key. Every request it makes reads and writes the test environment only, and live data is never touched. Test and live have separate customers, wallets, transfers, cases, reports, webhook subscriptions, and provider and integration credentials. Regulatory thresholds, and whether a provider or integration is enabled, are shared by both environments, so only a live key changes them.

  1. Create a test API key in the dashboard, under Developers, API keys.
  2. Check that the key answers in the test environment: the records it lists and creates carry "environment": "test".
  3. Create a customer, and set its Travel Rule identity.
  4. Register a wallet under that customer.
  5. Create an outgoing transfer with an Idempotency-Key.
  6. Follow the transfer with GET /api/v2/transfers/:id.
  7. Create a webhook subscription with POST /api/v2/webhooks, or in the dashboard under Developers, Webhooks, and send it a test event with POST /api/v2/webhooks/:id/test.
  8. Verify webhook signatures against the raw request body.
Terminal window
curl "$COVALENT_URL/api/v2/customers" \
-H "x-api-key: $COVALENT_API_KEY"

Expected result for a valid key with customers:read, before any customer exists:

{
"data": [],
"meta": {
"apiVersion": 2,
"timestamp": "2026-10-09T12:00:00.000Z",
"cursor": null,
"hasMore": false,
"total": 0,
"limit": 50
}
}

A missing or malformed key answers 401 with MISSING_KEY or INVALID_FORMAT, in the same envelope.

Send the same transfer create request twice with the same Idempotency-Key.

Attempt Expected Status
First request 201 or 202, depending on the Travel Rule threshold
Second request 200, with the first request's transfer and meta.idempotent: true
  • Match on code, never on the error message.
  • Read details where a code has it, such as details.issues for 400 INVALID_QUERY.
  • On 429 and 503, wait for Retry-After before retrying.
  • Page lists with meta.cursor only: an item's ID is not a cursor (400 INVALID_CURSOR).

When receiving webhooks:

  • Read the raw request body before JSON parsing.
  • Verify X-Webhook-Signature.
  • Reject stale timestamps.
  • Store X-Webhook-Delivery-Id for idempotency.

Screening integrations and Travel Rule providers use the credentials saved for the environment: test credentials for test keys. Save them with PUT /api/v2/integrations/:name and PUT /api/v2/providers/:name, or in the dashboard, and check them with the /test endpoints. An enabled integration with no credentials for the environment does not pass screening silently: its checks fail.