This guide defines how your API should handle and respond to errors when accessed by Reach. Proper error handling ensures a smooth integration experience, supports troubleshooting, and helps maintain a reliable sync process.
All error responses must be returned as JSON and include the following structure:
{ "errors": [ { "error": "Unauthorized", "message": "Access token is missing or invalid.", "level": 8 } ] }
- errors: An array of one or more error objects
- error: A short machine-readable label or code
- message: A clear, human-readable explanation of the issue
- level (optional): A numeric severity level from 1 (informational) to 10 (critical failure)
Even if there is only one issue, wrap it in the errors[] array.
| Scenario | Status Code | Notes |
|---|---|---|
| Missing or invalid access token | 401 Unauthorized | Token is absent, expired, or incorrect |
| Token is valid but lacks access | 403 Forbidden | Token exists but isn’t allowed to access the requested resource |
| Company ID or input is invalid | 400 Bad Request or 404 Not Found | Use 400 for malformed input, 404 for missing resource |
| Your system is down or something failed | 500 Internal Server Error | Unexpected server error |
| Temporary unavailability (e.g., maintenance) | 503 Service Unavailable | Temporary — Reach will retry |
| No data available but request was valid | 200 OK with empty array or 204 No Content | Use when there’s simply no data to return, not an error |
- Always return JSON, even on errors
- Use proper status codes — never return 200 OK for errors
- Use the errors[] array for consistency, even if there’s only one error
- Set level to reflect the severity:
- 1–3: Informational / Non-blocking
- 4–6: Warning / Unexpected but not fatal
- 7–10: Errors that prevent data sync or indicate system failure
- Keep logs of all failed requests for troubleshooting
- Avoid exposing sensitive information in error messages