Start · Authentication

Authentication & agent keys

Public reads need no key. Anything that moves funds requires a scoped agent key whose risk policy is enforced server-side, before any order reaches a venue.

How agent keys work

A human owner authenticates with their multi (Dynamic) session JWT and mints keys for their agents. Each key looks like multi_sk_live_… (or multi_sk_test_…) and carries two things: a set of scopes (what it may do) and a risk policy (how much it may do). A key always trades the owner's own wallet.

  1. 1
    Mint a key (owner JWT)
    mint a key
    curl -X POST https://multi-venym-labs.vercel.app/api/agent/keys \
      -H "Authorization: Bearer <your-multi-jwt>" \
      -H "Content-Type: application/json" \
      -d '{
        "label": "momentum-bot",
        "scopes": ["market:read", "account:read", "orders:execute", "pairs:execute"],
        "policy": {
          "executionEnabled": true,
          "maxOrderUsd": 500,
          "dailyNotionalUsd": 2500,
          "maxLeverage": 5,
          "venuesAllow": ["hyperliquid", "lighter"],
          "marketsAllow": ["BTC", "ETH", "SOL"],
          "maxSlippageBps": 50
        }
      }'
  2. 2
    Store the secret once

    The raw multi_sk_… secret is returned once, at mint or rotate — multi stores only a salted hash. Put it in an env var (MULTI_API_KEY); never ship a key in client-side code.

  3. 3
    Send it on every request
    http
    Authorization: Bearer multi_sk_live_...
    # or
    x-multi-key: multi_sk_live_...
Lost or leaked? Rotate with POST /api/agent/keys/{id}/rotate — the old secret is revoked and a new one is minted in one call.

Scopes

A key carries a set of scopes. Each tool / endpoint declares the scope it needs.

market:readPublic market data. No key required — a key only raises your rate limits.
account:readPositions, balances, and open orders for the key's subject wallet.
orders:executePlace / cancel perp orders and open / close positions.
pairs:executeOpen and close long/short pair trades.
swap:quoteQuote swaps and build unsigned (non-custodial) swap transactions.
swap:executeExecute cross-chain swaps headlessly via a delegated wallet.

Risk policy

Every key carries a risk policy. Requests that breach it are rejected with a 403 / 429 before reaching a venue. Omitted caps fall back to conservative defaults.

executionEnabledbooleandefault false

Master switch — fail-closed. No execution of any kind until the owner sets this true.

maxOrderUsdnumberdefault $100

Per-order notional ceiling (USD).

dailyNotionalUsdnumberdefault $500

Rolling 24h (UTC-day) notional cap across all execution.

maxLeveragenumberdefault 10x

Maximum leverage for perp orders.

venuesAllowstring[]

Allowlist of venues, e.g. ["hyperliquid","lighter"]. Empty = all venues.

marketsAllow / marketsDenystring[]

Symbol allow / deny lists, e.g. ["BTC","ETH"]. Deny wins over allow.

swapChainsAllow(string|number)[]

Allowlist of chain IDs for swaps. Empty = all chains.

swapMaxUsdnumberdefault $100

Per-swap value ceiling (USD).

maxSlippageBpsnumberdefault 100

Hard slippage cap (basis points). Any requested slippage is clamped to this.

ipAllowstring[]

Optional IP allowlist for the key.

rateLimits{ read?, execute?, swap? }default 600 / 60 / 30 per min

Per-key request limits by class. Defaults: read 600/min, execute 60/min, swap 30/min.

Example

key request body
{
  "label": "momentum-bot",
  "scopes": ["market:read", "account:read", "orders:execute", "pairs:execute"],
  "policy": {
    "executionEnabled": true,
    "maxOrderUsd": 500,
    "dailyNotionalUsd": 2500,
    "maxLeverage": 5,
    "venuesAllow": ["hyperliquid", "lighter"],
    "marketsAllow": ["BTC", "ETH", "SOL"],
    "maxSlippageBps": 50
  }
}

Managing keys

Key management is authenticated with your multi (Dynamic) session JWT — a human owner mints keys for their agents. A key always trades the owner's own wallet.

POST/api/agent/keysowner JWT
Mint a key. Returns the raw secret once.
GET/api/agent/keysowner JWT
List your keys (redacted).
PATCH/api/agent/keys/{id}owner JWT
Update label, scopes, or policy.
POST/api/agent/keys/{id}/rotateowner JWT
Revoke and re-mint (new secret).
DELETE/api/agent/keys/{id}owner JWT
Revoke a key.
GET/api/agent/keys/{id}/usageowner JWT
Daily notional + order counts.

Auth errors

  • 401 UNAUTHORIZED — missing, invalid, or revoked key.
  • 403 INSUFFICIENT_SCOPE — the key lacks the required scope.
  • 403 EXECUTION_DISABLEDpolicy.executionEnabled is not true.
  • 403 ORDER_TOO_LARGE / LEVERAGE_TOO_HIGH / VENUE_NOT_ALLOWED — a policy cap was breached.
  • 429 RATE_LIMITED / DAILY_CAP — per-key rate limit or daily notional cap hit.

See the safety model for the full error catalog.