Rate limits

Per-plan request limits across Listings and Social, the 429 response shape, and how to back off and retry.

The Listings API meters requests per account against your plan's rate limit. Staying inside the limit keeps your integration responsive; crossing it returns 429 Too Many Requests with everything you need to retry gracefully.

Per-plan limits

Limits are plan-based and enforced per account: every API key on an account draws from the same budget. Requests are metered on three windows: a per-minute burst limit, an hourly limit, and a daily cap. Every request costs the same, regardless of endpoint. A free trial runs on the plan you picked, so it has that plan's limits from the first request.

PlanPer-minute limitPer-hour limitDaily limit
Launch10 req/min600 req/hour7,200 req/day
Growth50 req/min3,000 req/hour36,000 req/day
EnterpriseSet per contractSet per contractSet per contract

Social draws on the same budget

Social endpoints are metered against the same per-account request budget as everything else. A POST /social/bulk-posts carrying 500 rows costs one request, not 500, so bulk is the cheapest way to load a lot of content.

Listings and Social are separate subscriptions, but they are not separate budgets. An account holding both gets the higher of the two tiers' limits, applied once across every endpoint — not the sum, and not one budget per product. A customer on Listings Launch and Social Growth is metered at the Growth numbers above for all of their traffic.

The 429 response

When you exceed a limit the API responds with HTTP 429 and the standard error response. Three fields matter for retries:

  • retry_after_seconds: how long to wait before retrying. The Retry-After HTTP header carries the same value when present.
  • correlation_id: a request identifier to quote if you contact support.
  • doc_url: a link back to the rate_limited entry in the error-codes reference.
JSON
{  "error": {    "code": "RATE_LIMITED",    "message": "Too many requests. Slow down.",    "retry_after_seconds": 30,    "correlation_id": "9f2c1e64-2b1a-4b0e-9f1a-2c7d5e8a1b3c",    "doc_url": "https://listingsapi.com/docs/error-codes#rate_limited"  }}

Handling 429s with backoff

Honor retry_after_seconds when it is present, and otherwise back off exponentially: doubling the delay on each consecutive 429 up to a ceiling, with a little random jitter so a fleet of clients doesn't retry in lockstep.

Python
import randomimport time import requests MAX_RETRIES = 5  def get_with_backoff(url: str, headers: dict, max_retries: int = MAX_RETRIES):    for attempt in range(max_retries):        resp = requests.get(url, headers=headers)        if resp.status_code != 429:            resp.raise_for_status()            return resp.json()         # Prefer the server's hint; fall back to exponential backoff + jitter.        body = resp.json().get("error", {})        retry_after = body.get("retry_after_seconds")        if retry_after is None:            retry_after = min(2 ** attempt, 30) + random.uniform(0, 1)        time.sleep(retry_after)     raise RuntimeError("Still rate limited after retrying")

Staying under the limit

  • Request one page at a time: tight parallel pagination loops are the most common source of 429s. Read pageInfo.hasNextPage and only fetch the next page once the current one returns.
  • Filter server-side with the filter query parameter instead of pulling every page and discarding rows client-side.
  • Cache responses that don't change often rather than re-fetching them on every request.