Errors
The Crane Ledger REST API uses a consistent JSON structure for all error responses. This page describes that format, common error types, and how to handle them in your application.
Error Response Format
All API errors return a JSON object with an error key:
{
"error": {
"type": "validation_error",
"code": "transaction_does_not_balance",
"message": "Transaction does not balance",
"details": {
"total_debits": 150.00,
"total_credits": 100.00,
"difference": 50.00
},
"status": 400
}
}
Error Object Fields
| Field | Type | Description |
|---|---|---|
type | string | High-level error category |
code | string | Machine-readable error code |
message | string | Human-readable description |
details | object | Optional; additional context (e.g. validation fields) |
status | integer | HTTP status code |
The details object, when present, often includes field-level validation errors or extra context to fix the request.
Common Error Types
| Type | HTTP Status | Description |
|---|---|---|
authentication_error | 401 | Invalid, missing, or expired API key |
authorization_error | 403 | API key valid but lacks permission for this operation |
validation_error | 400 | Invalid request body or parameters |
not_found_error | 404 | Resource does not exist or is not accessible |
business_rule_error | 422 | Request is valid but violates a business rule |
rate_limit_error | 429 | Too many requests; retry after backoff |
credit_limit_error | 402 | Insufficient credits for this operation |
server_error | 500 | Internal error; retry with backoff |
Example Error Responses
Authentication Error (401)
{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid or expired",
"status": 401
}
}
Validation Error (400)
{
"error": {
"type": "validation_error",
"code": "invalid_request",
"message": "Request validation failed",
"details": {
"fields": {
"entries": "At least two entries are required",
"entries[0].amount": "Must be a positive number"
}
},
"status": 400
}
}
Business Rule Error (422)
{
"error": {
"type": "business_rule_error",
"code": "transaction_does_not_balance",
"message": "Transaction does not balance",
"details": {
"total_debits": 150.00,
"total_credits": 100.00,
"difference": 50.00
},
"status": 422
}
}
Rate Limit Error (429)
{
"error": {
"type": "rate_limit_error",
"code": "rate_limit_exceeded",
"message": "API rate limit exceeded. Try again later.",
"retry_after": 60,
"status": 429
}
}
Use the retry_after value (seconds) to wait before retrying. See Rate Limits for headers and retry guidance.
Handling Errors in Code
Check the HTTP status and parse the error object to decide how to respond:
Troubleshooting
- 401 Unauthorized – Verify the API key is correct, not expired, and sent as
Authorization: Bearer <key>. - 403 Forbidden – The key may not have permission for this resource or action; check key permissions in the Dashboard or API Keys.
- 404 Not Found – Confirm the URL path and organization ID. Ensure the resource ID exists and belongs to the organization.
- 422 Business rule errors – Read the
messageanddetailsto see which rule was violated (e.g. unbalanced transaction, invalid state transition). - 429 Rate limit – Implement exponential backoff and respect
Retry-Afteror the responseretry_aftervalue. See Rate Limits. - 5xx Server errors – Retry with backoff; if the issue persists, contact support.
Idempotency
For critical write operations, use idempotency keys where supported so that retries do not create duplicate resources.
Need help?
Create a free account to access our support portal. Once signed in, use the Support tab in your dashboard to submit a support ticket — our team typically responds within 24 hours.
- ✨ For LLMs/AI assistants: Read our structured API reference