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

# Errors

> Error codes and response format

All errors follow a consistent envelope format.

## Error response shape

```json theme={null}
{
  "error": {
    "code": "not_found",
    "message": "Signal '0001f3a7b9c8d4e5f6a7b8c9d0e1f2a3b4c5d6e7' not found",
    "status": 404,
    "request_id": "req_8f3a1c9e"
  }
}
```

| Field         | Type    | Description                                                                                      |
| ------------- | ------- | ------------------------------------------------------------------------------------------------ |
| `code`        | string  | Machine-readable error code                                                                      |
| `message`     | string  | Human-readable description                                                                       |
| `status`      | integer | HTTP status code                                                                                 |
| `request_id`  | string  | Correlation ID, also returned in the `X-Request-Id` header. Include it when reporting a failure. |
| `field`       | string  | Present on `422` errors: the parameter that failed validation.                                   |
| `retry_after` | integer | Present on `429` and `503`: seconds to wait before retrying (also the `Retry-After` header).     |

## Error codes

| Status | Code                  | Description                                                                                    |
| ------ | --------------------- | ---------------------------------------------------------------------------------------------- |
| 400    | `bad_request`         | Invalid request parameters (some endpoints return a more specific code, e.g. `invalid_params`) |
| 401    | `unauthorized`        | Invalid or missing API key                                                                     |
| 403    | `forbidden`           | Insufficient permissions                                                                       |
| 404    | `not_found`           | Resource not found                                                                             |
| 409    | `conflict`            | Resource already exists (e.g. duplicate API key)                                               |
| 422    | `validation_error`    | Request validation failed; `field` names the offending parameter                               |
| 429    | `rate_limit_exceeded` | Rate limit exceeded (check `Retry-After`)                                                      |
| 503    | `service_unavailable` | A dependency is temporarily unavailable; retry after `Retry-After`                             |

## Handling errors

<CodeGroup>
  ```python Python SDK theme={null}
  import time

  from gildea import Gildea, RateLimitError, APIError

  client = Gildea()
  try:
      client.signals.list(keyword="AI")
  except RateLimitError as e:
      time.sleep(e.retry_after or 60)
  except APIError as e:
      print(f"Error ({e.status}): {e}")
  ```

  ```python Python (requests) theme={null}
  resp = requests.get(url, headers=headers)
  if resp.status_code == 429:
      retry_after = int(resp.headers.get("Retry-After", 60))
      time.sleep(retry_after)
  elif resp.status_code >= 400:
      error = resp.json()["error"]
      print(f"Error {error['code']}: {error['message']}")
  ```

  ```javascript JavaScript theme={null}
  const resp = await fetch(url, { headers });
  if (resp.status === 429) {
    const retryAfter = parseInt(resp.headers.get("Retry-After") || "60");
    await new Promise(r => setTimeout(r, retryAfter * 1000));
  } else if (!resp.ok) {
    const { error } = await resp.json();
    console.error(`Error ${error.code}: ${error.message}`);
  }
  ```
</CodeGroup>
