Call limits

At most so many calls to a tool, an MCP server or a tool-name pattern, per conversation, hour or day, for each agent.

What a call limit is

A call limit caps how often an agent calls a tool, not what it spends: "at most 20 calls to stripe/refund an hour", "at most 200 calls to any github tool a day", "at most 5 calls to send_email per conversation". Money belongs to model requests, so dollar and token budgets stay on Costs → Budgets; a call limit counts tool calls.

  • Target: a tool (server/tool), a whole MCP server (server/*), or a tool name or pattern on any server (send_email, *refund*). Case is ignored; in the tool name ., _ and - are one separator.
  • Window: per conversation (the session id), per hour or per day. Hours and days are fixed in UTC (14:00 to 15:00, 00:00 to 24:00), so the count you see is the count the gateway keeps.
  • Past the limit: stop the call (CALL_CAP_EXCEEDED), or ask a person for each further call (CALL_CAP_ASK).

Organization and agent

The organization sets limits for each agent on Costs → Budgets (each agent has its own count). An agent adds its own on its page's Limits. Every limit that matches a call applies, so an agent's can only be lower: a limit above the organization's for the same tool and window is refused, and where the organization stops, an agent's limit can't ask a person instead.

GET /api/agents/:id/limits      # limits, with each call limit's count in its current window
PUT /api/agents/:id/limits      { "call_caps": [{ "id": "refunds", "target": "stripe/refund",
                                   "window": "hour", "limit": 20, "action": "block" }] }
PUT /api/org/limits             { "call_caps": [ ... ] }   # null removes them

Requests a minute: per agent, per key, per person

Beside call limits, Costs → Budgets sets how many model and tool requests a minute go through: for each agent (an agent can only lower it), for each runtime key, and for each person. A key and a person are read from the verified key, never from a header: a developer's coding tool and a sign-in name the person, and a key that names nobody is counted per key only. Each limit has its own count, shared by every gateway machine. Over a limit, the request is refused with HTTP 429 (AGENT_RATE_LIMIT, KEY_RATE_LIMIT or USER_RATE_LIMIT), so SDKs back off and retry. If the count can't be read, requests are not refused for it.

PUT /api/org/limits   { "rate_limit_rpm": 600, "rate_limit_rpm_per_key": 120, "rate_limit_rpm_per_user": 60 }
                      # null removes one

What counts

  • Only calls that run count. An allowed call takes a slot; a call held for a person takes it when it is released; a blocked call takes none.
  • One action counts once: when the gateway checks a call a model proposed and the agent then runs that same call, it is one call.
  • A call held for another reason when a stopping limit is already used up is stopped then, instead of asking a person for a call that couldn't run.
  • A person's approval answers an asking limit for that call. It never lifts a stopping limit.
  • A per-conversation limit needs the conversation: send X-Intertrace-Session-Id (or session_id on authorize). A call with none can't be counted.

The counts on the agent's Limits come from its recorded calls that ran since 00:00 UTC (per conversation, the busiest conversation today). The gateway keeps its own live count, so a call it just counted may not be recorded yet.