> ## Documentation Index
> Fetch the complete documentation index at: https://www.sapientpriors.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Limits

> Request rates, how many answers can run at once, file sizes, images per message, text field sizes, and agents per organization.

This page lists every limit. After you read it, you know how fast you can send requests, how large a file or an image can be, and what error each limit returns.

Every number on this page is a default. Your organization can have different numbers. `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 returns `429 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.

| Header | Meaning |
| - | - |
| `X-RateLimit-Limit` | The number of requests allowed in the window. |
| `X-RateLimit-Remaining` | The number of requests you can still send in this window. |
| `X-RateLimit-Reset` | When the window resets, as a Unix timestamp. |
| `Retry-After` | Only on a `429`. The number of seconds to wait. |

## Request rates

The table below lists the window for each operation.

| Operation | Per subject | Per organization | Reason |
| - | - | - | - |
| Create a thread | 5 per 10 s | 30 per 10 s | Cheap. |
| `observe` | 60 per 60 s | 300 per 60 s | This is the call for large amounts of data. One call carries up to 100 observations. |
| `observe-and-respond`, `observe-and-enrich` | 20 per 60 s | 120 per 60 s | Each call searches the memory and writes an answer. |
| `chat`, `chat/stream` | 20 per 60 s | 120 per 60 s | The same cost as an answer. |
| `observe-file` | 1 per 10 s | 6 per 10 s | Each call converts and learns a whole document. |
| Upload an image | 20 per 60 s | 120 per 60 s | One storage write each. |

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.

| Limit | Value |
| - | - |
| Answers running at the same time, per subject | 2 |
| Answers running at the same time, per organization | 4 |

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

| Limit | Value |
| - | - |
| Observations in one `observe` call | 100 |
| Content blocks in one observation | 20 |
| Characters in one content block | 100,000 |
| Length of `img_url` | 2,048 characters |

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:

| You send | While the agent is busy with | You receive |
| - | - | - |
| `observe` | Anything | `429 rate_limit_exceeded` with `Retry-After: 1` |
| `observe-file` | A file | `202` with `queued: true`. The file waits its turn and starts by itself. |
| `observe-file` | An `observe` | `429 rate_limit_exceeded` with `Retry-After: 1` |

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

| Field | Limit | Error when the limit is passed |
| - | - | - |
| `agent_config.role` | 1 to 200 characters | `422 invalid_request` |
| `agent_config.objective` | 1 to 2,000 characters | `422 invalid_request` |
| `agent_config.metadata`, thread `metadata` | 50 keys | `422 invalid_request` |
| Thread `title` | 1 to 200 characters | `422 invalid_request` |
| `chat` `message` | 1 to 2,000 characters | `422 invalid_request`. Longer text belongs in `observe`. |
| `chat` `turn_id` | 1 to 200 characters | `422 invalid_request` |
| `max_context_chars` | 100 to 100,000 | `422 invalid_request` |
| `limit` on list calls | 1 to 100. The default is 50. | `400 invalid_request` |

## Documents

| Limit | Value | Error when the limit is passed |
| - | - | - |
| Size of one file | 10 MB | `413 document_too_large`, before any conversion. |
| Pieces one file can become | 2,000 | `413 document_too_many_turns`. Split the file, or raise `max_chars`. |
| Files being learned at the same time, per agent | 1 | Not an error: the next file is accepted with `queued: true` and starts when the one ahead finishes. |
| Files being learned at the same time, per organization | 3 | `429` with `Retry-After: 90`. |
| Uploads started | 1 per 10 s per subject | `429 rate_limit_exceeded`. |

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

| Limit | Value | Error when the limit is passed |
| - | - | - |
| Size of one image | 10 MB | `413 payload_too_large`. |
| Images in one chat message | 10 | `413 payload_too_large`. The message is refused, not cut. |
| Total size of the images in one chat message | 32 MB | `413 payload_too_large`. |
| Formats | PNG, JPEG, WebP | `422 invalid_request`. |

## Agents and keys

| Limit | Value | Error when the limit is passed |
| - | - | - |
| Agents one organization owns | 100 | `409 agent_quota_exceeded`. The 101st create is refused, not queued. |
| Live API keys one organization holds | 5 | `409 conflict`. Revoke a key first. |

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

1. Read `code`. The limits use `rate_limit_exceeded` and the `409` code `agent_quota_exceeded`. On a `429`, `details` names which window refused.
2. On `429`: wait `Retry-After` seconds, then send the same request again.
3. Watch `X-RateLimit-Remaining` on your successful requests. When it reaches zero, pause until `X-RateLimit-Reset`.
4. If your product needs higher limits, contact us with your organization name and the operation.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.