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

# Errors

> Error codes and how to handle them.

All errors follow the same format:

```json theme={null}
{
  "error": {
    "code": "not_found",
    "message": "Note not found"
  }
}
```

## Error codes

| HTTP status | Code                 | Description                                                                   |
| ----------- | -------------------- | ----------------------------------------------------------------------------- |
| 400         | `validation_error`   | Invalid request body or query parameters. Check the `message` for details.    |
| 401         | `invalid_api_key`    | Missing, malformed, expired, or revoked API key.                              |
| 403         | `forbidden`          | Your API key doesn't have the required scope for this endpoint.               |
| 404         | `not_found`          | The resource doesn't exist or belongs to another user.                        |
| 405         | `method_not_allowed` | Wrong HTTP method. Check the endpoint documentation.                          |
| 409         | `conflict`           | Duplicate resource — for example, a folder with the same name already exists. |
| 429         | `rate_limited`       | Rate limit exceeded. Check the `Retry-After` header.                          |
| 500         | `internal_error`     | Something went wrong on our end. Retry after a short delay.                   |

## Handling errors

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    const res = await fetch(url, { headers: { Authorization: `Bearer ${KEY}` } });

    if (!res.ok) {
      const { error } = await res.json();
      if (error.code === "rate_limited") {
        const retryAfter = res.headers.get("Retry-After");
        await new Promise((r) => setTimeout(r, retryAfter * 1000));
        // retry the request
      }
      throw new Error(`${error.code}: ${error.message}`);
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import time, requests

    res = requests.get(url, headers={"Authorization": f"Bearer {KEY}"})

    if res.status_code == 429:
        retry_after = int(res.headers.get("Retry-After", 5))
        time.sleep(retry_after)
        # retry the request

    res.raise_for_status()
    ```
  </Tab>
</Tabs>
