Request rate limits

Все още не е преведено — показано на английски.

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

PlanRequests per second
Pay as you go10
Starter25
Business100

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 limitQuota or credit
UnitRequests per secondCharacters per period
Error429 rate_limited402 quota_exceeded or 402 credit_exhausted
RemedySlow down or batchRaise 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.

Редактирано на 7.09.2026 г., 0:00 ч.