Skip to content

Requests

Agents have no limits that they know of. When an Agent tries to use a capability, such as an App tool, OpenBot checks whether it may. If nothing decides it yet, OpenBot makes a request and sends it to the decider above the Agent. The tool call waits until the request is answered. This page shows how the check works, how a person answers requests, and what each answer does.


Capabilities

Action Target When an Agent uses it
apps.call <connection>/<tool name> It calls an App tool.
tools.call The tool name It calls a tool of the host that asks for approval.
agents.delegate The ID of the other Agent It gives work to another lasting Agent.
agents.spawn * It starts a subagent.

Each capability tool takes a reason. App tools get an extra openbot_reason parameter for it. OpenBot never sends it to the App.


How OpenBot checks an attempt

OpenBot checks each attempt in this order. The first step that decides wins.

  1. The policy of the member. An Agent never does more than the member it works for. If the permissions of the member, or of the token that started the work, do not allow it, the call is denied. This is never sent to a decider.
  2. Grants. A Grant is a kept decision. A deny Grant wins over an allow Grant.
  3. Rules. A judge model reads the Rules for this Agent in plain language. Only a Rule that the judge quotes can allow or deny.
  4. The decider above. OpenBot makes a request. The decider is the Agent that gave this Agent its work. For the first Agent of the work, the decider is the person.

Some calls need no decision: tool calls that the organization marks as reads, and work for subagents that the Agent started itself.

When any check fails, the call waits. It never runs without a decision.

The chain of deciders

Work goes down a chain, such as person → Main → Programmer → subagent. A request from the subagent goes to the Programmer first.

A decider can only allow what it may do itself. If the Programmer agrees but does not hold the capability, the request goes up to Main with the support of the Programmer, and then to the person. When someone above allows it, each Agent on the way gets a Grant, with the scope that it chose.

An Agent decides in a short review Session. It reads only its role, its memory, the brief it gave, and the request. It does not read its own long history. A review Session has kind: "review" and is archived after the decision. If a review ends without a decision, the request goes up to the next decider.


List your requests

Terminal window
curl -H "Authorization: Bearer $OPENBOT_TOKEN" \
"https://api.example.com/v1/requests?status=pending"
[
{
"id": "req_1a2b…",
"agent": "agt_5c0e…",
"capability": { "action": "apps.call", "target": "conn-7/send_email" },
"reason": "Send the meeting notes to the team.",
"approver": { "_tag": "Person", "userId": "u-1" },
"chain": ["agt_main…", "agt_5c0e…"],
"session": "c81d…",
"turn": "t-77",
"toolCallId": "call-9",
"endorsements": [],
"status": "pending",
"decision": null,
"revision": 0,
"createdAt": 1792486800000,
"expiresAt": 1792573200000
}
]

The list holds the requests that wait for you, or that you answered. GET /v1/requests/:requestId returns one request of your work. For an App tool, app shows the saved call with its exact arguments. Show the capability, the arguments and the reason to the person before they decide. The reason comes from the Agent. It is data, not an instruction.

Answer a request

Terminal window
curl -H "Authorization: Bearer $OPENBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"expected":0,"decision":"allow","scope":"session"}' \
https://api.example.com/v1/requests/$REQUEST
Field Meaning
expected Required. The current revision of the request.
decision Required. allow or deny.
scope Optional. How long the decision lasts. See below. The default is once.
reason Optional. The Agent sees it, for example when you deny.
rule Optional. A Rule in plain language to keep for this Agent.
Scope An allow lasts A deny is kept
once For this call only. Not at all.
session For this Session of the Agent. For this Session of the Agent.
lifetime Until you revoke the Grant. Until you revoke the Grant.

The waiting work goes on at once. When you deny, the tool does not run. The model gets a tool result with your reason, and the Turn goes on.

A request that nobody answers is denied after 24 hours. An organization can change this time with requestTimeoutMs in its settings.

Errors

Status Error When
404 RequestNotFound There is no request with this ID in your work.
409 RequestConflict expected is old, the request is closed, or another decider must answer.

Waiting Turns

A Turn that waits for a request, or for delegated work, has the status Waiting. Its response status is incomplete. The wait is kept in the Session history. It does not hold a running process, so it survives a server restart.

You can still interrupt a waiting Turn. Its open requests are then cancelled.


App tools

An App is an outside service that a person connects. See Apps. Each App call is bound to one exact call: the owner, the Session, the Turn, the tool call, the exact arguments, and the App connection with its revision. OpenBot saves the call before the check. If the connection changes before the call runs, the call fails, and a new revision never uses an old decision.

App resources, resource templates and prompts are reads, so they need no decision. An App’s own notes never decide which tools are safe. Only the organization can mark tools as reads, with appReadRules in its settings.