Skip to content
Agent Mandate
AGENT AUTHORIZATION API

Your agent is about to move money. What exactly was it allowed to do?

Agent Mandate turns that answer into a signed document instead of a prompt. You issue a mandate — this agent, these actions, these resources, this ceiling, until this date. Every consequential action is checked against it and comes back allowed, denied, or needing a human, with the clause that decided and a digest you can put in an audit log.

Free tier: 500 verified actions/month Paid from $299/month No card to run the demo
Live verification Ready

Runs the same engine the paid endpoint uses. Nothing is stored and no key is needed.

Press “Verify this action” to call the live API.
The problem

The agent’s authority exists only in a prompt, and a prompt is not a control.

The moment an agent can spend money, sign something, or change a production system, “we told it not to” stops being an answer anyone will accept.

Instructions aren’t enforcement

“Only pay approved vendors, never above $1,000” lives in the same context window as everything else the model reads. It can be argued with, crowded out, or overridden by content the agent retrieves. Nothing in the stack stops the call.

Your scopes are too coarse to say no

An API key or OAuth scope says this integration may call payments. It cannot say this agent, for this user, up to $1,000, to these three vendors, until Friday. So the permission you actually meant was never expressible.

Afterwards, nobody can reconstruct why

The action happened. Which rule allowed it, what the ceiling was, whether a human approved — all of it is spread across logs, prompts and a model that will not answer the same way twice. That is not an audit trail.

What it costs

The first serious incident does not stay a technical problem.

Autonomy fails asymmetrically. Thousands of correct actions buy you nothing; one wrong consequential action is the whole conversation.

  • Financial
    An action that was never authorized, and no clause that says so

    A payment goes to the wrong counterparty at the wrong size. The recovery conversation begins with “what was it permitted to do?” — and the honest answer is a paragraph of English that lived in a prompt template nobody versioned.

  • Regulatory
    You cannot show the control, only describe it

    An auditor asks for the authorization boundary in force on a specific date and the evidence it was applied. Reconstructing that from prompt history and application logs is not evidence; it is an argument. Signed mandates and decision receipts are the artefact the question is asking for.

  • Adoption
    The agent gets switched off rather than bounded

    Without an enforceable boundary, the only safe setting is a human in front of everything — which removes the reason the agent existed. Teams shelve working automation because they cannot describe its limits to their own risk function.

The solution

A mandate is a signed document, and verification is deny-by-default.

The mandate carries everything needed to decide: who granted it, who holds it, which actions on which resources, what ceilings, and when it stops. It is signed with a key that is yours alone and never leaves this service, so it cannot be edited in flight and cannot be replayed against another account.

DecisionWhat it meansWhat your code does
allowEvery clause was satisfied.Proceed.
requires_approvalAuthorized in principle, but above the approval threshold. Returned only when approval is the only thing missing.Route to a human, then retry with the approval token.
denyAt least one clause was violated. The receipt lists every one, not the first.Do not proceed. Log the receipt — it says exactly why.

Intent Signed mandate Proposed action Evaluated Receipt Audit log

  • 01

    Intent becomes a mandate

    You describe what the user actually authorized: the agent, the actions, the resources, per-action and total ceilings in integer minor units, an approval threshold, and an expiry. Anything not written down is not granted.

  • 02

    Signed, then self-contained

    HMAC-SHA256 over a canonical encoding of the claims, so the same document signs identically on any runtime. Store it wherever you like — verification needs no lookup, so it does not become a database round-trip in your hot path.

  • 03

    Every consequential action is checked

    Signature, agent binding, validity window, revocation, action, resource, per-action cap, total spend, count limit, currency and approval — all evaluated, none skipped because an earlier one failed.

  • 04

    Deny by default

    An action matching no grant is denied. Wildcards cover exactly one further segment: payments.* matches payments.transfer but not payments.transfer.bulk, so adding a nested action never silently widens authority.

  • 05

    A receipt, not a boolean

    The decision, the grant that made it, every violation with a stable code, remaining spend headroom, and a SHA-256 digest over the decision inputs that pins the entry to exactly this evaluation.

  • 06

    Revocation when you need it

    A signed document cannot un-sign itself, so revocation is the one thing that is looked up. Verifications read a briefly cached list, so a revocation takes effect within about ten seconds — stated plainly rather than hidden behind “immediately”.

Example receipt

This is what a decision looks like when it reaches your code.

A $300.00 transfer under a mandate that caps single actions at $1,000.00 and requires human approval above $250.00 — authorized in principle, held for a human.

{
  "decision": "requires_approval",
  "mandateId": "mnd_e11ce348-36de-4006-a699-dec9fa22e066",
  "agent": "agent_procurement_v3",
  "principal": "user_8814",
  "action": "payments.transfer",
  "matchedGrant": {
    "action": "payments.transfer",
    "resources": ["vendor.acme"],
    "maxAmountMinor": 100000,
    "approvalRequiredAboveMinor": 25000
  },
  "matchedGrantIndex": 0,
  "violations": [
    {
      "code": "approval_required",
      "detail": "Actions above 25000 minor units need a human approval token.",
      "grantIndex": 0
    }
  ],
  "remainingSpendMinor": 470000,
  "evaluatedAt": "2026-08-31T05:41:02.118Z",
  "digest": "9f2c1ba7e4d05c83a1e6f77b0c2d4938a55e1b0c7d3f8e29a4b6c1d05e7f3a82"
}

Amounts are integers, always

Every ceiling and every amount is an integer number of minor units. A fractional amount is rejected at validation rather than rounded — a spend cap is the last place in a system where a floating-point cent should be tolerated.

The currency is checked before the number

¥5,000 against a 5,000-cent ceiling would otherwise pass silently. If any cap is monetary, the mandate must name a currency and a mismatched action is denied rather than compared.

Every violation, not the first

An expired mandate presented for an ungranted action reports both. An approval queue needs the whole reason a request failed, not whichever clause the evaluator happened to reach first.

Violation codes

Branch on the code, never on the message

  • signature_invalid — altered after signing, or signed with a different key
  • mandate_expired — evaluated at or after expiresAt
  • mandate_not_yet_valid — evaluated before notBefore
  • mandate_revoked — on your account’s revocation list
  • agent_mismatch — presented by an agent the mandate does not name
  • action_not_granted — no grant covers it; deny by default
  • resource_not_granted — action granted, resource not
  • amount_exceeds_action_cap — above the matched grant’s ceiling
  • amount_exceeds_total_cap — prior spend plus this action exceeds the total
  • count_exceeds_cap — the grant’s maxCount is used up
  • currency_mismatch — the action is denominated differently from the caps
  • approval_required — above the threshold, no token; yields requires_approval
  • approval_token_invalid — a token was supplied but not recognised

This service is newly launched. We publish no uptime percentage, customer count, logo wall or certification claim until we have the operating history to support one.

How it works

Two calls to put a boundary around an agent

  • Issue a mandate

    POST what the user authorized. You get the mandate back with a detached signature. Issuing is free — it does not consume your allowance, because short-lived narrowly-scoped mandates are the ones worth encouraging.

  • Verify before you act

    POST the mandate and the action your agent proposes. One unit per action verified, up to 500 in a single call. Branch on decision; store the receipt.

  • Revoke when it is over

    POST to the revoke endpoint. Idempotent, never billable, and effective within about ten seconds. You should still give every mandate a short expiresAt — revocation is the exception, expiry is the design.

What the mandate does not do

It authorizes; it does not execute or remember

Agent Mandate never touches your payment rails or your systems of record — it returns a decision and your code acts on it. It is also stateless about usage: you pass priorSpendMinor and priorCount, because you are the one who knows what actually completed. A service that guessed at your ledger would be worse than one that asks.

Developer integration

Small surface, versioned, OpenAPI-first

Authenticate with Authorization: Bearer <key>. Every error returns a stable code and a requestId you can quote.

POST/v1/keysPublic. Emails a one-time claim token to the address you give it. No key is returned on this call — proving the mailbox is what stops anyone minting a key on your account.
POST/v1/keys/claimPublic. Spends the emailed token and returns the key, shown once — 500 verified actions a month, no card.
POST/v1/mandatesIssue a signed mandate. Free — issuance is not the billable unit.
POST/v1/verifyVerify one action or up to 500. Billed one unit per action verified.
POST/v1/mandates/:id/revokeRevoke. Idempotent, never billable, effective within ~10s.
GET/v1/revocationsThe revocation list verifications actually consult.
POST/v1/demo/verifyPublic. Signs and verifies in one call, capped at 10 actions. No key required.
GET/v1/violationsPublic. Every violation code and decision, with meanings.
curl -X POST https://agentmandate-api.com/v1/verify \
  -H "Authorization: Bearer $AGENT_MANDATE_KEY" \
  -H "content-type: application/json" \
  -d '{"mandate": {"mandate": {...}, "signature": "v1:..."},
        "action": {"agent":"agent_procurement_v3","action":"payments.transfer",
                   "resource":"vendor.acme","amountMinor":30000,"currency":"USD"}}'
Pricing

Priced per verified action, capped so a runaway agent can’t surprise you

One unit is one action verified. Issuing and revoking mandates are free. Every plan includes an allowance, then a per-unit overage that is hard-capped per billing period — your worst-case bill is the base price plus the cap, never more.

Developer
$299 /month
  • 10,000 verified actions included
  • $0.06 per additional verified action
  • Overage capped at $600 per period
  • Full API access, Python and TypeScript SDKs
Start with this plan
Scale
$4,999 /month
  • 400,000 verified actions included
  • $0.02 per additional verified action
  • Overage capped at $10,000 per period
  • Full API access, Python and TypeScript SDKs
Start with this plan
Enterprise
$10,000+ /month
  • 1,200,000 verified actions included
  • $0.01 per additional verified action
  • Overage capped at $20,000 per period
  • Full API access, Python and TypeScript SDKs
Contact sales

Free tier: 500 verified actions per month, no card. Prices in USD, billed monthly. Payment is processed by Square through our shared billing platform; card details never touch this site.

What counts as a verified action?
One action in one call to /v1/verify. A batch of 50 actions bills 50 units. Issuing a mandate, revoking one and listing revocations are all free — the unit is the decision, not the paperwork around it.
Where is the mandate stored?
Wherever you put it. The signed document is self-contained, so verification needs no lookup and does not become a database round-trip in your hot path. The only thing we store is your account’s signing key and the mandate ids you have revoked.
How fast does a revocation take effect?
Within about ten seconds. Verifications read a briefly cached copy of your revocation list so they never block on a database. If you need an instant boundary, use a short expiresAt — expiry is the design, revocation is the exception.
What stops someone replaying a leaked mandate?
Three things, and you should use all of them. Supply agent on the action so a mandate presented by a different agent is denied. Keep expiresAt short. Scope grants to specific resources with real ceilings. The signature proves the document is authentic; it does not prove who is holding it.
Does it track how much the agent has already spent?
No, deliberately. You pass priorSpendMinor and priorCount, because you are the one who knows which actions actually completed. A service that guessed at your ledger would be worse than one that asks for it.
Can I evaluate it before paying?
Yes. The demo at the top of this page is the real engine with no key at all, and the free tier gives you 500 verified actions a month against the full authenticated surface.

Put the boundary in writing.

The free tier is 500 verified actions a month, no card. Create a key, issue a mandate, and the next call tells you exactly what your agent may and may not do.

curl -X POST https://agentmandate-api.com/v1/keys \
  -H "content-type: application/json" \
  -d '{"email":"you@company.com","name":"Evaluation key"}'

# 202 Accepted. A one-time token is emailed to that address — spend it,
# and the response carries the key, shown once.

curl -X POST https://agentmandate-api.com/v1/keys/claim \
  -H "content-type: application/json" \
  -d '{"token":"<token from the email>"}'