# Error Handling Guide

## Purpose

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.

## Error Response Structure

All error responses must be returned as JSON and include the following structure:

```json
{
  "errors": [
    {
      "error": "Unauthorized",
      "message": "Access token is missing or invalid.",
      "level": 8
    }
  ]
}
```

### Fields

- `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.

## When to Use Which Status Code

| 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 |


## Guidelines

- 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


## Example Error Responses

### 401 Unauthorized

Returned when the access token is missing, expired, or invalid.

```json
{
  "errors": [
    {
      "error": "Unauthorized",
      "message": "Access token is missing or invalid.",
      "level": 8
    }
  ]
}
```

### 403 Forbidden

Returned when the token is valid but the user doesn't have permission to access the requested resource.

```json
{
  "errors": [
    {
      "error": "Forbidden",
      "message": "You do not have permission to access this company's data.",
      "level": 7
    }
  ]
}
```

### 400 Bad Request

Returned when the request contains malformed or invalid input.

```json
{
  "errors": [
    {
      "error": "BadRequest",
      "message": "The 'startDate' parameter is required and must be in YYYY-MM-DD format.",
      "level": 5
    }
  ]
}
```

### 404 Not Found

Returned when the requested resource does not exist.

```json
{
  "errors": [
    {
      "error": "NotFound",
      "message": "Company with ID 'abc123' was not found.",
      "level": 6
    }
  ]
}
```

### 500 Internal Server Error

Returned when an unexpected error occurs on the server.

```json
{
  "errors": [
    {
      "error": "InternalServerError",
      "message": "An unexpected error occurred. Please try again later.",
      "level": 10
    }
  ]
}
```

### 503 Service Unavailable

Returned during planned maintenance or temporary outages. Reach will automatically retry.

```json
{
  "errors": [
    {
      "error": "ServiceUnavailable",
      "message": "The service is temporarily unavailable for maintenance. Please try again in a few minutes.",
      "level": 7
    }
  ]
}
```