GET /v1/session returns the upload limits that apply to you. Read them once when your client starts.
Every window is counted twice: once against the subject the request acts for, and once against your organization as a whole.
How rate limits work
Each operation has a time window per subject and a larger time window per organization. A window counts the requests in the last N seconds. When the count reaches the limit, the next request returns429 rate_limit_exceeded and does no work. As old requests leave the window, new requests are allowed again.
The subject is whoever X-SP-End-User names. Send the header and each of your customers gets their own window. Leave it out and every call your backend makes is one subject, so all of your traffic shares a single per-subject window. This is the main reason to send it on every call and not only when you create a thread.
details on a 429 body names which of the two refused: user for the per-subject window, organization for your ceiling.
Every response has headers that tell you where you are in the window, so that you can slow down before you hit the limit.
Request rates
The table below lists the window for each operation.
A person who types sends five or six messages per minute, so these windows never affect one of your customers. They stop a program that sends requests in a loop.
Answers that run at the same time
The answering calls have a second limit: how many can run at the same time. This limit is separate from the rate window.
A third answer for the same subject returns
429 with Retry-After: 5. Wait for one answer to finish. A chat/stream call holds its place until the stream ends.
Here too, X-SP-End-User is what makes the per-subject number a per-customer number.
Observations
To send old messages, put up to 100 observations in one call, and send up to 60 calls per minute. That is 6,000 observations per minute per subject, bounded by the single ingestion slot below.
Priors learns one thing at a time for each agent, across all of its threads.
observe and observe-file share that single slot, and it is held until the work reaches committed, not just until the call returns 202.
Which error you receive depends on which call is refused:
So poll the running observation until
committed before you send the next observe for that agent, and keep a queue per agent for backfills. Files queue on the Priors side, so you can send them one after another. This does not block answering: observe-and-enrich, observe-and-respond, chat, and chat/stream all run while an ingestion is in progress.
Text fields
Documents
To load ten PDF files into one agent: upload one, poll until
committed, then upload the next. To load ten PDF files into ten agents: three at a time.
If you upload a file with exactly the same bytes as one this agent already read in the same thread, Priors skips it. The response is 202 with "duplicate": true, and nothing is read or charged again.
If the agent read those bytes in another thread, the upload returns 409 document_already_ingested. One memory index serves every thread, so what that read learned is already searchable from here. Send allow_duplicate=true to read it again and store a second copy.
Images
Agents and keys
Deleted agents do not count.
One agent per customer means one hundred customers. If you are heading past roughly eighty, contact us then rather than at the wall: raising it is work on our side and it needs lead time.
What to do when you hit a limit
- Read
code. The limits userate_limit_exceededand the409codeagent_quota_exceeded. On a429,detailsnames which window refused. - On
429: waitRetry-Afterseconds, then send the same request again. - Watch
X-RateLimit-Remainingon your successful requests. When it reaches zero, pause untilX-RateLimit-Reset. - If your product needs higher limits, contact us with your organization name and the operation.