Limits
Every limit Sallyport applies to your calls, its value, where you change it and what happens past it.
On this page
A limit exists only where its absence would break memory, money or somebody else's service. Going over your plan never stops a call.
Calls
| Limit | Value | Past the limit |
|---|---|---|
| Calls on your plan | 10,000 a month on Solo, 100,000 on Pro, 1,000,000 on Team, no ceiling on Agency | Calls keep running. The console shows a notice, and the MCP result of a call that ran straight away carries PLAN_LIMIT. Answers on /p/ do not. |
| Agents on your plan | 1 on Solo, up to 5 on Pro, up to 25 on Team, no limit on Agency | A new agent is refused with PLAN_LIMIT. Delete an agent or move to a bigger plan. |
| A plan in force | Every organization needs one. A new organization starts the 7-day trial with its first agent. | Calls are refused with PLAN_REQUIRED and a link to the billing page until an owner picks a plan. Keys, agents and the journal are kept. |
| Calls per hour, per agent | None for the first 30 days of an account, then 10,000. Set your own in "Calls per hour" on the agent's page. | The call is refused with RATE_LIMITED and a time to retry: the start of the next minute. |
| Calls at once, per agent | 32. Change it in "Concurrent calls" on the agent's page. | The call is refused with RATE_LIMITED and a retry after one second. |
| Calls at once, per account | 64, across all its agents | The call is refused with UNAVAILABLE and a retry after half a second. |
| Calls per hour, per connection | None until you set one on the connection's page, under Limits, "Calls an hour before a person is asked", or as budget_calls_per_hour with PATCH /v1/bindings/{id}. 0 turns it off. | Each further call on that connection that hour waits for a person, and a grant does not cover it. |
| Waiting approval cards | 20 per agent, 100 per account | The call that crosses it is refused with SUSPENDED, and the agent pauses behind one card. Answering that card starts it again. |
| Reading budget | Off. Set 2 to 100 in "Reading budget" on the agent's page. | It starts after 7 days of history. Then a card asks you once the agent's bytes read from one connection in an hour pass that many times its median hour. |
Sizes
| Limit | Value | Past the limit |
|---|---|---|
| Answer inside an MCP tool result | 24 KiB, or what the agent sets in max_inline_bytes, up to 1 MiB | The rest is stored. The agent reads it with fetch_body for 30 days. |
| Answer from the service | 512 MiB per call, the most a connection takes. Lower it on the connection's page, under Limits, "Largest answer from the service", or with max_upstream_bytes. | Over MCP the call fails with UPSTREAM_TOO_LARGE and returns nothing partial. On /p/ the answer is already streaming, so it stops short, and a later poll of the call shows UPSTREAM_TOO_LARGE. |
| Request body through the HTTP proxy | 32 MiB, or 1 MiB for the JSON open form | The request is refused before anything is sent. |
| One MCP message | 8 MiB | The message is refused before anything is sent. |
| File written over SFTP | Up to 32 MiB with PUT on /p/. Inside an MCP call, what fits in one 8 MiB message: about 6 MiB as content_base64. | The request is refused before anything is sent. |
| File read over SFTP | The connection's largest answer from the service, 512 MiB by default. offset and length read a larger file in parts. | As for any answer: UPSTREAM_TOO_LARGE over MCP, a stream that stops short on /p/. |
| Database answer | 1,000 rows | The answer says so. Page through the rest with LIMIT and OFFSET. |
| Email message | 100 recipients, 20 attachments, 10 MiB | The agent is told which bound, and nothing is sent. |
| WebSocket message | 1 MiB, either way | Both sides get close 1009, and the message is not passed on. |
Time
| Limit | Value | Past the limit |
|---|---|---|
| Service starts answering | 60 seconds after the request is sent | The call fails with UPSTREAM_ERROR. |
| A call without a stream | 5 minutes from start to answer | The call fails with UPSTREAM_ERROR. |
| Silence inside a stream | 10 minutes between two pieces of the answer | The stream is closed. |
| WebSocket session | 60 minutes | Both sides get close 1001 with the reason. |
| Silence in a WebSocket session | 10 minutes without a frame either way | Both sides get close 1001 with the reason. |
| Database statement | 30 seconds, or up to 300 seconds when the agent asks | The database stops the statement and says so. |
| Mailbox operation | 120 seconds | The call stops and says so. |
| MCP call waiting for a person | 240 seconds for a client that sends a progress token, 45 seconds for one that does not | The agent gets APPROVAL_PENDING with a call_id and continues the same call later. |
| Approval card | 60 minutes. Change it in Settings, Organization, "Approval window (seconds)": 60 to 86,400. | The card expires and the call ends with APPROVAL_EXPIRED. |
| Permission from a card | As long as "Longest grant (seconds)": 24 hours by default and at most. By default up to 200 reads, 20 writes or 1 destructive call. | The next call is asked about again. |
| Access request | 7 days | The request closes. The agent can ask again. |
| Stored answers | 30 days | The answer is deleted. |
| Call history and journal | 180 days. Change it in "Journal and call history (days)". | Older calls and journal months are deleted. |
Floods stop at the edge
Every Sallyport hostname sits behind Cloudflare, and only Cloudflare can reach the gateway. Request floods are Cloudflare's to stop. The gateway's own limits are the ones on this page.