Limits
Chat limits how often you may call it, how large a request may be and how long tokens live. This page lists every limit in one table and explains what happens when you hit one. The same values are on Limits in the reference.
All limits
Section titled “All limits”| Kind | What | Limit |
|---|---|---|
| Rate | Any request with a machine token | 600 requests per 60 s per client |
| Rate | Sending a message | 30 messages per 10 s per user |
| Rate | User lookup | 20 lookups per 10 s per user |
| Size | Request body | 256 kB |
| Size | Message body | 10,000 characters |
| Size | Attachments per message | 10 attachments |
| Paging | Default page size | 50 items |
| Paging | Maximum page size | 100 items |
| Lifetime | User token, by token exchange | 10 minutes at most |
| Lifetime | Realtime token | 10 minutes at most |
| Realtime | Channels one realtime token covers | 100 channels |
Rate limits count requests in fixed windows. A machine limit is counted per backend client, and the others per user. Chat’s own web sign-in has a separate limit per client address, which tenant applications never use.
What an over-limit call looks like
Section titled “What an over-limit call looks like”A request over a rate limit answers 429 with error: "rate_limited" and a Retry-After header holding the seconds to wait:
HTTP/1.1 429 Too Many RequestsRetry-After: 4Size limits answer immediately and are not retryable as sent:
| Limit | Response |
|---|---|
| Request body | 413 payload_too_large |
| Message body | 400 body_too_long |
| Attachments | 400 too_many_attachments |
| Page size | Capped to the maximum. Not an error. |
How to stay under the limits
Section titled “How to stay under the limits”- Cache tokens. Reuse a machine token until shortly before it expires, and cache each user’s Chat token until about a minute before expiry. Asking for a new token per request wastes your budget and the Identity Server’s.
- Back off. On a 429, wait
Retry-Afterseconds. On a 5xx, retry with exponential backoff. Do not retry other 4xx errors. - Use realtime instead of polling. Realtime pushes new messages and presence changes, so your app does not need to list again and again. See Realtime.
- Do not create what exists. Creating a
DIRECTconversation again returns the existing one, but it still counts as a request. Store theconversation_idwhen you can. - Share one backend client carefully. The machine limit counts per client across all your backend’s instances.
- Page sensibly. Ask for the page size you display, not the maximum.
Every machine request counts, including reads. If one backend job sends a burst of messages on behalf of many users, spread it over time.