Documentation

Rate Limits

Understand API rate limits, send throughput, retries, and live-mode controls.

Rate limits protect provider reliability, spend controls, and customer experience.

Textree surfaces rate-limit failures with:

  • request ID
  • endpoint
  • retry guidance
  • related message or webhook event

Production throughput depends on sender registration, provider limits, and workspace plan.

Response shape

{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests for this workspace.",
    "retry_after_seconds": 30,
    "request_id": "req_123"
  }
}

Use retry_after_seconds when present. If the field is missing, use exponential backoff with jitter instead of retrying immediately.

Retry pattern

async function sendWithBackoff(payload, attempt = 1) {
  const response = await fetch("https://api.texttree.ai/api/v1/messages", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.TEXTREE_ACCESS_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(payload),
  });

  if (response.status !== 429) {
    return response;
  }

  const retryAfter = Number(response.headers.get("retry-after") || 2 ** attempt);
  await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
  return sendWithBackoff(payload, attempt + 1);
}

Idempotency

Always include idempotency_key when retrying workflow sends. This lets Textree return the original message instead of creating duplicate SMS records when the first request succeeded but your client timed out.

{
  "phone_number": "+15551234567",
  "body": "Your appointment is tomorrow at 9 AM.",
  "idempotency_key": "appointment-123-reminder"
}

Operational guidance

  • Burst tests in Test mode before moving traffic to Live.
  • Keep webhook receivers fast and return 2xx quickly.
  • Use message logs and request IDs to debug throttled sends.
  • Ask support for higher production throughput after sender registration is stable.