> ## Documentation Index
> Fetch the complete documentation index at: https://developer.zeeg.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Reference for HTTP status codes and error response shapes returned by the Zeeg API, with examples for 400, 401, 403, 404, 409, 422, and 500 errors.

The Zeeg API uses standard HTTP status codes to indicate the success or failure of a request. Codes in the `2xx` range indicate success, `4xx` codes indicate a client error, and `5xx` codes indicate a server-side issue.

## Status codes

| Code  | Meaning               | Description                                                        |
| ----- | --------------------- | ------------------------------------------------------------------ |
| `201` | Created               | The resource was created successfully.                             |
| `400` | Bad Request           | The request is malformed or contains invalid parameters.           |
| `401` | Unauthorized          | Authentication is missing or invalid.                              |
| `403` | Forbidden             | You do not have permission to access the resource.                 |
| `404` | Not Found             | The requested resource does not exist.                             |
| `409` | Conflict              | The resource already exists or conflicts with the current state.   |
| `422` | Unprocessable Entity  | The request body failed validation.                                |
| `429` | Too Many Requests     | You have exceeded the rate limit. See [Rate Limits](/rate-limits). |
| `500` | Internal Server Error | Something went wrong on our end.                                   |

## Error response shapes

<Note>
  The exact response shape varies slightly between endpoints. Some endpoints use an `error` field, while others use a `success` + `message` pattern. Always check the HTTP status code first, then parse the response body.
</Note>

<Tabs>
  <Tab title="400 Bad Request">
    Returned when the request is malformed or a required parameter is missing.

    ```json theme={null}
    {
      "success": false,
      "message": "Missing required parameter: event_uuid.",
      "status": 400
    }
    ```

    <ResponseField name="success" type="boolean">
      Always `false` for error responses.
    </ResponseField>

    <ResponseField name="message" type="string">
      A human-readable description of the error.
    </ResponseField>

    <ResponseField name="status" type="integer">
      The HTTP status code.
    </ResponseField>
  </Tab>

  <Tab title="401 Unauthorized">
    Returned when the `Authorization` header is missing, malformed, or the API key is invalid.

    ```json theme={null}
    {
      "message": "Unauthenticated."
    }
    ```

    <ResponseField name="message" type="string">
      A human-readable description of the error.
    </ResponseField>
  </Tab>

  <Tab title="403 Forbidden">
    Returned when the authenticated user does not have permission to access the requested resource.

    ```json theme={null}
    {
      "success": false,
      "message": "You cannot access this resource.",
      "status": 403
    }
    ```

    <ResponseField name="success" type="boolean">
      Always `false` for error responses.
    </ResponseField>

    <ResponseField name="message" type="string">
      A human-readable description of the error.
    </ResponseField>

    <ResponseField name="status" type="integer">
      The HTTP status code.
    </ResponseField>
  </Tab>

  <Tab title="404 Not Found">
    Returned when the requested resource does not exist.

    ```json theme={null}
    {
      "error": "Resource not found"
    }
    ```

    <ResponseField name="error" type="string">
      A human-readable description of the error.
    </ResponseField>
  </Tab>

  <Tab title="409 Conflict">
    Returned when the resource already exists or the request conflicts with the current state.

    ```json theme={null}
    {
      "success": false,
      "message": "Resource already exists.",
      "status": 409
    }
    ```

    <ResponseField name="success" type="boolean">
      Always `false` for error responses.
    </ResponseField>

    <ResponseField name="message" type="string">
      A human-readable description of the error.
    </ResponseField>

    <ResponseField name="status" type="integer">
      The HTTP status code.
    </ResponseField>
  </Tab>

  <Tab title="422 Unprocessable Entity">
    Returned when the request body fails validation. The `errors` object contains field-level details.

    ```json theme={null}
    {
      "message": "The given data was invalid.",
      "errors": {
        "field_name": [
          "The field_name field is required."
        ]
      }
    }
    ```

    <ResponseField name="message" type="string">
      A summary of the validation failure.
    </ResponseField>

    <ResponseField name="errors" type="object">
      A map of field names to arrays of validation error messages.
    </ResponseField>
  </Tab>

  <Tab title="500 Internal Server Error">
    Returned when an unexpected error occurs on our side. If this persists, contact support.

    ```json theme={null}
    {
      "success": false,
      "message": "An unexpected error occurred.",
      "status": 500
    }
    ```

    <ResponseField name="success" type="boolean">
      Always `false` for error responses.
    </ResponseField>

    <ResponseField name="message" type="string">
      A human-readable description of the error.
    </ResponseField>

    <ResponseField name="status" type="integer">
      The HTTP status code.
    </ResponseField>
  </Tab>
</Tabs>

## Best practices

* **Check the HTTP status code first.** The status code is the most reliable indicator of what happened. Parse the response body only after determining the status.
* **Handle both error shapes.** Some endpoints return `{"error": "..."}` while others return `{"success": false, "message": "...", "status": ...}`. Your client code should handle both.
* **Use 422 errors for form validation.** The `errors` object gives you per-field messages you can surface directly to users.
* **Retry on 500 errors.** Internal server errors are transient. Use exponential backoff when retrying.
