{"openapi":"3.1.0","info":{"title":"OptionProfit — Embedded Options Intelligence API","version":"1.0.0","description":"Feed-agnostic options analytics for brokers and developers: payoff, the Greeks, probability of profit, decision metrics (expected value, CVaR, Kelly, probability of touch), a strategy recommender, Monte-Carlo, backtesting, margin/roll analysis and multi-leg order mapping. You pass your own market data; no dependency on any third-party feed. Not investment advice — an analysis layer you control.\n\n## Authentication\nThere is no login/secret exchange and no OAuth token flow — a single **API key IS your credential**. Send it either as the `X-API-Key` header **or** as `Authorization: Bearer <key>`.\n\n**Getting a key:** try free with the public demo key `op_demo_public_key` (capped daily); buy a self-serve key with prepaid credits from €20 at https://options-strategies.com/v1/pricing (PayPal, no subscription — the key is issued the moment payment completes); or request an unmetered partner key for a broker integration via partnerships@options-strategies.com. Keys are 144-bit random tokens (`op_live_…`); keep them secret and send over HTTPS only. Check remaining credits at `GET /v1/balance`.\n\n## Pricing\nBilling is **per leg: €0.01 per option/stock leg** analysed (1 credit = 1 leg = €0.01). A 1-leg long call costs €0.01; a 4-leg iron condor €0.04. Prepaid from a €20 buy-in (2,000 legs). Cost breakdown per endpoint: `analyze`, `greeks`, `simulate`, `scenario`, `probability`, `analytics`, `margin`, `order-ticket`, `build` bill the request's leg count; `roll` bills the closing + opening legs together; `batch` bills the TOTAL legs across every position in the call; `price`, `iv`, `chain-highlights`, `volume-profile`, `iv-rank` bill 1; `recommend` bills the total legs across the strategies it returns; `backtest` bills 4 (compute-heavy). `GET /v1/strategies` and `GET /v1/balance` are free. The `X-Units-Charged` and `X-Credits-Remaining` response headers report the charge.\n\n## Rate limits\n**120 requests/minute per API key** (a sliding window). Exceeding it returns `429` with an `Error` body; back off and retry. The public demo key additionally has a daily request cap (also `429`). Need a higher limit? Ask for a partner key (unmetered). High-volume refreshers should prefer `POST /v1/batch` — one call, up to 500 positions — over many single calls.\n\n## Errors\nEvery non-2xx response uses the `Error` schema: `{ ok:false, error:\"<stable_code>\", message:\"<human text>\" }`. The `error` code is stable and safe to switch on; the `message` is for humans and may change. Common codes: `invalid_api_key` (401), `insufficient_credits` (402), `legs_and_underlying_required` / `chain_required` / `unknown_strategyId` (400), `demo_daily_cap` (429).\n\n## Modelling multi-expiration & skew\nA `Leg` carries an optional per-leg `iv` (model a volatility **skew** by giving each strike its own IV) and per-leg `tExp` (years to that leg's own expiry — model **calendars and diagonals**). Omit them and the leg inherits the position-level IV and horizon. The engine supports both today; supplying them makes analyze/greeks/simulate/analytics accurate for those structures.","contact":{"name":"OptionProfit (Desego BV)","email":"partnerships@options-strategies.com","url":"https://options-strategies.com/brokers/integration"}},"externalDocs":{"description":"Interactive reference, pricing + live sandbox","url":"https://options-strategies.com/v1/docs"},"servers":[{"url":"https://options-strategies.com/v1"}],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"tags":[{"name":"Position analysis","description":"Analyse a multi-leg position you already have."},{"name":"Risk & analytics","description":"Decision metrics (EV, CVaR, Kelly, prob-of-touch), margin estimate and roll analysis."},{"name":"Batch","description":"Analyse many positions in one call — the volume path for refreshing a whole book."},{"name":"Strategies","description":"The strategy catalog, building a named strategy, and ranking."},{"name":"Pricing & IV","description":"Black-Scholes pricing primitives and implied-volatility tools."},{"name":"Market data","description":"Derived stats from a chain you supply (highlights, volume, IV rank)."},{"name":"Execution","description":"Map a strategy to a broker-neutral order ticket."},{"name":"Account","description":"Credit balance (auth required; free)."}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Your API key in the X-API-Key header. Get one at /v1/pricing (from €20, prepaid) or use the demo key op_demo_public_key."},"BearerAuth":{"type":"http","scheme":"bearer","description":"The same key passed as Authorization: Bearer <key>."}},"schemas":{"OptionQuote":{"type":"object","required":["strike"],"description":"A single option contract from your own chain.","properties":{"strike":{"type":"number"},"bid":{"type":"number"},"ask":{"type":"number"},"last":{"type":"number"},"iv":{"type":"number","description":"Implied volatility as a decimal (0.30 = 30%)."},"openInterest":{"type":"integer"},"volume":{"type":"integer"},"expiration":{"type":"string","format":"date","description":"ISO expiry (YYYY-MM-DD); enables multi-expiration chains."}}},"Leg":{"type":"object","required":["kind","side"],"properties":{"kind":{"type":"string","enum":["call","put","stock"]},"side":{"type":"string","enum":["long","short"]},"strike":{"type":"number","description":"Required for call/put; omit for a stock leg."},"premium":{"type":"number","description":"Per-share price paid (long) or received (short) — the mark."},"qty":{"type":"integer","default":1},"mult":{"type":"integer","default":100,"description":"Contract multiplier (shares per contract)."},"iv":{"type":"number","description":"Per-leg implied volatility (decimal). Give each strike its own IV to model vertical skew; defaults to the position IV."},"tExp":{"type":"number","description":"Years to THIS leg's own expiry. Set it per leg to model calendars/diagonals; defaults to the position horizon."}}},"Chain":{"type":"object","required":["underlying"],"properties":{"underlying":{"type":"number"},"days":{"type":"integer","description":"Days to expiry for the front chain."},"calls":{"type":"array","items":{"$ref":"#/components/schemas/OptionQuote"}},"puts":{"type":"array","items":{"$ref":"#/components/schemas/OptionQuote"}}}},"Greeks":{"type":"object","properties":{"delta":{"type":"number"},"gamma":{"type":"number"},"theta":{"type":"number"},"vega":{"type":"number"},"rho":{"type":"number"}}},"Analytics":{"type":"object","description":"Decision metrics derived from the Monte-Carlo distribution.","properties":{"expectedValue":{"type":"number","description":"Mean P/L across simulated paths."},"returnOnRisk":{"type":"number","description":"Expected value ÷ capital at risk."},"rewardRisk":{"type":"number","description":"Max profit ÷ max loss."},"expectedShortfall":{"type":"number","description":"CVaR — the mean P/L of the worst 5% of outcomes."},"p50":{"type":"number","description":"Median (50th-percentile) P/L."},"kelly":{"type":"number","description":"Kelly-criterion position fraction."},"probOfTouch":{"type":"array","description":"Probability the underlying touches each breakeven before expiry.","items":{"type":"object","properties":{"level":{"type":"number"},"prob":{"type":"number"}}}}}},"Analysis":{"type":"object","description":"Full payoff/Greeks/probability analysis of a position.","properties":{"legs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}},"underlying":{"type":"number"},"days":{"type":"integer"},"iv":{"type":"number"},"breakevens":{"type":"array","items":{"type":"number"}},"maxProfit":{"type":"number","nullable":true,"description":"null when unbounded."},"maxLoss":{"type":"number","nullable":true,"description":"null when unbounded (naked short)."},"netDebit":{"type":"number","description":">0 = net debit paid; <0 = net credit received."},"pop":{"type":"number","description":"Probability of profit (0–1)."},"greeks":{"$ref":"#/components/schemas/Greeks"},"expectedMove":{"type":"number","description":"One-sigma expected move to expiry."},"multiExpiration":{"type":"boolean"},"curve":{"type":"array","description":"Expiry payoff curve, [{ price, pnl }].","items":{"type":"object"}},"todayCurve":{"type":"array","description":"Mark-to-model payoff today (T+0).","items":{"type":"object"}}}},"Simulation":{"type":"object","properties":{"winRate":{"type":"number"},"mean":{"type":"number"},"median":{"type":"number"},"percentiles":{"type":"object","description":"P/L at p5/p25/p50/p75/p95."},"histogram":{"type":"array","items":{"type":"object"}},"analytics":{"$ref":"#/components/schemas/Analytics"}}},"GreeksProfiles":{"type":"object","properties":{"net":{"$ref":"#/components/schemas/Greeks"},"vsPrice":{"type":"array","description":"Net Greeks across a range of underlying prices.","items":{"type":"object"}},"vsTime":{"type":"array","nullable":true,"description":"Net Greeks across days-to-expiry (null for ≤1 day).","items":{"type":"object"}}}},"Backtest":{"type":"object","properties":{"stats":{"type":"object","properties":{"n":{"type":"integer"},"winRate":{"type":"number"},"avgReturnOnRisk":{"type":"number"},"totalPnl":{"type":"number"},"best":{"type":"number"},"worst":{"type":"number"}}},"equity":{"type":"array","description":"Equity curve, [{ date, equity }].","items":{"type":"object"}}}},"PriceGreeks":{"type":"object","properties":{"price":{"type":"number"},"greeks":{"$ref":"#/components/schemas/Greeks"}}},"OrderTicket":{"type":"object","description":"Broker-neutral multi-leg order ticket.","properties":{"symbol":{"type":"string"},"strategyId":{"type":"string"},"quantity":{"type":"integer"},"orderType":{"type":"string","description":"e.g. limit / market."},"netPrice":{"type":"number"},"priceEffect":{"type":"string","enum":["debit","credit"]},"optionLegs":{"type":"array","items":{"type":"object"}},"stockLegs":{"type":"array","items":{"type":"object"}}}},"Margin":{"type":"object","description":"Indicative buying-power requirement — your broker computes the definitive figure.","properties":{"definedRisk":{"type":"boolean","description":"true → the requirement equals the capital at risk (max loss)."},"marginEstimate":{"type":"number"},"currency":{"type":"string"},"basis":{"type":"string","description":"How the estimate was derived."}}},"Roll":{"type":"object","properties":{"rollNet":{"type":"number","description":">0 = extra debit to roll; <0 = net credit received."},"currentValue":{"type":"number","description":"Net value of the current legs at supplied marks."},"newDebit":{"type":"number","description":"Net debit of the new legs at supplied marks."},"newPosition":{"$ref":"#/components/schemas/Analysis"}}},"Balance":{"type":"object","properties":{"ok":{"type":"boolean"},"tier":{"type":"string","enum":["demo","paid","partner"]},"credits":{"type":"integer","nullable":true,"description":"Remaining credits (paid tier); null otherwise."}}},"StrategyInfo":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"category":{"type":"string"},"direction":{"type":"string"},"multiExp":{"type":"boolean"}}},"Envelope":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"apiVersion":{"type":"string"},"disclaimer":{"type":"string"},"data":{"type":"object"}}},"Error":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Stable, machine-readable error code — safe to switch on."},"message":{"type":"string","description":"Human-readable explanation (may change; do not parse)."}}}}},"paths":{"/strategies":{"get":{"tags":["Strategies"],"summary":"List the built-in strategy catalog.","description":"Every built-in strategy id + name/category/direction. Free. Use an id with /build, /backtest or /order-ticket.","responses":{"200":{"description":"Strategy catalog","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"strategies":{"type":"array","items":{"$ref":"#/components/schemas/StrategyInfo"}}}}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/balance":{"get":{"tags":["Account"],"summary":"Remaining credits for your key.","description":"Reports your tier and, for paid keys, the remaining credit balance (1 credit = 1 leg = €0.01). Free. Not enveloped — returns the Balance object directly.","responses":{"200":{"description":"Balance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Balance"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/analyze":{"post":{"tags":["Position analysis"],"summary":"Analyse a multi-leg position.","description":"Payoff curve (expiry + today), breakevens, max profit/loss, net debit/credit, net Greeks and probability of profit. Bills 1 credit per leg.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["legs","underlying"],"properties":{"legs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}},"underlying":{"type":"number"},"days":{"type":"integer"},"iv":{"type":"number"},"chain":{"$ref":"#/components/schemas/Chain"}}},"example":{"legs":[{"kind":"call","side":"long","strike":100,"premium":3.2,"qty":1},{"kind":"call","side":"short","strike":110,"premium":1.1,"qty":1}],"underlying":100,"days":30,"iv":0.3}}}},"responses":{"200":{"description":"Full position analysis","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Analysis"}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/greeks":{"post":{"tags":["Position analysis"],"summary":"Net Greeks + profiles.","description":"Net delta/gamma/theta/vega/rho plus Greek-vs-price and Greek-vs-time (days-to-expiry) curves. Bills per leg.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["legs","underlying"],"properties":{"legs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}},"underlying":{"type":"number"},"days":{"type":"integer"},"iv":{"type":"number"}}},"example":{"legs":[{"kind":"call","side":"long","strike":100,"premium":3.2,"qty":1},{"kind":"call","side":"short","strike":110,"premium":1.1,"qty":1}],"underlying":100,"days":30,"iv":0.3}}}},"responses":{"200":{"description":"Greeks + profiles","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GreeksProfiles"}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/simulate":{"post":{"tags":["Position analysis"],"summary":"Monte-Carlo P/L distribution.","description":"Thousands of GBM price paths → win rate, percentiles, a P/L histogram and the full decision-metric block (EV, CVaR, Kelly, prob-of-touch). Bills per leg.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["legs","underlying"],"properties":{"legs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}},"underlying":{"type":"number"},"days":{"type":"integer"},"iv":{"type":"number"},"trials":{"type":"integer","description":"1000–50000 (default engine value)."}}},"example":{"legs":[{"kind":"call","side":"long","strike":100,"premium":3.2,"qty":1},{"kind":"call","side":"short","strike":110,"premium":1.1,"qty":1}],"underlying":100,"days":30,"iv":0.3,"trials":20000}}}},"responses":{"200":{"description":"Distribution + analytics","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Simulation"}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/analytics":{"post":{"tags":["Risk & analytics"],"summary":"Decision metrics (EV, CVaR, Kelly, prob-of-touch).","description":"The trade-decision block on its own: expected value, return-on-risk, reward:risk, expected shortfall (CVaR), median P/L, Kelly fraction and probability-of-touch per breakeven — from a Monte-Carlo run. Bills per leg.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["legs","underlying"],"properties":{"legs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}},"underlying":{"type":"number"},"days":{"type":"integer"},"iv":{"type":"number"},"trials":{"type":"integer"}}},"example":{"legs":[{"kind":"call","side":"long","strike":100,"premium":3.2,"qty":1},{"kind":"call","side":"short","strike":110,"premium":1.1,"qty":1}],"underlying":100,"days":30,"iv":0.3,"trials":20000}}}},"responses":{"200":{"description":"Decision metrics","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"winRate":{"type":"number"},"analytics":{"$ref":"#/components/schemas/Analytics"}}}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/scenario":{"post":{"tags":["Position analysis"],"summary":"Price × IV stress grid.","description":"A grid of P/L across underlying-price and IV-shock scenarios. Bills per leg.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["legs","underlying"],"properties":{"legs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}},"underlying":{"type":"number"},"days":{"type":"integer"},"iv":{"type":"number"},"r":{"type":"number"}}},"example":{"legs":[{"kind":"call","side":"long","strike":100,"premium":3.2,"qty":1},{"kind":"call","side":"short","strike":110,"premium":1.1,"qty":1}],"underlying":100,"days":30,"iv":0.3}}}},"responses":{"200":{"description":"Stress grid","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"type":"object","description":"Grid of P/L across price × IV shocks."}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/probability":{"post":{"tags":["Position analysis"],"summary":"Probability of profit.","description":"Lognormal probability the position finishes profitable. Bills per leg.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["legs","underlying"],"properties":{"legs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}},"underlying":{"type":"number"},"days":{"type":"integer"},"iv":{"type":"number"}}},"example":{"legs":[{"kind":"call","side":"long","strike":100,"premium":3.2,"qty":1},{"kind":"call","side":"short","strike":110,"premium":1.1,"qty":1}],"underlying":100,"days":30,"iv":0.3}}}},"responses":{"200":{"description":"POP","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"probabilityOfProfit":{"type":"number"}}}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/margin":{"post":{"tags":["Risk & analytics"],"summary":"Margin / buying-power estimate.","description":"Indicative buying-power requirement for a multi-leg position: defined-risk → capital at risk; naked shorts → a Reg-T-style estimate. Your broker computes the definitive figure. Bills per leg.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["legs","underlying"],"properties":{"legs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}},"underlying":{"type":"number"},"days":{"type":"integer"},"iv":{"type":"number"}}},"example":{"legs":[{"kind":"call","side":"long","strike":100,"premium":3.2,"qty":1},{"kind":"call","side":"short","strike":110,"premium":1.1,"qty":1}],"underlying":100,"days":30,"iv":0.3}}}},"responses":{"200":{"description":"Margin estimate","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Margin"}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/roll":{"post":{"tags":["Risk & analytics"],"summary":"Roll analysis (cost to move a position).","description":"The daily options-seller question: what does it cost to roll from the current legs to a new set? Net debit/credit at supplied marks plus a full analysis of the new position. Bills the closing + opening legs.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["currentLegs","newLegs","underlying"],"properties":{"currentLegs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}},"newLegs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}},"underlying":{"type":"number"},"days":{"type":"integer"},"iv":{"type":"number"}}},"example":{"currentLegs":[{"kind":"call","side":"long","strike":100,"premium":3.2,"qty":1},{"kind":"call","side":"short","strike":110,"premium":1.1,"qty":1}],"newLegs":[{"kind":"call","side":"long","strike":100,"premium":4.1},{"kind":"call","side":"short","strike":112,"premium":1.4}],"underlying":103,"days":60,"iv":0.32}}}},"responses":{"200":{"description":"Roll cost + new-position analysis","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Roll"}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/batch":{"post":{"tags":["Batch"],"summary":"Analyse many positions in one call.","description":"Pass up to 500 positions; get an aligned array of analyses back. One round-trip to refresh a whole book. Bills the TOTAL legs across every position. Per-position failures come back as { ok:false, error } without failing the call.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["positions"],"properties":{"positions":{"type":"array","maxItems":500,"items":{"type":"object","required":["legs","underlying"],"properties":{"legs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}},"underlying":{"type":"number"},"days":{"type":"integer"},"iv":{"type":"number"}}}}}},"example":{"positions":[{"legs":[{"kind":"call","side":"long","strike":100,"premium":3.2,"qty":1},{"kind":"call","side":"short","strike":110,"premium":1.1,"qty":1}],"underlying":100,"days":30,"iv":0.3},{"legs":[{"kind":"put","side":"short","strike":95,"premium":1.8}],"underlying":100,"days":21,"iv":0.28}]}}}},"responses":{"200":{"description":"Array of analyses","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"count":{"type":"integer"},"results":{"type":"array","items":{"allOf":[{"type":"object","properties":{"ok":{"type":"boolean"},"error":{"type":"string"}}},{"$ref":"#/components/schemas/Analysis"}]}}}}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/build":{"post":{"tags":["Strategies"],"summary":"Build a named strategy from your chain.","description":"Turn a strategy id + your option chain into concrete legs (real strikes/premiums) and analyse it. Bills per built leg.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["strategyId","chain"],"properties":{"strategyId":{"type":"string"},"chain":{"$ref":"#/components/schemas/Chain"},"params":{"type":"object"}}},"example":{"strategyId":"iron-condor","chain":{"underlying":100,"days":30,"calls":[],"puts":[]}}}}},"responses":{"200":{"description":"Legs + analysis","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"strategyId":{"type":"string"},"legs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}},"analysis":{"$ref":"#/components/schemas/Analysis"}}}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/recommend":{"post":{"tags":["Strategies"],"summary":"Rank strategies for a target price.","description":"Score the catalog against your target price + risk appetite on the chain you supply. Bills the total legs across the returned set.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["chain","expectedPrice"],"properties":{"chain":{"$ref":"#/components/schemas/Chain"},"expectedPrice":{"type":"number"},"riskAppetite":{"type":"number"},"topN":{"type":"integer"}}},"example":{"chain":{"underlying":100,"days":30,"calls":[],"puts":[]},"expectedPrice":108,"riskAppetite":0.5,"topN":8}}}},"responses":{"200":{"description":"Ranked strategies","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"underlying":{"type":"number"},"days":{"type":"integer"},"ranked":{"type":"array","items":{"type":"object"}}}}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/backtest":{"post":{"tags":["Strategies"],"summary":"Backtest a strategy over your price history.","description":"Roll a strategy through the daily price history you supply → win rate, average return-on-risk, best/worst, equity curve. Bills 4 credits (compute-heavy).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["strategyId","priceHistory"],"properties":{"strategyId":{"type":"string"},"priceHistory":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"close":{"type":"number"}}}},"dte":{"type":"integer"}}},"example":{"strategyId":"bull-put-spread","priceHistory":[{"date":"2026-01-02","close":98.1}],"dte":30}}}},"responses":{"200":{"description":"Backtest stats","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Backtest"}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/price":{"post":{"tags":["Pricing & IV"],"summary":"Black-Scholes price + Greeks (one option).","description":"Theoretical price and full Greeks for a single option. Bills 1 credit.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["type","S","K","iv"],"properties":{"type":{"type":"string","enum":["call","put"]},"S":{"type":"number"},"K":{"type":"number"},"days":{"type":"integer"},"iv":{"type":"number"},"r":{"type":"number"}}},"example":{"type":"call","S":100,"K":105,"days":30,"iv":0.3,"r":0}}}},"responses":{"200":{"description":"Price + Greeks","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PriceGreeks"}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/iv":{"post":{"tags":["Pricing & IV"],"summary":"Implied volatility (one option).","description":"Solve the implied volatility from a market price for a single option. Bills 1 credit.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["type","S","K","marketPrice"],"properties":{"type":{"type":"string","enum":["call","put"]},"S":{"type":"number"},"K":{"type":"number"},"marketPrice":{"type":"number"},"days":{"type":"integer"},"r":{"type":"number"}}},"example":{"type":"call","S":100,"K":105,"marketPrice":2.4,"days":30,"r":0}}}},"responses":{"200":{"description":"Implied vol","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"iv":{"type":"number"}}}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/iv-rank":{"post":{"tags":["Market data"],"summary":"IV Rank + percentile.","description":"Where the current IV sits vs a supplied IV history (0–100 rank + percentile). Bills 1 credit.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["history","currentIv"],"properties":{"history":{"type":"array","items":{"type":"number"}},"currentIv":{"type":"number"}}},"example":{"history":[0.22,0.31,0.28,0.4,0.35],"currentIv":0.3}}}},"responses":{"200":{"description":"IV rank","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"ivRank":{"type":"number"},"ivPercentile":{"type":"number"}}}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/chain-highlights":{"post":{"tags":["Market data"],"summary":"Chain highlights.","description":"Put/call OI + volume ratios, the OI \"walls\" and most-active strikes from a chain you supply. Bills 1 credit.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["chain"],"properties":{"chain":{"$ref":"#/components/schemas/Chain"}}},"example":{"chain":{"underlying":100,"days":30,"calls":[],"puts":[]}}}}},"responses":{"200":{"description":"Highlights","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"type":"object"}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/volume-profile":{"post":{"tags":["Market data"],"summary":"Volume & OI by strike.","description":"Per-strike call/put volume and open interest around spot from a chain you supply. Bills 1 credit.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["chain"],"properties":{"chain":{"$ref":"#/components/schemas/Chain"},"window":{"type":"integer"}}},"example":{"chain":{"underlying":100,"days":30,"calls":[],"puts":[]},"window":21}}}},"responses":{"200":{"description":"Per-strike series","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"type":"object"}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/order-ticket":{"post":{"tags":["Execution"],"summary":"Map a strategy to an order ticket.","description":"Turn legs (or a strategy id + chain) into a broker-neutral multi-leg order ticket ready for your routing stack. Bills per leg.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"legs":{"type":"array","items":{"$ref":"#/components/schemas/Leg"}},"strategyId":{"type":"string"},"chain":{"$ref":"#/components/schemas/Chain"},"symbol":{"type":"string"},"expiration":{"type":"string"},"quantity":{"type":"integer"}}},"example":{"legs":[{"kind":"call","side":"long","strike":100,"premium":3.2,"qty":1},{"kind":"call","side":"short","strike":110,"premium":1.1,"qty":1}],"symbol":"AAPL","expiration":"2026-12-18","quantity":1}}}},"responses":{"200":{"description":"Order ticket","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/OrderTicket"}}}]}}}},"400":{"description":"Missing or invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit (120/min per key) or demo daily cap exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}