Mandate
What a user lets one agent do.
A mandate is what a user lets one agent do. It is issued by an operator or tenant on the user’s behalf, stored by the authorizer, and never signed or modified by the agent.
The user sets the rules for each agent, at each venue, in each currency. The authorizer only enforces them. It does not decide how wide a rule should be.
An agent MUST have exactly one live mandate (status active and expires_at in the future) for an intent to be judged. None is A2M_MANDATE_INACTIVE; more than one is A2M_MANDATE_AMBIGUOUS. Both fail closed.
Mandate-wide fields
Section titled “Mandate-wide fields”| Field | Meaning |
|---|---|
venues |
Allowlist of venue names. Required, non-empty. |
instruments |
Allowlist of instruments. Required, non-empty. |
price_collar_bps |
Maximum distance of the limit price from the reference price, in basis points. Also bounds the protect price of market orders on venues that need one. |
max_open_orders |
Throttle on working orders. |
max_orders_per_minute |
Throttle on order rate. |
expires_at |
Must be in the future when issued. |
reduce_only |
Restrict the agent to reducing orders. |
allow_resize |
Shrink an order to what the limits allow (verdict RESIZE) instead of rejecting it. |
Limits
Section titled “Limits”Amounts live in limits, one row per venue and currency. An order is checked only against the row for its venue and its instrument’s quote currency. If there is no such row, the order is refused (A2M_LIMIT_MISSING). There is no FX: a USDC row and a USD row never add up.
"limits": [ {"venue": "hyperliquid", "currency": "USDC", "max_order_notional": "35", "position_limit_notional": "80", "daily_loss_limit": "5", "max_order_qty": {"ETH": "0.015"}}, {"venue": "alpaca", "currency": "USD", "max_order_notional": "500", "position_limit_notional": "2000", "daily_loss_limit": "100", "max_order_qty": {"AAPL": "10"}}]| Row field | Meaning | Default |
|---|---|---|
venue, currency |
Which orders the row covers | required |
max_order_notional, position_limit_notional, daily_loss_limit |
In the row’s currency. Daily loss is realized PnL in that currency for the UTC day | required |
max_order_qty |
Per instrument, in that instrument’s units. An instrument not listed has no quantity cap | none |
approval_above_notional |
A human approves orders above this notional | none |
budget_id |
Sub-budget the row draws on; must be in the row’s currency | none |
instruments |
Narrower allowlist for this venue | the mandate’s list |
allow_short |
Stored; opening or extending a short is still refused (A2M_SHORT_DISABLED) until the authorizer has a short collateral ledger |
false |
max_leverage |
Only 1 is accepted until the authorizer models margin. A value greater than 1 is refused |
1 |
short_collateral_ratio |
Share of short notional held as collateral. A value below 1 is refused until a margin model exists |
1 |
The old flat shape (max_order_qty, max_order_notional, position_limit_notional, daily_loss_limit, approval_above_notional, budget_id on the mandate itself) is still accepted when every listed instrument is quoted in one currency. The authorizer turns it into one row per venue, with max_order_qty applied to each instrument. Reads return limits, plus the flat fields when the mandate has a single row.
Reference data
Section titled “Reference data”A mandate is always checked together with reference data the authorizer holds:
- Instrument: lot size, tick size, currency, trading calendar and status.
- Protected unit: one product class on one venue, with its market rules and broker rules (accepted order types and times in force, minimum and maximum notional).
A product class the authorizer has no risk treatment for fails closed (A2M_UNSUPPORTED_PRODUCT).
Not standardised
Section titled “Not standardised”How a mandate is requested from and confirmed by the user is not standardised yet. In the reference implementation an operator API issues and revokes mandates. A user-facing mandate request flow is planned.