Errors and Troubleshooting
Error responses look like this:
{ "statusCode": 401, "message": "Invalid signature", "error": "Unauthorized" }
message is an array of strings for field validation errors. Some errors also
carry a code.
Authentication
| HTTP | Message | Cause and fix |
|---|---|---|
| 400 | ownerAddress is required | Add ownerAddress to the body (POST) or query (GET, DELETE). |
| 401 | API key is invalid | Wrong or replaced key. Generate a new one in the dashboard. |
| 401 | API key does not match ownerAddress | The key belongs to another wallet. |
| 400 | timestamp is invalid | x-depay-timestamp is missing or not a number. |
| 401 | Signature is required | No API key and no x-depay-signature. |
| 401 | Request timestamp is expired | More than 5 minutes of clock drift. Sync the server clock. |
| 401 | Timestamp already used | Every signed request, including retries, needs a new timestamp. |
| 401 | Invalid signature | The signed message differs from what the server rebuilt. See the checklist below. |
Invoices
| HTTP | Message or code | Cause and fix |
|---|---|---|
| 400 | CHAIN_NOT_SUPPORTED | Use a supported chain. Ethereum mainnet is not supported. |
| 400 | Invoice with invoiceId "…" already exists for this owner | Use a new invoiceId or omit it. |
| 400 | tokenAddress "…" is not a valid address and not a supported symbol on chain … | Check the token address or symbol for that chain. |
| 404 | Invoice not found… | Wrong paymentAddress, or the invoice was cancelled. |
| 403 | Invoice does not belong to ownerAddress | The invoice belongs to another merchant. |
| 500 | RPC_UNAVAILABLE | The chain is temporarily unreachable. Retry with backoff. |
Withdrawals
| HTTP | Code | Cause and fix |
|---|---|---|
| 400 | OWNER_ONLY_WITHDRAW | Owner-only withdrawals are enabled for your wallet. Withdraw from the owner wallet or contract directly. |
Fees and payout
| HTTP | Message | Cause and fix |
|---|---|---|
| 400 | Invalid nonce. Expected X, got Y | Re-read nonces(owner) on that chain and sign again. |
| 400 | Signature deadline is expired | Deadline must be in the future, in Unix seconds. |
| 401 | Invalid setFee signature / Invalid setPayout signature | Wrong EIP-712 domain or signer. |
How to handle errors
400— fix the request; do not retry unchanged.401/403— check credentials. For signed requests, re-sign with a new timestamp.404— treat as missing; for invoices check that you usepaymentAddress.500— retry with exponential backoff.
Invalid signature checklist
- Keys of the canonical JSON are sorted alphabetically at every level.
ownerAddressin the message is checksummed (EIP-55).- The timestamp in the message equals the header value, in milliseconds.
- The
payloadis exactly what you send, minusownerAddress, with the right types (chainIdis a number,amountis a string). - List endpoints:
pageandlimitare included in the payload. - No
nullvalues for fields you meant to omit. - You signed with
personal_sign(EIP-191), not EIP-712.
See Request signature.
Payment issues
- The payer paid but the invoice is still
pending. CallGET /integration/invoices/statusto force an on-chain check. Check that the payer used the right chain and token and paid the full amount; partial payments are visible inbalance. - The payer paid after expiry. The status call detects it and moves the
invoice to
paid. See late payments. - No webhook arrived. Webhooks are retried for about 20 minutes and delivery is not guaranteed. Reconcile with the status endpoint.