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 type | Can do |
|---|---|
| Read | Every GET: accounts, rules, limits, positions, orders, fills, statement and market data. Never trades. |
| Trade | Read, 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.
https://api.backed.ioLimits and pagination#
| Limit | Value |
|---|---|
| Reads per key | 600 per minute |
| Order writes per key | 60 per minute |
| Over the limit | 429 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#
{ "error": { "code": "insufficient_scope", "message": "this API key is read-only (needs the trade scope)" } }| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_request | A field is missing or malformed; `details` says which. |
| 401 | unauthorized | Key missing, mistyped, revoked or expired. |
| 403 | insufficient_scope | A read-only key tried to trade. |
| 403 | account_not_allowed | The key is restricted to another account. |
| 403 | api_trading_disabled | API and AI trading is turned off for this account. |
| 404 | not_found | Unknown id, or not yours. |
| 429 | rate_limited | Too many requests; wait for `Retry-After` seconds. |
Rejected orders are not errors
reject_rule, not as an HTTP error. The rules book explains each rule.Account#
Orders#
Market data#
Public catalog#
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)#
- 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 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#
| Tool | What it does | Key |
|---|---|---|
list_accounts | Your accounts: plan, state, markets, balance, equity. | Read |
get_account | Balance, equity, target progress, daily loss and drawdown used and left, buying power, lifetime stats. | Read |
get_rules | The account’s rules in plain words for every market, plus the raw values. | Read |
get_max_order_size | The largest order the rules allow right now on any market, and the rule that binds. | Read |
list_positions | Open positions in every market with entry, mark, PnL, leverage and TP/SL. | Read |
list_open_orders | Resting limits, stops and TP/SL legs in every market. | Read |
get_order | One order: status, fills, fee, slippage, rejection rule. | Read |
get_trade_history | Every fill with price, fee and realised PnL, totals per market. | Read |
get_pnl_by_market | Realised and open PnL, wins, losses and best and worst trade per market. | Read |
get_payout_eligibility | Whether a funded account can request a payout, what blocks it, how much and when. | Read |
get_payout_history | Payout requests: amount, your share, status and payment. | Read |
get_rewards | Rank level and XP, Backpay ready to claim per cadence, level rewards not claimed, Backed balance. Read-only. | Read |
get_backed_balance_history | Backed balance credits and spends over time. Read-only. | Read |
get_packs | Backed Packs held and recent openings with their prizes. Read-only. | Read |
search_tokens | Find memecoins by symbol, name or mint. | Read |
get_token | Memecoin price, market cap, liquidity, volume, holder concentration. | Read |
discover_tokens | New, graduating and graduated memecoin lists. | Read |
list_markets | Crypto perps, TradFi (stocks, FX, gold, oil, indices) and futures, with price, volume, funding and leverage. | Read |
get_market | One perps, TradFi or futures market: price, funding, leverage, trading hours, contract spec. | Read |
search_predictions | Find prediction events by text or category with YES / NO prices. | Read |
get_prediction_event | One prediction event and every market in it. | Read |
get_prediction_market | One prediction market: rules, prices, status, end date. | Read |
get_candles | OHLCV bars for any market. | Read |
get_order_book | Live order book for perps, TradFi, futures and prediction outcomes. | Read |
get_recent_trades | Latest trades on any market. | Read |
preview_order | Memecoin dry run: fill, fee, slippage, every rule check, the largest size that passes. | Read |
place_order | Memecoin market or limit order with optional TP/SL. Needs confirm: true. | Trade |
preview_perps_order | Perps, TradFi or futures dry run: size, margin, fee, liquidation, limits. | Read |
place_perps_order | Perps, TradFi or futures order: market, limit or stop, long or short, leverage or contracts, TP/SL. Needs confirm: true. | Trade |
preview_prediction_order | Prediction dry run: shares, price, fee, what it pays if it wins, limits. | Read |
place_prediction_order | Buy or sell YES / NO shares at market or with a limit, optional TP/SL. Needs confirm: true. | Trade |
close_position | Close part or all of a position in any market. Needs confirm: true. | Trade |
set_tpsl | Add take-profit / stop-loss legs to a position in any market. Set at once; runs on its own. | Trade |
cancel_order | Cancel a resting limit, stop or TP/SL leg. Happens at once. | Trade |
Bot quickstart (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#
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#
| Problem | Fix |
|---|---|
| The order came back "pending" | That is normal: orders are processed asynchronously. Poll GET /v1/orders/{orderId}. |
| A retry placed a second order | Send an Idempotency-Key header; the same key returns the first order instead. |
| Order rejected with a rule code | Read /v1/accounts/{id}/limits for the largest size that passes, and the rules book for the rule. |
| 401 after it worked before | The key expired or was revoked. Create a new one. |
| 403 account_not_allowed | The key is limited to another account. |
| Numbers are strings | Parse them as decimals; never use floats for money comparisons. |
| 429 rate_limited | Wait for the Retry-After seconds and slow your polling. |