Developers

Build on Backed

Trade your account with your own code or an AI agent. Keys, limits, every endpoint with copy-paste examples, and how to connect Claude, Cursor and other assistants.
REST · JSONMCP for AI agents

Authentication#

Create a key in the app under Settings → API & AI agents and send it with every request, either as Authorization: Bearer bk_live_… or X-API-Key: bk_live_…. The key is shown once; keep it secret.

Key typeCan do
ReadEvery GET: accounts, rules, limits, positions, orders, fills, statement and market data. Never trades.
TradeRead, plus placing and cancelling orders and adding take-profit / stop-loss.
  • Restrict a key to one account and give it an expiry where you can. Revoke it any time in Settings; it stops working at once.
  • Payouts, key management and checkout need you signed in to the app; keys cannot do them.
  • Orders placed with a key go through exactly the same rules as the app and are marked as API orders in your history.
Base URL
https://api.backed.io

Limits and pagination#

LimitValue
Reads per key600 per minute
Order writes per key60 per minute
Over the limit429 with a Retry-After header (seconds)

Lists return { items, nextCursor }, newest first. Pass cursor=nextCursor for the next page and limit to change its size. Money is USD; numeric database columns come back as strings.

Errors#

Every error
{ "error": { "code": "insufficient_scope", "message": "this API key is read-only (needs the trade scope)" } }
HTTPCodeMeaning
400invalid_requestA field is missing or malformed; `details` says which.
401unauthorizedKey missing, mistyped, revoked or expired.
403insufficient_scopeA read-only key tried to trade.
403account_not_allowedThe key is restricted to another account.
403api_trading_disabledAPI and AI trading is turned off for this account.
404not_foundUnknown id, or not yours.
429rate_limitedToo many requests; wait for `Retry-After` seconds.

Rejected orders are not errors

A rule that blocks an order (for example the daily loss limit or a position size cap) shows up as order status rejected with the rule in reject_rule, not as an HTTP error. The rules book explains each rule.

Account#

Your profile, accounts, rules and history. {id} is an account id, or me for your most recent tradable account.

Orders#

Orders are simulated prop-firm orders. POST /v1/orders queues the order and answers 202 with its id; the risk engine fills or rejects it within seconds against live prices and your account rules. Poll GET /v1/orders/{orderId} (or the account’s orders) for the result.

Market data#

Read-only market data for every market an account can trade. Candles take tf (1s … 1d, depending on the market), and from / to in unix seconds or countback.

Public catalog#

No key needed.

Live updates#

The app streams prices and account events over a WebSocket. For API keys, poll the REST endpoints instead: an account check every few seconds is well inside the limits. Streaming for keys is planned.

Connect an AI (MCP)#

Our Model Context Protocol server is free and lets an AI assistant read your account and research and trade every market Backed lists: memecoins, crypto perps, TradFi (stocks, FX, gold, oil, indices), CME futures in whole contracts and prediction markets. Orders go through the same API and rules as the app.
  • URL: shown in Settings → API & AI agents in the app (Streamable HTTP).
  • Auth: your API key as Authorization: Bearer bk_live_…. Start with a read key; use a trade key only when you want the AI to place orders.
  • Placing or closing needs your OK in the chat: place_order, place_perps_order, place_prediction_order and close_position refuse to trade without confirm: true and return a preview instead.
  • Take profits, stop losses, limits and cancels you ask for are set straight away, and a stop, take profit or limit then runs on its own when its price is reached unless you ask the AI to change it.
  • Payout eligibility and history, Backpay, rank, Backed balance and packs are readable (rewards with a key that covers the whole profile); requesting payouts, claiming, opening packs and checkout stay in the app and are refused for keys.
  • Memecoins: launchpad tokens (pump.fun, bonk, bags, brrr) plus the top 100 Solana memecoins on CoinMarketCap, such as BONK, WIF and POPCAT.
Claude Code
claude mcp add --transport http backed <mcp-url> --header "Authorization: Bearer bk_live_…"

Claude Desktop needs Node.js 18 or newer for the mcp-remote bridge; restart it after saving the config. Any MCP client with Streamable HTTP and custom headers works the same way. Web connectors that sign in with OAuth (claude.ai, ChatGPT) are coming.

MCP tools#

ToolWhat it doesKey
list_accountsYour accounts: plan, state, markets, balance, equity.Read
get_accountBalance, equity, target progress, daily loss and drawdown used and left, buying power, lifetime stats.Read
get_rulesThe account’s rules in plain words for every market, plus the raw values.Read
get_max_order_sizeThe largest order the rules allow right now on any market, and the rule that binds.Read
list_positionsOpen positions in every market with entry, mark, PnL, leverage and TP/SL.Read
list_open_ordersResting limits, stops and TP/SL legs in every market.Read
get_orderOne order: status, fills, fee, slippage, rejection rule.Read
get_trade_historyEvery fill with price, fee and realised PnL, totals per market.Read
get_pnl_by_marketRealised and open PnL, wins, losses and best and worst trade per market.Read
get_payout_eligibilityWhether a funded account can request a payout, what blocks it, how much and when.Read
get_payout_historyPayout requests: amount, your share, status and payment.Read
get_rewardsRank level and XP, Backpay ready to claim per cadence, level rewards not claimed, Backed balance. Read-only.Read
get_backed_balance_historyBacked balance credits and spends over time. Read-only.Read
get_packsBacked Packs held and recent openings with their prizes. Read-only.Read
search_tokensFind memecoins by symbol, name or mint.Read
get_tokenMemecoin price, market cap, liquidity, volume, holder concentration.Read
discover_tokensNew, graduating and graduated memecoin lists.Read
list_marketsCrypto perps, TradFi (stocks, FX, gold, oil, indices) and futures, with price, volume, funding and leverage.Read
get_marketOne perps, TradFi or futures market: price, funding, leverage, trading hours, contract spec.Read
search_predictionsFind prediction events by text or category with YES / NO prices.Read
get_prediction_eventOne prediction event and every market in it.Read
get_prediction_marketOne prediction market: rules, prices, status, end date.Read
get_candlesOHLCV bars for any market.Read
get_order_bookLive order book for perps, TradFi, futures and prediction outcomes.Read
get_recent_tradesLatest trades on any market.Read
preview_orderMemecoin dry run: fill, fee, slippage, every rule check, the largest size that passes.Read
place_orderMemecoin market or limit order with optional TP/SL. Needs confirm: true.Trade
preview_perps_orderPerps, TradFi or futures dry run: size, margin, fee, liquidation, limits.Read
place_perps_orderPerps, TradFi or futures order: market, limit or stop, long or short, leverage or contracts, TP/SL. Needs confirm: true.Trade
preview_prediction_orderPrediction dry run: shares, price, fee, what it pays if it wins, limits.Read
place_prediction_orderBuy or sell YES / NO shares at market or with a limit, optional TP/SL. Needs confirm: true.Trade
close_positionClose part or all of a position in any market. Needs confirm: true.Trade
set_tpslAdd take-profit / stop-loss legs to a position in any market. Set at once; runs on its own.Trade
cancel_orderCancel a resting limit, stop or TP/SL leg. Happens at once.Trade

Bot quickstart (Python)#

Check the account, find a market, place a sized order with a stop, and wait for the fill.
Python
import os, time, uuid, requests

API = "https://api.backed.io"
H = {"Authorization": f"Bearer {os.environ['BACKED_API_KEY']}"}

# 1. a tradable account, and how much room it has
me = requests.get(f"{API}/v1/me", headers=H).json()
acct = next(a for a in me["accounts"] if a["tradable"])
view = requests.get(f"{API}/v1/accounts/{acct['id']}", headers=H).json()
print(acct["planLabel"], view["balanceUsdc"], view["equity"], "left before max drawdown:", view["leftUsd"])

# 2. find the BTC perp
perps = requests.get(f"{API}/v1/instruments", params={"market": "perps"}).json()["items"]
btc = next(i for i in perps if i["externalId"] == "BTC")

# 3. a $500, 5x long with a stop-loss (the Idempotency-Key makes a retry safe)
order = requests.post(f"{API}/v1/orders", headers={**H, "Idempotency-Key": str(uuid.uuid4())}, json={
    "accountId": acct["id"], "instrumentId": btc["id"], "side": "buy", "type": "market",
    "notional": "500", "leverage": 5,
    "tpsl": [{"kind": "sl", "triggerPrice": str(round(float(btc["mark"]) * 0.98, 1)), "sizePct": 100}],
}).json()

# 4. orders are filled or rejected within seconds: poll for the result
for _ in range(10):
    o = requests.get(f"{API}/v1/orders/{order['orderId']}", headers=H).json()
    if o["status"] in ("filled", "rejected", "cancelled"):
        print(o["status"], o.get("reject_rule"))
        break
    time.sleep(1)

AI coding agent quickstart#

Building with Claude Code, Cursor or another coding agent? Paste this into its context first so it trades safely.
Context for your agent
You are trading a Backed prop-firm account through its REST API.
Base URL: https://api.backed.io   Auth header: Authorization: Bearer $BACKED_API_KEY

Rules that matter:
- Orders are simulated. POST /v1/orders answers 202 {orderId, status: "pending"}; poll GET /v1/orders/{orderId} until
  filled / rejected. A rejection names the rule (reject_rule).
- Equity-based daily loss limit and max drawdown: crossing either ENDS the account. Read GET /v1/accounts/me/rules
  and GET /v1/accounts/me/limits before sizing anything.
- One trade may commit at most a set share of the balance (margin for perps). /limits returns the largest order
  each market accepts right now.
- Send a fresh Idempotency-Key with every order. Never resend a failed order without checking it was not placed.
- Limits: 600 reads and 60 writes per minute; on 429 wait Retry-After seconds.
- Numeric database columns come back as strings.
Always show the user the order (market, side, size, leverage, stop) and wait for their OK before placing it.

Common pitfalls#

ProblemFix
The order came back "pending"That is normal: orders are processed asynchronously. Poll GET /v1/orders/{orderId}.
A retry placed a second orderSend an Idempotency-Key header; the same key returns the first order instead.
Order rejected with a rule codeRead /v1/accounts/{id}/limits for the largest size that passes, and the rules book for the rule.
401 after it worked beforeThe key expired or was revoked. Create a new one.
403 account_not_allowedThe key is limited to another account.
Numbers are stringsParse them as decimals; never use floats for money comparisons.
429 rate_limitedWait for the Retry-After seconds and slow your polling.