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

# Limits and quotas

> Plan allowances, API rate limits, the plan limit error, import size, copilot limits and when a version comparison can give a verdict.

Signal has two kinds of limit. Plan allowances follow your plan and count volume. Rate limits and sizes protect the service and are the same on every plan. This page lists both and what you see when you reach one. [Pricing](/billing/pricing) has the counting rules and the worked example.

## Plan allowances

| | Free | Starter | Growth | Scale | Enterprise |
| - | - | - | - | - | - |
| Price per month, billed monthly | \$0 | \$49 | \$149 | \$399 | From \$1,500 |
| Price per month, billed yearly | \$0 | \$39 | \$119 | \$319 | Custom |
| Charged once a year | \$0 | \$468 | \$1,428 | \$3,828 | Custom |
| Analysed calls a month | 200 | 1,500 | 5,000 | 15,000 | Custom (50,000+) |
| Agents | 1 | 3 | 10 | 25 | Unlimited |
| Copilot messages a month | 20 | 100 | 300 | 600 | Custom |
| Simulated test calls a month | 10 | 50 | 200 | 500 | Custom |
| Seats | 2 | 3 | 10 | 20 | Unlimited, SSO |
| Price per analysed call at full use, billed monthly | \$0 | \$0.033 | \$0.030 | \$0.027 | From \$0.030 |

Every plan includes the board, flow, traces, versions, the REST API and the MCP server. Plans differ in volume, not in features. Prices are in US dollars. Analysed calls, copilot messages and simulated test calls are counted per billing period. Agents and seats are totals.

| Allowance | What counts | At the limit |
| - | - | - |
| Analysed calls | One per 10 minutes started, when Signal takes a call for analysis | Calls keep importing and wait. Analysis resumes after an upgrade or at the reset. No error |
| Agents | Agents in the workspace now, not a monthly count. The demo agent is excluded | Connecting another is refused with a 402 |
| Copilot messages | Each message in the brief chat or the copilot, and each quick check | The copilot box is disabled and the brief chat refuses. In the app, a notice with an upgrade link |
| Simulated test calls | One per test and persona in a run. Calibration counts one per test | The whole run is refused before it starts, with a 402 |
| Seats | People in your organization | Set by your plan. Signal does not count or remove members |

A Free workspace's period is the calendar month in UTC. A paid workspace's period is its billing period. Unused allowance does not carry over. **Plan and usage** under **Settings** shows each count against its limit.

## Plan limit errors

A request that passes a plan allowance is refused with HTTP 402 and the code `quota_exceeded`. The API and the MCP server return the same fields as the app, in the API's error object. `error.quota` says which limit, how much is used and which plan.

```json 402 from POST /v1/agents/{agentId}/runs theme={null}
{
  "error": {
    "type": "budget_error",
    "code": "quota_exceeded",
    "message": "This run needs 12 simulated calls and Starter has 4 of 50 left this month. Run fewer tests or upgrade.",
    "param": null,
    "requestId": "req_3f9a1c07d2b84e6a5c1d9b30",
    "quota": {
      "metric": "test_calls",
      "limit": 50,
      "used": 46,
      "plan": "starter",
      "upgradePath": "/billing"
    }
  }
}
```

An MCP tool returns the same object as a tool error, with the status beside it:

```json Tool error from start_run theme={null}
{
  "status": 402,
  "error": {
    "type": "budget_error",
    "code": "quota_exceeded",
    "message": "This run needs 12 simulated calls and Starter has 4 of 50 left this month. Run fewer tests or upgrade.",
    "param": null,
    "requestId": "req_3f9a1c07d2b84e6a5c1d9b30",
    "quota": { "metric": "test_calls", "limit": 50, "used": 46, "plan": "starter", "upgradePath": "/billing" }
  }
}
```

| Field | Meaning |
| - | - |
| `quota.metric` | The allowance: `analysed_calls`, `agents`, `copilot_messages` or `test_calls` |
| `quota.limit` | What the plan includes for that metric |
| `quota.used` | What the workspace has used in the period (agents: the number connected) |
| `quota.plan` | The plan: `free_org`, `starter`, `growth`, `scale` or `enterprise` |
| `quota.upgradePath` | The app page to change plan: `/billing`, which is **Plan and usage**, under the app address |

Through the API and the MCP server, only `test_calls` reaches you today. Starting a run, or calibrating from a signed-in session, spends simulated test calls. The copilot, the brief chat and connecting agents exist in the app only, and calls past the analysed-call allowance wait instead of failing. In the app, the same refusal shows as a notice with **See plans**. On Enterprise the message ends "Contact us to raise the limit."

Do not retry a 402 `quota_exceeded` as it is. Nothing changes until the period resets, you upgrade, or you ask for fewer simulated calls.

Two other 402 codes are budgets and settings, not the plan:

* `budget_exceeded`: your key's monthly budget, the agent's test budget or the workspace's AI model allowance did not cover the request.
* `testing_not_configured`: testing is not set up for the agent.

The AI model allowance is a workspace limit on Signal's AI features over the last 30 days. It is separate from your plan, so an upgrade does not raise it. When it is used up, AI features pause, and they resume as older usage leaves the 30-day window. Through the API, a rescore it refuses shows as `budget_exceeded`.

## API rate limits

Rate limits count requests in token buckets. A bucket holds the burst size and refills steadily at the rate, so after a quiet spell you can send a burst, then the sustained rate.

| Limit | Applies to | Rate a minute | Burst |
| - | - | - | - |
| All requests | Each API key, or each signed-in person | 600 | 120 |
| Writes (a write route also draws from the all-requests bucket) | Each API key, or each signed-in person | 60 | 20 |
| Workspace | Every key, person and MCP call together, shared with the app | 600 | 600 |
| AI-backed routes (brief chat, test generation, persona drafts, rescore) | The workspace | 10 | 10 |
| MCP endpoint | Each client address | 600 | 120 |
| Failed authentication | Each client address, across the app, the API and MCP | 30 | 30 |

Every `/v1` response carries the tighter of the key's buckets:

| Header | Meaning |
| - | - |
| `RateLimit-Limit` | The bucket size |
| `RateLimit-Remaining` | Requests left in the bucket |
| `RateLimit-Reset` | Seconds until the bucket is full again |
| `Retry-After` | On a 429 only: seconds to wait before the next request |
| `Request-Id` | The id of this request, also in `error.requestId`. Quote it when you ask for help |

A refused request returns HTTP 429 with the code `rate_limited`. A client address that has failed authentication too often gets `too_many_failed_authentications` instead, with or without a valid key, until its failures age out.

```json 429 theme={null}
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limited",
    "message": "Too many requests. Retry after 1 second(s).",
    "param": null,
    "requestId": "req_b41e7c90a2d85f3617e0c9a4"
  }
}
```

Wait for `Retry-After`, then retry. Treat the numbers as a guide to sustained use, not a guarantee.

Calibrating tests needs a signed-in session. Every API key is refused with 403 and the code `people_only`.

## Import limits

These are the limits on the hosted service. They bound how much one import brings in. They are not the plan allowance.

| Limit | Value |
| - | - |
| How far back an import reaches | 30 days |
| Calls in one import | 1,000 |
| First import, on approving the brief | The latest 500 calls from the last 30 days |

After that, new calls arrive on their own, within minutes of ending, and are not held to the import size. How many are analysed is set by your plan's analysed-call allowance. A call past it is stored and waits. The import status on **Agent config** says how many are waiting, such as "120 analysed, 30 waiting for next month or an upgrade." See [Connect Retell](/guides/connect-retell).

## Copilot limits

| Limit | Value |
| - | - |
| Message length | 8,000 characters |
| Answers at a time | One. **Stop** ends an answer early |

A message counts once against the copilot allowance however many lookups it takes. Each quick check counts as one more. A question that needs too many lookups, a very long call or a very large lookup is cut short, and the copilot answers from what it read. Narrow the question if that happens.

The copilot also has a usage limit of its own over the last 30 days, the same on every plan, so an upgrade does not raise it. At that limit it says "This workspace has reached the copilot's spending limit for this period." It also pauses when the workspace's [AI model allowance](#plan-limit-errors) is used up. See [Copilot overview](/copilot/overview).

## Version comparisons

A comparison needs enough calls on each version before it gives a verdict. With too few, the measure reads **Not enough calls** and no verdict is given, however large the difference looks. Wait for more calls on the new version.

An issue's fix verdict also waits until the live version has taken calls for the agent's grace period, 7 days by default. You can change it with **Resolved after** on the **Issues** page. See [Versions](/concepts/versions).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.