Agents
How an account authorises a key to trade for it, the limits the chain enforces on that key, and the reason codes it refuses with.
An agent is a key that trades for an account. The account registers it, gives it a policy, and can revoke it at any time. The chain checks every operation the agent signs against that policy, and refuses what it forbids with a reason code. An agent can never withdraw: the chain refuses a withdrawal signed by anything but the account's own key.
Whether the full agent rules are enforced right now: —.
What makes a key an agent
An agent key needs two things:
- a registration, signed by the account:
RegisterAgentV2, with a name, a mandate and an expiry; - a session of the account naming the agent key (
SessionCreate): an agent signs orders as a session key of its account.
An account holds one session at a time. Opening a session for an agent ends the account's other session (a browser's, for example), and the other way round.
The operations
All are EIP-712, under the VordCore domain, sent to POST /submit (signing,
REST):
| Operation | Signed by | What it does |
|---|---|---|
RegisterAgentV2 | the account | registers an agent with a name, a mandate and an expiry |
SetAgentName | the account | renames it |
SetAgentPolicyV1 | the account, or the agent to tighten only | sets what it may do and how much |
SetAgentMarketLimit | the account | allows or denies one market, with order, position and leverage limits |
ClearAgentLock | the account | lifts a lock the agent is in |
RevokeAgent | the account | ends it for good |
The exact type strings, field by field, are in Signing. A 202 from
/submit means received: read the agent back with GET /agents/{account}/{agent} to see what was applied.
Rules the chain enforces
Expiry. expiresMs is UNIX milliseconds on the chain's clock. Once the chain's time reaches it the agent can sign
nothing; 0 means already expired. Renew by registering again with a later expiry. Resting orders are not cancelled
by expiry.
Nonces. Every operation for an agent carries a nonce above the last one stored for that account and agent; the time in milliseconds works.
Names. 3 to 32 characters: letters, digits, space, -, _ and ., with at least one letter or digit, no leading,
trailing or double space. A name is unique among the account's own agents and is checked against reserved words. A
rename waits a day after the last naming; the first naming is free. An account can hold up to 16 live agents.
Capabilities. A policy grants capabilities as bits: place 1, cancel 2, modify 4, take-profit and stop-loss 8, close 16, vault 32. Anything not granted is refused.
Limits. A policy sets the agent's total exposure, maximum leverage, daily loss limit, daily fee cap, operations per window, active hours (UTC), and a price band around the oracle price. A zero means "no limit" for leverage, fee cap and operations.
Markets. A policy names the markets the agent may trade, with SetAgentMarketLimit: a market it does not name is
refused (market_not_allowed), and each named market has its own largest order, largest position and leverage.
Raises wait an hour. Tightening any limit applies at once. Loosening one — a higher limit, a new capability, a later
expiry — applies only an hour after the last loosening, so a limit cannot be widened again and again in quick succession. The
agent read shows last_raise_ms and next_raise_ms.
Locks. Reaching the daily loss limit or the daily fee cap, or a liquidation, locks the agent to reduce-only and
cancels its resting orders that are not reduce-only. The account lifts the lock with ClearAgentLock, naming the lock
it clears, so a clear signed in advance can never clear a later lock.
Reason codes
Every refusal is recorded (GET /events/agent/{agent}, kind agent_refused) with one of these reasons. An order refused
at intake answers 403 with "code": "agent_refused", the reason and its meaning. The table is read from the testnet's
spec, where the full rules are enforced:
| Reason | Meaning (as the network publishes it) |
|---|---|
registration_not_live | The agent's registration is revoked or expired. |
policy_expired | The agent's policy has expired. |
policy_disabled | The owner disabled the agent's policy. |
no_policy | The agent has no policy, so every action is refused. |
agents_paused | All agents are paused on this network. |
agent_mode_off | The agent's trading mode is off. |
capability_not_granted | The policy does not allow this kind of action. |
market_not_allowed | The policy does not allow this market. |
outside_active_window | Outside the policy's active hours (UTC). |
rate_limit | The agent used all actions allowed in its window. |
locked_reduce_only | The agent is locked to reduce-only (a limit was reached). |
reduce_only_or_side | Only reducing orders, or only the policy's side, are allowed. |
max_order | The order is larger than the policy allows. |
max_position | The position would exceed the policy's maximum. |
max_total_exposure | The agent's total exposure would exceed the policy's maximum. |
max_leverage | The leverage is above the policy's maximum. |
daily_loss_limit | The agent's daily loss limit is reached. |
daily_fee_cap | The agent's daily fee cap is reached. |
price_outside_band | The price is outside the policy's band around the oracle price. |
oracle_unavailable | The market's oracle price is missing, stale or its breaker is tripped. |
not_agents_order | The order or TWAP was not placed by this agent. |
other | Another agent check refused the action. |
Network facts last checked against the network 2026-10-22 13:00:37 UTC · mainnet spec v28 · testnet spec v8
CoreWriter
How an EVM contract trades and moves funds on VordCore — transfers, USDC between the EVM and the core, orders and vault actions — on the testnet.
Signing
The EIP-712 domains, why they are bound to the genesis, the type strings of every public operation, and where the canonical test vectors are.