# Rate limits

These limits apply to the API only — never to your store

Everything on this page counts **requests made with an API key** against `https://api.dzbuild.app/v1`.

Your **storefront**, your **customers checking out**, your **dashboard**, the mobile app, and every built-in feature of the platform are completely unaffected. They do not consume this quota, they are never throttled by it, and hitting a `429` here has **zero** effect on your store staying open and taking orders.

If you have never created an API key, none of this page applies to you.

The per-minute limit is enforced **per store** — all keys belonging to one store share a single budget, so creating more keys never raises the ceiling. It runs on a fixed 60-second window: the counter resets on each wall-clock minute. Because the window is fixed rather than sliding, a burst that straddles a minute boundary can briefly pass more than the ceiling. Handle `429` defensively rather than pacing exactly to the limit.

## Per-minute limits

**Personal API keys are available on the Enterprise plan only.** Keys can only be issued for Enterprise stores, and a key whose store leaves Enterprise, by downgrade or by letting the subscription expire, gets `403 forbidden` ("API access requires an active Enterprise plan") on every call. Nothing needs re-issuing: the same key starts working again the moment the store is back on an active Enterprise plan. Installed-app tokens work on every plan the app accepts: they share the store's per-minute budget and also have their own limit of 120 requests a minute per install.

| Plan             | Requests/min                                                              | Requests/month                                       |
| ---------------- | ------------------------------------------------------------------------- | ---------------------------------------------------- |
| Enterprise       | 600                                                                       | unlimited                                            |
| Every other plan | no personal keys; installed-app tokens share 600, at most 120 per install | no personal keys; unlimited for installed-app tokens |

This ceiling is sized for real integration work: syncing a catalog, running a mobile app or custom storefront, or driving the store from an AI assistant. Normal usage does not come close. If a genuine workload needs more, ask support for a per-store override rather than working around the limit.

There is no monthly cap: usage is bounded by the per-minute ceiling only, unless support has set a per-store override with an explicit monthly allowance (see [Quotas](https://dzbuild.com/api-docs/resources/quotas.md)).

## Expensive endpoints have their own budget

A few endpoints do far more work per call than a normal read: they download and re-encode files, or start background jobs. These carry a second, smaller budget **per store**, on top of the per-minute limit above:

| Endpoint                                                                                                                                                   | Limit       | At once       |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------------- |
| `POST /v1/products/{id}/images`                                                                                                                            | 10 / minute | 3 in parallel |
| `POST /v1/landing-pages/generate`                                                                                                                          | 5 / minute  | 2 in parallel |
| Home page section writes (`/v1/store/home-layout`, `/v1/store/home-layout/*`)                                                                              | 30 / minute | 5 in parallel |
| Courier calls (`POST /v1/orders/{id}/send-to-delivery`, `POST /v1/shipping/providers`, `POST /v1/shipping/providers/test`, `POST /v1/shipping/rates/sync`) | 6 / minute  | 2 in parallel |

Exceeding the per-minute portion returns `429 rate_limited`; exceeding the parallel portion returns `429 too_many_concurrent`, which simply means "retry in a few seconds" — an earlier call is still finishing.

These are deliberately tight. Adding a product's full photo gallery still takes well under a minute, and the cap keeps one integration from slowing the servers that also serve your storefront.

## What happens when you hit a limit

* **Per-minute exceeded** → `429 rate_limited` with a `Retry-After` header (seconds until the window resets). Wait that long and retry.
* **Too many at once** → `429 too_many_concurrent`. Retry in a few seconds.
* **Monthly allowance exhausted** (only possible when a per-store override sets a monthly cap) → `402 quota_exceeded`. Contact support or wait for the next month.

The monthly counter increments once per authenticated request that is not answered from cache — cached `GET`s and `/v1/ping` are free, and failed requests still count.

## Checking your own limits

Call `GET /v1/quotas` (see [Quotas](https://dzbuild.com/api-docs/resources/quotas.md)) to read the limits currently recorded for your store, including any override support has applied to your account.

A per-store override can raise your allowances without changing your plan. If you are building something that genuinely needs sustained higher throughput, contact support with your expected request pattern.
