Rate Limits
Understanding and handling API rate limits.
The Linq API enforces rate limits to protect Apple’s ecosystem and prevent automated feedback loops between bots.
Recommended daily volume
Section titled “Recommended daily volume”We recommend limiting message volume to a combined total of up to 7,000 inbound and outbound messages per day per line. Steady high volume with healthy reply rates is usually fine, but lines that go past this do occasionally get flagged, and ramping a quiet line up to it quickly adds to that risk.
There’s no hard daily cap — the API won’t return a 429 for crossing 7,000 — so control volume on your end: ramp lines up gradually, spread new users across lines in your onboarding flow, and add lines rather than pushing one past the recommendation. See Phone Reputation for how send volume factors into a line’s reputation.
Per-phone-pair rate limit
Section titled “Per-phone-pair rate limit”The API enforces a rate limit of 30 messages per 60-second window for each unique sender–recipient pair. This is designed to prevent automated feedback loops where two numbers (i.e. bots) rapidly exchange messages.
When exceeded, the API returns HTTP 429 with a Retry-After header (seconds until reset) and error code 1007. The same value is also available as retry_after in the error body. Hitting this limit almost always means a bug — check for retry loops, duplicate sends, or webhook handlers that inadvertently reply to themselves.
Capability check rate limit
Section titled “Capability check rate limit”Capability check endpoints (/v3/capability/check_imessage and /v3/capability/check_rcs) are also rate-limited to prevent abuse (e.g. using them to enumerate which numbers are on iMessage). Excessive calls return the same HTTP 429 with Retry-After and error code 1007.
Capability checks are limited to 1 per 10 seconds. Cache results briefly (minutes, not days) rather than re-checking the same address on every send — capability is stable over short windows and the cache reduces your risk of hitting this limit.
Rate limit response
Section titled “Rate limit response”When you hit a rate limit, the API returns HTTP 429 Too Many Requests with a Retry-After header and this body:
{ "success": false, "error": { "status": 429, "code": 1007, "message": "Rate limited. Try again in 45 seconds.", "retry_after": 45, "doc_url": "https://docs.linqapp.com/error/codes/1xxx/1007/" }, "trace_id": "trace_abc123def456"}The retry_after field mirrors the Retry-After header and is only present on 429 responses. See Error Codes for the full envelope shape used by all error responses.
Handling rate limits
Section titled “Handling rate limits”On a 429 response, prefer the Retry-After header when present; fall back to exponential backoff (e.g. 1s → 2s → 4s) otherwise. Do not retry on 429 more than a few times — keep an upper bound and surface the failure if you keep hitting the wall.
Tip: The official SDKs handle this automatically with exponential backoff. You only need custom retry logic if you’re calling the API directly.
Best practices
Section titled “Best practices”- Queue messages — Use a message queue to control send rate rather than sending as fast as possible
- Monitor usage — Track your daily message count to avoid hitting limits unexpectedly
- Batch wisely — Space out bulk sends rather than sending all at once
- Use idempotency keys — Include an
idempotency_keyfield in the message body on retries to prevent duplicates (see Sending Messages)
Other error codes
Section titled “Other error codes”Rate limits aren’t the only reason requests can fail. See Error Codes for the complete reference, including infrastructure errors (3xxx) that may also require retry logic. See the Send Message and Create Chat API references for endpoint details.