Request rate limits
Ende e papërkthyer — shfaqur në anglisht.
The limit is counted per team across all of its keys. It applies to every authenticated endpoint, not only to /v1/translate.
Limits by plan
| Plan | Requests per second |
|---|---|
| Pay as you go | 10 |
| Starter | 25 |
| Business | 100 |
Headers
Every successful response reports the state of the window:
HTTP/1.1 200 OK
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 6
X-RateLimit-Reset: 1
X-RateLimit-Reset is the number of seconds until the window has moved on and is always 1. The headers are set on responses that passed the limiter; a 429 carries Retry-After instead.
The sliding window
The limiter keeps a timestamp for each request of the last 1,000 milliseconds. A new request is admitted if fewer than the limit are recorded in that span. There is no burst credit: an idle minute does not bank requests for later.
What a 429 looks like
{
"type": "https://langapi.xyz/docs/errors#rate-limited",
"title": "Rate limited",
"status": 429,
"code": "rate_limited",
"detail": "Too many requests. Your plan allows 10 requests per second.",
"request_id": "01JAX4N2Q6S8U0W2Y4A6C8E0G2",
"limit": 10
}
The response includes Retry-After: 1. A rejected request is not counted against your characters and no usage record is written.
Sizing a client
A translate request typically takes longer than one second, so a worker pool sized a little below the limit rarely trips it. Ten workers against a limit of 25 will not; forty will.
Batching is the more effective lever. One request with fifty texts costs one slot; fifty requests with one text each cost fifty. Build batches by character count so they also stay under the per-request character limit:
import "unicode/utf8"
func chunk(texts []string, maxChars, maxItems int) [][]string {
var batches [][]string
var current []string
size := 0
for _, t := range texts {
n := utf8.RuneCountInString(t)
if len(current) > 0 && (size+n > maxChars || len(current) == maxItems) {
batches = append(batches, current)
current, size = nil, 0
}
current = append(current, t)
size += n
}
if len(current) > 0 {
batches = append(batches, current)
}
return batches
}
Call it with maxItems = 50 and maxChars equal to your plan's per-request limit.
Backing off
On 429, sleep for Retry-After seconds plus a small random jitter before resending. If several workers hit the limit simultaneously, jitter is what prevents them from retrying in lockstep and being rejected together again.
Rate limit and quota are separate
| Rate limit | Quota or credit | |
|---|---|---|
| Unit | Requests per second | Characters per period |
| Error | 429 rate_limited | 402 quota_exceeded or 402 credit_exhausted |
| Remedy | Slow down or batch | Raise the cap, top up, or change plan |
Both are described in Error codes reference.
When the limiter itself is unavailable
If the store behind the limiter cannot be reached, requests are let through rather than rejected, and the headers report the full limit as remaining. The condition is logged on our side. You will not see a 429 during such a window, but you may see 503 service_unavailable from the quota step that follows.
Rishikuar më 7 sht 2026, 12:00 e paradites