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

# Rate limits

> Integration API and MCP rate limits, headers, and retry behavior.

Forecastable enforces per-token rate limits on Integration API requests and MCP tool calls. Limits are counted in rolling one-minute windows and scoped by API key or OAuth token, organization, endpoint group, and read vs write traffic.

## How limits are applied

Each authenticated request consumes one unit from a bucket identified by:

* **Token** — the API key or OAuth access token ID
* **Organization** — `X-Organization-Id` when present, otherwise `global`
* **Endpoint group** — the API surface area (accounts, contacts, opportunities, and so on)
* **Verb** — read (`GET`, `HEAD`, `OPTIONS`) or write (`POST`, `PUT`, `PATCH`, `DELETE`)

REST endpoints and MCP tools that call the same underlying resources share these buckets. For example, `listAccounts` over REST and `listAccounts` over MCP both count against the **accounts** group for that token and organization.

MCP tool invocations are always counted as **write** traffic for rate-limit purposes, even when the tool only reads data.

## Limits by endpoint group

All windows are **60 seconds**.

| Endpoint group      | Read limit / min | Write limit / min |
| ------------------- | ---------------: | ----------------: |
| `foundation`        |              120 |                60 |
| `organizations`     |               60 |               60¹ |
| `accounts`          |              120 |                60 |
| `contacts`          |              120 |                60 |
| `opportunities`     |              120 |                60 |
| `relationship_maps` |               60 |                30 |
| `feed`              |               30 |                —² |
| `engage`            |               60 |                30 |
| `engage_send`       |               —² |                20 |
| `engage_queue`      |               60 |                30 |
| `engage_analytics`  |               20 |                —² |
| `plans`             |               90 |                45 |
| `calendar`          |               60 |                30 |

¹ When the write limit is `0`, write traffic uses the read limit instead.\
² No limit is configured for that verb; the request is not rate-limited on that axis.

`GET /meta` is public and does not consume authenticated rate-limit buckets.

## Response headers

Successful responses within a limit include:

```http theme={null}
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 119
X-RateLimit-Reset: 1718380800
```

`X-RateLimit-Reset` is a Unix timestamp (seconds) for when the current window resets.

## Rate limit errors

When a bucket is exhausted, Forecastable returns **HTTP 429** with error code `rate_limit_exceeded`:

```json theme={null}
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded.",
    "details": {
      "limit": 60,
      "retryAfterSeconds": 42,
      "endpointGroup": "accounts",
      "write": true
    }
  }
}
```

The response also includes:

```http theme={null}
Retry-After: 42
```

Wait at least `retryAfterSeconds` (or use the `Retry-After` header) before retrying the same class of request.

MCP tool failures use the same error code with `details.toolName` set to the tool that was throttled.

## Retry guidance

* **Backoff** — honor `Retry-After` / `retryAfterSeconds` before retrying.
* **Spread reads** — paginate list endpoints with `limit` and `cursor` instead of polling aggressively.
* **Batch writes** — use bulk endpoints where available (for example `bulkCreateAccounts` or `POST /engage/campaigns/bulk`) instead of many single-record writes.
* **Scope by org** — limits are per organization when `X-Organization-Id` is set; separate orgs do not share the same bucket.

## Engage sends: idempotency and provider pauses

Outbound Engage operations (`POST /engage/messages/send` and `POST /engage/campaigns/{campaignId}/start`) require an `Idempotency-Key` header in addition to the `engage_send` rate limit:

```http theme={null}
Idempotency-Key: 8f7d3a2e-1b4c-4f6a-9e0d-5c8b7a6f4e3d
```

* Retrying with the **same key and same payload** replays the stored result (the response carries `Idempotency-Replayed: true`) without sending again.
* Reusing a key with a **different payload** returns `409 conflict`.
* A duplicate request while the original is still in flight returns `409 conflict`; retry after the original completes.
* Keys are stored per organization, token, and operation, and expire after 24 hours.

Separately from Forecastable's rate limits, email providers can throttle a sender. When a sender is paused, immediate sends return **429** with a `retryAt` detail; scheduled sends are accepted and retried by the delivery worker after the pause lifts.

## MCP-specific notes

The [MCP server](/developers/mcp) applies the same store and endpoint groups as the REST API. Each tool maps to a group such as `accounts` or `contacts`.

Because MCP counts tool calls as write traffic, read-only tools such as `listAccounts` use each group's **write** limit (60 requests per minute for accounts, contacts, and opportunities).

`getMeta` uses the `foundation` write bucket (60 per minute) when called over MCP.

## Configuration status

`GET /api/v1/meta` reports whether rate limiting is enabled and which store backs counters:

```bash theme={null}
curl -s https://app.forecastable.com/api/v1/meta | jq '.rateLimiting'
```

Example:

```json theme={null}
{
  "enabled": true,
  "store": "shared"
}
```

Production uses a shared store so limits apply consistently across app instances. Development environments may use an in-memory store.

## Related guides

<Card title="API keys" icon="key" href="/developers/api-keys">
  Rate limits apply per issued API key.
</Card>

<Card title="Scopes" icon="list" href="/developers/scopes">
  Scope errors (`403`) are separate from rate limits (`429`).
</Card>

<Card title="MCP server" icon="https://mintcdn.com/forecastable/fU69crspsqRT-kfC/images/mcp.png?fit=max&auto=format&n=fU69crspsqRT-kfC&q=85&s=ecb2d15b0f6d90ada43faa0eb38b8746" href="/developers/mcp" width="32" height="32" data-path="images/mcp.png">
  MCP tools share Integration API rate-limit buckets.
</Card>

<Card title="GET /meta" icon="code" href="/api-reference/meta/get-integration-api-metadata">
  Live metadata including rate-limit configuration.
</Card>
