Skip to main content
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
  • OrganizationX-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. ¹ 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:
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:
The response also includes:
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:
  • 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 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:
Example:
Production uses a shared store so limits apply consistently across app instances. Development environments may use an in-memory store.

API keys

Rate limits apply per issued API key.

Scopes

Scope errors (403) are separate from rate limits (429).

MCP server

MCP tools share Integration API rate-limit buckets.

GET /meta

Live metadata including rate-limit configuration.