Response codes
Reference of the HTTP codes used across the whole Rapid API.
Success codes
Section titled “Success codes”| Code | Meaning |
|---|---|
| 200 | Success with body |
| 201 | Resource created |
| 204 | Success without body (e.g. DELETE) |
Client error codes
Section titled “Client error codes”| Code | Meaning |
|---|---|
| 400 | Body is not valid JSON (INVALID_JSON) |
| 401 | Missing or invalid credentials |
| 403 | Company blocked |
| 404 | Resource not found |
| 409 | Conflict (duplicate, immutable resource) |
| 413 | Body above the maximum size (PAYLOAD_TOO_LARGE) |
| 422 | Validation error |
| 429 | Too many requests (rate limit) |
Server error codes
Section titled “Server error codes”| Code | Meaning |
|---|---|
| 500 | Internal error (INTERNAL_ERROR), retry recommended |
Error body format
Section titled “Error body format”Every error response has this structure:
{ "error": { "code": "SEMANTIC_CODE", "message": "Human-readable description of the error" }}The message is in English and is meant for whoever reads the log: its wording can change. To decide what to do in your code, use the code. The endpoints kept from the previous system respond as they did before.
Most common semantic codes
Section titled “Most common semantic codes”| Code | HTTP | Use |
|---|---|---|
INVALID_JSON | 400 | The body is not valid JSON |
UNAUTHORIZED | 401 | Missing or invalid credentials |
COMPANY_BLOCKED | 403 | Company blocked |
VALIDATION_ERROR | 422 | One or more invalid fields |
NOT_FOUND | 404 | The address does not exist in the API (typo in the path, extra trailing slash) |
TRANSACTION_NOT_FOUND | 404 | Transaction does not exist |
TRANSACTION_DUPLICATE | 409 | external_source + external_id already registered |
TRANSACTION_IMMUTABLE | 409 | Transaction already used, cannot be modified |
MERCHANT_NOT_FOUND | 404 | Merchant does not exist |
ALERT_NOT_FOUND | 404 | Alert does not exist |
ALERT_INVALID_STATUS | 422 | Invalid status, or transition not allowed (deadline, expiration or status already final) |
PAYLOAD_TOO_LARGE | 413 | Body above the limit: 1 MB per request, 5 MB in batch upload |
RATE_LIMIT_EXCEEDED | 429 | Request limit exceeded (see below) |
INTERNAL_ERROR | 500 | Unexpected server error |
Rate limit
Section titled “Rate limit”All routes share a limit of 100 requests per minute per IP, including those that answer 401 for invalid credentials. The exception is sending an event from the browser, which has its own cap of 120 per minute and does not count toward the 100.
When you go over it, the API returns:
HTTP/1.1 429 Too Many RequestsRetry-After: 15X-RateLimit-Limit: 100X-RateLimit-Remaining: 0X-RateLimit-Reset: 15{ "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Rate limit exceeded, retry in 15 seconds" }}Use Retry-After. It says, in seconds, how long until the window resets, and the message repeats the same number. Waiting exactly that long is better than guessing: blind exponential backoff can retry too early (and get another 429) or wait longer than needed.
The X-RateLimit-* headers come in every response, not only in the 429, so you can get ahead of it: when X-RateLimit-Remaining gets close to zero, hold the sending instead of waiting for the error. For volume, prefer batch upload, which sends up to 1000 transactions in one request and uses one unit of the limit.
Retrying 5xx errors
Section titled “Retrying 5xx errors”5xx errors are usually transient. Retry with increasing intervals between attempts. Never retry 4xx: they mean an error on your side and will fail again.