Skip to content
V2 (Legacy) API ReferenceGet started
Platform

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.

We recommend limiting message volume to a combined total of up to 7,000 inbound and outbound messages per day per line. Volume north of the recommended range has the potential to degrade performance.

There are no hard caps on daily volume (excluding sandbox accounts). These recommendations are meant to optimize the performance of your lines. We recommend you control volume via onboarding flows you build on your end.

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.

Sandbox accounts are the exception to the “no hard caps” rule:

  • 100 messages per day — Resets at midnight UTC

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.

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.

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
},
"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.

Prefer the Retry-After header when present; fall back to exponential backoff otherwise:

async function sendWithRetry(
client: LinqAPIV3,
chatId: string,
message: MessageParams,
maxRetries = 3,
) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await client.chats.messages.send(chatId, message);
} catch (error) {
if (error.status === 429 && attempt < maxRetries) {
const retryAfter = Number(error.headers?.['retry-after']);
const delayMs = Number.isFinite(retryAfter)
? retryAfter * 1000
: Math.pow(2, attempt) * 1000; // 1s, 2s, 4s fallback
await new Promise(resolve => setTimeout(resolve, delayMs));
continue;
}
throw error;
}
}
}
import time
def send_with_retry(client, chat_id, message, max_retries=3):
for attempt in range(max_retries + 1):
try:
return client.chats.messages.send(chat_id, **message)
except Exception as e:
if getattr(e, "status_code", None) == 429 and attempt < max_retries:
retry_after = getattr(e, "response", None) and e.response.headers.get("retry-after")
delay = int(retry_after) if retry_after else (2 ** attempt) # 1s, 2s, 4s fallback
time.sleep(delay)
continue
raise

Tip: The official SDKs handle retries automatically with exponential backoff. You only need custom retry logic if you’re using the API directly.

  • 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_key field in the message body on retries to prevent duplicates (see Sending Messages)

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.