Skip to main content
An approval is a named person’s decision about one agent action. The person gets a one-tap link by email or SMS and needs no OneShot account. Every decision is recorded as a signed receipt. An agent that can’t be audited isn’t autonomous. It’s unsupervised. Approvals work in two ways:
  • Action policy. Rules on your agent decide which email, SMS, voice and commerce calls run, which are denied, and which wait for a person. A held call is not run and not charged.
  • Ask directly. Your agent asks a person to decide something (POST /v1/approvals) and acts on the answer itself.
An agent with no policy is unaffected until you set one.

Action policy

A policy is a set of rules on the agent. The API checks it before any money moves.
A rule has a tool (email, sms, voice, commerce, physical_mail, linkedin_invite, linkedin_invite_withdraw, linkedin_react, linkedin_reply, linkedin_message, build, browser, or *), conditions under when, and an action (require_approval or deny). A rule matches only when all its conditions hold. If several rules match, deny wins over require_approval. The policy is checked on every paid route with a side effect outside OneShot: email/send, sms/send, voice/call, commerce/buy, physical-mail/send, linkedin/invite, linkedin/invite/withdraw, linkedin/react, linkedin/reply, linkedin/message, build and browser. It runs once the price is known and before any payment is settled or credit is debited. Routes that only read (research, enrichment, search, verification, linkedin/profile-view, linkedin/sync) are not gated. For build and browser, the rule sees what the quote will run, not the request body. Only a wallet session can set it; an access token can read it but not change it.

When a call is held

The call returns 403 and nothing is sent or charged:
The approver is paged once per distinct call. Retrying the same call while it is pending returns the same approval. After approval, repeat the same call with the approval id; it runs once:
Over HTTP, send the id in the X-Approval-Id header. An approval releases only the action it was granted for (same recipients, content, product and quantity), within 24 hours of the decision. A second use returns 409 approval_already_used. If the released call fails before dispatch (for example, a payment that doesn’t settle), the approval is restored so you can retry. A call a rule denies returns 403 action_denied_by_policy with the rule id. The SDKs raise ApprovalRequiredError and ActionDeniedError.

Asking directly

POST /v1/approvals asks a person a question. Your agent reads the answer and acts on it.
These approvals are informational. They can’t release a held paid call.

What the approver sees

The link opens a page with the summary, the preview, and Approve / Deny buttons (with an optional note). Opening the link decides nothing, so email scanners that follow links can’t approve by accident. Each link works once and expires at the deadline. An unanswered approval is denied.

Compute goals

When a compute goal needs human input and your policy has an approver, the approver gets the same kind of link. Their decision resolves the goal’s human_approval task, as POST /v1/compute/:goalId/respond would. If you answer through /respond first, the link stops working.

Receipts

Every decision (approved, denied, expired, or cancelled) writes a signed $0 receipt in the approval subcategory. It records who was asked (as a digest), the decision, when and how it was made, and a digest of what the approver saw. A call released by an approval has approvalId in its receipt metadata, so the action and the decision link to each other.

Endpoints

All use the same signed agent proof as budgets. An agent can have at most 20 pending approvals at once.