Errors
Every error the TEDR Pay API returns uses the same body shape. Each endpoint page repeats the codes that apply to it; this page gathers every code the reference documents. Treat it as open rather than closed — keep a fallback branch for a code you have not seen here.
Error envelope
The HTTP status carries the class of the failure and the body names it. code is the stable identifier to branch on; message is a human-readable description of the same thing.
{
"error": {
"code": "BUSINESS_INVOICE_NOT_FOUND",
"message": "Human-readable description of the failure"
}
}
Error codes
UNAUTHORIZED is listed twice: a missing session and a malformed signature answer with the same code. The signature codes are explained in full on the Authentication page.
| Code | HTTP | Where it comes from |
|---|---|---|
| VALIDATION_ERROR | 400 | The body or query did not pass validation: an unknown or malformed field, an invalid id, periodFrom later than periodTo, a corrupted or mismatched cursor, an amount of zero or less, an invoice command its current status does not allow (cancelling once a payment has started, reactivating an expired invoice, deleting a type that does not support deletion), or an API key field that breaks its own rules — an empty or over-long name, an unreachable webhookUrl. |
| PRODUCT_IMAGE_NOT_FOUND | 400 | The productImageId was not found, belongs to another merchant, or has been removed from your catalogue. |
| UNAUTHORIZED | 401 | The request carries no valid session JWT. |
| UNAUTHORIZED | 401 | A signed request is missing KeyId, Timestamp or X-Signature, its Algorithm is outside the supported list, or its Timestamp is not a number. |
| FORBIDDEN | 403 | The invoice belongs to another merchant. |
| BUSINESS_INVOICE_NOT_FOUND | 404 | The invoice does not exist, or it has been deleted. |
| BUSINESS_INVOICE_CANNOT_DELETE | 400 | Deleting an invoice that already has payment activity. |
| API_KEY_LIMIT_REACHED | 403 | You already have an active API key. |
| API_KEY_NOT_FOUND | 404 | The key does not exist, has been revoked, or belongs to another merchant. |
| TIMESTAMP_EXPIRED | 401 | Timestamp is further from the server clock than the allowed window — five minutes by default, in either direction. |
| API_KEY_INVALID | 401 | No key matches the KeyId header, or that key has been revoked. |
| SIGNATURE_INVALID | 401 | The signature did not match either of the two accepted forms of the body. |
| INVALID_DATE_RANGE | — | periodFrom is later than periodTo on GET /transactions. |
| — | 409 | A withdrawal is created again with the same requestId but different parameters. |
A dash marks a value the current contract withholds, not an empty field: INVALID_DATE_RANGE comes without an HTTP status, and the 409 on a repeated requestId comes without an error code. Neither is guessed at here.
Withdrawal errors
Creating a withdrawal is idempotent on requestId: repeating the same requestId with the same parameters returns the request that already exists, while repeating it with different parameters answers 409. That status comes without an error code, so there is nothing to match on beyond the status itself.
The rest of the withdrawal failures are described on the Withdrawals page. The current contract gives neither codes nor statuses for them, so they are not listed here.
