Guides · Safety

Safety model

Execution is gated by scopes and a server-side risk policy. Quotes and prepared swaps never move funds. Orders that breach policy never reach a venue.

Fail-closed by default. A freshly minted key cannot execute anything: policy.executionEnabled defaults to false, and every execution path also requires its matching scope. Nothing moves funds until a human owner turns both on.

Risk gates

Every policy check runs server-side, before an order is sent to any venue. An agent cannot bypass them — they are not client-side suggestions.

  • Fail-closed — execution is off until policy.executionEnabled is true and the matching scope is granted.
  • Pre-trade checks — size, leverage, venue, market, and slippage caps are checked before an order is sent. A breach returns 4xx; nothing is placed.
  • Daily notional cap — reserved atomically per key, per UTC day; reverted if execution fails.
  • Least privilege — grant only the scopes an agent needs; keep maxOrderUsd / dailyNotionalUsd tight.

Execution strategies (TWAP / scaled)

Strategies are policy-checked for their full notional up-front — an agent can't evade maxOrderUsd or dailyNotionalUsd by slicing a big order into small pieces. If the key is revoked (or execution disabled) mid-flight, the strategy self-cancels before its next slice.

Idempotency

Send an Idempotency-Key header on every execution request. Retries with the same key are de-duplicated and return the original result, so a network blip never double-submits. This is essential for autonomous loops.

Custody

  • Non-custodialswap_prepare returns an unsigned transaction you sign with your own wallet. multi never holds your keys.
  • Delegated — perp execution and headless swaps run against credentials the owner has explicitly stored, bounded by the key's policy. A key can only ever trade the owner's own wallet.
Treat agent keys like production secrets. Scope them narrowly, set an expiresAt, optionally pin an ipAllow list, and rotate regularly. Run with MULTI_READONLY=1 wherever execution isn't needed.

Error & status catalog

Every policy denial names the exact cap it hit, so an agent can adapt instead of blindly retrying. The SDKs surface these as typed errors (MultiAuthError, MultiRateLimitError, …).

401UNAUTHORIZEDMissing, invalid, or revoked agent key.Check the header; rotate or re-mint the key.
401KEY_EXPIREDAgent key has expired.Mint a new key (or rotate) and update MULTI_API_KEY.
403INSUFFICIENT_SCOPEKey lacks the scope the endpoint requires.Owner adds the scope via PATCH /api/agent/keys/{id}.
403EXECUTION_DISABLEDpolicy.executionEnabled is not true.Owner flips the master switch — fail-closed by design.
403ORDER_TOO_LARGEOrder notional exceeds maxOrderUsd.Shrink the order or raise the cap; consider a TWAP.
403LEVERAGE_TOO_HIGHLeverage exceeds maxLeverage.Lower leverage or raise the policy cap.
403VENUE_NOT_ALLOWEDVenue not in venuesAllow.Route to an allowed venue or extend the allowlist.
403MARKET_NOT_ALLOWEDSymbol not in marketsAllow.Trade an allowed symbol or extend the allowlist.
403MARKET_DENIEDSymbol is in marketsDeny (deny wins over allow).Pick another market — deny entries are absolute.
403SWAP_TOO_LARGESwap value exceeds swapMaxUsd.Split the swap or raise the per-swap cap.
403CHAIN_NOT_ALLOWEDChain not in swapChainsAllow.Swap on an allowed chain or extend the allowlist.
429DAILY_CAPRolling 24h notional cap reached.Stop executing until the UTC day rolls, or raise dailyNotionalUsd.
429RATE_LIMITEDPer-key request rate limit hit.Back off per the Retry-After header — the SDKs do this for you.
400VALIDATION_ERRORMalformed request body.Fix the payload; the message names the offending field.

Rate limits

Per-key limits apply on top of a global IP limit: roughly 600/min for reads, 60/min for execution, 30/min for swaps (overridable per key via policy.rateLimits). On 429, back off using the Retry-After header — the SDKs do this for you.

Questions? Back to overview · Authentication.