Errors
What a Gravv error response looks like, what each HTTP status code means, and what to do about each one.
This page shows the shape of a Gravv error, the feature access errors, and what each HTTP status code means.
Gravv uses HTTP status codes to show whether an API request succeeds or fails. A 2xx code means success. A 4xx code means an error in the request. A 5xx code means an error on Gravv's side or a temporary outage.
Error body
Every error except one kind of 503 uses the same envelope. data is null, and error describes the problem. error is usually a string:
{
"data": null,
"error": "missing idempotency key in request headers"
}
Some errors add fields next to error: a machine-readable code, field-level details, and for transfers transfer_status or window. Branch on code when it is present, not on the message text. For example, the API returns this not-found error with HTTP 400:
{
"data": null,
"error": "payee 3f0c6a8e-6b1d-4c1e-9a55-0d2f7b9e4a11: resource not found",
"code": "ERROR_CODE_NOT_FOUND"
}
A few errors carry an object in error instead of a string:
| Status | error |
When |
|---|---|---|
409 |
{"code":"idempotency_in_flight","message":"…"} |
The same Idempotency-Key is still running. See Idempotent requests |
422 |
{"code":"idempotency_key_reused","message":"…"} |
You sent the same Idempotency-Key with a different payload |
413 |
{"code":"request_body_too_large","message":"…","limit":14002176} |
A document upload is too large |
403 |
{"reason":"forbidden","required_any":["…"]} |
Your API key lacks the permission the endpoint needs |
When a Gravv service is briefly unreachable, the API returns 503 with a different body, without data:
{
"error": "service_unavailable",
"message": "A downstream dependency is temporarily unavailable"
}
Read error as either a string or an object, and treat code and details as optional.
Feature access errors
Some products, such as card issuing, card acquiring and the OTC trade desk, need Gravv to enable access for your business. Until Gravv enables access, the endpoint returns 403 with a feature_access_* code and where to request access:
{
"data": null,
"error": {
"code": "feature_access_required",
"message": "Your business does not have access to otc_trade_desk.",
"feature": "otc_trade_desk",
"access_status": "locked",
"request_access_url": "/v1/feature-access/requests",
"documentation_url": "https://docs.gravv.xyz/fx/trade-desk/access"
}
}
The code is one of feature_access_required, feature_access_pending, feature_access_action_required, feature_access_rejected and feature_access_suspended.
Status code summary
| Status code | Meaning | What to do |
|---|---|---|
| 200 | The request succeeded | |
| 400 | Gravv rejected the request. Many endpoints use 400 for every error, including a resource that doesn't exist and some server-side failures, so read the message | Fix the request, then send it with a new Idempotency-Key |
| 401 | The Api-Key header is missing, or the key is invalid. See Authentication |
Use a current key for the environment |
| 403 | Your key lacks a permission, the endpoint is Dashboard-only, or the feature is not enabled for your business | Read the body. A feature-access error says how to request access |
| 404 | The resource doesn't exist, on endpoints that report it this way | Check the id and the environment |
| 409 | A conflict. The same Idempotency-Key is still running, or the transfer is a duplicate or already in progress (ERROR_CODE_DUPLICATE_TRANSACTION, ERROR_CODE_TRANSFER_IN_PROGRESS) |
Wait for Retry-After when the response includes it, then retry |
| 410 | The paused transfer you tried to resume has expired or was cancelled (ERROR_CODE_TRANSFER_PAUSE_EXPIRED, ERROR_CODE_TRANSFER_PAUSE_CANCELLED) |
Start a new transfer |
| 413 | A document upload is too large. In sandbox, any request from about 600 KB gets the uploaded file is too large — the maximum is 10MB |
Send a smaller file. See Formats and limits |
| 422 | The same Idempotency-Key with a different payload, or a transfer refused by a limit, a block, or missing sender details or a supporting document (ERROR_CODE_LIMIT_EXCEEDED and the daily, per-transfer, monthly and annual variants, ERROR_CODE_SUBJECT_BLOCKED, ERROR_CODE_REMITTER_INFORMATION_REQUIRED, ERROR_CODE_SUPPORTING_DOCUMENT_REQUIRED) |
Read code |
| 429 | You hit the rate limit. See Rate limits | Back off, then retry. A POST needs a new Idempotency-Key |
| 500 | An error on Gravv's side | Retry later. For a payment, check whether it ran before you retry |
| 501 | The operation is not available | |
| 503 | A Gravv service is temporarily unavailable, for example ERROR_CODE_LIMITS_UNAVAILABLE on a transfer |
Retry with backoff |
| 504 | A Gravv service timed out | Check whether the operation ran, then retry with backoff |