Skip to main content
The API limits how many requests each organization can make per minute, so a runaway integration cannot degrade the platform for everyone else. Limits are counted per organization (the owner of the API key), not per key: rotating your API key does not reset your budget.

Limits

Limits use a fixed 60-second window. Once a limit is exceeded, requests in that scope are rejected until the window resets — the Retry-After header tells you how long to wait. The listing budget is counted in addition to the organization budget: a call to GET /v1/contacts consumes one request from both.
Listing endpoints also cap limit at 1000 records per page. Send limit and offset together and iterate using pagination.total_rows from the response.

Response headers

Every response includes the state of your organization budget: On listing endpoints the same headers are also reported for the listing budget with the -heavy suffix (X-RateLimit-Limit-heavy, X-RateLimit-Remaining-heavy, X-RateLimit-Reset-heavy), and the IP budget uses the -ip suffix.

When a limit is exceeded

The API responds with 429 Too Many Requests and a Retry-After header (in seconds):
Wait for Retry-After seconds before retrying. Retrying immediately does not help: the request is rejected again and the window does not reset any sooner.

Best practices

  • Honor Retry-After. Treat 429 as a signal to pause, not as an error to retry in a tight loop.
  • Paginate with limit=1000. A full export of 100,000 contacts is 100 requests — about five minutes at the listing rate — and only needs to run once.
  • Poll on a schedule (for example every few minutes) instead of continuously, and only ask for what changed when the endpoint supports it.
  • Batch on your side. If several systems need the same data, fetch it once and share it rather than having each of them call the API.
If your integration needs higher limits, contact support@contactship.ai with your organization name and expected volume.

Handling 429 in code