> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.runtype.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.runtype.com/_mcp/server.

# Rate limits and usage

Use this guide to find out why Runtype refused or stopped a run, fix the cause, and keep production executions running. An execution is one Flow or Agent run.

## Find the cause

Most limit responses include a `code` field. Branch on `code`, not on the `error` or `message` text. The following table lists the responses and what to do about each one:

| Status | `code`                                                                | Cause                                                                                                    | What to do                                                                                  |
| ------ | --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| `429`  | `RATE_LIMIT_EXCEEDED`                                                 | You started more executions in a 10-second window than your plan's burst rate allows.                    | Wait for the seconds in `Retry-After`, then retry. Spread out the requests that start runs. |
| `429`  | `TEST_KEY_DAILY_LIMIT_EXCEEDED` or `TEST_KEY_LIFETIME_LIMIT_EXCEEDED` | A Test API key or a test surface key reached its execution limit.                                        | Use a Production API key or a live surface key.                                             |
| `402`  | `SPEND_LIMIT_EXCEEDED`                                                | Your month-to-date spend reached your monthly spend cap.                                                 | Raise or clear the cap, or wait until the time in `resetsAt`.                               |
| `402`  | `DAILY_EVAL_LIMIT`                                                    | You reached your plan's daily limit on eval submissions.                                                 | Wait until midnight UTC, or upgrade your plan.                                              |
| `402`  | `PLATFORM_KEY_SPEND_EXCEEDED`                                         | Platform-key credit is unavailable: credit ran out, the free trial ended, or an automatic top-up failed. | Set a default payment method, or use your own provider API keys (BYOK).                     |
| `503`  | `SERVICE_UNAVAILABLE`                                                 | An end user of your widget or surface reached one of these limits. The response hides the cause.         | Check the causes in this table for your account.                                            |

## Fix a limit

To fix a limit in production, follow these steps:

1. Read the status and the `code` in the response. For a streaming request, read the `execution_error` event. For more information, see [Streaming requests](#streaming-requests).
2. For `RATE_LIMIT_EXCEEDED`, retry after the `Retry-After` interval. To prevent more `429` responses, lower client concurrency, queue requests, or submit large workloads as a [batch](/user-guide/flows/running-flows-in-batch).
3. For a `402`, open **Settings > Billing** and review your credit, payment method, and spend cap.
4. If you use platform keys and need your provider's own limits, connect your own provider API keys. BYOK requires a plan that includes it. For more information, see [Billing and plans](/user-guide/settings/billing-and-plans).
5. For a `503` that your end users see, check your account for the `429` and `402` causes in the table.

## What can return a `429`

Some plans have a burst rate that limits how many executions you can start in a 10-second window. The check runs once when a run starts, not for each step or model call inside the run. If you exceed the burst rate, the API returns `429` with a `Retry-After` header. Plans without a burst rate skip this check.

The response body names the limit:

**`429 response (abridged)`**

```json title="429 response (abridged)"
{
  "error": "Limit Exceeded",
  "message": "Rate limit exceeded. Please retry after 5 second(s).",
  "code": "RATE_LIMIT_EXCEEDED",
  "limitType": "rate",
  "upgradeUrl": "/settings/billing"
}
```

The response also includes `resetsAt` and `stats`.

Your account's execution count never causes a `429`. These other limits also return `429`:

* **Test API keys**: a Test key allows 20 executions per day and 200 in total. For more information, see [Managing API keys](/user-guide/settings/managing-api-keys).
* **Surface API keys**: a test surface key allows 50 executions per UTC day and returns `TEST_KEY_DAILY_LIMIT_EXCEEDED` after that. Each surface key also has per-minute and per-day rate limits, which return the code `RATE_LIMITED` and a `Retry-After` header. For more information, see [Setting up an API surface](/user-guide/products-surfaces/setting-up-an-api-surface).
* **Batch records**: a batch submission is refused when it takes you over 250,000 records per user per hour. This response has no `code` field.
* **Client tokens**: requests from a chat widget have per-token and per-session rate limits. For more information, see [Client tokens and domain restrictions](/user-guide/products-surfaces/client-tokens-and-domain-restrictions#set-session-and-rate-limits).

## What can return a `402`

Spending controls return `402`, not `429`, in these cases:

* **Spend cap** (`SPEND_LIMIT_EXCEEDED`): your month-to-date spend reached your monthly spend cap. New executions don't start. The cap resets at the start of each month (UTC), and `resetsAt` in the response gives that time. A cap of \$0 pauses all new executions.
* **Daily eval limit** (`DAILY_EVAL_LIMIT`): your plan limits how many evals you can submit each day. The count resets at midnight UTC. For more information, see [Running an eval](/user-guide/evals/running-an-eval).
* **Platform-key credit** (`PLATFORM_KEY_SPEND_EXCEEDED`): your credit ran out and automatic top-up didn't replenish it, your free trial ended with no payment method, or an automatic top-up payment failed. Model calls and tools that use platform keys stop working. Models that use your own provider API keys keep working.

A run that is already in progress can also end with `402` when platform-key credit runs out during the run.

Runtype emails your account when your spend reaches 50%, 80%, and 100% of your spend cap. Runtype also emails you when platform-key credit is exhausted or an automatic top-up fails. To change the cap or your payment method, open **Settings > Billing**.

## Other ways a limit appears

The status code alone doesn't identify every limit. Streaming requests and end-user requests report limits differently.

### Streaming requests

When a streaming request is refused before the run starts, the response has status `200`. Read the `code` from the one `execution_error` event in the stream:

**`Refused streaming request (abridged)`**

```text title="Refused streaming request (abridged)"
event: execution_error
data: {"type":"execution_error","kind":"flow","error":{"code":"RATE_LIMIT_EXCEEDED","message":"Rate limit exceeded. Please retry after 5 second(s)."},"code":"RATE_LIMIT_EXCEEDED","upgradeUrl":"/settings/billing"}
```

A streamed run that stops because platform-key credit ran out also ends with an `execution_error` event. Read `code`, or `error.code` when `code` is absent.

### Requests from end users

Requests from a chat widget, a client token, a surface key, or a public surface never show billing details. When one of these requests reaches a rate or spend limit, the API returns `503` with a neutral body. A streaming request gets an `execution_error` event with the same `code` and `message` instead.

The following example shows the `503` body:

**`503 response for end users`**

```json title="503 response for end users"
{
  "error": "Service Unavailable",
  "message": "This assistant is temporarily unavailable. Please try again later.",
  "code": "SERVICE_UNAVAILABLE"
}
```

If your widget shows this message, check your burst rate, spend cap, and credit in **Settings > Billing**.

## Retry after a `429`

When a burst rate applies, a `429` response includes these headers:

**`429 response headers`**

```http title="429 response headers"
Retry-After: 5
RateLimit-Limit: 50
RateLimit-Remaining: 0
RateLimit-Reset: 5
X-Quota-Policy: unlimited
```

`RateLimit-Limit` is your plan's burst rate for each 10-second window. `RateLimit-Reset` gives the same wait in seconds as `Retry-After`. `RateLimit-Remaining` doesn't count down on successful responses, so use a `429` as the signal to slow down. Every account gets `X-Quota-Policy: unlimited` because execution counts have no cap.

The following TypeScript example retries a burst-rate `429` after the `Retry-After` interval:

**`Retry a burst-rate 429`**

```ts title="Retry a burst-rate 429"
async function dispatchWithRetry(body: unknown, maxAttempts = 3): Promise<Response> {
  for (let attempt = 1; ; attempt++) {
    const response = await fetch('https://api.runtype.com/v1/dispatch', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.RUNTYPE_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(body),
    })
    if (response.status !== 429 || attempt === maxAttempts) return response

    const { code } = await response.clone().json()
    if (code !== 'RATE_LIMIT_EXCEEDED') return response

    const waitSeconds = Number(response.headers.get('Retry-After') ?? '5')
    await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1000))
  }
}
```

The example reads your API key from the `RUNTYPE_API_KEY` environment variable. It returns other `429` responses without a retry, because waiting a few seconds doesn't clear them.

## How Runtype limits usage

Runtype doesn't cap the number of executions that you run. No plan has a daily or monthly execution pool or charges execution overage fees, with or without a payment method on file. Test credentials are the exception. For their limits, see [Daily executions](/user-guide/dashboard/daily-executions).

Your spend comes from AI model calls and built-in tools. Prepaid credit and your spend cap can pause new executions. Runtype limits apply when an execution starts. AI providers apply their own rate limits to each model call.

Your key setup decides which provider limits apply to each model call:

* **Platform keys** use shared Runtype capacity. Provider throttling can slow responses during peak usage.
* **Bring your own key (BYOK)** uses your provider account's limits, and the provider bills you directly. To connect your keys, see [Connecting AI model providers](/user-guide/integrations/connecting-ai-model-providers).

For a full comparison, see [Platform keys vs. bring your own key (BYOK)](/user-guide/getting-started/platform-keys-vs-byok).

## Check your usage

Use these places to monitor usage:

* The **Activity** chart on Dashboard home shows how many runs started in each 24-hour interval.
* **Settings > Usage** shows spend by model and tool. For more information, see [Usage data](/user-guide/settings/usage-data).
* **Settings > Billing** shows your credit, automatic top-up, and spend cap.

## Reduce cost and latency

Use these practices to reduce cost and latency:

* Cache repeated results in [Records](/user-guide/records/what-are-records) when you don't need to run the same Flow again.
* Choose a smaller model for high-volume steps. Spend, not execution count, sets platform-key cost.
* Upgrade your plan when you need BYOK, faster schedules, or longer log retention.

## Next steps

Continue with these guides:

* [Billing and plans](/user-guide/settings/billing-and-plans): manage credit, your spend cap, and plan features.
* [Daily executions](/user-guide/dashboard/daily-executions): read the dashboard execution counts.
* [Common errors and solutions](/user-guide/troubleshooting-faq/common-errors-and-solutions): fix other API and Flow errors.
* [Authentication](/developer-guides/getting-started/authentication#rate-limits): read the API rate-limit headers and error responses.
* [Managing AI models](/user-guide/settings/managing-ai-models): choose models for your Flows and Agents.
* [API error reference](/user-guide/troubleshooting-faq/api-error-reference): look up error codes, status codes, and limit responses.
* [Credits and spend limits](/user-guide/settings/credits-and-spend-limits): buy credit, set up auto top-up, and set a spend cap.