# Rate Limits

Canonical URL: https://texttree.ai/en/docs/rate-limits/
Markdown URL: https://texttree.ai/en/docs/rate-limits.md
Page type: docs
Translation status: approved
Legal status: not_required

## Summary

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

## Source content

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

TextTree 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.

## Account bootstrap throttle

Headless account bootstrap is intentionally stricter than normal API traffic:

- `POST /api/v1/accounts`
- `POST /mcp/accounts`

Each IP address can create one account successfully every five minutes. TextTree
stores only a hash of the IP address for this throttle record. A repeated
successful creation attempt within the window returns:

```json
{
  "error": "account_creation_rate_limited",
  "retry_after_seconds": 300
}
```

## Message send rate limit

`POST /api/v1/messages` is rate limited per API credential (per access token) so
that one key cannot flood the shared send queue. The limit is a token bucket:
short bursts are allowed, then requests are throttled to a sustained rate.

| Plan tier | Burst capacity | Token refill |
| --- | ---: | --- |
| Starter | 1 message | 1 token every 1,200 ms |
| Growth | 5 messages | 1 token every 1,200 ms |
| Scale | 10 messages | 1 token every 1,200 ms |
| Enterprise | 20 messages | 1 token every 1,200 ms |

All tiers keep the default sustained API-admission refill at or below the
default Dial provider ceiling of one token every 1,200 ms. Paid tiers increase
short-burst admission; actual delivery still queues behind provider registration,
Dial rate limits, spend controls, and workspace sender configuration.

When the bucket is empty the endpoint responds with `429 Too Many Requests`, a
`Retry-After` header (in seconds), and:

```json
{
  "error": "message_send_rate_limited",
  "message": "Too many message send requests. Retry after the indicated delay.",
  "retry_after_seconds": 1,
  "limit": {
    "tier": "starter",
    "capacity": 1,
    "refill_ms": 1200
  }
}
```

Reads (`GET /api/v1/messages/:id`) and previews are not affected by this limit.
Higher sustained throughput is available per workspace plan after sender
registration is stable — contact support.

## Response shape

```json
{
  "error": "message_send_rate_limited",
  "message": "Too many message send requests. Retry after the indicated delay.",
  "retry_after_seconds": 30,
  "limit": {
    "tier": "growth",
    "capacity": 5,
    "refill_ms": 1200
  }
}
```

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

## Retry pattern

```js
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 TextTree return the
original message instead of creating duplicate SMS records when the first request succeeded but
your client timed out.

```json
{
  "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.
