Rate limits▾

Rate limits

Per-key request limits, the headers that report them, and how to back off.

Limits are per API key, measured over a rolling 60-second window. They are separate from Meta's own messaging tier limits, which cap how many unique contacts you may start conversations with per day.

Endpoint groupRequests / minute
POST /v1/messages600
GET on any resource1200
POST /v1/broadcasts60
POST /v1/media120
Everything else600

Headers

HeaderMeaning
X-RateLimit-LimitCeiling for the current window
X-RateLimit-RemainingRequests left in the window
X-RateLimit-ResetUnix seconds at which the window resets
Retry-AfterSeconds to wait — only present on a 429

Backing off

Node
async function send(body: unknown, attempt = 0): Promise<Response> {
  const res = await fetch("https://api.sendport.tech/v1/messages", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SENDPORT_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": crypto.randomUUID(),
    },
    body: JSON.stringify(body),
  });

  if (res.status !== 429 || attempt >= 5) return res;

  const wait = Number(res.headers.get("retry-after") ?? 2 ** attempt);
  await new Promise((r) => setTimeout(r, wait * 1000));
  return send(body, attempt + 1);
}

Meta messaging tiers are a separate ceiling

A new number starts at 1,000 unique contacts per rolling 24 hours and climbs to 10K, 100K then unlimited as quality holds. Hitting it returns 422 with messaging_limit_reached, not 429.