BLACK FRIDAY IS BACKNov 24 to 30. Join the list and get in a day early.Join the list

Autoview for AI agents

Autoview · AI agents (MCP) · Updated October 28, 2026

This page is written for an AI agent working without human help. It covers how to connect to the Autoview MCP server, run a simulated order with no account, price it, fix every error the server can return, and find out what going live costs.

Autoview is a webhook-driven trade-automation service. Any system that can send a webhook can drive orders on 22+ exchanges and brokers through it. The MCP server gives an agent the same engine through tool calls.

What the sandbox is (and is not)

  • What it is for: trying Autoview before you connect any exchange keys. It needs no account and no key, and it never places a real order.
  • How fills work: each order is priced once, at one snapshot price. That price is the venue's best ask (for a buy) or best bid (for a sell), read from its public ticker when the alert arrives, or the price you pass. A market order fills at that price. A limit order fills at that price only if the limit has reached it: a buy limit at or above it, a sell limit at or below it. A limit that has not been reached comes back not_filled, and the sandbox never fills it later.
  • What it does not model: order-book depth past the best ask and bid, slippage, latency or partial fills, and a price you pass gets no spread. Every order fills in full at that one price or not at all. Live results will differ from sandbox results.
  • For live-like execution: send the same orders through Autoview to a venue's own testnet or demo account. The venue's own test system then handles the order. These venues cost $0 on Autoview and need no subscription. Crypto: binance_testnet, binance_futures_testnet, bybit_testnet, deribit_testnet, okx_demo, kraken_futures_demo, gemini_sandbox, hyperliquid_testnet, gate_futures_testnet and crypto_demo. Forex and CFDs: oanda_practice and capital_demo. Stocks: alpaca_paper and tradestation-simulator. Futures: tradovate_simulation. Call pricing with no arguments for the full list (each one has demo: true). Your user needs an Autoview account and the venue's test keys, added at /account/credentials/create/.

Connect

  • Endpoint: https://api.autoview.com/mcp/ (streamable HTTP, JSON-RPC 2.0).
  • No token needed for three tools: sandbox_run, sandbox_results and pricing. They need no account and no exchange key, and they never place a real order.
  • Token needed for every other tool: setup, connect, link, catalog, entry, alert, command, hooks, events and explain_command. The token is an av_mcp_ personal access token from /account/tokens/, sent as an Authorization: Bearer header or as the token argument. The MCP overview covers those tools.

Client config for an MCP-aware agent (no header needed for the sandbox):

{
  "mcpServers": {
    "autoview": { "url": "https://api.autoview.com/mcp/" }
  }
}

Call tools/list first. If sandbox_run is not in the list, the server you reached does not have the sandbox tools yet. Tell your user, and point them to the web Alert Sandbox, which runs the same simulation in a browser.

Calling it with plain HTTP

A client with no MCP support can POST JSON-RPC to the endpoint directly. No initialize call is needed first.

  • Send Content-Type: application/json and Accept: application/json, text/event-stream. With only application/json in Accept, the server answers HTTP 406.
  • Send a normal User-Agent header, such as my-agent/1.0. Cloudflare in front of the server answers HTTP 403 with "error code: 1010" to some library defaults, for example Python's urllib (Python-urllib/3.x). curl and requests defaults work.
  • The reply is an event stream. The JSON-RPC message is on the line that starts with data: .
  • The tool's own answer is a JSON string in result.content[0].text. Parse it. When the tool refused, result.isError is true and the text holds { error, code, fix }.
curl -s -X POST https://api.autoview.com/mcp/ \
  -H 'User-Agent: my-agent/1.0' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

A reply looks like this:

event: message
data: {"result":{"tools":[ ... ]},"jsonrpc":"2.0","id":1}

Quick-start prompt

Paste this into any agent. It is self-contained: it names the endpoint, explains plain HTTP for clients without MCP, and tells the agent to follow the fix steps on any error.

You can test trade automation on Autoview without an account. Autoview is a webhook-driven service: any system that can send a webhook can drive orders on 22+ exchanges and brokers. Its MCP server is https://api.autoview.com/mcp/ (streamable HTTP, JSON-RPC 2.0).

1. Connect. If you support MCP, add that URL as a remote MCP server. No token is needed for the sandbox. If you do not support MCP, POST JSON-RPC 2.0 to the URL with the headers Content-Type: application/json, Accept: application/json, text/event-stream, and a normal User-Agent such as my-agent/1.0 (Cloudflare answers 403, error 1010, to Python's default urllib User-Agent). The reply is an event stream: the JSON is on the line that starts with "data: ", and the tool's answer is a JSON string in result.content[0].text.
2. Call tools/list. Use only sandbox_run, sandbox_results and pricing. They need no token, no account and no exchange key, and they never place a real order.
3. Call sandbox_run once for each of these orders:
   crypto:   {"order": {"exchange": "kraken", "symbol": "BTCUSD", "side": "buy", "qty": 0.01}}
   forex:    {"order": {"exchange": "oanda", "symbol": "EURUSD", "side": "buy", "qty": 1000}}
   US stock: {"order": {"exchange": "alpaca_paper", "symbol": "AAPL", "side": "buy", "qty": 1}}
   Autoview prices crypto from the venue's public ticker. It has no forex or stock price of its own, so for those pass "price" with "price_source" (where you got it) and "price_time" (when). Use a price you or your user are allowed to use for this. Never make one up; if you have none, ask your user. "price" is the market price you read; a limit order puts its limit in the order as "type": "limit", "limit_price": 50000.
   The first reply carries a "sandbox_id". Pass it back in each later sandbox_run so every run lands in the same sandbox, then call sandbox_results with it to read them all.
4. If a reply carries an error with a "code" and a "fix", or a fill carries "price_error", do what the fix says and call again. Every code and its fix: https://autoview.com/mcp/agents/
5. Call pricing with the exchanges you used. Report each fill's price, its "origin" label, and what going live would cost.
Sandbox fills use one snapshot price (the venue's best ask or bid, or your price) and do not model order-book depth, slippage, latency or partial fills, so live results will differ. For live-like execution, a venue's own testnet or demo account through Autoview costs $0.

Your first sandbox run

These are real calls. The replies are trimmed to the parts that matter; ids and prices will differ.

1. A crypto pair (Autoview prices it)

{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"sandbox_run",
  "arguments":{"order":{"exchange":"kraken","symbol":"BTCUSD","side":"buy","qty":0.01}}}}
{
  "sandbox": true, "real_order_placed": false,
  "sandbox_id": "91d25d6fb89071adcfc559af95aeb780",
  "orders": [{ "exchange": "kraken", "symbol": "BTCUSD", "side": "buy", "qty": "0.01", "type": "market",
    "fill": { "status": "filled", "price": 80709.8, "price_label": "Kraken XBTUSD best ask",
              "price_source": "Kraken XBTUSD best ask",
              "origin": "venue_ticker", "side_of_book": "ask", "price_age_ms": 0 } }],
  "next": "Call sandbox_results with sandbox_id ... To see what going live costs, call pricing."
}

A buy fills at the ask and a sell at the bid, read from the venue's public ticker when the alert arrives.

2. EUR/USD (you pass the price)

Without a price, the fill comes back unpriced with steps to fix it:

"fill": { "status": "no_price", "price": null,
  "price_error": { "code": "no_live_source", "market": "forex",
    "message": "No live price for EURUSD: Autoview has no live forex price of its own to give you.",
    "fix": [ "Pass price as a plain decimal ... Read it from your user's own data source.",
             "If your user has no forex price feed, a free OANDA practice account ... or a free Capital.com demo account ... is a place they can read one themselves. Autoview pricing your sandbox runs from a connected account is coming, not live yet ...",
             "Or put the price in the alert itself with fp= ..." ] } }

So pass the price you read for your user, with where and when you read it:

{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"sandbox_run",
  "arguments":{"order":{"exchange":"oanda","symbol":"EURUSD","side":"buy","qty":1000},
               "price":1.0842,"price_source":"my OANDA practice account","price_time":"2026-10-28T17:50:00Z"}}}
"fill": { "status": "filled", "price": 1.0842, "price_label": "caller-supplied",
          "price_source": "caller-supplied", "origin": "caller",
          "origin_note": "Caller-supplied price: the source and time are the ones you sent, not Autoview's quote.",
          "priced_at": "2026-10-28T17:50:00.000Z", "price_age_ms": 30370,
          "caller_price_source": "my OANDA practice account", "caller_price_time": "2026-10-28T17:50:00.000Z" }

price_label is Autoview's short label for where the fill price came from: caller-supplied here, or for a venue fill the venue, pair and side of the book (Kraken XBTUSD best ask). price_source holds the same label under its older name, kept so existing readers do not break. The source and time you named come back in caller_price_source and caller_price_time.

A price more than 15 minutes old when it arrives still fills, and the fill adds a price_warning, for example "The caller price is 5h 2m old (price_time ...); the fill used it as sent. ...". Read a fresh price if you want a current fill.

3. A US stock (you pass the price)

{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"sandbox_run",
  "arguments":{"order":{"exchange":"alpaca_paper","symbol":"AAPL","side":"buy","qty":1},
               "price":"231.50","price_source":"my Alpaca paper account (IEX, not consolidated)"}}}
"fill": { "status": "filled", "price": 231.5, "price_source": "caller-supplied", "origin": "caller",
          "caller_price_source": "my Alpaca paper account (IEX, not consolidated)" }

Two ways to send an order

  • order: structured fields exchange, symbol, side (buy or sell), qty, optional type (market by default, or limit) and limit_price (required for a limit). Those six fields only: order.price is refused with order_bad_field, because it could mean the limit or the market price. The limit goes in limit_price; the market price you read goes in the top-level price. The reply's compiled field shows the alert line it became.
  • command: alert text in the classic form (e=kraken s=BTCUSD b=buy q=0.01 t=market) or one line of the Autoview trade language (buy(BTCUSD, 0.01)). Add exchange when the text has no e=.

Send one or the other, not both. In alert text, a line with no t= is a limit order, the same default as any Autoview alert. Write t=market or use order when you mean a market order.

Pass the returned sandbox_id back to sandbox_run to add more alerts to the same sandbox, and read every stored fill with sandbox_results (newest first; more is true when older alerts exist). Any webhook sender can also POST alerts to the returned webhook_url.

The sandbox_results reply ends with next_step: the free testnet or demo venue for the market you just ran, and connect_url, the page where your user connects it. A Kraken BTCUSD run points to Binance Testnet (/account/setup/binance_testnet/), because Kraken spot has no practice venue on Autoview. An OANDA EURUSD run points to OANDA Practice (/account/setup/oanda_practice/). When no free venue fits, next_step says so: for Tradovate, free is false, because Tradovate Simulation keys need a funded live Tradovate account and Tradovate's paid API add-on. Pass next_step.text to your user as the next step.

How a fill gets its price

Each fill is priced by the first source that works, and fill.origin says which one it was:

originWhere the price came fromStatus
own_keyThe user's own connected exchange accountNot available yet, coming. The label exists, but Autoview cannot read a price from a connected account today. Pass price instead. On the raw webhook, price_origin=own_key is read as caller.
venue_tickerThe venue's free public ticker, read when the alert arrivesLive for crypto on Kraken (the default), Coinbase Advanced, Bybit, Bybit spot and OKX
callerThe price you passed, with your price_source and price_timeLive. Labelled caller-supplied, never shown as Autoview's quote.
alert_fpfp= in the alert itself, for example fp={{close}} in a TradingView alertLive. A symbol with a _DL or _DLY exchange suffix is marked delayed.

When nothing prices an order, the fill has status: "no_price" and a price_error object: { code, market, message, fix: [steps] }. market is one of crypto, forex, stock, futures or unknown.

A limit order can have a price and still not fill. On a venue with a public ticker, a buy limit is checked against the best ask and a sell limit against the best bid; with any other price, against that price. A buy limit below it, or a sell limit above it, comes back as status: "not_filled" with price: null, the reference_price it was checked against (and side_of_book on a venue), your limit, its origin, a note and a fix. The sandbox never fills it later. A limit the price has reached fills at the ask, bid or reference price, not at the limit. Do not pass the price again: send a market order, or move the limit to the other side of the reference price, or accept the result if a resting order is what you meant.

Price field rules: price is a positive number or a plain decimal string. price_source is up to 120 characters. price_time is ISO-8601 or epoch milliseconds, not before 2000 and not more than 24 hours in the future. price_source and price_time need price. An old price_time is not refused: past 15 minutes the fill carries price_warning.

Where to get a price, by market

Autoview does not fetch prices from third-party data providers. When it has no price of its own, the agent brings one from a source its user is allowed to use, and Autoview labels it as theirs.

MarketDoes Autoview price it?Free source the user can openWhat to send
CryptoYes, from the venue's public ticker (e= kraken, coinbase_advanced, bybit, bybit_spot or okx). Testnet and demo venues are not priced.None neededNothing. On a venue without a ticker, set one of those exchanges or pass price.
ForexNoA free OANDA practice account (v20 API, the user's own token) or a free Capital.com demo account (demo login, 2FA and an API key)price read from the user's account, with price_source and price_time
US stocks and ETFsNoA free Alpaca paper account. Its free real-time price is IEX only, not consolidated; full-market data on the free plan is 15 minutes delayed.price, with a price_source that says "IEX, not consolidated"
FuturesNoNone free for API use. A Tradovate demo has real-time prices only during its 14-day trial and is delayed after that, and Tradovate's market-data API needs a CME licence.price from a source the user is licensed for, or fp={{close}} from the user's own TradingView alert (a _DL symbol is labelled delayed)
Indices, commodities, CFDsNoA free Capital.com demo account, for the user's own runprice, or fp= in the alert
Canadian stocksNoNone free foundfp={{close}} from the user's own TradingView alert, or price

Connecting one of these accounts to Autoview does not yet make Autoview price the run for you (see own_key above). That is coming, not live. For now these accounts are places your user can read a price themselves: read it and pass it as price.

Data providers such as Finnhub, Twelve Data, Alpha Vantage and Tiingo have free plans licensed for personal use. An agent may use one through its own user's account, for that user's own run, under that provider's terms. Autoview never fetches from them, and a price from one of them is labelled caller-supplied like any other passed price.

Every error and its fix

Every refusal from the MCP server is { error, code, fix } with a stable snake_case code. Do what fix says and call again. The tables below give the same fix in more words.

sandbox_run and sandbox_results

codeWhat happenedFix
command_requiredNeither command nor order was sent, or command was emptySend one of them
command_and_orderBoth were sentSend only one
bad_v3_lineA trade-language line did not compile; error holds the compiler's messageCorrect the line per the message and the language page, or send order instead
bad_sandbox_idsandbox_id is not 32 lowercase hex charactersUse the id sandbox_run returned, or omit it to get a new one
order_missing_fieldexchange, symbol, side or qty is missing, or limit_price is missing on a limitAdd the named field
order_bad_fieldorder is not an object, it has a field it does not take (such as order.price), or a field has the wrong form: side not buy/sell, qty or limit_price not positive, type not market/limit, or a bad exchange or symbolSend the field in the form the schema describes. For a limit, use limit_price; for the market price you read, use the top-level price.
bad_priceprice is not a positive finite number or plain decimal string, is longer than 32 characters, or the sandbox refused the price. In the last case the sandbox's own price_error comes back beside the code.Send a positive number, such as 1.0842 or "1.0842", of 32 characters or fewer. A very small number such as 0.0000001 is fine; the server sends it as a plain decimal. If price_error is present, follow its fix steps.
bad_price_sourceprice_source is empty or over 120 charactersSend a short, non-empty description of where the price came from
bad_price_timeprice_time cannot be read, is before 2000, or is more than 24 hours aheadSend ISO-8601 (2026-10-28T17:00:00Z) or epoch milliseconds, for when you read the price
price_fields_without_priceprice_source or price_time was sent without priceAdd price, or drop the other two
sandbox_refusedThe sandbox refused the alert (HTTP 4xx other than 429); its text is in error. Reading an id that belongs to an account gets this too.Read error and correct the alert, or start a new sandbox by omitting sandbox_id
sandbox_rate_limitedToo many alerts in a short time (HTTP 429)Wait, then retry with fewer calls
sandbox_bad_answerThe sandbox answered with a server error or something that is not JSONRetry in a little while
sandbox_unreachableA network failure reaching the sandboxRetry in a little while
sandbox_timeoutNo answer within 8 secondsRetry
internal_errorAn unexpected failure on Autoview's sideRetry once; if it repeats, tell your user what you sent

pricing

codeWhat happenedFix
bad_exchangesexchanges is not an array of stringsSend an array of venue ids, such as ["kraken", "oanda"], or omit it to list every venue
too_many_exchangesMore than 60 idsSend 60 or fewer, or omit the field
unknown_exchangeAn id is not a known venue. It is listed in unknown[], or returned as the whole error when no id was known.Call pricing with no arguments to see every id, then use one of those

Fill status (fill.status)

statusWhat happenedWhat to do
filledThe order filled at price; origin and price_label say where the price came fromNothing, unless price_warning says the price was old
not_filledA limit order had a price (reference_price) but the limit was not marketable at it, so nothing filled. The sandbox never fills it later.Do what fix says: a market order, or a buy limit at or above the reference price (a sell limit at or below it). Do not pass the price again.
no_priceNothing priced the orderFollow price_error.fix, usually: pass price

Price errors inside a fill (price_error.code)

codeWhat happenedFix
no_live_sourceAutoview has no price of its own for this market or venue (forex, stocks, futures, unknown markets, crypto venues without a ticker)Pass price with price_source and price_time, or put fp= in the alert. For crypto, set a priced exchange. For an unknown market, set e= and s= so the market can be told.
venue_read_failedThe venue's public ticker failed, timed out (1 second), sent junk or showed a crossed bookRetry in a few seconds, or pass price, or use fp=
price_ambiguousprice was sent with an alert that has more than one symbol, so it was not usedSend one symbol per call when you pass price, or drop price and put fp= on each line
bad_price_paramOnly on the raw webhook: a price query parameter is malformed. HTTP 400, nothing stored. Over MCP the server checks these first and returns its own codes above.Send price as a plain decimal above zero, price_origin as caller or leave it out, and the other price parameters only together with price. Over MCP, if this reaches you it arrives as bad_price with this price_error beside it.

A fill with status: "no_price" and no price_error needs the same fix: pass price. The reply's next field says so.

Protocol errors (no code)

  • HTTP 406 "Not Acceptable": send Accept: application/json, text/event-stream.
  • HTTP 403 "error code: 1010": Cloudflare refused your client's User-Agent (Python's urllib default is one). Send a normal User-Agent header, such as my-agent/1.0.
  • HTTP 401 "unauthorized" on a tool call: that tool needs an Autoview token. For testing, use sandbox_run, sandbox_results or pricing. For the other tools, your user creates a token at /account/tokens/.
  • A schema error before the tool runs (for example a price_source over 120 characters, or a wrong type): the MCP library returns its own message without a code. Match the argument to the tool's input schema from tools/list.

Sandbox on the raw webhook

The sandbox's webhook_url takes alerts from any webhook sender: POST the alert text as the body. Prices go in URL query parameters: price, price_source, price_time and price_origin (caller, the default). This public webhook does not accept an own-account price: price_origin=own_key is read as caller, labelled caller-supplied, and never takes priority over a live venue price.

Going live

The sandbox never trades. Going live is set up by your user in a browser. You never see or handle exchange keys.

  1. Your user creates an account at /register/.
  2. Your user subscribes to the exchange at /account/subscription/. Practice venues and free venues need no subscription.
  3. Your user adds that exchange's API keys at /account/credentials/create/. This is the link the connect tool returns as connect_url. Real-money keys go in the browser, never in a chat.
  4. Your user creates an av_mcp_ token at /account/tokens/ with "Allow live orders" on, and sets its own two caps: a max order size and a daily limit.
  5. Optional, recommended: your user sets account caps on the same page, a max order size and a daily limit for every agent token on the account together. The token caps then have to fit inside them.

Then call setup with the token and check live_allowed for the exchange.

Caps

A live order through an agent needs the token's own caps. Account caps are optional: once set, they add a ceiling across every token on the account. Only your user can set or raise them, at /account/tokens/, with their passphrase. No tool can change them.

  • Unit: USD notional, the order quantity times its limit price. The market must be quoted in USD or a USD stablecoin (for example BTCUSD, BTCUSDT, EURUSD, AAPL).
  • Account caps: optional. With none set, the token caps govern alone. Once set, they are the hard outer limit. The account daily limit adds up the live orders of every agent token on the account, so a second token does not add more room. Webhook alerts are not counted.
  • Token caps: required for a live token. Each token's own max order size and daily limit sit inside the account caps when those are set, so one agent cannot use the whole day.
  • Max order size: one live order above the token's, or the account's when set, is refused.
  • Daily limit: the sum of live orders since 00:00 UTC, counted per token, and for the whole account when account caps are set. An order that would take either past its limit is refused. Orders count when they are sent, filled or not.
  • Pause: your user can pause all agent trading on the account at /account/tokens/, with their passphrase. While it is on, every new live order from any token is refused. Cancel, close and flat still work. No tool can turn it on or off.
  • Read them: call live_limits with the token. It returns the token's caps and the account's (account.set: false when none are set), what each has used today, what is left, when the day resets, and agent_trading_paused.

Live orders go through entry with live: true, as a limit order with a number quantity and a price. Dry runs are not capped and work as before.

Refusals for live orders

codeWhat happenedFix
agent_trading_pausedYour user paused all agent trading on the accountCancel and close still work. Ask your user to turn agent trading back on at /account/tokens/
caps_not_setThe token allows live orders but has no capsAsk your user to set a max order size and a daily limit on this token at /account/tokens/
caps_unavailableThe caps could not be read, so nothing was sentTry again shortly. Nothing was placed
cap_quantity_unsupportedA percent quantity has no USD size before it fillsSend a number quantity
cap_limit_price_requiredA market order, or a limit order with no priceSend type: "limit" with a price
cap_quote_unsupportedThe market is not quoted in USD or a USD stablecoinPick a USD-quoted market
cap_market_unsupportedFutures contracts have a multiplier, so quantity times price is not their USD sizeUse a market other than futures for live agent orders
cap_max_order_exceededThe order's USD size is over the max order sizeSend a smaller order, or ask your user to raise the cap at /account/tokens/
cap_account_max_order_exceededThe order's USD size is over the account max order sizeSend a smaller order, or ask your user to raise the account cap at /account/tokens/
cap_daily_limit_exceededThe order would take this token's total today past its daily limitWait for 00:00 UTC, send a smaller order, or ask your user to raise the cap at /account/tokens/
cap_account_daily_limit_exceededThe order would take the account's total today, all tokens together, past the account daily limitWait for 00:00 UTC, send a smaller order, or ask your user to raise the account cap at /account/tokens/

Pricing

Call pricing (no token) with the exchanges your user wants. Omit exchanges to list every venue.

  • Each live exchange is its own subscription. Most are $39.99 a month or $399.99 a year.
  • Practice, demo and testnet venues are free ($0), for example oanda_practice and alpaca_paper.
  • A few venues are free live. Crypto.com is one.
{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"pricing","arguments":{"exchanges":["oanda"]}}}

{ "currency": "USD",
  "venues": [{ "exchange": "oanda", "name": "OANDA", "live_monthly": 39.99, "live_yearly": 399.99, "demo": false,
               "free_practice_venue": "oanda_practice" }],
  "how_to_go_live": "Each live exchange is its own subscription; ...",
  "source": "autoview.com price list, as of 2026-10-24. Prices are before any tax or coupon." }

Prices are before any tax or coupon. The pricing page is the published list.

The Autoview MCP overview

What brought you here today?