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

# Errors and rate limits

> A consistent error envelope, the status codes you will see, and how rate limiting works.

Errors are returned as JSON with a consistent shape so you can handle them uniformly.

## Error envelope

```json theme={null}
{
  "error": "rate_limited",
  "message": "Too many requests.",
  "retry_after": 30
}
```

`error` is a stable machine-readable code; `message` is human readable. Some errors carry extra fields (for example `retry_after` on a `429`, field-level details on a `422`, or a `reference` correlation code on a `500`).

## Status codes

| Code  | Meaning                 | What to do                                                                                                                                             |
| ----- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `200` | Success                 | Read the body.                                                                                                                                         |
| `401` | Not authenticated       | Check the bearer token; it may be missing, expired, or revoked.                                                                                        |
| `403` | Not permitted           | The key lacks the required scope, or your shop does not have API access.                                                                               |
| `404` | Not found               | The resource does not exist for this shop.                                                                                                             |
| `409` | Conflict                | The request conflicts with an existing resource. Customer creation returns `duplicate_customer` with `existing_customer_id` when a duplicate is found. |
| `422` | Validation failed       | Fix the request; the body lists what was wrong.                                                                                                        |
| `429` | Rate limited            | Back off and retry after `Retry-After`.                                                                                                                |
| `500` | Server error            | Something went wrong on our side. The body carries a short `reference` code; retry later, and quote the `reference` to support if the error persists.  |
| `503` | Temporarily unavailable | The API is briefly offline for maintenance. Retry later.                                                                                               |

Identifiers are scoped to your shop. A resource that belongs to another shop is reported as `404`, never another shop's data.

## Rate limiting

Requests are rate limited per token, per shop, and per IP address. When you exceed any of these limits you receive a `429` carrying:

* `Retry-After` (seconds to wait),
* `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset`.

Respect `Retry-After` and use exponential backoff. Spread bulk reads over time rather than bursting.

## Good citizenship

* Cache responses where you can and poll with `filter[updated_since]` instead of re-reading everything.
* Prefer webhooks for change notifications; reserve polling for reconciliation.
* Treat repeated `404`s as a bug in your integration, not a way to discover records.
