Rate limit
I rate limit sono applicati per endpoint su una finestra mobile di 60 secondi. Ogni endpoint ha il proprio contatore, quindi raggiungere il limite su una route non ne influenza un'altra. Superare un limite restituisce 429 Too Many Requests.
Come funziona
- La finestra è di 1 minuto per ogni endpoint.
- I limiti sono isolati per endpoint —
list-boardsesend-messagecontano separatamente. - Ogni response porta header di rate limit così puoi regolare il ritmo prima di colpire il cap.
Header di response
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed for this endpoint per window. |
X-RateLimit-Remaining | Requests remaining in the current window. |
X-RateLimit-Reset | When the current window resets. |
Retry-After | Seconds to wait before retrying (sent on 429 only). |
Limiti per categoria
I limiti si raggruppano in pochi tier. Il cap esatto dipende da quanto è pesante l'operazione.
| Category | Typical limit (per minute) | Examples |
|---|---|---|
| Reads | 50 | List boards, get a row, list channels, list notifications, list bookings |
| Heavier reads | 30 | Docs tree, drive tree, all /workspace/* reads |
| Writes | 30 | Create/update/delete rows, docs, comments, folders; upload presigned URLs |
| Heavy writes | 20 | Markdown writes (row, column, doc), multipart upload start/finalize |
| Search | 60 | The cross-entity /search endpoint (docs/drive search are 50) |
| Notification mutations | 60 | Mark read/unread, delete |
| Messaging | 100 | Send channel message, send direct message |
| Export | 10 | Async table export (the most restricted endpoint) |
Limiti rappresentativi per endpoint
| Endpoint | Method | Limit / min |
|---|---|---|
/board/list-boards | GET | 50 |
/board/{boardId}/table/{tableId}/rows | GET | 50 |
/board/{boardId}/table/{tableId}/row | POST | 30 |
/board/{boardId}/table/{tableId}/row/{rowId}/md | POST | 20 |
/board/{boardId}/table/{tableId}/export | POST | 10 |
/docs/tree | GET | 30 |
/docs/{docId}/md | POST | 20 |
/drive/files/upload/multipart/start | POST | 20 |
/search | GET | 60 |
/notifications | GET | 50 |
/notifications/{notificationId} | PATCH / DELETE | 60 |
/workspace/info | GET | 30 |
/chat/channels | GET | 50 |
/chat/channel/{channelId}/send-message | POST | 100 |
Questi numeri sono accurati al momento della scrittura ma possono cambiare. Leggi sempre gli header X-RateLimit-* a runtime invece di hardcodare i limiti — e consulta l'API Reference per il valore attuale di un endpoint specifico.
La response 429
Quando superi un limite, l'endpoint restituisce:
{
"statusCode": 429,
"error": "Too Many Requests",
"message": "Too many requests, please try again later",
"retryAfter": 27
}
L'header Retry-After porta lo stesso valore (in secondi) del campo body retryAfter — il tempo fino al reset della finestra.
Guida al backoff
- Rispetta
Retry-After. Su un429, attendi i secondi che specifica prima di ritentare. - Usa exponential backoff come fallback. Se non c'è
Retry-After(ad esempio su un5xx), fai backoff esponenziale: 1s, 2s, 4s, … - Osserva
X-RateLimit-Remaining. Rallenta proattivamente mentre si avvicina a zero invece di aspettare un429. - Distribuisci il lavoro bulk. Quando iteri liste grandi o crei righe in batch, aggiungi un piccolo delay tra le chiamate per restare sotto il cap per-minuto.
- Limita i retry. Rinuncia dopo alcuni tentativi e propaga l'errore invece di ritentare all'infinito.
Vedi Gestione errori per un esempio completo di retry.