---
title: "Record a spend against a mandate"
method: POST
path: "/api/mandate/consume"
tags: ["mandates"]
---

# Record a spend against a mandate

`POST /api/mandate/consume`

## Request

- Base URL: `https://api.anygas.xyz/svc`
- URL: `https://api.anygas.xyz/svc/api/mandate/consume`
- Auth: none declared

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|<mandateId>|<transferId>|<amount>"). 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.

## Request body

- object

## Response `200`

counted / not counted, with the on-chain verdict

- object

## Other responses

- `400`: missing transferId or unknown mandate

---

[API](https://skmtc.dev/anygas/apis/robyn-anygas-api.md) · [All operations](https://skmtc.dev/anygas/apis/robyn-anygas-api/llms.txt) · [OpenAPI document](https://skmtc.dev/anygas/apis/robyn-anygas-api/revisions/9b7498be8304?raw)
