{"openapi":"3.1.0","info":{"title":"MarginPad Free Crypto API","version":"2.9.1","description":"Free, keyless, CORS-enabled crypto market-data API. Live prices, OHLC candles, a scored futures screener, funding rates, open interest, long/short ratios, liquidations, an economic calendar, the Fear & Greed index, top coins, global market stats, DeFi TVL, trading calculators, and a free paper-trading REST API for testing bots. No API key. No sign-up. about 60 requests/minute per client. Every response uses the envelope { ok, data, error, ts }, except the four liquidation-collector passthroughs (feed, liquidations/live, liquidations/recent, clusters), which return the raw collector object and are marked as such.","contact":{"name":"MarginPad","url":"https://marginpad.io/free-crypto-api/"},"license":{"name":"Free for public use"}},"servers":[{"url":"https://marginpad.io","description":"Production"}],"externalDocs":{"description":"Full manual with curl / JS / Python examples","url":"https://marginpad.io/free-crypto-api/"},"tags":[{"name":"Market data","description":"Live prices, candles, symbols"},{"name":"Derivatives","description":"Funding, open interest, long/short, liquidations (measured from exchange public feeds and MarginPad's own nine-exchange liquidation collector)"},{"name":"Screener","description":"Technically scored USDT-perp screener"},{"name":"Macro","description":"Economic calendar, Fear & Greed, global stats, DeFi TVL"},{"name":"Calculators","description":"Liquidation price, position size, PnL, risk/reward, take-profit"},{"name":"Paper trading","description":"Free simulated trading REST API (test your bot with no real money). Auth via X-API-Key."},{"name":"Regional quotes","description":"Argentina (dólar cripto: USDT in pesos per exchange) and Brazil (Bitcoin and USDT in reais per exchange, ágio over the commercial dollar). Plain JSON, keyless."},{"name":"Meta","description":"Status & version"}],"paths":{"/api/v1/ping":{"get":{"tags":["Meta"],"summary":"API status & version","description":"Health check. Returns service name, version, rate limit, and the list of available endpoints. Use this to confirm the API is reachable.","responses":{"200":{"description":"ok"}}}},"/api/v1/price":{"get":{"tags":["Market data"],"summary":"Live price for one coin","description":"Current price for a single symbol, aggregated across Binance/Bybit/OKX/Gate. Use when a user asks \"what is the price of X\".","parameters":[{"name":"symbol","in":"query","required":true,"description":"Coin ticker, e.g. BTC, ETH, SOL (no USDT suffix needed).","schema":{"type":"string"},"example":"BTC"}],"responses":{"200":{"description":"ok"}}}},"/api/v1/prices":{"get":{"tags":["Market data"],"summary":"Live prices for major coins","description":"Batch snapshot of the top coins in one call (BTC, ETH, SOL, BNB, XRP, DOGE, ADA, AVAX).","responses":{"200":{"description":"ok"}}}},"/api/v1/klines":{"get":{"tags":["Market data"],"summary":"OHLC candles","description":"Historical candlesticks for a symbol. Use for charts, backtests, and indicator math.","parameters":[{"name":"symbol","in":"query","required":true,"description":"Coin ticker, e.g. BTC.","schema":{"type":"string"},"example":"BTC"},{"name":"interval","in":"query","required":false,"description":"Minutes per candle: 1, 5, 15, 60, 240, or 1440 (1d).","schema":{"type":"string"},"example":"60"}],"responses":{"200":{"description":"ok"}}}},"/api/v1/symbols":{"get":{"tags":["Market data"],"summary":"Tradable symbols","description":"List of ~500 liquid USDT-perpetual symbols by volume. Use to validate a ticker or populate a picker.","responses":{"200":{"description":"ok"}}}},"/api/v1/screener":{"get":{"tags":["Screener"],"summary":"Scored futures screener","description":"Top USDT-perps with a 0-100 technical score, verdict (bullish/bearish), RSI, MACD, trend, and an ATR-based trade setup (entry/SL/TP) when decisive. Use when a user asks \"what looks bullish/bearish right now\".","responses":{"200":{"description":"ok"}}}},"/api/v1/funding":{"get":{"tags":["Derivatives"],"summary":"Funding rates","description":"Perp funding rates across ~160 pairs, measured from the public endpoints of the exchanges. Positive = longs pay shorts.","responses":{"200":{"description":"ok"}}}},"/api/v1/open-interest":{"get":{"tags":["Derivatives"],"summary":"Open interest","description":"Open interest (USD) across ~160 pairs. Rising OI + rising price = new money entering.","responses":{"200":{"description":"ok"}}}},"/api/v1/long-short":{"get":{"tags":["Derivatives"],"summary":"Long/short ratio","description":"Aggregated long vs short account ratio for major coins. Crowd positioning.","responses":{"200":{"description":"ok"}}}},"/api/v1/liquidations":{"get":{"tags":["Derivatives"],"summary":"Liquidations","description":"Aggregated 24h liquidation totals per coin (longs vs shorts) across all exchanges.","responses":{"200":{"description":"ok"}}}},"/api/v1/venues":{"get":{"tags":["Derivatives"],"summary":"Liquidations by exchange","description":"24h liquidation total, market share and long/short split per venue (Binance, Bybit, OKX, Hyperliquid, Gate, HTX, dYdX, BitMEX, Bitfinex), measured from their public feeds by our own collector.","responses":{"200":{"description":"ok"}}}},"/api/v1/feed":{"get":{"tags":["Derivatives"],"summary":"Newest liquidation events","description":"The latest liquidation events across all tracked symbols: {events:[{ts, exchange, symbol, side, price, qty, notional}]}. Seconds behind the exchanges (3 s edge cache). Poll every 3-5 s. Passthrough from the liquidation collector: this route returns the raw object, NOT the { ok, data, ts } envelope.","responses":{"200":{"description":"Raw collector object (no envelope)"}}}},"/api/v1/liquidations/live":{"get":{"tags":["Derivatives"],"summary":"Recent liquidations for one symbol","description":"Raw recent liquidation events for one symbol; side is long_liquidated or short_liquidated, notional is USD. Passthrough from the liquidation collector: this route returns the raw object, NOT the { ok, data, ts } envelope.","parameters":[{"name":"symbol","in":"query","required":true,"description":"Coin ticker, e.g. BTC.","schema":{"type":"string"},"example":"BTC"},{"name":"limit","in":"query","required":false,"description":"Max events, up to 1000.","schema":{"type":"string"},"example":"400"}],"responses":{"200":{"description":"ok"}}}},"/api/v1/liquidations/recent":{"get":{"tags":["Derivatives"],"summary":"Liquidation histogram","description":"Time-bucketed long vs short liquidation dollars for one symbol - the source of the heatmap statistics. Passthrough from the liquidation collector: this route returns the raw object, NOT the { ok, data, ts } envelope.","parameters":[{"name":"symbol","in":"query","required":true,"description":"Coin ticker.","schema":{"type":"string"},"example":"BTC"},{"name":"minutes","in":"query","required":false,"description":"Window, up to 43200 (30 days).","schema":{"type":"string"},"example":"1440"}],"responses":{"200":{"description":"ok"}}}},"/api/v1/clusters":{"get":{"tags":["Derivatives"],"summary":"Liquidation clusters","description":"Modelled price levels where liquidation liquidity is estimated to sit right now: {clusters:[{price, side, est_notional}]}, with updatedAt as the measurement time. These are ESTIMATES from a model, not observed events. Passthrough from the liquidation collector: this route returns the raw object, NOT the { ok, data, ts } envelope.","parameters":[{"name":"symbol","in":"query","required":true,"description":"Coin ticker.","schema":{"type":"string"},"example":"BTC"}],"responses":{"200":{"description":"ok"}}}},"/api/v1/calendar":{"get":{"tags":["Macro"],"summary":"Crypto economic calendar","description":"FOMC, CPI, NFP, options expiry and crypto milestones with exact UTC timestamps. Omit params for the upcoming window; pass year for a full year incl. history.","parameters":[{"name":"year","in":"query","required":false,"description":"Full year 2023-2027 for the whole year incl. past events. Omit for the upcoming window.","schema":{"type":"string"},"example":"2026"}],"responses":{"200":{"description":"ok"}}}},"/api/v1/fear-greed":{"get":{"tags":["Macro"],"summary":"Fear & Greed index","description":"Current crypto Fear & Greed value (0-100) and classification.","responses":{"200":{"description":"ok"}}}},"/api/v1/coins":{"get":{"tags":["Macro"],"summary":"Top coins by market cap","description":"Top ~250 coins: price, market cap, 1h/24h/7d change, sparkline. Optional category filter.","parameters":[{"name":"cat","in":"query","required":false,"description":"CoinGecko category id, e.g. layer-1, decentralized-finance-defi, meme-token, artificial-intelligence.","schema":{"type":"string"},"example":"layer-1"}],"responses":{"200":{"description":"ok"}}}},"/api/v1/global":{"get":{"tags":["Macro"],"summary":"Global market stats","description":"Total market cap, 24h volume, BTC dominance.","responses":{"200":{"description":"ok"}}}},"/api/v1/trending":{"get":{"tags":["Macro"],"summary":"Trending coins","description":"Currently trending coins (CoinGecko search trending).","responses":{"200":{"description":"ok"}}}},"/api/v1/defi":{"get":{"tags":["Macro"],"summary":"DeFi TVL overview","description":"Total DeFi TVL, top chains, biggest protocols, largest stablecoins (DefiLlama-aggregated).","responses":{"200":{"description":"ok"}}}},"/api/latam/ar":{"get":{"tags":["Regional quotes"],"summary":"Dólar cripto (Argentina): USDT in pesos per exchange","description":"The peso price of USDT on every exchange operating in Argentina, fees included (totalAsk/totalBid), sorted by buy price; mid = median across venues quoting both sides; venues more than 20% off the median are dropped; bestBuy/bestSell; the reference dollars (oficial, blue, MEP, CCL, tarjeta) and the gap (\"brecha\") in percent; own hourly history. Plain JSON, not the envelope. 60 s cache; stale:true when the upstream (CriptoYa) is down and the last known quote is served. Human page: /dolar-cripto/.","responses":{"200":{"description":"{ ok, ts, stale, n, mid, bestBuy, bestSell, rows:[{id,name,ask,bid,spread}], dolar, brecha, hist }"}}}},"/api/latam/br":{"get":{"tags":["Regional quotes"],"summary":"Bitcoin hoje (Brazil): BTC and USDT in reais per exchange","description":"BTC/BRL and USDT/BRL on every exchange operating in Brazil, fees included, sorted by buy price; btcMid/usdtMid = medians; agio = ask ÷ (BTC/USD × dólar comercial) − 1 in percent per venue (dólar comercial from awesomeapi with Banco Central PTAX fallback; BTC/USD from MarginPad's own feed); own hourly history. Plain JSON, 60 s cache, stale:true on upstream failure. Human page: /bitcoin-hoje/.","responses":{"200":{"description":"{ ok, ts, stale, n, btcMid, usdtMid, btcUsd, usdbrl, fair, agioMid, bestBuy, bestSell, btc:[{id,name,ask,bid,spread,agio}], usdt:[…], hist }"}}}},"/api/v1/calc/liquidation":{"get":{"tags":["Calculators"],"summary":"Liquidation price","description":"Compute the liquidation price for a leveraged position.","parameters":[{"name":"entry","in":"query","required":true,"description":"Entry price.","schema":{"type":"string"},"example":"60000"},{"name":"leverage","in":"query","required":true,"description":"Leverage, e.g. 10.","schema":{"type":"string"},"example":"10"},{"name":"side","in":"query","required":false,"description":"long or short.","schema":{"type":"string"},"example":"long"},{"name":"mmr","in":"query","required":false,"description":"Maintenance margin rate in percent (default 0.5).","schema":{"type":"string"},"example":"0.5"}],"responses":{"200":{"description":"ok"}}}},"/api/v1/calc/position-size":{"get":{"tags":["Calculators"],"summary":"Position size","description":"Risk-based position size from account balance, risk %, entry and stop.","parameters":[{"name":"balance","in":"query","required":true,"description":"Account balance.","schema":{"type":"string"},"example":"10000"},{"name":"risk","in":"query","required":true,"description":"Risk percent of balance, e.g. 1.","schema":{"type":"string"},"example":"1"},{"name":"entry","in":"query","required":true,"description":"Entry price.","schema":{"type":"string"},"example":"60000"},{"name":"stop","in":"query","required":true,"description":"Stop-loss price.","schema":{"type":"string"},"example":"58000"},{"name":"leverage","in":"query","required":false,"description":"Optional leverage for margin required.","schema":{"type":"string"},"example":"10"}],"responses":{"200":{"description":"ok"}}}},"/api/v1/calc/pnl":{"get":{"tags":["Calculators"],"summary":"PnL / ROI","description":"Profit/loss and ROI for a position. Size is the position size in units of the asset, not in dollars.","parameters":[{"name":"entry","in":"query","required":true,"description":"Entry price.","schema":{"type":"string"},"example":"60000"},{"name":"exit","in":"query","required":true,"description":"Exit price.","schema":{"type":"string"},"example":"63000"},{"name":"size","in":"query","required":true,"description":"Position size, in units of the asset.","schema":{"type":"string"},"example":"0.5"},{"name":"leverage","in":"query","required":false,"description":"Leverage multiple.","schema":{"type":"string"},"example":"10"},{"name":"side","in":"query","required":false,"description":"long or short.","schema":{"type":"string"},"example":"long"}],"responses":{"200":{"description":"ok"}}}},"/api/v1/calc/risk-reward":{"get":{"tags":["Calculators"],"summary":"Risk / reward","description":"Risk-reward ratio from entry, stop and target. Entry and stop must differ.","parameters":[{"name":"entry","in":"query","required":true,"description":"Entry price.","schema":{"type":"string"},"example":"60000"},{"name":"stop","in":"query","required":true,"description":"Stop-loss price.","schema":{"type":"string"},"example":"58000"},{"name":"tp","in":"query","required":true,"description":"Take-profit price.","schema":{"type":"string"},"example":"65000"}],"responses":{"200":{"description":"ok"}}}},"/api/v1/calc/take-profit":{"get":{"tags":["Calculators"],"summary":"Take-profit price","description":"The price at which a position reaches a target return on equity.","parameters":[{"name":"entry","in":"query","required":true,"description":"Entry price, above zero.","schema":{"type":"string"},"example":"60000"},{"name":"roe","in":"query","required":true,"description":"Target return on equity, in percent.","schema":{"type":"string"},"example":"50"},{"name":"leverage","in":"query","required":false,"description":"Leverage multiple.","schema":{"type":"string"},"example":"10"},{"name":"side","in":"query","required":false,"description":"long or short.","schema":{"type":"string"},"example":"long"}],"responses":{"200":{"description":"ok"}}}},"/api/bot/v1/price":{"get":{"tags":["Paper trading"],"summary":"Paper price (keyless)","description":"Fill price used by the paper-trading engine.","parameters":[{"name":"symbol","in":"query","required":true,"description":"Coin ticker.","schema":{"type":"string"},"example":"BTC"}],"responses":{"200":{"description":"ok"}}}},"/api/bot/v1/time":{"get":{"tags":["Paper trading"],"summary":"Server time (keyless)","description":"Server clock. Pass client_ts to get drift_ms back - a bot bucketing candles against a drifting local clock builds bars nobody else sees.","parameters":[{"name":"client_ts","in":"query","required":false,"description":"Your unix ms, to measure drift.","schema":{"type":"string"},"example":"1787200000000"}],"responses":{"200":{"description":"ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerTime"}}}}}}},"/api/bot/v1/open":{"post":{"tags":["Paper trading"],"summary":"Open a paper position","description":"Open a simulated position at the live price. Auth: header X-API-Key (mint one at POST /api/bot/key while signed in). Send client_order_id so a network retry cannot open a second position.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenRequest"}}}},"responses":{"200":{"description":"ok","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"position":{"$ref":"#/components/schemas/Position"},"idempotent":{"type":"boolean","description":"true when this returned an existing position because client_order_id was reused."}}}}}},"400":{"description":"validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"too many open positions (Free 50 / API Pro 200 / Max 500 / Business 1000)"},"429":{"description":"rate limited - see X-RateLimit-Reset and Retry-After"}}}},"/api/bot/v1/close":{"post":{"tags":["Paper trading"],"summary":"Close a paper position","description":"Close a simulated position fully or partially. P&L settles net of the round-trip taker fee and accrued funding.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CloseRequest"}}}},"responses":{"200":{"description":"ok","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"closed":{"$ref":"#/components/schemas/Position"},"remaining":{"$ref":"#/components/schemas/Position"},"position":{"$ref":"#/components/schemas/Position"}}}}}},"400":{"description":"error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/bot/v1/sltp":{"post":{"tags":["Paper trading"],"summary":"Move stop-loss / take-profit","description":"Change the stop or target on an OPEN position without closing it. Both are side-checked against the entry price. Pass null to clear one.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SltpRequest"}}}},"responses":{"200":{"description":"ok"},"400":{"description":"error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/bot/v1/orders":{"get":{"tags":["Paper trading"],"summary":"List limit orders","description":"Resting limit orders plus the last 20 that filled, expired or were cancelled (a filled one carries the position_id it created).","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"ok"}}}},"/api/bot/v1/cancel_order":{"post":{"tags":["Paper trading"],"summary":"Cancel a limit order","description":"Cancel one resting order. Body: {\"order_id\":\"lo...\"}.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"ok"},"404":{"description":"no such order"},"409":{"description":"already filled, cancelled or expired"}}}},"/api/bot/v1/positions":{"get":{"tags":["Paper trading"],"summary":"List paper positions","description":"Your positions with live mark price and P&L net of fees. Supports If-None-Match (ETag over structural state, so a poll that changed nothing costs a 304) and ?since=<unix ms>.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"since","in":"query","required":false,"description":"Only positions opened or closed at/after this unix ms.","schema":{"type":"string"},"example":"1787200000000"}],"responses":{"200":{"description":"ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Positions"}}}},"304":{"description":"nothing changed since your ETag"}}}},"/api/bot/v1/trades":{"get":{"tags":["Paper trading"],"summary":"Closed-trade ledger","description":"Full closed-trade history with paging - /positions is capped at 100, this pages through the whole retention window. Follow next_before for the next page.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"1-500, default 100.","schema":{"type":"string"},"example":"100"},{"name":"before","in":"query","required":false,"description":"Cursor: unix ms from next_before.","schema":{"type":"string"},"example":"1787200000000"}],"responses":{"200":{"description":"ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Trades"}}}}}}},"/api/bot/v1/account":{"get":{"tags":["Paper trading"],"summary":"Paper account","description":"Open positions, margin in use, unrealized P&L, LIFETIME realized P&L, wins/losses, win rate, plus balance_usd, equity_usd, free_margin_usd and return_pct.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}}}}},"/api/bot/v1/close_all":{"post":{"tags":["Paper trading"],"summary":"Close every open paper position","description":"Closes all open bot positions at the live price. Fees and funding settle exactly as in /close.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"ok","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"closed":{"type":"integer"},"positions":{"type":"array","items":{"$ref":"#/components/schemas/Position"}}}}}}}}}},"/api/bot/v1/balance":{"get":{"tags":["Paper trading"],"summary":"Paper balance","description":"Starting balance, balance, equity, margin in use, free margin, unrealized P&L. The balance is a scorecard: margin_enforced is false, so opens are never rejected for lack of funds.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Balance"}}}}}}},"/api/bot/v1/markets":{"get":{"tags":["Paper trading"],"summary":"Tradable markets","description":"Every tradable symbol with asset_class, max_leverage and taker_fee_pct (per side, charged as a round trip at close). Call once at startup instead of discovering limits by trial and error.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"class","in":"query","required":false,"description":"Filter by asset class","schema":{"type":"string"},"example":"crypto"}],"responses":{"200":{"description":"ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Markets"}}}}}}},"/api/bot/v1/modify_order":{"post":{"tags":["Paper trading"],"summary":"Modify a resting order","description":"Change a resting limit or stop order in place: limit_price, sl, tp, margin_usd, leverage, trail_pct. The direction is re-derived from the market now and the candle watermark restarts, so a moved level never fills on a bar printed before the change.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifyOrderRequest"}}}},"responses":{"200":{"description":"ok"},"404":{"description":"no such order"},"409":{"description":"already filled, cancelled or expired"}}}},"/api/bot/v1/webhooks":{"get":{"tags":["Paper trading"],"summary":"List webhooks (Premium)","description":"Your registered webhooks with delivery counts, consecutive failures, the last error and whether each is active. Also lists the event names and the signature scheme.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhooks"}}}},"402":{"description":"Premium required"}}},"post":{"tags":["Paper trading"],"summary":"Add / delete / test a webhook (Premium)","description":"act:\"add\" {url, events?} registers an https URL (max 3 per account) and returns its secret once. act:\"delete\" {id}. act:\"test\" {id} delivers a ping right now and returns the HTTP status your server answered. Deliveries: POST JSON {event, ts, hook_id, data} with headers X-MP-Event, X-MP-Delivery, X-MP-Timestamp and X-MP-Signature = sha256=HMAC_SHA256(secret, raw body). Retried 5 times with backoff; paused after 25 consecutive failures.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookRequest"}}}},"responses":{"200":{"description":"ok"},"400":{"description":"bad_url / bad_event"},"402":{"description":"Premium required"},"409":{"description":"too_many_webhooks"}}}},"/api/bot/v1/usage":{"get":{"tags":["Paper trading"],"summary":"Your plan, limits and usage","description":"Everything this key is allowed to do, read back from the server so a bot never has to hardcode a limit: the plan name and when it ends (plan_until), requests per minute and how many are left this window, keys, open positions, books, resting orders, webhooks and AI reads, how many days of trade history this plan keeps (trade_history_days) and how far back the report may look (report_max_days), plus the catalogue of every plan and its price. If the account is inside a free month, free_month.days_left says so. Every keyed response also carries X-MP-Plan, and inside the last fourteen days X-MP-Plan-Expires and X-MP-Plan-Days-Left, so an unattended bot can warn its owner without calling this at all. Requires an API key.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"{ plan, plan_until, limits:{requests_per_minute, max_keys, max_open_positions, max_books, max_resting_orders, trade_history_days, report_max_days, websocket}, features, used, plans, free_month }"},"401":{"description":"missing_api_key / bad_api_key"}}}},"/api/bot/v1/realism":{"get":{"tags":["Paper trading"],"summary":"Fill realism (read)","description":"Two deliberate simplifications in the engine, made optional: a market order fills at the live price with no slippage, and maintenance margin is a flat 0.5%. Both are off by default. Returns your setting, the published maintenance-margin rate of every venue, the whole size-tier ladder and what each switch does. Requires a key.","responses":{"200":{"description":"{ realism:{slippage, margin_tiers, margin_venue}, defaults, effective, margin_venues, tiers, explain, applies_to }"}}},"post":{"tags":["Paper trading"],"summary":"Fill realism (set)","description":"Set the account default. Any field you omit keeps its current value. Applies to positions opened from now on - a position always keeps the maintenance margin it was filled with. A per-call override (slippage, margin_tiers, mmr_pct) is accepted on /v1/open.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"slippage":{"type":"boolean"},"margin_tiers":{"type":"boolean"},"margin_venue":{"type":"string","example":"binance"}}}}}},"responses":{"200":{"description":"{ ok, realism }"},"400":{"description":"unknown_margin_venue"}}}},"/api/bot/v1/fees":{"get":{"tags":["Paper trading"],"summary":"Fee schedules (venues) and your default","description":"The exchanges whose taker schedule your paper fills can be charged at - Bybit, Binance, OKX, Bitget, MEXC, Gate, KuCoin, Kraken, Hyperliquid - each with taker_pct, maker_pct, the referral discount a MarginPad sign-up gets there, the effective rate, its code and link; plus the MarginPad default rates and your current fee_venue. Both legs pay the venue TAKER rate less the discount (the engine fills at market). Crypto perps only; other asset classes keep the MarginPad rate.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"ok"}}},"post":{"tags":["Paper trading"],"summary":"Set your default fee venue","description":"Body {\"venue\":\"hyperliquid\"} makes every open from now on (site and API) pay that schedule unless a call names its own fee_venue; {\"venue\":null} or \"marginpad\" returns to the default rate. Open positions keep the rate they were filled with.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"venue":{"type":["string","null"],"example":"hyperliquid"}}}}}},"responses":{"200":{"description":"ok"},"400":{"description":"unknown_fee_venue"}}}},"/api/bot/v1/accounts":{"get":{"tags":["Paper trading"],"summary":"Books (sub-accounts) of this account","description":"Every book of the account behind the key with lifetime numbers and the keys bound to it. A book is a separate journal, balance, report and equity curve: mint a key with {\"act\":\"create\",\"name\":\"…\",\"book\":\"strat-a\"} on POST /api/bot/key (site session) and every call made with that key trades that book. Free: 1 book besides the main account; Premium: 5.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"ok"}}}},"/api/bot/v1/reset":{"post":{"tags":["Paper trading"],"summary":"Reset this book to $10,000","description":"Body {\"confirm\":true}. Closed trades are archived (never deleted), resting orders cancelled, the report / ledger / equity curve restart from the reset. Refused (409 open_positions_exist) while positions are open - close them first.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm":{"type":"boolean","example":true}},"required":["confirm"]}}}},"responses":{"200":{"description":"{ ok, reset_ts, archived_trades, cancelled_orders, starting_balance_usd }"},"400":{"description":"confirm_required"},"409":{"description":"open_positions_exist"}}}},"/api/bot/v1/equity":{"get":{"tags":["Paper trading"],"summary":"Equity curve","description":"starting_balance_usd + realized P&L per bucket from the ledger (fees and funding settled), the live unrealized point at the end, and max_drawdown_pct. Buckets before the first close carry the realized total up to that time.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"days","in":"query","required":false,"description":"1-90, default 30.","schema":{"type":"string"},"example":"30"},{"name":"step_min","in":"query","required":false,"description":"Bucket size in minutes, 5-1440 (default 60 up to 14 days, 240 beyond).","schema":{"type":"string"},"example":"60"}],"responses":{"200":{"description":"{ ok, points:[{t, realized_pnl_usd, equity_usd, closes}], now:{…}, max_drawdown_pct }"}}}},"/api/bot/v1/replay":{"get":{"tags":["Paper trading"],"summary":"Replay status, price and candles","description":"While a replay runs on this key’s book: cursor (market time), the price under it, progress, finished, and the candles up to the cursor. ?interval=1|5|15|60|240 (minutes), ?bars=1-500.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"interval","in":"query","required":false,"description":"Candle size in minutes (aggregated from 1m).","schema":{"type":"string"},"example":"5"},{"name":"bars","in":"query","required":false,"description":"How many candles up to the cursor.","schema":{"type":"string"},"example":"120"}],"responses":{"200":{"description":"{ running, symbol, day, speed, cursor_ts, cursor_iso, progress_pct, price, finished, bars:[{time,open,high,low,close}] }"}}},"post":{"tags":["Paper trading"],"summary":"Start or stop a replay of a past day","description":"Start: {symbol, day:\"YYYY-MM-DD\" (a complete past UTC day), speed (1-600 market seconds per real second, default 60)}. From then on the key’s trading calls act on a separate replay journal priced from MarginPad’s own 1-minute candles; stops, targets and liquidations are checked on every candle between two calls. Stop: {act:\"stop\"} closes everything at the cursor, returns the summary and empties the replay journal. One replay per key at a time; crypto only; limit and stop entries are not available in replay.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"symbol":{"type":"string","example":"BTC"},"day":{"type":"string","example":"2026-09-11"},"speed":{"type":"number","example":60},"act":{"type":"string","enum":["start","stop"]}}}}}},"responses":{"200":{"description":"start: { ok, replay:{id, symbol, day, speed, start_ts, end_ts, candles, first_price} } · stop: { ok, replay:{closes, wins, losses, win_rate_pct, pnl_usd, return_pct, liquidations, trades} }"},"400":{"description":"day_invalid / day_not_finished / speed_invalid / replay_crypto_only"},"404":{"description":"no_data / no_replay"},"409":{"description":"replay_running"}}}},"/api/arena":{"get":{"tags":["Paper trading"],"summary":"Bot arena (public)","description":"The current 14-day season board of bot-opened paper trades: every account or book with at least 5 closes, ranked by realized P&L. win_rate_pct counts CLOSED trades only - read it beside open_positions and open_unrealized_usd, because a bot that closes its winners and holds its losers reads 100% and is not winning; pnl_incl_open_usd is the whole book. realism.label says what the fills ran with (off = the engine defaults, no slippage and a flat 0.5% maintenance margin). No key, 60 s cache. Human page: /arena/.","responses":{"200":{"description":"{ ok, season, min_closes, note, rows:[{rank, who, account, closes, wins, win_rate_pct, pnl_usd, return_pct, avg_roe_pct, liquidations, open_positions, open_margin_usd, open_unrealized_usd, pnl_incl_open_usd, realism:{slippage_closes, tiered_closes, label}}] }"}}}},"/api/bot/v1/report":{"get":{"tags":["Paper trading"],"summary":"Trading report","description":"The 30-day trading report for the account behind the key, measured from its own closed trades. Totals and the skill score on every plan; breakdowns by coin, leverage band, side, hour and day plus written findings on Premium (locked[] names what is withheld). Every finding carries the n it rests on.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"days","in":"query","required":false,"description":"1-30, default 30.","schema":{"type":"string"},"example":"30"}],"responses":{"200":{"description":"ok"}}}},"/api/bot/v1/ai":{"post":{"tags":["Paper trading"],"summary":"AI market read (Premium)","description":"The chart panel’s AI read, from the API: {symbol, interval (minutes: 1,5,15,60,240,1440), question?, lang?}. Same model, prompt and 50-a-day quota as Ask-AI on the site. Returns the answer, a parsed plan when the model gives one, and the brief it reasoned over. Educational, not financial advice.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"symbol":{"type":"string","example":"BTC"},"interval":{"type":"string","example":"60"},"question":{"type":"string","maxLength":280},"lang":{"type":"string","example":"en"}},"required":["symbol"]}}}},"responses":{"200":{"description":"ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiRead"}}}},"402":{"description":"Premium required"},"429":{"description":"daily AI quota used"}}}},"/api/whsink/{token}":{"post":{"tags":["Paper trading"],"summary":"Webhook test sink (write)","description":"POST anything here and read it back with GET - the last 20 bodies for 15 minutes. Register https://marginpad.io/api/whsink/<token> as a webhook to see exactly what a delivery looks like before pointing it at your own server. No auth: the token is the secret (12-48 letters, digits, - or _).","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"ok"}}},"get":{"tags":["Paper trading"],"summary":"Webhook test sink (read)","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"ok"}}}},"/api/bot/v2/{endpoint}":{"get":{"tags":["Paper trading"],"summary":"Same API, standard envelope","description":"Every /api/bot/v1/* path has a /v2 twin: identical parameters and identical data, wrapped as {ok:true,data,ts} or {ok:false,error:{code,message},ts}. v1 response bodies are frozen and will not change; new work happens on v2. Swap v1 for v2 in the URL. There is also a WebSocket that OpenAPI cannot describe: wss://marginpad.io/api/bot/v2/stream?api_key=... pushes position opened/updated/closed events and mark prices, which replaces polling /positions entirely.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"endpoint","in":"path","required":true,"description":"account | balance | positions | trades | markets | open | close | close_all | sltp | price | klines | time","schema":{"type":"string"},"example":"account"}],"responses":{"200":{"description":"ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Required for paper-trading endpoints; OPTIONAL on /api/v1/* data endpoints, where sending it moves the call from the 60/minute per-IP limit to the key’s own budget (120/minute on Free, 600 on API Pro, 2000 on Max, 5000 on Business). Mint a key at POST /api/bot/key while signed in, or on https://marginpad.io/trading-api/."}},"schemas":{"Envelope":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{},"error":{"$ref":"#/components/schemas/ApiError"},"ts":{"type":"integer","description":"Server unix ms"}},"required":["ok","ts"]},"ApiError":{"type":"object","description":"code is a stable identifier you can branch on; message is prose and may be reworded.","properties":{"code":{"type":"string","example":"unknown_symbol"},"message":{"type":"string"},"symbol":{"type":"string"},"live":{"type":"number","description":"On sl_wrong_side / tp_wrong_side: the live price, so a caller can correct and retry."},"limit":{},"max":{"type":"integer"}},"required":["code","message"]},"Position":{"type":"object","properties":{"id":{"type":"string","description":"Pass to /close and /sltp."},"symbol":{"type":"string"},"side":{"type":"string","enum":["long","short"]},"entry_price":{"type":"number"},"margin_usd":{"type":"number"},"leverage":{"type":"number"},"qty":{"type":"number"},"liq_price":{"type":"number"},"sl":{"type":["number","null"]},"tp":{"type":["number","null"]},"status":{"type":"string","enum":["open","closed","liquidated"]},"opened_ts":{"type":"integer"},"source":{"type":"string","enum":["bot","app"]},"mark_price":{"type":"number","description":"Open positions only."},"unrealized_pnl_usd":{"type":"number","description":"Open positions only. NET of the round-trip fee and accrued funding - what the position actually settles at, not a gross figure."},"fees_usd":{"type":"number","description":"Round-trip taker fee already subtracted from unrealized_pnl_usd."},"funding_usd":{"type":"number","description":"Funding accrued so far, already subtracted."},"exit_price":{"type":["number","null"],"description":"Closed positions only."},"pnl_usd":{"type":["number","null"],"description":"Closed positions only. Net of fees and funding, floored at -margin_usd."},"closed_ts":{"type":["integer","null"]},"partial_pct":{"type":"integer","description":"Present when this row is a partial close."}},"required":["id","symbol","side","entry_price","margin_usd","leverage","qty","status"]},"Positions":{"type":"object","properties":{"positions":{"type":"array","items":{"$ref":"#/components/schemas/Position"}}},"required":["positions"]},"Account":{"type":"object","properties":{"open_positions":{"type":"integer"},"margin_in_use_usd":{"type":"number"},"unrealized_pnl_usd":{"type":"number"},"realized_pnl_usd":{"type":"number","description":"LIFETIME, not the last 100 trades."},"closed_trades":{"type":"integer"},"wins":{"type":"integer"},"losses":{"type":"integer"},"win_rate_pct":{"type":["number","null"]},"starting_balance_usd":{"type":"number","example":10000},"balance_usd":{"type":"number"},"equity_usd":{"type":"number"},"free_margin_usd":{"type":"number"},"return_pct":{"type":"number"},"best_trade_usd":{"type":["number","null"]},"margin_enforced":{"type":"boolean","description":"Always false: the balance is a scorecard, opens are never rejected for lack of funds."}}},"Balance":{"type":"object","properties":{"starting_balance_usd":{"type":"number"},"balance_usd":{"type":"number"},"equity_usd":{"type":"number"},"margin_in_use_usd":{"type":"number"},"free_margin_usd":{"type":"number"},"unrealized_pnl_usd":{"type":"number"},"margin_enforced":{"type":"boolean"}}},"Market":{"type":"object","properties":{"symbol":{"type":"string"},"asset_class":{"type":"string","enum":["crypto","stock","forex","metal","index"]},"max_leverage":{"type":"number"},"taker_fee_pct":{"type":"number","description":"Per side. Charged on notional, per side. position.margin is what you committed; position.feeOpen reports the entry leg for the cost breakdown only. BOTH legs settle in realized pnl at close; unrealized_pnl_usd excludes fees."}}},"Markets":{"type":"object","properties":{"markets":{"type":"array","items":{"$ref":"#/components/schemas/Market"}},"count":{"type":"integer"},"note":{"type":"string"}}},"Trade":{"type":"object","properties":{"id":{"type":["string","null"]},"closed_ts":{"type":"integer"},"symbol":{"type":"string"},"side":{"type":"string","enum":["long","short"]},"leverage":{"type":"number"},"margin_usd":{"type":"number"},"pnl_usd":{"type":["number","null"]},"roe_pct":{"type":["number","null"]},"liquidated":{"type":"boolean"},"via":{"type":["string","null"],"description":"Which path executed the close: bot, site, sweep, cron, sltp."}}},"Trades":{"type":"object","properties":{"trades":{"type":"array","items":{"$ref":"#/components/schemas/Trade"}},"count":{"type":"integer"},"next_before":{"type":["integer","null"],"description":"Cursor for the next page; null when there are no more."},"retention_days":{"type":"integer","example":30}}},"OpenRequest":{"type":"object","properties":{"fee_venue":{"type":["string","null"],"description":"Charge this open at a real venue’s taker schedule less our referral discount (GET /v1/fees). Omit for your account default; null or \"marginpad\" for the default rate."},"symbol":{"type":"string","example":"BTC"},"side":{"type":"string","enum":["long","short"]},"margin_usd":{"type":"number","minimum":1,"maximum":100000},"leverage":{"type":"number","minimum":1},"type":{"type":"string","enum":["market","limit"],"default":"market","description":"market fills now at the live price; limit rests until the market reaches limit_price and fills AT that price."},"limit_price":{"type":"number","description":"Required for type:\"limit\". The level may sit on EITHER side of the market: below it the order behaves as a classic limit, above it as a breakout entry. Either way it waits until the market reaches the level and fills AT the level."},"sl":{"type":["number","null"]},"tp":{"type":["number","null"]},"client_order_id":{"type":"string","maxLength":64,"description":"Idempotency key. Retrying with the same value returns the position the first call created (idempotent: true) instead of opening a second one. Strongly recommended."}},"required":["symbol","side","margin_usd","leverage"]},"CloseRequest":{"type":"object","properties":{"id":{"type":"string"},"pct":{"type":"number","minimum":1,"maximum":100,"description":"Percent to close. Omit for the whole position."},"symbol":{"type":"string","description":"The position symbol, copied from /positions. Optional but strongly recommended: it lets the server price exactly one feed and skip a lookup round trip, which is worth several hundred milliseconds from Asia. A wrong value costs nothing - the server falls back automatically."}},"required":["id"]},"SltpRequest":{"type":"object","properties":{"id":{"type":"string"},"sl":{"type":["number","null"],"description":"null clears the stop."},"tp":{"type":["number","null"]},"trail_pct":{"type":["number","null"],"description":"Trailing stop distance in percent (0.05-50), ratcheted server-side from the best price seen. null switches it off."}},"required":["id"]},"ModifyOrderRequest":{"type":"object","properties":{"order_id":{"type":"string"},"limit_price":{"type":"number"},"sl":{"type":["number","null"]},"tp":{"type":["number","null"]},"margin_usd":{"type":"number"},"leverage":{"type":"number"},"trail_pct":{"type":["number","null"]}},"required":["order_id"]},"WebhookRequest":{"type":"object","properties":{"act":{"type":"string","enum":["add","delete","test"]},"url":{"type":"string","description":"add: https URL on a public host"},"events":{"type":"array","items":{"type":"string","enum":["position.opened","position.updated","position.closed","position.liquidated","order.filled","order.expired","order.cancelled"]},"description":"add: subset to receive; omit for all"},"id":{"type":"string","description":"delete / test: the webhook id"}},"required":["act"]},"Webhook":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"secret":{"type":"string","description":"HMAC key for X-MP-Signature"},"events":{"type":"array","items":{"type":"string"}},"created":{"type":"integer"},"last_delivery_ts":{"type":["integer","null"]},"deliveries":{"type":"integer"},"consecutive_failures":{"type":"integer"},"active":{"type":"boolean"},"last_error":{"type":["string","null"]}}},"Webhooks":{"type":"object","properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}},"pending_deliveries":{"type":"integer"},"max":{"type":"integer"},"events":{"type":"array","items":{"type":"string"}},"signature":{"type":"string"}}},"WebhookDelivery":{"type":"object","description":"The body we POST to your URL.","properties":{"event":{"type":"string","example":"position.closed"},"ts":{"type":"integer"},"hook_id":{"type":"string"},"data":{"description":"A Position (position.*) or an order (order.*, with the Position it created on order.filled)."}}},"AiRead":{"type":"object","properties":{"symbol":{"type":"string"},"interval":{"type":"integer"},"answer":{"type":"string"},"plan":{"type":["object","null"],"description":"bias / reason / entry / stop / targets / levels when the model saw a setup"},"brief":{"type":"object"},"used":{"type":"integer"},"limit":{"type":"integer"}}},"ServerTime":{"type":"object","properties":{"server_time_ms":{"type":"integer"},"server_time_iso":{"type":"string"},"client_time_ms":{"type":"integer"},"drift_ms":{"type":"integer","description":"client_ts minus server time, when you pass ?client_ts="}}}}}}