Error Handling
When a request fails, Monetro returns a consistent error response with an HTTP status code, a machine-readable error code, and a human-readable message.
Error Response Format
{
"error": {
"message": "Customer not found",
"code": "NOT_FOUND",
"status": 404
}
}
| Field | Type | Description |
|---|---|---|
message | string | Human-readable description of the error |
code | string | Machine-readable error code (see table below) |
status | number | HTTP status code |
HTTP Status Codes
| Status | Meaning | When It Occurs |
|---|---|---|
400 | Bad Request | Invalid input, missing required fields, validation errors |
401 | Unauthorized | Missing or expired access token |
403 | Forbidden | Insufficient role permissions or plan limit reached |
404 | Not Found | Resource does not exist or is not accessible to your tenant |
409 | Conflict | Duplicate resource (e.g., duplicate email on user creation) |
422 | Unprocessable Entity | Semantically invalid request (e.g., invoice total mismatch) |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Unexpected server error |
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
INVALID_INPUT | 400 | Request body failed validation |
MISSING_FIELD | 400 | A required field is missing |
INVALID_FORMAT | 400 | A field has an invalid format (e.g., malformed email) |
NOT_FOUND | 404 | The requested resource was not found |
UNAUTHORIZED | 401 | Authentication is required or the token is invalid |
TOKEN_EXPIRED | 401 | The access token has expired --- refresh it |
FORBIDDEN | 403 | Your role does not permit this operation |
RATE_LIMITED | 429 | Too many requests --- wait and retry |
DUPLICATE | 409 | A resource with the same unique identifier already exists |
PLAN_LIMIT | 403 | Your subscription plan does not include this feature |
IMMUTABLE | 400 | The resource cannot be modified (e.g., finalized invoice) |
DEPENDENCY | 400 | The resource cannot be deleted due to existing dependencies |
PROVIDER_ERROR | 502 | An external service (e.g., email, OCR) returned an error |
INTERNAL_ERROR | 500 | An unexpected server error occurred |
Handling Errors
Token Expiry (401)
When you receive a 401 with code TOKEN_EXPIRED, refresh your access token:
curl -X POST https://app.monetro.at/api/auth/refresh \
-b cookies.txt \
-c cookies.txt
If the refresh also returns 401, the refresh token has expired and you must re-authenticate via login.
In a frontend application, use an HTTP interceptor that automatically retries the failed request after refreshing the token. The Monetro frontend uses an Axios interceptor for this pattern.
Validation Errors (400)
Validation errors may include additional detail about which fields failed:
{
"error": {
"message": "Validation failed",
"code": "INVALID_INPUT",
"status": 400,
"details": [
{ "field": "email", "message": "Invalid email format" },
{ "field": "taxRate", "message": "Must be one of: 0, 10, 13, 20" }
]
}
}
Rate Limiting (429)
When rate-limited, check the Retry-After header for the number of seconds to wait:
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Implement exponential backoff in your integration to handle rate limits gracefully.
Server Errors (500)
If you receive a 500 Internal Server Error, the issue is on the Monetro side. These errors are automatically logged and the team is notified. If the problem persists, contact support at [email protected].