Error Responses
The REST API returns errors as a flat JSON object.
Error Format
Section titled “Error Format”{ "statusCode": 401, "code": "UNAUTHENTICATED", "message": "Human-readable description", "details": {}}details is optional and present only for some errors (e.g. validation, rate limiting).
HTTP Status Codes
Section titled “HTTP Status Codes”| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Malformed request or invalid parameters |
| 401 | UNAUTHENTICATED | Invalid or missing authentication |
| 401 | CLI_SIG_INVALID | Signed-request signature failed verification |
| 401 | CLI_IDENTITY_UNKNOWN | The public key is not registered |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | NOT_FOUND | Resource not found |
| 409 | CONFLICT | Resource already exists or state conflict |
| 429 | RATE_LIMITED | Too many requests |
| 500 | INTERNAL_ERROR | Unexpected server error |
| 503 | SERVICE_UNAVAILABLE | An upstream dependency is unavailable |
Validation Errors
Section titled “Validation Errors”Validation errors include field-level details:
{ "statusCode": 400, "code": "VALIDATION_ERROR", "message": "Validation failed", "details": [ { "field": "name", "message": "Required" }, { "field": "exchange_account_id", "message": "Invalid id format" } ]}Rate-Limit Errors
Section titled “Rate-Limit Errors”{ "statusCode": 429, "code": "RATE_LIMITED", "message": "Rate limit exceeded. Please slow down.", "details": { "limit": 100, "remaining": 0, "resetMs": 42000 }}GraphQL Errors
Section titled “GraphQL Errors”GraphQL responses use the standard errors array:
{ "data": null, "errors": [ { "message": "Not authorized", "path": ["me"], "errorType": "Unauthorized" } ]}Many GraphQL operations also return a success/error envelope inside data:
{ "data": { "create_strategy": { "success": false, "error": "Exchange account not found", "data": null } }}
