Objects
Intent
What an agent asks for.
An intent is what an agent asks for. One wire form is shared by every binding: the REST endpoints POST /v1/check and POST /v1/authorize, and the MCP tools a2m_check and a2m_place_order all take the same object.
Fields
Section titled “Fields”| Field | Type | Required | Notes |
|---|---|---|---|
intent_id |
string | yes | The caller’s idempotency key. Repeating it with the same body returns the same result; repeating it with a different body is A2M_IDEMPOTENCY (409). |
venue |
string | yes | Venue name, for example hyperliquid or sim. |
instrument |
string | yes | The venue’s own symbol, for example ETH on Hyperliquid perpetuals or BTC/USDT. |
side |
string | yes, except mleg |
buy or sell. A spread has a side per leg instead. |
qty |
decimal string | yes, unless notional |
Must be positive. At most 9 decimal places; more is a 400 (APEX_4011), never rounded. The venue’s lot size applies. Options: contracts; mleg: strategy units. |
notional |
decimal string | no | Instead of qty, for a market order: spend (buy) or raise (sell) this much in the quote currency. The venue’s filled quantity is final. |
order_type |
string | no | limit (default), market, stop, stop_limit or trailing_stop. |
limit_price |
decimal string | for limit, stop_limit |
At most 9 decimal places; more is a 400 (APEX_4011), never rounded. The venue’s tick applies. For mleg, the net price per unit (positive a debit, negative a credit). |
stop_price |
decimal string | for stop, stop_limit |
The trigger. |
trail_price, trail_percent |
decimal string | for trailing_stop |
Exactly one. |
order_class |
string | no | simple (default), bracket (entry plus take_profit and stop_loss), oto (entry plus one exit), oco (take_profit and stop_loss closing a position), mleg (2 to 4 option legs). |
take_profit |
object | for bracket, oco; oto one of the two |
{ "limit_price": "..." } |
stop_loss |
object | for bracket, oco; oto one of the two |
{ "stop_price": "...", "limit_price": "..." }; limit_price makes it a stop limit. |
legs |
array | for mleg |
{ "instrument", "ratio_qty" (integer, default 1), "side", "position_intent" }, one underlying and expiry. |
position_intent |
string | no | Options: buy_to_open, buy_to_close, sell_to_open, sell_to_close. |
replaces |
string | no | The client_order_id of a working order of the same agent, venue, instrument and side that this intent replaces. |
time_in_force |
string | no | gtc (default), ioc, fok, post_only, day, opg, cls. See below. |
reference_price |
decimal string | see notes | The agent’s view of the price. At most 9 decimal places. Ignored when the authorizer prices intents itself from a quote source. |
reference_price_ts |
RFC 3339 string | see notes | Time of the reference price. A missing, unparseable, stale or future reference fails closed (A2M_STALE_PRICE). The reference implementation’s default maximum age is 10 seconds. |
reduce_only |
boolean | no | Only shrink an existing position. |
extended_hours |
boolean | no | Default false. When true, the order may also trade in the market’s pre- and post-market sessions. Only a limit order with day or gtc is accepted; any other combination is a 400 (APEX_4011). See Sessions and calendars. |
The agent does not send a client_order_id. The authorizer mints one when it issues an executable decision. See Orders and execution reports.
Time in force
Section titled “Time in force”The protocol values are lower case. Common aliases are accepted and normalised (alo, add_liquidity_only and postonly become post_only; good_till_cancel becomes gtc; immediate_or_cancel becomes ioc; fill_or_kill becomes fok). Any other value is a 400 error, never a silent default.
| Value | Meaning |
|---|---|
gtc |
Good till cancelled |
ioc |
Immediate or cancel: fill what crosses now, cancel the rest |
fok |
Fill or kill |
post_only |
Add liquidity only; rejected if it would cross |
day |
Expires at the end of the venue’s trading day |
opg |
Opening auction only |
cls |
Closing auction only |
The decision fixes the time in force and the order type; nothing downstream may change them. A venue that does not support a combination MUST refuse the order before sending it (A2M_TIME_IN_FORCE or A2M_ORDER_TYPE). It MUST NOT downgrade, coerce or substitute a supported value.
The default time_in_force is gtc. A market order that omits it is therefore gtc, and is refused on any venue that does not accept market plus gtc. The agent SHOULD set a time in force the venue accepts for that order type. For a market order, Hyperliquid accepts ioc; Alpaca accepts day (stocks and options) or gtc and ioc (crypto).
What a venue accepts is declared per asset class by its adapter (see Venue adapter contract): order types with their time in force, order classes, notional orders, replace, extended hours, maximum legs and exercise. The authorizer’s rules are venue-neutral; the executor refuses an undeclared form before sending (A2M_ORDER_TYPE, A2M_ORDER_CLASS, A2M_TIME_IN_FORCE, A2M_REPLACE, A2M_ACTION).
Sessions and calendars
Section titled “Sessions and calendars”The authorizer judges session against the instrument’s calendar, in that calendar’s time zone.
- Regular sessions are the market’s ordinary trading hours. An intent with
extended_hoursfalse is accepted only inside a regular session on a trading day (A2M_MARKET_CLOSEDotherwise). - Extended sessions are the pre- and post-market periods, when the market has them. US equities in the reference data use 04:00–09:30 and 16:00–20:00 Eastern Time (17:00 on early-close days).
- Holidays are closed for every session.
- Early closes cut a trading day short: regular sessions end at the early close, and extended sessions end at the early extended close. The gap between the early regular close and the usual post-market start stays closed; the authorizer fails closed rather than guess.
- A market with no extended sessions (for example a 24-hour crypto venue) refuses
extended_hourstrue (A2M_EXTENDED_HOURS). If both regular and extended sessions are closed, the refusal isA2M_MARKET_CLOSED. - A missing or unreadable calendar fails closed (
A2M_MARKET_CLOSED).
The executor refuses an extended-hours decision before sending (A2M_EXTENDED_HOURS, 422) unless the venue declares extended_hours in its capabilities (Alpaca does). It MUST NOT silently send the order as a regular-hours order.
Option contracts
Section titled “Option contracts”Listed options are named by OCC symbol: root, expiry YYMMDD, C or P, strike times 1000 in 8 digits (SPY261218C00600000). The authorizer adds a contract to its reference data the first time it is named (multiplier 100). Allowlists match an option by its underlying. Which options an agent may open is the mandate row’s options_level; see Mandate.
Option actions
Section titled “Option actions”POST /v1/actions with { "intent_id", "venue", "instrument", "action" } asks to exercise a long option, or tells the broker do_not_exercise it at expiry. It needs options level 2 and a long position; an exercise must also fit max_order_notional (the shares at the strike) and, for a call, the strike cash at the broker. The answer is a signed decision like an order’s, holding nothing; the shares or cash arrive as broker activity, which the authorizer books.
Example
Section titled “Example”{ "intent_id": "demo-0001", "venue": "hyperliquid", "instrument": "ETH", "side": "buy", "qty": "0.01", "order_type": "limit", "limit_price": "2000", "time_in_force": "gtc"}A bracket: buy at market, then sell at a take-profit or a stop loss, whichever comes first.
{ "intent_id": "demo-0002", "venue": "alpaca", "instrument": "AAPL", "side": "buy", "qty": "1", "order_type": "market", "time_in_force": "day", "order_class": "bracket", "take_profit": { "limit_price": "370" }, "stop_loss": { "stop_price": "345" }}