Skip to navigation

Limits and rate limits

Every field limit the API enforces, the per-organization rate limits, and how to handle 429 and 529.

The API enforces size limits on each request body. Rate limits depend on the key type and the organization’s production tier, and every model shares them.

Test keys use the monthly test tokens. Production keys use purchased credits at $0.04 per million input tokens. The Free plan cannot buy credits. See Pricing.

Every request needs an API key. See Authentication. decision-machine-1 takes content-type: application/json and a body. rakeaudio takes the audio file as the body: see rakeaudio limits and errors.

Field limits

These limits apply to decision-machine-1.

Every capability reads text or texts. The other fields depend on the capability.

FieldCapabilityLimit
textall eight1 to 20,000 characters
textsall eight1 to 32 items, each 1 to 20,000 characters
imageall eightone image, JPEG, PNG or WebP, at most 5 MB decoded
detailall eightlow, medium or high; medium by default
statementyes-nominimum 1 character
statementsyes-no1 to 32 items, each minimum 1 character
when_true, when_falseyes-nono length limit
labels (array form)classify2 to 64 items, each minimum 1 character
labels (object form)classifyname to description map, each name minimum 1 character, no item count limit
treeclassify-tree2 to 64 entries per level, each name minimum 1 character
tree depthclassify-treeat most 8 levels
scalerate2 to 10 items, each minimum 1 character, ordered low to high
questionanswerminimum 1 character
questionsanswer1 to 32 items, each minimum 1 character
types (array form)entities1 to 64 items, each minimum 1 character
types (object form)entitiestype to description map, no item count limit
schemaextractobject with properties, no size limit on text; at most 5 fields with an image
fieldverifyobject { name, description }, name minimum 1 character
valueverifystring or number, required
statesystemonestring, object or array, at most 20,000 characters once rendered
questionssystemone1 to 32 named questions
criteria (choice)systemone2 to 64 options
criteria (score)systemone2 to 10 levels

Send exactly one of text, texts or image. All eight capabilities reject a request that carries text and texts together, and a request that carries none of the three. Both cases return the message body: provide text, texts or image. An image may travel with a text.

What a breach returns

A limit breach returns 400 with the standard error envelope. The message names the field and the bound. These captures are real responses:

{"error":{"code":"invalid_request","message":"text: Too big: expected string to have <=20000 characters"}}
{"error":{"code":"invalid_request","message":"texts: Too big: expected array to have <=32 items"}}
{"error":{"code":"invalid_request","message":"labels: Too small: expected array to have >=2 items"}}
{"error":{"code":"invalid_request","message":"labels: Too big: expected array to have <=64 items"}}
{"error":{"code":"invalid_request","message":"scale: Too big: expected array to have <=10 items"}}
{"error":{"code":"invalid_request","message":"tree.billing.labels: each level needs 2 to 64 labels"}}
{"error":{"code":"invalid_request","message":"tree.a.labels.a.labels.a.labels.a.labels.a.labels.a.labels.a.labels.a.labels: tree is deeper than 8 levels"}}

Validation reports up to three problems, joined with ; . Each one reads path: message. See Errors for every code.

Rate limits

Test and production keys use separate rate-limit buckets within each organization. All keys of the same type share their buckets.

Buckets refill continuously, not on a fixed minute boundary. Creating more keys does not increase the limits.

Key typeInference requests per minute (RPM)Input tokens per minute
Test30500,000
Production Tier 11,0001,000,000
Production Tier 25,0001,000,000
Production Tier 35,000Unlimited
Production Tier 410,000Unlimited

RPM and usage count admitted inference request units, not HTTP calls or successful results. One HTTP call can consume many units.

A rakeaudio call counts toward RPM. Its input tokens are billed after the transcript, so they do not count toward the input-tokens-per-minute limit.

CallInference request units
One text1
24 texts24
One text with 3 statements3
2 texts with 3 statements or questions6
classify-tree1 per text, regardless of tree depth
OpenAI-compatible chat completion1
TypeSafe-compatible systemone1 per question
rakeaudio transcription1 per file

Text counts multiply by statement or question counts. A missing array contributes one to the calculation.

Admitted calls still consume their units if processing later fails. Authenticated invalid or non-inference calls that reach admission consume at least one unit, including GET calls.

The API keeps existing requests and rpm field names. These names refer to inference request units. Input-token limits count each call’s input tokens.

Production tiers

Every production tier requires a paid credit bundle of at least $10. Auto top-up and a saved credit card are optional.

TierLifetime paid spendTime since first payment
Tier 1At least $10Immediate
Tier 2At least $50At least 14 days
Tier 3At least $250At least 21 days
Tier 4At least $500At least 30 days

Your organization receives the highest tier for which it meets both thresholds. The monthly test tokens do not count toward paid spend.

Billing synchronization updates the saved access status and tier. Inference requests use that saved status without fetching billing records.

Need immediate assistance with a higher tier? Reach out to our support team: support@milliseconds.ai.

One call may be larger than the whole token budget. That call goes through. The next calls wait for the bucket to refill. The request bucket works differently: a batch needs its full count of request units, or it returns 429 with a retry-after that covers the shortfall.

Rate-limit headers

The API checks and reserves request units before processing an admitted call. Successful admission returns the bucket state after that reservation.

A rate-limit refusal returns the current bucket state without spending units. Headers are snapshots; concurrent calls can change the remaining balance:

HeaderMeaning
x-ratelimit-limit-requestsThe inference request-unit limit per minute.
x-ratelimit-limit-tokensThe input-token limit per minute.
x-ratelimit-remaining-requestsThe inference request units left in the bucket.
x-ratelimit-remaining-tokensThe input tokens left in the bucket.
x-ratelimit-reset-requestsThe time until the request bucket is full, for example 12s.
x-ratelimit-reset-tokensThe time until the token bucket is full, for example 6m0s.

The reset values read as a duration: 12s, 6m0s, 1h2m3s.

Tiers with unlimited input tokens omit the token limit, remaining, and reset headers. Request-limit headers still apply.

What a breach returns

A breach returns 429 with the standard envelope and a retry-after header in seconds:

{"error":{"code":"rate_limit_exceeded","message":"Rate limit reached for requests on this organization. Retry after 3s."}}
{"error":{"code":"rate_limit_exceeded","message":"Rate limit reached for tokens on this organization. Retry after 12s."}}

Wait for retry-after before you send the call again. A retry inside that window fails again. The rejected call spends no request unit and no tokens, but it wastes a round trip.

Read x-ratelimit-remaining-requests and x-ratelimit-remaining-tokens on every response. Slow your concurrency down before you reach zero.

Response headers per call

Every capability response carries the input size and the model processing time:

HeaderMeaning
x-input-charsThe number of input characters. For texts, the sum over all items.
x-input-tokensThe input tokens billed for this call. This is the billing unit.
x-inference-msThe model processing time for this request, in milliseconds. It excludes queueing, network and the API layer.

The OpenAI-compatible routes omit the two input headers. They report the same count inside usage. They do return x-inference-ms. The TypeSafe-compatible route returns all three headers.

No credits left

Test requests consume only the monthly test tokens. Production requests consume only purchased credits. Neither key type can use the other credit pool.

When the applicable balance is exhausted, the API returns 429 insufficient_quota without retry-after.

  • For test keys, wait for the monthly allowance to replenish.
  • For production keys, add purchased credits in Billing.

Do not retry on a timer. A credit purchase does not restore an exhausted test allowance.

Production access disabled

Production keys return 403 production_access_disabled if the organization no longer meets the paid-bundle requirement, or its saved billing status needs a refresh.

Open Billing to refresh your status. Buy a qualifying credit bundle only if you have no qualifying purchase. The console warns on every page when production keys exist without access.

529 is the backpressure signal

Inference runs on a fixed pool of slots. When every slot stays busy, the API returns 529:

{"error":{"code":"overloaded","message":"Every inference slot stayed busy. Retry with backoff."}}

Treat 529 as “retry later”, never as “the request was wrong”. The body is unchanged and correct. Retry with exponential backoff and jitter. The call goes through once a slot frees.

Retry 429 with retry-after, 529 and 502. Never retry 400, 401, 403, 404 or a 429 with the code insufficient_quota: the request or the balance must change first. The examples below retry 502 and 529.

curl -s --retry 5 --retry-delay 1 --retry-all-errors \
https://api.milliseconds.ai/v1/decision-machine-1/yes-no \
-H 'content-type: application/json' \
-H 'authorization: Bearer test_sk-...' \
-d '{
"text": "The customer asks for a refund before Friday.",
"statement": "This message is urgent"
}'

A 429 carries retry-after in seconds. A 502 and a 529 carry no such header, so pick your own backoff there.

Stay inside the limits

  • Split documents above 20,000 characters yourself. Send each part as one item of texts.
  • Keep a batch at 32 items or fewer. Chunk a longer queue into groups of 32 and send them in sequence.
  • Batch statements and questions instead of texts where you can. They ride one model call, while each item of texts costs its own call. Every item still spends one request unit.
  • Prefer the object form of labels and types when you need more than 64 entries. Descriptions also improve accuracy.
  • Log x-input-tokens on every call. It records the input tokens billed for that call.
  • Watch x-ratelimit-remaining-requests and x-ratelimit-remaining-tokens. Large batches spend both buckets fast: a batch of 32 texts is 32 inference request units.

Next