AnyGas Mandates API

Principal-signed spending budgets for autonomous agents, enforced outside the agent and consumed only against on-chain-verified transfers.

Operations 10

POST /api/mandate/prepare Build a spending mandate for the PRINCIPAL to sign #
POST /api/mandate/register Register a principal-signed mandate #
GET /api/mandate/status Remaining budget #
POST /api/mandate/check Would this spend fit? #
POST /api/mandate/consume Record a spend against a mandate #
POST /api/mandate/revoke Withdraw a mandate immediately #
GET /api/mandate/certificate Signed proof the agent stayed within budget #
GET /api/mandate/list Every budget a principal has granted #
POST /api/mandate/cosign-request Does this spend need the principal to approve it? #
GET /api/mandate/events What has happened to my budgets #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/anygas-xyz:anygas-xyz-mandates-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

anygas-xyz-mandates-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Anygas Xyz Mandates API
  version: 3.28.2
  contact:
    name: Robyn AnyGas
    url: https://anygas.xyz
  license:
    name: Service terms
    url: https://anygas.xyz/svc/api/terms
  x-lastUpdated: '2026-07-29'
  description: 'Operations tagged mandates across 2 of this provider''s published API definitions: anygas-openapi.json, anygas-xyz-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.anygas.xyz/svc
  description: Production gateway (also https://anygas.xyz/svc)
tags:
- name: Mandates
  description: Principal-signed spending budgets for autonomous agents, enforced outside the agent and consumed only against on-chain-verified transfers.
paths:
  /api/mandate/prepare:
    post:
      tags:
      - Mandates
      summary: Build a spending mandate for the PRINCIPAL to sign
      operationId: mandatePrepare
      description: 'Handing money to an autonomous agent is all-or-nothing today, and every existing control sits on the WRONG side of the trust boundary: a limit the agent enforces on itself is a limit it can drop, and a limit in its prompt is a suggestion. This builds a budget the PRINCIPAL signs with their own wallet. Robyn never signs mandates and holds no principal keys — a budget signed by Robyn would be a budget Robyn granted itself. SCOPE: covers spending THROUGH ROBYN only. It is not custody and cannot stop the agent spending elsewhere with the same key; the payload says so. Treat it as an auditable budget, not a hard cap. Optional `cosignAbove` (base units) adds a PER-SPEND approval threshold: spends above it require the principal to countersign that specific payment. Omit it, or pass 0, for no threshold — mandates granted before this existed behave exactly as before. Pass `sandbox: true` (and on register) to create a throwaway mandate in a separate store — used by our own tests so test grants never appear in an owner''s exposure figures.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        '200':
          description: mandate + digest to sign
          content:
            application/json:
              schema:
                type: object
        '400':
          description: missing/invalid fields
          content:
            application/json:
              schema:
                type: object
    servers:
    - url: https://api.anygas.xyz/svc
      description: Production gateway (also https://anygas.xyz/svc)
  /api/mandate/register:
    post:
      tags:
      - Mandates
      summary: Register a principal-signed mandate
      operationId: mandateRegister
      description: Verifies the signature recovers to the principal NAMED IN THE MANDATE. An impostor signing a budget that names someone else as principal is refused with 401 — otherwise anyone could grant themselves an allowance.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        '200':
          description: registered mandate status
          content:
            application/json:
              schema:
                type: object
        '401':
          description: signature does not recover to the named principal
          content:
            application/json:
              schema:
                type: object
    servers:
    - url: https://api.anygas.xyz/svc
      description: Production gateway (also https://anygas.xyz/svc)
  /api/mandate/status:
    get:
      tags:
      - Mandates
      summary: Remaining budget
      operationId: mandateStatus
      parameters:
      - name: mandateId
        in: query
        required: true
        schema:
          type: string
      description: Consumption counts ONLY transfers verified on-chain, so the remaining figure cannot be inflated by claiming spends that never happened, nor understated by omitting ones that did.
      responses:
        '200':
          description: consumed / remaining / active
          content:
            application/json:
              schema:
                type: object
        '404':
          description: unknown mandate
          content:
            application/json:
              schema:
                type: object
    servers:
    - url: https://api.anygas.xyz/svc
      description: Production gateway (also https://anygas.xyz/svc)
  /api/mandate/check:
    post:
      tags:
      - Mandates
      summary: Would this spend fit?
      operationId: mandateCheck
      description: Returns WITHIN_MANDATE, EXCEEDS_MANDATE or EXPIRED. If it exceeds, do not split the spend to get under the limit — that defeats the control the principal set. Ask them to raise it.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        '200':
          description: verdict + remaining
          content:
            application/json:
              schema:
                type: object
        '404':
          description: unknown mandate
          content:
            application/json:
              schema:
                type: object
    servers:
    - url: https://api.anygas.xyz/svc
      description: Production gateway (also https://anygas.xyz/svc)
  /api/mandate/consume:
    post:
      tags:
      - Mandates
      summary: Record a spend against a mandate
      operationId: mandateConsume
      description: 'Requires a `transferId`. The transfer is VERIFIED ON-CHAIN before anything is counted, and the amount counted is what the destination chain shows arrived — not what the caller claims. An unverifiable transfer is not counted (and the response says so plainly, since that also means the budget does not yet reflect it). The same transferId cannot be counted twice. If the mandate has a `cosignAbove` threshold and the amount exceeds it, a valid `cosignature` from the principal is required and is checked BEFORE any on-chain work — an unapproved large spend is refused on its face. The agent cannot approve its own. REQUIRES `agentSignature`: the AGENT named in the mandate must sign keccak256("v1|robyn-mandate-consume|||"). Without it, anyone who learned the mandateId could attribute an unrelated on-chain transfer to your budget and exhaust it — consumption needs a verifiable transfer, so a spend cannot be fabricated, but it could be MISATTRIBUTED. The authorisation binds the transfer as well as the amount, so it cannot be replayed onto a different payment. Note the principal cannot consume on the agent''s behalf; this authenticates the spender, not the grantor.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        '200':
          description: counted / not counted, with the on-chain verdict
          content:
            application/json:
              schema:
                type: object
        '400':
          description: missing transferId or unknown mandate
          content:
            application/json:
              schema:
                type: object
    servers:
    - url: https://api.anygas.xyz/svc
      description: Production gateway (also https://anygas.xyz/svc)
  /api/mandate/revoke:
    post:
      tags:
      - Mandates
      summary: Withdraw a mandate immediately
      operationId: mandateRevoke
      description: 'A budget you cannot withdraw is not a safety control: the moment you most need the limit is the moment you want it gone entirely, not merely capped, and waiting for expiry is not an option. Only the PRINCIPAL who granted the mandate can revoke it — an agent cannot revoke the budget that constrains it, and a third party cannot revoke someone else''s (401 otherwise). Revocation is DELIBERATELY IRREVERSIBLE. A kill switch that can be flipped back is one an attacker who briefly holds the key can undo; issue a fresh mandate instead. It stops Robyn endorsing further spend. It does NOT claw back money already spent and does not stop the agent spending elsewhere with the same key — if the key is compromised, rotate the key. The consumption record is kept so history stays auditable.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        '200':
          description: revoked status
          content:
            application/json:
              schema:
                type: object
        '401':
          description: not signed by the principal
          content:
            application/json:
              schema:
                type: object
        '404':
          description: unknown mandate
          content:
            application/json:
              schema:
                type: object
    servers:
    - url: https://api.anygas.xyz/svc
      description: Production gateway (also https://anygas.xyz/svc)
  /api/mandate/certificate:
    get:
      tags:
      - Mandates
      summary: Signed proof the agent stayed within budget
      operationId: mandateCertificate
      parameters:
      - name: mandateId
        in: query
        required: true
        schema:
          type: string
      description: 'What a principal actually wants at the end of a period: not a dashboard, but a document they can verify and keep. Lists every counted spend, the budget, the total, and whether it stayed inside. Every spend listed was VERIFIED ON-CHAIN before counting, and the figure is what the destination chain showed arrived — not what the agent reported. It certifies adherence to a ROBYN budget. It does NOT certify the agent spent nothing elsewhere, because Robyn can only account for money that moved through Robyn — `doesNotCertify` says so in the payload rather than in a footnote, since a principal reading it as proof of total spending would be badly misled.'
      responses:
        '200':
          description: signed compliance certificate
          content:
            application/json:
              schema:
                type: object
        '404':
          description: unknown mandate
          content:
            application/json:
              schema:
                type: object
    servers:
    - url: https://api.anygas.xyz/svc
      description: Production gateway (also https://anygas.xyz/svc)
  /api/mandate/list:
    get:
      tags:
      - Mandates
      summary: Every budget a principal has granted
      operationId: mandateList
      parameters:
      - name: principal
        in: query
        required: true
        schema:
          type: string
      description: You cannot revoke what you cannot find, and expecting anyone to have kept every mandateId is how a forgotten grant stays live for months. Lists remaining budget, co-sign threshold, expiry and revocation state, live mandates first, with the total still drawable WITHOUT further approval. Returns only mandates granted by the address you ask about.
      responses:
        '200':
          description: mandates granted by this principal
          content:
            application/json:
              schema:
                type: object
        '400':
          description: invalid address
          content:
            application/json:
              schema:
                type: object
    servers:
    - url: https://api.anygas.xyz/svc
      description: Production gateway (also https://anygas.xyz/svc)
  /api/mandate/cosign-request:
    post:
      tags:
      - Mandates
      summary: Does this spend need the principal to approve it?
      operationId: mandateCosignRequest
      description: 'A mandate caps a TOTAL, which is the wrong control for the risk people actually fear: "$500 this month" still permits one catastrophic $500 transfer to the wrong place. Set `cosignAbove` when preparing a mandate and any spend over it needs the principal to approve THAT PAYMENT. Returns whether approval is required and the exact digest to sign. The digest binds the mandate, the transfer AND the amount — an approval therefore cannot be replayed against a different payment, which is what would otherwise reduce the control to theatre. If a spend is refused for want of a countersignature, get the principal to sign it — do NOT split the spend to slip under the threshold.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        '200':
          description: cosignatureRequired + digest to sign
          content:
            application/json:
              schema:
                type: object
        '404':
          description: unknown mandate
          content:
            application/json:
              schema:
                type: object
    servers:
    - url: https://api.anygas.xyz/svc
      description: Production gateway (also https://anygas.xyz/svc)
  /api/mandate/events:
    get:
      tags:
      - Mandates
      summary: What has happened to my budgets
      operationId: mandateEvents
      parameters:
      - name: principal
        in: query
        required: false
        schema:
          type: string
      - name: since
        in: query
        required: false
        schema:
          type: string
        description: the cursor from your last call
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          default: 100
          maximum: 500
      description: 'A principal who granted a budget cannot otherwise learn that it is nearly spent, or that a large payment is waiting on their approval, without polling every mandate individually. Emits `spend`, `nearly-exhausted`, `exhausted`, `approval-required` and `revoked`. Pass the returned `cursor` back as `since` for only what is new. DELIBERATELY A PULL FEED, NOT A WEBHOOK: a mandate is created by an untrusted caller, so letting it name a callback URL would hand anyone a request primitive originating inside a host that holds signing keys. The convenience of a push is not worth that, and the response says so.'
      responses:
        '200':
          description: events plus a cursor
          content:
            application/json:
              schema:
                type: object
    servers:
    - url: https://api.anygas.xyz/svc
      description: Production gateway (also https://anygas.xyz/svc)
x-refined-from:
- anygas-openapi.json
- anygas-xyz-openapi.json