{"openapi":"3.1.0","info":{"title":"trdrs Engine API","version":"1.1.0","description":"## API Reference\n\nEvery route the trdrs engine serves, with what to send and what comes back. It covers market\ndata and news, trading and account state for a trader's own software, Connect pre-registration,\nthe venue routes a prop firm or brokerage runs its accounts through, and a trader's own challenges.\n\nStart with the Quickstart for your first call. The API standards hold the rules every route\nshares: keys, errors, rate limits, idempotency, paging and streaming."},"components":{"securitySchemes":{"venueOperatorKey":{"type":"http","scheme":"bearer","description":"The Venue key (`trdrs_vk_sandbox_…` or `trdrs_vk_production_…`), in preview. It belongs to one venue in one environment and carries the scopes it was created with. The venue's verified owner creates it while signed in, and it works only on the `/api/partner/venues/{venueId}` routes. A `trdrs_sk_…` key can't be used in its place. It never lets you act as a trader, sign in or manage keys. Keep it on your server."},"tenantKey":{"type":"http","scheme":"bearer","description":"The Trading API key (`trdrs_sk_…`), for market data, orders and account state on the accounts its owner holds. Use it server-to-server only, never in a browser. Its scope is named `tenant` in the API."},"partnerKey":{"type":"http","scheme":"bearer","description":"The Partner key (`trdrs_sk_…`), issued to a firm for Connect pre-registration and the sandbox self-check. It works only on those routes under `/api/partner/`, outside the venue routes. It looks like a Trading API key but has a different scope: a Trading API key is refused here, and a Partner key is refused everywhere else. A venue’s own backend uses a Venue key instead."},"sessionCookie":{"type":"apiKey","in":"cookie","name":"session","description":"The signed session cookie of a trdrs user who is signed in, used by trdrs's own apps in a browser. An API key cannot reach a route secured this way."}},"schemas":{"ConformanceRun":{"type":"object","description":"One sandbox self-check run.","required":["id","status","rulesetVersion","openedAt","expiresAt","closedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"The run's id."},"status":{"type":"string","enum":["open","passed","failed","expired"],"description":"Where the run stands: open, then passed or failed when you finish it, or expired when its two hours run out."},"rulesetVersion":{"type":"string","description":"The version of the rules the run checks."},"openedAt":{"type":"string","format":"date-time","description":"When the run opened."},"expiresAt":{"type":"string","format":"date-time","description":"When the run expires."},"closedAt":{"type":["string","null"],"format":"date-time","description":"When the run was finished, or null while it is open."}}},"ConformanceGrade":{"type":"object","description":"How the run did against each rule.","required":["rulesetVersion","passed","outstanding","results"],"properties":{"rulesetVersion":{"type":"string","description":"The version of the rules checked."},"passed":{"type":"boolean","description":"True when every rule was exercised and passed."},"outstanding":{"type":"array","items":{"type":"string"},"description":"The rules not yet passed."},"results":{"type":"array","description":"One result per rule.","items":{"type":"object","required":["rule","title","kind","outcome","passes","failures","note"],"properties":{"rule":{"type":"string","description":"The rule's id."},"title":{"type":"string","description":"What the rule checks."},"kind":{"type":"string","enum":["passive","injected"],"description":"`passive` rules are checked on your ordinary requests. `injected` rules check how your client handles a problem the sandbox causes on purpose."},"outcome":{"type":"string","enum":["pass","fail","not_exercised"],"description":"Whether the rule passed, failed, or hasn't been exercised yet."},"passes":{"type":"integer","description":"How many times it was seen to pass."},"failures":{"type":"integer","description":"How many times it was seen to fail."},"note":{"type":["string","null"],"description":"More detail, or null."}}}}}},"ConformanceResponse":{"type":"object","description":"A self-check run, with its grade and the rules it checks.","required":["run"],"properties":{"run":{"$ref":"#/components/schemas/ConformanceRun"},"grade":{"$ref":"#/components/schemas/ConformanceGrade"},"rules":{"type":"array","description":"The rules the run checks, with how to exercise each.","items":{"type":"object","properties":{"id":{"type":"string","description":"The rule's id."},"title":{"type":"string","description":"What the rule checks."},"kind":{"type":"string","description":"`passive` or `injected`."},"minObservations":{"type":"integer","description":"How many times the rule must be seen to pass."},"howToExercise":{"type":"string","description":"What your client should do so the rule is exercised."}}}},"attestation":{"type":"string","description":"What you attest to separately, because the run can't measure it."}},"example":{"run":{"id":"96507d96-8c4f-4b84-a718-a72dd77ba104","status":"open","rulesetVersion":"1.0","openedAt":"2026-09-11T12:00:00.000Z","expiresAt":"2026-09-11T14:00:00.000Z","closedAt":null},"grade":{"rulesetVersion":"1.0","passed":false,"outstanding":["stream_reconnect"],"results":[{"rule":"stream_reconnect","title":"Streams recover from a reconnect snapshot","kind":"injected","outcome":"not_exercised","passes":0,"failures":0,"note":"Open an account stream and reconnect after the sandbox drops it."}]}}},"ErrorResponse":{"type":"object","description":"The body of every error response. It always carries `error`, an English sentence you can show. A refused trading request also carries `code`, one of the refusal codes, and `params`, the details of that refusal. Translate by `code` and `params`, and show a generic message for a code you don't recognize. Other errors may carry a `code` of their own.","properties":{"error":{"type":"string","description":"What went wrong, as an English sentence."},"code":{"type":"string","description":"A stable machine code. On a refused trading request, it is one of the refusal codes."},"params":{"type":"object","description":"The details of the refusal named by `code`, on a refused trading request."}},"required":["error"],"example":{"error":"invalid_instrument"}},"Refusal":{"type":"object","description":"Why a trading action is refused: a stable `code`, the details in `params`, and an English `message`. A refused request carries the same code and details beside its `error`, and an action verdict carries them before you send anything. New codes are added over time, so show a generic message for a code you don't recognize.","properties":{"code":{"type":"string","enum":["mode_unreadable","mode_unrecognized","hedge_position_mode","multi_assets_mode","classic_account","portfolio_margin","unified_account","unverified_account_abstraction","unknown_instrument","instrument_not_tradable","market_data_unavailable","market_data_stale","market_data_delayed","settlement_asset_unmodeled","product_unproven","venue_fill_refused","continuous_symbol_not_contract","contract_unregistered","contract_not_trading","margin_window_closing","risk_policy_unbound","risk_terms_missing","risk_terms_stale","risk_terms_contradictory","asset_class_not_supported","bare_root_unresolved","contract_past_safe_window","contract_dates_uncovered","venue_conditions_missing","entry_halted","instrument_not_permitted","venue_instrument_disabled","venue_instrument_expired","venue_route_missing","venue_route_retired","order_quantity_above_limit","position_quantity_above_limit","position_notional_above_limit","below_min_notional","valuation_required","valuation_stale","reduce_only_violation","collateral_policy_unverified","collateral_insufficient","collateral_unvalued","risk_locked","feature_disabled","stage_version_unrecorded","reconciliation_hold","not_found","permission_denied","invalid_request","version_conflict","idempotency_conflict","position_mode_unsupported","position_not_closable","position_revision_stale","product_economics_unsupported","currency_economics_unsupported","safety_lane_refused","command_blocked","command_settled","outcome_unknown","account_not_owned","account_unresolved","engine_overloaded","engine_draining","order_rejected"],"description":"The refusal code. Translate by this and `params`."},"params":{"type":"object","description":"The details of a refusal. Which ones it carries depends on `code`. Details never carry a secret, an account number or text a provider sent.\n\n**The account's settings at a provider** (`mode_unreadable`, `mode_unrecognized`, `hedge_position_mode`, `multi_assets_mode`, `classic_account`, `portfolio_margin`, `unified_account`, `unverified_account_abstraction`): `provider`; `instrument`, or null when the setting covers the whole account; `setting`; `reported`, the value the provider reported, or null when it could not be read or is undocumented; and `supported`, the values trdrs trades with.\n\n**The instrument** (`unknown_instrument`, `instrument_not_tradable`, `market_data_delayed`): `instrument`.\n\n`market_data_unavailable`: `instrument` and `cause`. On the paper book an order that needs a price the instrument's feed has not delivered yet waits for it, at most 5 seconds, and is refused this way only when the wait passes without it. `cause` is one of these:\n- `feed_down`: no live feed serves the instrument.\n- `feed_unreconciled`: the feed reconnected, and the prices it missed are not yet reconciled with the source.\n- `feed_other_contract`: the feed prices a different contract.\n- `quote_missing`: no quote arrived.\n- `quote_one_sided`: the side of the book the fill needs is empty.\n- `quote_invalid`: the quote is crossed, or a price in it is zero or below where the instrument allows none.\n- `mark_missing`: no mark or valuation price for the instrument arrived.\n- `source_mismatch`: the price is not from the source the venue names for the instrument, or it names no observation.\n- `price_time_invalid`: the price is stamped in the future or at no valid time.\n- `login_missing`: no market data login the trader connected carries the instrument. For futures in production that is a login on the trader’s firm’s production Rithmic system; a Rithmic Test login carries none. The paper book refuses a futures order on a contract the account trades from a trader with none before anything is claimed; a contract the account doesn’t trade is refused for that first.\n- `feed_capacity`: the engine could not open another market data session.\n- `feed_displaced`: another application took over the market data session on that login.\n\nA price that is only old is refused as `market_data_stale`, never as `market_data_unavailable`.\n\n`market_data_stale`: `instrument` and `ageSeconds`, the age of the newest price the order needed in whole seconds (never negative), or null when no price arrived or the feed went quiet.\n\n`venue_fill_refused`: `instrument` and `reason`, which is one of these:\n- `outside_collar`: the executable price, moved by the venue's markup, lies outside the route's collar.\n- `beyond_limit`: that price is past the order's limit price.\n- `commission_unit_mismatch`: the commission is charged per contract, lot or base unit, and the instrument counts its quantity in a different unit.\n\nA limit order refused this way on arrival is refused, never rested, whatever its time in force.\n\n`settlement_asset_unmodeled`: `instrument`, `settlementAsset`, `accountCurrency` and `issued`.\n\n`product_unproven`: `instrument`, `accountCurrency`, and `products`, every product trdrs trades in that currency (empty when it trades none).\n\n**A paper book contract, or the risk policy an account is bound to:**\n- `continuous_symbol_not_contract`: `instrument` and `root`. A continuous chart symbol names a product, not a dated contract.\n- `contract_unregistered` and `risk_policy_unbound`: `instrument`.\n- `contract_not_trading`: `instrument`; `phase` (`not_listed`, `close_only`, `expired` or `session_closed`); and `lastTradeAt` (null for a perpetual).\n- `margin_window_closing`: `instrument`; `overnightAt` (ISO 8601); `overnightInitial` and `overnightMaintenance`, the overnight margin per contract as decimal strings; and `asset`.\n- `risk_terms_missing` and `risk_terms_contradictory`: `instrument` and `term` (`futures_margin`, `derivative_margin`, `cfd_margin`, `markup`, `financing`, `funding`, `conversion`, `thresholds`, `valuation`, `settlement` or `posting`).\n- `risk_terms_stale`: the same, and `effectiveUntil`.\n\n`asset_class_not_supported`: `instrument`, `assetClass` and `provider`. `provider` is null when the asset class is switched off everywhere, and `paper` when the account's risk policy on the paper book states no terms for the instrument's product class.\n\n`bare_root_unresolved`: `root`; `cause` (`dates_unmodeled`, `dates_uncovered`, `unsafe_window` or `ambiguous`); `contract`, the dated contract the roll rule names; `heldContract`, for `ambiguous`, the contract the account holds instead; `window` (`provider_cutoff`, `first_intention_day` or `last_trade_day`) and `boundary` (ISO 8601, when the window opened), for `unsafe_window`; `source`, the exchange specification the dates come from; and `cutoffTerm`, the connection's delivery cutoff as name@version. Each is null when it does not apply. It also answers a continuous symbol, such as `ZN1!` or `ZN2!`, whose contract the roll rule can't name, with the same parameters.\n\n`contract_past_safe_window`: `contract`, `window`, `boundary`, `source` and `cutoffTerm`. `contract_dates_uncovered`: `contract` and `source`.\n\n**An issued account's venue conditions** (`venue_conditions_missing`, `entry_halted`, `instrument_not_permitted`, `venue_instrument_disabled`, `venue_instrument_expired`, `venue_route_missing`, `venue_route_retired`, `order_quantity_above_limit`, `position_quantity_above_limit`, `position_notional_above_limit`, `below_min_notional`, `valuation_required`, `valuation_stale`, `reduce_only_violation`): `instrument` and `limit`, the venue's limit as a decimal string, or null. On an account a venue issued on the paper book, these refuse an order that adds exposure, whether it fills at once or rests, and `instrument` is the venue's instrument id. An order that only reduces exposure passes all of them, and the account's size limits come from its risk policy.\n\n`collateral_policy_unverified`: `instrument` and `cause` (`missing`, `unpublished`, `stale` or `contradictory`).\n\n`collateral_insufficient`: `instrument`, `currency`, and `required` and `available` as decimal strings in the collateral pool's currency. `available` is negative when the pool already holds less than it requires.\n\n`collateral_unvalued`: `instrument` (null for a pending obligation) and `cause` (`obligation_pending`, `mark_unavailable`, `mark_stale`, `conversion_unavailable` or `conversion_stale`).\n\n`risk_locked`: `holds`, the holds on the account (`trading_lock`, `drawdown_latch`, `liquidation_incident`, `stop_out_latch`, `risk_uncovered`), or null when they could not be read, and `error` names each hold in its own words. A hold refuses only an order that can add exposure: a reduce-only order, a close, a cancel, and setting, moving or removing a protective stop or target pass every hold. On an account bound to a risk policy, `risk_uncovered` means the account's risk check has not valued it. While the risk check is only processing the account's latest change (the account was just opened, a position was just opened, or a price stream it reads is reconnecting), an order that adds exposure waits for it, at most 5 seconds, and then goes on. If the wait passes first, an order that adds exposure on an instrument that has had no price is refused as `market_data_unavailable` with cause `mark_missing`, and any other order that adds exposure as `risk_locked`. A price the account is valued at that is stale, or whose feed is down, is not waited for: an order that adds exposure is refused at once as `market_data_stale`, or as `market_data_unavailable` with cause `feed_down`, naming the instrument.\n\n`feature_disabled`: `feature`.\n\n`stage_version_unrecorded`: `reason` and `stageId`. `reason` is `no_record`, or `activated_after_opening` when the stage rules in force took effect after the current cycle opened and the account has traded in it. The account is close-only, so cancels, exits and reductions still work.\n\n`reconciliation_hold` carries no details. A reconciliation check found a problem, and the account is held until a trdrs operator releases it: an order that may add exposure is refused, while reductions and cancels still work.\n\n`safety_lane_refused`: `action`.\n\n**Refusals while the paper book records the order** carry no details, except `invalid_request`. Nothing is written when one of them is returned.\n- `not_found`: the order or instrument is not on the account.\n- `permission_denied`: the venue does not allow it now, because its route is closed to it or the account is held.\n- `invalid_request`: the request is not valid for the instrument. `field` is the path of the refused value and `reason` is its code; both are null when the request as a whole is refused. The instrument's own terms refuse with `instrument_order_type_unsupported`, `instrument_tif_unsupported`, `decimal_string_required`, `instrument_quantity_range`, `off_quantity_grid`, `nonpositive_price`, `price_outside_bands` or `off_price_grid`.\n- `version_conflict`: the account kept changing while the engine admitted the order. The engine reads and admits it again up to three times before answering this, so send it again.\n- `idempotency_conflict`: the id is already taken with other terms.\n- `position_mode_unsupported`: the command names a position in a way the account's position mode doesn't support, such as a reduce-only order that names no ticket on an account that holds separate tickets, or a read of one net position per instrument on such an account.\n- `position_not_closable`: the position a close or its exits name is not open on the instrument, is held on the side the close trades, or holds less than the close asks for.\n- `position_revision_stale`: the position changed after the `positionRevision` the command stated.\n- `product_economics_unsupported` and `currency_economics_unsupported`: the paper book does not value the product or settle the currency.\n\n`command_blocked`, `command_settled`, `outcome_unknown`, `account_not_owned`, `account_unresolved`, `engine_overloaded`, `engine_draining` and `order_rejected` carry no details. `order_rejected` covers any other rejection, and its `error` is the sentence to show."},"message":{"type":"string","description":"The refusal as an English sentence, for a client that doesn't translate the code."}},"required":["code","params","message"]},"ActionVerdict":{"type":"object","description":"Whether one action is allowed right now and, when it isn't, the refusal the order would get. It's advice for your interface: the order is checked again when you send it.","properties":{"allowed":{"type":"boolean","description":"True when the action is allowed now."},"refusal":{"oneOf":[{"$ref":"#/components/schemas/Refusal"},{"type":"null"}],"description":"The refusal the action would get, or null when it is allowed."}},"required":["allowed","refusal"]},"AccountActionsResponse":{"type":"object","description":"What the account may do right now, as one verdict per action. Each verdict is the answer the route that carries the action would give. Without an instrument, `open`, `reduce`, `close` and `protect` say what stops them on every instrument, and `flatten` says what stops flattening the whole account. On the paper book, flattening the account closes every position it can, and each position's own verdict says which one it can't. A feature the provider doesn't support at all is stated in the account's `capabilities`, not here.","properties":{"instrument":{"type":["string","null"],"description":"The instrument the verdicts are for, as you requested it, or null for the account-wide verdicts."},"actions":{"type":"object","description":"One verdict per action. Live trading can be switched off, and then every order through `POST /api/trading/order` is refused, so `open` and `reduce` both follow that switch. A risk hold (`risk_locked`) or a reconciliation hold (`reconciliation_hold`) refuses an entry. A reduce-only order passes both holds where the provider enforces reduce-only, so `reduce` follows the holds only where it doesn't. On an account a venue issued, the venue lets a reduction through every entry check. The close route is not stopped by the switch. Under a hold, a close passes only where the provider enforces it as reduce-only, so `close` follows the hold elsewhere, while `flatten` and `cancel` stay available.","properties":{"open":{"$ref":"#/components/schemas/ActionVerdict","description":"Any order that could open or add exposure: an entry of any type, a bracket, a reverse or a reprice."},"reduce":{"$ref":"#/components/schemas/ActionVerdict","description":"An order through `POST /api/trading/order` that only reduces the held position."},"close":{"$ref":"#/components/schemas/ActionVerdict","description":"Closing part of the position with `POST /api/trading/close`."},"protect":{"$ref":"#/components/schemas/ActionVerdict","description":"Placing or moving the position's stop and target."},"flatten":{"$ref":"#/components/schemas/ActionVerdict","description":"Closing the position outright or, without an instrument, every position on the account."},"cancel":{"$ref":"#/components/schemas/ActionVerdict","description":"Cancelling a working order."}},"required":["open","reduce","close","protect","flatten","cancel"]},"checkedAt":{"type":"integer","description":"When the verdicts were worked out, in epoch seconds."}},"required":["instrument","actions","checkedAt"],"example":{"instrument":"CME:ESZ2026","actions":{"open":{"allowed":false,"refusal":{"code":"contract_not_trading","params":{"instrument":"CME:ESZ2026","phase":"close_only","lastTradeAt":"2026-12-18T14:30:00.000Z"},"message":"CME:ESZ2026 is close only; its last trade is 2026-12-18T14:30:00.000Z"}},"protect":{"allowed":true,"refusal":null},"reduce":{"allowed":true,"refusal":null},"close":{"allowed":true,"refusal":null},"flatten":{"allowed":true,"refusal":null},"cancel":{"allowed":true,"refusal":null}},"checkedAt":1788006720}},"OkResponse":{"type":"object","description":"The confirmation a write returns when it has nothing else to say.","properties":{"ok":{"type":"boolean","description":"True when the write succeeded."}},"required":["ok"],"example":{"ok":true}},"WireBar":{"type":"object","description":"One price bar: the open, high, low, close and volume over one timeframe interval.","properties":{"t":{"type":"number","description":"When the bar opens, in epoch seconds."},"o":{"type":"number","description":"The first price in the interval."},"h":{"type":"number","description":"The highest price in the interval."},"l":{"type":"number","description":"The lowest price in the interval."},"c":{"type":"number","description":"The last price in the interval."},"v":{"type":"number","description":"The volume traded in the interval."}},"required":["t","o","h","l","c","v"]},"WireSymbolRow":{"type":"object","description":"One symbol in a search result.","properties":{"symbol":{"type":"string","description":"The symbol id: for futures a root (`ES`), a continuous symbol (`ES1!`, `ES2!`) or a dated contract (`CME:ESZ2026`). Use it exactly as returned in every other market data call."},"name":{"type":"string","description":"The short display name. A continuous symbol names its position (`E-mini S&P 500 continuous front month`), and a dated contract its month (`E-mini S&P 500 Dec 2026`)."},"exchange":{"type":"string","description":"The exchange the symbol trades on."},"type":{"type":"string","description":"The kind of instrument."},"provider":{"type":["string","null"],"enum":["pyth","rithmic",null],"description":"The provider that publishes the data for you, named only when it really publishes it, or null. A symbol more than one provider serves you lists once for each."},"via":{"type":["string","null"],"description":"The feed the data comes through when it is proxied, or null."}},"required":["symbol","name","exchange","type","provider","via"]},"SymbolsResponse":{"type":"object","description":"One page of symbol search results.","properties":{"symbols":{"type":"array","items":{"$ref":"#/components/schemas/WireSymbolRow"},"description":"The matching symbols on this page."},"provider":{"type":["string","null"],"enum":["pyth","rithmic",null],"description":"The provider that publishes the data for this page, or null."},"hasMore":{"type":"boolean","description":"True when more results follow. It is exact, so paging with `offset` until it is false always ends."}},"required":["symbols","provider","hasMore"],"example":{"symbols":[{"symbol":"ES","name":"E-mini S&P 500","exchange":"CME","type":"future","provider":"rithmic","via":null},{"symbol":"ES1!","name":"E-mini S&P 500 continuous front month","exchange":"CME","type":"future","provider":"rithmic","via":null},{"symbol":"ES2!","name":"E-mini S&P 500 continuous second month","exchange":"CME","type":"future","provider":"rithmic","via":null},{"symbol":"CME:ESZ2026","name":"E-mini S&P 500 Dec 2026","exchange":"CME","type":"future","provider":"rithmic","via":null},{"symbol":"CME:ESH2027","name":"E-mini S&P 500 Mar 2027","exchange":"CME","type":"future","provider":"rithmic","via":null}],"provider":"rithmic","hasMore":false}},"SessionSegment":{"type":"object","description":"One stretch of a trading day on the holiday calendar.","properties":{"start":{"type":"number","description":"Where the stretch starts, in minutes after midnight, exchange time."},"end":{"type":"number","description":"Where the stretch ends, in minutes after midnight, exchange time, exclusive. 1440 is the next midnight."},"session":{"type":"string","enum":["pre","open","eth","after"],"description":"Which session the stretch belongs to: pre-market, the regular session, extended trading hours or after hours."}},"required":["start","end","session"]},"Subsession":{"type":"object","description":"One of a symbol's named sessions.","properties":{"id":{"type":"string","enum":["regular","extended","premarket","postmarket"],"description":"Which session this is. `regular` is the exchange's regular hours, `premarket` and `postmarket` are the extended hours before and after them, and `extended` is the whole span from the pre-market open to the post-market close. The symbol's `session` equals `regular` on an exchange whose session is its regular hours (NYSE), and equals `extended` on an exchange whose one continuous session contains them (CME Globex)."},"session":{"type":"string","description":"The session's hours, in the same format as the symbol's `session`, including its trading-day suffix.","example":"0400-0930"},"description":{"type":"string","description":"A display label some third-party feeds send. trdrs never sends it: take labels from your own catalog, by `id`."},"sessionCorrections":{"type":"string","description":"The trading days that shorten this session, in the same format as the symbol's `corrections`. Present only when the served calendar shortens this session. A session that a shortened day drops entirely (the Globex closing hour on an early close) has no entry, because the format states shorter hours, not none. On any date, a session never runs past that date's `extended` hours.","example":"1300-1700:20261127,20261224"}},"required":["id","session"]},"PriceFormat":{"type":"object","description":"How the symbol's prices are written. It follows exactly from the symbol's tick and quotation convention, never from the size of a price.","properties":{"pricescale":{"type":"number","description":"Price units per whole unit: 100 writes cents, 100000 writes pipettes and 32 writes thirty-seconds. It alone sets how many decimal places to show."},"minmov":{"type":"number","description":"The smallest move, in those units."},"minmove2":{"type":"number","description":"How many parts one minmov step divides into again: 2 is halves of a thirty-second, 4 is quarters."},"fractional":{"type":"boolean","description":"True when the part below one unit is written as a counted fraction, such as 119'16."},"variableTickSize":{"type":"string","description":"A tick ladder, for a symbol that has one: a tick, then the price below which it applies, repeated, ending with the tick that applies above the last price."}},"required":["pricescale","minmov"]},"SymbolInfoResponse":{"type":"object","description":"Everything you need to display and chart one symbol: its identity, how its prices are written, and its trading sessions and holidays.","properties":{"symbol":{"type":"string","description":"The symbol as you asked for it."},"name":{"type":"string","description":"The short display name."},"ticker":{"type":"string","description":"The symbol id to use in every later call, to resolve or subscribe."},"description":{"type":"string","description":"The long display name."},"exchange":{"type":"string","description":"The exchange the symbol trades on."},"listedExchange":{"type":"string","description":"The exchange that lists the symbol."},"type":{"type":"string","description":"The kind of instrument. A spread expression resolves as `spread`."},"supportedResolutions":{"type":"array","items":{"type":"string"},"description":"The timeframes this symbol's feed serves. Empty means the feed serves any timeframe the format from /api/market/config accepts, rather than a short list that would promise less than it serves."},"timezone":{"type":"string","description":"The IANA time zone of the exchange session, such as America/Chicago."},"session":{"type":"string","description":"The weekly session in exchange time, as HHMM-HHMM. A trading-day suffix (1 is Sunday through 7 is Saturday) marks a session that opens on the previous calendar day, and `24x7` marks a market that never closes."},"sessionHolidays":{"type":"string","description":"The days the market is fully closed, as comma-separated YYYYMMDD dates in order. Present only when `sessionCalendar` is."},"corrections":{"type":"string","description":"The trading days whose hours differ from the weekly session, as semicolon-separated `hours:dates` entries. The hours use the same format as `session`, without a trading-day suffix: a start later than the end opens on the previous calendar day, and hours that run to midnight end at 0000. The dates are an ordered, comma-separated YYYYMMDD list. Full closures are never listed here, because they are in `sessionHolidays`. Present only when the served calendar holds a shortened trading day.","example":"1700-1200:20261126;1700-1215:20261127,20261224"},"subsessions":{"type":"array","items":{"$ref":"#/components/schemas/Subsession"},"description":"The named sessions of a market that keeps extended hours: regular, extended, premarket and postmarket. For a stock, the regular entry has the same hours as `session`, and the extended hours appear only here. For a future, the extended entry has the same hours as `session`, and the regular entry states the regular trading hours inside it. Read pre-market and post-market status and extended-hours shading from here. Present for stocks and futures, and absent for FX, crypto and spreads, which have one session with no named parts.","example":[{"id":"regular","session":"0930-1600","sessionCorrections":"0930-1300:20261127,20261224"},{"id":"extended","session":"0400-2000","sessionCorrections":"0400-1700:20261127,20261224"},{"id":"premarket","session":"0400-0930"},{"id":"postmarket","session":"1600-2000","sessionCorrections":"1300-1700:20261127,20261224"}]},"dataStatus":{"type":"string","enum":["streaming","endofday","delayed_streaming"],"description":"How live the data is for you. `streaming` means a real-time feed serves the symbol. `delayed_streaming` means your feed sends prices the exchange has delayed: show them as delayed, because they never count as real time. `endofday` means no feed serves it."},"currencyCode":{"type":"string","description":"The quote currency: an ISO 4217 code for a market quoted in money, or the quote asset the provider declares for a perpetual margined in a stablecoin. Absent when the instrument declares none."},"unitId":{"type":"string","description":"The unit a symbol that isn't quoted in a currency is quoted in."},"volumePrecision":{"type":"number","description":"How many decimal places to show for volume: 0 for a market that trades whole units, otherwise the provider's size step."},"format":{"$ref":"#/components/schemas/PriceFormat","description":"How to write the symbol's prices."},"provider":{"type":["string","null"],"enum":["pyth","rithmic",null],"description":"The provider that publishes the data, or null when no feed is set up for the symbol."},"via":{"type":["string","null"],"description":"The feed the data comes through when it is proxied, or null."},"tick":{"type":["number","null"],"description":"The smallest price move, or null when the symbol has none, as a spread expression doesn't."},"quotes":{"type":"boolean","description":"True when the feed serves real top-of-book quotes for the symbol."},"sessionClass":{"type":"string","enum":["equity","futures","fx","crypto"],"description":"The trading-session model the symbol follows. trdrs states it, so you never have to guess it."},"sessionCalendar":{"type":"object","description":"The holiday calendar for the symbol's session model, for futures and stocks. It is absent for FX and crypto. Dates are exchange-local YYYY-MM-DD, an empty list of stretches is a full closure, and a date that isn't listed follows the weekday rules. trdrs keeps this calendar up to date every year, so your client never ships its own calendar updates.","properties":{"holidays":{"type":"object","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/SessionSegment"}},"description":"The stretches that trade on each listed date, keyed by YYYY-MM-DD."},"coverageThrough":{"type":"string","description":"The last exchange-local date the calendar covers, as YYYY-MM-DD."}},"required":["holidays","coverageThrough"]},"multiplier":{"type":["number","null"],"description":"What a price move of 1.0 is worth per unit, in dollars, or null when it isn't known. It is never a guess."}},"required":["symbol","name","ticker","description","exchange","listedExchange","type","supportedResolutions","timezone","session","dataStatus","volumePrecision","format","provider","via","tick","quotes","sessionClass","multiplier"],"example":{"symbol":"ESU6","name":"E-mini S&P 500 Sep 2026","ticker":"ESU6","description":"E-mini S&P 500 Sep 2026","exchange":"CME","listedExchange":"CME","type":"future","supportedResolutions":[],"timezone":"America/Chicago","session":"1700-1600:23456","sessionHolidays":"20261225,20270101","corrections":"1700-1200:20261126;1700-1215:20261127,20261224","subsessions":[{"id":"regular","session":"0830-1515:23456","sessionCorrections":"0830-1200:20261126;0830-1215:20261127,20261224"},{"id":"extended","session":"1700-1600:23456","sessionCorrections":"1700-1200:20261126;1700-1215:20261127,20261224"},{"id":"premarket","session":"1700-0830:23456"},{"id":"postmarket","session":"1515-1600:23456"}],"dataStatus":"streaming","currencyCode":"USD","volumePrecision":0,"format":{"pricescale":100,"minmov":25},"provider":"rithmic","via":null,"tick":0.25,"quotes":true,"sessionClass":"futures","sessionCalendar":{"holidays":{"2026-12-25":[]},"coverageThrough":"2027-06-30"},"multiplier":50}},"HistoryResponse":{"type":"object","description":"The bars for one symbol and timeframe, oldest first.","properties":{"instrument":{"type":"string","description":"The symbol the bars are for."},"tf":{"type":"string","description":"The timeframe of the bars."},"bars":{"type":"array","items":{"$ref":"#/components/schemas/WireBar"},"description":"The bars, oldest first."},"noData":{"type":"boolean","description":"Present, and true, only when a `countBack` request found no bars at all."},"stale":{"type":"boolean","description":"Present, and true, only when every bar returned is older than the window the `countBack` request asked for."}},"required":["instrument","tf","bars"],"example":{"instrument":"ESU6","tf":"5m","bars":[{"t":1787581200,"o":6478.25,"h":6481.5,"l":6477.75,"c":6480.5,"v":12841},{"t":1787581500,"o":6480.5,"h":6483.25,"l":6479.5,"c":6482.75,"v":9973},{"t":1787581800,"o":6482.75,"h":6484,"l":6480.25,"c":6481.25,"v":11204}]}},"WireQuoteSnapshot":{"type":"object","description":"A quote for one symbol. A value that isn't known is null, never a made-up 0. `bid` and `ask` are the real top of the book or null: trdrs never fills in a missing side.","properties":{"symbol":{"type":"string","description":"The symbol."},"last":{"type":["number","null"],"description":"The last traded price."},"open":{"type":["number","null"],"description":"The session's opening price."},"high":{"type":["number","null"],"description":"The session's high."},"low":{"type":["number","null"],"description":"The session's low."},"prevClose":{"type":["number","null"],"description":"The previous session's closing price."},"volume":{"type":["number","null"],"description":"The volume traded in the session."},"change":{"type":["number","null"],"description":"The change from the previous close."},"changePct":{"type":["number","null"],"description":"The change from the previous close, in percent."},"bid":{"type":["number","null"],"description":"The best bid, or null."},"ask":{"type":["number","null"],"description":"The best ask, or null."},"spark":{"type":"array","items":{"type":"number"},"description":"Recent daily closes, oldest first, for a small chart. It may be empty."}},"required":["symbol","last","prevClose","change","changePct","bid","ask","spark"]},"QuotesResponse":{"type":"object","description":"Quotes for the symbols you asked for.","properties":{"quotes":{"type":"array","items":{"$ref":"#/components/schemas/WireQuoteSnapshot"},"description":"One quote per symbol."}},"required":["quotes"],"example":{"quotes":[{"symbol":"ESU6","last":6481.25,"open":6470.5,"high":6488,"low":6465.75,"prevClose":6474.5,"volume":812450,"change":6.75,"changePct":0.1,"bid":6481,"ask":6481.25,"spark":[6459.25,6462,6474.5,6481.25]},{"symbol":"XAUUSD","last":null,"prevClose":null,"change":null,"changePct":null,"bid":null,"ask":null,"spark":[]}]}},"ServerTimeResponse":{"type":"object","description":"The engine's clock.","properties":{"time":{"type":"number","description":"The engine's clock in epoch seconds, rounded down."},"timeMs":{"type":"integer","description":"The same reading in epoch milliseconds."}},"required":["time","timeMs"],"example":{"time":1787581920,"timeMs":1787581920123}},"ConnectProvider":{"type":"object","description":"One built-in provider as Connect lists it, with its login style.","properties":{"provider":{"type":"string","enum":["rithmic","tastytrade","hyperliquid","binance","bybit","paper"],"description":"The provider id. It is also the value `?provider=` takes on the trading and account routes."},"name":{"type":"string","description":"The product name."},"loginStyle":{"type":"string","enum":["trader_login","oauth","api_key","wallet_key","firm_credentials","none"],"description":"How the provider is signed into. `trader_login`: the trader’s own username and password at the provider. `oauth`: the trader authorizes trdrs at the provider. `api_key`: an API key and secret. `wallet_key`: a wallet address and an agent key. `firm_credentials`: the venue connects it with the firm’s own credentials, and the trader types nothing. `none`: the provider has no login of its own, so signing in to trdrs is the login."},"needsSystem":{"type":"boolean","description":"True when a trader’s login belongs to a named system (the trader’s firm), which the sign-in form then asks for. Only Rithmic needs one today."}},"required":["provider","name","loginStyle","needsSystem"]},"ConnectProvidersResponse":{"type":"object","description":"The built-in providers Connect lists.","properties":{"providers":{"type":"array","items":{"$ref":"#/components/schemas/ConnectProvider"},"description":"One entry per built-in provider."}},"required":["providers"],"example":{"providers":[{"provider":"rithmic","name":"Rithmic","loginStyle":"trader_login","needsSystem":true},{"provider":"tastytrade","name":"Tastytrade","loginStyle":"oauth","needsSystem":false},{"provider":"hyperliquid","name":"Hyperliquid","loginStyle":"wallet_key","needsSystem":false},{"provider":"binance","name":"Binance","loginStyle":"api_key","needsSystem":false},{"provider":"bybit","name":"Bybit","loginStyle":"api_key","needsSystem":false},{"provider":"paper","name":"trdrs paper book","loginStyle":"none","needsSystem":false}]}},"MarketConfigResponse":{"type":"object","description":"Which timeframes the market data routes accept, how much each call may ask for, and which asset classes the catalog serves.","properties":{"timeframes":{"type":"object","description":"The timeframe format. A timeframe is written `<N><unit>`, and any count from 1 to a unit's `maxCount` is accepted, so custom values such as `45s`, `90m`, `250t` and `3mo` work even though no preset lists them. Check a timeframe against `units` and you get the same answer the engine gives, without a round trip.","properties":{"units":{"type":"array","description":"Every unit, with its largest accepted count.","items":{"type":"object","properties":{"unit":{"type":"string","enum":["t","s","m","h","d","w","mo"],"description":"Tick, second, minute, hour, day, week or month."},"maxCount":{"type":"integer","description":"The largest count accepted, inclusive. A larger count is refused with 400."},"nominalSeconds":{"type":"integer","description":"The length of one bar, in seconds. It is exact except for `t` (about a minute) and `mo` (about 30 days). Use it to size ranges and order menus, never as a promise about how far apart bars are."}},"required":["unit","maxCount","nominalSeconds"]}},"presets":{"type":"array","items":{"type":"string"},"description":"The standard timeframe menu to show. It is a suggestion, not the limit of what is accepted."}},"required":["units","presets"]},"limits":{"type":"object","description":"How much one call may ask for.","properties":{"maxBars":{"type":"integer","description":"The most bars one /api/market/history call returns: the largest `countBack`, and the widest `from`/`to` window, in bars."},"maxSymbolsPerPage":{"type":"integer","description":"The largest `limit` on symbol search. A larger `limit` is lowered to this, not refused."},"maxQuoteSymbols":{"type":"integer","description":"The most symbols one /api/market/quotes call accepts."}},"required":["maxBars","maxSymbolsPerPage","maxQuoteSymbols"]},"assetClasses":{"type":"array","items":{"type":"string"},"description":"The asset classes the catalog serves here, so any filter you offer has results behind it."}},"required":["timeframes","limits","assetClasses"],"example":{"timeframes":{"units":[{"unit":"t","maxCount":1000,"nominalSeconds":60},{"unit":"s","maxCount":3600,"nominalSeconds":1},{"unit":"m","maxCount":1440,"nominalSeconds":60},{"unit":"h","maxCount":168,"nominalSeconds":3600},{"unit":"d","maxCount":365,"nominalSeconds":86400},{"unit":"w","maxCount":52,"nominalSeconds":604800},{"unit":"mo","maxCount":120,"nominalSeconds":2592000}],"presets":["1s","5s","15s","30s","1m","3m","5m","15m","30m","1h","2h","4h","1d","1w"]},"limits":{"maxBars":5000,"maxSymbolsPerPage":100,"maxQuoteSymbols":50},"assetClasses":["futures","crypto"]}},"PriceFraction":{"type":"object","description":"How a product the exchange quotes in thirty-seconds of a point writes and trades its prices. `denominator` is how many parts one point divides into, and `subFraction` is how many parts one of those divides into again. A 1/32 tick is `{ denominator: 32 }`, a 1/64 tick is `{ denominator: 64, subFraction: 2 }`, and a 1/128 tick is `{ denominator: 128, subFraction: 4 }`. Those are the only three. A product quoted in decimals has no price fraction.","properties":{"denominator":{"type":"integer","enum":[32,64,128],"description":"How many parts one point divides into."},"subFraction":{"type":"integer","enum":[2,4],"description":"How many parts one of those divides into again: 2 is halves of a thirty-second, 4 is quarters. Absent for a whole thirty-second."}},"required":["denominator"]},"ContractSpec":{"type":"object","description":"One futures product: where it lists, its tick size and tick value, its dollar multiplier, its roll cycle, and the months it lists contracts in when trdrs doesn't model its roll. These are the facts an order ticket sizes and rounds prices with.","properties":{"root":{"type":"string","description":"The product root, such as `ES`."},"name":{"type":"string","description":"The product name."},"exchange":{"type":"string","description":"The listing exchange, such as `CME`."},"tickSize":{"type":"number","description":"The smallest price move."},"tickValue":{"type":"number","description":"What one tick is worth on one contract, in dollars."},"multiplier":{"type":"number","description":"What a price move of 1.0 is worth on one contract, in dollars. It equals tickValue divided by tickSize."},"cycle":{"type":["string","null"],"enum":["quarterly",null],"description":"`quarterly` means trdrs models the product's own contract dates (the equity index, Euro FX and Treasury rules), so a bare root names one March, June, September or December contract. Null means the product has its own dates that trdrs doesn't model, so an order must name its contract month."},"months":{"type":"array","items":{"type":"integer","minimum":1,"maximum":12},"description":"The calendar months, 1 to 12, that a product with a null `cycle` lists contracts in. Absent on quarterly products."},"fractionalPrice":{"type":"boolean","description":"True when the exchange quotes the product in thirty-seconds of a point rather than in decimals, as CBOT Treasury futures are. It doesn't depend on tickSize, and it sets the fractional price format on /api/market/symbol-info. Absent means decimal."},"priceFraction":{"$ref":"#/components/schemas/PriceFraction","description":"How the product writes and trades prices in thirty-seconds. Present only when fractionalPrice and tickSize together name one of the three fractions. Absent means the product is priced in decimals, so size and round against tickSize. Read this rather than working out a denominator from the tick."}},"required":["root","name","exchange","tickSize","tickValue","multiplier","cycle"]},"InstrumentsResponse":{"type":"object","description":"The futures products trdrs trades, one row per product root.","properties":{"instruments":{"type":"array","items":{"$ref":"#/components/schemas/ContractSpec"},"description":"One row per product root."}},"required":["instruments"],"example":{"instruments":[{"root":"ES","name":"E-mini S&P 500","exchange":"CME","tickSize":0.25,"tickValue":12.5,"multiplier":50,"cycle":"quarterly"},{"root":"CL","name":"Crude Oil","exchange":"NYMEX","tickSize":0.01,"tickValue":10,"multiplier":1000,"cycle":null,"months":[1,2,3,4,5,6,7,8,9,10,11,12]},{"root":"ZN","name":"10-Year T-Note","exchange":"CBOT","tickSize":0.015625,"tickValue":15.625,"multiplier":1000,"cycle":"quarterly","fractionalPrice":true,"priceFraction":{"denominator":64,"subFraction":2}}]}},"WireNewsItem":{"type":"object","description":"One market news headline. `instruments` holds the futures roots the story was tagged with when it arrived.","properties":{"id":{"type":"string","description":"A stable id, which is also the key for the thumbnail route."},"source":{"type":"string","description":"The publisher's name, for attribution."},"headline":{"type":"string","description":"The headline."},"summary":{"type":"string","description":"A teaser or the full story, as plain text in a light format: a line starting '## ' is a subheading, a line starting '• ' is a bullet, and everything else is a paragraph. Publisher HTML never appears. It is an empty string when the source sent none."},"url":{"type":"string","description":"The story on the publisher's site."},"imageUrl":{"type":["string","null"],"description":"Non-null when the story has a thumbnail. Fetch the image from /api/news/image/{id}, never from this URL."},"publishedAt":{"type":"string","description":"When the story was published, in ISO 8601."},"tags":{"type":"array","items":{"type":"string"},"description":"The source's categories, such as macro, energy or metals."},"instruments":{"type":"array","items":{"type":"string"},"description":"The futures roots the story was tagged with, such as ES, GC or ZC."}},"required":["id","source","headline","summary","url","imageUrl","publishedAt","tags","instruments"]},"NewsResponse":{"type":"object","description":"A page of news headlines.","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WireNewsItem"},"description":"The headlines, newest first."}},"required":["items"],"example":{"items":[{"id":"a3f8c2d94b1e6a07c5d2f8b3e9a1c4d7f0b6e2a8c1d5f9b4e7a0c3d6f2b8e5a1","source":"fxstreet","headline":"S&P 500 futures hold near highs as rate-cut bets firm","summary":"Equity index futures held near session highs on Monday.\n## The rates picture\nMarkets now price a September cut as the base case.\n• ES up 0.4% at 6,481\n• 10-year yield down 4bp","url":"https://www.fxstreet.com/news/example-article","imageUrl":"https://cdn.example.com/thumb.jpg","publishedAt":"2026-08-24T13:42:00.000Z","tags":["macro","stocks"],"instruments":["ES","NQ"]},{"id":"b7e1d4a92c8f5b3e6a0d7c2f9b4e1a8d5c0f3b6e9a2d7c4f1b8e5a0d3c6f9b2","source":"brownfield","headline":"Corn, soybeans firm ahead of USDA export sales","summary":"Grain futures traded higher in quiet overnight dealing.","url":"https://www.brownfieldagnews.com/news/example","imageUrl":null,"publishedAt":"2026-08-24T11:05:00.000Z","tags":["ag"],"instruments":["ZC","ZS"]}]}},"WireCalendarEvent":{"type":"object","description":"One scheduled economic release or market event.","properties":{"id":{"type":"string","description":"The event id."},"source":{"type":"string","description":"Where the event comes from."},"title":{"type":"string","description":"The event's name."},"country":{"type":"string","description":"The country, as an uppercase ISO country code."},"category":{"type":"string","description":"The kind of event."},"scheduledAt":{"type":"string","description":"When the event is scheduled, in ISO 8601."},"timeConfidence":{"type":"string","enum":["exact","date_only"],"description":"`date_only` means the source published a date but no reliable time of day, so show the time as TBA."},"impact":{"type":"string","enum":["high","medium","low"],"description":"How much the event is expected to move markets."},"forecast":{"type":["string","null"],"description":"The forecast, as a display string such as \"3.4%\". Units vary by release, and trdrs never parses them."},"previous":{"type":["string","null"],"description":"The previous reading, as a display string."},"actual":{"type":["string","null"],"description":"The actual reading, as a display string, or null until it is released."},"sourceUrl":{"type":["string","null"],"description":"The event on the source's site, or null."}},"required":["id","source","title","country","category","scheduledAt","timeConfidence","impact","forecast","previous","actual","sourceUrl"]},"CalendarResponse":{"type":"object","description":"Calendar events in time order.","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/WireCalendarEvent"},"description":"The events, earliest first."}},"required":["events"],"example":{"events":[{"id":"cal_9f2e7b4a","source":"fxstreet","title":"Core PCE Price Index (YoY)","country":"US","category":"inflation","scheduledAt":"2026-08-28T12:30:00.000Z","timeConfidence":"exact","impact":"high","forecast":"2.6%","previous":"2.7%","actual":null,"sourceUrl":"https://www.fxstreet.com/economic-calendar/event/example"},{"id":"cal_4c8d1a6e","source":"fxstreet","title":"Fed Beige Book","country":"US","category":"central-bank","scheduledAt":"2026-08-26T00:00:00.000Z","timeConfidence":"date_only","impact":"medium","forecast":null,"previous":null,"actual":null,"sourceUrl":null}]}},"AccountRow":{"type":"object","description":"One account you can trade. A money value that isn't known yet is null, never a made-up 0.","properties":{"accountId":{"type":"string","description":"The account's id, the same one the account snapshot and the `account` stream event carry. Key your panels and subscriptions by it, and treat it as opaque: never take it apart."},"provider":{"type":"string","description":"The provider the account is at. Pass it as `?provider=` on the trading and account routes."},"environment":{"type":"string","description":"The provider environment the account is in."},"accountNumber":{"type":"string","description":"The account number. Pass it as `?account=`."},"login":{"type":["string","null"],"description":"The login the account belongs to, as the trader knows it: the firm or system name for a Rithmic login (`Apex`, `Rithmic Paper Trading`). Null for a provider with one login and for a Demo. A trader may have several Rithmic logins, one per system."},"loginId":{"type":"string","description":"The login's key: the Rithmic system name, or `default` for a provider with one login."},"capabilities":{"type":"object","description":"What the provider supports on this account. See the account snapshot for the full list."},"firm":{"type":"object","description":"The firm that issued the account, for display. In the sandbox it appears before the firm has passed its self-check, and in production only once the firm is reviewed. It is display information only, never a route to trade through.","properties":{"id":{"type":"string","description":"The firm's id."},"name":{"type":"string","description":"The firm's name."},"logoUrl":{"type":["string","null"],"description":"The firm's logo, or null."},"logoBleed":{"type":"boolean","description":"True when the logo is meant to fill its frame edge to edge."}},"required":["id","name","logoUrl","logoBleed"]},"accountName":{"type":["string","null"],"description":"The account's display name, or null."},"status":{"type":"string","enum":["active","closed","unknown"],"description":"Whether the account is open."},"openPositions":{"type":"number","description":"How many positions are open."},"realizedPnl":{"type":["number","null"],"description":"Realized profit and loss, or null when it isn't known."},"unrealizedPnl":{"type":["number","null"],"description":"Unrealized profit and loss on open positions, or null when it isn't known."},"balance":{"type":["number","null"],"description":"The balance, or null when it isn't known."},"currency":{"type":"string","description":"The currency the account is held in."},"asOf":{"type":["number","null"],"description":"When these values were read, in epoch seconds, or null before the first reading."}},"required":["accountId","provider","accountNumber","capabilities","status"]},"AccountListResponse":{"type":"object","description":"Every account you can trade.","properties":{"accounts":{"type":"array","items":{"$ref":"#/components/schemas/AccountRow"},"description":"The accounts."}},"required":["accounts"],"example":{"accounts":[{"accountId":"7a1f4c93b28d05e6f1a3c7d9b4e28f60","provider":"rithmic","environment":"live","accountNumber":"PA-4821-07","login":"Apex","loginId":"Apex","capabilities":{"nativeBracket":true,"stopLimit":true,"multiTargetBracket":true,"nativeAutoBreakeven":false,"bracketLevelAmend":true,"exits":true},"accountName":"Apex 50K Eval","status":"active","openPositions":1,"realizedPnl":245.5,"unrealizedPnl":75,"balance":50245.5,"currency":"USD","asOf":1787581920}]}},"AccountInstrument":{"type":"object","description":"One symbol the account can trade.","properties":{"symbol":{"type":"string","description":"The exact string an order carries: a dated futures contract on the paper book (`CME:ESZ2026`), a futures product root at a provider that picks the contract itself (`ES`), or a crypto symbol prefixed with its provider (`HYPERLIQUID:BTC`)."},"name":{"type":"string","description":"The display name."},"exchange":{"type":"string","description":"The listing exchange for a future, or the provider's name for a crypto perpetual. An account a venue issued shows the venue's label."},"type":{"type":"string","enum":["future","crypto","equity","fx","metal","commodity","rates"],"description":"The asset class, using the same values symbol search returns, so a symbol picker can filter these rows and pick their icons the same way."},"root":{"type":"string","description":"For a dated futures contract only: the product root it belongs to, which a continuous chart symbol such as `ES1!` names (`ES`)."},"front":{"type":"boolean","description":"For a dated futures contract only: `true` when it is its root's front contract now, the contract a continuous chart symbol of the root trades. At most one listed contract of a root is the front one, and none is when the account doesn't list it."},"rollAt":{"type":"string","format":"date-time","description":"For a dated futures contract only: when it rolls. From then on the root's next contract is the front one, and an account whose risk policy closes a contract at its roll, such as your Demo, can only reduce a position in it."}},"required":["symbol","name","exchange","type"]},"AccountInstrumentsResponse":{"type":"object","description":"The symbols the account can trade through trdrs, with the label to show for the account.","properties":{"account":{"type":"string","description":"The account number the symbols are for."},"label":{"type":"string","description":"The label to show for the account: the firm or system name when trdrs has one (`Apex`), otherwise the account number."},"symbols":{"type":"array","items":{"$ref":"#/components/schemas/AccountInstrument"},"description":"The symbols the account can trade."}},"required":["account","label","symbols"],"example":{"account":"DEMO-3F9A1C","label":"DEMO-3F9A1C","symbols":[{"symbol":"CME:ESZ2026","name":"E-mini S&P 500 Dec 2026","exchange":"CME","type":"future","root":"ES","front":true,"rollAt":"2026-12-09T23:00:00.000Z"},{"symbol":"CME:ESH2027","name":"E-mini S&P 500 Mar 2027","exchange":"CME","type":"future","root":"ES","front":false,"rollAt":"2027-03-10T23:00:00.000Z"},{"symbol":"HYPERLIQUID:BTC","name":"Bitcoin perpetual","exchange":"Hyperliquid","type":"crypto"}]}},"RiskSettings":{"type":"object","description":"The five risk controls on one account: four loss and profit limits in the account's currency, and an end-of-day close in whole minutes before the 16:00 CT session close. A control that is on always has a positive value, and one that is off reads null.","properties":{"provider":{"type":"string","description":"The provider the account is at."},"accountNumber":{"type":"string","description":"The account number."},"dailyLossEnabled":{"type":"boolean","description":"Whether the daily loss limit is on."},"dailyLossValue":{"type":["number","null"],"description":"When the session is down this much, positions close and trading locks for the day."},"weeklyLossEnabled":{"type":"boolean","description":"Whether the weekly loss limit is on."},"weeklyLossValue":{"type":["number","null"],"description":"When the week is down this much, positions close and trading locks for the week."},"dailyProfitEnabled":{"type":"boolean","description":"Whether the daily profit cap is on."},"dailyProfitValue":{"type":["number","null"],"description":"When the session is up this much, positions close and trading locks for the day."},"weeklyProfitEnabled":{"type":"boolean","description":"Whether the weekly profit cap is on."},"weeklyProfitValue":{"type":["number","null"],"description":"When the week is up this much, positions close and trading locks for the week."},"eodCloseEnabled":{"type":"boolean","description":"Whether the end-of-day close is on."},"eodCloseValue":{"type":["number","null"],"description":"Whole minutes before the 16:00 CT close, from 1 to 240. At that time every position closes and trading locks until the 17:00 CT reopen. It goes by the clock, so it fires even when profit and loss can't be read."},"lockSettingsWhenTradingLocked":{"type":"boolean","description":"When a control locks trading, also lock these settings until 16:00 CT, so the lock can't be undone partway through the period. It is turned off automatically while no control is on."},"updatedAt":{"type":"number","description":"When the controls were last changed, in epoch seconds."}},"required":["provider","accountNumber","dailyLossEnabled","dailyLossValue","weeklyLossEnabled","weeklyLossValue","dailyProfitEnabled","dailyProfitValue","weeklyProfitEnabled","weeklyProfitValue","eodCloseEnabled","eodCloseValue","lockSettingsWhenTradingLocked","updatedAt"]},"RiskLock":{"type":"object","description":"Whether the account is locked, why, and when it unlocks. While `tradingLocked` is true, every route that places an order refuses with 423 `risk_locked`. While `settingsLocked` is true, you can't edit the controls or unlock by hand until `settingsUnlockAt`.","properties":{"provider":{"type":"string","description":"The provider the account is at."},"accountNumber":{"type":"string","description":"The account number."},"tradingLocked":{"type":"boolean","description":"True while trading is locked. Every route that places an order checks it and refuses while it is true."},"settingsLocked":{"type":"boolean","description":"True while the \"lock settings when trading is locked\" choice keeps the controls shut, until 16:00 CT."},"lockReason":{"type":["string","null"],"enum":["daily_loss","weekly_loss","daily_profit","weekly_profit","eod_close","eval_breach","firm_halt","max_drawdown","daily_drawdown","margin_stop_out",null],"description":"Which control locked the account, or null while it can trade. `eval_breach` is a failed prop evaluation. `firm_halt` is the firm halting the account, which lasts until the firm resumes it. `max_drawdown` and `daily_drawdown` are the venue's stage drawdown rule breached on an account it issued, which last like `eval_breach`. You can't unlock any of these three by hand. `margin_stop_out` is a margin stop-out on the paper book. It holds until the account is covered again and its risk is resolved, and you can't unlock it by hand either."},"lockWindow":{"type":["string","null"],"enum":["daily","weekly",null],"description":"The period the lock belongs to. A daily lock ends at the next 17:00 CT reopen, and a weekly lock at 17:00 CT on Sunday."},"tradingUnlockAt":{"type":["number","null"],"description":"When trading unlocks by itself, in epoch seconds, or null when there is no lock or the lock has no set end."},"settingsUnlockAt":{"type":["number","null"],"description":"When the settings unlock (16:00 CT), in epoch seconds, or null."},"triggerPnl":{"type":["number","null"],"description":"The net profit and loss that set off the lock, or null."},"flattenConfirmed":{"type":"boolean","description":"True once the account has been seen flat after the lock. Until then the lock holds while trdrs keeps closing whatever position remains."},"monitoring":{"type":"string","enum":["live","paused"],"description":"`paused` means profit and loss can't be read right now, so no new control can fire. Existing locks still hold. It is never a silent all-clear."},"clearable":{"type":"boolean","description":"Whether `POST /api/risk/unlock` would clear the lock now. It's false while the settings are locked, for a failed evaluation, a firm halt or a drawdown rule, and for any lock that holds trading on an account bound to a risk policy. It's true while nothing is locked. Offer the trader a way to clear the lock only while `tradingLocked` and `clearable` are both true."},"settings":{"$ref":"#/components/schemas/RiskSettings","description":"The account's controls."}},"required":["provider","accountNumber","tradingLocked","settingsLocked","lockReason","lockWindow","tradingUnlockAt","settingsUnlockAt","triggerPnl","flattenConfirmed","monitoring","clearable","settings"]},"RiskStateResponse":{"type":"object","description":"The account's risk controls as stored, whether it is locked now, and, on an account bound to a risk policy, every limit set on it by anyone.","properties":{"settings":{"$ref":"#/components/schemas/RiskSettings","description":"Your controls, as stored."},"lock":{"$ref":"#/components/schemas/RiskLock","description":"Whether the account is locked now."},"limits":{"type":["object","null"],"description":"Every limit on an account bound to a risk policy, read-only. `inForce` is the version the account is held to now, and `next` is a version recorded since, which takes effect at the next session day. Null on an account that only your controls bind.","properties":{"inForce":{"oneOf":[{"$ref":"#/components/schemas/RiskLimitsVersion"},{"type":"null"}],"description":"The version in force now, or null."},"next":{"oneOf":[{"$ref":"#/components/schemas/RiskLimitsVersion"},{"type":"null"}],"description":"The version that takes effect at the next session day, or null."}},"required":["inForce","next"]}},"required":["settings","lock","limits"],"example":{"settings":{"provider":"rithmic","accountNumber":"PA-4821-07","dailyLossEnabled":true,"dailyLossValue":1000,"weeklyLossEnabled":false,"weeklyLossValue":null,"dailyProfitEnabled":false,"dailyProfitValue":null,"weeklyProfitEnabled":false,"weeklyProfitValue":null,"eodCloseEnabled":true,"eodCloseValue":15,"lockSettingsWhenTradingLocked":true,"updatedAt":1787581500},"lock":{"provider":"rithmic","accountNumber":"PA-4821-07","tradingLocked":false,"settingsLocked":false,"lockReason":null,"lockWindow":null,"tradingUnlockAt":null,"settingsUnlockAt":null,"triggerPnl":null,"flattenConfirmed":false,"monitoring":"live","clearable":true,"settings":{"provider":"rithmic","accountNumber":"PA-4821-07","dailyLossEnabled":true,"dailyLossValue":1000,"weeklyLossEnabled":false,"weeklyLossValue":null,"dailyProfitEnabled":false,"dailyProfitValue":null,"weeklyProfitEnabled":false,"weeklyProfitValue":null,"eodCloseEnabled":true,"eodCloseValue":15,"lockSettingsWhenTradingLocked":true,"updatedAt":1787581500}},"limits":{"inForce":{"version":"4f1c0e9a7b2d6e31a8c5f0d2b9e7a614","terms":[{"rule":"daily_loss","authority":"trader","amount":"1000"},{"rule":"daily_loss","authority":"firm","amount":"2500"}],"endOfDay":{"authority":"trader","minutesBeforeClose":15},"session":{"timeZone":"America/Chicago","rolloverHour":17}},"next":null}}},"RiskLimitsVersion":{"type":"object","description":"One version of the limits an account is held to, read-only: every limit with who sets it, the end-of-day close with who sets it, and the session the day and week are counted in. You change only your own limits, through the risk controls.","properties":{"version":{"type":"string","description":"The version id."},"terms":{"type":"array","description":"The loss and profit limits.","items":{"type":"object","properties":{"rule":{"type":"string","enum":["daily_loss","weekly_loss","daily_profit","weekly_profit"],"description":"Which limit this is."},"authority":{"type":"string","enum":["trader","firm","venue"],"description":"Who sets the limit: you, the firm that issued the account, or its venue. Every one of them applies at once."},"amount":{"type":"string","description":"The limit, as an exact decimal string in the account's currency."}},"required":["rule","authority","amount"]}},"endOfDay":{"type":["object","null"],"description":"The end-of-day close, or null when there is none.","properties":{"authority":{"type":"string","enum":["trader","firm","venue"],"description":"Who sets the limit: you, the firm that issued the account, or its venue. Every one of them applies at once."},"minutesBeforeClose":{"type":"integer","description":"How many minutes before the session close positions close."}},"required":["authority","minutesBeforeClose"]},"session":{"type":"object","description":"The session the day and week are counted in.","properties":{"timeZone":{"type":"string","description":"The IANA time zone."},"rolloverHour":{"type":"integer","description":"The hour the trading day starts, in that time zone."}},"required":["timeZone","rolloverHour"]}},"required":["version","terms","endOfDay","session"]},"RiskSettingsRequest":{"type":"object","description":"All of the account's controls, replaced in one write. A control that is on needs a positive value in range: loss and profit limits in the account's currency, and the end-of-day close in whole minutes from 1 to 240. A control that is off has its value ignored and stored as null. `lockSettingsWhenTradingLocked` is turned off when no control is on.","properties":{"dailyLossEnabled":{"type":"boolean","description":"Turn the daily loss limit on or off."},"dailyLossValue":{"type":["number","null"],"description":"The daily loss limit, in the account's currency."},"weeklyLossEnabled":{"type":"boolean","description":"Turn the weekly loss limit on or off."},"weeklyLossValue":{"type":["number","null"],"description":"The weekly loss limit, in the account's currency."},"dailyProfitEnabled":{"type":"boolean","description":"Turn the daily profit cap on or off."},"dailyProfitValue":{"type":["number","null"],"description":"The daily profit cap, in the account's currency."},"weeklyProfitEnabled":{"type":"boolean","description":"Turn the weekly profit cap on or off."},"weeklyProfitValue":{"type":["number","null"],"description":"The weekly profit cap, in the account's currency."},"eodCloseEnabled":{"type":"boolean","description":"Turn the end-of-day close on or off."},"eodCloseValue":{"type":["number","null"],"description":"Whole minutes before the 16:00 CT close, from 1 to 240."},"lockSettingsWhenTradingLocked":{"type":"boolean","description":"Also lock these settings until 16:00 CT whenever a control locks trading."}},"example":{"dailyLossEnabled":true,"dailyLossValue":1000,"weeklyLossEnabled":false,"weeklyLossValue":null,"dailyProfitEnabled":false,"dailyProfitValue":null,"weeklyProfitEnabled":false,"weeklyProfitValue":null,"eodCloseEnabled":true,"eodCloseValue":15,"lockSettingsWhenTradingLocked":true}},"RiskUnlockResponse":{"type":"object","description":"The account's lock state after the unlock.","properties":{"lock":{"$ref":"#/components/schemas/RiskLock","description":"The lock state now."}},"required":["lock"],"example":{"lock":{"provider":"rithmic","accountNumber":"PA-4821-07","tradingLocked":false,"settingsLocked":false,"lockReason":null,"lockWindow":null,"tradingUnlockAt":null,"settingsUnlockAt":null,"triggerPnl":null,"flattenConfirmed":false,"monitoring":"live","clearable":true,"settings":{"provider":"rithmic","accountNumber":"PA-4821-07","dailyLossEnabled":true,"dailyLossValue":1000,"weeklyLossEnabled":false,"weeklyLossValue":null,"dailyProfitEnabled":false,"dailyProfitValue":null,"weeklyProfitEnabled":false,"weeklyProfitValue":null,"eodCloseEnabled":true,"eodCloseValue":15,"lockSettingsWhenTradingLocked":true,"updatedAt":1787581500}}}},"AccountSummary":{"type":"object","description":"The account's balance, profit and loss, and buying power. A value that isn't known yet is null, never a made-up 0.","properties":{"provider":{"type":"string","description":"The provider the account is at."},"accountNumber":{"type":"string","description":"The account number."},"balance":{"type":["number","null"],"description":"The balance."},"realizedPnl":{"type":["number","null"],"description":"Realized profit and loss."},"unrealizedPnl":{"type":["number","null"],"description":"Unrealized profit and loss on open positions."},"netLiquidating":{"type":["number","null"],"description":"What the account would be worth if every position closed now."},"availableBuyingPower":{"type":["number","null"],"description":"Buying power for new positions, as the provider reports and enforces it. It is the real basis of margin and leverage (leverage is netLiquidating divided by marginRequired). Always null on a paper book account, including a Demo, because the paper book doesn't report a buying power figure here: its `balance` is only the balance. The paper book still checks margin. It refuses an order whose margin doesn't fit the account's free collateral under its risk policy, and `POST /api/trading/margin-preview` tells you beforehand whether an order fits."},"usedBuyingPower":{"type":["number","null"],"description":"Buying power in use by open positions and working orders."},"marginBalance":{"type":["number","null"],"description":"The provider's margin balance: the equity it counts toward margin."},"currency":{"type":"string","description":"The currency the account is held in."},"asOf":{"type":["number","null"],"description":"When these values were read, in epoch seconds, or null until the provider's first reading."}},"required":["provider","accountNumber","currency"],"example":{"provider":"rithmic","accountNumber":"PA-4821-07","balance":50245.5,"realizedPnl":245.5,"unrealizedPnl":75,"netLiquidating":50320.5,"availableBuyingPower":47120.5,"usedBuyingPower":3200,"marginBalance":null,"currency":"USD","asOf":1787581920}},"AccountCapabilities":{"type":"object","description":"What the provider behind this account supports, so your interface offers only what will work instead of a control the provider will refuse. Every flag describes something trdrs has built and checked against the provider, and anything unchecked is false and refused. This is not permission: whether the account may trade right now is the risk lock, sent on the stream's `lock` event.","properties":{"provider":{"type":"string","description":"The name of the provider integration behind the account, for your logs."},"assetClasses":{"type":"array","items":{"type":"string"},"description":"The asset classes the provider may ever trade here. Empty means none."},"orderTypes":{"type":"array","items":{"type":"string","enum":["market","limit","stop","stop_limit"]},"description":"The order types the provider accepts."},"tifs":{"type":"array","items":{"type":"string","enum":["day","gtc","ioc","fok","post_only"]},"description":"The times in force the provider supports. Any other is refused, never quietly changed to a different one."},"nativeBracket":{"type":"boolean","description":"True when the provider holds a bracket (an entry with its stop and target) itself."},"multiTargetBracket":{"type":"boolean","description":"True when a bracket can have more than one target."},"nativeAutoBreakeven":{"type":"boolean","description":"True when the provider moves the stop to breakeven itself."},"bracketLevelAmend":{"type":"boolean","description":"True when a bracket's stop and target prices can be changed in place."},"amendOrder":{"type":"boolean","description":"True when a resting order can be changed in place, keeping its identity at the provider. False means trdrs cancels it and places a new one, which gets a new identity."},"reduceOnly":{"type":"boolean","description":"True when the provider enforces reduce-only orders."},"exits":{"type":"boolean","description":"True when you can set a position's stop and target with `POST /api/trading/exits`."},"symbolConfig":{"type":"boolean","description":"True when leverage can be read and set with `/api/trading/symbol-config`."},"marginPreview":{"type":"string","enum":["real","estimate","none"],"description":"`real` when the provider computes the margin preview, `estimate` when trdrs estimates it, and `none` when there is no preview."},"updates":{"type":"object","description":"Which parts of the account the provider pushes as they change. A part it doesn't push is refreshed on trdrs's regular polling instead.","properties":{"summary":{"type":"boolean","description":"Balance and profit and loss."},"positions":{"type":"boolean","description":"Positions."},"orders":{"type":"boolean","description":"Working orders."},"executions":{"type":"boolean","description":"Fills."},"push":{"type":"boolean","description":"True when the provider pushes updates at all."}},"required":["summary","positions","orders","executions","push"]},"instrumentFacts":{"type":"object","description":"Which facts the provider gives about each instrument. When an order needs a check the provider can't answer, the order is refused rather than guessed.","properties":{"priceIncrement":{"type":"boolean","description":"The price increment."},"quantityStep":{"type":"boolean","description":"The quantity step."},"quantityBounds":{"type":"boolean","description":"The smallest and largest quantity."},"contractMultiplier":{"type":"boolean","description":"The contract multiplier."}},"required":["priceIncrement","quantityStep","quantityBounds","contractMultiplier"]},"exitPlanSupport":{"type":"array","items":{"type":"string","enum":["stop_loss","take_profit","multiple_targets","runner_leg","breakeven","trailing_stop"]},"description":"Which parts of a saved exit plan this account can actually run, worked out from the flags beside it. Compare it with a plan's own `requires` to offer only the plans that will work."},"completeOrderBook":{"type":"boolean","description":"True when the order history can say whether a `clientOrderId` was ever accepted, across the account's whole history."}},"required":["provider","assetClasses","orderTypes","tifs","nativeBracket","multiTargetBracket","nativeAutoBreakeven","bracketLevelAmend","amendOrder","reduceOnly","exits","symbolConfig","marginPreview","updates","instrumentFacts","exitPlanSupport","completeOrderBook"]},"AccountSnapshot":{"type":"object","description":"The whole account at one revision: its summary, positions, working orders, protection and capabilities. `GET /api/account/snapshot` returns it, and every `account` event on the stream carries the same shape. Apply frames by `revision` alone: keep the newest one you have for the `accountId`, drop any at or behind it, and replace your whole picture with any ahead of it.","properties":{"accountId":{"type":"string","description":"The account's id. It is opaque: key your panels and subscriptions by it, and never take it apart."},"revision":{"type":"integer","description":"The account's revision. A frame that skips revisions is still complete, so there is nothing to catch up on and nothing to resync. Never work out a revision of your own."},"clock":{"type":"string","enum":["engine","observation"],"description":"What the revision counts. `engine` is the account's own history on trdrs. `observation` is trdrs reading a provider: every reading gets a new revision, so two reads of an account nothing happened to still differ. Compare revisions, never count them."},"cycle":{"type":["integer","null"],"description":"The paper book account's cycle, read with its rows. A reset starts a new cycle, so a frame from an earlier cycle describes an account that no longer exists, and nothing held from it applies. Null on a provider account, and on some older Demo accounts, whose reads carry no cycle."},"positionModel":{"type":"string","enum":["net","independent_tickets"],"description":"How the account holds positions. On `net` there is at most one signed position row per instrument, except on a provider account in hedge mode, which shows the rows its provider reports beside an `accountMode` refusal and sends no order. On `independent_tickets` every open ticket is its own row with its `positionId`, and its exits are the reduce-only orders that name that id."},"capabilities":{"$ref":"#/components/schemas/AccountCapabilities","description":"What the provider behind the account supports."},"connected":{"type":"boolean","description":"True while trdrs's connection to the provider is live. False means this is the last picture trdrs has, which you must be able to tell apart from an account that is flat."},"account":{"$ref":"#/components/schemas/AccountSummary","description":"Balance, profit and loss, and buying power."},"positions":{"type":"array","items":{"$ref":"#/components/schemas/PositionRow"},"description":"The open positions."},"orders":{"type":"array","items":{"$ref":"#/components/schemas/WorkingOrderRow"},"description":"The working orders."},"brackets":{"type":"array","items":{"$ref":"#/components/schemas/AccountBracket"},"description":"The protection around the account's positions: every bracket, with its legs and their states."},"managedExits":{"type":"array","items":{"$ref":"#/components/schemas/ManagedExit"},"description":"The stops trdrs manages on the account's behalf."},"accountMode":{"oneOf":[{"$ref":"#/components/schemas/AccountMode"},{"type":"null"}],"description":"The account settings a crypto provider reported on this reading, and whether trdrs can trade under them. Null for every other account."}},"required":["accountId","revision","clock","cycle","positionModel","capabilities","connected","account","positions","orders","brackets","managedExits","accountMode"],"example":{"accountId":"7a1f4c93b28d05e6f1a3c7d9b4e28f60","revision":4831,"clock":"observation","cycle":null,"positionModel":"net","capabilities":{"provider":"rithmic","assetClasses":["futures"],"orderTypes":["market","limit","stop","stop_limit"],"tifs":["day","gtc"],"nativeBracket":true,"multiTargetBracket":true,"nativeAutoBreakeven":false,"bracketLevelAmend":true,"amendOrder":true,"reduceOnly":false,"exits":true,"symbolConfig":false,"marginPreview":"estimate","updates":{"summary":true,"positions":true,"orders":true,"executions":false,"push":true},"instrumentFacts":{"priceIncrement":true,"quantityStep":true,"quantityBounds":false,"contractMultiplier":true},"exitPlanSupport":["stop_loss","take_profit","multiple_targets","runner_leg","breakeven","trailing_stop"],"completeOrderBook":false},"connected":true,"account":{"provider":"rithmic","accountNumber":"PA-4821-07","balance":50245.5,"realizedPnl":245.5,"unrealizedPnl":75,"netLiquidating":50320.5,"availableBuyingPower":47120.5,"usedBuyingPower":3200,"marginBalance":null,"currency":"USD","asOf":1787581920},"positions":[{"instrument":"ESU6","root":"ES","positionId":null,"positionRevision":null,"qty":2,"avgPrice":6480.5,"unrealizedPnl":75,"liquidationPrice":null,"leverage":null,"margin":null}],"orders":[{"providerOrderId":"234992187","instrument":"ESU6","side":"sell","qty":2,"orderType":"limit","triggerPrice":null,"limitPrice":6492.25,"status":"working","clientOrderId":"a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d","submittedAt":1787581400,"tif":"gtc","reduceOnly":true}],"accountMode":null}},"AccountMode":{"type":"object","description":"The account settings a crypto provider reported. trdrs reads them when the account connects and on every reading, and never changes them. Binance trades USDT linear perpetuals in one-way position mode and single-asset mode. Bybit trades USDT linear perpetuals on a unified trading account, in cross or isolated margin, one-way per symbol. Hyperliquid trades USDC linear perpetuals on a standard account, each asset in cross or isolated margin.","properties":{"provider":{"type":"string","description":"The provider."},"product":{"type":"string","enum":["usdt_linear_perpetual","usdc_linear_perpetual"],"description":"The product trdrs trades at this provider."},"status":{"type":"string","enum":["supported","unsupported","unknown"],"description":"`supported` when every setting read is supported, `unsupported` when a setting is refused, and `unknown` when a setting that must be read couldn't be."},"settings":{"type":"array","items":{"$ref":"#/components/schemas/AccountModeSetting"},"description":"Every setting read."},"refusals":{"type":"array","items":{"$ref":"#/components/schemas/AccountModeRefusal"},"description":"What is refused. A refusal for the whole account (`instrument` null) refuses every order before anything is sent, and a refusal for one instrument refuses orders on that instrument."},"checkedAt":{"type":"integer","description":"When the settings were read, in epoch seconds."}},"required":["provider","product","status","settings","refusals","checkedAt"]},"AccountModeSetting":{"type":"object","description":"One account setting the provider reports.","properties":{"setting":{"type":"string","enum":["position_mode","asset_mode","account_type","margin_mode","account_abstraction"],"description":"Which setting this is."},"value":{"type":"string","description":"The setting's value: a fixed token for a documented value, and the provider's own string for anything else. `position_mode` is 'one_way' or 'hedge'. `asset_mode` is 'single_asset' or 'multi_assets'. `account_type` is 'classic', 'unified_1', 'unified_1_pro', 'unified_2' or 'unified_2_pro'. `margin_mode` is 'cross', 'isolated' or 'portfolio'. `account_abstraction` is 'standard', 'default', 'unified_account', 'portfolio_margin' or 'dex_abstraction'."},"instrument":{"type":["string","null"],"description":"The instrument the setting applies to, or null for the whole account."},"supported":{"type":"boolean","description":"True when trdrs trades with this value."}},"required":["setting","value","instrument","supported"]},"AccountModeRefusal":{"type":"object","description":"Why the account, or one instrument on it, can't trade on trdrs, as a refusal code with its details. An order, exit, close or flatten on it is refused with the same code and details. Translate by code, and show a generic message for a code you don't recognize.","properties":{"code":{"type":"string","enum":["mode_unreadable","mode_unrecognized","hedge_position_mode","multi_assets_mode","classic_account","portfolio_margin","unified_account","unverified_account_abstraction"],"description":"The refusal code."},"params":{"type":"object","description":"What you need to explain the refusal in your own words. The provider's own string is never repeated.","properties":{"provider":{"type":"string","description":"The provider."},"instrument":{"type":["string","null"],"description":"The instrument, or null for the whole account."},"setting":{"type":"string","enum":["position_mode","asset_mode","account_type","margin_mode","account_abstraction"],"description":"The setting that is refused."},"reported":{"type":["string","null"],"description":"The value the provider reported, as a fixed token, or null when it couldn't be read or isn't documented."},"supported":{"type":"array","items":{"type":"string"},"description":"The values trdrs trades with for this setting."}},"required":["provider","instrument","setting","reported","supported"]},"message":{"type":"string","description":"The refusal as an English sentence."},"instrument":{"type":["string","null"],"description":"The instrument refused, or null when the whole account is refused."}},"required":["code","params","message","instrument"]},"AccountBracket":{"type":"object","description":"The protection around one position, as trdrs records it: the entry, its stop and its targets.","properties":{"id":{"type":"string","description":"The bracket's id."},"accountId":{"type":"string","description":"The account's id."},"instrument":{"type":"string","description":"The instrument."},"side":{"type":"string","enum":["buy","sell"],"description":"The entry's side. The stop and target are always the opposite side."},"state":{"type":"string","enum":["pending_entry","active","completed","cancelled","failed"],"description":"`failed` is final and never quiet: the entry filled but the protection couldn't be put in place, and `endReason` says what happened."},"clientOrderId":{"type":"string","description":"The entry order's `clientOrderId`."},"entryOrderId":{"type":["string","null"],"description":"The entry order's id at the provider, or null."},"qty":{"type":"number","description":"The bracket's quantity."},"filledQty":{"type":"number","description":"How much of the entry has filled."},"legs":{"type":"array","items":{"$ref":"#/components/schemas/AccountBracketLeg"},"description":"The legs."},"endReason":{"type":["string","null"],"description":"Why the bracket ended, or null while it is open."},"createdAt":{"type":"integer","description":"When the bracket was created, in epoch milliseconds."},"updatedAt":{"type":"integer","description":"When it last changed, in epoch milliseconds."}},"required":["id","accountId","instrument","side","state","clientOrderId","qty","filledQty","legs","createdAt","updatedAt"],"example":{"id":"b41e7d2a-9c58-4f03-a6b1-2e8d5c7f0a94","accountId":"7a1f4c93b28d05e6f1a3c7d9b4e28f60","instrument":"ESU6","side":"buy","state":"pending_entry","clientOrderId":"a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d","entryOrderId":"234992187","qty":2,"filledQty":0,"legs":[{"id":"3c9a0f61-52d4-4b78-8e15-7f6b2a4d0c83","role":"stop","seq":1,"qty":1,"filledQty":0,"state":"pre_armed","providerOrderId":null,"ocoGroup":"a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d:oco","triggerPrice":6477.5,"limitPrice":null,"parentOrderId":"234992187","parentInstrument":"ESU6","rejectReason":null},{"id":"5e7d1b04-8a26-4c39-9f52-1d0c6b8e3a75","role":"target","seq":1,"qty":1,"filledQty":0,"state":"pre_armed","providerOrderId":null,"ocoGroup":"a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d:oco","triggerPrice":null,"limitPrice":6485.5,"parentOrderId":"234992187","parentInstrument":"ESU6","rejectReason":null}],"endReason":null,"createdAt":1787581400000,"updatedAt":1787581400000}},"AccountBracketLeg":{"type":"object","description":"One leg of a bracket, as trdrs records it.","properties":{"id":{"type":"string","description":"The leg's id."},"role":{"type":"string","enum":["entry","stop","target"],"description":"What the leg does."},"seq":{"type":"integer","description":"The leg's sequence number within the bracket."},"qty":{"type":"number","description":"The leg's quantity."},"filledQty":{"type":"number","description":"How much of the leg has filled."},"state":{"type":"string","enum":["pre_armed","working","filled","cancelled","rejected"],"description":"`pre_armed` is a leg trdrs has priced and recorded but is deliberately not resting yet, because the position it protects doesn't exist yet."},"providerOrderId":{"type":["string","null"],"description":"The order id at the provider once the leg is resting there, or null while it is pre-armed."},"ocoGroup":{"type":["string","null"],"description":"The one-cancels-other group the leg belongs to, or null."},"triggerPrice":{"type":["number","null"],"description":"The stop trigger price, or null."},"limitPrice":{"type":["number","null"],"description":"The limit price, or null."},"parentOrderId":{"type":["string","null"],"description":"The entry order a pre-armed leg hangs from. Once the entry fills, the leg protects the position and this is null, so never key a leg by its parent order."},"parentInstrument":{"type":"string","description":"The instrument of the position or order the leg belongs to."},"rejectReason":{"type":["string","null"],"description":"Why the leg was rejected, or null."}},"required":["id","role","seq","qty","filledQty","state","parentInstrument"],"example":{"id":"3c9a0f61-52d4-4b78-8e15-7f6b2a4d0c83","role":"stop","seq":1,"qty":1,"filledQty":0,"state":"pre_armed","providerOrderId":null,"ocoGroup":"a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d:oco","triggerPrice":6477.5,"limitPrice":null,"parentOrderId":"234992187","parentInstrument":"ESU6","rejectReason":null}},"BracketsResponse":{"type":"object","description":"The account's brackets and the revision they were read at.","properties":{"revision":{"type":"integer","description":"The account revision these rows were read at. This read only looks at the current revision and never advances it."},"items":{"type":"array","items":{"$ref":"#/components/schemas/AccountBracket"},"description":"The brackets."}},"required":["revision","items"],"example":{"revision":412,"items":[{"id":"b41e7d2a-9c58-4f03-a6b1-2e8d5c7f0a94","accountId":"7a1f4c93b28d05e6f1a3c7d9b4e28f60","instrument":"ESU6","side":"buy","state":"pending_entry","clientOrderId":"a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d","entryOrderId":"234992187","qty":2,"filledQty":0,"legs":[{"id":"3c9a0f61-52d4-4b78-8e15-7f6b2a4d0c83","role":"stop","seq":1,"qty":1,"filledQty":0,"state":"pre_armed","providerOrderId":null,"ocoGroup":"a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d:oco","triggerPrice":6477.5,"limitPrice":null,"parentOrderId":"234992187","parentInstrument":"ESU6","rejectReason":null},{"id":"5e7d1b04-8a26-4c39-9f52-1d0c6b8e3a75","role":"target","seq":1,"qty":1,"filledQty":0,"state":"pre_armed","providerOrderId":null,"ocoGroup":"a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d:oco","triggerPrice":null,"limitPrice":6485.5,"parentOrderId":"234992187","parentInstrument":"ESU6","rejectReason":null}],"endReason":null,"createdAt":1787581400000,"updatedAt":1787581400000}]}},"ManagedExit":{"type":"object","description":"One exit trdrs is managing for you, such as a move of the stop to breakeven, a trailing stop, or both.","properties":{"id":{"type":"string","description":"The managed exit's id."},"accountId":{"type":"string","description":"The account's id."},"bracketId":{"type":["string","null"],"description":"The bracket it manages, or null."},"planId":{"type":["string","null"],"description":"The saved exit plan it came from, or null."},"planRevision":{"type":["string","null"],"description":"The revision of the plan it runs, or null. The plan was copied at that revision when the exit started, so editing the saved plan never changes an exit that is already running."},"instrument":{"type":"string","description":"The instrument."},"side":{"type":"string","enum":["buy","sell"],"description":"The entry's side."},"state":{"type":"string","enum":["pending","managing","paused","completed","cancelled","failed"],"description":"`paused` means nothing is moving the stop right now, not that it failed: the last stop the market accepted is still resting there, and `pauseReason` says why it isn't moving."},"phase":{"type":"string","enum":["awaiting_entry","protecting","breakeven","trailing","done"],"description":"What the exit is doing now."},"actionable":{"type":"boolean","description":"True when your interface may offer an action on it."},"stopLevel":{"type":["number","null"],"description":"The current stop price, or null."},"targetLevels":{"type":"array","items":{"type":"number"},"description":"The target prices."},"relatedOrderIds":{"type":"array","items":{"type":"string"},"description":"The orders that make up the exit."},"pauseReason":{"type":["string","null"],"enum":["venue_disconnected","no_price_feed","no_instrument_facts","unsupported_shape","account_locked",null],"description":"Why the exit is paused, or null."},"failureReason":{"type":["string","null"],"description":"Why the exit failed, or null."},"asOfRevision":{"type":"integer","description":"The account revision this record was read at."}},"required":["id","accountId","instrument","side","state","phase","actionable","targetLevels","relatedOrderIds","asOfRevision"],"example":{"id":"9d2b6a30-4e17-4c85-b0f3-6a1c8e5d7204","accountId":"7a1f4c93b28d05e6f1a3c7d9b4e28f60","bracketId":"b41e7d2a-9c58-4f03-a6b1-2e8d5c7f0a94","planId":"0f6c2d18-7b4a-4a3e-9d21-8c5e4b0a9f37","planRevision":"q2Jm4XxT0aVnR7cLp1sZfE9d","instrument":"ESU6","side":"buy","state":"pending","phase":"awaiting_entry","actionable":true,"stopLevel":null,"targetLevels":[6485.5],"relatedOrderIds":["234992187"],"pauseReason":null,"failureReason":null,"asOfRevision":4831}},"ManagedExitsResponse":{"type":"object","description":"The exits trdrs is managing on the account, and the revision they were read at.","properties":{"revision":{"type":"integer","description":"The account revision these rows were read at. This read only looks at the current revision and never advances it."},"items":{"type":"array","items":{"$ref":"#/components/schemas/ManagedExit"},"description":"The managed exits."}},"required":["revision","items"],"example":{"revision":412,"items":[{"id":"9d2b6a30-4e17-4c85-b0f3-6a1c8e5d7204","accountId":"7a1f4c93b28d05e6f1a3c7d9b4e28f60","bracketId":"b41e7d2a-9c58-4f03-a6b1-2e8d5c7f0a94","planId":"0f6c2d18-7b4a-4a3e-9d21-8c5e4b0a9f37","planRevision":"q2Jm4XxT0aVnR7cLp1sZfE9d","instrument":"ESU6","side":"buy","state":"pending","phase":"awaiting_entry","actionable":true,"stopLevel":null,"targetLevels":[6485.5],"relatedOrderIds":["234992187"],"pauseReason":null,"failureReason":null,"asOfRevision":4831}]}},"ExitPlanTrailStep":{"type":"object","description":"One tier of a trailing stop. Once the position is `triggerDistance` in profit, the stop follows the best price at `trailDistance` behind it, and moves only after the price has advanced a whole `frequencyTicks`. Tiers go up by trigger distance and can only tighten the stop.","properties":{"stepSeq":{"type":"integer","description":"The tier's order in the list."},"triggerDistance":{"type":"number","description":"How far in profit the position must be before this tier starts, in the plan's `unit`."},"trailDistance":{"type":"number","description":"How far behind the best price the stop follows, in the plan's `unit`."},"frequencyTicks":{"type":"integer","description":"How far the price must advance before the stop moves, always in whole ticks whatever the plan's `unit`, because it limits how often trdrs calls the provider."}},"required":["stepSeq","triggerDistance","trailDistance","frequencyTicks"],"example":{"stepSeq":1,"triggerDistance":16,"trailDistance":8,"frequencyTicks":2}},"ExitPlanBreakeven":{"type":"object","description":"A one-time move of the stop to the entry price plus `plusDistance`, once the position is `triggerDistance` in profit.","properties":{"triggerDistance":{"type":"number","description":"How far in profit the position must be, in the plan's `unit`."},"plusDistance":{"type":"number","description":"How far beyond the entry price the stop goes, in the plan's `unit`. Zero is exact breakeven."}},"required":["triggerDistance","plusDistance"],"example":{"triggerDistance":8,"plusDistance":0}},"ExitPlanLeg":{"type":"object","description":"One rung of the plan's ladder. Every leg has a stop, because a plan can't save an unprotected rung. A leg with no `targetDistance` is a runner, held with a stop and nothing else, and a plan has at most one.","properties":{"seq":{"type":"integer","description":"The leg's order in the ladder."},"quantity":{"type":"number","description":"The quantity this leg covers."},"stopDistance":{"type":"number","description":"How far from the entry the stop sits, in the plan's `unit`."},"targetDistance":{"type":["number","null"],"description":"How far from the entry the target sits, in the plan's `unit`, or null for a runner."},"breakeven":{"oneOf":[{"$ref":"#/components/schemas/ExitPlanBreakeven"},{"type":"null"}],"description":"The move to breakeven, or null for none."},"trail":{"type":"array","items":{"$ref":"#/components/schemas/ExitPlanTrailStep"},"description":"The trailing stop tiers, lowest trigger first. Empty for no trailing stop."}},"required":["seq","quantity","stopDistance","trail"],"example":{"seq":2,"quantity":1,"stopDistance":12,"targetDistance":null,"breakeven":{"triggerDistance":8,"plusDistance":0},"trail":[{"stepSeq":1,"triggerDistance":16,"trailDistance":8,"frequencyTicks":2}]}},"ExitPlanDefinition":{"type":"object","description":"The plan itself: everything trdrs needs to work out concrete exit orders, and nothing about an account, a market or a price.","properties":{"unit":{"type":"string","enum":["ticks","price","currency"],"description":"What the plan's distances are in. `currency` is money per unit of quantity. trdrs converts `price` and `currency` distances to ticks using the account's own instrument facts."},"quantity":{"type":"number","description":"The quantity the ladder was written for. An order may carry more, and the extra is left over for you to manage: the plan never protects it."},"tif":{"type":"string","description":"The time in force of the plan's orders."},"entryType":{"type":"string","enum":["market","limit","stop","stop_limit"],"description":"The entry order type the plan is written for."},"legs":{"type":"array","items":{"$ref":"#/components/schemas/ExitPlanLeg"},"description":"The ladder's legs."}},"required":["unit","quantity","tif","entryType","legs"],"example":{"unit":"ticks","quantity":2,"tif":"gtc","entryType":"limit","legs":[{"seq":1,"quantity":1,"stopDistance":12,"targetDistance":20,"breakeven":null,"trail":[]},{"seq":2,"quantity":1,"stopDistance":12,"targetDistance":null,"breakeven":{"triggerDistance":8,"plusDistance":0},"trail":[{"stepSeq":1,"triggerDistance":16,"trailDistance":8,"frequencyTicks":2}]}]}},"SavedExitPlan":{"type":"object","description":"One saved exit plan.","properties":{"id":{"type":"string","description":"The plan's id."},"name":{"type":"string","description":"The plan's name."},"revision":{"type":"string","description":"The plan's revision. It is opaque: send back exactly the value you read when you replace or delete the plan, and never make one up."},"applicability":{"type":"object","description":"Where the plan is meant to be used.","properties":{"assetClasses":{"type":"array","items":{"type":"string"},"description":"The asset classes it is for."},"instruments":{"type":"array","items":{"type":"string"},"description":"The instruments it is for."}},"required":["assetClasses","instruments"]},"definition":{"$ref":"#/components/schemas/ExitPlanDefinition","description":"The plan itself."},"requires":{"type":"array","items":{"type":"string","enum":["stop_loss","take_profit","multiple_targets","runner_leg","breakeven","trailing_stop"]},"description":"What an account must support to run the plan, worked out from the plan itself. Compare it with an account's `exitPlanSupport` to see which plans that account can run."},"updatedAt":{"type":"integer","description":"When the plan was last saved, in epoch milliseconds."}},"required":["id","name","revision","applicability","definition","requires","updatedAt"],"example":{"id":"0f6c2d18-7b4a-4a3e-9d21-8c5e4b0a9f37","name":"Two rungs and a runner","revision":"q2Jm4XxT0aVnR7cLp1sZfE9d","applicability":{"assetClasses":["futures"],"instruments":["ES"]},"definition":{"unit":"ticks","quantity":2,"tif":"gtc","entryType":"limit","legs":[{"seq":1,"quantity":1,"stopDistance":12,"targetDistance":20,"breakeven":null,"trail":[]},{"seq":2,"quantity":1,"stopDistance":12,"targetDistance":null,"breakeven":{"triggerDistance":8,"plusDistance":0},"trail":[{"stepSeq":1,"triggerDistance":16,"trailDistance":8,"frequencyTicks":2}]}]},"requires":["stop_loss","take_profit","runner_leg","breakeven","trailing_stop"],"updatedAt":1787581400000}},"ExitPlansResponse":{"type":"object","description":"Your saved exit plans.","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/SavedExitPlan"},"description":"The plans."}},"required":["items"],"example":{"items":[{"id":"0f6c2d18-7b4a-4a3e-9d21-8c5e4b0a9f37","name":"Two rungs and a runner","revision":"q2Jm4XxT0aVnR7cLp1sZfE9d","applicability":{"assetClasses":["futures"],"instruments":["ES"]},"definition":{"unit":"ticks","quantity":2,"tif":"gtc","entryType":"limit","legs":[{"seq":1,"quantity":1,"stopDistance":12,"targetDistance":20,"breakeven":null,"trail":[]},{"seq":2,"quantity":1,"stopDistance":12,"targetDistance":null,"breakeven":{"triggerDistance":8,"plusDistance":0},"trail":[{"stepSeq":1,"triggerDistance":16,"trailDistance":8,"frequencyTicks":2}]}]},"requires":["stop_loss","take_profit","runner_leg","breakeven","trailing_stop"],"updatedAt":1787581400000}]}},"ExitPlanResponse":{"type":"object","description":"One saved exit plan.","properties":{"plan":{"$ref":"#/components/schemas/SavedExitPlan","description":"The plan."}},"required":["plan"],"example":{"plan":{"id":"0f6c2d18-7b4a-4a3e-9d21-8c5e4b0a9f37","name":"Two rungs and a runner","revision":"q2Jm4XxT0aVnR7cLp1sZfE9d","applicability":{"assetClasses":["futures"],"instruments":["ES"]},"definition":{"unit":"ticks","quantity":2,"tif":"gtc","entryType":"limit","legs":[{"seq":1,"quantity":1,"stopDistance":12,"targetDistance":20,"breakeven":null,"trail":[]},{"seq":2,"quantity":1,"stopDistance":12,"targetDistance":null,"breakeven":{"triggerDistance":8,"plusDistance":0},"trail":[{"stepSeq":1,"triggerDistance":16,"trailDistance":8,"frequencyTicks":2}]}]},"requires":["stop_loss","take_profit","runner_leg","breakeven","trailing_stop"],"updatedAt":1787581400000}}},"ExitPlanWriteRequest":{"type":"object","description":"A plan to create or replace. To replace one, send the `revision` you read. A revision that isn't the stored one is refused with 409, rather than overwriting an edit you haven't seen.","properties":{"name":{"type":"string","description":"The plan's name."},"revision":{"type":"string","description":"The revision you read. Required when you replace a plan, and ignored when you create one."},"applicability":{"type":"object","description":"Where the plan is meant to be used.","properties":{"assetClasses":{"type":"array","items":{"type":"string"},"description":"The asset classes it is for."},"instruments":{"type":"array","items":{"type":"string"},"description":"The instruments it is for."}}},"definition":{"$ref":"#/components/schemas/ExitPlanDefinition","description":"The plan itself."}},"required":["name","definition"],"example":{"name":"Two rungs and a runner","revision":"q2Jm4XxT0aVnR7cLp1sZfE9d","applicability":{"assetClasses":["futures"],"instruments":["ES"]},"definition":{"unit":"ticks","quantity":2,"tif":"gtc","entryType":"limit","legs":[{"seq":1,"quantity":1,"stopDistance":12,"targetDistance":20,"breakeven":null,"trail":[]},{"seq":2,"quantity":1,"stopDistance":12,"targetDistance":null,"breakeven":{"triggerDistance":8,"plusDistance":0},"trail":[{"stepSeq":1,"triggerDistance":16,"trailDistance":8,"frequencyTicks":2}]}]}}},"ExitPlanConflict":{"type":"object","description":"The plan changed between your read and your write. It tells you where the plan is now, so you can show the difference rather than only the refusal.","properties":{"error":{"type":"string","enum":["exit_plan_conflict"],"description":"Always `exit_plan_conflict`."},"planId":{"type":"string","description":"The plan's id."},"expectedRevision":{"type":"string","description":"The revision you sent."},"actualRevision":{"type":["string","null"],"description":"The revision stored now, or null when there is none."}},"required":["error","planId","expectedRevision"],"example":{"error":"exit_plan_conflict","planId":"0f6c2d18-7b4a-4a3e-9d21-8c5e4b0a9f37","expectedRevision":"q2Jm4XxT0aVnR7cLp1sZfE9d","actualRevision":"Kb8vN2wY6tQ1rD5xLp0hUeAc"}},"ResolvedExitLeg":{"type":"object","description":"One leg as trdrs will place it. It gives both the distance in ticks and the price, because your interface shows one and the provider takes the other, and neither is worked out anywhere else.","properties":{"seq":{"type":"integer","description":"The leg's order in the ladder."},"quantity":{"type":"number","description":"The quantity this leg covers."},"stopTicks":{"type":"integer","description":"The stop's distance from the entry, in ticks."},"stopPrice":{"type":"number","description":"The stop price."},"targetTicks":{"type":["integer","null"],"description":"The target's distance from the entry, in ticks, or null for a runner."},"targetPrice":{"type":["number","null"],"description":"The target price, or null for a runner."},"breakevenTriggerTicks":{"type":["integer","null"],"description":"How far in profit, in ticks, the stop moves to breakeven, or null."},"breakevenPlusTicks":{"type":["integer","null"],"description":"How far beyond the entry, in ticks, the stop goes at breakeven, or null."},"trailSteps":{"type":"array","description":"The trailing stop tiers, in ticks.","items":{"type":"object","properties":{"stepSeq":{"type":"integer","description":"The tier's order in the list."},"triggerTicks":{"type":"integer","description":"How far in profit, in ticks, the tier starts."},"trailDistanceTicks":{"type":"integer","description":"How far behind the best price the stop follows, in ticks."},"frequencyTicks":{"type":"integer","description":"How far the price must advance before the stop moves, in ticks."}},"required":["stepSeq","triggerTicks","trailDistanceTicks","frequencyTicks"]}}},"required":["seq","quantity","stopTicks","stopPrice","trailSteps"],"example":{"seq":1,"quantity":1,"stopTicks":12,"stopPrice":6477.5,"targetTicks":20,"targetPrice":6485.5,"breakevenTriggerTicks":null,"breakevenPlusTicks":null,"trailSteps":[]}},"ExitPlanPreviewRequest":{"type":"object","description":"The order to preview a plan against. trdrs supplies every price, so name the order and nothing else.","properties":{"planId":{"type":"string","description":"The saved plan to preview."},"clientOrderId":{"type":"string","description":"The `clientOrderId` the order will be placed with. The preview's token is tied to it, so a confirmation is used up on one order rather than good for any order until it expires."},"instrument":{"type":"string","description":"The instrument."},"side":{"type":"string","enum":["buy","sell"],"description":"The entry's side."},"quantity":{"type":"number","description":"The entry's quantity."},"entryType":{"type":"string","enum":["market","limit","stop","stop_limit"],"description":"The entry order type."},"entryPrice":{"type":["number","null"],"description":"The resting entry's price. Ignored for a market entry, whose ladder is measured from the mark price when the order is placed."}},"required":["planId","clientOrderId","instrument","side","quantity"],"example":{"planId":"0f6c2d18-7b4a-4a3e-9d21-8c5e4b0a9f37","instrument":"ESU6","side":"buy","quantity":2,"entryType":"limit","entryPrice":6480.5}},"ExitPlanPreview":{"type":"object","description":"The exit orders the plan would place, and a token that confirms them. The token covers the order (the account, the `clientOrderId`, the plan and its revision, the instrument, the side, the quantity and the entry), never the prices: when you place the order, trdrs reloads the plan at that revision and works the prices out again. For the same reason, a market entry's prices here are only a guide.","properties":{"planId":{"type":"string","description":"The plan's id."},"planRevision":{"type":"string","description":"The plan's revision. Send it back when you place the order."},"legs":{"type":"array","items":{"$ref":"#/components/schemas/ResolvedExitLeg"},"description":"The exit orders, leg by leg."},"managedQuantity":{"type":"number","description":"The quantity the plan protects."},"unmanagedQuantity":{"type":"number","description":"The quantity the order carries that the plan doesn't protect."},"engineManaged":{"type":"boolean","description":"True when trdrs itself will move the stop, rather than the market holding it still."},"token":{"type":"string","description":"The confirmation token. Send it back as `previewToken` when you place the order."},"expiresAt":{"type":"integer","description":"When the token expires, in epoch milliseconds."}},"required":["planId","planRevision","legs","managedQuantity","unmanagedQuantity","engineManaged","token","expiresAt"],"example":{"planId":"0f6c2d18-7b4a-4a3e-9d21-8c5e4b0a9f37","planRevision":"q2Jm4XxT0aVnR7cLp1sZfE9d","legs":[{"seq":1,"quantity":1,"stopTicks":12,"stopPrice":6477.5,"targetTicks":20,"targetPrice":6485.5,"breakevenTriggerTicks":null,"breakevenPlusTicks":null,"trailSteps":[]},{"seq":2,"quantity":1,"stopTicks":12,"stopPrice":6477.5,"targetTicks":null,"targetPrice":null,"breakevenTriggerTicks":8,"breakevenPlusTicks":0,"trailSteps":[{"stepSeq":1,"triggerTicks":16,"trailDistanceTicks":8,"frequencyTicks":2}]}],"managedQuantity":2,"unmanagedQuantity":0,"engineManaged":true,"token":"WyI3YTFmNGM5M2IyOGQwNWU2Il0.9Qp3Vv1sKdN0yTbXmR7cLh","expiresAt":1787581980000}},"ExitPlanPlacement":{"type":"object","description":"Apply a saved plan to this order. Send the plan, the revision you previewed and the token you were given, but no prices. trdrs reloads the plan at that revision and refuses the order if the plan was edited or deleted, the account changed, the order differs from the one you previewed, or the token expired.","properties":{"planId":{"type":"string","description":"The plan's id."},"planRevision":{"type":"string","description":"The revision you previewed."},"previewToken":{"type":"string","description":"The token from the preview."}},"required":["planId","planRevision","previewToken"],"example":{"planId":"0f6c2d18-7b4a-4a3e-9d21-8c5e4b0a9f37","planRevision":"q2Jm4XxT0aVnR7cLp1sZfE9d","previewToken":"WyI3YTFmNGM5M2IyOGQwNWU2Il0.9Qp3Vv1sKdN0yTbXmR7cLh"}},"PositionRow":{"type":"object","description":"One open position: the instrument's net position on a net account, or one open ticket on an account that holds separate tickets.","properties":{"instrument":{"type":"string","description":"The instrument."},"root":{"type":"string","description":"The product root, such as `ES`."},"positionId":{"type":["string","null"],"description":"The position's id, stable and opaque, unique within the account. Its exits, closes and history name it by this id. On the paper book every position has one: each ticket its own, and a net position a new one each time it opens, so a reversal or a reopen after flat gets a new id. Null where no position id is kept: for every position a provider reports, and on some older Demo accounts."},"positionRevision":{"type":["integer","null"],"description":"The position's own revision on the paper book: 1 when it opens, and one more each time a fill changes it, so a command can state the revision it expects. Null wherever `positionId` is null."},"qty":{"type":"number","description":"The signed quantity: positive for long and negative for short. A ticket stays long or short for its whole life."},"avgPrice":{"type":["number","null"],"description":"The position's average entry price. For a ticket, its own entry price."},"unrealizedPnl":{"type":["number","null"],"description":"The position's own unrealized profit and loss, or null when it isn't known. Never a made-up zero."},"liquidationPrice":{"type":["number","null"],"description":"The liquidation price the provider reports for a leveraged position. Null where there is no such price: for futures, and on the paper book."},"leverage":{"type":["number","null"],"description":"The position's leverage as the provider reports it. Null where there is no such thing, so show no value rather than 1."},"margin":{"type":["number","null"],"description":"The margin set aside for this position as the provider reports it, or null where the provider doesn't report one. Always null on the paper book, whose risk policy sets margin per instrument, never per position. On an account that holds separate tickets, it is set across the instrument's tickets by the policy's hedging method."}},"required":["instrument","positionId","positionRevision","qty","margin"]},"PositionsResponse":{"type":"object","description":"The open positions, and the position mode they were read under, in one read.","properties":{"positionModel":{"type":"string","enum":["net","independent_tickets"],"description":"How the account holds positions. `net` means at most one signed row per instrument. `independent_tickets` is a paper book account where each entry order opens its own ticket, so every open ticket is its own row with its own `positionId`, and opposite tickets on one instrument are two rows, never one net row."},"positions":{"type":"array","items":{"$ref":"#/components/schemas/PositionRow"},"description":"The open positions."}},"required":["positionModel","positions"],"example":{"positionModel":"independent_tickets","positions":[{"instrument":"ESU6","root":"ES","positionId":"c41e8a07:ticket","positionRevision":1,"qty":2,"avgPrice":6480.5,"unrealizedPnl":75,"liquidationPrice":null,"leverage":null,"margin":null},{"instrument":"ESU6","root":"ES","positionId":"f2b9d315:ticket","positionRevision":2,"qty":-1,"avgPrice":6486.25,"unrealizedPnl":250,"liquidationPrice":null,"leverage":null,"margin":null}]}},"ClosedPositionRow":{"type":"object","description":"One closed position.","properties":{"instrument":{"type":"string","description":"The instrument."},"root":{"type":"string","description":"The product root."},"qty":{"type":"number","description":"The quantity that was held."},"avgEntryPrice":{"type":["number","null"],"description":"The average entry price, or null when it isn't known."},"avgExitPrice":{"type":["number","null"],"description":"The average exit price, or null when it isn't known."},"realizedPnl":{"type":["number","null"],"description":"The realized profit and loss, or null when it isn't known."},"openedAt":{"type":["number","null"],"description":"When the position opened, in epoch seconds."},"closedAt":{"type":["number","null"],"description":"When it closed, in epoch seconds."}},"required":["instrument","qty"]},"ClosedPositionsResponse":{"type":"object","description":"The account's closed positions. The list is empty when the provider can't supply history.","properties":{"positions":{"type":"array","items":{"$ref":"#/components/schemas/ClosedPositionRow"},"description":"The closed positions."}},"required":["positions"],"example":{"positions":[{"instrument":"ESU6","root":"ES","qty":3,"avgEntryPrice":6462.25,"avgExitPrice":6470,"realizedPnl":1162.5,"openedAt":1787569200,"closedAt":1787574600}]}},"WorkingOrderRow":{"type":"object","description":"One order at the provider. A price that doesn't apply is null.","properties":{"providerOrderId":{"type":"string","description":"The order id at the provider."},"instrument":{"type":"string","description":"The instrument."},"side":{"type":"string","enum":["buy","sell"],"description":"Buy or sell."},"qty":{"type":"number","description":"The quantity the order was placed for, never the quantity left to fill."},"orderType":{"type":"string","enum":["market","stop","limit","stop_limit","trailing_stop"],"description":"The order type."},"triggerPrice":{"type":["number","null"],"description":"The stop trigger price, or null."},"limitPrice":{"type":["number","null"],"description":"The limit price, or null."},"status":{"type":"string","enum":["working","filled","cancelled","rejected"],"description":"The order's status."},"filledQty":{"type":["number","null"],"description":"How much of `qty` has filled, or null where the provider doesn't report it. Null means unknown, never 0. It tells an order cancelled untouched from one cancelled after part of it filled."},"clientOrderId":{"type":["string","null"],"description":"The `clientOrderId` it was placed with, or null."},"submittedAt":{"type":["number","null"],"description":"When the order was placed, in epoch seconds."},"tif":{"type":["string","null"],"enum":["day","gtc","ioc","fok","post_only",null],"description":"The time in force, or null."},"reduceOnly":{"type":"boolean","description":"True when the order can only reduce a position."},"endReason":{"type":["string","null"],"enum":["trader_cancelled","oco_sibling_filled","replaced","liquidation_cancelled","position_closed","import_entry_cancelled","import_replaced",null],"description":"Why the order ended, where the paper book can say: `trader_cancelled`, `oco_sibling_filled`, `replaced`, `liquidation_cancelled`, `position_closed`, `import_entry_cancelled` or `import_replaced`. Null on an order that is still working, filled or rejected, and on every order a provider ends without saying why. Show a value you don't recognize as it is."},"positionId":{"type":["string","null"],"description":"The paper book position this order acts on. On an account that holds separate tickets, it is the ticket the order opens or, when `reduceOnly`, the one ticket it closes or protects, so a ticket's exits are the reduce-only orders that name its id. On a net account, it is the position that a protective exit, placed when a fill opened it, protects. Null on a net account's other orders, and on every provider's orders."}},"required":["providerOrderId","instrument","side","qty","orderType","triggerPrice","limitPrice","status","filledQty","clientOrderId","submittedAt","tif","reduceOnly","endReason","positionId"]},"WorkingOrdersResponse":{"type":"object","description":"The account's working orders.","properties":{"orders":{"type":"array","items":{"$ref":"#/components/schemas/WorkingOrderRow"},"description":"The orders."}},"required":["orders"],"example":{"orders":[{"providerOrderId":"234992187","instrument":"ESU6","side":"sell","qty":2,"orderType":"limit","triggerPrice":null,"limitPrice":6495,"status":"working","clientOrderId":"tp-esu6-1787581800","submittedAt":1787581800,"tif":"gtc","reduceOnly":false}]}},"HistoryOrderRow":{"type":"object","description":"One order from the account's order history.","properties":{"providerOrderId":{"type":"string","description":"The order id at the provider."},"clientOrderId":{"type":["string","null"],"description":"The `clientOrderId` it was placed with, or null."},"instrument":{"type":"string","description":"The instrument."},"root":{"type":"string","description":"The product root."},"side":{"type":"string","enum":["buy","sell"],"description":"Buy or sell."},"qty":{"type":"number","description":"The quantity the order was placed for."},"orderType":{"type":"string","enum":["market","stop","limit","stop_limit","trailing_stop"],"description":"The order type."},"triggerPrice":{"type":["number","null"],"description":"The stop trigger price, or null."},"limitPrice":{"type":["number","null"],"description":"The limit price, or null."},"avgFillPrice":{"type":["number","null"],"description":"The average fill price, or null."},"filledQty":{"type":["number","null"],"description":"How much filled, or null when it isn't known."},"status":{"type":"string","enum":["working","filled","cancelled","rejected","expired"],"description":"The order's status."},"submittedAt":{"type":["number","null"],"description":"When the order was placed, in epoch seconds."},"updatedAt":{"type":["number","null"],"description":"When it last changed, in epoch seconds."}},"required":["providerOrderId","clientOrderId","instrument","root","side","qty","orderType","triggerPrice","limitPrice","avgFillPrice","filledQty","status","submittedAt","updatedAt"]},"OrderHistoryResponse":{"type":"object","description":"One page of the account's order history.","properties":{"orders":{"type":"array","items":{"$ref":"#/components/schemas/HistoryOrderRow"},"description":"The orders on this page."},"nextCursor":{"type":["string","null"],"description":"Pass it as `cursor` to get the next page, or null on the last page."},"sinceSec":{"type":["integer","null"],"description":"The time the page starts from, in epoch seconds: the open of the current trading session with `window=session`, and null otherwise."}},"required":["orders","nextCursor","sinceSec"],"example":{"orders":[{"providerOrderId":"234991458","clientOrderId":"entry-esu6-1787580900","instrument":"ESU6","root":"ES","side":"buy","qty":2,"orderType":"market","triggerPrice":null,"limitPrice":null,"avgFillPrice":6480.5,"filledQty":2,"status":"filled","submittedAt":1787580900,"updatedAt":1787580901}],"nextCursor":"1787580900:234991458"}},"WireExecution":{"type":"object","description":"One fill on the account.","properties":{"id":{"type":"string","description":"The fill's id."},"instrument":{"type":"string","description":"The instrument."},"root":{"type":"string","description":"The product root."},"side":{"type":"string","enum":["buy","sell"],"description":"Buy or sell."},"qty":{"type":"number","description":"The quantity filled."},"price":{"type":"number","description":"The fill price."},"executedAt":{"type":"number","description":"When it filled, in epoch seconds."}},"required":["id","instrument","side","qty","price","executedAt"]},"ExecutionsResponse":{"type":"object","description":"The account's fills for one instrument.","properties":{"executions":{"type":"array","items":{"$ref":"#/components/schemas/WireExecution"},"description":"The fills."}},"required":["executions"],"example":{"executions":[{"id":"ex_9f27c1","instrument":"ESU6","root":"ES","side":"buy","qty":2,"price":6480.5,"executedAt":1787580901}]}},"DayPnlRow":{"type":"object","description":"Profit and loss for one account on one trading day. The `matched` values are trdrs's own, worked out by matching the day's fills first in, first out. The `provider` values are what the provider reported for the day. The two sets are kept apart, and either may be null when its source hasn't reported.","properties":{"provider":{"type":"string","description":"The provider the account is at."},"accountNumber":{"type":"string","description":"The account number."},"tradingDay":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"The trading day, as YYYY-MM-DD."},"matchedRealizedPnl":{"type":["number","null"],"description":"The realized profit and loss of the round trips closed that day."},"matchedCommission":{"type":["number","null"],"description":"The commission on the round trips closed that day."},"matchedFees":{"type":["number","null"],"description":"The fees on the round trips closed that day."},"providerRealizedPnl":{"type":["number","null"],"description":"The day's realized profit and loss, as the provider reported it."},"providerUnrealizedPnl":{"type":["number","null"],"description":"The day's unrealized profit and loss, as the provider reported it."},"providerNetLiq":{"type":["number","null"],"description":"The account's net liquidation value, as the provider reported it. Use it for an equity curve."},"providerBalance":{"type":["number","null"],"description":"The account's balance, as the provider reported it."},"providerCommission":{"type":["number","null"],"description":"The day's commission, as the provider reported it."},"updatedAt":{"type":"number","description":"When the row last changed, in epoch seconds."}},"required":["provider","accountNumber","tradingDay","matchedRealizedPnl","matchedCommission","matchedFees","providerRealizedPnl","providerUnrealizedPnl","providerNetLiq","providerBalance","providerCommission","updatedAt"]},"PnlHistoryResponse":{"type":"object","description":"Daily profit and loss for the account.","properties":{"days":{"type":"array","items":{"$ref":"#/components/schemas/DayPnlRow"},"description":"One row per trading day."}},"required":["days"],"example":{"days":[{"provider":"rithmic","accountNumber":"PA-4821-07","tradingDay":"2026-08-21","matchedRealizedPnl":387.5,"matchedCommission":8.4,"matchedFees":2.1,"providerRealizedPnl":387.5,"providerUnrealizedPnl":0,"providerNetLiq":50120.3,"providerBalance":50120.3,"providerCommission":8.4,"updatedAt":1787344200},{"provider":"rithmic","accountNumber":"PA-4821-07","tradingDay":"2026-08-24","matchedRealizedPnl":245.5,"matchedCommission":4.2,"matchedFees":1.05,"providerRealizedPnl":245.5,"providerUnrealizedPnl":75,"providerNetLiq":50320.5,"providerBalance":50245.5,"providerCommission":4.2,"updatedAt":1787581920}]}},"RoundTripRow":{"type":"object","description":"One closed trade: an entry fill matched with the fill that closed it, first in, first out.","properties":{"provider":{"type":"string","description":"The provider the account is at."},"accountNumber":{"type":"string","description":"The account number."},"instrument":{"type":"string","description":"The instrument."},"root":{"type":"string","description":"The product root."},"direction":{"type":"string","enum":["long","short"],"description":"The entry's direction."},"qty":{"type":"number","description":"The quantity matched, always positive."},"entryAvgPrice":{"type":"number","description":"The average entry price."},"exitAvgPrice":{"type":"number","description":"The average exit price."},"openedAt":{"type":"number","description":"When the entry filled, in epoch seconds."},"closedAt":{"type":"number","description":"When the exit filled, in epoch seconds."},"tradeDay":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"The trading day the trade closed on, as YYYY-MM-DD."},"realizedPnl":{"type":"number","description":"The realized profit and loss, signed."},"commission":{"type":["number","null"],"description":"The commission, or null when it isn't known."},"fees":{"type":["number","null"],"description":"The fees, or null when they aren't known."},"entrySourceExecId":{"type":"string","description":"The id of the entry fill."},"closeSourceExecId":{"type":"string","description":"The id of the closing fill."}},"required":["provider","accountNumber","instrument","root","direction","qty","entryAvgPrice","exitAvgPrice","openedAt","closedAt","tradeDay","realizedPnl","commission","fees","entrySourceExecId","closeSourceExecId"]},"RoundTripsResponse":{"type":"object","description":"One page of the account's closed trades.","properties":{"roundTrips":{"type":"array","items":{"$ref":"#/components/schemas/RoundTripRow"},"description":"The closed trades on this page."},"nextCursor":{"type":["string","null"],"description":"Pass it as `cursor` to get the next page, or null on the last page."}},"required":["roundTrips","nextCursor"],"example":{"roundTrips":[{"provider":"rithmic","accountNumber":"PA-4821-07","instrument":"ESU6","root":"ES","direction":"long","qty":3,"entryAvgPrice":6462.25,"exitAvgPrice":6470,"openedAt":1787569200,"closedAt":1787574600,"tradeDay":"2026-08-24","realizedPnl":1162.5,"commission":12.6,"fees":3.15,"entrySourceExecId":"ex_9f27a8","closeSourceExecId":"ex_9f27b3"}],"nextCursor":null}},"SyncStream":{"type":["object","null"],"description":"How far trdrs has copied one history from the provider, or null before it starts.","properties":{"backfillDone":{"type":"boolean","description":"True once the past history has been copied."},"hasError":{"type":"boolean","description":"True when the last copy attempt failed."},"lastError":{"type":["string","null"],"description":"Why it failed, or null."},"updatedAt":{"type":"string","format":"date-time","description":"When the state last changed."}},"required":["backfillDone","hasError","lastError","updatedAt"]},"SyncStatusResponse":{"type":"object","description":"How far trdrs has copied the account's fill and order history.","properties":{"fills":{"$ref":"#/components/schemas/SyncStream","description":"The fill history."},"orders":{"$ref":"#/components/schemas/SyncStream","description":"The order history."}},"required":["fills","orders"],"example":{"fills":{"backfillDone":true,"hasError":false,"lastError":null,"updatedAt":"2026-08-24T14:32:00Z"},"orders":{"backfillDone":true,"hasError":false,"lastError":null,"updatedAt":"2026-08-24T14:32:00Z"}}},"NetPositionResponse":{"type":"object","description":"The account's net position in one instrument.","properties":{"instrument":{"type":"string","description":"The instrument."},"qty":{"type":"number","description":"The signed quantity: positive for long, negative for short, and 0 when flat."},"avgPrice":{"type":["number","null"],"description":"The average entry price, or null when there is none or it isn't known."}},"required":["instrument","qty","avgPrice"],"example":{"instrument":"ESU6","qty":2,"avgPrice":6480.5}},"WireOrderWarning":{"type":"object","description":"Something that went only partly right on a request that was otherwise accepted.","properties":{"code":{"type":"string","enum":["exit_plan_remainder_unplaced","exit_plan_not_recorded","bracket_not_recorded"],"description":"What went wrong."},"message":{"type":"string","description":"The warning as an English sentence."},"requestedQty":{"type":"number","description":"The quantity asked for, where it applies."},"placedQty":{"type":"number","description":"The quantity actually placed, where it applies."}},"required":["code","message"]},"OrderRequest":{"type":"object","description":"The order to place. Send a new `clientOrderId` for each order you mean to place, and the same one when you retry it.","properties":{"instrument":{"type":"string","description":"The instrument, as the account's instrument list names it."},"side":{"type":"string","enum":["buy","sell"],"description":"Buy or sell."},"qty":{"type":"number","description":"The quantity, positive."},"clientOrderId":{"type":"string","description":"Your own id for this order, and its idempotency key. Keep it the same across retries of one order."},"orderType":{"type":"string","enum":["market","limit","stop","stop_limit"],"default":"market","description":"The order type. Omit it for a market order."},"limitPrice":{"type":"number","description":"The limit price, for a limit order."},"triggerPrice":{"type":"number","description":"The trigger price, for a stop or stop-limit order."},"stopLimitPrice":{"type":"number","description":"The limit price a stop-limit order rests at once its trigger is hit."},"stopLoss":{"type":"object","description":"The bracket's protective stop: `price`, the exit price, above 0, and `offsetTicks`, the same level as a whole number of ticks from the entry, at least 1. Send both, and each provider uses the one it needs. A trailing stop can't be set here: use a saved exit plan with trailing tiers."},"takeProfit":{"type":"object","description":"The bracket's target, in the same form as `stopLoss`."},"exitPlan":{"$ref":"#/components/schemas/ExitPlanPlacement","description":"A saved exit plan to apply to the order, instead of `stopLoss` and `takeProfit`."},"tif":{"type":"string","enum":["day","gtc"],"description":"The time in force."}},"required":["instrument","side","qty","clientOrderId"],"example":{"instrument":"ESU6","side":"buy","qty":2,"clientOrderId":"entry-esu6-1787580900","orderType":"limit","limitPrice":6480.5,"stopLoss":{"price":6472.5,"offsetTicks":32},"takeProfit":{"price":6495,"offsetTicks":58},"tif":"day"}},"OrderResponse":{"type":"object","description":"The order you placed.","properties":{"providerOrderId":{"type":"string","description":"The order id at the provider."},"filledQty":{"type":"number","description":"How much filled at once."},"avgFillPrice":{"type":"number","description":"The average fill price of what filled at once."},"exitPlan":{"type":"object","description":"Present when a saved exit plan was applied: which plan and revision, what was actually placed, and whether trdrs or the market moves the stop."},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/WireOrderWarning"},"description":"Present only when part of the request went wrong although the order was placed."}},"required":["providerOrderId","filledQty","avgFillPrice"],"example":{"providerOrderId":"234991458","filledQty":2,"avgFillPrice":6480.5,"warnings":[]}},"ReplaceOrderRequest":{"type":"object","description":"The working order to change, and what it should become.","properties":{"providerOrderId":{"type":"string","description":"The order id at the provider."},"instrument":{"type":"string","description":"The instrument."},"side":{"type":"string","enum":["buy","sell"],"description":"Buy or sell."},"qty":{"type":"number","description":"The new quantity."},"orderType":{"type":"string","enum":["limit","stop","stop_limit"],"description":"The order type."},"price":{"type":"number","description":"The new price: a limit order's limit, or a stop or stop-limit order's trigger."},"stopLimitPrice":{"type":"number","description":"Required for a stop-limit order: the limit price it rests at once triggered."},"stopLoss":{"type":["object","null"],"description":"The bracket's stop after the change: an object sets it, null removes it, and leaving it out keeps it as it is."},"takeProfit":{"type":["object","null"],"description":"The bracket's target after the change, with the same rules as `stopLoss`."},"restoreBracket":{"type":"object","description":"The bracket as it is now, so trdrs can put it back if the change is rejected."},"clientOrderId":{"type":"string","description":"Your own id for this change, and its idempotency key."}},"required":["providerOrderId","instrument","side","qty","orderType","price","clientOrderId"],"example":{"providerOrderId":"234992187","instrument":"ESU6","side":"sell","qty":2,"orderType":"limit","price":6497.25,"clientOrderId":"replace-tp-1787582100"}},"ReplaceOrderResponse":{"type":"object","description":"What happened to the order.","properties":{"outcome":{"type":"string","enum":["amended","replaced","gone","restored","restored_without_bracket","unconfirmed","order_lost"],"description":"What happened. See the operation for what each outcome means."},"providerOrderId":{"type":["string","null"],"description":"The id of the order that is working after the change: the same id where the provider changes the order in place, and a new one where the order was cancelled and placed again."},"message":{"type":["string","null"],"description":"More detail, as an English sentence, or null."}},"required":["outcome","providerOrderId"],"example":{"outcome":"amended","providerOrderId":"234992187","message":null}},"ExitsRequest":{"type":"object","description":"The stop and target to set on a position.","properties":{"instrument":{"type":"string","description":"The instrument."},"stopLoss":{"type":["number","null"],"description":"The stop price. Null removes the stop, and leaving it out keeps it."},"takeProfit":{"type":["number","null"],"description":"The target price. Null removes the target, and leaving it out keeps it."},"clientOrderId":{"type":"string","description":"Your own id for this change, and its idempotency key."},"positionId":{"type":"string","description":"The one position to act on, by the id the account snapshot gives it: a ticket on an account that holds separate tickets, or the net position. Only where the provider names its positions. Anywhere else the request is refused, rather than applied to the instrument."},"positionRevision":{"type":"integer","minimum":1,"description":"The position revision you saw. If the position has changed since, the request is refused with `position_revision_stale`. Only with `positionId`."}},"required":["instrument","clientOrderId"],"example":{"instrument":"ESU6","stopLoss":6472.5,"takeProfit":6495,"clientOrderId":"exits-esu6-6472.5-6495"}},"FlattenRequest":{"type":"object","description":"The position to close.","properties":{"instrument":{"type":"string","description":"The instrument."}},"required":["instrument"],"example":{"instrument":"ESU6"}},"CancelOrderRequest":{"type":"object","description":"The order to cancel.","properties":{"providerOrderId":{"type":"string","description":"The order id at the provider."}},"required":["providerOrderId"],"example":{"providerOrderId":"234992187"}},"ReverseRequest":{"type":"object","description":"The position to reverse.","properties":{"instrument":{"type":"string","description":"The instrument."},"clientOrderId":{"type":"string","description":"Your own id for this reverse, and its idempotency key."}},"required":["instrument","clientOrderId"],"example":{"instrument":"ESU6","clientOrderId":"reverse-esu6-1787582400"}},"ReverseOrderResponse":{"type":"object","description":"The order that reversed the position.","properties":{"providerOrderId":{"type":"string","description":"The order id at the provider."},"filledQty":{"type":["number","null"],"description":"How much filled, or null when it isn't known."},"avgFillPrice":{"type":["number","null"],"description":"The average fill price, or null when it isn't known."},"cancelledOrders":{"type":"number","description":"How many working orders on the instrument were cancelled first."},"side":{"type":"string","enum":["buy","sell"],"description":"The side of the reversing order."},"qty":{"type":"number","description":"The quantity of the reversing order."}},"required":["providerOrderId","filledQty","avgFillPrice","cancelledOrders","side","qty"],"example":{"providerOrderId":"234993004","filledQty":4,"avgFillPrice":6481.5,"cancelledOrders":2,"side":"sell","qty":4}},"MarginPreviewRequest":{"type":"object","description":"The order to preview.","properties":{"instrument":{"type":"string","description":"The instrument."},"side":{"type":"string","enum":["buy","sell"],"description":"Buy or sell."},"qty":{"type":"number","description":"The quantity."},"orderType":{"type":"string","description":"The order type. Omit it for `market`."},"limitPrice":{"type":"number","description":"The limit price, for a limit or stop-limit order."},"triggerPrice":{"type":"number","description":"The trigger price, for a stop order."}},"required":["instrument","side","qty"],"example":{"instrument":"ESU6","side":"buy","qty":2,"orderType":"market"}},"MarginPreviewResponse":{"type":"object","description":"The margin the order would need, and whether the account can cover it.","properties":{"marginRequired":{"type":["number","null"],"description":"The margin the order would need, or null when it isn't known."},"estimate":{"type":"boolean","description":"True when the figure is trdrs's estimate rather than the provider's own."},"currency":{"type":"string","description":"The currency of the figure."},"sufficient":{"type":["boolean","null"],"description":"Whether the account can cover the order, by the provider's own figures, or on the paper book by the same collateral check the order meets when it arrives. False means your interface should block the order. Null means there is no verdict and nothing blocks: the figure is unknown, or it can't be judged now."},"basis":{"type":"string","description":"Where the figure comes from, or why it is unknown, where the provider says. The paper book names the risk policy version the figure was read from, or says why there is no verdict."}},"required":["marginRequired","estimate","currency","sufficient"],"example":{"marginRequired":3080,"estimate":false,"currency":"USD","sufficient":true}},"ClosePositionRequest":{"type":"object","description":"The position to close part of, and how much.","properties":{"instrument":{"type":"string","description":"The instrument."},"qty":{"type":"number","description":"How much to close, positive."},"clientOrderId":{"type":"string","description":"Your own id for this close, and its idempotency key."},"positionId":{"type":"string","description":"The one position to act on, by the id the account snapshot gives it: a ticket on an account that holds separate tickets, or the net position. Only where the provider names its positions. Anywhere else the request is refused, rather than applied to the instrument."},"positionRevision":{"type":"integer","minimum":1,"description":"The position revision you saw. If the position has changed since, the request is refused with `position_revision_stale`. Only with `positionId`."}},"required":["instrument","qty","clientOrderId"],"example":{"instrument":"ESU6","qty":1,"clientOrderId":"close-esu6-1787582700"}},"CancelAllRequest":{"type":"object","description":"Which working orders to cancel.","properties":{"instrument":{"type":"string","description":"The instrument whose orders to cancel. Omit it to cancel on every instrument."}},"example":{"instrument":"ESU6"}},"SymbolConfig":{"type":"object","description":"The leverage and margin mode set for one instrument.","properties":{"leverage":{"type":"number","description":"The leverage set."},"marginMode":{"type":"string","enum":["cross","isolated"],"description":"The margin mode."},"maxLeverage":{"type":"number","description":"The most leverage the provider allows on the instrument."}}},"SymbolConfigResponse":{"type":"object","description":"The instrument's leverage and margin mode.","properties":{"config":{"type":["object","null"],"description":"The settings, or null when the provider reports none.","properties":{"leverage":{"type":"number","description":"The leverage set."},"marginMode":{"type":"string","enum":["cross","isolated"],"description":"The margin mode."},"maxLeverage":{"type":"number","description":"The most leverage the provider allows on the instrument."}}}},"required":["config"],"example":{"config":{"leverage":10,"marginMode":"cross","maxLeverage":100}}},"SymbolConfigRequest":{"type":"object","description":"The leverage to set on one instrument.","properties":{"instrument":{"type":"string","description":"The instrument."},"leverage":{"type":"number","exclusiveMinimum":0,"description":"The leverage, greater than 0."}},"required":["instrument","leverage"],"additionalProperties":false,"example":{"instrument":"HYPERLIQUID:BTC","leverage":10}},"PartnerRegistration":{"type":"object","description":"One pre-registration: the trader it is for and the account Connect will show them. It never holds a password or any other credential.","properties":{"id":{"type":"string","description":"The pre-registration id."},"email":{"type":"string","description":"The trader’s sign-in email, in lowercase."},"provider":{"type":"string","description":"The id of the built-in provider the pre-registration opens in Connect, for example `rithmic`. `GET /api/connect/providers` lists every id."},"system":{"type":["string","null"],"description":"Your Rithmic system, filled in for the trader, or null for other providers."},"accountNumber":{"type":["string","null"],"description":"The account number at the provider, or null when you didn’t send one."},"venueLogin":{"type":["string","null"],"description":"The login name your firm issued, or null. It is never a password."},"status":{"type":"string","enum":["pending","linked","revoked","expired"],"description":"`pending` until the trader links the account, then `linked`. `revoked` once you cancel it, and `expired` when it went unused for 30 days."},"expiresAt":{"type":"string","description":"When the pre-registration expires, in ISO 8601."},"createdAt":{"type":"string","description":"When you created it, in ISO 8601."},"linkedAt":{"type":["string","null"],"description":"When the trader linked the account by signing in to the provider, in ISO 8601, or null until then."}},"required":["id","email","provider","system","accountNumber","venueLogin","status","expiresAt","createdAt","linkedAt"]},"PartnerRegistrationRegisterRequest":{"type":"object","description":"The trader to pre-register. Send their sign-in email, and the account number and login name when you have them. Never send a password.","properties":{"email":{"type":"string","description":"The trader’s trdrs sign-in email, at most 254 characters."},"accountNumber":{"type":"string","description":"The account number at the provider, at most 40 characters, when you know it."},"venueLogin":{"type":"string","description":"The login name your firm issued, at most 60 characters. Never a password."}},"required":["email"],"example":{"email":"trader@example.com","accountNumber":"PA-4821-07","venueLogin":"jsmith-apex"}},"PartnerRegistrationRegisterResponse":{"type":"object","description":"The pre-registration you created or refreshed.","properties":{"registration":{"$ref":"#/components/schemas/PartnerRegistration","description":"The pre-registration."}},"required":["registration"],"example":{"registration":{"id":"reg_7f3ka9","email":"trader@example.com","provider":"rithmic","system":"Apex","accountNumber":"PA-4821-07","venueLogin":"jsmith-apex","status":"pending","expiresAt":"2026-09-23T14:32:00Z","createdAt":"2026-08-24T14:32:00Z","linkedAt":null}}},"PartnerRegistrationsResponse":{"type":"object","description":"Every pre-registration your firm has made, newest first.","properties":{"firm":{"type":"string","description":"Your firm’s name, as trdrs holds it."},"registrations":{"type":"array","items":{"$ref":"#/components/schemas/PartnerRegistration"},"description":"The pre-registrations, newest first."}},"required":["firm","registrations"],"example":{"firm":"yourfirm","registrations":[{"id":"reg_7f3ka9","email":"trader@example.com","provider":"rithmic","system":"Apex","accountNumber":"PA-4821-07","venueLogin":"jsmith-apex","status":"pending","expiresAt":"2026-09-23T14:32:00Z","createdAt":"2026-08-24T14:32:00Z","linkedAt":null},{"id":"reg_2b8dx4","email":"second@example.com","provider":"rithmic","system":"Apex","accountNumber":"PA-4821-09","venueLogin":"mlee-apex","status":"linked","expiresAt":"2026-09-17T16:05:00Z","createdAt":"2026-08-18T16:05:00Z","linkedAt":"2026-08-20T09:14:00Z"}]}},"PartnerRegistrationRevokeResponse":{"type":"object","description":"Confirms that the pre-registration is cancelled.","properties":{"id":{"type":"string","description":"The cancelled pre-registration’s id."},"revoked":{"type":"boolean","description":"Always true."}},"required":["id","revoked"],"example":{"id":"reg_7f3ka9","revoked":true}},"ProviderProfile":{"type":"object","additionalProperties":false,"properties":{"companyId":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"documentationUrl":{"type":"string","format":"uri"},"connectionGuideUrl":{"type":"string","format":"uri"},"contactEmail":{"type":"string","format":"email"},"requirements":{"type":"string"},"assetClasses":{"type":"array","items":{"type":"string"}},"maintainerNote":{"type":"string"},"visibility":{"type":"string","enum":["private","sandbox","public"]},"version":{"type":"integer","minimum":1}},"required":["companyId","organizationId","documentationUrl","connectionGuideUrl","contactEmail","requirements","assetClasses","maintainerNote","visibility","version"]},"ProviderRelease":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"companyId":{"type":"string","format":"uuid"},"manifest":{"$ref":"#/components/schemas/VenueProviderManifest"},"manifestHash":{"type":"string"},"authoredBy":{"type":"string"},"authoredOrganizationId":{"type":"string","format":"uuid"},"profileVersion":{"type":"integer"},"state":{"type":"string","enum":["draft","submitted","changes_requested","listed","suspended"]},"evidence":{"type":"object","additionalProperties":false,"properties":{"suite":{"type":"string","enum":["provider-market-data-v1","provider-contract-v1"]},"url":{"type":"string","format":"uri"},"environment":{"type":"string","enum":["sandbox","production"]}},"required":["suite","url","environment"]},"review":{"oneOf":[{"type":"object","additionalProperties":false,"properties":{"actor":{"type":"string"},"note":{"type":"string"},"at":{"type":"string","format":"date-time"}},"required":["actor","note","at"]},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","companyId","manifest","manifestHash","authoredBy","authoredOrganizationId","profileVersion","state","evidence","review","createdAt"]},"ProviderMaintenanceTransfer":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"companyId":{"type":"string","format":"uuid"},"sourceOrganizationId":{"type":"string","format":"uuid"},"targetOrganizationId":{"type":"string","format":"uuid"},"proposedBy":{"type":"string"},"acceptedBy":{"type":["string","null"]},"profileVersion":{"type":"integer"},"state":{"type":"string","enum":["pending","accepted","cancelled"]},"expiresAt":{"type":"string","format":"date-time"}},"required":["id","companyId","sourceOrganizationId","targetOrganizationId","proposedBy","acceptedBy","profileVersion","state","expiresAt"]},"ProviderCatalogItem":{"type":"object","additionalProperties":false,"properties":{"company":{"$ref":"#/components/schemas/CompanyRecord"},"profile":{"$ref":"#/components/schemas/ProviderProfile"}},"required":["company","profile"]},"ProviderDirectoryItem":{"type":"object","additionalProperties":false,"properties":{"company":{"$ref":"#/components/schemas/CompanyRecord"},"profile":{"$ref":"#/components/schemas/ProviderProfile"},"maintainer":{"type":"string"},"releases":{"type":"array","items":{"$ref":"#/components/schemas/ProviderRelease"}},"executionPermission":{"const":false}},"required":["company","profile","maintainer","releases","executionPermission"]},"VenueRecord":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"legacyFirmId":{"type":["string","null"],"format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"environment":{"type":"string","enum":["sandbox","production"]},"state":{"type":"string","enum":["draft","active","halted"]},"version":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"rules":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"applies":{"type":"object","additionalProperties":false,"properties":{"orders":{"type":"boolean"},"fills":{"type":"boolean"},"stages":{"type":"boolean"}},"required":["orders","fills","stages"]},"appliesAtProvider":{"type":"object","additionalProperties":false,"properties":{"orders":{"type":"boolean"},"fills":{"type":"boolean"},"stages":{"type":"boolean"}},"required":["orders","fills","stages"]}},"required":["enabled","applies","appliesAtProvider"],"description":"Venue rules: your own order limits, stages and analytics on the accounts the venue holds. `enabled` is your switch, turned on when you create your first group. `applies` says what trdrs applies today to an account issued on the paper book: `orders` (the halt, instrument list, and size and notional limits, checked before an order is accepted), `fills` (markup, collar and commission at the fill) and `stages` (eligibility read from the account's own fills). `appliesAtProvider` says the same for an account held at a provider, and all three are false there: the provider's orders and fills don't pass through these rules, and stage performance needs a verified start of the cycle that a first snapshot can't give. A false entry means the setting is saved but not applied to trading yet."},"company":{"oneOf":[{"$ref":"#/components/schemas/CompanyRecord"},{"type":"null"}],"description":"The company behind this venue, which holds its brand, its roles and its listing state. Null only for an early venue no company could be matched to."}},"required":["id","organizationId","legacyFirmId","name","description","environment","state","version","createdAt","rules","company"]},"VenueProviderManifest":{"type":"object","additionalProperties":false,"properties":{"providerVersion":{"type":"string"},"protocolVersion":{"const":"1.0"},"schemaDigest":{"type":"string","pattern":"^[a-f0-9]{64}$"},"capabilities":{"type":"object","additionalProperties":false,"properties":{"accounts":{"type":"boolean"},"execution":{"type":"boolean"},"marketData":{"type":"boolean"},"generationFencing":{"type":"boolean"},"completeOrderBook":{"type":"boolean"},"executionHistory":{"type":"boolean"},"executionCorrections":{"type":"boolean"},"orderTypes":{"type":"array","items":{"type":"string","enum":["market","limit","stop","stop_limit"]}},"timeInForce":{"type":"array","items":{"type":"string","enum":["day","gtc","ioc","fok","post_only"]}},"reduceOnly":{"type":"boolean"},"nativeReplace":{"type":"boolean"},"nativeOco":{"type":"boolean"},"accountProvisioning":{"type":"boolean"},"positionModels":{"type":"array","items":{"type":"string","enum":["net","hedged"]}},"replayRetentionSeconds":{"type":"integer","minimum":0,"maximum":31536000}},"required":["accounts","execution","marketData","generationFencing","completeOrderBook","executionHistory","executionCorrections","orderTypes","timeInForce","reduceOnly","nativeReplace","nativeOco","accountProvisioning","positionModels","replayRetentionSeconds"]}},"required":["providerVersion","protocolVersion","schemaDigest","capabilities"],"description":"A public provider's declaration of what it supports, checked against the provider contract. A provider must offer accounts, market data or both. One that offers execution must also offer accounts, generation fencing, a complete order book and execution history, keep at least seven days of replay, and list at least one order type, time in force and position model; one that doesn't can't declare any execution feature, and account provisioning and position models need accounts. Lists hold no duplicates, and registering a manifest doesn't certify its claims."},"CompanyRecord":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"blurb":{"type":["string","null"]},"logoUrl":{"type":["string","null"]},"logoBleed":{"type":"boolean"},"referralUrl":{"type":["string","null"]},"sortOrder":{"type":"integer"},"kind":{"type":"string","enum":["prop","broker","crypto","market"]},"builtInProvider":{"type":["string","null"],"enum":["rithmic","tastytrade","hyperliquid","binance","bybit","paper",null]},"connectsTraders":{"type":"boolean"},"pluggable":{"type":"boolean"},"runsVenue":{"type":"boolean"},"listingState":{"type":"string","enum":["draft","conformance_passed","submitted","in_review","changes_requested","approved","listed","suspended"]},"enabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","blurb","logoUrl","logoBleed","referralUrl","sortOrder","kind","builtInProvider","connectsTraders","pluggable","runsVenue","listingState","enabled","createdAt","updatedAt"],"description":"A company on trdrs, with the roles it plays: traders connect their own accounts through it (`connectsTraders`), a venue can plug it in as a provider (`pluggable`), or it runs a venue (`runsVenue`). Where the company appears follows from those roles. Each of the six built-in providers is a company with `builtInProvider` set, and a company holds its brand and listing state."},"VenueBrand":{"type":"object","additionalProperties":false,"properties":{"companyId":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"logoUrl":{"type":["string","null"],"description":"The logo trdrs serves, or null when none was uploaded."},"logoBleed":{"type":"boolean","description":"Whether the logo's art reaches its edges, measured when it was uploaded."},"listingState":{"type":"string","enum":["draft","conformance_passed","submitted","in_review","changes_requested","approved","listed","suspended"]},"updatedAt":{"type":"string","format":"date-time","description":"When the brand last changed. Send it back as `expectedUpdatedAt` when you change the brand."}},"required":["companyId","name","description","logoUrl","logoBleed","listingState","updatedAt"],"description":"Your venue's brand as traders see it. You can change the name, the description and the logo; the listing state, the company's roles, referral links, routing and approval stay with trdrs."},"VenueProviderVersion":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"venueId":{"type":"string","format":"uuid"},"name":{"type":"string"},"publishedReleaseId":{"type":["string","null"],"format":"uuid"},"manifest":{"$ref":"#/components/schemas/VenueProviderManifest"},"manifestHash":{"type":"string"},"state":{"type":"string","enum":["candidate","sandbox_usable","qualified"]},"creationKey":{"type":"string"},"creationHash":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","venueId","name","publishedReleaseId","manifest","manifestHash","state","creationKey","creationHash","createdAt"]},"VenueProviderConnection":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"venueId":{"type":"string","format":"uuid"},"providerVersionId":{"type":"string","format":"uuid"},"environment":{"type":"string","enum":["sandbox","production"]},"endpoint":{"type":"string"},"credentialId":{"type":"string"},"hasCredential":{"const":true},"state":{"type":"string","enum":["draft","validated","halted","revoked"]},"version":{"type":"integer"},"exposed":{"type":"boolean","description":"Whether this venue shows the plugged-in provider to its own traders in Connect. It is off by default, and the expose route changes it."},"createdAt":{"type":"string","format":"date-time"}},"required":["id","venueId","providerVersionId","environment","endpoint","credentialId","hasCredential","state","version","exposed","createdAt"]},"VenueProviderValidation":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"connectionId":{"type":"string","format":"uuid"},"connectionVersion":{"type":"integer"},"kind":{"type":"string","enum":["manifest","manifest_and_accounts"]},"discoverySnapshotId":{"type":["string","null"],"format":"uuid"},"state":{"type":"string","enum":["pending","running","passed","failed"]},"resultCode":{"type":["string","null"]},"observedManifestHash":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"finishedAt":{"type":["string","null"],"format":"date-time"},"tradingReady":{"const":false}},"required":["id","connectionId","connectionVersion","kind","discoverySnapshotId","state","resultCode","observedManifestHash","createdAt","finishedAt","tradingReady"],"description":"One check of a connection. It fails if the key that started it is revoked, or its creator stops being an owner, before the check reads the provider or records its result. `tradingReady` is always false: a pass doesn't make the connection ready to trade."},"VenueRiskPolicy":{"type":"object","additionalProperties":false,"properties":{"maxOrderQuantity":{"type":["string","null"],"description":"An exact decimal string, or null where this layer sets no limit."},"maxPositionQuantity":{"type":["string","null"],"description":"An exact decimal string, or null where this layer sets no limit."},"maxPositionNotional":{"type":["string","null"],"description":"An exact decimal string, or null where this layer sets no limit."},"instrumentAllowlist":{"type":["array","null"],"items":{"type":"string"}},"dailyLossLimit":{"type":["string","null"],"description":"The most the account's equity may lose in one session day or one trading week, or null for no limit. It is taken only while every account the venue issued is held to your published risk policy; otherwise it is refused with `400` `loss_limit_unenforced` and `field` naming it. Saving it applies it to every account it covers from that account's next session day, and the effective conditions say whether each limit is enforced."},"weeklyLossLimit":{"type":["string","null"],"description":"The most the account's equity may lose in one session day or one trading week, or null for no limit. It is taken only while every account the venue issued is held to your published risk policy; otherwise it is refused with `400` `loss_limit_unenforced` and `field` naming it. Saving it applies it to every account it covers from that account's next session day, and the effective conditions say whether each limit is enforced."},"entryHalted":{"type":"boolean"}},"required":["maxOrderQuantity","maxPositionQuantity","maxPositionNotional","instrumentAllowlist","dailyLossLimit","weeklyLossLimit","entryHalted"],"description":"Safety limits. Null means this layer sets no limit, not that nothing limits the account. A more specific layer (a group, then an account) can lower a limit, narrow the instrument list or halt new exposure, and never the reverse. The daily and weekly loss limits are taken only while every account the venue issued is held to your published risk policy."},"VenueConditionProfile":{"type":"object","additionalProperties":false,"properties":{"margin":{"oneOf":[{"type":"null"},{"type":"object","additionalProperties":false,"properties":{"kind":{"const":"fixedPerUnit"},"initial":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"maintenance":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"currency":{"type":"string"}},"required":["kind","initial","maintenance","currency"]},{"type":"object","additionalProperties":false,"properties":{"kind":{"const":"linearNotional"},"initialRate":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"maintenanceRate":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."}},"required":["kind","initialRate","maintenanceRate"]}],"description":"Always null when you write. What an account must hold comes from your published risk policy alone, so a margin policy here is refused with `400` `margin_policy_superseded` and `field` naming it. A margin stored before that rule still reads back, and the effective conditions report it as not applied."},"commission":{"oneOf":[{"type":"object","additionalProperties":false,"properties":{"kind":{"const":"perUnit"},"timing":{"type":"string","enum":["fill","round_turn"],"description":"When the commission is charged. `fill` charges each fill as it lands. `round_turn` charges nothing on the entry, then the stated round-turn amount on the quantity each reducing fill closes."},"direction":{"type":"string","enum":["entry","exit","both"],"description":"Which fills the commission charges: `entry` the part of a fill that opens or adds exposure, `exit` the part that reduces it, and `both` every fill. A `round_turn` commission uses `both`."},"unit":{"const":"quantity","description":"What a per-unit amount counts: each unit of the instrument's own quantity, whether contracts, lots or base units. To charge a product class its own per-unit rate, hold the accounts that trade it to a policy offering that class alone, in a group of their own."},"amount":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"currency":{"type":"string"},"orderMinimum":{"type":["string","null"],"description":"An exact decimal string, or null where this layer sets no limit."}},"required":["kind","timing","direction","unit","amount","currency","orderMinimum"]},{"type":"object","additionalProperties":false,"properties":{"kind":{"const":"notionalBps"},"timing":{"type":"string","enum":["fill","round_turn"],"description":"When the commission is charged. `fill` charges each fill as it lands. `round_turn` charges nothing on the entry, then the stated round-turn amount on the quantity each reducing fill closes."},"direction":{"type":"string","enum":["entry","exit","both"],"description":"Which fills the commission charges: `entry` the part of a fill that opens or adds exposure, `exit` the part that reduces it, and `both` every fill. A `round_turn` commission uses `both`."},"bps":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"minAmount":{"type":["string","null"],"description":"An exact decimal string, or null where this layer sets no limit."},"currency":{"type":"string"},"orderMinimum":{"type":["string","null"],"description":"An exact decimal string, or null where this layer sets no limit."}},"required":["kind","timing","direction","bps","minAmount","currency","orderMinimum"]}]},"markup":{"type":"object","additionalProperties":false,"properties":{"buyMarkupTicks":{"type":"integer","minimum":0,"maximum":1000},"sellMarkupTicks":{"type":"integer","minimum":0,"maximum":1000}},"required":["buyMarkupTicks","sellMarkupTicks"]},"risk":{"$ref":"#/components/schemas/VenueRiskPolicy"}},"required":["margin","commission","markup","risk"],"description":"What the venue charges and allows: commission, markup and safety limits, each stated with its `kind`. A zero commission is a real choice, and in a group override a field you leave out is inherited, not defaulted. Margin is always null and there is no financing here: your published risk policy states what an account must hold and a CFD's rollover financing, so a profile or group that states financing is refused with `financing_superseded`."},"VenueConditionProfileRecord":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"venueId":{"type":"string","format":"uuid"},"environment":{"type":"string","enum":["sandbox","production"]},"name":{"type":"string"},"profile":{"$ref":"#/components/schemas/VenueConditionProfile"},"contentHash":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"state":{"const":"published"},"inForce":{"type":"boolean"}},"required":["id","venueId","environment","name","profile","contentHash","createdAt","state","inForce"]},"VenueGroupOverride":{"type":"object","additionalProperties":false,"properties":{"margin":{},"commission":{},"markup":{},"risk":{}},"required":[],"description":"A partial profile that changes the venue's conditions for one group. It is the most specific layer that can change what accounts are charged. A field you leave out is inherited from the venue, and a safety limit you state can only tighten it."},"VenueAccountGroup":{"type":"object","additionalProperties":false,"properties":{"groupId":{"type":"string"},"name":{"type":"string"},"override":{"$ref":"#/components/schemas/VenueGroupOverride"},"routeId":{"type":["string","null"]},"stageId":{"type":["string","null"]},"revision":{"type":"integer","minimum":1},"activatedAt":{"type":"string","format":"date-time"}},"required":["groupId","name","override","routeId","stageId","revision","activatedAt"]},"VenueRational":{"type":"object","additionalProperties":false,"properties":{"numerator":{"type":"string"},"denominator":{"type":"string"}},"required":["numerator","denominator"],"description":"An exact fraction, its numerator and denominator whole numbers written as decimal strings, such as `{ \"numerator\": \"100000\", \"denominator\": \"1\" }`. Money is carried this way until it is recorded, so nothing is rounded twice."},"VenueStageFacts":{"type":"object","additionalProperties":false,"properties":{"netTradingPnl":{"type":["string","null"],"description":"An exact decimal string, or null where this layer sets no limit."},"currency":{"type":"string"},"tradingDays":{"type":["integer","null"],"minimum":0},"breaches":{"type":"array","items":{"type":"string"}},"observedRules":{"type":"array","items":{"type":"string"}},"flat":{"type":"boolean"},"workingOrders":{"type":"integer","minimum":0},"unresolvedCommands":{"type":"integer","minimum":0},"complete":{"type":"boolean"},"accountActive":{"type":"boolean"},"halted":{"type":"boolean"},"accountRevision":{"type":["integer","null"],"minimum":1},"decidedRevision":{"type":["integer","null"],"minimum":1}},"required":["netTradingPnl","currency","tradingDays","breaches","observedRules","flat","workingOrders","unresolvedCommands","complete","accountActive","halted","accountRevision","decidedRevision"],"description":"What the account's own trading shows for this stage. A null `netTradingPnl` or `tradingDays` means the cycle's history isn't verified, never zero, and the stage refuses to pass on it even if `complete` reads true. `observedRules` names the rules this history can speak to, so an empty `breaches` list proves nothing about a rule it doesn't name. For an account trdrs measures from its own risk decisions, `accountRevision` is the revision the facts were measured at and `decidedRevision` the revision the decisions have reached, null before their first; trading days are the session days on which the cycle's positions changed, counted to `decidedRevision` and null until the decisions take the cycle under its stage, and `breaches` are every risk rule that fired in the cycle. Both revisions are null for an account the firm issued before it had a venue that hasn't moved to the venue's books, whose facts come from its own fills, counting trading days from when each fill traded."},"VenueStageEligibility":{"type":"object","additionalProperties":false,"properties":{"stageId":{"type":"string"},"policyId":{"type":"string","format":"uuid"},"activationRevision":{"type":"integer","minimum":1},"economicHash":{"type":"string"},"routingPolicyId":{"type":"string","format":"uuid"},"routingActivationRevision":{"type":"integer","minimum":1},"cycleId":{"type":"string"},"snapshotRevision":{"type":"integer","minimum":1},"facts":{"$ref":"#/components/schemas/VenueStageFacts"},"verdict":{"type":"object","additionalProperties":false,"properties":{"eligible":{"type":"boolean"},"reasons":{"type":"array","items":{"type":"string"}},"evaluated":{"type":"array","items":{"type":"string"}}},"required":["eligible","reasons","evaluated"]}},"required":["stageId","policyId","activationRevision","economicHash","routingPolicyId","routingActivationRevision","cycleId","snapshotRevision","facts","verdict"],"description":"Two versions of the stage rules decide an advance, and the advance records both. `policyId`, `activationRevision` and `economicHash` name the version that judges the running cycle, the one in force when it opened, so a later change of rules applies from the next cycle. `routingPolicyId` and `routingActivationRevision` name the version in force now, whose `nextGroupId` is where a passing account lands, since a change of destination applies at once."},"VenueStageAdvance":{"type":"object","additionalProperties":false,"properties":{"state":{"type":"string","enum":["advanced","reserved"]},"targetAccountId":{"type":"string"},"cycleId":{"type":"string"},"stageId":{"type":"string"},"policyId":{"type":"string","format":"uuid"},"transitionReference":{"type":"string"}},"required":["state","targetAccountId","cycleId","stageId","policyId","transitionReference"],"description":"The successor account. `reserved` means it was named and created but its opening balance isn't confirmed yet; `advanced` means it is. They stay distinct because a successor may one day be created at a provider, where asking for an account and having one are different facts."},"VenueStagePolicy":{"type":"object","additionalProperties":false,"properties":{"stageId":{"type":"string"},"profitTarget":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"minimumTradingDays":{"type":"integer","minimum":0,"maximum":3650},"session":{"type":"object","additionalProperties":false,"properties":{"timeZone":{"type":"string"},"rolloverHour":{"type":"integer","minimum":0,"maximum":23}},"required":["timeZone","rolloverHour"]},"disqualifying":{"type":"array","items":{"type":"string"}},"nextGroupId":{"type":["string","null"]},"drawdown":{"oneOf":[{"type":"null"},{"type":"object","additionalProperties":false,"properties":{"maxLoss":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"kind":{"type":"string","enum":["static","trailing"]},"measure":{"type":"string","enum":["balance","equity"]},"highWater":{"type":["string","null"],"enum":["intraday","endOfDay",null]},"dailyMaxLoss":{"type":["string","null"],"description":"An exact decimal string, or null where this layer sets no limit."}},"required":["maxLoss","kind","measure","highWater","dailyMaxLoss"]}],"description":"The drawdown the account may not exceed while it runs this stage, or null for none, with every distance in money. `static` measures from the starting balance, on the realized `balance` or on live `equity`, with `highWater` null. `trailing` measures equity from its high-water mark, which rises `intraday` with every reading or `endOfDay` only at the session roll. `dailyMaxLoss` is a second distance, from the day's opening equity in the stage's session. A breach flattens the account and locks it with reason `max_drawdown` or `daily_drawdown`, which the stage facts record as breaches; name them in `disqualifying` to fail the cycle on them. Putting in force a version that adds or changes this rule waits until the accounts are flat."},"maximumReturn":{"type":["string","null"],"description":"A consistency cap: a gain in equity, in money above the cycle's starting balance, at or above which the cycle fails, or null for none. A breach flattens the account and locks it with reason `eval_breach` until it is reset. Changing it waits for flat accounts, as the drawdown rule does."},"maximumDays":{"type":["integer","null"],"minimum":1,"maximum":3650,"description":"How many whole days the cycle may run from its first trade before it fails, from 1 to 3,650, or null for no limit. Past that point the cycle fails, and the account is flattened and locked with reason `eval_breach` until it is reset. Changing it waits for flat accounts, as the drawdown rule does."}},"required":["stageId","profitTarget","minimumTradingDays","session","disqualifying","nextGroupId","drawdown","maximumReturn","maximumDays"],"description":"What an account must achieve to pass a stage, stored with the venue rather than sent with the advance, so whoever asks can't make the target easier. `profitTarget` is money, `minimumTradingDays` counts days in `session` (a time zone and the hour, 0 to 23, the trading day rolls over), and `disqualifying` names the recorded risk breaches that fail a cycle; leaving one out doesn't weaken your risk settings. A null `nextGroupId` means you haven't said where a passing account goes, and an advance is refused rather than guessed."},"VenueStagePolicyRecord":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"venueId":{"type":"string","format":"uuid"},"environment":{"type":"string","enum":["sandbox","production"]},"stageId":{"type":"string"},"name":{"type":"string"},"policy":{"$ref":"#/components/schemas/VenueStagePolicy"},"contentHash":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"inForce":{"type":"boolean"}},"required":["id","venueId","environment","stageId","name","policy","contentHash","createdAt","inForce"]},"VenueEffectiveConditions":{"type":"object","description":"The conditions one account trades under, each value with the layer that decided it (venue, group, account or trader), and a digest of the values alone. It doesn't mean an order will be accepted, which still needs collateral, a fresh price and a live account stream. `dailyLossLimit` and `weeklyLossLimit` also carry `enforced`, true only while every account the venue issued is held to your published risk policy, since anywhere else a stored limit protects nothing. `margin` carries `applied: false`: a margin stored before margins were refused applies nowhere, because your published risk policy states what an account must hold."},"VenueCollarPolicy":{"oneOf":[{"type":"object","additionalProperties":false,"properties":{"kind":{"const":"ticks"},"maxAdverseTicks":{"type":"integer","minimum":0,"maximum":100000}},"required":["kind","maxAdverseTicks"]},{"type":"object","additionalProperties":false,"properties":{"kind":{"const":"basisPoints"},"maxAdverseBasisPoints":{"type":"integer","minimum":0,"maximum":100000}},"required":["kind","maxAdverseBasisPoints"]}],"description":"How far past a fresh quote a fill may still be accepted, in ticks or in basis points of the price. A tick count means the same at every price, so it is the only kind allowed where prices can go negative, where a proportional allowance would widen as the price falls and flip sign at zero."},"VenueRoutePolicy":{"type":"object","additionalProperties":false,"properties":{"routeId":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["internal","external"]},"connectionId":{"type":["string","null"],"format":"uuid"},"externalAccountId":{"type":["string","null"]},"state":{"type":"string","enum":["offered","retired"]},"collar":{"$ref":"#/components/schemas/VenueCollarPolicy"},"feeReservePerUnit":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"uncappedMarketAllowed":{"type":"boolean"},"revision":{"type":"integer","minimum":1},"version":{"type":"string"}},"required":["routeId","name","mode","connectionId","externalAccountId","state","collar","feeReservePerUnit","uncappedMarketAllowed","revision","version"],"description":"Where a group's orders go, and what protects an order sent there. An external route names both its provider connection and the dedicated account there; an internal route, on the paper book, names neither. `version` is recorded with each order, so every fill traces back to the exact route it was sent under."},"VenueCustomerLedger":{"type":"object","description":"The balance, the collateral held and the open positions of an account whose balance trdrs keeps. An account whose provider keeps its balance has none of this."},"VenueLiquidationIncident":{"type":["object","null"],"description":"The liquidation open on this account, with its recorded reduction steps, or null. While it is open, the account can't open new exposure."},"VenueConditionPreview":{"type":"object","additionalProperties":false,"properties":{"scope":{"type":"string","enum":["venue","group"]},"economicChange":{"type":"boolean"},"affectedAccounts":{"type":"integer","minimum":0},"blockers":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"reason":{"type":"string","enum":["pending_command","working_order","position_open","account_state_unknown"]}},"required":["accountId","reason"]}}},"required":["scope","economicChange","affectedAccounts","blockers"],"description":"What the proposed change would do, without doing it. `economicChange` says whether it changes what accounts are charged, and `blockers` lists each account that isn't flat yet and why. It is a snapshot: an account can open a position before you apply the change, so applying it checks again."},"VenueAccountInstrument":{"type":"object","additionalProperties":false,"properties":{"instrumentId":{"type":"string"},"symbol":{"type":"string"},"instrumentVersionId":{"type":"string","format":"uuid"},"version":{"type":"string"},"blockedBy":{"type":"array","items":{"type":"string","enum":["entry_halted","instrument_not_permitted","instrument_disabled","expired","no_route","route_retired","unmapped_on_route"]}},"poolRefusal":{"oneOf":[{"type":"null"},{"type":"object","additionalProperties":false,"properties":{"code":{"type":"string"},"params":{"type":"object"}},"required":["code","params"]}],"description":"Why the account's risk policy refuses new exposure on this instrument, with the same code and parameters an entry order would be refused with, or null when nothing does. `product_economics_unsupported`; `currency_economics_unsupported` (the instrument settles in an asset the account can't hold, such as a USDC-settled perpetual on a USD account); `asset_class_not_supported` (a product class the account's risk policy states no terms for, such as a CFD under a policy of futures alone, with `provider` `paper`); `collateral_policy_unverified` (no policy, a policy not in force, or a term the instrument needs that is missing or lapsed, a perpetual's funding included); or `settlement_asset_unmodeled`. It lists only what holds at every hour, so a contract past its roll, or a futures day window closing to new exposure, isn't listed."},"tradingReady":{"const":false}},"required":["instrumentId","symbol","instrumentVersionId","version","blockedBy","poolRefusal","tradingReady"],"description":"One active instrument as this account sees it. An empty `blockedBy` and a null `poolRefusal` mean nothing in the account's settings or its risk policy stands in the way of new exposure; they don't mean an order will fill, which is why `tradingReady` stays false. A blocked instrument is listed with its reasons rather than left out, so a trader can be told why something they traded yesterday is unavailable."},"VenueActiveInstrument":{"type":"object","additionalProperties":false,"properties":{"instrumentId":{"type":"string"},"instrumentVersionId":{"type":"string","format":"uuid"},"version":{"type":"string"},"revision":{"type":"integer","minimum":1},"state":{"type":"string","enum":["enabled","disabled"]},"activatedAt":{"type":"string","format":"date-time"},"symbol":{"type":"string"},"name":{"type":"string"},"productModel":{"type":"string"},"quoteCurrency":{"type":"string"},"lastTradeAt":{"type":["string","null"],"format":"date-time"},"sessionOpen":{"type":["boolean","null"],"description":"Whether the instrument's own calendar has it open at the moment of the read. Null where that can't be said, and null never means open."},"tradingReady":{"const":false}},"required":["instrumentId","instrumentVersionId","version","revision","state","activatedAt","symbol","name","productModel","quoteCurrency","lastTradeAt","sessionOpen","tradingReady"],"description":"The active version of an instrument, the one orders on it use now. `tradingReady` stays false because an order still needs collateral, market data access, a fresh price and a live account stream."},"VenueInstrumentCandidateSpecification":{"type":"object","additionalProperties":false,"properties":{"instrumentId":{"type":"string"},"version":{"type":"string"},"venueId":{"type":"string","format":"uuid"},"symbol":{"type":"string"},"name":{"type":"string"},"productModel":{"type":"string","enum":["linear_spot","linear_future","linear_perpetual","linear_cfd"]},"quoteCurrency":{"type":"string"},"settlementCurrency":{"type":"string"},"negativePrices":{"type":"boolean"},"quantity":{"type":"object","additionalProperties":false,"properties":{"unit":{"type":"string","enum":["contracts","base_units","lots"]},"lotSize":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"min":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"max":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"step":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."}},"required":["unit","lotSize","min","max","step"]},"contractMultiplier":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"minNotional":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"ticks":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"from":{"type":["string","null"],"description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"to":{"type":["string","null"],"description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"size":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."}},"required":["from","to","size"]}},"orderTypes":{"type":"array","items":{"type":"string","enum":["market","limit","stop","stop_limit"]}},"timeInForce":{"type":"array","items":{"type":"string","enum":["day","gtc","ioc","fok","post_only"]}},"mappings":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"connectionId":{"type":"string","format":"uuid"},"providerSymbol":{"type":"string"}},"required":["connectionId","providerSymbol"]}},"sessions":{"type":"object","additionalProperties":false,"properties":{"timezone":{"type":"string"},"coverageFrom":{"type":"string","format":"date"},"coverageThrough":{"type":"string","format":"date"},"weekly":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"day":{"type":"integer","minimum":0,"maximum":6},"windows":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"startMinute":{"type":"integer","minimum":0,"maximum":1439},"endMinute":{"type":"integer","minimum":0,"maximum":1439},"endDayOffset":{"type":"integer","enum":[0,1]}},"required":["startMinute","endMinute","endDayOffset"]}}},"required":["day","windows"]}},"holidays":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"date":{"type":"string","format":"date"},"windows":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"startMinute":{"type":"integer","minimum":0,"maximum":1439},"endMinute":{"type":"integer","minimum":0,"maximum":1439},"endDayOffset":{"type":"integer","enum":[0,1]}},"required":["startMinute","endMinute","endDayOffset"]}}},"required":["date","windows"]}}},"required":["timezone","coverageFrom","coverageThrough","weekly","holidays"]},"expiresAt":{"type":["string","null"],"format":"date-time"},"lastTradeAt":{"type":["string","null"],"format":"date-time"},"pricing":{"type":"object","additionalProperties":false,"properties":{"sourceId":{"type":"string"},"stopTrigger":{"type":"string","enum":["last","mark","bid_ask"]},"maxAgeMs":{"type":"integer","minimum":1,"maximum":2000,"description":"The oldest price, in milliseconds from 1 to 2,000, that a fill or an order check on this instrument accepts. A Hyperliquid mark that hasn't moved arrives again at most every 500 ms, so a bound at or below that plus Hyperliquid's own update interval reads a quiet Hyperliquid market as stale."}},"required":["sourceId","stopTrigger","maxAgeMs"]},"entitlement":{"type":["string","null"]},"state":{"type":"string","enum":["enabled","disabled"]}},"required":["instrumentId","version","venueId","symbol","name","productModel","quoteCurrency","settlementCurrency","negativePrices","quantity","contractMultiplier","minNotional","ticks","orderTypes","timeInForce","mappings","sessions","expiresAt","lastTradeAt","pricing","entitlement","state"],"description":"The definition of an instrument candidate. Saving it activates nothing and lets no order through. The rules checked across fields: quote and settlement currencies match; a future counts contracts and states its expiry and last trade, and spot counts base units; quantity bounds sit on the step, `lotSize` is 1 unless the unit is lots, and the multiplier is 1 for base units and equals `lotSize` for lots. Price ranges in `ticks` run on from zero with no gap and cover every allowed price, a null bound meaning no end, and only a future may allow negative prices. An instrument that names an entitlement is priced from each trader's own feed, so its `pricing.sourceId` must be a source trdrs serves per trader (Rithmic today); any other is refused as `entitled_source_unserved` on `instrument.pricing.sourceId`, both here and when an older candidate is activated. The weekly calendar lists all seven days once, a holiday replaces the windows of its local opening date (overnight ones included), overlapping windows and daylight-saving times that are ambiguous or don't exist are refused, coverage dates are explicit, and every mapping belongs to this venue and environment."},"VenueInstrumentCandidate":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"venueId":{"type":"string","format":"uuid"},"environment":{"type":"string","enum":["sandbox","production"]},"specification":{"$ref":"#/components/schemas/VenueInstrumentCandidateSpecification"},"contentHash":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"state":{"const":"candidate"},"tradingReady":{"const":false}},"required":["id","venueId","environment","specification","contentHash","createdAt","state","tradingReady"]},"VenueInvitation":{"type":"object","additionalProperties":false,"properties":{"claimId":{"type":"string","format":"uuid"},"token":{"type":"string","pattern":"^[A-Za-z0-9_-]{43}$"},"expiresAt":{"type":"string","format":"date-time"},"canTrade":{"type":"boolean"}},"required":["claimId","token","expiresAt","canTrade"]},"VenueGrantStatus":{"type":"object","additionalProperties":false,"properties":{"claimId":{"type":"string","format":"uuid"},"accountId":{"type":"string"},"email":{"type":"string"},"canTrade":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time"},"claimedAt":{"type":["string","null"],"format":"date-time"},"revokedAt":{"type":["string","null"],"format":"date-time"},"version":{"type":"integer","minimum":1}},"required":["claimId","accountId","email","canTrade","expiresAt","claimedAt","revokedAt","version"]},"VenueOperatorKeyIssued":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"token":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","enum":["venue:read","venue:configure","connection:manage","connect:manage","account:issue","account:read","account:reset","provider:manage","grant:manage","balance:write","risk:halt","stage:advance","hedge:read","hedge:manage","hedge:execute"]}},"expiresAt":{"type":"string","format":"date-time"}},"required":["id","token","scopes","expiresAt"]},"VenueIssuedAccount":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"accountNumber":{"type":"string"},"email":{"type":"string"},"groupId":{"type":"string"},"book":{"const":"canonical"},"balance":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"currency":{"type":"string"},"riskPolicy":{"type":"object","additionalProperties":false,"properties":{"policyId":{"type":"string"},"version":{"type":"string"},"sequence":{"type":"integer"}},"required":["policyId","version","sequence"]},"positionMode":{"type":"string","enum":["net","independent_tickets"]},"created":{"type":"boolean"}},"required":["accountId","accountNumber","email","groupId","book","balance","currency","riskPolicy","positionMode","created"],"description":"The account you issued, on the paper book (`book` is `canonical`): its currency, its balance, and your risk policy it is held to, with the version in force. `created: false` means the `referenceId` already issued this account for the same request, and nothing new was issued."},"VenueAccountRow":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"accountNumber":{"type":"string"},"provider":{"type":"string"},"purpose":{"type":"string","enum":["evaluation","brokerage","connected"]},"balanceAuthority":{"type":"string","enum":["trdrs","provider"]},"currency":{"type":"string"},"version":{"type":"integer","minimum":1},"groupId":{"type":["string","null"]},"email":{"type":["string","null"]},"status":{"type":["string","null"],"enum":["active","closed",null]},"issuedAt":{"type":["string","null"],"format":"date-time"},"balance":{"type":["string","null"],"description":"An exact decimal string, or null where this layer sets no limit."},"startingBalance":{"type":["string","null"],"description":"An exact decimal string, or null where this layer sets no limit."},"resetAt":{"type":["string","null"],"format":"date-time"}},"required":["accountId","accountNumber","provider","purpose","balanceAuthority","currency","version","groupId","email","status","issuedAt","balance","startingBalance","resetAt"],"description":"One account the venue holds. The balance fields are null for an account whose provider keeps its balance, never a made-up zero."},"VenueAccountAnalytics":{"type":"object","description":"One account's current cycle. An account trdrs measures from its own risk decisions states in `pnl.imported` and `tradingDays.imported` what a cycle carried over when it moved from the older paper records. For an account held at a provider (`book: provider`), the current balance, equity, positions and orders are available where covered, while `pnl.grossRealized`, `pnl.fees`, `pnl.netTrading`, `tradingDays.count` and `tradingDays.days` stay null until the cycle's real start and full history are verified: the first provider snapshot is only a starting observation, `completeness.trading` is false with `economic_cycle_unverified`, `equityHistory` is null and `risk.observedRules` is empty. Never show a null as zero or use it for a stage."},"VenueRiskControls":{"type":"object","additionalProperties":false,"properties":{"dailyLossEnabled":{"type":"boolean"},"dailyLossValue":{"type":["number","null"]},"weeklyLossEnabled":{"type":"boolean"},"weeklyLossValue":{"type":["number","null"]},"dailyProfitEnabled":{"type":"boolean"},"dailyProfitValue":{"type":["number","null"]},"weeklyProfitEnabled":{"type":"boolean"},"weeklyProfitValue":{"type":["number","null"]},"eodCloseEnabled":{"type":"boolean"},"eodCloseValue":{"type":["number","null"]},"updatedAt":{"type":"integer"}},"required":["dailyLossEnabled","dailyLossValue","weeklyLossEnabled","weeklyLossValue","dailyProfitEnabled","dailyProfitValue","weeklyProfitEnabled","weeklyProfitValue","eodCloseEnabled","eodCloseValue","updatedAt"],"description":"The five controls, each a switch and a value. Loss and profit values are positive amounts in the account currency, and a disabled control's value is null. `eodCloseValue` is whole minutes before the 16:00 Central time close, and `updatedAt` is the time of the last write in epoch seconds."},"VenueDiscoveredAccount":{"type":"object","additionalProperties":false,"properties":{"externalAccountId":{"type":"string"},"label":{"type":"string"},"currency":{"type":"string"},"positionModel":{"type":"string","enum":["net","hedged"]},"permissions":{"type":"object","additionalProperties":false,"properties":{"read":{"type":"boolean"},"trade":{"type":"boolean"}},"required":["read","trade"]}},"required":["externalAccountId","label","currency","positionModel","permissions"]},"VenueConnectedAccount":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"currency":{"type":"string"},"connectionId":{"type":"string","format":"uuid"},"externalAccountId":{"type":"string"},"canRead":{"type":"boolean"},"canTrade":{"type":"boolean"},"state":{"const":"bound"},"tradingReady":{"const":false}},"required":["accountId","currency","connectionId","externalAccountId","canRead","canTrade","state","tradingReady"]},"VenueHedgePolicy":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"venueId":{"type":"string","format":"uuid"},"environment":{"type":"string","enum":["sandbox","production"]},"groupId":{"type":"string"},"name":{"type":"string"},"destinationAccountId":{"type":"string","format":"uuid"},"ratio":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"quantityCap":{"type":["string","null"],"description":"An exact decimal string, or null where this layer sets no limit."},"notionalCap":{"type":["string","null"],"description":"An exact decimal string, or null where this layer sets no limit."},"residualThreshold":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"createdAt":{"type":"string","format":"date-time"}},"required":["id","venueId","environment","groupId","name","destinationAccountId","ratio","quantityCap","notionalCap","residualThreshold","createdAt"]},"VenueHedgeActivation":{"type":"object","additionalProperties":false,"properties":{"venueId":{"type":"string","format":"uuid"},"environment":{"type":"string","enum":["sandbox","production"]},"groupId":{"type":"string"},"policyId":{"type":"string","format":"uuid"},"state":{"type":"string","enum":["active","paused","stopped"]},"revision":{"type":"integer","minimum":1},"activatedAt":{"type":"string","format":"date-time"}},"required":["venueId","environment","groupId","policyId","state","revision","activatedAt"]},"VenueHedgeTarget":{"type":"object","description":"One stored hedge calculation. The customer exposure, the target, the position confirmed at the provider, the pending orders and the rounding residual stay separate, so a retry can never double a hedge unnoticed."},"VenueHedgeIntent":{"type":"object","description":"One hedge order derived from a target, safe to send twice. An order whose outcome is unknown stays pending, and nothing that adds exposure runs until it is reconciled."},"VenueHedgeReport":{"type":"object","additionalProperties":false,"properties":{"policies":{"type":"array","items":{"$ref":"#/components/schemas/VenueHedgePolicy"}},"activations":{"type":"array","items":{"$ref":"#/components/schemas/VenueHedgeActivation"}},"targets":{"type":"array","items":{"$ref":"#/components/schemas/VenueHedgeTarget"}},"intents":{"type":"array","items":{"$ref":"#/components/schemas/VenueHedgeIntent"}},"incidents":{"type":"array","items":{"type":"object"}},"metrics":{"type":"object","additionalProperties":false,"properties":{"complete":{"type":"boolean"},"unresolvedIntents":{"type":"integer"},"executions":{"type":"integer"},"feesByCurrency":{"type":"object","additionalProperties":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."}},"slippageBps":{"type":["string","null"],"description":"An exact decimal string, or null where this layer sets no limit."},"missingFeeRecords":{"type":"integer"}},"required":["complete","unresolvedIntents","executions","feesByCurrency","slippageBps","missingFeeRecords"]}},"required":["policies","activations","targets","intents","incidents","metrics"]},"ProviderDirectoryResponse":{"type":"object","additionalProperties":false,"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ProviderDirectoryItem"}},"builtIns":{"type":"array","items":{"$ref":"#/components/schemas/CompanyRecord"}},"nextCursor":{"type":["string","null"],"format":"uuid"}},"required":["items","builtIns","nextCursor"],"example":{"items":[],"builtIns":[],"nextCursor":null}},"ProviderMaintainedResponse":{"type":"object","additionalProperties":false,"properties":{"organizationId":{"type":"string","format":"uuid"},"items":{"type":"array","items":{"$ref":"#/components/schemas/ProviderCatalogItem"}},"releases":{"type":"array","items":{"$ref":"#/components/schemas/ProviderRelease"}},"transfers":{"type":"array","items":{"$ref":"#/components/schemas/ProviderMaintenanceTransfer"}}},"required":["organizationId","items","releases","transfers"],"example":{"organizationId":"00000000-0000-0000-0000-000000000001","items":[],"releases":[],"transfers":[]}},"ProviderProfileCreateRequest":{"type":"object","additionalProperties":false,"properties":{"profile":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"blurb":{"type":"string"},"documentationUrl":{"type":"string","format":"uri"},"connectionGuideUrl":{"type":"string","format":"uri"},"contactEmail":{"type":"string","format":"email"},"requirements":{"type":"string"},"assetClasses":{"type":"array","items":{"type":"string"}},"maintainerNote":{"type":"string"}},"required":["name","blurb","documentationUrl","connectionGuideUrl","contactEmail","requirements","assetClasses","maintainerNote"]}},"required":["profile"],"example":{"profile":{"name":"Example Pricing","blurb":"Test quotes","documentationUrl":"https://example.com/docs","connectionGuideUrl":"https://example.com/connect","contactEmail":"support@example.com","requirements":"Dedicated credentials","assetClasses":["forex"],"maintainerNote":"Maintained by Example"}}},"ProviderProfileResponse":{"type":"object","additionalProperties":false,"properties":{"company":{"$ref":"#/components/schemas/CompanyRecord"},"profile":{"$ref":"#/components/schemas/ProviderProfile"}},"required":["company","profile"],"example":{"company":{"id":"00000000-0000-0000-0000-000000000001","name":"Example Pricing","blurb":"Test quotes","logoUrl":null,"logoBleed":false,"referralUrl":null,"sortOrder":100,"kind":"market","builtInProvider":null,"connectsTraders":false,"pluggable":false,"runsVenue":false,"listingState":"draft","enabled":true,"createdAt":"2026-09-14T12:00:00.000Z","updatedAt":"2026-09-14T12:00:00.000Z"},"profile":{"companyId":"00000000-0000-0000-0000-000000000001","organizationId":"00000000-0000-0000-0000-000000000001","documentationUrl":"https://example.com/docs","connectionGuideUrl":"https://example.com/connect","contactEmail":"support@example.com","requirements":"Dedicated credentials","assetClasses":["forex"],"maintainerNote":"Maintained by Example","visibility":"private","version":1}}},"ProviderProfileUpdateRequest":{"type":"object","additionalProperties":false,"properties":{"profile":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"blurb":{"type":"string"},"documentationUrl":{"type":"string","format":"uri"},"connectionGuideUrl":{"type":"string","format":"uri"},"contactEmail":{"type":"string","format":"email"},"requirements":{"type":"string"},"assetClasses":{"type":"array","items":{"type":"string"}},"maintainerNote":{"type":"string"}},"required":["name","blurb","documentationUrl","connectionGuideUrl","contactEmail","requirements","assetClasses","maintainerNote"]},"expectedVersion":{"type":"integer","minimum":1}},"required":["profile","expectedVersion"],"example":{"profile":{"name":"Example Pricing","blurb":"Test quotes","documentationUrl":"https://example.com/docs","connectionGuideUrl":"https://example.com/connect","contactEmail":"support@example.com","requirements":"Dedicated credentials","assetClasses":["forex"],"maintainerNote":"Maintained by Example"},"expectedVersion":1}},"ProviderProfileLogoRequest":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"string"},"expectedVersion":{"type":"integer","minimum":1}},"required":["data","expectedVersion"],"example":{"data":"BASE64_PNG_BYTES","expectedVersion":1}},"ProviderLogoResponse":{"type":"object","additionalProperties":false,"properties":{"profile":{"$ref":"#/components/schemas/ProviderProfile"}},"required":["profile"],"example":{"profile":{"companyId":"00000000-0000-0000-0000-000000000001","organizationId":"00000000-0000-0000-0000-000000000001","documentationUrl":"https://example.com/docs","connectionGuideUrl":"https://example.com/connect","contactEmail":"support@example.com","requirements":"Dedicated credentials","assetClasses":["forex"],"maintainerNote":"Maintained by Example","visibility":"private","version":2}}},"ProviderReleaseCreateRequest":{"type":"object","additionalProperties":false,"properties":{"manifest":{"$ref":"#/components/schemas/VenueProviderManifest"},"evidence":{"type":"object","additionalProperties":false,"properties":{"suite":{"type":"string","enum":["provider-market-data-v1","provider-contract-v1"]},"url":{"type":"string","format":"uri"},"environment":{"type":"string","enum":["sandbox","production"]}},"required":["suite","url","environment"]},"expectedVersion":{"type":"integer","minimum":1}},"required":["manifest","evidence","expectedVersion"],"example":{"manifest":{"providerVersion":"example-1","protocolVersion":"1.0","schemaDigest":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","capabilities":{"accounts":false,"execution":false,"marketData":true,"generationFencing":false,"completeOrderBook":false,"executionHistory":false,"executionCorrections":false,"orderTypes":[],"timeInForce":[],"reduceOnly":false,"nativeReplace":false,"nativeOco":false,"accountProvisioning":false,"positionModels":[],"replayRetentionSeconds":0}},"evidence":{"suite":"provider-market-data-v1","url":"https://example.com/evidence","environment":"sandbox"},"expectedVersion":1}},"ProviderReleaseResponse":{"type":"object","additionalProperties":false,"properties":{"release":{"$ref":"#/components/schemas/ProviderRelease"}},"required":["release"],"example":{"release":{"id":"00000000-0000-0000-0000-000000000001","companyId":"00000000-0000-0000-0000-000000000001","manifest":{"providerVersion":"example-1","protocolVersion":"1.0","schemaDigest":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","capabilities":{"accounts":false,"execution":false,"marketData":true,"generationFencing":false,"completeOrderBook":false,"executionHistory":false,"executionCorrections":false,"orderTypes":[],"timeInForce":[],"reduceOnly":false,"nativeReplace":false,"nativeOco":false,"accountProvisioning":false,"positionModels":[],"replayRetentionSeconds":0}},"manifestHash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","authoredBy":"user_1","authoredOrganizationId":"00000000-0000-0000-0000-000000000001","profileVersion":1,"state":"draft","evidence":{"suite":"provider-market-data-v1","url":"https://example.com/evidence","environment":"sandbox"},"review":null,"createdAt":"2026-09-14T12:00:00.000Z"}}},"ProviderPublicationRequest":{"type":"object","additionalProperties":false,"properties":{"releaseId":{"type":"string","format":"uuid"},"action":{"type":"string","enum":["preview","submit","withdraw"]},"expectedVersion":{"type":"integer","minimum":1}},"required":["releaseId","action","expectedVersion"],"example":{"releaseId":"00000000-0000-0000-0000-000000000002","action":"submit","expectedVersion":1}},"ProviderPublicationResponse":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"releaseId":{"type":"string","format":"uuid"},"action":{"type":"string","enum":["preview","submit","withdraw"]}},"required":["id","releaseId","action"],"example":{"id":"00000000-0000-0000-0000-000000000001","releaseId":"00000000-0000-0000-0000-000000000001","action":"submit"}},"ProviderReleaseInstallRequest":{"type":"object","additionalProperties":false,"properties":{},"required":[],"example":{}},"ProviderReleaseInstallResponse":{"type":"object","additionalProperties":false,"properties":{"provider":{"$ref":"#/components/schemas/VenueProviderVersion"},"tradingReady":{"const":false}},"required":["provider","tradingReady"],"example":{"provider":{"id":"00000000-0000-0000-0000-000000000001","venueId":"00000000-0000-0000-0000-000000000001","name":"Example Pricing","manifest":{"providerVersion":"example-1","protocolVersion":"1.0","schemaDigest":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","capabilities":{"accounts":false,"execution":false,"marketData":true,"generationFencing":false,"completeOrderBook":false,"executionHistory":false,"executionCorrections":false,"orderTypes":[],"timeInForce":[],"reduceOnly":false,"nativeReplace":false,"nativeOco":false,"accountProvisioning":false,"positionModels":[],"replayRetentionSeconds":0}},"manifestHash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","publishedReleaseId":"00000000-0000-0000-0000-000000000001","state":"candidate","creationKey":"example-request","creationHash":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","createdAt":"2026-09-14T12:00:00.000Z"},"tradingReady":false}},"ProviderTransferRequest":{"type":"object","additionalProperties":false,"properties":{"targetOrganizationId":{"type":"string","format":"uuid"},"expectedVersion":{"type":"integer","minimum":1}},"required":["targetOrganizationId","expectedVersion"],"example":{"targetOrganizationId":"00000000-0000-0000-0000-000000000003","expectedVersion":1}},"ProviderTransferResponse":{"type":"object","additionalProperties":false,"properties":{"transfer":{"$ref":"#/components/schemas/ProviderMaintenanceTransfer"}},"required":["transfer"],"example":{"transfer":{"id":"00000000-0000-0000-0000-000000000001","companyId":"00000000-0000-0000-0000-000000000001","sourceOrganizationId":"00000000-0000-0000-0000-000000000001","targetOrganizationId":"00000000-0000-0000-0000-000000000002","proposedBy":"user_1","acceptedBy":null,"profileVersion":1,"state":"pending","expiresAt":"2026-09-14T12:00:00.000Z"}}},"ProviderTransferAcceptRequest":{"type":"object","additionalProperties":false,"properties":{},"required":[],"example":{}},"ProviderTransferCancelRequest":{"type":"object","additionalProperties":false,"properties":{},"required":[],"example":{}},"ProviderPublicationReviewRequest":{"type":"object","additionalProperties":false,"properties":{"decision":{"type":"string","enum":["list","changes_requested","suspend"]},"note":{"type":"string"},"expectedVersion":{"type":"integer","minimum":1}},"required":["decision","note","expectedVersion"],"example":{"decision":"list","note":"Data-only evidence reviewed","expectedVersion":1}},"VenueProviderListResponse":{"type":"object","additionalProperties":false,"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/VenueProviderVersion"}},"nextCursor":{"type":["string","null"]},"available":{"type":"array","items":{"$ref":"#/components/schemas/CompanyRecord"},"description":"Enabled, listed companies that currently declare the pluggable role. Trader-only companies appear separately in the provider catalog directory."}},"required":["items","nextCursor","available"],"example":{"items":[],"nextCursor":null,"available":[]}},"VenueProviderSaveRequest":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"manifest":{"$ref":"#/components/schemas/VenueProviderManifest"}},"required":["name","manifest"],"example":{"name":"Example provider","manifest":{"providerVersion":"example-v1","protocolVersion":"1.0","schemaDigest":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","capabilities":{"accounts":true,"execution":true,"marketData":false,"generationFencing":true,"completeOrderBook":true,"executionHistory":true,"executionCorrections":false,"orderTypes":["market","limit"],"timeInForce":["day"],"reduceOnly":true,"nativeReplace":false,"nativeOco":false,"accountProvisioning":false,"positionModels":["net"],"replayRetentionSeconds":604800}}}},"VenueProviderSaveResponse":{"type":"object","additionalProperties":false,"properties":{"provider":{"$ref":"#/components/schemas/VenueProviderVersion"}},"required":["provider"],"example":{"provider":{"id":"00000000-0000-0000-0000-000000000001","venueId":"00000000-0000-0000-0000-000000000001","name":"Example provider","manifest":{"providerVersion":"example-v1","protocolVersion":"1.0","schemaDigest":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","capabilities":{"accounts":true,"execution":true,"marketData":false,"generationFencing":true,"completeOrderBook":true,"executionHistory":true,"executionCorrections":false,"orderTypes":["market","limit"],"timeInForce":["day"],"reduceOnly":true,"nativeReplace":false,"nativeOco":false,"accountProvisioning":false,"positionModels":["net"],"replayRetentionSeconds":604800}},"manifestHash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","publishedReleaseId":null,"state":"candidate","creationKey":"example-request","creationHash":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","createdAt":"2026-09-14T12:00:00.000Z"}}},"VenueConnectionListResponse":{"type":"object","additionalProperties":false,"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/VenueProviderConnection"}},"nextCursor":{"type":["string","null"]}},"required":["items","nextCursor"],"example":{"items":[],"nextCursor":null}},"VenueConnectionSaveRequest":{"type":"object","additionalProperties":false,"properties":{"providerVersionId":{"type":"string","format":"uuid","description":"A provider version this venue registered, in the same environment."},"endpoint":{"type":"string","format":"uri","description":"The provider's base URL: `https` on port 443 with a hostname, and no user name, password, query or fragment."},"credentialId":{"type":"string","description":"Your name for the credential, at most 128 characters."},"credential":{"type":"string","writeOnly":true,"maxLength":8192,"description":"The secret the provider issued you, at most 8,192 printable characters with no spaces. It is stored encrypted and never returned."},"environment":{"type":"string","enum":["sandbox","production"],"description":"The venue's own environment."}},"required":["providerVersionId","endpoint","credentialId","credential","environment"],"example":{"providerVersionId":"00000000-0000-0000-0000-000000000001","endpoint":"https://provider.example.com","credentialId":"example-credential","credential":"replace-with-provider-credential","environment":"sandbox"}},"VenueConnectionSaveResponse":{"type":"object","additionalProperties":false,"properties":{"connection":{"$ref":"#/components/schemas/VenueProviderConnection"}},"required":["connection"],"example":{"connection":{"id":"00000000-0000-0000-0000-000000000001","venueId":"00000000-0000-0000-0000-000000000001","providerVersionId":"00000000-0000-0000-0000-000000000001","environment":"sandbox","endpoint":"https://provider.example.com/","credentialId":"example-credential","hasCredential":true,"state":"draft","version":1,"exposed":false,"createdAt":"2026-09-14T12:00:00.000Z"}}},"VenueConnectionExposeRequest":{"type":"object","additionalProperties":false,"properties":{"exposed":{"type":"boolean","description":"True to show the provider to your traders, false to hide it."}},"required":["exposed"],"example":{"exposed":true}},"VenueConnectionExposeResponse":{"type":"object","additionalProperties":false,"properties":{"connection":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"exposed":{"type":"boolean"}},"required":["id","exposed"]}},"required":["connection"],"example":{"connection":{"id":"00000000-0000-0000-0000-000000000001","exposed":true}}},"VenueRulesRequest":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean","description":"True to turn venue rules on, false to turn them off. Sending the current state changes nothing."}},"required":["enabled"],"example":{"enabled":false}},"VenueRulesResponse":{"type":"object","additionalProperties":false,"properties":{"venue":{"$ref":"#/components/schemas/VenueRecord"}},"required":["venue"],"example":{"venue":{"id":"00000000-0000-0000-0000-000000000001","organizationId":"00000000-0000-0000-0000-000000000001","legacyFirmId":null,"name":"Example venue","description":null,"environment":"sandbox","state":"draft","version":2,"createdAt":"2026-09-14T12:00:00.000Z","rules":{"enabled":false,"applies":{"orders":true,"fills":true,"stages":true},"appliesAtProvider":{"orders":false,"fills":false,"stages":false}},"company":null}}},"VenueValidationRequest":{"type":"object","additionalProperties":false,"properties":{},"required":[],"example":{}},"VenueValidationResponse":{"type":"object","additionalProperties":false,"properties":{"validation":{"$ref":"#/components/schemas/VenueProviderValidation"}},"required":["validation"],"example":{"validation":{"id":"00000000-0000-0000-0000-000000000001","connectionId":"00000000-0000-0000-0000-000000000001","connectionVersion":1,"kind":"manifest","discoverySnapshotId":null,"state":"pending","resultCode":null,"observedManifestHash":null,"createdAt":"2026-09-14T12:00:00.000Z","finishedAt":null,"tradingReady":false}}},"VenueExistingAccountListResponse":{"type":"object","additionalProperties":false,"properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"accountNumber":{"type":"string"},"provider":{"type":"string"},"email":{"type":"string"},"status":{"type":"string","enum":["active","closed"]},"issuedAt":{"type":"string"},"balance":{"type":["string","null"],"description":"The paper balance, or null when the paper book holds no record of the account."},"currency":{"type":["string","null"],"description":"The account currency, or null when the paper book holds no record of the account."},"rules":{"const":"original"}},"required":["accountId","accountNumber","provider","email","status","issuedAt","balance","currency","rules"]}},"nextCursor":{"type":["string","null"]}},"required":["items","nextCursor"],"example":{"items":[{"accountId":"example-prior","accountNumber":"EVAL-PRIOR","provider":"paper","email":"trader@example.com","status":"active","issuedAt":"2026-09-14T12:00:00.000Z","balance":"50000","currency":"USD","rules":"original"}],"nextCursor":null}},"VenueAccountListResponse":{"type":"object","additionalProperties":false,"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/VenueAccountRow"}},"nextCursor":{"type":["string","null"]}},"required":["items","nextCursor"],"example":{"items":[{"accountId":"example-account","accountNumber":"EVAL-7C21A9","provider":"paper","purpose":"evaluation","balanceAuthority":"trdrs","currency":"USD","version":1,"groupId":"firm-meridian-evaluation","email":"trader@example.com","status":"active","issuedAt":"2026-09-14T12:00:00.000Z","balance":"50000","startingBalance":"50000","resetAt":null}],"nextCursor":null}},"VenueAccountIssueRequest":{"type":"object","additionalProperties":false,"properties":{"groupId":{"type":"string","description":"The group the account joins. It must have a route."},"email":{"type":"string","description":"The trader's sign-in email, at most 254 characters. The trader must already have a trdrs sign-in."},"startingBalance":{"type":"integer","minimum":1000,"maximum":10000000,"description":"The opening balance in `currency`, a whole number from 1,000 to 10,000,000."},"currency":{"type":"string","description":"The account currency. `USD` issues everywhere, posted in cents; `USDC` issues on the sandbox, posted in six decimals."},"riskPolicy":{"type":"object","additionalProperties":false,"properties":{"policyId":{"type":"string"}},"required":["policyId"],"description":"Your published risk policy the account is held to, by `policyId` alone: the account trades every product class the policy offers. The policy must be yours, published and in the account currency. Any other field is refused."},"positionMode":{"type":"string","enum":["net","independent_tickets"],"default":"net","description":"How the account holds its positions. `net`, the default, keeps one signed position per instrument. `independent_tickets` makes each opening order its own position, closed by naming it and never netted against an opposite one, and needs a policy that states ticket hedging for every product class it offers."},"referenceId":{"type":"string","maxLength":80,"description":"Your own reference for this issue, at most 80 characters. The same `referenceId` with the same request returns the account it already issued; with a different request it's refused."}},"required":["groupId","email","startingBalance","currency","riskPolicy","referenceId"],"example":{"groupId":"firm-meridian-evaluation","email":"trader@example.com","startingBalance":50000,"currency":"USD","riskPolicy":{"policyId":"meridian-futures"},"positionMode":"net","referenceId":"order-84117"}},"VenueAccountIssueResponse":{"type":"object","additionalProperties":false,"properties":{"account":{"$ref":"#/components/schemas/VenueIssuedAccount"}},"required":["account"],"example":{"account":{"accountId":"example-account","accountNumber":"EVAL-7C21A9","email":"trader@example.com","groupId":"firm-meridian-evaluation","book":"canonical","balance":"50000.00","currency":"USD","riskPolicy":{"policyId":"meridian-futures","version":"2026-10-01","sequence":1},"positionMode":"net","created":true}}},"VenueAccountBalanceRequest":{"type":"object","additionalProperties":false,"properties":{"op":{"type":"string","enum":["credit","debit","adjustment"],"description":"`credit` adds money, `debit` takes it away, and `adjustment` records a correction."},"amount":{"type":"number","exclusiveMinimum":0,"description":"A positive amount in the account currency, at most 1,000,000,000, with no more decimals than the currency posts in."},"comment":{"type":["string","null"],"maxLength":300,"description":"An optional note kept with the record, at most 300 characters."}},"required":["op","amount"],"example":{"op":"debit","amount":800,"comment":"payout 2026-08-31"}},"VenueAccountBalanceResponse":{"type":"object","additionalProperties":false,"properties":{"recorded":{"const":true},"accountId":{"type":"string"},"op":{"type":"string","enum":["credit","debit","adjustment"]},"amount":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"currency":{"type":"string"},"referenceId":{"type":"string"}},"required":["recorded","accountId","op","amount","currency","referenceId"],"example":{"recorded":true,"accountId":"example-account","op":"debit","amount":"800","currency":"USD","referenceId":"payout-2026-08-31-a"}},"VenueAccountResetRequest":{"type":"object","additionalProperties":false,"properties":{"comment":{"type":"string","minLength":1,"maxLength":300,"description":"Why you reset the account, at most 300 characters. It is required, and recorded with who reset it and when."}},"required":["comment"],"example":{"comment":"failed evaluation, second attempt"}},"VenueAccountResetResponse":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"reset":{"const":true},"referenceId":{"type":"string"}},"required":["accountId","reset","referenceId"],"example":{"accountId":"example-account","reset":true,"referenceId":"reset-2026-09-16-a"}},"VenueAccountHaltRequest":{"type":"object","additionalProperties":false,"properties":{},"required":[],"example":{}},"VenueAccountHaltResponse":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"halted":{"type":"boolean"}},"required":["accountId","halted"],"example":{"accountId":"example-account","halted":true}},"VenueAccountResumeRequest":{"type":"object","additionalProperties":false,"properties":{},"required":[],"example":{}},"VenueAccountResumeResponse":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"halted":{"type":"boolean"}},"required":["accountId","halted"],"example":{"accountId":"example-account","halted":false}},"VenueRiskControlsResponse":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"controls":{"$ref":"#/components/schemas/VenueRiskControls"},"currency":{"type":"string"},"halted":{"type":"boolean"},"lockReason":{"type":["string","null"]}},"required":["accountId","controls","currency","halted","lockReason"],"example":{"accountId":"example-account","controls":{"dailyLossEnabled":true,"dailyLossValue":1500,"weeklyLossEnabled":false,"weeklyLossValue":null,"dailyProfitEnabled":false,"dailyProfitValue":null,"weeklyProfitEnabled":false,"weeklyProfitValue":null,"eodCloseEnabled":true,"eodCloseValue":10,"updatedAt":1757980800},"currency":"USD","halted":false,"lockReason":null}},"VenueRiskControlsRequest":{"type":"object","additionalProperties":false,"properties":{"dailyLossEnabled":{"type":"boolean"},"dailyLossValue":{"type":["number","null"],"description":"A positive amount in the account currency when the control is enabled. Send null, or leave it out, when it is disabled."},"weeklyLossEnabled":{"type":"boolean"},"weeklyLossValue":{"type":["number","null"],"description":"A positive amount in the account currency when the control is enabled. Send null, or leave it out, when it is disabled."},"dailyProfitEnabled":{"type":"boolean"},"dailyProfitValue":{"type":["number","null"],"description":"A positive amount in the account currency when the control is enabled. Send null, or leave it out, when it is disabled."},"weeklyProfitEnabled":{"type":"boolean"},"weeklyProfitValue":{"type":["number","null"],"description":"A positive amount in the account currency when the control is enabled. Send null, or leave it out, when it is disabled."},"eodCloseEnabled":{"type":"boolean"},"eodCloseValue":{"type":["integer","null"],"minimum":1,"maximum":240,"description":"Whole minutes before the 16:00 Central time close, from 1 to 240, when the control is enabled. Send null, or leave it out, when it is disabled."}},"required":["dailyLossEnabled","weeklyLossEnabled","dailyProfitEnabled","weeklyProfitEnabled","eodCloseEnabled"],"example":{"dailyLossEnabled":true,"dailyLossValue":1500,"weeklyLossEnabled":false,"dailyProfitEnabled":false,"weeklyProfitEnabled":false,"eodCloseEnabled":true,"eodCloseValue":10}},"VenueAccountAnalyticsResponse":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"analytics":{"$ref":"#/components/schemas/VenueAccountAnalytics"}},"required":["accountId","analytics"],"example":{"accountId":"example-account","analytics":{"netTradingPnl":1250,"tradingDays":4,"complete":true}}},"VenueUsageResponse":{"type":"object","additionalProperties":false,"properties":{"firm":{"type":"string"},"month":{"type":"string"},"basis":{"type":"string","enum":["rithmic-system","unattributable"]},"activeAccounts":{"type":"integer"},"priceCentsPerActiveAccount":{"type":["integer","null"]},"amountCents":{"type":["integer","null"]},"currency":{"const":"USD"}},"required":["firm","month","basis","activeAccounts","priceCentsPerActiveAccount","amountCents","currency"],"example":{"firm":"Meridian Evaluation","month":"2026-08","basis":"rithmic-system","activeAccounts":42,"priceCentsPerActiveAccount":500,"amountCents":21000,"currency":"USD"}},"VenueUsageAccountsResponse":{"type":"object","additionalProperties":false,"properties":{"firm":{"type":"string"},"month":{"type":"string"},"basis":{"type":"string","enum":["rithmic-system","unattributable"]},"accounts":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"accountNumber":{"type":"string"},"fills":{"type":"integer"},"firstFillAt":{"type":"string","format":"date-time"},"lastFillAt":{"type":"string","format":"date-time"}},"required":["accountNumber","fills","firstFillAt","lastFillAt"]}}},"required":["firm","month","basis","accounts"],"example":{"firm":"Meridian Evaluation","month":"2026-08","basis":"rithmic-system","accounts":[{"accountNumber":"EVAL-7C21A9","fills":61,"firstFillAt":"2026-08-03T14:31:07.000Z","lastFillAt":"2026-08-28T19:58:40.000Z"}]}},"VenueBalanceReceiptResponse":{"type":"object","additionalProperties":false,"properties":{"referenceId":{"type":"string"},"accountNumber":{"type":"string"},"op":{"type":"string","enum":["credit","debit","adjustment"]},"amount":{"type":"string"},"currency":{"type":"string"},"state":{"type":"string","enum":["applied","legacy_unknown"]},"appliedAt":{"type":["string","null"],"format":"date-time"}},"required":["referenceId","accountNumber","op","amount","currency","state","appliedAt"],"example":{"referenceId":"payout-2026-08-31-a","accountNumber":"EVAL-7C21A9","op":"debit","amount":"800","currency":"USD","state":"applied","appliedAt":"2026-09-14T12:00:00.000Z"}},"VenueWebhookListResponse":{"type":"object","additionalProperties":false,"properties":{"webhooks":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"},"description":"The event types this endpoint receives. An empty list means every event."},"enabled":{"type":"boolean"},"secret":{"type":"string","description":"The signing secret. Each delivery carries a `trdrs-signature` header computed with it, which your endpoint checks."},"createdAt":{"type":"string","format":"date-time"}},"required":["id","url","events","enabled","secret","createdAt"]}},"eventTypes":{"type":"array","items":{"type":"string"}}},"required":["webhooks","eventTypes"],"example":{"webhooks":[{"id":"00000000-0000-0000-0000-000000000001","url":"https://backoffice.example.com/trdrs","events":[],"enabled":true,"secret":"trdrs_whsec_example","createdAt":"2026-09-14T12:00:00.000Z"}],"eventTypes":["registration.linked","registration.revoked","account.reset","balance.recorded","risk.locked","risk.unlocked"]}},"VenueWebhookCreateRequest":{"type":"object","additionalProperties":false,"properties":{"url":{"type":"string","maxLength":500,"description":"An `https` URL, at most 500 characters."},"events":{"type":"array","items":{"type":"string"},"description":"The event types to receive. Leave it out, or send an empty list, to receive every event."}},"required":["url"],"example":{"url":"https://backoffice.example.com/trdrs","events":["balance.recorded","risk.locked"]}},"VenueWebhookResponse":{"type":"object","additionalProperties":false,"properties":{"webhook":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"},"description":"The event types this endpoint receives. An empty list means every event."},"enabled":{"type":"boolean"},"secret":{"type":"string","description":"The signing secret. Each delivery carries a `trdrs-signature` header computed with it, which your endpoint checks."},"createdAt":{"type":"string","format":"date-time"}},"required":["id","url","events","enabled","secret","createdAt"]}},"required":["webhook"],"example":{"webhook":{"id":"00000000-0000-0000-0000-000000000001","url":"https://backoffice.example.com/trdrs","events":["balance.recorded","risk.locked"],"enabled":true,"secret":"trdrs_whsec_example","createdAt":"2026-09-14T12:00:00.000Z"}}},"VenueWebhookDeleteResponse":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"deleted":{"type":"boolean"}},"required":["id","deleted"],"example":{"id":"00000000-0000-0000-0000-000000000001","deleted":true}},"VenueWebhookTestRequest":{"type":"object","additionalProperties":false,"properties":{},"required":[],"example":{}},"VenueWebhookTestResponse":{"type":"object","additionalProperties":false,"properties":{"ok":{"type":"boolean"},"status":{"type":["integer","null"]},"detail":{"type":["string","null"]}},"required":["ok","status","detail"],"example":{"ok":false,"status":503,"detail":"endpoint answered 503"}},"VenueWebhookDeliveriesResponse":{"type":"object","additionalProperties":false,"properties":{"deliveries":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"eventType":{"type":"string"},"status":{"type":"string","enum":["pending","delivered","failed"]},"attempts":{"type":"integer"},"responseStatus":{"type":["integer","null"]},"lastError":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"lastAttemptAt":{"type":["string","null"],"format":"date-time"},"payload":{"type":"object"}},"required":["id","eventType","status","attempts","responseStatus","lastError","createdAt","lastAttemptAt","payload"]}}},"required":["deliveries"],"example":{"deliveries":[{"id":"00000000-0000-0000-0000-000000000001","eventType":"balance.recorded","status":"delivered","attempts":1,"responseStatus":200,"lastError":null,"createdAt":"2026-09-14T12:00:00.000Z","lastAttemptAt":"2026-09-14T12:00:00.000Z","payload":{"type":"balance.recorded","createdAt":"2026-09-14T12:00:00.000Z","data":{"accountNumber":"EVAL-7C21A9","op":"debit","amount":800,"currency":"USD","referenceId":"payout-2026-08-31-a"}}}]}},"VenueBrandResponse":{"type":"object","additionalProperties":false,"properties":{"brand":{"$ref":"#/components/schemas/VenueBrand"}},"required":["brand"],"example":{"brand":{"companyId":"00000000-0000-0000-0000-000000000001","name":"Meridian Evaluation","description":"Futures evaluations on the paper book","logoUrl":"/api/connect/companies/00000000-0000-0000-0000-000000000001/logo.png","logoBleed":true,"listingState":"draft","updatedAt":"2026-09-14T12:00:00.000Z"}}},"VenueBrandUpdateRequest":{"type":"object","additionalProperties":false,"minProperties":2,"required":["expectedUpdatedAt"],"properties":{"name":{"type":"string","minLength":1,"maxLength":60,"description":"The venue's name, 1 to 60 characters. Another company can't already use it."},"description":{"type":["string","null"],"maxLength":140,"description":"A short description, at most 140 characters. Null or an empty string clears it."},"expectedUpdatedAt":{"type":"string","format":"date-time","description":"The `updatedAt` of the brand you last read, exactly as it was returned."}},"example":{"name":"Meridian Futures","description":"Evaluation accounts for futures traders.","expectedUpdatedAt":"2026-09-14T12:00:00.000Z"}},"VenueLogoUploadRequest":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"string","format":"byte","maxLength":703000,"description":"The PNG, base64-encoded: at most 512 KiB before encoding, square, from 256 to 1,024 pixels a side."},"expectedUpdatedAt":{"type":"string","format":"date-time","description":"The `updatedAt` of the brand you last read, exactly as it was returned."}},"required":["data","expectedUpdatedAt"],"example":{"data":"iVBORw0KGgo…","expectedUpdatedAt":"2026-09-14T12:00:00.000Z"}},"VenueLogoUploadResponse":{"type":"object","additionalProperties":false,"properties":{"brand":{"$ref":"#/components/schemas/VenueBrand"},"logo":{"type":"object","additionalProperties":false,"properties":{"width":{"type":"integer"},"height":{"type":"integer"},"bleed":{"type":"boolean"}},"required":["width","height","bleed"]}},"required":["brand","logo"],"example":{"brand":{"companyId":"00000000-0000-0000-0000-000000000001","name":"Meridian Evaluation","description":"Futures evaluations on the paper book","logoUrl":"/api/connect/companies/00000000-0000-0000-0000-000000000001/logo.png","logoBleed":true,"listingState":"draft","updatedAt":"2026-09-14T12:00:00.000Z"},"logo":{"width":512,"height":512,"bleed":true}}},"VenueInstrumentReferenceResponse":{"type":"object","additionalProperties":false,"properties":{"instruments":{"type":"array","items":{"$ref":"#/components/schemas/ContractSpec"}}},"required":["instruments"],"example":{"instruments":[{"root":"ES","name":"E-mini S&P 500","exchange":"CME","tickSize":0.25,"tickValue":12.5,"multiplier":50,"cycle":"quarterly"}]}},"VenueHedgeReportResponse":{"$ref":"#/components/schemas/VenueHedgeReport","example":{"policies":[],"activations":[],"targets":[],"intents":[],"incidents":[],"metrics":{"complete":true,"unresolvedIntents":0,"executions":0,"feesByCurrency":{},"slippageBps":null,"missingFeeRecords":0}}},"VenueHedgePolicyRequest":{"type":"object","additionalProperties":false,"properties":{"groupId":{"type":"string","description":"The group whose customer exposure is hedged."},"name":{"type":"string"},"destinationAccountId":{"type":"string","format":"uuid","description":"The venue-owned provider account the hedge trades in."},"ratio":{"type":"string","description":"The share of the group's exposure to hedge, a decimal string from 0 to 1."},"quantityCap":{"type":["string","null"],"description":"The largest hedge position, in the instrument's quantity unit and above zero, or null for no cap."},"notionalCap":{"type":["string","null"],"description":"The largest hedge notional, above zero, or null for no cap."},"residualThreshold":{"type":"string","description":"The smallest change in the hedge target, in the instrument's quantity unit, that sends an order. A smaller change waits."}},"required":["groupId","name","destinationAccountId","ratio","quantityCap","notionalCap","residualThreshold"],"example":{"groupId":"standard","name":"Standard 100% hedge","destinationAccountId":"00000000-0000-0000-0000-000000000001","ratio":"1","quantityCap":null,"notionalCap":null,"residualThreshold":"0.001"}},"VenueHedgePolicyResponse":{"type":"object","additionalProperties":false,"properties":{"policy":{"$ref":"#/components/schemas/VenueHedgePolicy"}},"required":["policy"],"example":{"policy":{"id":"00000000-0000-0000-0000-000000000001","venueId":"00000000-0000-0000-0000-000000000001","environment":"sandbox","groupId":"standard","name":"Standard 100% hedge","destinationAccountId":"00000000-0000-0000-0000-000000000001","ratio":"1","quantityCap":null,"notionalCap":null,"residualThreshold":"0.001","createdAt":"2026-09-14T12:00:00.000Z"}}},"VenueHedgeActivationRequest":{"type":"object","additionalProperties":false,"properties":{"policyId":{"type":"string","format":"uuid"},"state":{"type":"string","enum":["active","paused","stopped"]},"expectedRevision":{"type":["integer","null"],"minimum":1,"description":"Null for the policy's first activation, then its current revision."}},"required":["policyId","state","expectedRevision"],"example":{"policyId":"00000000-0000-0000-0000-000000000001","state":"active","expectedRevision":null}},"VenueHedgeActivationResponse":{"type":"object","additionalProperties":false,"properties":{"activation":{"$ref":"#/components/schemas/VenueHedgeActivation"}},"required":["activation"],"example":{"activation":{"venueId":"00000000-0000-0000-0000-000000000001","environment":"sandbox","groupId":"standard","policyId":"00000000-0000-0000-0000-000000000001","state":"active","revision":1,"activatedAt":"2026-09-14T12:00:00.000Z"}}},"VenueHedgeCalculateRequest":{"type":"object","additionalProperties":false,"required":["groupId","instrumentId","markPrice","markObservedAt"],"properties":{"groupId":{"type":"string"},"instrumentId":{"type":"string"},"markPrice":{"type":"string","description":"The mark to value the exposure at, as a decimal string."},"markObservedAt":{"type":"string","format":"date-time","description":"When the mark was observed, as an ISO 8601 UTC timestamp with milliseconds. It must be fresh."},"dryRun":{"type":"boolean","description":"True to calculate without writing a target, an order, an audit event or a webhook."}},"example":{"groupId":"standard","instrumentId":"BINANCE:BTCUSDT","markPrice":"65000","markObservedAt":"2026-09-14T12:00:00.000Z","dryRun":true}},"VenueHedgeCalculateResponse":{"type":"object","additionalProperties":false,"properties":{"target":{"$ref":"#/components/schemas/VenueHedgeTarget"},"intent":{"oneOf":[{"$ref":"#/components/schemas/VenueHedgeIntent"},{"type":"null"}]}},"required":["target","intent"],"example":{"target":{"id":"00000000-0000-0000-0000-000000000001","sourceQuantity":"1","targetQuantity":"1","confirmedQuantity":"0","pendingQuantity":"1","residualQuantity":"0"},"intent":{"id":"00000000-0000-0000-0000-000000000001","state":"prepared","deltaQuantity":"1"}}},"VenueHedgeEmptyRequest":{"type":"object","additionalProperties":false,"properties":{},"required":[],"example":{}},"VenueHedgeIntentResponse":{"type":"object","additionalProperties":false,"properties":{"intent":{"$ref":"#/components/schemas/VenueHedgeIntent"}},"required":["intent"],"example":{"intent":{"id":"00000000-0000-0000-0000-000000000001","state":"accepted"}}},"VenueHedgeReconcileResponse":{"type":"object","example":{"intent":{"id":"00000000-0000-0000-0000-000000000001","state":"filled"},"confirmedQuantity":"1","pendingQuantity":"0"}},"VenueHedgeEmergencyStopRequest":{"type":"object","additionalProperties":false,"properties":{"reason":{"type":"string","minLength":1,"maxLength":300,"description":"Why you stopped hedging, 1 to 300 characters. It is recorded with the stop."}},"required":["reason"],"example":{"reason":"provider stream is unavailable"}},"VenueHedgeEmergencyStopResponse":{"type":"object","additionalProperties":false,"properties":{"stoppedPolicies":{"type":"integer"},"cancelledIntents":{"type":"integer"},"openIncidents":{"type":"integer"}},"required":["stoppedPolicies","cancelledIntents","openIncidents"],"example":{"stoppedPolicies":1,"cancelledIntents":0,"openIncidents":1}},"VenueHedgeFlattenRequest":{"type":"object","additionalProperties":false,"properties":{"destinationAccountId":{"type":"string","format":"uuid"}},"required":["destinationAccountId"],"example":{"destinationAccountId":"00000000-0000-0000-0000-000000000001"}},"VenueHedgeFlattenResponse":{"type":"object","additionalProperties":false,"properties":{"destinationAccountId":{"type":"string","format":"uuid"},"state":{"const":"flatten_requested"}},"required":["destinationAccountId","state"],"example":{"destinationAccountId":"00000000-0000-0000-0000-000000000001","state":"flatten_requested"}},"VenueRiskResponse":{"type":"object","additionalProperties":false,"properties":{"risk":{"type":"object","additionalProperties":false,"properties":{"venueId":{"type":"string","format":"uuid"},"environment":{"type":"string","enum":["sandbox","production"]},"asOf":{"type":"string","format":"date-time"},"snapshot":{"type":"object","additionalProperties":false,"properties":{"basis":{"const":"single_transaction"},"isolation":{"const":"repeatable_read"}},"required":["basis","isolation"]},"currency":{"type":["string","null"]},"currencies":{"type":"array","items":{"type":"string"}},"scope":{"type":"object","additionalProperties":false,"properties":{"listed":{"type":"integer"},"included":{"type":"integer"},"excluded":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"reason":{"type":"string","enum":["provider_book_not_synchronized","account_unreadable"]}},"required":["accountId","reason"]}},"limit":{"const":500},"limitExceeded":{"type":"boolean"}},"required":["listed","included","excluded","limit","limitExceeded"],"description":"Which accounts the read covers, at most 500. An account held at a provider keeps its positions there and is listed under `excluded`, as is one that couldn't be read."},"markPolicy":{"type":"object","additionalProperties":false,"properties":{"basis":{"const":"risk_decisions"},"notional":{"const":"quantity_times_mark_times_multiplier"},"valuationCurrency":{"const":"account_currency"}},"required":["basis","notional","valuationCurrency"],"description":"How positions are valued: each at the price its account's own risk decisions valued it at (`basis` `risk_decisions`), and notional is quantity times that price times the contract multiplier, in the account currency."},"totals":{"type":"object","additionalProperties":false,"properties":{"balance":{"type":["number","null"]},"equity":{"type":["number","null"]},"unrealizedPnl":{"type":["number","null"]},"grossRealizedPnl":{"type":["number","null"]},"fees":{"type":["number","null"]},"netTradingPnl":{"type":["number","null"]},"balanceAdjustments":{"type":["number","null"]}},"required":["balance","equity","unrealizedPnl","grossRealizedPnl","fees","netTradingPnl","balanceAdjustments"],"description":"Sums across the included accounts, stated only when every one of them answered in one currency. A sum a missing mark would change is null, never partial. Money is exact and stated once at the currency's precision, rounded half to even: cents for US dollars, six decimals for USDC."},"counts":{"type":"object","additionalProperties":false,"properties":{"openPositions":{"type":"integer"},"workingOrders":{"type":"integer"},"accountsWithPositions":{"type":"integer"},"halted":{"type":"integer"},"breaches":{"type":"integer"},"incompleteAccounts":{"type":"integer"},"unmarkedPositions":{"type":"integer"}},"required":["openPositions","workingOrders","accountsWithPositions","halted","breaches","incompleteAccounts","unmarkedPositions"]},"grossNotional":{"type":["number","null"]},"exposure":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"instrument":{"type":"string"},"mark":{"type":["number","null"]},"multiplier":{"type":["number","null"]},"long":{"type":"number"},"short":{"type":"number"},"net":{"type":"number"},"gross":{"type":"number"},"accounts":{"type":"integer"},"longNotional":{"type":["number","null"]},"shortNotional":{"type":["number","null"]},"netNotional":{"type":["number","null"]},"grossNotional":{"type":["number","null"]},"unrealizedPnl":{"type":["number","null"]},"dataStatus":{"type":"string","enum":["marked","no_fresh_mark","unknown_instrument"]},"hedges":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"groupId":{"type":"string"},"instrumentId":{"type":"string"},"sourceQuantity":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"targetQuantity":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"confirmedQuantity":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"pendingQuantity":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"residualQuantity":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"markPrice":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"calculatedAt":{"type":"string","format":"date-time"}},"required":["groupId","instrumentId","sourceQuantity","targetQuantity","confirmedQuantity","pendingQuantity","residualQuantity","markPrice","calculatedAt"],"description":"A hedge target as the hedge calculation stated it at `calculatedAt`. It is listed beside the customer exposure in the same instrument and never netted into it."}}},"required":["instrument","mark","multiplier","long","short","net","gross","accounts","longNotional","shortNotional","netNotional","grossNotional","unrealizedPnl","dataStatus","hedges"]},"description":"Customer exposure by instrument. Its money is null when the included accounts hold more than one currency."},"positions":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"accountNumber":{"type":"string"},"email":{"type":["string","null"]},"groupId":{"type":["string","null"]},"instrument":{"type":"string"},"positionId":{"type":["string","null"]},"side":{"type":"string","enum":["long","short"]},"quantity":{"type":"number"},"averagePrice":{"type":"number"},"mark":{"type":["number","null"]},"multiplier":{"type":["number","null"]},"notional":{"type":["number","null"]},"unrealizedPnl":{"type":["number","null"]},"realizedPnl":{"type":"number"},"dataStatus":{"type":"string","enum":["marked","no_fresh_mark","unknown_instrument"]}},"required":["accountId","accountNumber","email","groupId","instrument","positionId","side","quantity","averagePrice","mark","multiplier","notional","unrealizedPnl","realizedPnl","dataStatus"]}},"orders":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"accountNumber":{"type":"string"},"instrument":{"type":"string"},"side":{"type":"string","enum":["buy","sell"]},"quantity":{"type":"number"},"orderType":{"type":"string"},"limitPrice":{"type":["number","null"]},"stopPrice":{"type":["number","null"]},"reduceOnly":{"type":"boolean"}},"required":["accountId","accountNumber","instrument","side","quantity","orderType","limitPrice","stopPrice","reduceOnly"]}},"accounts":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"accountNumber":{"type":"string"},"email":{"type":["string","null"]},"groupId":{"type":["string","null"]},"status":{"type":["string","null"]},"currency":{"type":"string"},"positionModel":{"type":"string","enum":["net","independent_tickets"]},"balance":{"type":"number"},"equity":{"type":["number","null"]},"unrealizedPnl":{"type":["number","null"]},"netTradingPnl":{"type":"number"},"fees":{"type":"number"},"positions":{"type":"integer"},"orders":{"type":"integer"},"halted":{"type":"boolean"},"breaches":{"type":"integer"},"complete":{"type":"boolean"},"reasons":{"type":"array","items":{"type":"string"}}},"required":["accountId","accountNumber","email","groupId","status","currency","positionModel","balance","equity","unrealizedPnl","netTradingPnl","fees","positions","orders","halted","breaches","complete","reasons"]}},"hedging":{"oneOf":[{"type":"object","additionalProperties":false,"properties":{"state":{"const":"unavailable"},"reason":{"type":"string","enum":["hedging_not_configured","hedge_read_not_permitted"]}},"required":["state","reason"]},{"type":"object","additionalProperties":false,"properties":{"state":{"const":"reported"},"targets":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"groupId":{"type":"string"},"instrumentId":{"type":"string"},"sourceQuantity":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"targetQuantity":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"confirmedQuantity":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"pendingQuantity":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"residualQuantity":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"markPrice":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"calculatedAt":{"type":"string","format":"date-time"}},"required":["groupId","instrumentId","sourceQuantity","targetQuantity","confirmedQuantity","pendingQuantity","residualQuantity","markPrice","calculatedAt"],"description":"A hedge target as the hedge calculation stated it at `calculatedAt`. It is listed beside the customer exposure in the same instrument and never netted into it."}},"policies":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"groupId":{"type":"string"},"name":{"type":"string"},"ratio":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"state":{"type":["string","null"],"enum":["active","paused","stopped",null]}},"required":["id","groupId","name","ratio","state"]}},"openIncidents":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"groupId":{"type":"string"},"instrumentId":{"type":"string"},"reason":{"type":"string"},"openedAt":{"type":"string","format":"date-time"}},"required":["id","groupId","instrumentId","reason","openedAt"]}},"intents":{"type":"object","additionalProperties":false,"properties":{"total":{"type":"integer"},"unresolved":{"type":"integer"},"prepared":{"type":"integer"}},"required":["total","unresolved","prepared"]},"metrics":{"type":"object"}},"required":["state","targets","policies","openIncidents","intents","metrics"]}]},"history":{"type":"object","description":"Equity history, built from the samples written once a minute for each account and grouped into buckets (`basis` `minute_bucket_samples`). A `state` of `unavailable` carries a `reason`, `scope_not_totalable` or `no_samples_in_window`, and no points. A point is complete only when every account in scope that existed by then was sampled in its bucket exactly once; otherwise its balance and equity are null and `reason` says why (`accounts_not_sampled`, `reset_in_bucket` or `equity_unmarked`). `skewMs` is the time between the first and last sample in the bucket."},"completeness":{"type":"object","additionalProperties":false,"properties":{"complete":{"type":"boolean"},"reasons":{"type":"array","items":{"type":"string","enum":["account_limit_exceeded","accounts_excluded","mixed_currency","account_data_incomplete","mark_unavailable"]}}},"required":["complete","reasons"]}},"required":["venueId","environment","asOf","snapshot","currency","currencies","scope","markPolicy","totals","counts","grossNotional","exposure","positions","orders","accounts","hedging","history","completeness"]}},"required":["risk"],"example":{"risk":{"venueId":"00000000-0000-0000-0000-000000000001","environment":"sandbox","asOf":"2026-09-14T12:00:00.000Z","snapshot":{"basis":"single_transaction","isolation":"repeatable_read"},"currency":"USD","currencies":["USD"],"scope":{"listed":2,"included":2,"excluded":[],"limit":500,"limitExceeded":false},"markPolicy":{"basis":"risk_decisions","notional":"quantity_times_mark_times_multiplier","valuationCurrency":"account_currency"},"totals":{"balance":99997,"equity":101497,"unrealizedPnl":1500,"grossRealizedPnl":0,"fees":3,"netTradingPnl":-3,"balanceAdjustments":0},"counts":{"openPositions":2,"workingOrders":0,"accountsWithPositions":2,"halted":0,"breaches":0,"incompleteAccounts":0,"unmarkedPositions":0},"grossNotional":903000,"exposure":[{"instrument":"ES","mark":6020,"multiplier":50,"long":2,"short":1,"net":1,"gross":3,"accounts":2,"longNotional":602000,"shortNotional":301000,"netNotional":301000,"grossNotional":903000,"unrealizedPnl":1500,"dataStatus":"marked","hedges":[]}],"positions":[{"accountId":"acct:EVAL-7C21A9","accountNumber":"EVAL-7C21A9","email":"trader@example.com","groupId":"desk-a","instrument":"ES","positionId":null,"side":"long","quantity":2,"averagePrice":6000,"mark":6020,"multiplier":50,"notional":602000,"unrealizedPnl":2000,"realizedPnl":0,"dataStatus":"marked"}],"orders":[],"accounts":[],"hedging":{"state":"unavailable","reason":"hedging_not_configured"},"history":{"basis":"minute_bucket_samples","intervalMinutes":5,"windowMinutes":1440,"since":"2026-09-14T12:00:00.000Z","until":"2026-09-14T12:00:00.000Z","state":"unavailable","reason":"no_samples_in_window","points":[]},"completeness":{"complete":true,"reasons":[]}}}},"VenueDiscoveryResponse":{"type":"object","additionalProperties":false,"properties":{"discoverySnapshotId":{"type":"string","format":"uuid"},"expiresAt":{"type":"string","format":"date-time"},"items":{"type":"array","items":{"$ref":"#/components/schemas/VenueDiscoveredAccount"}},"nextCursor":{"type":["string","null"]},"tradingReady":{"const":false}},"required":["discoverySnapshotId","expiresAt","items","nextCursor","tradingReady"],"example":{"discoverySnapshotId":"00000000-0000-0000-0000-000000000001","expiresAt":"2026-09-14T12:00:00.000Z","items":[{"externalAccountId":"EXTERNAL-1","label":"Example account","currency":"USD","positionModel":"net","permissions":{"read":true,"trade":true}}],"nextCursor":null,"tradingReady":false}},"VenueBindRequest":{"type":"object","additionalProperties":false,"properties":{"mode":{"type":"string","enum":["connect","hedge"],"description":"`connect` binds a customer account. `hedge` binds a hedge destination, and only the Venue key route accepts it: the back office refuses it with `400`."},"connectionId":{"type":"string","format":"uuid"},"externalAccountId":{"type":"string","description":"The account's `externalAccountId` from the discovery."},"discoverySnapshotId":{"type":"string","format":"uuid","description":"The `discoverySnapshotId` of the discovery that found the account."}},"required":["mode","connectionId","externalAccountId","discoverySnapshotId"],"example":{"mode":"connect","connectionId":"00000000-0000-0000-0000-000000000001","externalAccountId":"EXTERNAL-1","discoverySnapshotId":"00000000-0000-0000-0000-000000000001"}},"VenueBindResponse":{"type":"object","additionalProperties":false,"properties":{"account":{"$ref":"#/components/schemas/VenueConnectedAccount"}},"required":["account"],"example":{"account":{"accountId":"example-account","currency":"USD","connectionId":"00000000-0000-0000-0000-000000000001","externalAccountId":"EXTERNAL-1","canRead":true,"canTrade":true,"state":"bound","tradingReady":false}}},"VenueReadResponse":{"type":"object","additionalProperties":false,"properties":{"venue":{"$ref":"#/components/schemas/VenueRecord"}},"required":["venue"],"example":{"venue":{"id":"00000000-0000-0000-0000-000000000001","organizationId":"00000000-0000-0000-0000-000000000001","legacyFirmId":null,"name":"Example venue","description":null,"environment":"sandbox","state":"draft","version":1,"createdAt":"2026-09-14T12:00:00.000Z","rules":{"enabled":false,"applies":{"orders":true,"fills":true,"stages":true},"appliesAtProvider":{"orders":false,"fills":false,"stages":false}},"company":{"id":"00000000-0000-0000-0000-000000000001","name":"Meridian Evaluation","blurb":"Futures evaluations on the paper book","logoUrl":null,"logoBleed":false,"referralUrl":null,"sortOrder":100,"kind":"prop","builtInProvider":null,"connectsTraders":false,"pluggable":false,"runsVenue":true,"listingState":"listed","enabled":true,"createdAt":"2026-09-14T12:00:00.000Z","updatedAt":"2026-09-14T12:00:00.000Z"}}}},"VenueInstrumentListResponse":{"type":"object","additionalProperties":false,"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/VenueInstrumentCandidate"}},"nextCursor":{"type":["string","null"]}},"required":["items","nextCursor"],"example":{"items":[],"nextCursor":null}},"VenueInstrumentSaveRequest":{"type":"object","additionalProperties":false,"properties":{"specification":{"$ref":"#/components/schemas/VenueInstrumentCandidateSpecification"}},"required":["specification"],"example":{"specification":{"instrumentId":"BTCUSD","version":"v1","venueId":"00000000-0000-0000-0000-000000000001","symbol":"BTCUSD","name":"Bitcoin / USD","productModel":"linear_spot","quoteCurrency":"USD","settlementCurrency":"USD","negativePrices":false,"quantity":{"unit":"base_units","lotSize":"1","min":"0.001","max":"100","step":"0.001"},"contractMultiplier":"1","minNotional":"10","ticks":[{"from":"0","to":null,"size":"0.01"}],"orderTypes":["market","limit"],"timeInForce":["gtc"],"mappings":[],"sessions":{"timezone":"UTC","coverageFrom":"2026-01-01","coverageThrough":"2026-12-31","weekly":[{"day":0,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":1,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":2,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":3,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":4,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":5,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":6,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]}],"holidays":[]},"expiresAt":null,"lastTradeAt":null,"pricing":{"sourceId":"example-feed","stopTrigger":"last","maxAgeMs":1000},"entitlement":null,"state":"enabled"}}},"VenueInstrumentSaveResponse":{"type":"object","additionalProperties":false,"properties":{"instrument":{"$ref":"#/components/schemas/VenueInstrumentCandidate"}},"required":["instrument"],"example":{"instrument":{"id":"00000000-0000-0000-0000-000000000001","venueId":"00000000-0000-0000-0000-000000000001","environment":"sandbox","specification":{"instrumentId":"BTCUSD","version":"v1","venueId":"00000000-0000-0000-0000-000000000001","symbol":"BTCUSD","name":"Bitcoin / USD","productModel":"linear_spot","quoteCurrency":"USD","settlementCurrency":"USD","negativePrices":false,"quantity":{"unit":"base_units","lotSize":"1","min":"0.001","max":"100","step":"0.001"},"contractMultiplier":"1","minNotional":"10","ticks":[{"from":"0","to":null,"size":"0.01"}],"orderTypes":["market","limit"],"timeInForce":["gtc"],"mappings":[],"sessions":{"timezone":"UTC","coverageFrom":"2026-01-01","coverageThrough":"2026-12-31","weekly":[{"day":0,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":1,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":2,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":3,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":4,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":5,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":6,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]}],"holidays":[]},"expiresAt":null,"lastTradeAt":null,"pricing":{"sourceId":"example-feed","stopTrigger":"last","maxAgeMs":1000},"entitlement":null,"state":"enabled"},"contentHash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","createdAt":"2026-09-14T12:00:00.000Z","state":"candidate","tradingReady":false}}},"VenueRouteListResponse":{"type":"object","additionalProperties":false,"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/VenueRoutePolicy"}},"nextCursor":{"type":["string","null"]}},"required":["items","nextCursor"],"example":{"items":[],"nextCursor":null}},"VenueRouteSaveRequest":{"type":"object","additionalProperties":false,"properties":{"routeId":{"type":"string","description":"Your id for the route."},"name":{"type":"string"},"mode":{"type":"string","enum":["internal","external"],"description":"`internal` fills on the paper book; `external` sends orders to a provider account."},"connectionId":{"type":["string","null"],"format":"uuid","description":"The provider connection an external route uses. Required for `external`, and must be absent for `internal`."},"externalAccountId":{"type":["string","null"],"description":"The dedicated provider account an external route trades in. Required for `external`, and must be absent for `internal`."},"state":{"type":"string","enum":["offered","retired"],"description":"`retired` stops new groups taking the route and keeps it serving the groups already on it."},"collar":{"$ref":"#/components/schemas/VenueCollarPolicy","description":"How far past a fresh quote a fill may still be accepted. Leaving it out means zero adverse ticks, the strictest collar, not no collar."},"feeReservePerUnit":{"type":"string","description":"An exact decimal string, such as `\"12.5\"`, with at most 18 digits after the point and no exponent."},"uncappedMarketAllowed":{"type":"boolean","description":"Whether a market order may go out with no price cap, leaving the protection to the provider. It defaults to false and is refused on an internal route, where the collar is the protection."},"expectedRevision":{"type":["integer","null"],"minimum":1,"description":"Null to create the route, then its current revision."}},"required":["routeId","name","mode","connectionId","externalAccountId","state","collar","feeReservePerUnit","uncappedMarketAllowed","expectedRevision"],"example":{"routeId":"lp-primary","name":"Primary LP","mode":"external","connectionId":"00000000-0000-0000-0000-000000000001","externalAccountId":"EXT-LP","collar":{"kind":"ticks","maxAdverseTicks":4},"feeReservePerUnit":"2.50","uncappedMarketAllowed":false,"expectedRevision":null}},"VenueRouteSaveResponse":{"type":"object","additionalProperties":false,"properties":{"route":{"$ref":"#/components/schemas/VenueRoutePolicy"}},"required":["route"],"example":{"route":{"routeId":"lp-primary","name":"Primary LP","mode":"external","connectionId":"00000000-0000-0000-0000-000000000001","externalAccountId":"EXT-LP","state":"offered","revision":1,"version":"lp-primary:1"}}},"VenueGroupRouteRequest":{"type":"object","additionalProperties":false,"properties":{"routeId":{"type":["string","null"],"description":"The route to use, or null to remove the group's route."}},"required":["routeId"],"example":{"routeId":"lp-primary"}},"VenueGroupRouteResponse":{"type":"object","additionalProperties":false,"properties":{"group":{"type":"object","additionalProperties":false,"properties":{"groupId":{"type":"string"},"routeId":{"type":["string","null"]},"revision":{"type":"integer"}},"required":["groupId","routeId","revision"]}},"required":["group"],"example":{"group":{"groupId":"professional","routeId":"lp-primary","revision":2}}},"VenueAccountInstrumentsResponse":{"type":"object","additionalProperties":false,"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/VenueAccountInstrument"}},"nextCursor":{"type":["string","null"]},"basis":{"const":"account_configuration_and_policy"}},"required":["items","nextCursor","basis"],"example":{"items":[{"instrumentId":"BTC-USD-SPOT","symbol":"BTCUSD","instrumentVersionId":"00000000-0000-0000-0000-000000000001","version":"v1","blockedBy":[],"poolRefusal":null,"tradingReady":false},{"instrumentId":"ETH-USD-SPOT","symbol":"ETHUSD","instrumentVersionId":"00000000-0000-0000-0000-000000000001","version":"v1","blockedBy":["entry_halted"],"poolRefusal":{"code":"product_economics_unsupported","params":{}},"tradingReady":false}],"nextCursor":null,"basis":"account_configuration_and_policy"}},"VenueCustomerLedgerResponse":{"type":"object","additionalProperties":false,"properties":{"ledger":{"$ref":"#/components/schemas/VenueCustomerLedger"},"route":{"oneOf":[{"$ref":"#/components/schemas/VenueRoutePolicy"},{"type":"null"}]}},"required":["ledger","route"],"example":{"ledger":{"accountId":"example-account","currency":"USD","balance":"25000.00","reserved":"1000.00","revision":4,"incomplete":false,"positions":[]},"route":null}},"VenueLiquidationIncidentResponse":{"type":"object","additionalProperties":false,"properties":{"incident":{"$ref":"#/components/schemas/VenueLiquidationIncident"}},"required":["incident"],"example":{"incident":null}},"VenueConditionProfileListResponse":{"type":"object","additionalProperties":false,"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/VenueConditionProfileRecord"}},"nextCursor":{"type":["string","null"]}},"required":["items","nextCursor"],"example":{"items":[],"nextCursor":null}},"VenueConditionProfileSaveRequest":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"profile":{"$ref":"#/components/schemas/VenueConditionProfile"}},"required":["name","profile"],"example":{"name":"Standard","profile":{"margin":null,"commission":{"kind":"perUnit","timing":"fill","direction":"both","unit":"quantity","amount":"2.50","currency":"USD","orderMinimum":null},"markup":{"buyMarkupTicks":0,"sellMarkupTicks":0},"risk":{"maxOrderQuantity":"10","maxPositionQuantity":null,"maxPositionNotional":null,"instrumentAllowlist":null,"dailyLossLimit":null,"weeklyLossLimit":null,"entryHalted":false}}}},"VenueConditionProfileSaveResponse":{"type":"object","additionalProperties":false,"properties":{"profile":{"$ref":"#/components/schemas/VenueConditionProfileRecord"}},"required":["profile"],"example":{"profile":{"id":"00000000-0000-0000-0000-000000000001","venueId":"00000000-0000-0000-0000-000000000001","environment":"sandbox","name":"Standard","profile":{"margin":null,"commission":{"kind":"perUnit","timing":"fill","direction":"both","unit":"quantity","amount":"2.50","currency":"USD","orderMinimum":null},"markup":{"buyMarkupTicks":0,"sellMarkupTicks":0},"risk":{"maxOrderQuantity":"10","maxPositionQuantity":null,"maxPositionNotional":null,"instrumentAllowlist":null,"dailyLossLimit":null,"weeklyLossLimit":null,"entryHalted":false}},"contentHash":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc","createdAt":"2026-09-14T12:00:00.000Z","state":"published","inForce":false}}},"VenueConditionActivationRequest":{"type":"object","additionalProperties":false,"properties":{"profileId":{"type":"string","format":"uuid"},"expectedRevision":{"type":["integer","null"],"minimum":1,"description":"Null when no profile is in force yet, then the current revision."}},"required":["profileId","expectedRevision"],"example":{"profileId":"00000000-0000-0000-0000-000000000001","expectedRevision":null}},"VenueConditionActivationResponse":{"type":"object","additionalProperties":false,"properties":{"activation":{"type":"object","additionalProperties":false,"properties":{"profileId":{"type":"string","format":"uuid"},"revision":{"type":"integer"},"activatedAt":{"type":"string","format":"date-time"}},"required":["profileId","revision","activatedAt"]}},"required":["activation"],"example":{"activation":{"profileId":"00000000-0000-0000-0000-000000000001","revision":1,"activatedAt":"2026-09-14T12:00:00.000Z"}}},"VenueConditionPreviewRequest":{"type":"object","description":"Either `{ profileId }` for a published profile, or `{ groupId, override }` for a proposed group override.","example":{"profileId":"00000000-0000-0000-0000-000000000001"}},"VenueConditionPreviewResponse":{"type":"object","additionalProperties":false,"properties":{"preview":{"$ref":"#/components/schemas/VenueConditionPreview"}},"required":["preview"],"example":{"preview":{"scope":"venue","economicChange":true,"affectedAccounts":4,"blockers":[{"accountId":"example-account","reason":"position_open"}]}}},"VenueAccountGroupListResponse":{"type":"object","additionalProperties":false,"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/VenueAccountGroup"}},"nextCursor":{"type":["string","null"]}},"required":["items","nextCursor"],"example":{"items":[],"nextCursor":null}},"VenueAccountGroupSaveRequest":{"type":"object","additionalProperties":false,"properties":{"groupId":{"type":"string","description":"Your id for the group."},"name":{"type":"string"},"override":{"$ref":"#/components/schemas/VenueGroupOverride"},"stageId":{"type":["string","null"],"description":"The stage the group's accounts run, or null for none."},"expectedRevision":{"type":["integer","null"],"minimum":1,"description":"Null to create the group, then its current revision."}},"required":["groupId","name","override","stageId","expectedRevision"],"example":{"groupId":"professional","name":"Professional","override":{"risk":{"maxOrderQuantity":"5"}},"expectedRevision":null}},"VenueAccountGroupSaveResponse":{"type":"object","additionalProperties":false,"properties":{"group":{"$ref":"#/components/schemas/VenueAccountGroup"}},"required":["group"],"example":{"group":{"groupId":"professional","name":"Professional","override":{"risk":{"maxOrderQuantity":"5"}},"revision":1,"activatedAt":"2026-09-14T12:00:00.000Z"}}},"VenueStageEligibilityResponse":{"type":"object","additionalProperties":false,"properties":{"eligibility":{"$ref":"#/components/schemas/VenueStageEligibility"}},"required":["eligibility"],"example":{"eligibility":{"stageId":"evaluation-1","policyId":"00000000-0000-0000-0000-000000000001","activationRevision":1,"economicHash":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc","routingPolicyId":"00000000-0000-0000-0000-000000000001","routingActivationRevision":1,"cycleId":"cycle:2026-09-14T12:00:00.000Z","snapshotRevision":1,"facts":{"netTradingPnl":"2500","currency":"USD","tradingDays":7,"breaches":[],"observedRules":["stop_out"],"flat":true,"workingOrders":0,"unresolvedCommands":0,"complete":true,"accountActive":true,"halted":true,"accountRevision":42,"decidedRevision":42},"verdict":{"eligible":true,"reasons":[],"evaluated":["history_complete","account_active","net_trading_profit","minimum_trading_days","flat","no_working_orders","no_unresolved_commands","disqualifying_rules_observed","disqualifying_breaches","venue_pause","successor_configuration"]}}}},"VenueStageAdvanceRequest":{"type":"object","additionalProperties":false,"properties":{"startingAllocation":{"oneOf":[{"$ref":"#/components/schemas/VenueRational"},{"type":"null"}],"description":"The successor's opening balance as an exact fraction. It is required, and null is a real value meaning a successor with a zero balance."}},"required":["startingAllocation"],"example":{"startingAllocation":{"numerator":"10000000","denominator":"100"}}},"VenueStageAdvanceResponse":{"type":"object","additionalProperties":false,"properties":{"advance":{"$ref":"#/components/schemas/VenueStageAdvance"}},"required":["advance"],"example":{"advance":{"state":"advanced","targetAccountId":"funded-account-1","cycleId":"cycle:2026-09-14T12:00:00.000Z","stageId":"evaluation-1","policyId":"00000000-0000-0000-0000-000000000001","transitionReference":"stage-9f1c2b7e4a5d80361c2b7e4a5d803612"}}},"VenueStagePolicyListResponse":{"type":"object","additionalProperties":false,"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/VenueStagePolicyRecord"}},"nextCursor":{"type":["string","null"]}},"required":["items","nextCursor"],"example":{"items":[{"id":"00000000-0000-0000-0000-000000000001","venueId":"00000000-0000-0000-0000-000000000001","environment":"sandbox","stageId":"evaluation-1","name":"Evaluation stage one","policy":{"stageId":"evaluation-1","profitTarget":"2000","minimumTradingDays":5,"session":{"timeZone":"America/Chicago","rolloverHour":17},"disqualifying":["daily_loss","trailing_drawdown"],"nextGroupId":"funded"},"contentHash":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd","createdAt":"2026-09-14T12:00:00.000Z","inForce":true}],"nextCursor":null}},"VenueStagePolicySaveRequest":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"policy":{"$ref":"#/components/schemas/VenueStagePolicy"}},"required":["name","policy"],"example":{"name":"Evaluation stage one","policy":{"stageId":"evaluation-1","profitTarget":"2000","minimumTradingDays":5,"session":{"timeZone":"America/Chicago","rolloverHour":17},"disqualifying":["daily_loss","trailing_drawdown"],"nextGroupId":"funded"}}},"VenueStagePolicySaveResponse":{"type":"object","additionalProperties":false,"properties":{"policy":{"$ref":"#/components/schemas/VenueStagePolicyRecord"}},"required":["policy"],"example":{"policy":{"id":"00000000-0000-0000-0000-000000000001","venueId":"00000000-0000-0000-0000-000000000001","environment":"sandbox","stageId":"evaluation-1","name":"Evaluation stage one","policy":{"stageId":"evaluation-1","profitTarget":"2000","minimumTradingDays":5,"session":{"timeZone":"America/Chicago","rolloverHour":17},"disqualifying":["daily_loss","max_drawdown"],"nextGroupId":"funded","drawdown":{"maxLoss":"2500","kind":"trailing","measure":"equity","highWater":"endOfDay","dailyMaxLoss":"1000"},"maximumReturn":null,"maximumDays":30},"contentHash":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd","createdAt":"2026-09-14T12:00:00.000Z","inForce":false}}},"VenueStageActivationRequest":{"type":"object","additionalProperties":false,"properties":{"policyId":{"type":"string","format":"uuid"},"expectedRevision":{"type":["integer","null"],"minimum":1,"description":"Null when no version of the stage is in force yet, then the current revision."}},"required":["policyId","expectedRevision"],"example":{"policyId":"00000000-0000-0000-0000-000000000001","expectedRevision":null}},"VenueStageActivationResponse":{"type":"object","additionalProperties":false,"properties":{"activation":{"type":"object","additionalProperties":false,"properties":{"stageId":{"type":"string"},"policyId":{"type":"string","format":"uuid"},"revision":{"type":"integer"},"activatedAt":{"type":"string","format":"date-time"}},"required":["stageId","policyId","revision","activatedAt"]}},"required":["activation"],"example":{"activation":{"stageId":"evaluation-1","policyId":"00000000-0000-0000-0000-000000000001","revision":1,"activatedAt":"2026-09-14T12:00:00.000Z"}}},"VenueAccountAssignmentRequest":{"type":"object","additionalProperties":false,"properties":{"groupId":{"type":["string","null"],"description":"The group to join, or null to leave every group."}},"required":["groupId"],"example":{"groupId":"professional"}},"VenueAccountAssignmentResponse":{"type":"object","additionalProperties":false,"properties":{"assignment":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"groupId":{"type":["string","null"]},"revision":{"type":"integer"}},"required":["accountId","groupId","revision"]}},"required":["assignment"],"example":{"assignment":{"accountId":"example-account","groupId":"professional","revision":1}}},"VenueAccountRiskRequest":{"type":"object","additionalProperties":false,"properties":{"risk":{"$ref":"#/components/schemas/VenueRiskPolicy"}},"required":["risk"],"example":{"risk":{"maxOrderQuantity":"2"}}},"VenueAccountRiskResponse":{"type":"object","additionalProperties":false,"properties":{"account":{"type":"object","additionalProperties":false,"properties":{"accountId":{"type":"string"},"revision":{"type":"integer"}},"required":["accountId","revision"]}},"required":["account"],"example":{"account":{"accountId":"example-account","revision":1}}},"VenueEffectiveConditionsResponse":{"type":"object","additionalProperties":false,"properties":{"conditions":{"$ref":"#/components/schemas/VenueEffectiveConditions"}},"required":["conditions"],"example":{"conditions":{"venueId":"00000000-0000-0000-0000-000000000001","groupId":"professional","profileId":"00000000-0000-0000-0000-000000000001","revisions":{"venue":1,"group":1,"account":null},"hash":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"}}},"VenueActivationListResponse":{"type":"object","additionalProperties":false,"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/VenueActiveInstrument"}},"nextCursor":{"type":["string","null"]}},"required":["items","nextCursor"],"example":{"items":[],"nextCursor":null}},"VenueActivationRequest":{"type":"object","additionalProperties":false,"properties":{"instrumentId":{"type":"string"},"instrumentVersionId":{"type":"string","format":"uuid","description":"The saved candidate to activate. It must belong to this venue, environment and instrument, and keep at least one mapping on a live connection."},"expectedRevision":{"type":["integer","null"],"minimum":1,"description":"Required. Null when the instrument has no active version yet, then its current revision, so two people activating at once can't both succeed."}},"required":["instrumentId","instrumentVersionId","expectedRevision"],"example":{"instrumentId":"BTC-USD-SPOT","instrumentVersionId":"00000000-0000-0000-0000-000000000001","expectedRevision":null}},"VenueActivationResponse":{"type":"object","additionalProperties":false,"properties":{"activation":{"$ref":"#/components/schemas/VenueActiveInstrument"}},"required":["activation"],"example":{"activation":{"instrumentId":"BTC-USD-SPOT","instrumentVersionId":"00000000-0000-0000-0000-000000000001","version":"v1","revision":1,"state":"enabled","activatedAt":"2026-09-14T12:00:00.000Z","symbol":"BTCUSD","name":"Bitcoin / USD","productModel":"linear_spot","quoteCurrency":"USD","lastTradeAt":null,"sessionOpen":true,"tradingReady":false}}},"VenueInstrumentReadResponse":{"type":"object","additionalProperties":false,"properties":{"instrument":{"$ref":"#/components/schemas/VenueInstrumentCandidate"}},"required":["instrument"],"example":{"instrument":{"id":"00000000-0000-0000-0000-000000000001","venueId":"00000000-0000-0000-0000-000000000001","environment":"sandbox","specification":{"instrumentId":"BTCUSD","version":"v1","venueId":"00000000-0000-0000-0000-000000000001","symbol":"BTCUSD","name":"Bitcoin / USD","productModel":"linear_spot","quoteCurrency":"USD","settlementCurrency":"USD","negativePrices":false,"quantity":{"unit":"base_units","lotSize":"1","min":"0.001","max":"100","step":"0.001"},"contractMultiplier":"1","minNotional":"10","ticks":[{"from":"0","to":null,"size":"0.01"}],"orderTypes":["market","limit"],"timeInForce":["gtc"],"mappings":[],"sessions":{"timezone":"UTC","coverageFrom":"2026-01-01","coverageThrough":"2026-12-31","weekly":[{"day":0,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":1,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":2,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":3,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":4,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":5,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]},{"day":6,"windows":[{"startMinute":0,"endMinute":0,"endDayOffset":1}]}],"holidays":[]},"expiresAt":null,"lastTradeAt":null,"pricing":{"sourceId":"example-feed","stopTrigger":"last","maxAgeMs":1000},"entitlement":null,"state":"enabled"},"contentHash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","createdAt":"2026-09-14T12:00:00.000Z","state":"candidate","tradingReady":false}}},"VenueInvitationRequest":{"type":"object","additionalProperties":false,"properties":{"email":{"type":"string","format":"email","maxLength":254,"description":"The email of the person invited, at most 254 characters."},"canTrade":{"type":"boolean","description":"True to let them trade the account, false for read-only access."},"expiresInSeconds":{"type":"integer","minimum":60,"maximum":604800,"description":"How long the invitation lasts, from 60 seconds to 7 days (604,800 seconds)."}},"required":["email","canTrade","expiresInSeconds"],"example":{"email":"trader@example.com","canTrade":true,"expiresInSeconds":3600}},"VenueInvitationResponse":{"type":"object","additionalProperties":false,"properties":{"invitation":{"$ref":"#/components/schemas/VenueInvitation"}},"required":["invitation"],"example":{"invitation":{"claimId":"00000000-0000-0000-0000-000000000001","token":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","expiresAt":"2026-09-14T12:00:00.000Z","canTrade":true}}},"VenueGrantReadResponse":{"type":"object","additionalProperties":false,"properties":{"grant":{"$ref":"#/components/schemas/VenueGrantStatus"}},"required":["grant"],"example":{"grant":{"claimId":"00000000-0000-0000-0000-000000000001","accountId":"example-account","email":"trader@example.com","canTrade":true,"expiresAt":"2026-09-14T12:00:00.000Z","claimedAt":null,"revokedAt":null,"version":1}}},"VenueGrantRevokeRequest":{"type":"object","additionalProperties":false,"properties":{},"required":[],"example":{}},"VenueGrantRevokeResponse":{"type":"object","additionalProperties":false,"properties":{"grant":{"type":"object","additionalProperties":false,"properties":{"claimId":{"type":"string","format":"uuid"},"version":{"type":"integer"},"revokedAt":{"type":"string","format":"date-time"}},"required":["claimId","version","revokedAt"]}},"required":["grant"],"example":{"grant":{"claimId":"00000000-0000-0000-0000-000000000001","version":3,"revokedAt":"2026-09-14T12:00:00.000Z"}}},"VenueOrganizationsResponse":{"type":"object","additionalProperties":false,"properties":{"organizations":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"role":{"enum":["owner","operator","reader"]},"version":{"type":"integer"}},"required":["id","name","role","version"]}}},"required":["organizations"],"example":{"organizations":[{"id":"00000000-0000-0000-0000-000000000001","name":"Meridian Futures","role":"owner","version":1}]}},"VenueOrganizationCreateRequest":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","description":"The organization's name, at most 80 characters."}},"required":["name"],"example":{"name":"Meridian Futures"}},"VenueOrganizationResponse":{"type":"object","additionalProperties":false,"properties":{"organization":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"principalId":{"type":"string","format":"uuid","description":"The organization's own identity, which owns its venues. Nobody signs in as it."}},"required":["id","name","principalId"]}},"required":["organization"],"example":{"organization":{"id":"00000000-0000-0000-0000-000000000001","name":"Meridian Futures","principalId":"00000000-0000-0000-0000-000000000001"}}},"VenueListResponse":{"type":"object","additionalProperties":false,"properties":{"venues":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"environment":{"enum":["sandbox","production"]},"legacyFirmId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","environment","legacyFirmId","createdAt"]}}},"required":["venues"],"example":{"venues":[{"id":"00000000-0000-0000-0000-000000000001","name":"Meridian Evaluation","environment":"sandbox","legacyFirmId":null,"createdAt":"2026-09-14T12:00:00.000Z"}]}},"VenueMembersResponse":{"type":"object","additionalProperties":false,"properties":{"members":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"authUserId":{"type":["string","null"]},"email":{"type":["string","null"]},"role":{"enum":["owner","operator","reader"]},"active":{"type":"boolean"},"pending":{"type":"boolean"},"version":{"type":"integer","minimum":0}},"required":["authUserId","email","role","active","pending","version"]}}},"required":["members"],"example":{"members":[{"authUserId":"user_1","email":"owner@example.com","role":"owner","active":true,"pending":false,"version":1},{"authUserId":null,"email":"desk@example.com","role":"operator","active":false,"pending":true,"version":1}]}},"VenueMemberSetRequest":{"type":"object","additionalProperties":false,"properties":{"email":{"type":"string","maxLength":254,"description":"The person's email, at most 254 characters. Send this or `authUserId`, not both."},"authUserId":{"type":"string","description":"An active member's user id. Send this or `email`, not both."},"role":{"enum":["owner","operator","reader"],"description":"`owner` manages members, keys and the venue; `operator` changes venue settings; `reader` only reads."},"expectedVersion":{"type":"integer","minimum":0,"description":"The member's or invitation's current `version`, or 0 for someone new."}},"required":["role","expectedVersion"],"oneOf":[{"required":["email"]},{"required":["authUserId"]}],"example":{"email":"desk@example.com","role":"operator","expectedVersion":0}},"VenueMemberResponse":{"type":"object","additionalProperties":false,"properties":{"member":{"type":"object","additionalProperties":false,"properties":{"authUserId":{"type":["string","null"]},"email":{"type":["string","null"]},"role":{"enum":["owner","operator","reader"]},"active":{"type":"boolean"},"pending":{"type":"boolean"},"version":{"type":"integer","minimum":1}},"required":["authUserId","email","role","active","pending","version"]}},"required":["member"],"example":{"member":{"authUserId":null,"email":"desk@example.com","role":"operator","active":false,"pending":true,"version":1}}},"VenueMemberRemoveRequest":{"type":"object","additionalProperties":false,"properties":{"authUserId":{"type":"string","description":"An active member's user id. Send this or `email`, not both."},"email":{"type":"string","maxLength":254,"description":"A pending invitation's email. Send this or `authUserId`, not both."},"expectedVersion":{"type":"integer","minimum":1,"description":"The member's or invitation's current `version`."}},"required":["expectedVersion"],"oneOf":[{"required":["authUserId"]},{"required":["email"]}],"example":{"authUserId":"user_2","expectedVersion":1}},"VenueMemberRemoveResponse":{"type":"object","additionalProperties":false,"properties":{"member":{"type":"object","additionalProperties":false,"properties":{"authUserId":{"type":"string"},"role":{"enum":["owner","operator","reader"]},"active":{"const":false},"version":{"type":"integer","minimum":1}},"required":["authUserId","role","active","version"]}},"required":["member"],"example":{"member":{"authUserId":"user_2","role":"operator","active":false,"version":2}}},"VenueCreateRequest":{"type":"object","additionalProperties":false,"properties":{"organizationId":{"type":"string","format":"uuid"},"name":{"type":"string","description":"The venue's name."},"environment":{"enum":["sandbox","production"],"description":"The environment this engine serves. An engine serves exactly one, and a body naming the other is refused with `400`."}},"required":["organizationId","name","environment"],"example":{"organizationId":"00000000-0000-0000-0000-000000000001","name":"Meridian Evaluation","environment":"sandbox"}},"VenueCreateResponse":{"type":"object","additionalProperties":false,"properties":{"venue":{"$ref":"#/components/schemas/VenueRecord"}},"required":["venue"],"example":{"venue":{"id":"00000000-0000-0000-0000-000000000001","organizationId":"00000000-0000-0000-0000-000000000001","legacyFirmId":"00000000-0000-0000-0000-000000000001","name":"Meridian Evaluation","description":null,"environment":"sandbox","state":"draft","version":1,"createdAt":"2026-09-14T12:00:00.000Z","rules":{"enabled":false,"applies":{"orders":true,"fills":true,"stages":true},"appliesAtProvider":{"orders":false,"fills":false,"stages":false}},"company":{"id":"00000000-0000-0000-0000-000000000001","name":"Meridian Evaluation","blurb":"Futures evaluations on the paper book","logoUrl":null,"logoBleed":false,"referralUrl":null,"sortOrder":100,"kind":"prop","builtInProvider":null,"connectsTraders":false,"pluggable":false,"runsVenue":true,"listingState":"listed","enabled":true,"createdAt":"2026-09-14T12:00:00.000Z","updatedAt":"2026-09-14T12:00:00.000Z"}}}},"VenueFirmAdoptResponse":{"type":"object","additionalProperties":false,"properties":{"venue":{"$ref":"#/components/schemas/VenueRecord"}},"required":["venue"],"example":{"venue":{"id":"00000000-0000-0000-0000-000000000001","organizationId":"00000000-0000-0000-0000-000000000001","legacyFirmId":"00000000-0000-0000-0000-000000000001","name":"Meridian Evaluation","description":null,"environment":"sandbox","state":"draft","version":2,"createdAt":"2026-09-14T12:00:00.000Z","rules":{"enabled":false,"applies":{"orders":true,"fills":true,"stages":true},"appliesAtProvider":{"orders":false,"fills":false,"stages":false}},"company":{"id":"00000000-0000-0000-0000-000000000001","name":"Meridian Evaluation","blurb":"Futures evaluations on the paper book","logoUrl":null,"logoBleed":false,"referralUrl":null,"sortOrder":100,"kind":"prop","builtInProvider":null,"connectsTraders":false,"pluggable":false,"runsVenue":true,"listingState":"listed","enabled":true,"createdAt":"2026-09-14T12:00:00.000Z","updatedAt":"2026-09-14T12:00:00.000Z"}}}},"VenueKeyIssueRequest":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":80,"description":"Your name for the key, 1 to 80 characters."},"scopes":{"type":"array","items":{"type":"string","enum":["venue:read","venue:configure","connection:manage","connect:manage","account:issue","account:read","account:reset","provider:manage","grant:manage","balance:write","risk:halt","stage:advance","hedge:read","hedge:manage","hedge:execute"]},"minItems":1,"uniqueItems":true,"description":"The scopes the key carries, at least one and each once. Each operation names the scope it needs."},"expiresInSeconds":{"type":"integer","minimum":60,"maximum":31536000,"description":"How long the key lasts, from 60 seconds to 365 days (31,536,000 seconds)."}},"required":["name","scopes","expiresInSeconds"],"example":{"name":"Account invitations","scopes":["account:read","grant:manage"],"expiresInSeconds":86400}},"VenueKeyIssueResponse":{"type":"object","additionalProperties":false,"properties":{"key":{"$ref":"#/components/schemas/VenueOperatorKeyIssued"}},"required":["key"],"example":{"key":{"id":"00000000-0000-0000-0000-000000000001","token":"trdrs_vk_sandbox_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","scopes":["account:read","grant:manage"],"expiresAt":"2026-09-14T12:00:00.000Z"}}},"VenueKeyListResponse":{"type":"object","additionalProperties":false,"properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","enum":["venue:read","venue:configure","connection:manage","connect:manage","account:issue","account:read","account:reset","provider:manage","grant:manage","balance:write","risk:halt","stage:advance","hedge:read","hedge:manage","hedge:execute"]}},"expiresAt":{"type":"string","format":"date-time"},"revokedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","scopes","expiresAt","revokedAt","createdAt"]}},"nextCursor":{"type":["string","null"]}},"required":["items","nextCursor"],"example":{"items":[],"nextCursor":null}},"VenueKeyRevokeRequest":{"type":"object","additionalProperties":false,"properties":{},"required":[],"example":{}},"VenueKeyRevokeResponse":{"type":"object","additionalProperties":false,"properties":{"key":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"revokedAt":{"type":"string","format":"date-time"}},"required":["id","revokedAt"]}},"required":["key"],"example":{"key":{"id":"00000000-0000-0000-0000-000000000001","revokedAt":"2026-09-14T12:00:00.000Z"}}},"VenueConnectOriginListResponse":{"type":"object","additionalProperties":false,"properties":{"origins":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"origin":{"type":"string"},"state":{"type":"string","enum":["pending","approved","revoked"]},"version":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","origin","state","version","createdAt","reviewedAt"]}}},"required":["origins"],"example":{"origins":[{"id":"00000000-0000-0000-0000-000000000001","origin":"https://backoffice.example.com","state":"approved","version":1,"createdAt":"2026-09-14T12:00:00.000Z","reviewedAt":"2026-09-14T12:00:00.000Z"}]}},"VenueConnectOriginRequest":{"type":"object","additionalProperties":false,"properties":{"origin":{"type":"string","description":"The exact origin, such as `https://backoffice.example.com`: `https` except for a localhost development origin, with no path and no wildcard."}},"required":["origin"],"example":{"origin":"https://backoffice.example.com"}},"VenueConnectOriginResponse":{"type":"object","additionalProperties":false,"properties":{"origin":{"type":"object"}},"required":["origin"],"example":{"origin":{"id":"00000000-0000-0000-0000-000000000001","origin":"https://backoffice.example.com","state":"approved"}}},"VenueConnectSessionCreateRequest":{"type":"object","additionalProperties":false,"required":["origin","email","expiresInSeconds"],"properties":{"origin":{"type":"string","description":"The approved origin of the page that embeds Connect Link, exactly as registered."},"email":{"type":"string","format":"email","maxLength":254,"description":"The email the trader signs in to trdrs with, at most 254 characters."},"grantId":{"type":"string","format":"uuid","description":"Optional. The id of an account grant for this trader, which the session claims for them when it completes."},"expiresInSeconds":{"type":"integer","minimum":60,"maximum":600,"description":"How long the token lasts, from 60 to 600 seconds."}},"example":{"origin":"https://backoffice.example.com","email":"trader@example.com","expiresInSeconds":300}},"VenueConnectSessionIssuedResponse":{"type":"object","additionalProperties":false,"properties":{"session":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"token":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"origin":{"type":"string"},"environment":{"type":"string","enum":["sandbox","production"]}},"required":["id","token","expiresAt","origin","environment"]}},"required":["session"],"example":{"session":{"id":"00000000-0000-0000-0000-000000000001","token":"trdrs_connect_example","expiresAt":"2026-09-14T12:00:00.000Z","origin":"https://backoffice.example.com","environment":"sandbox"}}},"VenueConnectSessionResponse":{"type":"object","example":{"session":{"id":"00000000-0000-0000-0000-000000000001","state":"created","expiresAt":"2026-09-14T12:00:00.000Z"}}},"VenueConnectSessionCloseRequest":{"type":"object","additionalProperties":false,"properties":{},"required":[],"example":{}},"ConnectLinkMountRequest":{"type":"object","additionalProperties":false,"properties":{"token":{"type":"string","description":"The token from creating the Connect Link session."}},"required":["token"],"example":{"token":"trdrs_connect_example"}},"ConnectLinkMountResponse":{"type":"object","example":{"sessionId":"00000000-0000-0000-0000-000000000001","browserToken":"trdrs_browser_example","state":"mounted"}},"ConnectLinkClaimRequest":{"type":"object","additionalProperties":false,"properties":{"browserToken":{"type":"string","description":"The browser token the mount returned."}},"required":["browserToken"],"example":{"browserToken":"trdrs_browser_example"}},"ConnectLinkClaimResponse":{"type":"object","example":{"session":{"id":"00000000-0000-0000-0000-000000000001","state":"authenticating"}}},"ConnectLinkCompleteRequest":{"type":"object","additionalProperties":false,"properties":{"provider":{"type":"string","description":"The provider the trader signed in to, such as `rithmic`."},"accountNumber":{"type":"string","description":"The account number at that provider."}},"required":["provider","accountNumber"],"example":{"provider":"rithmic","accountNumber":"EVAL-7C21A9"}},"ConnectLinkCompleteResponse":{"type":"object","example":{"session":{"id":"00000000-0000-0000-0000-000000000001","state":"connected"}}},"ConnectLinkStatusResponse":{"type":"object","example":{"session":{"id":"00000000-0000-0000-0000-000000000001","state":"connected"}}},"VenueRiskPolicyListResponse":{"type":"object","additionalProperties":false,"properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"policyId":{"type":"string"},"inForce":{"oneOf":[{"type":"object","additionalProperties":false,"properties":{"version":{"type":"string"},"sequence":{"type":"integer"}},"required":["version","sequence"]},{"type":"null"}]},"publications":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"sequence":{"type":"integer"},"version":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"publishedBy":{"type":"string"},"reference":{"type":"string"}},"required":["sequence","version","publishedAt","publishedBy","reference"]}},"versions":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"version":{"type":"string"},"contentDigest":{"type":"string"},"recordedAt":{"type":"string","format":"date-time"}},"required":["version","contentDigest","recordedAt"]}}},"required":["policyId","inForce","publications","versions"]}}},"required":["items"],"example":{"items":[{"policyId":"meridian-futures","inForce":{"version":"2026-10-01","sequence":1},"versions":[{"version":"2026-10-01","contentDigest":"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee","recordedAt":"2026-09-14T12:00:00.000Z"}],"publications":[{"sequence":1,"version":"2026-10-01","publishedAt":"2026-09-14T12:00:00.000Z","publishedBy":"00000000-0000-0000-0000-000000000001","reference":"publish-2026-10-01"}]}]}},"VenueRiskPolicyStoreRequest":{"type":"object","additionalProperties":false,"properties":{"policy":{"type":"object","description":"One version of an account risk policy, as the risk policy contract states it: the policy id and version, the authority (a firm, naming this venue), the account currency, the account's one thresholds term (the margin call, stop-out and recovery lines over the requirement of everything the account holds), the terms of each product class under `classes` (`futures`, `crypto_derivative` and `fx_cfd`, each stated, null for a class the policy does not offer), the settlement term and the posting term. A product class carries its futures margin by dated contract, its crypto derivative collateral or its CFD terms, its valuation age and how it margins opposite tickets, each term with its own version, authority, source and effective dates. An account bound to the policy trades every class it offers from one balance. Anything else is refused, with `field` naming what."}},"required":["policy"],"example":{"policy":{"policyId":"meridian-futures","version":"2026-10-01","authority":{"kind":"firm","venueId":"00000000-0000-0000-0000-000000000001","name":"Meridian Futures"},"currency":"USD","thresholds":{"version":"thresholds-2026-10-01","authority":"firm","source":"the venue's own terms","effectiveFrom":"2026-10-01T00:00:00.000Z","effectiveUntil":null,"marginCall":null,"stopOut":"1","recoveryLevel":"1.1","sources":{"marginCall":{"authority":"firm","source":"the venue's own terms","sourced":true},"stopOut":{"authority":"firm","source":"the venue's own terms","sourced":true},"recoveryLevel":{"authority":"firm","source":"the venue's own terms","sourced":true}}},"classes":{"futures":{"margin":{"version":"margin-2026-10-01","authority":"firm","source":"the venue's own terms","effectiveFrom":"2026-10-01T00:00:00.000Z","effectiveUntil":null,"asset":"USD","basis":"per_contract","window":{"timeZone":"America/Chicago","startMinute":510,"exposureCutoffMinute":900,"endMinute":915,"weekdays":[1,2,3,4,5],"closedDates":[]},"closeOnly":"at_roll","contracts":[{"contract":"CME:NQZ2026","root":"NQ","day":{"initial":"1000","maintenance":"500","sources":{"initial":{"authority":"firm","source":"the venue's own terms","sourced":true},"maintenance":{"authority":"firm","source":"the venue's own terms","sourced":true}}},"overnight":{"initial":"43207","maintenance":"43207","sources":{"initial":{"authority":"firm","source":"the venue's own terms","sourced":true},"maintenance":{"authority":"firm","source":"the venue's own terms","sourced":true}}}}]},"valuation":{"version":"valuation-2026-10-01","authority":"firm","source":"the venue's own terms","effectiveFrom":"2026-10-01T00:00:00.000Z","effectiveUntil":null,"maxAgeMs":5000},"ticketHedging":null},"crypto_derivative":null,"fx_cfd":null},"settlement":{"version":"settlement-2026-10-01","authority":"firm","source":"the venue's own terms","effectiveFrom":"2026-10-01T00:00:00.000Z","effectiveUntil":null,"kind":"settlement_asset"},"posting":{"version":"posting-2026-10-01","authority":"firm","source":"the venue's own terms","effectiveFrom":"2026-10-01T00:00:00.000Z","effectiveUntil":null,"currencies":[{"currency":"USD","decimals":2,"rounding":"half_even","source":{"authority":"publisher","source":"ISO 4217: USD minor unit 2","sourced":true,"document":null}}]}}}},"VenueRiskPolicyStoreResponse":{"type":"object","additionalProperties":false,"properties":{"version":{"type":"object","additionalProperties":false,"properties":{"policyId":{"type":"string"},"version":{"type":"string"},"contentDigest":{"type":"string"},"created":{"type":"boolean"}},"required":["policyId","version","contentDigest","created"]}},"required":["version"],"example":{"version":{"policyId":"meridian-futures","version":"2026-10-01","contentDigest":"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee","created":true}}},"VenueRiskPolicyReadResponse":{"type":"object","additionalProperties":false,"properties":{"policy":{"type":"object","additionalProperties":false,"properties":{"policyId":{"type":"string"},"inForce":{"oneOf":[{"type":"object","additionalProperties":false,"properties":{"version":{"type":"string"},"sequence":{"type":"integer"}},"required":["version","sequence"]},{"type":"null"}]},"publications":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"sequence":{"type":"integer"},"version":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"publishedBy":{"type":"string"},"reference":{"type":"string"}},"required":["sequence","version","publishedAt","publishedBy","reference"]}},"versions":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"version":{"type":"string"},"contentDigest":{"type":"string"},"recordedAt":{"type":"string","format":"date-time"},"policy":{"type":"object","description":"One version of an account risk policy, as the risk policy contract states it: the policy id and version, the authority (a firm, naming this venue), the account currency, the account's one thresholds term (the margin call, stop-out and recovery lines over the requirement of everything the account holds), the terms of each product class under `classes` (`futures`, `crypto_derivative` and `fx_cfd`, each stated, null for a class the policy does not offer), the settlement term and the posting term. A product class carries its futures margin by dated contract, its crypto derivative collateral or its CFD terms, its valuation age and how it margins opposite tickets, each term with its own version, authority, source and effective dates. An account bound to the policy trades every class it offers from one balance. Anything else is refused, with `field` naming what."}},"required":["version","contentDigest","recordedAt","policy"]}}},"required":["policyId","inForce","publications","versions"]}},"required":["policy"],"example":{"policy":{"policyId":"meridian-futures","inForce":{"version":"2026-10-01","sequence":1},"versions":[{"version":"2026-10-01","contentDigest":"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee","recordedAt":"2026-09-14T12:00:00.000Z","policy":{"policyId":"meridian-futures","version":"2026-10-01","authority":{"kind":"firm","venueId":"00000000-0000-0000-0000-000000000001","name":"Meridian Futures"},"currency":"USD","thresholds":{"version":"thresholds-2026-10-01","authority":"firm","source":"the venue's own terms","effectiveFrom":"2026-10-01T00:00:00.000Z","effectiveUntil":null,"marginCall":null,"stopOut":"1","recoveryLevel":"1.1","sources":{"marginCall":{"authority":"firm","source":"the venue's own terms","sourced":true},"stopOut":{"authority":"firm","source":"the venue's own terms","sourced":true},"recoveryLevel":{"authority":"firm","source":"the venue's own terms","sourced":true}}},"classes":{"futures":{"margin":{"version":"margin-2026-10-01","authority":"firm","source":"the venue's own terms","effectiveFrom":"2026-10-01T00:00:00.000Z","effectiveUntil":null,"asset":"USD","basis":"per_contract","window":{"timeZone":"America/Chicago","startMinute":510,"exposureCutoffMinute":900,"endMinute":915,"weekdays":[1,2,3,4,5],"closedDates":[]},"closeOnly":"at_roll","contracts":[{"contract":"CME:NQZ2026","root":"NQ","day":{"initial":"1000","maintenance":"500","sources":{"initial":{"authority":"firm","source":"the venue's own terms","sourced":true},"maintenance":{"authority":"firm","source":"the venue's own terms","sourced":true}}},"overnight":{"initial":"43207","maintenance":"43207","sources":{"initial":{"authority":"firm","source":"the venue's own terms","sourced":true},"maintenance":{"authority":"firm","source":"the venue's own terms","sourced":true}}}}]},"valuation":{"version":"valuation-2026-10-01","authority":"firm","source":"the venue's own terms","effectiveFrom":"2026-10-01T00:00:00.000Z","effectiveUntil":null,"maxAgeMs":5000},"ticketHedging":null},"crypto_derivative":null,"fx_cfd":null},"settlement":{"version":"settlement-2026-10-01","authority":"firm","source":"the venue's own terms","effectiveFrom":"2026-10-01T00:00:00.000Z","effectiveUntil":null,"kind":"settlement_asset"},"posting":{"version":"posting-2026-10-01","authority":"firm","source":"the venue's own terms","effectiveFrom":"2026-10-01T00:00:00.000Z","effectiveUntil":null,"currencies":[{"currency":"USD","decimals":2,"rounding":"half_even","source":{"authority":"publisher","source":"ISO 4217: USD minor unit 2","sourced":true,"document":null}}]}}}],"publications":[{"sequence":1,"version":"2026-10-01","publishedAt":"2026-09-14T12:00:00.000Z","publishedBy":"00000000-0000-0000-0000-000000000001","reference":"publish-2026-10-01"}]}}},"VenueRiskPolicyPublishRequest":{"type":"object","additionalProperties":false,"properties":{"version":{"type":"string","description":"The stored version to put in force."}},"required":["version"],"example":{"version":"2026-10-01"}},"VenueRiskPolicyPublishResponse":{"type":"object","additionalProperties":false,"properties":{"publication":{"type":"object","additionalProperties":false,"properties":{"policyId":{"type":"string"},"version":{"type":"string"},"sequence":{"type":"integer"},"publishedAt":{"type":"string","format":"date-time"},"pools":{"type":"integer"}},"required":["policyId","version","sequence","publishedAt","pools"]}},"required":["publication"],"example":{"publication":{"policyId":"meridian-futures","version":"2026-10-01","sequence":1,"publishedAt":"2026-09-14T12:00:00.000Z","pools":0}}},"WireChallenge":{"type":"object","description":"An evaluation program a trader can enroll in.","properties":{"id":{"type":"string","format":"uuid","description":"The program's id."},"name":{"type":"string","description":"The program's name."},"description":{"type":["string","null"],"description":"The program's description, or null."},"isActive":{"type":"boolean","description":"True when the program is open for enrollment."},"stage":{"type":"integer","description":"For a program with several stages, this program's stage number."},"nextChallengeId":{"type":["string","null"],"description":"The program for the next stage, for a two-step evaluation, or null."},"allowedTypes":{"type":"array","items":{"type":"string","enum":["trial","standard","funded"]},"description":"The kinds of enrollment the program allows."},"accountSizes":{"type":"array","items":{"type":"integer"},"description":"The starting balances allowed, in whole dollars."},"currency":{"type":"string","description":"The program's currency."},"priceCents":{"type":"integer","description":"The entry price in cents. A trader can enroll on their own only in a program priced at 0; see `/api/challenges/enroll`."},"sizes":{"type":"array","description":"The sizes an enrollment can be issued at, each with the venue group it is issued into and the rules it is judged by: the stage that group runs now, in money for that size. `stage` is null while no version of it is active. A program with sizes states its rules only here, and its percentage rules below are null.","items":{"type":"object","properties":{"size":{"type":"integer","description":"The starting balance, in whole units of the currency."},"venueId":{"type":"string","format":"uuid","description":"The venue the account is issued at."},"groupId":{"type":"string","description":"The group the account is issued into."},"stage":{"type":["object","null"],"description":"The stage rules the account is judged by, or null while none is active.","properties":{"stageId":{"type":"string","description":"The stage's id."},"profitTarget":{"type":"string","description":"The net trading profit required, in the account's currency."},"minimumTradingDays":{"type":"integer","description":"The fewest trading days required."},"session":{"type":"object","description":"The session the days are counted in.","properties":{"timeZone":{"type":"string","description":"The IANA time zone."},"rolloverHour":{"type":"integer","description":"The hour the trading day starts."}},"required":["timeZone","rolloverHour"]},"drawdown":{"type":["object","null"],"description":"The drawdown rule, or null for none.","properties":{"maxLoss":{"type":"string","description":"The largest loss allowed."},"kind":{"type":"string","enum":["static","trailing"],"description":"Whether the loss limit stays put or trails the high-water mark."},"measure":{"type":"string","enum":["balance","equity"],"description":"Whether the limit is measured on balance or equity."},"highWater":{"type":["string","null"],"enum":["intraday","endOfDay",null],"description":"For a trailing limit, when the high-water mark is taken, or null."},"dailyMaxLoss":{"type":["string","null"],"description":"The largest loss allowed in one day, or null."}},"required":["maxLoss","kind","measure","highWater","dailyMaxLoss"]},"maximumReturn":{"type":["string","null"],"description":"The largest return allowed, or null."},"maximumDays":{"type":["integer","null"],"description":"The most days the stage may run, or null."}},"required":["stageId","profitTarget","minimumTradingDays","session","drawdown","maximumReturn","maximumDays"]}},"required":["size","venueId","groupId","stage"]}},"profitSharePct":{"type":["number","null"],"description":"The trader's profit share, in percent, or null."}},"required":["id","name","isActive","stage","allowedTypes","accountSizes","currency","priceCents","sizes"]},"WireEnrollmentProgress":{"type":["object","null"],"description":"Where the enrollment stands against its rules. A value that isn't known is null, never 0.","properties":{"equity":{"type":["number","null"],"description":"The account's equity."},"balance":{"type":["number","null"],"description":"The account's balance."},"totalFloor":{"type":["number","null"],"description":"A static drawdown's floor: the equity level the account must always stay above. Falling below it is a breach. Null for a trailing drawdown."},"profitTargetLevel":{"type":"number","description":"The equity level that meets the profit target."},"tradingDays":{"type":"integer","description":"The number of session days with at least one fill."},"minTradingDays":{"type":"integer","description":"The fewest trading days required."},"openPositions":{"type":"integer","description":"How many positions are open."}},"required":["equity","balance","profitTargetLevel","tradingDays","minTradingDays","openPositions"]},"WireEnrollment":{"type":"object","description":"One attempt by a trader at one program.","properties":{"id":{"type":"string","format":"uuid","description":"The enrollment's id."},"challengeId":{"type":"string","format":"uuid","description":"The program's id."},"challengeName":{"type":"string","description":"The program's name."},"stage":{"type":"integer","description":"The program's stage number."},"accountNumber":{"type":"string","description":"The account the evaluation trades on."},"type":{"type":"string","enum":["trial","standard","funded"],"description":"The kind of enrollment."},"status":{"type":"string","enum":["registered","in_progress","passed","failed","reset","cancelled","upgraded","finished"],"description":"Where the enrollment stands."},"startingBalance":{"type":"integer","description":"The starting balance, in whole dollars."},"startsAt":{"type":["number","null"],"description":"When the evaluation started, in epoch seconds. It starts at the first fill, not at enrollment."},"endsAt":{"type":["number","null"],"description":"When the evaluation ends, in epoch seconds, or null."},"failReason":{"type":["string","null"],"description":"Why the evaluation failed, or null."},"createdAt":{"type":"number","description":"When the trader enrolled, in epoch seconds."},"progress":{"$ref":"#/components/schemas/WireEnrollmentProgress","description":"Where the enrollment stands against its rules."}},"required":["id","challengeId","challengeName","stage","accountNumber","type","status","startingBalance","createdAt","progress"]},"ChallengesResponse":{"type":"object","description":"The programs open to you.","properties":{"challenges":{"type":"array","items":{"$ref":"#/components/schemas/WireChallenge"},"description":"The programs."}},"required":["challenges"],"example":{"challenges":[{"id":"3f8a1c2e-9b47-4d10-a3fe-2c61b7c90d84","name":"50K Evaluation","description":"Two-stage evaluation on a 50K account.","isActive":true,"stage":1,"nextChallengeId":"8d2f5a90-1e4b-4c7a-9f3d-6b0a8c4e2f17","allowedTypes":["standard"],"accountSizes":[50000],"currency":"USD","priceCents":0,"sizes":[{"size":50000,"venueId":"5b1d7e20-3c4a-4f8e-9d21-7a6c0b3e9f42","groupId":"evaluation-50k","stage":{"stageId":"evaluation-1","profitTarget":"4000","minimumTradingDays":5,"session":{"timeZone":"America/Chicago","rolloverHour":17},"drawdown":{"maxLoss":"4000","kind":"trailing","measure":"equity","highWater":"endOfDay","dailyMaxLoss":"2000"},"maximumReturn":null,"maximumDays":null}}],"profitSharePct":null}]}},"ChallengeEnrollRequest":{"type":"object","description":"The program to enroll in, and the size.","properties":{"challengeId":{"type":"string","format":"uuid","description":"The program's id."},"size":{"type":"integer","description":"The starting balance, in whole dollars."}},"required":["challengeId","size"],"example":{"challengeId":"3f8a1c2e-9b47-4d10-a3fe-2c61b7c90d84","size":50000}},"ChallengeEnrollResponse":{"type":"object","description":"Your new enrollment.","properties":{"enrollment":{"$ref":"#/components/schemas/WireEnrollment","description":"The enrollment."}},"required":["enrollment"],"example":{"enrollment":{"id":"e5c90b1a-7d34-4f6b-8a2e-91c8f0d47a53","challengeId":"3f8a1c2e-9b47-4d10-a3fe-2c61b7c90d84","challengeName":"50K Evaluation","stage":1,"accountNumber":"EVAL-50K-0042","type":"standard","status":"registered","startingBalance":50000,"startsAt":null,"endsAt":null,"failReason":null,"createdAt":1787058000,"progress":{"equity":50000,"balance":50000,"totalFloor":null,"profitTargetLevel":54000,"tradingDays":0,"minTradingDays":5,"openPositions":0}}}},"EnrollmentsResponse":{"type":"object","description":"Your enrollments.","properties":{"enrollments":{"type":"array","items":{"$ref":"#/components/schemas/WireEnrollment"},"description":"The enrollments."}},"required":["enrollments"],"example":{"enrollments":[{"id":"e5c90b1a-7d34-4f6b-8a2e-91c8f0d47a53","challengeId":"3f8a1c2e-9b47-4d10-a3fe-2c61b7c90d84","challengeName":"50K Evaluation","stage":1,"accountNumber":"EVAL-50K-0042","type":"standard","status":"in_progress","startingBalance":50000,"startsAt":1787144400,"endsAt":null,"failReason":null,"createdAt":1787058000,"progress":{"equity":51230.5,"balance":51155,"totalFloor":null,"profitTargetLevel":54000,"tradingDays":3,"minTradingDays":5,"openPositions":1}}]}},"EnrollmentEvent":{"type":"object","description":"One change of an enrollment's status.","properties":{"status":{"type":"string","description":"The status it changed to."},"actor":{"type":"string","description":"Who changed it: an administrator's identity, or `system` for a change trdrs made on its own."},"reason":{"type":["string","null"],"description":"Why, or null."},"at":{"type":"number","description":"When, in epoch seconds."}},"required":["status","actor","reason","at"]},"EnrollmentEventsResponse":{"type":"object","description":"An enrollment's status history.","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/EnrollmentEvent"},"description":"The status changes."}},"required":["events"],"example":{"events":[{"status":"registered","actor":"system","reason":null,"at":1787058000},{"status":"in_progress","actor":"system","reason":"first fill","at":1787144400}]}}}},"servers":[{"url":"https://app.trdrs.co","description":"Production"},{"url":"/","description":"This engine"}],"tags":[{"name":"Venue platform preview","description":"Run your venue: its providers, instruments, conditions, groups, routes, stages, venue rules, keys, accounts, usage, balance receipts and webhooks. These routes are in preview. They are served on the sandbox to every venue, and production access is arranged when a venue qualifies. Every route here under `/api/partner/` takes a Venue key. The back office reaches the same routes under `/api/operator/` with a verified owner’s session, because a browser never holds a Venue key, and both run the same checks. Changes to these routes are additive only from here on."},{"name":"Market data","description":"Search and look up symbols, read price history and quotes, check the server clock, and stream live bars. Crypto prices come from each provider’s public feed. Futures prices are licensed to each user and stream only from that trader’s own futures source: a login on their firm’s production Rithmic system, under their own market data subscription. A Rithmic Test login carries no market data. Without a source, a futures request answers 503 `feed_requires_connection` and the symbol search lists no futures."},{"name":"News","description":"Market news and the economic calendar, from licensed and open sources, tagged with futures roots as they arrive. The content is the same for everyone, and these routes admit the same callers as market data: a licensed origin, a session or a Trading API key. Page headlines by publish time, filter them by instrument root, and stream them live over server-sent events. Thumbnails come through the image route."},{"name":"Trading","description":"Place, change and cancel orders, set a position’s exits, and close or flatten positions. Every call that places an order takes a `clientOrderId` as its idempotency key."},{"name":"Account","description":"Read an account a trader can trade: its balance, positions, working orders, fills, profit and loss history, and the live account stream. You don’t create accounts here. A trader connects their own account at a provider, or opens their own Demo on the paper book, in the trdrs app. A venue issues accounts on the paper book with Issue an account into a group, and a firm pre-registers accounts at a provider through Connect with Pre-register a trader’s account."},{"name":"Connect","description":"Connect is the account picker a trader opens, in the trdrs app or embedded on a firm’s site. It lists the built-in providers and every listed venue. The pre-registration routes let a firm fill it in ahead of time. You tell trdrs that a trader has an account at a built-in provider: their sign-in email, and optionally the account number and login name. When that trader signs in, Connect shows the account ready to link, and they sign in to the provider themselves, once. Nothing here sends a password or grants access before the trader’s own login succeeds. You can list who you pre-registered and who has linked, and cancel a pre-registration that hasn’t been used. A pre-registration expires after 30 days, and sending it again refreshes it. These routes take the Partner key. The whole flow is in the **[Quick Start](/docs/guides/quick-start)**."},{"name":"Challenges","description":"These routes list evaluation programs and a trader’s own enrollments. **Preview: the one group in this reference outside the additive-only guarantee.** Their shapes will change when challenges are rebuilt; see Stability. **They take a signed-in session, not a key**, and are served only where the engine runs with `CHALLENGES_ENABLED`. Without it, the routes don’t exist and every one answers `404`. The administration half isn’t documented here, because it is trdrs’s own tooling, not part of the API."}],"x-tagGroups":[{"name":"API Reference","tags":["Market data","News","Trading","Account","Challenges"]},{"name":"Connect","tags":["Connect"]},{"name":"Venue platform","tags":["Venue platform preview"]}],"paths":{"/api/market/config":{"get":{"tags":["Market data"],"summary":"Get market-data limits","security":[{"tenantKey":[]}],"description":"Returns which timeframes the market data routes accept, the largest request each one takes, and which asset classes the catalog serves. Call it once before your first data call, so you can check a timeframe or a request size yourself instead of learning the limit from a 400.\n\nRequired key: Trading API key.","responses":{"200":{"description":"The accepted timeframes, the request limits and the asset classes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketConfigResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/market/config', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/market/config' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/market/symbols":{"get":{"tags":["Market data"],"summary":"Search the symbol catalog","security":[{"tenantKey":[]}],"description":"Searches the symbol catalog for symbols whose text contains your query, across the asset classes this engine serves. Use it to build a symbol picker, then use each returned `symbol` exactly as it is in every other market data call. It returns one page of matches and whether more follow.\n\nFutures list only in a signed-in trader’s own session, and only when that trader has a futures source, once for each provider of their sources. Each futures product lists as its root, such as `ES`, then its continuous front month `ES1!` and second month `ES2!` where trdrs models the product’s roll, then each dated contract trdrs registers, such as `CME:ESZ2026`, in roll order until its last trade, named with its contract month. A continuous symbol stands for the contract its position names at the moment you use it, so a chart of `ES1!` moves to the next contract at the roll by itself. A dated contract is that contract and no other.\n\nRequired key: Trading API key.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"},"description":"The text to search for."},{"name":"limit","in":"query","schema":{"type":"integer","default":50},"description":"How many results to return, 50 by default. Anything above 100 is lowered to 100, not refused."},{"name":"class","in":"query","schema":{"type":"string"},"description":"Only return symbols of this asset class."},{"name":"offset","in":"query","schema":{"type":"integer","default":0},"description":"How many results to skip, for the next page. `hasMore` is exact, so paging until it is false always ends."}],"responses":{"200":{"description":"One page of matching symbols.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SymbolsResponse"}}}},"429":{"description":"Too many requests. Wait for the number of seconds in the `Retry-After` header, then try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/market/symbols?q=ES', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/market/symbols?q=ES' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/market/symbol-info":{"get":{"tags":["Market data"],"summary":"Get symbol details","security":[{"tenantKey":[]}],"description":"Returns what you need to display and chart one symbol: its names, how its prices are written, its tick size and multiplier, and its sessions and holiday calendar. Fetch it once per symbol and keep it for the session, so your charts and order tickets never hard-code exchange conventions. It answers even when no feed is set up for the symbol.\n\nA futures root, a continuous symbol such as `ES1!` or `ES2!`, and a dated contract such as `CME:ESZ2026` or `ESZ6` share their product’s details, and each is named for what it is: `E-mini S&P 500`, `E-mini S&P 500 continuous front month`, `E-mini S&P 500 Dec 2026`.\n\nRequired key: Trading API key.","parameters":[{"name":"symbol","in":"query","required":true,"schema":{"type":"string"},"description":"The symbol, or a spread expression as `/api/market/history` accepts. A spread resolves as type `spread`, with no tick and no quotes. A string that exactly matches a catalog symbol is always that symbol, never arithmetic."}],"responses":{"200":{"description":"The symbol's details. A known symbol with no feed set up still resolves, with `provider` null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SymbolInfoResponse"}}}},"404":{"description":"No such symbol. This is an answer about the data, not a failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/market/symbol-info?symbol=ESU6', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/market/symbol-info?symbol=ESU6' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/instruments":{"get":{"tags":["Market data"],"summary":"Get the futures catalog","security":[{"tenantKey":[]}],"description":"Returns the futures products trdrs trades, one row per product root, with the facts an order ticket needs to size orders and round prices: exchange, tick size and value, multiplier, roll cycle, and contract months where trdrs doesn't model the roll. Fetch it once and keep it. Crypto instruments aren't here, because each provider states its own.\n\nRequired key: Trading API key.","responses":{"200":{"description":"The futures catalog.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstrumentsResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/instruments', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/instruments' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/market/time":{"get":{"tags":["Market data"],"summary":"Get server time","security":[{"tenantKey":[]}],"description":"Returns the engine's clock, in epoch seconds and epoch milliseconds from the same reading. Read it once at startup, work out how far your clock is from it, and apply that offset locally, so your session countdowns and bar boundaries agree with the engine without polling. Time the request to bound the offset: the engine read the clock during the round trip, so the offset is right to within half of it.\n\nRequired key: Trading API key.","responses":{"200":{"description":"The engine's clock.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerTimeResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/market/time', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/market/time' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/market/history":{"get":{"tags":["Market data"],"summary":"Get price history","security":[{"tenantKey":[]}],"description":"Returns price bars for one symbol and timeframe: the most recent 500 or so by default, the bars between `from` and `to`, or the last `countBack` bars before `to` when you scroll back. The symbol can also be a spread expression over up to four symbols, such as `ES-NQ`, `1/ESU6` or `(ES+NQ)/2`, which the engine works out for you. A continuous futures symbol reads the contract its position names when you ask: `ES1!` the front contract, as a bare `ES` does, and `ES2!` the one after it.\n\nRequired key: Trading API key.","parameters":[{"name":"instrument","in":"query","required":true,"schema":{"type":"string"},"description":"The symbol, or a spread expression using `+ - * / ^`, parentheses and numbers over up to four symbols. A spread bar exists only where every symbol in it has a bar for that interval, and its volume is 0. A string that exactly matches a catalog symbol, such as the pair BTC/USD, is always that symbol, never arithmetic."},{"name":"tf","in":"query","required":true,"schema":{"type":"string"},"description":"The timeframe, such as `1m`, `4h`, `1d` or `100t`. /api/market/config lists what is accepted."},{"name":"from","in":"query","schema":{"type":"integer"},"description":"The start of the window, in epoch seconds, inclusive."},{"name":"to","in":"query","schema":{"type":"integer"},"description":"The end of the window, in epoch seconds, inclusive."},{"name":"countBack","in":"query","schema":{"type":"integer"},"description":"Return the last this many bars at or before `to`, for scrolling back. It takes priority over `from`. When there are no bars, the answer carries `noData: true`, your signal to stop scrolling back. When every bar is older than the window you asked for, because the market was closed, the answer carries `stale: true`, so you never mistake Friday's bars for a live Saturday session."}],"responses":{"200":{"description":"The bars.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistoryResponse"}}}},"400":{"description":"The timeframe or another parameter is malformed. Nothing is guessed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests. Wait for the number of seconds in the `Retry-After` header, then try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"No feed serves this symbol. For futures, the body carries one of these codes: `feed_requires_connection` (futures prices are licensed to each user and stream from your own login at a provider that carries them, so connect one), `feed_capacity` (you have reached your limit of feed sessions, so try again shortly) or `feed_displaced` (another application took over this login's market data session). Otherwise the code is `market_data_unavailable`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/market/history?instrument=ESU6&tf=5m', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/market/history?instrument=ESU6&tf=5m' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/market/quotes":{"get":{"tags":["Market data"],"summary":"Get quote snapshots","security":[{"tenantKey":[]}],"description":"Returns a quote for each of up to 50 symbols in one call, in the order you asked. A symbol with no feed comes back with every value null rather than missing, so a watchlist always gets one row per symbol. This is a snapshot: stream the symbols for live updates.\n\nRequired key: Trading API key.","parameters":[{"name":"symbols","in":"query","required":true,"schema":{"type":"string"},"description":"Comma-separated symbols, at most 50. Quotes come back in this order."}],"responses":{"200":{"description":"One quote per symbol, in the order you asked. A symbol with no feed comes back with every value null, so show a dash.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotesResponse"}}}},"400":{"description":"No symbols, or more than 50.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests. Wait for the number of seconds in the `Retry-After` header, then try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/market/quotes?symbols=ESU6%2CNQU6%2CBTC-PERP', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/market/quotes?symbols=ESU6%2CNQU6%2CBTC-PERP' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/market/stream":{"get":{"tags":["Market data"],"summary":"Stream live bars","security":[{"tenantKey":[]}],"description":"Streams live bars for one symbol and timeframe as server-sent events (`text/event-stream`). Every time you connect or reconnect, the stream sends the full current window as a `snapshot` first, then live events, so an EventSource that reconnects on its own needs no bookkeeping from you. A spread expression streams like any symbol. A continuous futures symbol, `ES1!` or `ES2!`, streams the contract its position names when you connect, so reconnect after its roll to follow the next contract.\n\nRequired key: Trading API key.","parameters":[{"name":"instrument","in":"query","required":true,"schema":{"type":"string"},"description":"The symbol, or a spread expression as `/api/market/history` accepts. If any symbol in a spread is refused, the spread is refused."},{"name":"tf","in":"query","required":true,"schema":{"type":"string"},"description":"The timeframe, such as `1m`."}],"responses":{"200":{"description":"An open event stream. The events are:\n- `snapshot` `{ bars: WireBar[] }`: the whole current window.\n- `bar` `{ bar: WireBar }`: a bar that is forming or finished. The same `t` updates the forming bar, and a new `t` opens the next one.\n- `quote` `{ bid: { price, size }, ask: { price, size } }`: the real top of the book, only where the feed has one.\n- `error` `{ code }`: the stream is ending. The codes are `unknown_instrument`, `not_entitled`, `feed_down`, `session_displaced` (another application signed in on the login that serves the data and took its market data session) and `session_expired` (your own session ended: while you are signed in, the stream can't outlive your session). Sign in again before you reconnect, rather than retrying blind.\n\nA dropped connection carries no event, and the browser reconnects on its own.","content":{"text/event-stream":{"schema":{"type":"string"}}}},"400":{"description":"A parameter is malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"No feed serves this symbol. For futures, the code is `feed_requires_connection` (connect your own login at a provider that carries futures prices), `feed_capacity` or `feed_displaced`, answered before any stream opens.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/market/stream?instrument=ESU6&tf=5m', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst decoder = new TextDecoder()\nfor await (const chunk of res.body!) {\n  // Each SSE frame: \"event: <name>\\ndata: <json>\\n\\n\". Snapshot first, then live events.\n  process.stdout.write(decoder.decode(chunk as Uint8Array))\n}"},{"lang":"shell","label":"cURL","source":"curl -N 'https://app.trdrs.co/api/market/stream?instrument=ESU6&tf=5m' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/market/streams":{"get":{"tags":["Market data"],"summary":"Stream multiplexed live bars","security":[{"tenantKey":[]}],"description":"Streams up to 24 bar subscriptions over one server-sent events connection, so a layout with several charts needs one connection instead of one per chart, which browsers limit per site. Every event names the `instrument` and `tf` it belongs to. To change what you follow, reconnect with the new `subs`: each connection starts with a fresh `snapshot` per subscription.\n\nRequired key: Trading API key.","parameters":[{"name":"subs","in":"query","required":true,"schema":{"type":"string"},"description":"Comma-separated `INSTRUMENT~tf` subscriptions, at most 24. Percent-encode each instrument. `~` and `,` never occur in symbols. Duplicates count once, and a malformed subscription is dropped without an error."}],"responses":{"200":{"description":"An open event stream. The events are those of a single stream, each also naming its subscription:\n- `snapshot` `{ instrument, tf, bars: WireBar[] }`\n- `bar` `{ instrument, tf, bar: WireBar }`\n- `quote` `{ instrument, bid, ask }`\n- `error` `{ instrument, tf, code, message }`\n\nA subscription that is refused or fails, with a 503 code of the single stream or one of its ending codes, becomes an `error` event for that subscription, and the connection and every other subscription carry on. Only `session_expired`, your own session ending, closes the whole connection.","content":{"text/event-stream":{"schema":{"type":"string"}}}},"400":{"description":"No subscription is valid, or there are more than 24.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/market/streams?subs=ESU6~5m%2CNQU6~1m', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst decoder = new TextDecoder()\nfor await (const chunk of res.body!) {\n  // Each SSE frame: \"event: <name>\\ndata: <json>\\n\\n\". Snapshot first, then live events.\n  process.stdout.write(decoder.decode(chunk as Uint8Array))\n}"},{"lang":"shell","label":"cURL","source":"curl -N 'https://app.trdrs.co/api/market/streams?subs=ESU6~5m%2CNQU6~1m' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/news":{"get":{"tags":["News"],"summary":"List news headlines","security":[{"tenantKey":[]}],"description":"Returns market news headlines, newest first, optionally for one futures root or one publisher. To page back, pass the oldest headline's `publishedAt` as `before`. Show each `summary` as plain text: publisher HTML never appears.\n\nRequired key: Trading API key.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":50},"description":"How many headlines to return, from 1 to 100. A larger number is lowered to 100."},{"name":"before","in":"query","schema":{"type":"string"},"description":"An ISO 8601 time. Only headlines published strictly before it are returned. Use it to page."},{"name":"instrument","in":"query","schema":{"type":"string"},"description":"One futures root, such as `ES`, never a full catalog symbol. Headlines are tagged with roots as they arrive."},{"name":"source","in":"query","schema":{"type":"string"},"description":"One publisher's name."}],"responses":{"200":{"description":"The headlines, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewsResponse"}}}},"400":{"description":"`before` isn't a valid time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests. Wait for the number of seconds in the `Retry-After` header, then try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/news', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/news' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/news/image/{id}":{"get":{"tags":["News"],"summary":"Get a news thumbnail","description":"Returns the thumbnail for a headline, by the headline's `id`. Use the URL exactly as the image `src`. The route is keyless on purpose: thumbnails are public content behind ids no one can guess, and an `<img>` tag can't carry a key.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The headline's `id`, 64 hexadecimal characters."}],"responses":{"200":{"description":"The image. Its content type is the source image's, and it may be cached indefinitely.","content":{"image/*":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"The headline has no image (`imageUrl` is null), or the source image is gone. Show the headline without one."}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/news/image/{id}', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/news/image/{id}' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/calendar":{"get":{"tags":["News"],"summary":"List calendar events","security":[{"tenantKey":[]}],"description":"Returns economic calendar events in time order: from 12 hours ago to 7 days ahead by default, or the window you choose, up to 90 days. Filter by impact, category or country. An event's `actual` stays null until the figure is released, and `/api/calendar/stream` tells you when to fetch again.\n\nRequired key: Trading API key.","parameters":[{"name":"from","in":"query","schema":{"type":"string"},"description":"The start of the window, an ISO 8601 time, inclusive."},{"name":"to","in":"query","schema":{"type":"string"},"description":"The end of the window, an ISO 8601 time. The window can be at most 90 days."},{"name":"impact","in":"query","schema":{"type":"string"},"description":"Comma-separated impact levels to include: `high`, `medium` or `low`, such as `high,medium`."},{"name":"category","in":"query","schema":{"type":"string"},"description":"Only events of this category."},{"name":"country","in":"query","schema":{"type":"string"},"description":"Only events for this country, as an ISO country code."}],"responses":{"200":{"description":"The events, earliest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarResponse"}}}},"400":{"description":"A time is malformed, the window ends before it starts or is longer than 90 days, or an impact level is unknown.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests. Wait for the number of seconds in the `Retry-After` header, then try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/calendar', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/calendar' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/news/stream":{"get":{"tags":["News"],"summary":"Stream news","security":[{"tenantKey":[]}],"description":"Streams new headlines for the whole market as server-sent events (`text/event-stream`). It sends nothing when you connect, so fetch `/api/news` for the list first, then keep this open to add new headlines to the top. To follow one instrument, filter each headline by its `instruments`.\n\nRequired key: Trading API key.","responses":{"200":{"description":"An open event stream with one event, `news_item`: one headline as it arrives. Skip a headline whose `id` you already have. Calendar changes come on `/api/calendar/stream`. A dropped connection carries no event, and EventSource reconnects on its own.","content":{"text/event-stream":{"schema":{"type":"string"}}}},"429":{"description":"Too many requests. Wait for the number of seconds in the `Retry-After` header, then try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/news/stream', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst decoder = new TextDecoder()\nfor await (const chunk of res.body!) {\n  // Each SSE frame: \"event: <name>\\ndata: <json>\\n\\n\". Snapshot first, then live events.\n  process.stdout.write(decoder.decode(chunk as Uint8Array))\n}"},{"lang":"shell","label":"cURL","source":"curl -N 'https://app.trdrs.co/api/news/stream' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/calendar/stream":{"get":{"tags":["News"],"summary":"Stream calendar updates","security":[{"tenantKey":[]}],"description":"Streams a notice as server-sent events (`text/event-stream`) whenever the economic calendar changes. When one arrives, fetch your `/api/calendar` window again rather than reading the change from the notice.\n\nRequired key: Trading API key.","responses":{"200":{"description":"An open event stream with one event, `calendar_update`, whose payload names what changed. Headlines come on `/api/news/stream`. A dropped connection carries no event, and EventSource reconnects on its own.","content":{"text/event-stream":{"schema":{"type":"string"}}}},"429":{"description":"Too many requests. Wait for the number of seconds in the `Retry-After` header, then try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/calendar/stream', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst decoder = new TextDecoder()\nfor await (const chunk of res.body!) {\n  // Each SSE frame: \"event: <name>\\ndata: <json>\\n\\n\". Snapshot first, then live events.\n  process.stdout.write(decoder.decode(chunk as Uint8Array))\n}"},{"lang":"shell","label":"cURL","source":"curl -N 'https://app.trdrs.co/api/calendar/stream' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/trading/position":{"get":{"tags":["Trading"],"summary":"Get the net position","security":[{"tenantKey":[]}],"description":"Returns the account's net position in one instrument: the signed quantity and the average price. Use it when a trade ticket shows one instrument, instead of filtering the whole positions list. An account that holds separate tickets has no net position, so read its tickets from `GET /api/account/positions`.\n\nRequired key: Trading API key.","parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."},{"name":"instrument","in":"query","required":true,"schema":{"type":"string"},"description":"The instrument."}],"responses":{"200":{"description":"The net position. `qty` is signed, and 0 means flat.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetPositionResponse"}}}},"400":{"description":"The instrument is missing or invalid, or no provider is connected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"`position_mode_unsupported`: the account holds separate tickets, not one net position per instrument, so it doesn't add them up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/trading/position?instrument=ESU6', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/trading/position?instrument=ESU6' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/trading/actions":{"get":{"tags":["Trading"],"summary":"Get what the account may do","description":"Returns, for one instrument or for the whole account, whether each trading action is allowed right now: open, reduce, close, protect, flatten and cancel, with the refusal each blocked action would get. Read it to disable what would be refused and say why before anything is sent. It runs the same checks an order runs, in the same order, but sends nothing, so the order is still checked again when you send it.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."},{"name":"instrument","in":"query","required":false,"schema":{"type":"string"},"description":"The instrument to check. Omit it for the verdicts across the whole account."}],"responses":{"200":{"description":"One verdict per action. The checks run in this order: whether live trading is switched on (`feature_disabled`), the account's holds (`risk_locked`), the asset classes the provider may trade, an issued account's venue conditions, the account's settings at its provider, and the paper book's product rules. Anything that depends on the order itself or the moment, such as its size, a venue limit or whether the price is fresh, is checked only when you send the order, and a cancel is never refused by a standing rule. On an account bound to a risk policy, `open` shows what the account's risk check refuses an addition for, on the instrument you name or across the account: a stale price (`market_data_stale`), a price feed that is down (`market_data_unavailable`), or a book it cannot value (`risk_locked` with `risk_uncovered`). While the risk check is only processing the account's latest change, `open` shows no refusal, because an order sent then waits for it, at most 5 seconds. No hold refuses `protect`: a protective stop or target cannot add exposure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountActionsResponse"}}}},"400":{"description":"The instrument is invalid, the provider or account is unknown, or no provider is connected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Whether live trading is switched on couldn't be read. Try again after the `Retry-After` header's number of seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/trading/actions', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/trading/actions' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/trading/margin-preview":{"post":{"tags":["Trading"],"summary":"Preview order margin","description":"Returns the margin an order would need and whether the account can cover it, without placing anything. Because nothing is placed, it takes no `clientOrderId` and isn't stopped by a risk lock.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarginPreviewRequest"}}}},"responses":{"200":{"description":"The preview. `estimate` is false where the provider computes the figure itself (a Tastytrade dry run) and true otherwise, and `marginRequired` is null when it isn't known. On the paper book, including a Demo, the figure is the initial margin the order adds under the account's risk policy: the Demo margin schedule for a Demo, and the policy your venue published for an issued account. `sufficient` says whether the order fits the account's free collateral now, judged the same way the order is judged when it arrives: the paper book refuses an order that adds exposure when its margin, plus the commission of an order that fills now, doesn't fit. The figure stays an estimate, because the price and the free collateral can change before your order arrives. `marginRequired` and `sufficient` are null when there's no verdict: there's no price, a position can't be valued, the risk policy doesn't cover the instrument, or the order would be refused for another reason first. `basis` says which. A risk lock and your size limits aren't judged here.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarginPreviewResponse"}}}},"400":{"description":"The instrument, side, quantity or order type is invalid, or the provider can't trade the instrument's asset class. The body carries a `code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/trading/margin-preview', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"instrument\": \"ESU6\",\n    \"side\": \"buy\",\n    \"qty\": 2,\n    \"orderType\": \"market\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/trading/margin-preview' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"instrument\":\"ESU6\",\"side\":\"buy\",\"qty\":2,\"orderType\":\"market\"}'"}]}},"/api/trading/symbol-config":{"get":{"tags":["Trading"],"summary":"Get leverage and margin mode","description":"Returns the leverage and margin mode set for one instrument at the provider. It is a setting, not exposure, so it isn't stopped by your plan or a risk lock. Futures have no such setting, because their leverage is fixed by the contract.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."},{"name":"instrument","in":"query","required":true,"schema":{"type":"string"},"description":"The instrument."}],"responses":{"200":{"description":"The settings. `config` is null when the provider has no setting for the instrument.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SymbolConfigResponse"}}}},"400":{"description":"The instrument is missing or invalid, the provider can't trade its asset class, or the provider has no leverage setting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/trading/symbol-config?instrument=BTC-PERP', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/trading/symbol-config?instrument=BTC-PERP' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]},"put":{"tags":["Trading"],"summary":"Set leverage","description":"Sets the leverage for one instrument at the provider. trdrs never changes a margin mode or a position mode: the trader changes those at the provider itself. Where the provider sets leverage and margin mode together, trdrs sends back the margin mode it just read.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SymbolConfigRequest"}}}},"responses":{"200":{"description":"The leverage is set.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"400":{"description":"The instrument is missing, the leverage is missing or not positive, the body carries a `marginMode`, or the provider has no leverage setting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The provider refused, or trdrs couldn't read the margin mode it must send back with the leverage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/trading/symbol-config', {\n  method: 'PUT',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"instrument\": \"HYPERLIQUID:BTC\",\n    \"leverage\": 10\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X PUT 'https://app.trdrs.co/api/trading/symbol-config' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"instrument\":\"HYPERLIQUID:BTC\",\"leverage\":10}'"}]}},"/api/trading/order":{"post":{"tags":["Trading"],"summary":"Place an order","description":"Places a market, limit, stop or stop-limit order, optionally with a stop and target that are placed together with it or not at all, or with a saved exit plan instead. `clientOrderId` is the idempotency key, so retry an order with the same id and it is never placed twice. Call `GET /api/trading/actions` first to learn whether the order would be refused, and why. On the paper book an order waits, at most 5 seconds, for a price of its instrument that has not arrived yet, for that price to reach the account's risk check on an instrument the account does not hold yet, and for the risk check to process the account's latest change, so the answer can take that long. A reduce-only order carries no stop, target or exit plan: it opens no position for them to protect, and is refused with 400.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at. Omit it to use your default provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderRequest"}}}},"responses":{"200":{"description":"The order is placed. `warnings` reports anything that went only partly right, such as a short fill or exits trdrs couldn't register to manage. Show them.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderResponse"}}}},"400":{"description":"The order is invalid: an unknown instrument class, a missing leg, an order type that doesn't go with the others, or both an exit plan and a stop or target.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The `clientOrderId` was already used. The earlier request stands, which is idempotency working as designed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The order was refused and nothing was placed, so you may retry with the same `clientOrderId`. Every refusal carries its `code` and `params` beside the English `error`. The provider may refuse it (`order_rejected`, with the provider's words in `error`), or trdrs refuses it before sending because:\n- the account's settings at its provider are unsupported or can't be read (the account snapshot's `accountMode` gives the same code),\n- an issued account's venue conditions refuse it, or\n- the paper book, including a Personal Demo, can't price it honestly.\n\nOn the paper book the codes are:\n- `unknown_instrument`: a symbol with no contract specification, such as one only the chart feed serves or a Hyperliquid market deployed by a builder.\n- `instrument_not_tradable`: a product class with no proven terms.\n- `market_data_stale`, `market_data_unavailable` or `market_data_delayed`: the price is old, missing or from a delayed feed. An order waits for a price its instrument's feed has not delivered yet, at most 5 seconds, before it is refused as missing. On an account bound to a risk policy whose risk decisions have still had no price of the instrument the order adds to when that wait passes, the order is refused as `market_data_unavailable` with cause `mark_missing`. A futures order on a contract the account trades, from a trader with no futures source (a login on their firm's production Rithmic system), is refused as `market_data_unavailable` with cause `login_missing` before anything is claimed, whatever its type.\n- `settlement_asset_unmodeled`: a perpetual on an issued account that isn't held in the asset the perpetual settles in (USDC for a Hyperliquid core perpetual, USDT for a Binance or Bybit USDT perpetual).\n- `product_unproven`: any instrument, futures included, on an account held in USDC, other than the products trdrs trades in USDC, which today is HYPERLIQUID:BTC.\n- the refusals of its contract and risk policy (`contract_not_trading`, `contract_unregistered`, `risk_policy_unbound` and the rest) for an entry.\n\nOn a Rithmic account, a bare futures root goes to the one dated contract its product rule names. It is refused as `bare_root_unresolved` when the rule names none, the CME calendar trdrs serves doesn't cover the dates, the account holds the root in another contract, or the order would add exposure inside the contract's unsafe window. A dated contract is sent as itself, and an order that adds exposure to it inside its unsafe window is refused as `contract_past_safe_window`, or `contract_dates_uncovered` when the calendar can't place the window. A continuous symbol goes where its position names: `ES1!` where a bare `ES` goes, and `ES2!` to the contract after it, which is then sent as that dated contract. On a Tastytrade account, `ES1!` trades Tastytrade's active contract and `ES2!` is refused. A close, a flatten or an amend keeps the position's or the order's own contract.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"423":{"description":"The account is locked by risk (`risk_locked`, with the account's holds in `params.holds`, or null when they couldn't be read), or held for reconciliation (`reconciliation_hold`). New exposure is refused until the hold lifts or is released, while cancels, closes and reductions still work.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/trading/order', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"instrument\": \"ESU6\",\n    \"side\": \"buy\",\n    \"qty\": 2,\n    \"clientOrderId\": \"entry-esu6-1787580900\",\n    \"orderType\": \"limit\",\n    \"limitPrice\": 6480.5,\n    \"stopLoss\": {\n      \"price\": 6472.5,\n      \"offsetTicks\": 32\n    },\n    \"takeProfit\": {\n      \"price\": 6495,\n      \"offsetTicks\": 58\n    },\n    \"tif\": \"day\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/trading/order' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"instrument\":\"ESU6\",\"side\":\"buy\",\"qty\":2,\"clientOrderId\":\"entry-esu6-1787580900\",\"orderType\":\"limit\",\"limitPrice\":6480.5,\"stopLoss\":{\"price\":6472.5,\"offsetTicks\":32},\"takeProfit\":{\"price\":6495,\"offsetTicks\":58},\"tif\":\"day\"}'"}]}},"/api/trading/replace":{"post":{"tags":["Trading"],"summary":"Replace an order","description":"Moves one resting order to a new price, as one operation under one `clientOrderId`. Where the provider can change an order in place, trdrs does, and the order keeps its id; elsewhere trdrs cancels it and places it again. Always show the `outcome`: `replaced` and `amended` mean it worked, and `restored`, `restored_without_bracket`, `gone`, `unconfirmed` and `order_lost` mean it didn't.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at. Omit it to use your default provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplaceOrderRequest"}}}},"responses":{"200":{"description":"The replace is finished. Read `outcome`. When you replace an entry that has exits attached, always send `restoreBracket`, the exits as you know them: without it, an entry that is restored after a rejected replace comes back without its exits (`restored_without_bracket`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplaceOrderResponse"}}}},"400":{"description":"The body is malformed, a stop-limit order has no `stopLimitPrice`, or `orderType` isn't the type trdrs reports for the order (`order_type_mismatch`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"423":{"description":"The account is locked by risk (`risk_locked`) or held for reconciliation (`reconciliation_hold`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/trading/replace', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"providerOrderId\": \"234992187\",\n    \"instrument\": \"ESU6\",\n    \"side\": \"sell\",\n    \"qty\": 2,\n    \"orderType\": \"limit\",\n    \"price\": 6497.25,\n    \"clientOrderId\": \"replace-tp-1787582100\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/trading/replace' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"providerOrderId\":\"234992187\",\"instrument\":\"ESU6\",\"side\":\"sell\",\"qty\":2,\"orderType\":\"limit\",\"price\":6497.25,\"clientOrderId\":\"replace-tp-1787582100\"}'"}]}},"/api/trading/cancel":{"post":{"tags":["Trading"],"summary":"Cancel an order","security":[{"tenantKey":[]}],"description":"Cancels one resting order by its `providerOrderId`, the id the account stream and the orders list give it. trdrs answers only once the provider has accepted the cancel. Either way, the account stream tells you what is still resting.\n\nRequired key: Trading API key.","parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at. Omit it to use your default provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelOrderRequest"}}}},"responses":{"200":{"description":"The provider accepted the cancel. If the account is copied to follower accounts, the cancel is copied to them only after this."},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/trading/cancel', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"providerOrderId\": \"234992187\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/trading/cancel' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"providerOrderId\":\"234992187\"}'"}]}},"/api/trading/cancel-all":{"post":{"tags":["Trading"],"summary":"Cancel all working orders","description":"Cancels every working order on the account, or only those on one instrument. Cancelling twice is safe, so you can send it again after a partial failure.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelAllRequest"}}}},"responses":{"200":{"description":"Every order is cancelled. The response gives how many."},"400":{"description":"The instrument is invalid, or the provider can't cancel all orders at once. `cancel_all_incomplete` means the provider rejected a cancel partway through: the body gives how many were cancelled, so read the orders again and send it again rather than assume none are left.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/trading/cancel-all', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"instrument\": \"ESU6\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/trading/cancel-all' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"instrument\":\"ESU6\"}'"}]}},"/api/trading/exits":{"post":{"tags":["Trading"],"summary":"Set position exits","description":"Sets or replaces a position's stop and target, applied together as one unit. Each level is three-state: a number sets it, null removes it, and leaving it out keeps the resting order as it is. Send `positionId` to protect one position alone, which is how you protect a ticket on an account that holds separate tickets. No hold on the account refuses it: a stop or target only closes the position it protects and cannot add exposure.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at. Omit it to use your default provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExitsRequest"}}}},"responses":{"200":{"description":"The exits are set."},"400":{"description":"`clientOrderId` is missing (build it from the instrument and the levels, so a retry counts once), a level is malformed, or the provider doesn't name its positions (`position_exits_unsupported`). On an account that holds separate tickets, exits by instrument alone are refused with `position_mode_unsupported`. A position that is no longer open is refused with `position_not_closable`, and one that changed after the `positionRevision` you sent with `position_revision_stale`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/trading/exits', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"instrument\": \"ESU6\",\n    \"stopLoss\": 6472.5,\n    \"takeProfit\": 6495,\n    \"clientOrderId\": \"exits-esu6-6472.5-6495\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/trading/exits' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"instrument\":\"ESU6\",\"stopLoss\":6472.5,\"takeProfit\":6495,\"clientOrderId\":\"exits-esu6-6472.5-6495\"}'"}]}},"/api/trading/close":{"post":{"tags":["Trading"],"summary":"Close part of a position","description":"Closes part of a position at market, under your `clientOrderId`. A `qty` larger than the position is refused rather than cut down, because that would turn \"close 3\" into \"close everything\" if the position moved; use `/api/trading/flatten` to close it all. Send `positionId` to close one position alone and never past flat, which is how you close a ticket on an account that holds separate tickets.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClosePositionRequest"}}}},"responses":{"200":{"description":"The close is accepted."},"400":{"description":"There is no position to close, `qty` is larger than the position (`close_exceeds_position`), the instrument can't be traded here, or the provider doesn't name its positions (`position_close_unsupported`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The `clientOrderId` was already used, or the account has a hold and its provider doesn't enforce the close as reduce-only (`risk_locked`). Switching live trading off never stops a close, and under a hold a close passes only where the provider enforces it as reduce-only. The `close` verdict of `GET /api/trading/actions` tells you this before you send. A position that changed after the `positionRevision` you sent is refused here with `position_revision_stale`, and one that is no longer open on the instrument, is held on the side the close trades, or is smaller than `qty` is refused with 422 `position_not_closable`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/trading/close', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"instrument\": \"ESU6\",\n    \"qty\": 1,\n    \"clientOrderId\": \"close-esu6-1787582700\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/trading/close' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"instrument\":\"ESU6\",\"qty\":1,\"clientOrderId\":\"close-esu6-1787582700\"}'"}]}},"/api/trading/flatten":{"post":{"tags":["Trading"],"summary":"Flatten a position","security":[{"tenantKey":[]}],"description":"Cancels the instrument's working orders, then closes its position at market, in that order so a resting order can never reopen the position. It acts on the one account `provider` and `account` name. To flatten everything at once, use `/api/trading/flatten-account`.\n\nRequired key: Trading API key.","parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at. Omit it to use your default provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlattenRequest"}}}},"responses":{"200":{"description":"The position is flattened."},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/trading/flatten', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"instrument\": \"ESU6\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/trading/flatten' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"instrument\":\"ESU6\"}'"}]}},"/api/trading/flatten-account":{"post":{"tags":["Trading"],"summary":"Flatten the account","description":"Closes every position and cancels every working order on the one account `provider` and `account` name, never on every connected account at once. It can't be undone, so confirm with the trader before you call it.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."}],"responses":{"200":{"description":"The account is flat.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"400":{"description":"No provider is connected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/trading/flatten-account', {\n  method: 'POST',\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/trading/flatten-account' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/trading/reverse":{"post":{"tags":["Trading"],"summary":"Reverse a position","description":"Cancels the position's working orders, then turns it around with a market order for twice its quantity, as one operation under one `clientOrderId`. trdrs runs both steps itself, because a cancel and an order sent separately could fail in between and leave the trader flat or without exits.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at. Omit it to use your default provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReverseRequest"}}}},"responses":{"200":{"description":"The position is reversed. The response gives how many working orders were cancelled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReverseOrderResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The `clientOrderId` was already used.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"423":{"description":"The account is locked by risk (`risk_locked`) or held for reconciliation (`reconciliation_hold`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/trading/reverse', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"instrument\": \"ESU6\",\n    \"clientOrderId\": \"reverse-esu6-1787582400\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/trading/reverse' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"instrument\":\"ESU6\",\"clientOrderId\":\"reverse-esu6-1787582400\"}'"}]}},"/api/account/list":{"get":{"tags":["Account"],"summary":"List accounts","description":"Returns every account you can trade, one row per account, with what its provider supports. Use `capabilities` to decide what your interface offers: trdrs checks everything again on the server and refuses what isn't supported, so capabilities shape what you show, never what is allowed.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"responses":{"200":{"description":"The accounts. A money value is the provider's own, or null, never a made-up 0.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountListResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/list', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/account/list' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/instruments":{"get":{"tags":["Account"],"summary":"List account instruments","description":"Returns the symbols the account can trade through trdrs, with the label to show for the account in a symbol picker. The list comes from the same rules the order checks use, so an order for a listed symbol isn't refused for the symbol alone, and each dated futures contract says whether it is the one a continuous chart symbol trades now. Reading it makes no call to the provider.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."}],"responses":{"200":{"description":"The symbols the account can trade. The list depends on the account:\n- A futures account at a provider lists the futures catalog by root, such as `ES`, and the provider picks the contract each order trades. A crypto account lists its provider's perpetuals.\n- The paper book trades futures only as dated contracts, such as `CME:ESZ2026`, and lists each one from when trdrs registers it until its last trade. Energy, metals, currency and Treasury futures aren't registered, so they aren't listed. An account a venue issued lists what its venue lists and the account can enter.\n- The paper book prices futures only from the trader's own futures source, a login on their firm's production Rithmic system, so an account on it lists futures, from either list, only for a trader who has one.\n- A dated contract also carries `root`, `front` and `rollAt`. The contract of a root marked `front` is the one a continuous chart symbol of that root, such as `ES1!`, trades now, so an order placed from that chart names it as its `instrument`. At `rollAt` the root's next contract becomes the front one, so read the list again then. A Demo can only reduce a position in a contract past its roll, which stays listed until its last trade.\n- The paper book's perpetuals are the registered Hyperliquid core perpetuals, which settle in USDC, and the registered Binance and Bybit USDT perpetuals, which settle in USDT. A Hyperliquid market deployed by a builder isn't registered or listed.\n- A Demo settles a registered perpetual's profit and loss in USD at a fixed 1:1 rate, and holds no stablecoin. An issued account never does: it refuses a registered perpetual unless it is held in the asset that perpetual settles in.\n- So an issued USD account lists dated futures contracts and no perpetual, and an account held in USDC lists only the products trdrs trades in USDC, which today is HYPERLIQUID:BTC.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountInstrumentsResponse"}}}},"400":{"description":"The provider or account is unknown, or no provider is connected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/instruments', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/account/instruments' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/summary":{"get":{"tags":["Account"],"summary":"Get the account summary","description":"Returns the account's money in one read: balance, profit and loss, net liquidation value and buying power. A value is null when the provider hasn't reported it or the account has no such figure, never 0 in its place.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."}],"responses":{"200":{"description":"The account summary. Buying power is the provider's own figure, so it is null on the paper book, including a Demo, which reports none here. The paper book still refuses an order whose margin doesn't fit the account's free collateral, and the margin preview tells you beforehand. A Demo's balance is in USD: a registered perpetual's realized profit and loss (a Hyperliquid core perpetual settles in USDC, a Binance or Bybit USDT perpetual in USDT) is added to it in USD at a fixed 1:1 rate, never held as a stablecoin. An issued account's money is in the currency it is held in, USD or USDC, which `currency` names. When the paper book can't value a position honestly (it has no current price, the feed is delayed outside the sandbox, or a futures position's contract is no longer the one priced), `unrealizedPnl` and `netLiquidating` are null.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountSummary"}}}},"400":{"description":"The provider or account is unknown, or no provider is connected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/summary', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/account/summary' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/snapshot":{"get":{"tags":["Account"],"summary":"Get the account snapshot","description":"Returns the whole account at one revision: its summary, positions, working orders and protection. Read this rather than combining separate reads, which are three moments with nothing to say whether they agree. It is the same body the account stream sends, so a client with no stream open, or one coming back after a disconnect, gets exactly what the stream would have sent.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at. Omit it to use your default provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts."}],"responses":{"200":{"description":"The account at one revision.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountSnapshot"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Reading the provider failed. A partial snapshot is never returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/snapshot', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/account/snapshot' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/positions":{"get":{"tags":["Account"],"summary":"List open positions","description":"Returns the open positions in one read, with the position mode they were read under. On an account that holds separate tickets, each open ticket is its own row with its `positionId`, so a long and a short ticket on one instrument are two rows.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."}],"responses":{"200":{"description":"The open positions. `qty` is positive for long and negative for short. `liquidationPrice` and `leverage` are null where there is no such thing: for futures, and on the paper book.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PositionsResponse"}}}},"400":{"description":"The provider or account is unknown, or no provider is connected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/positions', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/account/positions' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/positions/closed":{"get":{"tags":["Account"],"summary":"List closed positions","description":"Returns the account's closed positions in one read. A provider that can't supply position history returns an empty list, not an error.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."}],"responses":{"200":{"description":"The closed positions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClosedPositionsResponse"}}}},"400":{"description":"The provider or account is unknown, or no provider is connected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/positions/closed', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/account/positions/closed' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/orders":{"get":{"tags":["Account"],"summary":"List orders","description":"Returns orders as the provider reports them now. Without `filter` you get the working orders, the same set the account stream sends, so the two agree. For the stored history, use `/api/account/orders/history`.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."},{"name":"filter","in":"query","schema":{"type":"string","enum":["all","open","filled","cancelled"]},"description":"Which orders to return. Omit it for the working orders."}],"responses":{"200":{"description":"The orders.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkingOrdersResponse"}}}},"400":{"description":"The filter is unknown, the provider or account is unknown, or no provider is connected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/orders', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/account/orders' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/orders/history":{"get":{"tags":["Account"],"summary":"List order history","description":"Returns the account's stored order history, newest first, one page at a time. Pass the previous page's `nextCursor` to get the next, until it is null. With `window=session`, only orders last changed in the current trading session are returned.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."},{"name":"bucket","in":"query","schema":{"type":"string","default":"all"},"description":"Which part of the history to return. Omit it for `all`."},{"name":"window","in":"query","schema":{"type":"string","enum":["session"]},"description":"`session` returns only the current trading session, which opens at 17:00 America/Chicago, and the response gives that open as `sinceSec`. Omit it for the whole history."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":100},"description":"How many orders per page, from 1 to 200. 100 by default."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"The previous page's `nextCursor`, exactly as returned. Omit it for the first page. A malformed cursor is refused with 400, never treated as the first page."}],"responses":{"200":{"description":"One page of order history. The provider's raw data is left out of every row.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderHistoryResponse"}}}},"400":{"description":"The bucket, window, limit or cursor is invalid, or no provider is connected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/orders/history', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/account/orders/history' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/executions":{"get":{"tags":["Account"],"summary":"List fills for an instrument","description":"Returns the account's fills in one instrument, newest first. They come from trdrs's own stored copy of the account's fills rather than the provider, so the history outlives a provider session, which is what fill markers on a chart need.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."},{"name":"instrument","in":"query","required":true,"schema":{"type":"string","maxLength":32},"description":"The instrument, at most 32 characters."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":200},"description":"How many fills to return, from 1 to 500. 200 by default."}],"responses":{"200":{"description":"The fills, newest first. On an account bound to a risk policy, fills in the same second keep the order they were recorded in, the later one first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecutionsResponse"}}}},"400":{"description":"The instrument is missing, the limit is invalid, or no provider is connected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/executions?instrument=ESU6', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/account/executions?instrument=ESU6' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/pnl/history":{"get":{"tags":["Account"],"summary":"Get daily P&L history","description":"Returns the account's profit and loss day by day, for an equity curve, optionally between two dates.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."},{"name":"from","in":"query","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"description":"The first day, exactly as YYYY-MM-DD."},{"name":"to","in":"query","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"description":"The last day, exactly as YYYY-MM-DD."}],"responses":{"200":{"description":"One row per trading day.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PnlHistoryResponse"}}}},"400":{"description":"A date is malformed, which is refused rather than widening the range, or no provider is connected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/pnl/history', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/account/pnl/history' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/pnl/round-trips":{"get":{"tags":["Account"],"summary":"List closed round trips","description":"Returns the account's closed trades, each an entry matched with the fill that closed it, newest first, one page at a time. Pass the previous page's `nextCursor` to get the next, until it is null.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":100},"description":"How many trades per page, from 1 to 500. 100 by default."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"The previous page's `nextCursor`, exactly as returned. Treat it as opaque. Omit it for the first page."}],"responses":{"200":{"description":"One page of closed trades.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoundTripsResponse"}}}},"400":{"description":"The limit or cursor is invalid, or no provider is connected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/pnl/round-trips', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/account/pnl/round-trips' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/brackets":{"get":{"tags":["Account"],"summary":"List position exits","description":"Returns the exits recorded around the account's positions, with each bracket's legs and their states, and the account revision they were read at. If you already hold a snapshot, you don't need this: the snapshot's `brackets` is the same list. This read makes no call to the provider and doesn't advance the revision.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at. Omit it to use your default provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts."}],"responses":{"200":{"description":"The brackets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BracketsResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/brackets', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/account/brackets' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/managed-exits":{"get":{"tags":["Account"],"summary":"List managed stops","description":"Returns the stops trdrs is moving for the account, such as a move to breakeven or a trailing stop, with the phase each has reached. Where one is paused, it says why nothing is moving the stop. The stop resting at the market still protects the position while it is paused.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at. Omit it to use your default provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts."}],"responses":{"200":{"description":"The managed stops.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManagedExitsResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/managed-exits', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/account/managed-exits' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/exit-plans":{"get":{"tags":["Account"],"summary":"List exit plans","description":"Returns your saved exit plans. A plan belongs to you, not to an account, so the same ladder applies to whichever account you pick. Each plan comes with its revision, which you send back to replace or delete it, and with what it needs an account to support, so you can offer only the plans the chosen account can run.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"responses":{"200":{"description":"Your plans.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExitPlansResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/exit-plans', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/exit-plans' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]},"post":{"tags":["Account"],"summary":"Create an exit plan","description":"Saves a new exit plan and returns it with its revision, which you need to edit it later. The plan is checked as it is saved: every leg has a stop, targets widen down the ladder, stops don't tighten down it, a trailing stop only tightens, and at most one leg is a runner.\n\nRequired key: Trading API key.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExitPlanWriteRequest"}}}},"security":[{"tenantKey":[]}],"responses":{"200":{"description":"The plan as saved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExitPlanResponse"}}}},"400":{"description":"The plan breaks one of the rules above.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/exit-plans', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"name\": \"Two rungs and a runner\",\n    \"revision\": \"q2Jm4XxT0aVnR7cLp1sZfE9d\",\n    \"applicability\": {\n      \"assetClasses\": [\n        \"futures\"\n      ],\n      \"instruments\": [\n        \"ES\"\n      ]\n    },\n    \"definition\": {\n      \"unit\": \"ticks\",\n      \"quantity\": 2,\n      \"tif\": \"gtc\",\n      \"entryType\": \"limit\",\n      \"legs\": [\n        {\n          \"seq\": 1,\n          \"quantity\": 1,\n          \"stopDistance\": 12,\n          \"targetDistance\": 20,\n          \"breakeven\": null,\n          \"trail\": []\n        },\n        {\n          \"seq\": 2,\n          \"quantity\": 1,\n          \"stopDistance\": 12,\n          \"targetDistance\": null,\n          \"breakeven\": {\n            \"triggerDistance\": 8,\n            \"plusDistance\": 0\n          },\n          \"trail\": [\n            {\n              \"stepSeq\": 1,\n              \"triggerDistance\": 16,\n              \"trailDistance\": 8,\n              \"frequencyTicks\": 2\n            }\n          ]\n        }\n      ]\n    }\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/exit-plans' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Two rungs and a runner\",\"revision\":\"q2Jm4XxT0aVnR7cLp1sZfE9d\",\"applicability\":{\"assetClasses\":[\"futures\"],\"instruments\":[\"ES\"]},\"definition\":{\"unit\":\"ticks\",\"quantity\":2,\"tif\":\"gtc\",\"entryType\":\"limit\",\"legs\":[{\"seq\":1,\"quantity\":1,\"stopDistance\":12,\"targetDistance\":20,\"breakeven\":null,\"trail\":[]},{\"seq\":2,\"quantity\":1,\"stopDistance\":12,\"targetDistance\":null,\"breakeven\":{\"triggerDistance\":8,\"plusDistance\":0},\"trail\":[{\"stepSeq\":1,\"triggerDistance\":16,\"trailDistance\":8,\"frequencyTicks\":2}]}]}}'"}]}},"/api/exit-plans/{id}":{"put":{"tags":["Account"],"summary":"Replace an exit plan","description":"Replaces a saved plan, but only if it hasn't changed since you read it: send the revision you read, and a plan edited in between is refused rather than overwritten. There is no write that skips this check.\n\nRequired key: Trading API key.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The plan's id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExitPlanWriteRequest"}}}},"security":[{"tenantKey":[]}],"responses":{"200":{"description":"The plan as saved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExitPlanResponse"}}}},"400":{"description":"The plan breaks a plan rule, or no revision was sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No such exit plan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The plan changed since you read it. The body gives the revision it has now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExitPlanConflict"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/exit-plans/{id}', {\n  method: 'PUT',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"name\": \"Two rungs and a runner\",\n    \"revision\": \"q2Jm4XxT0aVnR7cLp1sZfE9d\",\n    \"applicability\": {\n      \"assetClasses\": [\n        \"futures\"\n      ],\n      \"instruments\": [\n        \"ES\"\n      ]\n    },\n    \"definition\": {\n      \"unit\": \"ticks\",\n      \"quantity\": 2,\n      \"tif\": \"gtc\",\n      \"entryType\": \"limit\",\n      \"legs\": [\n        {\n          \"seq\": 1,\n          \"quantity\": 1,\n          \"stopDistance\": 12,\n          \"targetDistance\": 20,\n          \"breakeven\": null,\n          \"trail\": []\n        },\n        {\n          \"seq\": 2,\n          \"quantity\": 1,\n          \"stopDistance\": 12,\n          \"targetDistance\": null,\n          \"breakeven\": {\n            \"triggerDistance\": 8,\n            \"plusDistance\": 0\n          },\n          \"trail\": [\n            {\n              \"stepSeq\": 1,\n              \"triggerDistance\": 16,\n              \"trailDistance\": 8,\n              \"frequencyTicks\": 2\n            }\n          ]\n        }\n      ]\n    }\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X PUT 'https://app.trdrs.co/api/exit-plans/{id}' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Two rungs and a runner\",\"revision\":\"q2Jm4XxT0aVnR7cLp1sZfE9d\",\"applicability\":{\"assetClasses\":[\"futures\"],\"instruments\":[\"ES\"]},\"definition\":{\"unit\":\"ticks\",\"quantity\":2,\"tif\":\"gtc\",\"entryType\":\"limit\",\"legs\":[{\"seq\":1,\"quantity\":1,\"stopDistance\":12,\"targetDistance\":20,\"breakeven\":null,\"trail\":[]},{\"seq\":2,\"quantity\":1,\"stopDistance\":12,\"targetDistance\":null,\"breakeven\":{\"triggerDistance\":8,\"plusDistance\":0},\"trail\":[{\"stepSeq\":1,\"triggerDistance\":16,\"trailDistance\":8,\"frequencyTicks\":2}]}]}}'"}]},"delete":{"tags":["Account"],"summary":"Delete an exit plan","description":"Deletes a saved plan, but only if it hasn't changed since you read it, so you never delete an edit you haven't seen. Send the revision you read in the query string.\n\nRequired key: Trading API key.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The plan's id."},{"name":"revision","in":"query","required":true,"schema":{"type":"string"},"description":"The revision you read, exactly as returned."}],"security":[{"tenantKey":[]}],"responses":{"200":{"description":"The plan is deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"400":{"description":"No revision was sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No such exit plan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The plan changed since you read it. The body gives the revision it has now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExitPlanConflict"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/exit-plans/{id}?revision=q2Jm4XxT0aVnR7cLp1sZfE9d', {\n  method: 'DELETE',\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X DELETE 'https://app.trdrs.co/api/exit-plans/{id}?revision=q2Jm4XxT0aVnR7cLp1sZfE9d' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/exit-plans/preview":{"post":{"tags":["Account"],"summary":"Preview an exit plan","description":"Returns the exit orders a saved plan would place for this account and this order, priced from the account's own instrument facts, with a token that confirms them. Preview before you place the order: the order carries the token and no prices, so you and trdrs agree on the same order rather than on prices your client worked out.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at. Omit it to use your default provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExitPlanPreviewRequest"}}}},"responses":{"200":{"description":"The exit orders, what the plan protects and what it doesn't, and the token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExitPlanPreview"}}}},"400":{"description":"The plan doesn't apply here, the account can't run it, or it can't be priced on this instrument.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No such exit plan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/exit-plans/preview', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"planId\": \"0f6c2d18-7b4a-4a3e-9d21-8c5e4b0a9f37\",\n    \"instrument\": \"ESU6\",\n    \"side\": \"buy\",\n    \"quantity\": 2,\n    \"entryType\": \"limit\",\n    \"entryPrice\": 6480.5\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/account/exit-plans/preview' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"planId\":\"0f6c2d18-7b4a-4a3e-9d21-8c5e4b0a9f37\",\"instrument\":\"ESU6\",\"side\":\"buy\",\"quantity\":2,\"entryType\":\"limit\",\"entryPrice\":6480.5}'"}]}},"/api/risk":{"get":{"tags":["Account"],"summary":"Get the risk state","description":"Returns the account's five risk controls (daily and weekly loss limits, daily and weekly profit caps, and the end-of-day close) and whether they have locked it. When a control fires, the account is flattened and trading locks until the period resets, and every order route answers 423 `risk_locked` until then. The same lock arrives live as the `lock` event on `/api/account/stream`.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","required":true,"schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic`, `tastytrade` or `paper`. Required, because risk controls belong to one account and never fall back to a default."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number, when the login holds more than one. It must be one of your own accounts, or the call is refused with 400. Omit it for the login's default account."}],"responses":{"200":{"description":"The controls as stored and the lock state now. A daily lock resets at the 17:00 CT reopen, and a weekly lock at 17:00 CT on Sunday.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskStateResponse"}}}},"400":{"description":"The provider is missing or unknown, or the account isn't yours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/risk?provider=rithmic&account=PA-4821-07', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/risk?provider=rithmic&account=PA-4821-07' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]},"put":{"tags":["Account"],"summary":"Set the risk controls","description":"Replaces the account's five risk controls in one write, and they apply from that moment. A control that is on needs a positive value in range: loss and profit limits in the account's currency, and the end-of-day close in whole minutes before the 16:00 CT close, from 1 to 240.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","required":true,"schema":{"type":"string"},"description":"The provider the account is at. Required."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number, when the login holds more than one. It must be one of your own accounts, or the call is refused with 400."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskSettingsRequest"}}}},"responses":{"200":{"description":"The controls as stored and the lock state now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskStateResponse"}}}},"400":{"description":"The body isn't valid JSON, a control that is on has no positive value in range, or the provider or account is unknown.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`risk_policy_unbound`: the account isn't bound to a risk policy yet, so no limit can be counted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"423":{"description":"`settings_locked`: the settings are locked. After a control fires with \"lock settings when trading is locked\" on, they stay locked until 16:00 CT. On an account bound to a risk policy, they stay locked until the limit holding the account releases it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/risk?provider=rithmic&account=PA-4821-07', {\n  method: 'PUT',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"dailyLossEnabled\": true,\n    \"dailyLossValue\": 1000,\n    \"weeklyLossEnabled\": false,\n    \"weeklyLossValue\": null,\n    \"dailyProfitEnabled\": false,\n    \"dailyProfitValue\": null,\n    \"weeklyProfitEnabled\": false,\n    \"weeklyProfitValue\": null,\n    \"eodCloseEnabled\": true,\n    \"eodCloseValue\": 15,\n    \"lockSettingsWhenTradingLocked\": true\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X PUT 'https://app.trdrs.co/api/risk?provider=rithmic&account=PA-4821-07' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"dailyLossEnabled\":true,\"dailyLossValue\":1000,\"weeklyLossEnabled\":false,\"weeklyLossValue\":null,\"dailyProfitEnabled\":false,\"dailyProfitValue\":null,\"weeklyProfitEnabled\":false,\"weeklyProfitValue\":null,\"eodCloseEnabled\":true,\"eodCloseValue\":15,\"lockSettingsWhenTradingLocked\":true}'"}]}},"/api/risk/unlock":{"post":{"tags":["Account"],"summary":"Clear the risk lock","description":"Clears the trading lock your own controls set, so every control can protect the account again this period. The body is empty. A lock you can't clear, such as a failed evaluation, a firm halt or a lock on an account bound to a risk policy, stays in place. Every lock the risk state and the account stream show says in `clearable` whether this call clears it now, so read that rather than judging by `lockReason`.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","required":true,"schema":{"type":"string"},"description":"The provider the account is at. Required."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number, when the login holds more than one. It must be one of your own accounts, or the call is refused with 400."}],"responses":{"200":{"description":"The lock is cleared, or there was none. The body gives the lock state now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskUnlockResponse"}}}},"400":{"description":"The provider is missing or unknown, or the account isn't yours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`risk_lock_active`: the account is still locked, because the lock isn't yours to clear here, such as a failed evaluation, a firm halt or a lock on an account bound to a risk policy. `risk_lock_changed`: the lock changed while it was being cleared, so read the risk state and try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"423":{"description":"`settings_locked`: the settings are locked until 16:00 CT, so the lock can't be cleared early.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/risk/unlock?provider=rithmic&account=PA-4821-07', {\n  method: 'POST',\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/risk/unlock?provider=rithmic&account=PA-4821-07' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/stream":{"get":{"tags":["Account"],"summary":"Stream account updates","description":"Streams the account and its risk lock as server-sent events (`text/event-stream`). Every change arrives as one `account` event carrying the whole account at one consistent revision, the same body `/api/account/snapshot` returns, and every connection opens with one. Apply frames by the revision and nothing else: keep the newest for the `accountId`, drop any at or behind it, and replace your whole picture with any ahead of it.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at. Omit it to use your default provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts."}],"responses":{"200":{"description":"An open event stream. Each event's name is its `event:` line, and its `data:` line is the body.\n- `account`: the whole account at one revision. There is no separate snapshot event, because the first frame is simply the first. A row missing from a frame is closed or cancelled. A frame that skips revisions is still complete, so there is nothing to recover. Never work out a revision of your own. Exits are part of the account, so `brackets` and `managedExits` come in the same frame, at the same revision.\n- `lock`: the risk lock, as `GET /api/risk` returns it in `lock`.","content":{"text/event-stream":{"schema":{"type":"string"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/stream', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst decoder = new TextDecoder()\nfor await (const chunk of res.body!) {\n  // Each SSE frame: \"event: <name>\\ndata: <json>\\n\\n\". Snapshot first, then live events.\n  process.stdout.write(decoder.decode(chunk as Uint8Array))\n}"},{"lang":"shell","label":"cURL","source":"curl -N 'https://app.trdrs.co/api/account/stream' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/account/sync-status":{"get":{"tags":["Account"],"summary":"Get history sync status","description":"Returns how far trdrs has copied the account's fill history and order history from the provider. Use it to tell \"no history yet\" from \"history still being copied\" before you show an empty list as if it were complete.\n\nRequired key: Trading API key.","security":[{"tenantKey":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"},"description":"The provider the account is at, such as `rithmic` or `paper`. Omit it to use your default provider. An unknown value is refused with 400, never replaced with another provider."},{"name":"account","in":"query","schema":{"type":"string"},"description":"The account number at that provider. It must be one of your own accounts, or the call is refused with 400."}],"responses":{"200":{"description":"The state of each history. Each is null until copying has started.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncStatusResponse"}}}},"400":{"description":"No provider is connected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key is missing, unknown or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/account/sync-status', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/account/sync-status' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/connect/providers":{"get":{"tags":["Connect"],"summary":"List the built-in providers and how each is signed into","description":"Returns every built-in provider with the login style each one declares. Connect builds its grid from this list and shows one sign-in form per login style, so it also tells an embedding page which providers exist. The route is keyless on purpose: the list isn't secret, and a page deciding what to show hasn't signed anyone in yet.","responses":{"200":{"description":"The built-in providers, in a fixed order. Every tile in Connect's firm list carries the same `loginStyle`, taken from its provider. New providers and login styles are only ever added, never renamed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectProvidersResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/connect/providers', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/connect/providers' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/partner/connect/accounts":{"post":{"tags":["Connect"],"summary":"Pre-register a trader’s account","security":[{"partnerKey":[]}],"description":"Tells trdrs that a trader has an account at your built-in provider, so Connect shows it to them ready to link when they sign in with `email`. Your tile opens with your system filled in, and the trader signs in to the provider themselves to finish. Sending the same email and account number again refreshes the 30-day expiry instead of creating a second pre-registration. You notify the trader and give them their login yourself: trdrs sends them no email.\n\nRequired key: Partner key.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerRegistrationRegisterRequest"}}}},"responses":{"200":{"description":"The pre-registration, created or refreshed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerRegistrationRegisterResponse"}}}},"400":{"description":"The body is malformed, the email is missing or invalid, a field is too long, or the body carries the retired `handover` field. There is no field for a password.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key isn't a Partner key for an active firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/connect/accounts', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"email\": \"trader@example.com\",\n    \"accountNumber\": \"PA-4821-07\",\n    \"venueLogin\": \"jsmith-apex\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/connect/accounts' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"email\":\"trader@example.com\",\"accountNumber\":\"PA-4821-07\",\"venueLogin\":\"jsmith-apex\"}'"}]},"get":{"tags":["Connect"],"summary":"List pre-registered accounts","security":[{"partnerKey":[]}],"description":"Returns every pre-registration your firm has made, newest first, so you can see who you invited and who has linked. Each one is `pending` while it waits for the trader, `linked` once the trader has linked the account, `revoked` or `expired`.\n\nRequired key: Partner key.","responses":{"200":{"description":"Your firm’s pre-registrations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerRegistrationsResponse"}}}},"401":{"description":"The key isn't a Partner key for an active firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/connect/accounts', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/connect/accounts' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]},"delete":{"tags":["Connect"],"summary":"Cancel a pre-registration","security":[{"partnerKey":[]}],"description":"Cancels one pending pre-registration by its `id`, for example after a refund or a mistake. A linked one can't be cancelled, because the trader has already linked the account.\n\nRequired key: Partner key.","parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string"},"description":"The pre-registration's id."}],"responses":{"200":{"description":"The pre-registration is cancelled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerRegistrationRevokeResponse"}}}},"400":{"description":"`id` is missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The key isn't a Partner key for an active firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No pending pre-registration has that id: it is linked, already cancelled, or not yours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/connect/accounts?id=reg_7f3ka9', {\n  method: 'DELETE',\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X DELETE 'https://app.trdrs.co/api/partner/connect/accounts?id=reg_7f3ka9' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/partner/conformance/runs":{"post":{"tags":["Connect"],"summary":"Start a sandbox self-check","description":"Opens a free two-hour self-check run in the sandbox. During the run, trdrs watches the requests you make with your Partner and Trading API keys, and injects one rate limit, one risk lock and one dropped account and market stream for your client to handle. You can have one run open at a time.\n\nRequired key: Partner key, in the sandbox.","servers":[{"url":"https://sandbox.trdrs.co","description":"Sandbox only"}],"security":[{"partnerKey":[]}],"responses":{"201":{"description":"The run, with its results so far.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConformanceResponse"}}}},"401":{"description":"A valid sandbox Partner key is required."},"409":{"description":"This isn't the sandbox, or you already have a run open."}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://sandbox.trdrs.co/api/partner/conformance/runs', {\n  method: 'POST',\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://sandbox.trdrs.co/api/partner/conformance/runs' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/partner/conformance/runs/{id}":{"get":{"tags":["Connect"],"summary":"Read self-check results","description":"Returns a self-check run with the rules it has seen pass, fail or not yet exercised. Only your own firm can read its runs. An expired run stops injecting problems and can't pass.\n\nRequired key: Partner key, in the sandbox.","servers":[{"url":"https://sandbox.trdrs.co","description":"Sandbox only"}],"security":[{"partnerKey":[]}],"responses":{"200":{"description":"The run and its results.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConformanceResponse"}}}},"401":{"description":"A valid sandbox Partner key is required."},"404":{"description":"No such run, or it belongs to another firm."},"409":{"description":"This isn't the sandbox."}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The run's id."}],"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://sandbox.trdrs.co/api/partner/conformance/runs/{id}', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://sandbox.trdrs.co/api/partner/conformance/runs/{id}' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/partner/conformance/runs/{id}/close":{"post":{"tags":["Connect"],"summary":"Finish a sandbox self-check","description":"Closes the run and grades it. To pass, every rule must have been exercised and passed: an unanswered rate limit or dropped stream fails. After the injected risk lock, wait at least ten seconds before closing; a client that stopped correctly doesn't need to send again. How your client shows missing money values is attested separately, not measured here.\n\nRequired key: Partner key, in the sandbox.","servers":[{"url":"https://sandbox.trdrs.co","description":"Sandbox only"}],"security":[{"partnerKey":[]}],"responses":{"200":{"description":"The graded run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConformanceResponse"}}}},"401":{"description":"A valid sandbox Partner key is required."},"404":{"description":"No such run, or it belongs to another firm."},"409":{"description":"This isn't the sandbox, or the run is already closed."}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The run's id."}],"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://sandbox.trdrs.co/api/partner/conformance/runs/{id}/close', {\n  method: 'POST',\n  headers: { Authorization: `Bearer ${process.env.TRDRS_API_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://sandbox.trdrs.co/api/partner/conformance/runs/{id}/close' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\""}]}},"/api/partner/venues/{venueId}/provider-catalog/directory":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Browse public provider integrations","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Required scope: `venue:read`. Any authorized venue member may browse. Public releases are reviewed. Sandbox previews are visible only to the maintaining organization in the sandbox. Built-ins include trader-only providers labeled by company roles, without pretending to support venue execution.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","schema":{"type":"string","format":"uuid"},"description":"Cursor from nextCursor, or omit for the first page."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderDirectoryResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/directory', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/directory' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/provider-catalog/mine":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read your maintained integrations","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Required scope: `venue:read`. Returns integrations maintained by the selected venue organization and transfers involving it. Other organizations cannot read drafts.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderMaintainedResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/mine', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/mine' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/provider-catalog/profiles":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Create a private provider profile","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Required scope: `provider:manage`. Requires an organization owner and provider:manage. Creates one canonical company brand, with no Connect role.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderProfileCreateRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderProfileResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/profiles', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"profile\": {\n      \"name\": \"Example Pricing\",\n      \"blurb\": \"Test quotes\",\n      \"documentationUrl\": \"https://example.com/docs\",\n      \"connectionGuideUrl\": \"https://example.com/connect\",\n      \"contactEmail\": \"support@example.com\",\n      \"requirements\": \"Dedicated credentials\",\n      \"assetClasses\": [\n        \"forex\"\n      ],\n      \"maintainerNote\": \"Maintained by Example\"\n    }\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/profiles' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"profile\":{\"name\":\"Example Pricing\",\"blurb\":\"Test quotes\",\"documentationUrl\":\"https://example.com/docs\",\"connectionGuideUrl\":\"https://example.com/connect\",\"contactEmail\":\"support@example.com\",\"requirements\":\"Dedicated credentials\",\"assetClasses\":[\"forex\"],\"maintainerNote\":\"Maintained by Example\"}}'"}]}},"/api/partner/venues/{venueId}/provider-catalog/profiles/{companyId}":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Update provider profile","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Required scope: `provider:manage`. Requires the maintaining organization owner, provider:manage and the current profile version.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"companyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderProfileUpdateRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderProfileResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/profiles/{companyId}', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"profile\": {\n      \"name\": \"Example Pricing\",\n      \"blurb\": \"Test quotes\",\n      \"documentationUrl\": \"https://example.com/docs\",\n      \"connectionGuideUrl\": \"https://example.com/connect\",\n      \"contactEmail\": \"support@example.com\",\n      \"requirements\": \"Dedicated credentials\",\n      \"assetClasses\": [\n        \"forex\"\n      ],\n      \"maintainerNote\": \"Maintained by Example\"\n    },\n    \"expectedVersion\": 1\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/profiles/{companyId}' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"profile\":{\"name\":\"Example Pricing\",\"blurb\":\"Test quotes\",\"documentationUrl\":\"https://example.com/docs\",\"connectionGuideUrl\":\"https://example.com/connect\",\"contactEmail\":\"support@example.com\",\"requirements\":\"Dedicated credentials\",\"assetClasses\":[\"forex\"],\"maintainerNote\":\"Maintained by Example\"},\"expectedVersion\":1}'"}]}},"/api/partner/venues/{venueId}/provider-catalog/profiles/{companyId}/logo":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Upload a provider logo","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Required scope: `provider:manage`. Requires the maintaining owner and provider:manage. Stores a sanitized PNG using canonical company logo storage. data is base64 upload bytes. The new profile version is private pending review.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"companyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderProfileLogoRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderLogoResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/profiles/{companyId}/logo', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"data\": \"BASE64_PNG_BYTES\",\n    \"expectedVersion\": 1\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/profiles/{companyId}/logo' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"data\":\"BASE64_PNG_BYTES\",\"expectedVersion\":1}'"}]}},"/api/partner/venues/{venueId}/provider-catalog/profiles/{companyId}/releases":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Record an immutable provider release","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Required scope: `provider:manage`. Requires the maintaining owner and provider:manage. Evidence is a link, not approval. Data-only manifests require provider-market-data-v1; execution manifests require the complete provider-contract-v1 suite. Manifest, digest, author and evidence cannot be changed afterward.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"companyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderReleaseCreateRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderReleaseResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/profiles/{companyId}/releases', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"manifest\": {\n      \"providerVersion\": \"example-1\",\n      \"protocolVersion\": \"1.0\",\n      \"schemaDigest\": \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n      \"capabilities\": {\n        \"accounts\": false,\n        \"execution\": false,\n        \"marketData\": true,\n        \"generationFencing\": false,\n        \"completeOrderBook\": false,\n        \"executionHistory\": false,\n        \"executionCorrections\": false,\n        \"orderTypes\": [],\n        \"timeInForce\": [],\n        \"reduceOnly\": false,\n        \"nativeReplace\": false,\n        \"nativeOco\": false,\n        \"accountProvisioning\": false,\n        \"positionModels\": [],\n        \"replayRetentionSeconds\": 0\n      }\n    },\n    \"evidence\": {\n      \"suite\": \"provider-market-data-v1\",\n      \"url\": \"https://example.com/evidence\",\n      \"environment\": \"sandbox\"\n    },\n    \"expectedVersion\": 1\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/profiles/{companyId}/releases' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"manifest\":{\"providerVersion\":\"example-1\",\"protocolVersion\":\"1.0\",\"schemaDigest\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"capabilities\":{\"accounts\":false,\"execution\":false,\"marketData\":true,\"generationFencing\":false,\"completeOrderBook\":false,\"executionHistory\":false,\"executionCorrections\":false,\"orderTypes\":[],\"timeInForce\":[],\"reduceOnly\":false,\"nativeReplace\":false,\"nativeOco\":false,\"accountProvisioning\":false,\"positionModels\":[],\"replayRetentionSeconds\":0}},\"evidence\":{\"suite\":\"provider-market-data-v1\",\"url\":\"https://example.com/evidence\",\"environment\":\"sandbox\"},\"expectedVersion\":1}'"}]}},"/api/partner/venues/{venueId}/provider-catalog/profiles/{companyId}/publication":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Preview, submit or withdraw a provider release","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Required scope: `provider:manage`. Requires the maintaining owner and provider:manage. preview is sandbox-only, submit queues review, withdraw hides the profile without deleting customer connections or changing pinned manifests. action is preview, submit or withdraw.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"companyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderPublicationRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderPublicationResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/profiles/{companyId}/publication', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"releaseId\": \"00000000-0000-0000-0000-000000000002\",\n    \"action\": \"submit\",\n    \"expectedVersion\": 1\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/profiles/{companyId}/publication' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"releaseId\":\"00000000-0000-0000-0000-000000000002\",\"action\":\"submit\",\"expectedVersion\":1}'"}]}},"/api/partner/venues/{venueId}/provider-catalog/releases/{releaseId}/install":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Pin a published release to your venue","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Required scope: `provider:manage`. Requires provider:manage. Copies the approved immutable manifest into a venue-local candidate registration with publishedReleaseId. The evidence environment must match the venue. Credentials and validation are configured separately through the existing Connections routes. A listing never grants liquidity or execution.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"releaseId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderReleaseInstallRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderReleaseInstallResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/releases/{releaseId}/install', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/provider-catalog/releases/{releaseId}/install' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/operator/venues/{venueId}/provider-catalog/directory":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Browse public provider integrations","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Any authorized venue member may browse. Public releases are reviewed. Sandbox previews are visible only to the maintaining organization in the sandbox. Built-ins include trader-only providers labeled by company roles, without pretending to support venue execution.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","schema":{"type":"string","format":"uuid"},"description":"Cursor from nextCursor, or omit for the first page."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderDirectoryResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/directory', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/directory' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/operator/venues/{venueId}/provider-catalog/mine":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read your maintained integrations","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Returns integrations maintained by the selected venue organization and transfers involving it. Other organizations cannot read drafts.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderMaintainedResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/mine', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/mine' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/operator/venues/{venueId}/provider-catalog/profiles":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Create a private provider profile","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Requires an organization owner and provider:manage. Creates one canonical company brand, with no Connect role.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderProfileCreateRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderProfileResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/profiles', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"profile\": {\n      \"name\": \"Example Pricing\",\n      \"blurb\": \"Test quotes\",\n      \"documentationUrl\": \"https://example.com/docs\",\n      \"connectionGuideUrl\": \"https://example.com/connect\",\n      \"contactEmail\": \"support@example.com\",\n      \"requirements\": \"Dedicated credentials\",\n      \"assetClasses\": [\n        \"forex\"\n      ],\n      \"maintainerNote\": \"Maintained by Example\"\n    }\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/profiles' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"profile\":{\"name\":\"Example Pricing\",\"blurb\":\"Test quotes\",\"documentationUrl\":\"https://example.com/docs\",\"connectionGuideUrl\":\"https://example.com/connect\",\"contactEmail\":\"support@example.com\",\"requirements\":\"Dedicated credentials\",\"assetClasses\":[\"forex\"],\"maintainerNote\":\"Maintained by Example\"}}'"}]}},"/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Update provider profile","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Requires the maintaining organization owner, provider:manage and the current profile version.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"companyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderProfileUpdateRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderProfileResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"profile\": {\n      \"name\": \"Example Pricing\",\n      \"blurb\": \"Test quotes\",\n      \"documentationUrl\": \"https://example.com/docs\",\n      \"connectionGuideUrl\": \"https://example.com/connect\",\n      \"contactEmail\": \"support@example.com\",\n      \"requirements\": \"Dedicated credentials\",\n      \"assetClasses\": [\n        \"forex\"\n      ],\n      \"maintainerNote\": \"Maintained by Example\"\n    },\n    \"expectedVersion\": 1\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"profile\":{\"name\":\"Example Pricing\",\"blurb\":\"Test quotes\",\"documentationUrl\":\"https://example.com/docs\",\"connectionGuideUrl\":\"https://example.com/connect\",\"contactEmail\":\"support@example.com\",\"requirements\":\"Dedicated credentials\",\"assetClasses\":[\"forex\"],\"maintainerNote\":\"Maintained by Example\"},\"expectedVersion\":1}'"}]}},"/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}/logo":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Upload a provider logo","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Requires the maintaining owner and provider:manage. Stores a sanitized PNG using canonical company logo storage. data is base64 upload bytes. The new profile version is private pending review.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"companyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderProfileLogoRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderLogoResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}/logo', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"data\": \"BASE64_PNG_BYTES\",\n    \"expectedVersion\": 1\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}/logo' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"data\":\"BASE64_PNG_BYTES\",\"expectedVersion\":1}'"}]}},"/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}/releases":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Record an immutable provider release","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Requires the maintaining owner and provider:manage. Evidence is a link, not approval. Data-only manifests require provider-market-data-v1; execution manifests require the complete provider-contract-v1 suite. Manifest, digest, author and evidence cannot be changed afterward.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"companyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderReleaseCreateRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderReleaseResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}/releases', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"manifest\": {\n      \"providerVersion\": \"example-1\",\n      \"protocolVersion\": \"1.0\",\n      \"schemaDigest\": \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n      \"capabilities\": {\n        \"accounts\": false,\n        \"execution\": false,\n        \"marketData\": true,\n        \"generationFencing\": false,\n        \"completeOrderBook\": false,\n        \"executionHistory\": false,\n        \"executionCorrections\": false,\n        \"orderTypes\": [],\n        \"timeInForce\": [],\n        \"reduceOnly\": false,\n        \"nativeReplace\": false,\n        \"nativeOco\": false,\n        \"accountProvisioning\": false,\n        \"positionModels\": [],\n        \"replayRetentionSeconds\": 0\n      }\n    },\n    \"evidence\": {\n      \"suite\": \"provider-market-data-v1\",\n      \"url\": \"https://example.com/evidence\",\n      \"environment\": \"sandbox\"\n    },\n    \"expectedVersion\": 1\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}/releases' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"manifest\":{\"providerVersion\":\"example-1\",\"protocolVersion\":\"1.0\",\"schemaDigest\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"capabilities\":{\"accounts\":false,\"execution\":false,\"marketData\":true,\"generationFencing\":false,\"completeOrderBook\":false,\"executionHistory\":false,\"executionCorrections\":false,\"orderTypes\":[],\"timeInForce\":[],\"reduceOnly\":false,\"nativeReplace\":false,\"nativeOco\":false,\"accountProvisioning\":false,\"positionModels\":[],\"replayRetentionSeconds\":0}},\"evidence\":{\"suite\":\"provider-market-data-v1\",\"url\":\"https://example.com/evidence\",\"environment\":\"sandbox\"},\"expectedVersion\":1}'"}]}},"/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}/publication":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Preview, submit or withdraw a provider release","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Requires the maintaining owner and provider:manage. preview is sandbox-only, submit queues review, withdraw hides the profile without deleting customer connections or changing pinned manifests. action is preview, submit or withdraw.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"companyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderPublicationRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderPublicationResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}/publication', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"releaseId\": \"00000000-0000-0000-0000-000000000002\",\n    \"action\": \"submit\",\n    \"expectedVersion\": 1\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}/publication' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"releaseId\":\"00000000-0000-0000-0000-000000000002\",\"action\":\"submit\",\"expectedVersion\":1}'"}]}},"/api/operator/venues/{venueId}/provider-catalog/releases/{releaseId}/install":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Pin a published release to your venue","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Requires provider:manage. Copies the approved immutable manifest into a venue-local candidate registration with publishedReleaseId. The evidence environment must match the venue. Credentials and validation are configured separately through the existing Connections routes. A listing never grants liquidity or execution.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"releaseId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderReleaseInstallRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderReleaseInstallResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/releases/{releaseId}/install', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/releases/{releaseId}/install' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}/transfer":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Propose maintenance handoff","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Verified source owner session only. Target organization must exist and differ from the source. The proposal expires after seven days. No ownership changes until a distinct verified target owner accepts.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"companyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderTransferRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderTransferResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}/transfer', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"targetOrganizationId\": \"00000000-0000-0000-0000-000000000003\",\n    \"expectedVersion\": 1\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/profiles/{companyId}/transfer' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"targetOrganizationId\":\"00000000-0000-0000-0000-000000000003\",\"expectedVersion\":1}'"}]}},"/api/operator/venues/{venueId}/provider-catalog/transfers/{transferId}/accept":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Accept maintenance handoff","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Verified target owner session only, distinct from the proposer. Must accept an unexpired unchanged proposal. Stable profile/release IDs, author attribution and existing customer connections remain intact.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"transferId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderTransferAcceptRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderTransferResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/transfers/{transferId}/accept', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/transfers/{transferId}/accept' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/operator/venues/{venueId}/provider-catalog/transfers/{transferId}/cancel":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Cancel maintenance handoff","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. Verified source owner session only. Cancels a pending proposal, including an expired one.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"transferId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderTransferCancelRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderTransferResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/transfers/{transferId}/cancel', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/transfers/{transferId}/cancel' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/operator/venues/{venueId}/provider-catalog/releases/{releaseId}/review":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Review provider publication","description":"Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes. Provider directory publication is separate from execution qualification, trader Connect and private customer connections. No credential, private endpoint or account binding is published. Profile changes hide the listing until a release for the new profile version is reviewed. Every write requires Idempotency-Key; an identical retry returns its original result, a changed body refuses with idempotency_conflict. First-party ADMIN_EMAILS verified session only, with a selected authorized venue. Venue ownership or a venue key alone cannot approve a listing. Review the evidence for its stated environment/capabilities and record a note. list requires a submitted release matching the current profile version. Publication never qualifies execution.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"releaseId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderPublicationReviewRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderReleaseResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/releases/{releaseId}/review', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"decision\": \"list\",\n    \"note\": \"Data-only evidence reviewed\",\n    \"expectedVersion\": 1\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/provider-catalog/releases/{releaseId}/review' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"decision\":\"list\",\"note\":\"Data-only evidence reviewed\",\"expectedVersion\":1}'"}]}},"/api/partner/venues/{venueId}/providers":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"List provider versions","description":"Lists the public provider versions you registered for this venue, and the providers you can plug in. Use it to pick the provider version a new connection points at. Each version is a stored declaration: reading it contacts nobody and doesn't make the provider ready to trade. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string","format":"uuid"},"description":"The `nextCursor` from the previous page, sent unchanged. A page holds at most 500 records."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueProviderListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/providers', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/providers' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Register a public provider version","description":"Registers a public provider's declaration with this venue as a new candidate version, after checking the manifest field by field. Use it before you create a connection to that provider. Nothing is contacted, approved or turned on, and the response is the stored version. Required scope: `provider:manage`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueProviderSaveRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueProviderSaveResponse"}}}},"400":{"description":"The manifest breaks a rule of the provider contract, and `field` names the value refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`idempotency_conflict`: the `Idempotency-Key` already registered a version with a different name or manifest. The same key and body return the original version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/providers', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Example provider\",\n    \"manifest\": {\n      \"providerVersion\": \"example-v1\",\n      \"protocolVersion\": \"1.0\",\n      \"schemaDigest\": \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n      \"capabilities\": {\n        \"accounts\": true,\n        \"execution\": true,\n        \"marketData\": false,\n        \"generationFencing\": true,\n        \"completeOrderBook\": true,\n        \"executionHistory\": true,\n        \"executionCorrections\": false,\n        \"orderTypes\": [\n          \"market\",\n          \"limit\"\n        ],\n        \"timeInForce\": [\n          \"day\"\n        ],\n        \"reduceOnly\": true,\n        \"nativeReplace\": false,\n        \"nativeOco\": false,\n        \"accountProvisioning\": false,\n        \"positionModels\": [\n          \"net\"\n        ],\n        \"replayRetentionSeconds\": 604800\n      }\n    }\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/providers' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Example provider\",\"manifest\":{\"providerVersion\":\"example-v1\",\"protocolVersion\":\"1.0\",\"schemaDigest\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"capabilities\":{\"accounts\":true,\"execution\":true,\"marketData\":false,\"generationFencing\":true,\"completeOrderBook\":true,\"executionHistory\":true,\"executionCorrections\":false,\"orderTypes\":[\"market\",\"limit\"],\"timeInForce\":[\"day\"],\"reduceOnly\":true,\"nativeReplace\":false,\"nativeOco\":false,\"accountProvisioning\":false,\"positionModels\":[\"net\"],\"replayRetentionSeconds\":604800}}}'"}]}},"/api/partner/venues/{venueId}/connections":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"List provider connections","description":"Lists this venue's connections to public providers: the endpoint, the provider version and the state of each. Credentials never appear in the response, and a draft or validated connection isn't ready to trade. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string","format":"uuid"},"description":"The `nextCursor` from the previous page, sent unchanged. A page holds at most 500 records."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectionListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/connections', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/connections' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Create a provider connection draft","description":"Creates a draft connection from this venue to a provider version it registered, storing the provider's credential encrypted and bound to this connection. Use it after registering the provider, then validate the connection. Nothing is contacted yet, no account or trading permission is created, and the response is the connection without its credential. Required scope: `connection:manage`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectionSaveRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectionSaveResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The provider version isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`idempotency_conflict`: the `Idempotency-Key` already created a connection with a different body or credential. The same key and body return the original connection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/connections', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"providerVersionId\": \"00000000-0000-0000-0000-000000000001\",\n    \"endpoint\": \"https://provider.example.com\",\n    \"credentialId\": \"example-credential\",\n    \"credential\": \"replace-with-provider-credential\",\n    \"environment\": \"sandbox\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/connections' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"providerVersionId\":\"00000000-0000-0000-0000-000000000001\",\"endpoint\":\"https://provider.example.com\",\"credentialId\":\"example-credential\",\"credential\":\"replace-with-provider-credential\",\"environment\":\"sandbox\"}'"}]}},"/api/partner/venues/{venueId}/connections/{connectionId}/expose":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Show or hide a plugged-in provider to this venue's traders","description":"Shows a provider you plugged in to your own traders in Connect, or hides it again. It's hidden by default. While shown, it appears only to traders holding an account this venue issued, signed in with the firm's credentials, and the response is the connection's new setting. Required scope: `connection:manage`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"connectionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectionExposeRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectionExposeResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The connection doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/connections/{connectionId}/expose', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"exposed\": true\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/connections/{connectionId}/expose' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"exposed\":true}'"}]}},"/api/partner/venues/{venueId}/rules":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Turn venue rules on or off","description":"Turns venue rules, your own order limits, stages and analytics on the accounts you issue, on or off. Creating your first group turns them on, so use this to turn them off again or back on by hand. With them off, your settings stay saved but aren't applied to trading, and the response is the venue with its new setting. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRulesRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRulesResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/rules', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"enabled\": false\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/rules' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"enabled\":false}'"}]}},"/api/partner/venues/{venueId}/connections/{connectionId}/validate":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Queue read-only provider validation","description":"Queues a read-only check of a connection: the provider's published manifest is fetched and compared, and a provider that holds accounts then lists every account your credential can see. Send an empty JSON body, then poll the job it returns. No order is placed, and a pass neither clears a halt nor makes the connection ready to trade. Required scope: `connection:manage`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"connectionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters. A retry with the same key returns the original job, even a failed one, so send a new key to check again."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueValidationRequest"}}}},"responses":{"202":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueValidationResponse"}}}},"400":{"description":"The body isn't empty, or the connection is revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The connection doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`version_conflict`: a check of this connection is already pending or running.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/connections/{connectionId}/validate', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/connections/{connectionId}/validate' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/partner/venues/{venueId}/connections/{connectionId}/validations/{jobId}":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read provider validation status","description":"Reads one validation job, so you can poll it until it passes or fails. When `kind` is `manifest_and_accounts` and it passed, use its `discoverySnapshotId` to list and bind the accounts it found before they expire. A failure, an expiry or a lost permission never reads as a pass, and provider errors are redacted. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"connectionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"jobId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueValidationResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/connections/{connectionId}/validations/{jobId}', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/connections/{connectionId}/validations/{jobId}' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/operator/venues/{venueId}/providers":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"List provider versions","description":"Lists the public provider versions you registered for this venue, and the providers you can plug in. Use it to pick the provider version a new connection points at. Each version is a stored declaration: reading it contacts nobody and doesn't make the provider ready to trade. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string","format":"uuid"},"description":"The `nextCursor` from the previous page, sent unchanged. A page holds at most 500 records."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueProviderListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/providers', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/providers' \\\n  -b \"session=$TRDRS_SESSION\""}]},"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Register a public provider version","description":"Registers a public provider's declaration with this venue as a new candidate version, after checking the manifest field by field. Use it before you create a connection to that provider. Nothing is contacted, approved or turned on, and the response is the stored version. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueProviderSaveRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueProviderSaveResponse"}}}},"400":{"description":"The manifest breaks a rule of the provider contract, and `field` names the value refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`idempotency_conflict`: the `Idempotency-Key` already registered a version with a different name or manifest. The same key and body return the original version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/providers', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"name\": \"Example provider\",\n    \"manifest\": {\n      \"providerVersion\": \"example-v1\",\n      \"protocolVersion\": \"1.0\",\n      \"schemaDigest\": \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n      \"capabilities\": {\n        \"accounts\": true,\n        \"execution\": true,\n        \"marketData\": false,\n        \"generationFencing\": true,\n        \"completeOrderBook\": true,\n        \"executionHistory\": true,\n        \"executionCorrections\": false,\n        \"orderTypes\": [\n          \"market\",\n          \"limit\"\n        ],\n        \"timeInForce\": [\n          \"day\"\n        ],\n        \"reduceOnly\": true,\n        \"nativeReplace\": false,\n        \"nativeOco\": false,\n        \"accountProvisioning\": false,\n        \"positionModels\": [\n          \"net\"\n        ],\n        \"replayRetentionSeconds\": 604800\n      }\n    }\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/providers' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Example provider\",\"manifest\":{\"providerVersion\":\"example-v1\",\"protocolVersion\":\"1.0\",\"schemaDigest\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"capabilities\":{\"accounts\":true,\"execution\":true,\"marketData\":false,\"generationFencing\":true,\"completeOrderBook\":true,\"executionHistory\":true,\"executionCorrections\":false,\"orderTypes\":[\"market\",\"limit\"],\"timeInForce\":[\"day\"],\"reduceOnly\":true,\"nativeReplace\":false,\"nativeOco\":false,\"accountProvisioning\":false,\"positionModels\":[\"net\"],\"replayRetentionSeconds\":604800}}}'"}]}},"/api/operator/venues/{venueId}/connections":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"List provider connections","description":"Lists this venue's connections to public providers: the endpoint, the provider version and the state of each. Credentials never appear in the response, and a draft or validated connection isn't ready to trade. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string","format":"uuid"},"description":"The `nextCursor` from the previous page, sent unchanged. A page holds at most 500 records."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectionListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/connections', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/connections' \\\n  -b \"session=$TRDRS_SESSION\""}]},"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Create a provider connection draft","description":"Creates a draft connection from this venue to a provider version it registered, storing the provider's credential encrypted and bound to this connection. Use it after registering the provider, then validate the connection. Nothing is contacted yet, no account or trading permission is created, and the response is the connection without its credential. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectionSaveRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectionSaveResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The provider version isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`idempotency_conflict`: the `Idempotency-Key` already created a connection with a different body or credential. The same key and body return the original connection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/connections', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"providerVersionId\": \"00000000-0000-0000-0000-000000000001\",\n    \"endpoint\": \"https://provider.example.com\",\n    \"credentialId\": \"example-credential\",\n    \"credential\": \"replace-with-provider-credential\",\n    \"environment\": \"sandbox\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/connections' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"providerVersionId\":\"00000000-0000-0000-0000-000000000001\",\"endpoint\":\"https://provider.example.com\",\"credentialId\":\"example-credential\",\"credential\":\"replace-with-provider-credential\",\"environment\":\"sandbox\"}'"}]}},"/api/operator/venues/{venueId}/connections/{connectionId}/expose":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Show or hide a plugged-in provider to this venue's traders","description":"Shows a provider you plugged in to your own traders in Connect, or hides it again. It's hidden by default. While shown, it appears only to traders holding an account this venue issued, signed in with the firm's credentials, and the response is the connection's new setting. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"connectionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectionExposeRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectionExposeResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The connection doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/connections/{connectionId}/expose', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"exposed\": true\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/connections/{connectionId}/expose' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"exposed\":true}'"}]}},"/api/operator/venues/{venueId}/rules":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Turn venue rules on or off","description":"Turns venue rules, your own order limits, stages and analytics on the accounts you issue, on or off. Creating your first group turns them on, so use this to turn them off again or back on by hand. With them off, your settings stay saved but aren't applied to trading, and the response is the venue with its new setting. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRulesRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRulesResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/rules', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"enabled\": false\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/rules' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"enabled\":false}'"}]}},"/api/operator/venues/{venueId}/connections/{connectionId}/validate":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Queue read-only provider validation","description":"Queues a read-only check of a connection: the provider's published manifest is fetched and compared, and a provider that holds accounts then lists every account your credential can see. Send an empty JSON body, then poll the job it returns. No order is placed, and a pass neither clears a halt nor makes the connection ready to trade. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"connectionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters. A retry with the same key returns the original job, even a failed one, so send a new key to check again."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueValidationRequest"}}}},"responses":{"202":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueValidationResponse"}}}},"400":{"description":"The body isn't empty, or the connection is revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The connection doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`version_conflict`: a check of this connection is already pending or running.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/connections/{connectionId}/validate', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/connections/{connectionId}/validate' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/operator/venues/{venueId}/connections/{connectionId}/validations/{jobId}":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read provider validation status","description":"Reads one validation job, so you can poll it until it passes or fails. When `kind` is `manifest_and_accounts` and it passed, use its `discoverySnapshotId` to list and bind the accounts it found before they expire. A failure, an expiry or a lost permission never reads as a pass, and provider errors are redacted. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"connectionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"jobId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueValidationResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/connections/{connectionId}/validations/{jobId}', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/connections/{connectionId}/validations/{jobId}' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/partner/venues/{venueId}/existing-accounts":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"List existing accounts with original rules","description":"Lists the accounts the venue's adopted firm issued before it had a venue that no venue holds yet, closed ones included, each still under the rules it was issued with. Use it to see what's left to bring into the venue. Reading it changes nothing, and pages are read one at a time, so read again after you move accounts. Required scope: `account:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string"},"description":"The `nextCursor` from the previous page, sent unchanged and URL-encoded. A page holds at most 100 rows."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueExistingAccountListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/existing-accounts', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/existing-accounts' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/accounts":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"List a venue's accounts","description":"Lists every account the venue holds, ordered by `accountId`, 100 to a page. Each row names the account's group, the trader's email and status where the venue issued it, and the balance where trdrs keeps it. Required scope: `account:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string"},"description":"The `nextCursor` from the previous page, which is the last `accountId` it held. A page holds at most 100 rows."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Issue an account into a group","description":"Issues a trader an account in one of your groups, for example when they buy an evaluation. The account opens on the paper book with the starting balance and currency you choose, under the stage your group runs and your published risk policy, and trades every product class that policy offers from its one balance. The trader finds it in their account list from the moment you get the answer. The response is the account, and the same `referenceId` sent again returns the same account with `created: false` and status `200`. Required scope: `account:issue`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, recorded as the audit reference of this write. The `referenceId` in the body is what makes the issue safe to retry."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountIssueRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountIssueResponse"}}}},"400":{"description":"`invalid_request` names the refused value in `field` (such as `startingBalance`, `riskPolicy` or `positionMode`). `currency_not_issuable` means this environment doesn't issue the currency, with `params.currency` and `params.environment`. Nothing is written.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"`no_user_with_that_email`: no trdrs sign-in uses that email. Also answered for a group or venue that isn't yours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Nothing is written. `group_has_no_route`: the group has no route. `risk_policy_unpublished`, `risk_policy_currency_mismatch` or `risk_policy_authority_mismatch`: the policy isn't published, is in another currency, or isn't yours. `position_mode_unsupported`: independent tickets under a policy that states no ticket hedging for a product class it offers. `idempotency_conflict`: the `referenceId` already issued an account with a different request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"groupId\": \"firm-meridian-evaluation\",\n    \"email\": \"trader@example.com\",\n    \"startingBalance\": 50000,\n    \"currency\": \"USD\",\n    \"riskPolicy\": {\n      \"policyId\": \"meridian-futures\"\n    },\n    \"positionMode\": \"net\",\n    \"referenceId\": \"order-84117\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"groupId\":\"firm-meridian-evaluation\",\"email\":\"trader@example.com\",\"startingBalance\":50000,\"currency\":\"USD\",\"riskPolicy\":{\"policyId\":\"meridian-futures\"},\"positionMode\":\"net\",\"referenceId\":\"order-84117\"}'"}]}},"/api/partner/venues/{venueId}/accounts/{accountId}/balance":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Credit, debit or adjust an account's balance","description":"Credits, debits or adjusts an account's balance, for a payout, a refund or a correction. The money is recorded in the account currency, apart from trading P&L, and on an account the venue issued a debit can only take money no open position or working order is holding. The response names what was recorded. Required scope: `balance:write`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Your reference for this operation, 1 to 128 characters. It is recorded before any money moves, so a retry with the same key is refused as `duplicate_reference` and moves nothing a second time. Read the result by this reference with the balance receipt route, which reads every reference this write accepts."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountBalanceRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountBalanceResponse"}}}},"400":{"description":"`amount_precision_exceeded`: the amount has more decimals than the account currency posts in, with `params.currency` and `params.decimals`. `invalid_request` names a malformed value in `field`. Nothing is recorded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Nothing is recorded. `duplicate_reference`: the `Idempotency-Key` was already used. `balance_refused`: the account can't spare the debit or a hold stops it, with `reason` (`insufficient_funds`, `permission_denied` or `invalid_request`). An account held for reconciliation answers `423` `reconciliation_hold` instead, and moves no money, a credit included, until a trdrs operator releases it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"The operation couldn't be applied here, so don't assume it happened. When another engine machine owns the account, the response carries `Retry-After`: retry with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/balance', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"op\": \"debit\",\n    \"amount\": 800,\n    \"comment\": \"payout 2026-08-31\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/balance' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"op\":\"debit\",\"amount\":800,\"comment\":\"payout 2026-08-31\"}'"}]}},"/api/partner/venues/{venueId}/accounts/{accountId}/reset":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Reset an account to its starting balance","description":"Resets an account for a new attempt, for example when a trader buys a retry after failing an evaluation. The balance returns to the figure its running cycle started at, a new cycle opens under the stage rules in force, and your `account.reset` webhook event is sent. The account must already be flat with no working order: a reset never closes or cancels anything. Required scope: `account:reset`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Your reference for this reset, 1 to 128 characters. It is recorded with the reset, so a retry with the same key is refused as `duplicate_reference` and never resets twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountResetRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountResetResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Nothing is recorded. `duplicate_reference`: the `Idempotency-Key` was already used. `not_settled`: the account holds a position, a working order, or an order or command whose outcome isn't known yet. `risk_unresolved`: its risk isn't resolved. `deficit_unreconciled`: its balance is negative. An account held for reconciliation answers `423` `reconciliation_hold` instead.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/reset', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"comment\": \"failed evaluation, second attempt\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/reset' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"comment\":\"failed evaluation, second attempt\"}'"}]}},"/api/partner/venues/{venueId}/accounts/{accountId}/halt":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Halt trading on an account","description":"Halts an account so it can't place new orders until you resume it, for example while you review its trading. Send an empty JSON body. Open positions stay open, the trader can't lift your halt, and halting an account you already halted changes nothing. Required scope: `risk:halt`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountHaltRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountHaltResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`lock_conflict`: the account is already locked by something other than your halt, which is left in place and named.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/halt', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/halt' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/partner/venues/{venueId}/accounts/{accountId}/resume":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Resume trading on an account","description":"Lifts your own halt on an account so it can trade again. Send an empty JSON body. It clears your halt and nothing else, and the response says whether the account is still halted. Required scope: `risk:halt`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountResumeRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountResumeResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`lock_conflict`: the account is locked by something other than your halt, such as a risk rule, and resuming doesn't clear it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/resume', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/resume' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/partner/venues/{venueId}/accounts/{accountId}/risk-controls":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read an account's five risk controls","description":"Reads an account's five risk controls: the daily and weekly loss limits, the daily and weekly profit targets, and the end-of-day close. The response also says whether the account is halted and why, where `firm_halt` is your own halt. Required scope: `account:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskControlsResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/risk-controls', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/risk-controls' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Replace an account's five risk controls","description":"Replaces all five of an account's risk controls in one write. A control that fires flattens the account and locks it, which is why this takes the halting scope. The same body twice changes nothing the second time, the trader's own \"prevent changes while locked\" choice survives it, and the response is the controls as stored. Required scope: `risk:halt`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskControlsRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskControlsResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/risk-controls', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"dailyLossEnabled\": true,\n    \"dailyLossValue\": 1500,\n    \"weeklyLossEnabled\": false,\n    \"dailyProfitEnabled\": false,\n    \"weeklyProfitEnabled\": false,\n    \"eodCloseEnabled\": true,\n    \"eodCloseValue\": 10\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/risk-controls' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"dailyLossEnabled\":true,\"dailyLossValue\":1500,\"weeklyLossEnabled\":false,\"dailyProfitEnabled\":false,\"weeklyProfitEnabled\":false,\"eodCloseEnabled\":true,\"eodCloseValue\":10}'"}]}},"/api/partner/venues/{venueId}/accounts/{accountId}/analytics":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read an account's analytics","description":"Reads one account's performance in its current cycle: net trading P&L apart from balance operations, trading days, breaches and equity samples. Trading days are counted in the session of the stage rules the cycle is judged by, or the 17:00 America/Chicago roll when no stage judges it. For an account held at a provider the same read covers the provider's records, with no equity history and no rules of yours. Required scope: `account:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"equityBefore","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"To page back through equity samples, send the `equityHistory.nextBefore` of the previous response. Check the cycle id hasn't changed between pages."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountAnalyticsResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/analytics', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/analytics' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/operator/venues/{venueId}/existing-accounts":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"List existing accounts with original rules","description":"Lists the accounts the venue's adopted firm issued before it had a venue that no venue holds yet, closed ones included, each still under the rules it was issued with. Use it to see what's left to bring into the venue. Reading it changes nothing, and pages are read one at a time, so read again after you move accounts. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string"},"description":"The `nextCursor` from the previous page, sent unchanged and URL-encoded. A page holds at most 100 rows."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueExistingAccountListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/existing-accounts', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/existing-accounts' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/operator/venues/{venueId}/accounts":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"List a venue's accounts","description":"Lists every account the venue holds, ordered by `accountId`, 100 to a page. Each row names the account's group, the trader's email and status where the venue issued it, and the balance where trdrs keeps it. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string"},"description":"The `nextCursor` from the previous page, which is the last `accountId` it held. A page holds at most 100 rows."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/accounts', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/accounts' \\\n  -b \"session=$TRDRS_SESSION\""}]},"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Issue an account into a group","description":"Issues a trader an account in one of your groups, for example when they buy an evaluation. The account opens on the paper book with the starting balance and currency you choose, under the stage your group runs and your published risk policy, and trades every product class that policy offers from its one balance. The trader finds it in their account list from the moment you get the answer. The response is the account, and the same `referenceId` sent again returns the same account with `created: false` and status `200`. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, recorded as the audit reference of this write. The `referenceId` in the body is what makes the issue safe to retry."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountIssueRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountIssueResponse"}}}},"400":{"description":"`invalid_request` names the refused value in `field` (such as `startingBalance`, `riskPolicy` or `positionMode`). `currency_not_issuable` means this environment doesn't issue the currency, with `params.currency` and `params.environment`. Nothing is written.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"`no_user_with_that_email`: no trdrs sign-in uses that email. Also answered for a group or venue that isn't yours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Nothing is written. `group_has_no_route`: the group has no route. `risk_policy_unpublished`, `risk_policy_currency_mismatch` or `risk_policy_authority_mismatch`: the policy isn't published, is in another currency, or isn't yours. `position_mode_unsupported`: independent tickets under a policy that states no ticket hedging for a product class it offers. `idempotency_conflict`: the `referenceId` already issued an account with a different request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/accounts', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"groupId\": \"firm-meridian-evaluation\",\n    \"email\": \"trader@example.com\",\n    \"startingBalance\": 50000,\n    \"currency\": \"USD\",\n    \"riskPolicy\": {\n      \"policyId\": \"meridian-futures\"\n    },\n    \"positionMode\": \"net\",\n    \"referenceId\": \"order-84117\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/accounts' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"groupId\":\"firm-meridian-evaluation\",\"email\":\"trader@example.com\",\"startingBalance\":50000,\"currency\":\"USD\",\"riskPolicy\":{\"policyId\":\"meridian-futures\"},\"positionMode\":\"net\",\"referenceId\":\"order-84117\"}'"}]}},"/api/operator/venues/{venueId}/accounts/{accountId}/balance":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Credit, debit or adjust an account's balance","description":"Credits, debits or adjusts an account's balance, for a payout, a refund or a correction. The money is recorded in the account currency, apart from trading P&L, and on an account the venue issued a debit can only take money no open position or working order is holding. The response names what was recorded. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Your reference for this operation, 1 to 128 characters. It is recorded before any money moves, so a retry with the same key is refused as `duplicate_reference` and moves nothing a second time. Read the result by this reference with the balance receipt route, which reads every reference this write accepts."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountBalanceRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountBalanceResponse"}}}},"400":{"description":"`amount_precision_exceeded`: the amount has more decimals than the account currency posts in, with `params.currency` and `params.decimals`. `invalid_request` names a malformed value in `field`. Nothing is recorded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Nothing is recorded. `duplicate_reference`: the `Idempotency-Key` was already used. `balance_refused`: the account can't spare the debit or a hold stops it, with `reason` (`insufficient_funds`, `permission_denied` or `invalid_request`). An account held for reconciliation answers `423` `reconciliation_hold` instead, and moves no money, a credit included, until a trdrs operator releases it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"The operation couldn't be applied here, so don't assume it happened. When another engine machine owns the account, the response carries `Retry-After`: retry with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/accounts/{accountId}/balance', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"op\": \"debit\",\n    \"amount\": 800,\n    \"comment\": \"payout 2026-08-31\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/accounts/{accountId}/balance' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"op\":\"debit\",\"amount\":800,\"comment\":\"payout 2026-08-31\"}'"}]}},"/api/operator/venues/{venueId}/accounts/{accountId}/reset":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Reset an account to its starting balance","description":"Resets an account for a new attempt, for example when a trader buys a retry after failing an evaluation. The balance returns to the figure its running cycle started at, a new cycle opens under the stage rules in force, and your `account.reset` webhook event is sent. The account must already be flat with no working order: a reset never closes or cancels anything. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Your reference for this reset, 1 to 128 characters. It is recorded with the reset, so a retry with the same key is refused as `duplicate_reference` and never resets twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountResetRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountResetResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Nothing is recorded. `duplicate_reference`: the `Idempotency-Key` was already used. `not_settled`: the account holds a position, a working order, or an order or command whose outcome isn't known yet. `risk_unresolved`: its risk isn't resolved. `deficit_unreconciled`: its balance is negative. An account held for reconciliation answers `423` `reconciliation_hold` instead.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/accounts/{accountId}/reset', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"comment\": \"failed evaluation, second attempt\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/accounts/{accountId}/reset' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"comment\":\"failed evaluation, second attempt\"}'"}]}},"/api/operator/venues/{venueId}/accounts/{accountId}/halt":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Halt trading on an account","description":"Halts an account so it can't place new orders until you resume it, for example while you review its trading. Send an empty JSON body. Open positions stay open, the trader can't lift your halt, and halting an account you already halted changes nothing. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountHaltRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountHaltResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`lock_conflict`: the account is already locked by something other than your halt, which is left in place and named.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/accounts/{accountId}/halt', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/accounts/{accountId}/halt' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/operator/venues/{venueId}/accounts/{accountId}/resume":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Resume trading on an account","description":"Lifts your own halt on an account so it can trade again. Send an empty JSON body. It clears your halt and nothing else, and the response says whether the account is still halted. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountResumeRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountResumeResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`lock_conflict`: the account is locked by something other than your halt, such as a risk rule, and resuming doesn't clear it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/accounts/{accountId}/resume', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/accounts/{accountId}/resume' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/operator/venues/{venueId}/accounts/{accountId}/risk-controls":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read an account's five risk controls","description":"Reads an account's five risk controls: the daily and weekly loss limits, the daily and weekly profit targets, and the end-of-day close. The response also says whether the account is halted and why, where `firm_halt` is your own halt. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskControlsResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/accounts/{accountId}/risk-controls', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/accounts/{accountId}/risk-controls' \\\n  -b \"session=$TRDRS_SESSION\""}]},"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Replace an account's five risk controls","description":"Replaces all five of an account's risk controls in one write. A control that fires flattens the account and locks it, which is why this takes the halting scope. The same body twice changes nothing the second time, the trader's own \"prevent changes while locked\" choice survives it, and the response is the controls as stored. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskControlsRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskControlsResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/accounts/{accountId}/risk-controls', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"dailyLossEnabled\": true,\n    \"dailyLossValue\": 1500,\n    \"weeklyLossEnabled\": false,\n    \"dailyProfitEnabled\": false,\n    \"weeklyProfitEnabled\": false,\n    \"eodCloseEnabled\": true,\n    \"eodCloseValue\": 10\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/accounts/{accountId}/risk-controls' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"dailyLossEnabled\":true,\"dailyLossValue\":1500,\"weeklyLossEnabled\":false,\"dailyProfitEnabled\":false,\"weeklyProfitEnabled\":false,\"eodCloseEnabled\":true,\"eodCloseValue\":10}'"}]}},"/api/operator/venues/{venueId}/accounts/{accountId}/analytics":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read an account's analytics","description":"Reads one account's performance in its current cycle: net trading P&L apart from balance operations, trading days, breaches and equity samples. Trading days are counted in the session of the stage rules the cycle is judged by, or the 17:00 America/Chicago roll when no stage judges it. For an account held at a provider the same read covers the provider's records, with no equity history and no rules of yours. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"equityBefore","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"To page back through equity samples, send the `equityHistory.nextBefore` of the previous response. Check the cycle id hasn't changed between pages."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountAnalyticsResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/accounts/{accountId}/analytics', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/accounts/{accountId}/analytics' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/partner/venues/{venueId}/usage":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read the venue's metered usage for a month","description":"Reads what the venue's firm is billed for in one month: the active accounts, the price per account and the amount, from the same figures the invoice uses. Money is in US cents, and a null price or amount means the month isn't priced yet, never a zero bill. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"month","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$"},"description":"The month, as `YYYY-MM` in UTC. Leave it out for the previous complete calendar month, the one being invoiced."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueUsageResponse"}}}},"400":{"description":"`invalid_month`: `month` isn't a valid `YYYY-MM`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The usage can't be read for this venue's firm, and it is never answered as a silent zero.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/usage', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/usage' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/usage/accounts":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read the accounts behind the venue's usage","description":"Lists the accounts that counted toward one month's usage, by account number, with the fills that made each count. The list always adds up to `activeAccounts` for the same month. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"month","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$"},"description":"The month, as `YYYY-MM` in UTC. Leave it out for the previous complete calendar month, the one being invoiced."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueUsageAccountsResponse"}}}},"400":{"description":"`invalid_month`: `month` isn't a valid `YYYY-MM`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The usage can't be read for this venue's firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/usage/accounts', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/usage/accounts' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/balance-ops/{referenceId}":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read the receipt of one balance operation","description":"Reads the recorded result of one balance operation by its reference, the `Idempotency-Key` you sent with it. Use it when you lost the answer to a balance write and need to know whether it was applied. A `state` of `legacy_unknown` means an older route recorded the operation without its outcome. Required scope: `account:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"referenceId","in":"path","required":true,"schema":{"type":"string","maxLength":128},"description":"The reference of the balance operation, at most 128 characters."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueBalanceReceiptResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No balance operation with that reference exists for this venue's firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/balance-ops/{referenceId}', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/balance-ops/{referenceId}' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/webhooks":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"List the venue's webhooks","description":"Lists every endpoint the venue's firm registered, newest first, with the event types a filter can name. Each row carries its signing secret, which lets your endpoint check a delivery came from trdrs and grants nothing here. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueWebhookListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue has no firm to bill or notify, or the resource isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/webhooks', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/webhooks' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Register a webhook","description":"Registers an endpoint that trdrs pushes signed events to, so your back office doesn't poll. A firm holds at most five endpoints. The response is the endpoint with its signing secret. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Required, 1 to 128 characters. It doesn't deduplicate this write: a retry registers a second endpoint, so list your webhooks before you retry."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueWebhookCreateRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueWebhookResponse"}}}},"400":{"description":"`unknown_event_type`: an event type isn't in the catalog, and the response names it and lists the catalog. `invalid_request` with `field` `url` or `events`: the URL isn't `https` or is too long, or `events` isn't a list of strings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue has no firm to bill or notify, or the resource isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`webhook_limit`: the firm already has five endpoints.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/webhooks', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"url\": \"https://backoffice.example.com/trdrs\",\n    \"events\": [\n      \"balance.recorded\",\n      \"risk.locked\"\n    ]\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/webhooks' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"url\":\"https://backoffice.example.com/trdrs\",\"events\":[\"balance.recorded\",\"risk.locked\"]}'"}]}},"/api/partner/venues/{venueId}/webhooks/{webhookId}":{"delete":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Remove a webhook","description":"Removes an endpoint and its delivery log, so no further events are sent to it. It takes no body and no version, so removing an endpoint you no longer control is never refused on a formality. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"The webhook's `id`."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueWebhookDeleteResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No such webhook for this venue's firm, or the venue has no firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/webhooks/{webhookId}', {\n  method: 'DELETE',\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X DELETE 'https://app.trdrs.co/api/partner/venues/{venueId}/webhooks/{webhookId}' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/webhooks/{webhookId}/test":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Send a signed test ping to a webhook","description":"Sends a signed test ping to an endpoint now and reports what happened, so you can check your endpoint before real events arrive. Send an empty JSON body. An endpoint that refuses the ping still answers `200` here, with `ok: false` and what it said. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"The webhook's `id`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Required, 1 to 128 characters. Each call sends a new ping, whatever the key."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueWebhookTestRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueWebhookTestResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No such webhook for this venue's firm, or the venue has no firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/webhooks/{webhookId}/test', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/webhooks/{webhookId}/test' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/partner/venues/{venueId}/webhooks/{webhookId}/deliveries":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read a webhook's delivery log","description":"Lists an endpoint's deliveries, newest first: what was sent, what came back, and what is still waiting to be retried. Use it to find events your endpoint missed. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"The webhook's `id`."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200},"description":"How many deliveries to return, from 1 to 200. The default is 50."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueWebhookDeliveriesResponse"}}}},"400":{"description":"`invalid_request` with `field` `limit`: the limit isn't a whole number from 1 to 200.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No such webhook for this venue's firm, or the venue has no firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/webhooks/{webhookId}/deliveries', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/webhooks/{webhookId}/deliveries' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/operator/venues/{venueId}/usage":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read the venue's metered usage for a month","description":"Reads what the venue's firm is billed for in one month: the active accounts, the price per account and the amount, from the same figures the invoice uses. Money is in US cents, and a null price or amount means the month isn't priced yet, never a zero bill. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"month","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$"},"description":"The month, as `YYYY-MM` in UTC. Leave it out for the previous complete calendar month, the one being invoiced."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueUsageResponse"}}}},"400":{"description":"`invalid_month`: `month` isn't a valid `YYYY-MM`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The usage can't be read for this venue's firm, and it is never answered as a silent zero.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/usage', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/usage' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/operator/venues/{venueId}/usage/accounts":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read the accounts behind the venue's usage","description":"Lists the accounts that counted toward one month's usage, by account number, with the fills that made each count. The list always adds up to `activeAccounts` for the same month. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"month","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$"},"description":"The month, as `YYYY-MM` in UTC. Leave it out for the previous complete calendar month, the one being invoiced."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueUsageAccountsResponse"}}}},"400":{"description":"`invalid_month`: `month` isn't a valid `YYYY-MM`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The usage can't be read for this venue's firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/usage/accounts', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/usage/accounts' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/operator/venues/{venueId}/balance-ops/{referenceId}":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read the receipt of one balance operation","description":"Reads the recorded result of one balance operation by its reference, the `Idempotency-Key` you sent with it. Use it when you lost the answer to a balance write and need to know whether it was applied. A `state` of `legacy_unknown` means an older route recorded the operation without its outcome. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"referenceId","in":"path","required":true,"schema":{"type":"string","maxLength":128},"description":"The reference of the balance operation, at most 128 characters."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueBalanceReceiptResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No balance operation with that reference exists for this venue's firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/balance-ops/{referenceId}', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/balance-ops/{referenceId}' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/operator/venues/{venueId}/webhooks":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"List the venue's webhooks","description":"Lists every endpoint the venue's firm registered, newest first, with the event types a filter can name. Each row carries its signing secret, which lets your endpoint check a delivery came from trdrs and grants nothing here. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueWebhookListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue has no firm to bill or notify, or the resource isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/webhooks', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/webhooks' \\\n  -b \"session=$TRDRS_SESSION\""}]},"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Register a webhook","description":"Registers an endpoint that trdrs pushes signed events to, so your back office doesn't poll. A firm holds at most five endpoints. The response is the endpoint with its signing secret. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Required, 1 to 128 characters. It doesn't deduplicate this write: a retry registers a second endpoint, so list your webhooks before you retry."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueWebhookCreateRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueWebhookResponse"}}}},"400":{"description":"`unknown_event_type`: an event type isn't in the catalog, and the response names it and lists the catalog. `invalid_request` with `field` `url` or `events`: the URL isn't `https` or is too long, or `events` isn't a list of strings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue has no firm to bill or notify, or the resource isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`webhook_limit`: the firm already has five endpoints.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/webhooks', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"url\": \"https://backoffice.example.com/trdrs\",\n    \"events\": [\n      \"balance.recorded\",\n      \"risk.locked\"\n    ]\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/webhooks' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"url\":\"https://backoffice.example.com/trdrs\",\"events\":[\"balance.recorded\",\"risk.locked\"]}'"}]}},"/api/operator/venues/{venueId}/webhooks/{webhookId}":{"delete":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Remove a webhook","description":"Removes an endpoint and its delivery log, so no further events are sent to it. It takes no body and no version, so removing an endpoint you no longer control is never refused on a formality. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"The webhook's `id`."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueWebhookDeleteResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No such webhook for this venue's firm, or the venue has no firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/webhooks/{webhookId}', {\n  method: 'DELETE',\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X DELETE 'https://app.trdrs.co/api/operator/venues/{venueId}/webhooks/{webhookId}' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/operator/venues/{venueId}/webhooks/{webhookId}/test":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Send a signed test ping to a webhook","description":"Sends a signed test ping to an endpoint now and reports what happened, so you can check your endpoint before real events arrive. Send an empty JSON body. An endpoint that refuses the ping still answers `200` here, with `ok: false` and what it said. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"The webhook's `id`."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Required, 1 to 128 characters. Each call sends a new ping, whatever the key."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueWebhookTestRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueWebhookTestResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No such webhook for this venue's firm, or the venue has no firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/webhooks/{webhookId}/test', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/webhooks/{webhookId}/test' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/operator/venues/{venueId}/webhooks/{webhookId}/deliveries":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read a webhook's delivery log","description":"Lists an endpoint's deliveries, newest first: what was sent, what came back, and what is still waiting to be retried. Use it to find events your endpoint missed. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"The webhook's `id`."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200},"description":"How many deliveries to return, from 1 to 200. The default is 50."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueWebhookDeliveriesResponse"}}}},"400":{"description":"`invalid_request` with `field` `limit`: the limit isn't a whole number from 1 to 200.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No such webhook for this venue's firm, or the venue has no firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/webhooks/{webhookId}/deliveries', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/webhooks/{webhookId}/deliveries' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/partner/venues/{venueId}/brand":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read the venue brand","description":"Reads the brand traders see for your venue in Connect: its name, description, logo and listing state. Use its `updatedAt` as `expectedUpdatedAt` when you change the brand. Referral links, routing, providers and approval aren't part of it. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueBrandResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/brand', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/brand' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"put":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Update the venue brand","description":"Changes your venue's name, description or both, leaving any field you leave out as it is. The listing state and routing can't be changed here, and the response is the brand as stored. This route takes no `Idempotency-Key`: `expectedUpdatedAt` keeps two writes from overwriting each other. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueBrandUpdateRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueBrandResponse"}}}},"400":{"description":"`invalid_request` with `field` naming the name, description or `expectedUpdatedAt` refused, or a body that changes nothing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`name_taken`: another company already uses the name. `version_conflict`: the brand changed since your last read, so read it again and send its `updatedAt`. An exact retry of a change already applied succeeds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/brand', {\n  method: 'PUT',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n  },\n  body: JSON.stringify({\n    \"name\": \"Meridian Futures\",\n    \"description\": \"Evaluation accounts for futures traders.\",\n    \"expectedUpdatedAt\": \"2026-09-14T12:00:00.000Z\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X PUT 'https://app.trdrs.co/api/partner/venues/{venueId}/brand' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Meridian Futures\",\"description\":\"Evaluation accounts for futures traders.\",\"expectedUpdatedAt\":\"2026-09-14T12:00:00.000Z\"}'"}]}},"/api/partner/venues/{venueId}/brand/logo":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Upload the venue logo","description":"Uploads your venue's logo as one square PNG, sent as base64. trdrs strips its metadata, measures whether the art reaches its edges, and serves its own copy. The response is the brand with its new logo URL and the logo's measured size. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueLogoUploadRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueLogoUploadResponse"}}}},"400":{"description":"`invalid_request`: the body isn't exactly `data` and `expectedUpdatedAt`. An image that isn't an acceptable square PNG answers `422`, with `rule` naming the check it failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`version_conflict`: the brand changed since your last read, so read it again and send its `updatedAt`. An exact retry of a change already applied succeeds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The image is larger than 512 KiB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/brand/logo', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n  },\n  body: JSON.stringify({\n    \"data\": \"iVBORw0KGgo…\",\n    \"expectedUpdatedAt\": \"2026-09-14T12:00:00.000Z\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/brand/logo' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"data\":\"iVBORw0KGgo…\",\"expectedUpdatedAt\":\"2026-09-14T12:00:00.000Z\"}'"}]}},"/api/partner/venues/{venueId}/reference/instruments":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read the venue instrument reference catalog","description":"Returns the futures contract facts the Trading API serves, so you can fill in an instrument candidate without a personal Trading API key. It is reference data only: it doesn't activate an instrument, grant market data or let an account trade anything. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueInstrumentReferenceResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/reference/instruments', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/reference/instruments' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/operator/venues/{venueId}/brand":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read the venue brand","description":"Reads the brand traders see for your venue in Connect: its name, description, logo and listing state. Use its `updatedAt` as `expectedUpdatedAt` when you change the brand. Referral links, routing, providers and approval aren't part of it. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueBrandResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/brand', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/brand' \\\n  -b \"session=$TRDRS_SESSION\""}]},"put":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Update the venue brand","description":"Changes your venue's name, description or both, leaving any field you leave out as it is. The listing state and routing can't be changed here, and the response is the brand as stored. This route takes no `Idempotency-Key`: `expectedUpdatedAt` keeps two writes from overwriting each other. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueBrandUpdateRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueBrandResponse"}}}},"400":{"description":"`invalid_request` with `field` naming the name, description or `expectedUpdatedAt` refused, or a body that changes nothing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`name_taken`: another company already uses the name. `version_conflict`: the brand changed since your last read, so read it again and send its `updatedAt`. An exact retry of a change already applied succeeds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/brand', {\n  method: 'PUT',\n  headers: {\n    'content-type': 'application/json',\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"name\": \"Meridian Futures\",\n    \"description\": \"Evaluation accounts for futures traders.\",\n    \"expectedUpdatedAt\": \"2026-09-14T12:00:00.000Z\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X PUT 'https://app.trdrs.co/api/operator/venues/{venueId}/brand' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Meridian Futures\",\"description\":\"Evaluation accounts for futures traders.\",\"expectedUpdatedAt\":\"2026-09-14T12:00:00.000Z\"}'"}]}},"/api/operator/venues/{venueId}/brand/logo":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Upload the venue logo","description":"Uploads your venue's logo as one square PNG, sent as base64. trdrs strips its metadata, measures whether the art reaches its edges, and serves its own copy. The response is the brand with its new logo URL and the logo's measured size. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueLogoUploadRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueLogoUploadResponse"}}}},"400":{"description":"`invalid_request`: the body isn't exactly `data` and `expectedUpdatedAt`. An image that isn't an acceptable square PNG answers `422`, with `rule` naming the check it failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`version_conflict`: the brand changed since your last read, so read it again and send its `updatedAt`. An exact retry of a change already applied succeeds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The image is larger than 512 KiB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/brand/logo', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"data\": \"iVBORw0KGgo…\",\n    \"expectedUpdatedAt\": \"2026-09-14T12:00:00.000Z\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/brand/logo' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"data\":\"iVBORw0KGgo…\",\"expectedUpdatedAt\":\"2026-09-14T12:00:00.000Z\"}'"}]}},"/api/operator/venues/{venueId}/reference/instruments":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read the venue instrument reference catalog","description":"Returns the futures contract facts the Trading API serves, so you can fill in an instrument candidate without a personal Trading API key. It is reference data only: it doesn't activate an instrument, grant market data or let an account trade anything. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueInstrumentReferenceResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/reference/instruments', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/reference/instruments' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/partner/venues/{venueId}/hedges":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read venue hedge state","description":"Reads your hedging: the policies and their states, each target, the position confirmed at the provider, what is pending, the rounding residual and any open incident, each reported separately. A hedge is a trade on your own provider account and never changes a customer's fill or balance. Required scope: `hedge:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeReportResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/hedges', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/hedges' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/hedges/policies":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Publish a hedge policy","description":"Publishes a policy that copies a share of one group's customer exposure into a provider account the venue owns. The destination must be an account bound for hedging, which can never be granted to a trader. Publishing doesn't turn the policy on: activate it separately. Required scope: `hedge:manage`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgePolicyRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgePolicyResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The policy, intent, group or destination account doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_ready`: something the step needs isn't in place, such as a fresh destination stream. `version_conflict`: the revision you sent is stale. A step blocked by an unresolved intent or an open incident answers `423` `blocked`, with `blockers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/hedges/policies', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"groupId\": \"standard\",\n    \"name\": \"Standard 100% hedge\",\n    \"destinationAccountId\": \"00000000-0000-0000-0000-000000000001\",\n    \"ratio\": \"1\",\n    \"quantityCap\": null,\n    \"notionalCap\": null,\n    \"residualThreshold\": \"0.001\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/hedges/policies' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"groupId\":\"standard\",\"name\":\"Standard 100% hedge\",\"destinationAccountId\":\"00000000-0000-0000-0000-000000000001\",\"ratio\":\"1\",\"quantityCap\":null,\"notionalCap\":null,\"residualThreshold\":\"0.001\"}'"}]}},"/api/partner/venues/{venueId}/hedges/activation":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Activate, pause or stop a hedge policy","description":"Activates, pauses or stops a hedge policy. Activating also needs `hedge:execute` and a live destination stream that can trade. The response is the policy's new state and revision. Required scope: `hedge:manage`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeActivationRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeActivationResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The policy, intent, group or destination account doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_ready`: something the step needs isn't in place, such as a fresh destination stream. `version_conflict`: the revision you sent is stale. A step blocked by an unresolved intent or an open incident answers `423` `blocked`, with `blockers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/hedges/activation', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"policyId\": \"00000000-0000-0000-0000-000000000001\",\n    \"state\": \"active\",\n    \"expectedRevision\": null\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/hedges/activation' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"policyId\":\"00000000-0000-0000-0000-000000000001\",\"state\":\"active\",\"expectedRevision\":null}'"}]}},"/api/partner/venues/{venueId}/hedges/calculate":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Preview or persist the next hedge target","description":"Calculates the next hedge target for one group and instrument from your customers' positions, the active instrument mapping and the mark you send, less what is already pending or unresolved. With `dryRun: true` nothing is written; otherwise the target and the order it needs are stored. The response is the target and that order, and a retry against the same positions returns them again. Required scope: `hedge:execute`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeCalculateRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeCalculateResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The policy, intent, group or destination account doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_ready`: something the step needs isn't in place, such as a fresh destination stream. `version_conflict`: the revision you sent is stale. A step blocked by an unresolved intent or an open incident answers `423` `blocked`, with `blockers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/hedges/calculate', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"groupId\": \"standard\",\n    \"instrumentId\": \"BINANCE:BTCUSDT\",\n    \"markPrice\": \"65000\",\n    \"markObservedAt\": \"2026-09-14T12:00:00.000Z\",\n    \"dryRun\": true\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/hedges/calculate' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"groupId\":\"standard\",\"instrumentId\":\"BINANCE:BTCUSDT\",\"markPrice\":\"65000\",\"markObservedAt\":\"2026-09-14T12:00:00.000Z\",\"dryRun\":true}'"}]}},"/api/partner/venues/{venueId}/hedges/intents/{intentId}/dispatch":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Dispatch one prepared hedge intent","description":"Sends one prepared hedge order to the provider, under a client order id derived from the order itself. Send an empty JSON body. If the provider's reply is lost, the order becomes unknown and nothing that adds exposure runs until you reconcile it. Required scope: `hedge:execute`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"intentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeEmptyRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeIntentResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The policy, intent, group or destination account doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_ready`: something the step needs isn't in place, such as a fresh destination stream. `version_conflict`: the revision you sent is stale. A step blocked by an unresolved intent or an open incident answers `423` `blocked`, with `blockers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/hedges/intents/{intentId}/dispatch', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/hedges/intents/{intentId}/dispatch' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/partner/venues/{venueId}/hedges/intents/{intentId}/reconcile":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Reconcile an uncertain hedge intent","description":"Settles a hedge order whose outcome is unknown by reading the provider's own order and fill records. Send an empty JSON body. Any quantity the records don't settle stays pending. Required scope: `hedge:execute`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"intentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeEmptyRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeReconcileResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The policy, intent, group or destination account doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_ready`: something the step needs isn't in place, such as a fresh destination stream. `version_conflict`: the revision you sent is stale. A step blocked by an unresolved intent or an open incident answers `423` `blocked`, with `blockers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/hedges/intents/{intentId}/reconcile', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/hedges/intents/{intentId}/reconcile' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/partner/venues/{venueId}/hedges/emergency-stop":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Stop every hedge policy for this venue","description":"Stops every hedge policy of the venue at once, cancels the prepared orders that would add exposure, and opens incidents. It doesn't flatten anything: flatten a destination separately. The response counts what it stopped, cancelled and opened. Required scopes: `hedge:manage` and `hedge:execute`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeEmergencyStopRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeEmergencyStopResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The policy, intent, group or destination account doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_ready`: something the step needs isn't in place, such as a fresh destination stream. `version_conflict`: the revision you sent is stale. A step blocked by an unresolved intent or an open incident answers `423` `blocked`, with `blockers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/hedges/emergency-stop', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"reason\": \"provider stream is unavailable\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/hedges/emergency-stop' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"reason\":\"provider stream is unavailable\"}'"}]}},"/api/partner/venues/{venueId}/hedges/flatten":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Flatten a hedge destination","description":"Closes every position in one hedge destination account with reducing orders. It works while policies are stopped or the provider's state is stale, and never touches a customer account. The response confirms the flatten was requested. Required scope: `hedge:execute`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeFlattenRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeFlattenResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The policy, intent, group or destination account doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_ready`: something the step needs isn't in place, such as a fresh destination stream. `version_conflict`: the revision you sent is stale. A step blocked by an unresolved intent or an open incident answers `423` `blocked`, with `blockers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/hedges/flatten', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"destinationAccountId\": \"00000000-0000-0000-0000-000000000001\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/hedges/flatten' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"destinationAccountId\":\"00000000-0000-0000-0000-000000000001\"}'"}]}},"/api/operator/venues/{venueId}/hedges":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read venue hedge state","description":"Reads your hedging: the policies and their states, each target, the position confirmed at the provider, what is pending, the rounding residual and any open incident, each reported separately. A hedge is a trade on your own provider account and never changes a customer's fill or balance. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeReportResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/hedges', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/hedges' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/operator/venues/{venueId}/hedges/policies":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Publish a hedge policy","description":"Publishes a policy that copies a share of one group's customer exposure into a provider account the venue owns. The destination must be an account bound for hedging, which can never be granted to a trader. Publishing doesn't turn the policy on: activate it separately. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgePolicyRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgePolicyResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The policy, intent, group or destination account doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_ready`: something the step needs isn't in place, such as a fresh destination stream. `version_conflict`: the revision you sent is stale. A step blocked by an unresolved intent or an open incident answers `423` `blocked`, with `blockers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/hedges/policies', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"groupId\": \"standard\",\n    \"name\": \"Standard 100% hedge\",\n    \"destinationAccountId\": \"00000000-0000-0000-0000-000000000001\",\n    \"ratio\": \"1\",\n    \"quantityCap\": null,\n    \"notionalCap\": null,\n    \"residualThreshold\": \"0.001\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/hedges/policies' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"groupId\":\"standard\",\"name\":\"Standard 100% hedge\",\"destinationAccountId\":\"00000000-0000-0000-0000-000000000001\",\"ratio\":\"1\",\"quantityCap\":null,\"notionalCap\":null,\"residualThreshold\":\"0.001\"}'"}]}},"/api/operator/venues/{venueId}/hedges/activation":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Activate, pause or stop a hedge policy","description":"Activates, pauses or stops a hedge policy. Activating also needs `hedge:execute` and a live destination stream that can trade. The response is the policy's new state and revision. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeActivationRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeActivationResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The policy, intent, group or destination account doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_ready`: something the step needs isn't in place, such as a fresh destination stream. `version_conflict`: the revision you sent is stale. A step blocked by an unresolved intent or an open incident answers `423` `blocked`, with `blockers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/hedges/activation', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"policyId\": \"00000000-0000-0000-0000-000000000001\",\n    \"state\": \"active\",\n    \"expectedRevision\": null\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/hedges/activation' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"policyId\":\"00000000-0000-0000-0000-000000000001\",\"state\":\"active\",\"expectedRevision\":null}'"}]}},"/api/operator/venues/{venueId}/hedges/calculate":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Preview or persist the next hedge target","description":"Calculates the next hedge target for one group and instrument from your customers' positions, the active instrument mapping and the mark you send, less what is already pending or unresolved. With `dryRun: true` nothing is written; otherwise the target and the order it needs are stored. The response is the target and that order, and a retry against the same positions returns them again. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeCalculateRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeCalculateResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The policy, intent, group or destination account doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_ready`: something the step needs isn't in place, such as a fresh destination stream. `version_conflict`: the revision you sent is stale. A step blocked by an unresolved intent or an open incident answers `423` `blocked`, with `blockers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/hedges/calculate', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"groupId\": \"standard\",\n    \"instrumentId\": \"BINANCE:BTCUSDT\",\n    \"markPrice\": \"65000\",\n    \"markObservedAt\": \"2026-09-14T12:00:00.000Z\",\n    \"dryRun\": true\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/hedges/calculate' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"groupId\":\"standard\",\"instrumentId\":\"BINANCE:BTCUSDT\",\"markPrice\":\"65000\",\"markObservedAt\":\"2026-09-14T12:00:00.000Z\",\"dryRun\":true}'"}]}},"/api/operator/venues/{venueId}/hedges/intents/{intentId}/dispatch":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Dispatch one prepared hedge intent","description":"Sends one prepared hedge order to the provider, under a client order id derived from the order itself. Send an empty JSON body. If the provider's reply is lost, the order becomes unknown and nothing that adds exposure runs until you reconcile it. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"intentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeEmptyRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeIntentResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The policy, intent, group or destination account doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_ready`: something the step needs isn't in place, such as a fresh destination stream. `version_conflict`: the revision you sent is stale. A step blocked by an unresolved intent or an open incident answers `423` `blocked`, with `blockers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/hedges/intents/{intentId}/dispatch', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/hedges/intents/{intentId}/dispatch' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/operator/venues/{venueId}/hedges/intents/{intentId}/reconcile":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Reconcile an uncertain hedge intent","description":"Settles a hedge order whose outcome is unknown by reading the provider's own order and fill records. Send an empty JSON body. Any quantity the records don't settle stays pending. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"intentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeEmptyRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeReconcileResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The policy, intent, group or destination account doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_ready`: something the step needs isn't in place, such as a fresh destination stream. `version_conflict`: the revision you sent is stale. A step blocked by an unresolved intent or an open incident answers `423` `blocked`, with `blockers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/hedges/intents/{intentId}/reconcile', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/hedges/intents/{intentId}/reconcile' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/operator/venues/{venueId}/hedges/emergency-stop":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Stop every hedge policy for this venue","description":"Stops every hedge policy of the venue at once, cancels the prepared orders that would add exposure, and opens incidents. It doesn't flatten anything: flatten a destination separately. The response counts what it stopped, cancelled and opened. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeEmergencyStopRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeEmergencyStopResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The policy, intent, group or destination account doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_ready`: something the step needs isn't in place, such as a fresh destination stream. `version_conflict`: the revision you sent is stale. A step blocked by an unresolved intent or an open incident answers `423` `blocked`, with `blockers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/hedges/emergency-stop', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"reason\": \"provider stream is unavailable\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/hedges/emergency-stop' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"reason\":\"provider stream is unavailable\"}'"}]}},"/api/operator/venues/{venueId}/hedges/flatten":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Flatten a hedge destination","description":"Closes every position in one hedge destination account with reducing orders. It works while policies are stopped or the provider's state is stale, and never touches a customer account. The response confirms the flatten was requested. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeFlattenRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueHedgeFlattenResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The policy, intent, group or destination account doesn't exist or isn't this venue's.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_ready`: something the step needs isn't in place, such as a fresh destination stream. `version_conflict`: the revision you sent is stale. A step blocked by an unresolved intent or an open incident answers `423` `blocked`, with `blockers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/hedges/flatten', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"destinationAccountId\": \"00000000-0000-0000-0000-000000000001\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/hedges/flatten' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"destinationAccountId\":\"00000000-0000-0000-0000-000000000001\"}'"}]}},"/api/partner/venues/{venueId}/risk":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read risk across the venue's accounts","description":"Reads every customer account the venue issued on the paper book, up to 500, as one snapshot at a single instant, `asOf`: totals, exposure by instrument, positions, working orders, per-account state and equity history. Use it as your risk desk. Each position is valued at the price and contract size the account's own risk valuation uses, and is unmarked until that valuation covers it; the hedging section also needs `hedge:read`, and reads as unavailable without it. Required scope: `account:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"historyWindow","in":"query","required":false,"schema":{"type":"integer","minimum":60,"maximum":10080,"default":1440},"description":"How many minutes of history to return, from 60 to 10,080. The default is 1,440, one day."},{"name":"historyInterval","in":"query","required":false,"schema":{"type":"integer","enum":[1,5,15,60],"default":5},"description":"Minutes between history points: 1, 5, 15 or 60. The default is 5. The window divided by the interval can't exceed 1,000 points."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/risk', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/risk' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/operator/venues/{venueId}/risk":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read risk across the venue's accounts","description":"Reads every customer account the venue issued on the paper book, up to 500, as one snapshot at a single instant, `asOf`: totals, exposure by instrument, positions, working orders, per-account state and equity history. Use it as your risk desk. Each position is valued at the price and contract size the account's own risk valuation uses, and is unmarked until that valuation covers it; the hedging section also needs `hedge:read`, and reads as unavailable without it. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"historyWindow","in":"query","required":false,"schema":{"type":"integer","minimum":60,"maximum":10080,"default":1440},"description":"How many minutes of history to return, from 60 to 10,080. The default is 1,440, one day."},{"name":"historyInterval","in":"query","required":false,"schema":{"type":"integer","enum":[1,5,15,60],"default":5},"description":"Minutes between history points: 1, 5, 15 or 60. The default is 5. The window divided by the interval can't exceed 1,000 points."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/risk', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/risk' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/partner/venues/{venueId}/connections/{connectionId}/accounts":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"List discovered provider accounts","description":"Lists the accounts the last validation of a connection found at the provider, 500 to a page, so you can pick one to bind. The list lasts only as long as the provider's grant, at most 60 seconds, and reading it never connects, invites or trades. Required scope: `account:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"connectionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string"},"description":"The `nextCursor` from the previous page, sent unchanged. A cursor belongs to one discovery."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueDiscoveryResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The connection doesn't exist, isn't this venue's, or is revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`version_conflict`: the discovery expired, a newer one replaced it, or the credential changed. Validate the connection again and use its new discovery.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/connections/{connectionId}/accounts', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/connections/{connectionId}/accounts' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/accounts/bind":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Bind a discovered external account","description":"Binds an account a validation discovered at a provider to the venue as a customer account held at that provider, which you can then invite a trader to. It needs a passed validation and its current discovery, and the account keeps the position model the provider reports, `net` or `hedged`, which the provider's manifest must declare. The response is the bound account. Send `mode: hedge` instead to bind a hedge destination, which also needs the `hedge:manage` and `hedge:execute` scopes, an account the provider lets you trade, and the `net` position model. Required scopes: `connection:manage` and `account:issue`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters. The same key and body return the existing binding; the same key with a different body is refused with `409`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueBindRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueBindResponse"}}}},"400":{"description":"`invalid_request`: a field is missing or malformed, or the provider's manifest doesn't declare the account's position model.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"`permission_denied`: the key lacks a scope this binding needs, the provider can't hold accounts or trade, or a hedge destination can't be traded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The discovery expired or was replaced, the account is already bound, the `Idempotency-Key` was used with a different body, or a hedge destination doesn't use the `net` position model (`position_mode_unsupported`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/bind', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"mode\": \"connect\",\n    \"connectionId\": \"00000000-0000-0000-0000-000000000001\",\n    \"externalAccountId\": \"EXTERNAL-1\",\n    \"discoverySnapshotId\": \"00000000-0000-0000-0000-000000000001\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/bind' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"mode\":\"connect\",\"connectionId\":\"00000000-0000-0000-0000-000000000001\",\"externalAccountId\":\"EXTERNAL-1\",\"discoverySnapshotId\":\"00000000-0000-0000-0000-000000000001\"}'"}]}},"/api/operator/venues/{venueId}/connections/{connectionId}/accounts":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"List discovered provider accounts","description":"Lists the accounts the last validation of a connection found at the provider, 500 to a page, so you can pick one to bind. The list lasts only as long as the provider's grant, at most 60 seconds, and reading it never connects, invites or trades. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"connectionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string"},"description":"The `nextCursor` from the previous page, sent unchanged. A cursor belongs to one discovery."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueDiscoveryResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The connection doesn't exist, isn't this venue's, or is revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`version_conflict`: the discovery expired, a newer one replaced it, or the credential changed. Validate the connection again and use its new discovery.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/connections/{connectionId}/accounts', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/connections/{connectionId}/accounts' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/operator/venues/{venueId}/accounts/bind":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Bind a discovered external account","description":"Binds an account a validation discovered at a provider to the venue as a customer account held at that provider, which you can then invite a trader to. It needs a passed validation and its current discovery, and the account keeps the position model the provider reports, `net` or `hedged`, which the provider's manifest must declare. The response is the bound account. The back office binds customer accounts only, so send `mode: connect`. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters. The same key and body return the existing binding; the same key with a different body is refused with `409`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueBindRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueBindResponse"}}}},"400":{"description":"`invalid_request`: a field is missing or malformed, `mode` isn't `connect`, or the provider's manifest doesn't declare the account's position model.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"`permission_denied`: your role can't bind, or the provider can't hold accounts or trade.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The discovery expired or was replaced, the account is already bound, or the `Idempotency-Key` was used with a different body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/accounts/bind', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"mode\": \"connect\",\n    \"connectionId\": \"00000000-0000-0000-0000-000000000001\",\n    \"externalAccountId\": \"EXTERNAL-1\",\n    \"discoverySnapshotId\": \"00000000-0000-0000-0000-000000000001\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/accounts/bind' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"mode\":\"connect\",\"connectionId\":\"00000000-0000-0000-0000-000000000001\",\"externalAccountId\":\"EXTERNAL-1\",\"discoverySnapshotId\":\"00000000-0000-0000-0000-000000000001\"}'"}]}},"/api/partner/venues/{venueId}":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read a venue","description":"Reads your venue: its name, environment, state, venue rules setting and the company that carries its brand. Call it first to confirm your Venue key works. It returns no credentials and changes nothing. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueReadResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/instruments":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"List instrument candidates","description":"Lists the instrument candidates you saved, 100 to a page. A candidate is a stored instrument definition that nothing trades until you activate it, so each reads `tradingReady: false`. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string","format":"uuid"},"description":"The `nextCursor` from the previous page, sent unchanged. A page holds at most 100 items."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueInstrumentListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/instruments', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/instruments' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Save an instrument candidate","description":"Saves the definition of an instrument your accounts could trade: its product, quantity and price rules, sessions, pricing source and the provider symbols it maps to. Every rule is checked, and saving changes no account and no active catalog: activate the candidate to make it tradable. The response is the stored candidate. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueInstrumentSaveRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueInstrumentSaveResponse"}}}},"400":{"description":"A rule of the specification is broken, and `field` names the value refused, such as `instrument.pricing.sourceId` with `entitled_source_unserved`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`idempotency_conflict`: the `Idempotency-Key` already saved a different candidate. The same key and body return the original.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is over 512 KiB, or the specification is over 256 KiB once normalized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/instruments', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"specification\": {\n      \"instrumentId\": \"BTCUSD\",\n      \"version\": \"v1\",\n      \"venueId\": \"00000000-0000-0000-0000-000000000001\",\n      \"symbol\": \"BTCUSD\",\n      \"name\": \"Bitcoin / USD\",\n      \"productModel\": \"linear_spot\",\n      \"quoteCurrency\": \"USD\",\n      \"settlementCurrency\": \"USD\",\n      \"negativePrices\": false,\n      \"quantity\": {\n        \"unit\": \"base_units\",\n        \"lotSize\": \"1\",\n        \"min\": \"0.001\",\n        \"max\": \"100\",\n        \"step\": \"0.001\"\n      },\n      \"contractMultiplier\": \"1\",\n      \"minNotional\": \"10\",\n      \"ticks\": [\n        {\n          \"from\": \"0\",\n          \"to\": null,\n          \"size\": \"0.01\"\n        }\n      ],\n      \"orderTypes\": [\n        \"market\",\n        \"limit\"\n      ],\n      \"timeInForce\": [\n        \"gtc\"\n      ],\n      \"mappings\": [],\n      \"sessions\": {\n        \"timezone\": \"UTC\",\n        \"coverageFrom\": \"2026-01-01\",\n        \"coverageThrough\": \"2026-12-31\",\n        \"weekly\": [\n          {\n            \"day\": 0,\n            \"windows\": [\n              {\n                \"startMinute\": 0,\n                \"endMinute\": 0,\n                \"endDayOffset\": 1\n              }\n            ]\n          },\n          {\n            \"day\": 1,\n            \"windows\": [\n              {\n                \"startMinute\": 0,\n                \"endMinute\": 0,\n                \"endDayOffset\": 1\n              }\n            ]\n          },\n          {\n            \"day\": 2,\n            \"windows\": [\n              {\n                \"startMinute\": 0,\n                \"endMinute\": 0,\n                \"endDayOffset\": 1\n              }\n            ]\n          },\n          {\n            \"day\": 3,\n            \"windows\": [\n              {\n                \"startMinute\": 0,\n                \"endMinute\": 0,\n                \"endDayOffset\": 1\n              }\n            ]\n          },\n          {\n            \"day\": 4,\n            \"windows\": [\n              {\n                \"startMinute\": 0,\n                \"endMinute\": 0,\n                \"endDayOffset\": 1\n              }\n            ]\n          },\n          {\n            \"day\": 5,\n            \"windows\": [\n              {\n                \"startMinute\": 0,\n                \"endMinute\": 0,\n                \"endDayOffset\": 1\n              }\n            ]\n          },\n          {\n            \"day\": 6,\n            \"windows\": [\n              {\n                \"startMinute\": 0,\n                \"endMinute\": 0,\n                \"endDayOffset\": 1\n              }\n            ]\n          }\n        ],\n        \"holidays\": []\n      },\n      \"expiresAt\": null,\n      \"lastTradeAt\": null,\n      \"pricing\": {\n        \"sourceId\": \"example-feed\",\n        \"stopTrigger\": \"last\",\n        \"maxAgeMs\": 1000\n      },\n      \"entitlement\": null,\n      \"state\": \"enabled\"\n    }\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/instruments' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"specification\":{\"instrumentId\":\"BTCUSD\",\"version\":\"v1\",\"venueId\":\"00000000-0000-0000-0000-000000000001\",\"symbol\":\"BTCUSD\",\"name\":\"Bitcoin / USD\",\"productModel\":\"linear_spot\",\"quoteCurrency\":\"USD\",\"settlementCurrency\":\"USD\",\"negativePrices\":false,\"quantity\":{\"unit\":\"base_units\",\"lotSize\":\"1\",\"min\":\"0.001\",\"max\":\"100\",\"step\":\"0.001\"},\"contractMultiplier\":\"1\",\"minNotional\":\"10\",\"ticks\":[{\"from\":\"0\",\"to\":null,\"size\":\"0.01\"}],\"orderTypes\":[\"market\",\"limit\"],\"timeInForce\":[\"gtc\"],\"mappings\":[],\"sessions\":{\"timezone\":\"UTC\",\"coverageFrom\":\"2026-01-01\",\"coverageThrough\":\"2026-12-31\",\"weekly\":[{\"day\":0,\"windows\":[{\"startMinute\":0,\"endMinute\":0,\"endDayOffset\":1}]},{\"day\":1,\"windows\":[{\"startMinute\":0,\"endMinute\":0,\"endDayOffset\":1}]},{\"day\":2,\"windows\":[{\"startMinute\":0,\"endMinute\":0,\"endDayOffset\":1}]},{\"day\":3,\"windows\":[{\"startMinute\":0,\"endMinute\":0,\"endDayOffset\":1}]},{\"day\":4,\"windows\":[{\"startMinute\":0,\"endMinute\":0,\"endDayOffset\":1}]},{\"day\":5,\"windows\":[{\"startMinute\":0,\"endMinute\":0,\"endDayOffset\":1}]},{\"day\":6,\"windows\":[{\"startMinute\":0,\"endMinute\":0,\"endDayOffset\":1}]}],\"holidays\":[]},\"expiresAt\":null,\"lastTradeAt\":null,\"pricing\":{\"sourceId\":\"example-feed\",\"stopTrigger\":\"last\",\"maxAgeMs\":1000},\"entitlement\":null,\"state\":\"enabled\"}}'"}]}},"/api/partner/venues/{venueId}/routes":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"List routes","description":"Lists your routes: where a group's orders go, and the collar and fee reserve that protect an order sent there. Each group uses exactly one route, and there is no routing by price. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string"},"description":"The `nextCursor` from the previous page, which is the last route id it held."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRouteListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/routes', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/routes' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Create or update a route","description":"Creates a route, or changes one, to say where a group's orders go and what protects them. A rename or a retirement applies at once, and a retired route keeps serving the groups already on it while no new group can take it. A change of mode, connection or account, or a wider collar, waits until every account on the route is flat, because it changes the worst case of a trade already open. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRouteSaveRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRouteSaveResponse"}}}},"400":{"description":"The route is incomplete or contradictory, such as an external route without both `connectionId` and `externalAccountId`, or an uncapped market on an internal route.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`version_conflict`: `expectedRevision` is stale. `not_quiescent`: the change waits for the accounts on the route to be flat, and `blockers` names them.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/routes', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"routeId\": \"lp-primary\",\n    \"name\": \"Primary LP\",\n    \"mode\": \"external\",\n    \"connectionId\": \"00000000-0000-0000-0000-000000000001\",\n    \"externalAccountId\": \"EXT-LP\",\n    \"collar\": {\n      \"kind\": \"ticks\",\n      \"maxAdverseTicks\": 4\n    },\n    \"feeReservePerUnit\": \"2.50\",\n    \"uncappedMarketAllowed\": false,\n    \"expectedRevision\": null\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/routes' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"routeId\":\"lp-primary\",\"name\":\"Primary LP\",\"mode\":\"external\",\"connectionId\":\"00000000-0000-0000-0000-000000000001\",\"externalAccountId\":\"EXT-LP\",\"collar\":{\"kind\":\"ticks\",\"maxAdverseTicks\":4},\"feeReservePerUnit\":\"2.50\",\"uncappedMarketAllowed\":false,\"expectedRevision\":null}'"}]}},"/api/partner/venues/{venueId}/groups/{groupId}/route":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Point a group at a route","description":"Sets the route a group's orders go through, or removes it. With no route, the group's accounts can't open new exposure, since there is no default route. A group whose accounts hold exposure can't move to a different route mid-trade, and a retired route takes no new groups. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"groupId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueGroupRouteRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueGroupRouteResponse"}}}},"400":{"description":"`invalid_request`: the route is retired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The group or the route doesn't exist at this venue.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_quiescent`: the group's accounts hold exposure, and `blockers` names them.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/groups/{groupId}/route', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"routeId\": \"lp-primary\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/groups/{groupId}/route' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"routeId\":\"lp-primary\"}'"}]}},"/api/partner/venues/{venueId}/accounts/{accountId}/instruments":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read what one account may trade","description":"Lists your active instruments as one account sees them, with what would stop it opening a position in each: its conditions, its route and any open liquidation in `blockedBy`, and what its risk policy refuses in `poolRefusal`. Use it to build a trader's instrument picker. Every reason stops only new exposure, so the account can always close what it holds, and the answer reads configuration and policy only, never a price, a balance or a stream, so an empty `blockedBy` doesn't promise an order will be accepted. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"after","in":"query","required":false,"schema":{"type":"string"},"description":"The `nextCursor` from the previous page, which is the last instrument id it held."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountInstrumentsResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The account doesn't belong to this venue. It is refused, never answered with an empty list that would read as nothing to trade.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/instruments', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/instruments' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/accounts/{accountId}/ledger":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read a customer account's books","description":"Reads an account's books: its balance, the collateral held against its working orders, its open positions at their exact average cost, and the route its orders go through. Use it to see what an account holds and where. Only accounts whose balance trdrs keeps have these books. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueCustomerLedgerResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The account isn't this venue's, or trdrs keeps no books for it: an account held at a provider keeps its own, and an account the firm issued before it had a venue that hasn't moved to the venue's books is read through its analytics instead.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/ledger', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/ledger' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/accounts/{accountId}/incident":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read an account's open liquidation","description":"Reads the liquidation open on an account, with every reduction step recorded against it, or null when none is open. While one is open the account can't open new exposure, and closing it doesn't lift that halt: whether the account trades again is an operator's decision. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueLiquidationIncidentResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/incident', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/incident' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/conditions/profiles":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"List condition profiles","description":"Lists the condition profiles you published, 100 to a page: the commission, markup and safety limits each one sets for the whole venue. A published profile never changes, and `inForce` marks the one the venue applies now. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string","format":"uuid"},"description":"The `nextCursor` from the previous page, sent unchanged. A page holds at most 100 items."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConditionProfileListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/conditions/profiles', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/conditions/profiles' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Publish a condition profile","description":"Publishes a complete condition profile for the venue: its commission, its markup and its safety limits. The profile must state every policy explicitly, because the venue layer is the base every group and account narrows. Publishing applies nothing, so apply the profile separately, and the response is the stored profile. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConditionProfileSaveRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConditionProfileSaveResponse"}}}},"400":{"description":"The profile is incomplete or breaks a rule, with `field` naming the value refused. A margin policy is refused as `margin_policy_superseded` and a financing term as `financing_superseded`, since your risk policy states both.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`idempotency_conflict`: the `Idempotency-Key` already published a different profile. The same key and body return the original.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/conditions/profiles', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Standard\",\n    \"profile\": {\n      \"margin\": null,\n      \"commission\": {\n        \"kind\": \"perUnit\",\n        \"timing\": \"fill\",\n        \"direction\": \"both\",\n        \"unit\": \"quantity\",\n        \"amount\": \"2.50\",\n        \"currency\": \"USD\",\n        \"orderMinimum\": null\n      },\n      \"markup\": {\n        \"buyMarkupTicks\": 0,\n        \"sellMarkupTicks\": 0\n      },\n      \"risk\": {\n        \"maxOrderQuantity\": \"10\",\n        \"maxPositionQuantity\": null,\n        \"maxPositionNotional\": null,\n        \"instrumentAllowlist\": null,\n        \"dailyLossLimit\": null,\n        \"weeklyLossLimit\": null,\n        \"entryHalted\": false\n      }\n    }\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/conditions/profiles' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Standard\",\"profile\":{\"margin\":null,\"commission\":{\"kind\":\"perUnit\",\"timing\":\"fill\",\"direction\":\"both\",\"unit\":\"quantity\",\"amount\":\"2.50\",\"currency\":\"USD\",\"orderMinimum\":null},\"markup\":{\"buyMarkupTicks\":0,\"sellMarkupTicks\":0},\"risk\":{\"maxOrderQuantity\":\"10\",\"maxPositionQuantity\":null,\"maxPositionNotional\":null,\"instrumentAllowlist\":null,\"dailyLossLimit\":null,\"weeklyLossLimit\":null,\"entryHalted\":false}}}'"}]}},"/api/partner/venues/{venueId}/conditions/active":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Apply a condition profile","description":"Puts a published condition profile in force for the whole venue. A change that only tightens safety limits, or only renames, applies at once. A change to commission or markup needs every account the venue holds to be flat first, and the response is the new activation and its revision. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConditionActivationRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConditionActivationResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`version_conflict`: `expectedRevision` is stale. `not_quiescent`: an account isn't flat, and `blockers` names each one with its reason.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/conditions/active', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"profileId\": \"00000000-0000-0000-0000-000000000001\",\n    \"expectedRevision\": null\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/conditions/active' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"profileId\":\"00000000-0000-0000-0000-000000000001\",\"expectedRevision\":null}'"}]}},"/api/partner/venues/{venueId}/conditions/preview":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Preview a conditions change","description":"Checks a proposed profile or group override before you apply it: whether it changes what accounts are charged, how many accounts it reaches, and which of them aren't flat yet. It writes nothing and locks nothing. Send either a `profileId`, or a `groupId` with its `override`. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConditionPreviewRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConditionPreviewResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/conditions/preview', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"profileId\": \"00000000-0000-0000-0000-000000000001\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/conditions/preview' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"profileId\":\"00000000-0000-0000-0000-000000000001\"}'"}]}},"/api/partner/venues/{venueId}/conditions/groups":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"List account groups","description":"Lists your groups: sets of accounts with one route and one set of rules, such as a prop firm's evaluation or a broker's clients. Each row carries the group's override, route, stage and revision. A group doesn't nest, copy trades or pool balances. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string"},"description":"The `nextCursor` from the previous page, which is the last group id it held."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountGroupListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/conditions/groups', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/conditions/groups' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Create or update an account group","description":"Creates a group, or changes one: its name, its override of the venue's conditions, and the stage its accounts run. A rename or a change that only tightens safety applies at once. A change to what the group charges, or a move to another stage, waits until the group's own accounts are flat, and creating your first group turns venue rules on. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountGroupSaveRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountGroupSaveResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`version_conflict`: `expectedRevision` is stale. `not_quiescent`: a member account isn't flat, and `blockers` names each one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/conditions/groups', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"groupId\": \"professional\",\n    \"name\": \"Professional\",\n    \"override\": {\n      \"risk\": {\n        \"maxOrderQuantity\": \"5\"\n      }\n    },\n    \"expectedRevision\": null\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/conditions/groups' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"groupId\":\"professional\",\"name\":\"Professional\",\"override\":{\"risk\":{\"maxOrderQuantity\":\"5\"}},\"expectedRevision\":null}'"}]}},"/api/partner/venues/{venueId}/accounts/{accountId}/stages/{stageId}/eligibility":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read an account's stage eligibility","description":"Checks whether an account has passed a stage, measured from its own trading against the rules its current cycle opened under, never rules that came into force later and never figures you send. Call it before you advance an account. The response states the facts measured (net trading P&L after every fee, financing and funding charge, trading days in the stage's session, flatness, working orders, recorded breaches and unsettled orders) and every failing reason at once. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"stageId","in":"path","required":true,"schema":{"type":"string"},"description":"The stage to check against, 1 to 80 letters, digits, hyphens or underscores."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueStageEligibilityResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The account isn't this venue's, the venue hasn't put the stage in force, or the account has no opening allocation and so no cycle to measure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_eligible` with `stage_version_unrecorded`: nothing records the rules the cycle opened under, so it isn't judged by the rules in force now. That holds for an account held at a provider, and for an account that joined the stage part-way through a traded cycle after the rules in force came into force, until it resets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/stages/{stageId}/eligibility', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/stages/{stageId}/eligibility' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/accounts/{accountId}/stages/{stageId}/advance":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Advance an account past a stage","description":"Advances an account that passed a stage: eligibility is decided again, then one successor account is issued on the paper book in the group the stage names as next, held to the same risk policy as the account it replaces. Each cycle and stage gets one successor only, so a second attempt, even with another key, returns the account the first one made. It needs an account whose balance trdrs keeps, that is flat and quiet, and whose rules and revision haven't moved since the decision. Required scope: `stage:advance`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"stageId","in":"path","required":true,"schema":{"type":"string"},"description":"The stage the account passed, 1 to 80 letters, digits, hyphens or underscores."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueStageAdvanceRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueStageAdvanceResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`not_eligible` lists every failing reason in `reasons`, including `successor_policy_unresolved` when the account is held to no risk policy, so there is none to hold its successor to. `version_conflict`: the account moved since its facts were measured. `stage_decision_pending`: the risk decisions are still catching up, which clears by itself, so retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/stages/{stageId}/advance', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"startingAllocation\": {\n      \"numerator\": \"10000000\",\n      \"denominator\": \"100\"\n    }\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/stages/{stageId}/advance' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"startingAllocation\":{\"numerator\":\"10000000\",\"denominator\":\"100\"}}'"}]}},"/api/partner/venues/{venueId}/stages/policies":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"List stage policies","description":"Lists the stage rules you published, 100 to a page: each version's profit target, trading days, session, drawdown and disqualifying rules, and the group a passing account moves to. A published version never changes, and `inForce` marks the version in force for each stage. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string","format":"uuid"},"description":"The `nextCursor` from the previous page, sent unchanged. A page holds at most 100 items."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueStagePolicyListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/stages/policies', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/stages/policies' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Publish a stage policy","description":"Publishes a version of a stage's rules: what an account must achieve to pass it, what fails it, and the group a passing account moves to. Publishing applies nothing, so put the version in force separately. The response is the stored version. Required scope: `stage:advance`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueStagePolicySaveRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueStagePolicySaveResponse"}}}},"400":{"description":"A rule is malformed, with `field` naming it. A session time zone the engine can't resolve is refused here, before it could file a fill under the wrong day.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`idempotency_conflict`: the `Idempotency-Key` already published different rules, so the same key with an easier target is refused. The same key and body return the original.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/stages/policies', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"name\": \"Evaluation stage one\",\n    \"policy\": {\n      \"stageId\": \"evaluation-1\",\n      \"profitTarget\": \"2000\",\n      \"minimumTradingDays\": 5,\n      \"session\": {\n        \"timeZone\": \"America/Chicago\",\n        \"rolloverHour\": 17\n      },\n      \"disqualifying\": [\n        \"daily_loss\",\n        \"trailing_drawdown\"\n      ],\n      \"nextGroupId\": \"funded\"\n    }\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/stages/policies' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Evaluation stage one\",\"policy\":{\"stageId\":\"evaluation-1\",\"profitTarget\":\"2000\",\"minimumTradingDays\":5,\"session\":{\"timeZone\":\"America/Chicago\",\"rolloverHour\":17},\"disqualifying\":[\"daily_loss\",\"trailing_drawdown\"],\"nextGroupId\":\"funded\"}}'"}]}},"/api/partner/venues/{venueId}/stages/active":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Put a stage policy in force","description":"Puts a published version of a stage's rules in force, at once and whatever the stage's accounts hold. Each cycle is judged by the version in force when it opened, so new rules reach an account at its next cycle, while a change to the group a passing account moves to applies to the next advance. The response is the activation and its revision. Required scope: `stage:advance`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueStageActivationRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueStageActivationResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`version_conflict`: `expectedRevision` is stale.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/stages/active', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"policyId\": \"00000000-0000-0000-0000-000000000001\",\n    \"expectedRevision\": null\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/stages/active' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"policyId\":\"00000000-0000-0000-0000-000000000001\",\"expectedRevision\":null}'"}]}},"/api/partner/venues/{venueId}/conditions/accounts/{accountId}/group":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Move an account between groups","description":"Moves an account into another group, or out of every group. When the new group charges differently, the move waits until this account alone is flat. The response is the account's group and revision. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountAssignmentRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountAssignmentResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/conditions/accounts/{accountId}/group', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"groupId\": \"professional\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/conditions/accounts/{accountId}/group' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"groupId\":\"professional\"}'"}]}},"/api/partner/venues/{venueId}/conditions/accounts/{accountId}/risk":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Set per-account safety limits","description":"Sets one account's own safety limits, which can only tighten what the venue and its group allow. It applies at once, since a lower limit can't disadvantage a trade already open, and what the account is charged can't be set here. The response is the account's new revision. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountRiskRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueAccountRiskResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/conditions/accounts/{accountId}/risk', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"risk\": {\n      \"maxOrderQuantity\": \"2\"\n    }\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/conditions/accounts/{accountId}/risk' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"risk\":{\"maxOrderQuantity\":\"2\"}}'"}]}},"/api/partner/venues/{venueId}/conditions/accounts/{accountId}/effective":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read one account's effective conditions","description":"Reads the conditions one account actually trades under, each value with the layer that decided it: the venue, the group, the account or the trader. It also carries a digest of the values alone, so two accounts that are charged and limited alike compare equal however their settings were reached. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueEffectiveConditionsResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The account isn't this venue's, or the venue has no profile in force, which is never answered with defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/conditions/accounts/{accountId}/effective', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/conditions/accounts/{accountId}/effective' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/instruments/active":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"List active instruments","description":"Lists the instruments your accounts can trade now, one row per instrument with its active version, ordered by instrument id and 100 to a page. An instrument missing from the list has no active version, and no order on it is sent anywhere. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string"},"description":"The `nextCursor` from the previous page, which is the last instrument id it held."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueActivationListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/instruments/active', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/instruments/active' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Activate an instrument version","description":"Makes one saved candidate the active version of an instrument, which is the only way a version becomes tradable. A rename or a change of its enabled state applies at once; any other change waits until every account the venue holds is flat in that instrument, with no unsettled order and no working order. Activating grants no account access and moves no balance, and the response is the active version. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueActivationRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueActivationResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`version_conflict`: `expectedRevision` is stale. `mapping_required`: the version has no mapping on a live connection. `not_quiescent`: an account isn't flat in the instrument, and `blockers` names each one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/instruments/active', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"instrumentId\": \"BTC-USD-SPOT\",\n    \"instrumentVersionId\": \"00000000-0000-0000-0000-000000000001\",\n    \"expectedRevision\": null\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/instruments/active' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"instrumentId\":\"BTC-USD-SPOT\",\"instrumentVersionId\":\"00000000-0000-0000-0000-000000000001\",\"expectedRevision\":null}'"}]}},"/api/partner/venues/{venueId}/instruments/{candidateId}":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read an instrument candidate","description":"Reads one saved instrument candidate by the id it was saved under, not by its symbol or its specification version. Use it to check a candidate before you activate it. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"candidateId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The candidate's `id`, as returned when it was saved."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueInstrumentReadResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"`not_found`: no candidate with that id belongs to this venue.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/instruments/{candidateId}', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/instruments/{candidateId}' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/accounts/{accountId}/grants":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Invite an account recipient","description":"Invites a person to an account the venue holds, by email, with an expiring token you send them privately. The email alone grants nothing: the person signs in with that email and presents the token. The response is the token and its expiry, and a retry with the same key returns the same token without extending it. Required scope: `grant:manage`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueInvitationRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueInvitationResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is over 4 KiB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/grants', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"email\": \"trader@example.com\",\n    \"canTrade\": true,\n    \"expiresInSeconds\": 3600\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/grants' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"email\":\"trader@example.com\",\"canTrade\":true,\"expiresInSeconds\":3600}'"}]}},"/api/partner/venues/{venueId}/accounts/{accountId}/grants/{claimId}":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read account invitation status","description":"Reads whether an invitation was accepted or revoked, and its current version, which you need to revoke it. The token is never returned, and an accepted invitation doesn't mean the account is ready to trade. Required scope: `account:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"claimId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueGrantReadResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/grants/{claimId}', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/grants/{claimId}' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"delete":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Revoke an account grant","description":"Revokes one person's access to an account, named by the invitation's claim id and its current version in `If-Match`, with a body of `{}`. It cancels no order, disconnects nothing, moves no balance and leaves other grants in place. Retrying with the same claim and version returns the original revocation. Required scope: `grant:manage`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string"}},{"name":"claimId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"Required, 1 to 128 characters. The claim id and version, not this key, identify the revocation."},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"[1-9][0-9]{0,8}\"$"},"description":"The grant's current version, in double quotes, for example `\"2\"`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueGrantRevokeRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueGrantRevokeResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/grants/{claimId}', {\n  method: 'DELETE',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n    \"If-Match\": \"\\\"2\\\"\",\n  },\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X DELETE 'https://app.trdrs.co/api/partner/venues/{venueId}/accounts/{accountId}/grants/{claimId}' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'If-Match: \"2\"' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/operator/organizations":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"List your operator organizations","description":"Lists the organizations you belong to, with your role in each. An organization owns venues, so this is the first call the back office makes, before a venue is chosen. Call it from a signed-in session with a verified email. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueOrganizationsResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/organizations', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/organizations' \\\n  -b \"session=$TRDRS_SESSION\""}]},"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Create an operator organization","description":"Creates an organization, the owner of your venues, and makes you its owner. Call it from a signed-in session with a verified email, on a trusted origin. The response is the organization, and the same `Idempotency-Key` sent again returns it rather than creating another. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueOrganizationCreateRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueOrganizationResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`idempotency_conflict`: the `Idempotency-Key` already created an organization with a different name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/organizations', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"name\": \"Meridian Futures\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/organizations' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Meridian Futures\"}'"}]}},"/api/operator/organizations/{organizationId}/venues":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"List an organization's venues","description":"Lists an organization's venues, each with its environment and the firm it adopted, if any, so the back office can offer a venue to pick. Any member of the organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/organizations/{organizationId}/venues', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/organizations/{organizationId}/venues' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/operator/organizations/{organizationId}/members":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"List organization members","description":"Lists an organization's members, active and removed, and its pending invitations. A pending invitation has `authUserId: null`, `active: false` and `pending: true`, and grants no access, while each row's `version` is what a change to it sends as `expectedVersion`. Any member can call it from a signed-in session, and there's no search across other people. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueMembersResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/organizations/{organizationId}/members', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/organizations/{organizationId}/members' \\\n  -b \"session=$TRDRS_SESSION\""}]},"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Add a member or change a role","description":"Adds a person to an organization, or changes their role. Someone without a verified trdrs sign-in for that email gets an invitation by email and no access, and their role starts the first time they read their organizations after verifying that exact email. An owner calls it from a signed-in session on a trusted origin, and no password or Venue key is ever shared. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueMemberSetRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueMemberResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`last_owner`: the change would leave no active owner. `version_conflict`: `expectedVersion` is stale. `idempotency_conflict`: the key was used with a different body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"`team_invitation_email_failed`: the invitation was stored but its email couldn't be sent, and the response carries the pending `member`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/organizations/{organizationId}/members', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"email\": \"desk@example.com\",\n    \"role\": \"operator\",\n    \"expectedVersion\": 0\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/organizations/{organizationId}/members' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"email\":\"desk@example.com\",\"role\":\"operator\",\"expectedVersion\":0}'"}]},"delete":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Remove a member","description":"Removes a member from an organization, or cancels a pending invitation. The person loses access to the organization's venues at once, while their membership stays listed as inactive with its version advanced. An owner calls it from a signed-in session on a trusted origin, and the same `Idempotency-Key` sent again returns the first result. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueMemberRemoveRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueMemberRemoveResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"`not_found`: nobody with that id or email was ever listed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`last_owner`: this is the last active owner. `version_conflict`: `expectedVersion` is stale.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/organizations/{organizationId}/members', {\n  method: 'DELETE',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"authUserId\": \"user_2\",\n    \"expectedVersion\": 1\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X DELETE 'https://app.trdrs.co/api/operator/organizations/{organizationId}/members' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"authUserId\":\"user_2\",\"expectedVersion\":1}'"}]}},"/api/operator/venues":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Create a venue","description":"Creates a venue in one of your organizations, ready to issue accounts on the paper book. A venue lives in one environment for good: going live means creating a production venue with the same definitions. An owner of the organization calls it from a signed-in session on a trusted origin, and the response is the new venue. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueCreateRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueCreateResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`idempotency_conflict`: the `Idempotency-Key` already created a different venue.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"organizationId\": \"00000000-0000-0000-0000-000000000001\",\n    \"name\": \"Meridian Evaluation\",\n    \"environment\": \"sandbox\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"organizationId\":\"00000000-0000-0000-0000-000000000001\",\"name\":\"Meridian Evaluation\",\"environment\":\"sandbox\"}'"}]}},"/api/operator/venues/{venueId}":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read one venue","description":"Reads one venue: its name, environment, state, venue rules setting and the company that carries its brand. Any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueReadResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/operator/venues/{venueId}/firm":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Adopt your firm into this venue","description":"Links the firm you ran before you had a venue to this venue, so the venue takes over its brand and its accounts can be brought in. Adopting moves nothing: accounts the firm already issued keep the conditions they were issued under, and the venue's groups and stages govern what it issues from now on. An owner or operator of the venue's organization calls it from a signed-in session on a trusted origin, with no body, and asking for a link that already exists returns the venue unchanged. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueFirmAdoptResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"`no_firm`: you run no firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`firm_already_linked`: another venue already holds your firm. `venue_already_linked`: this venue already holds a different firm.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/firm', {\n  method: 'POST',\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/firm' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/operator/venues/{venueId}/keys":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Create a venue operator key","description":"Creates a Venue key for your backend, bound to this venue, its environment and the scopes you name. Give the returned token only to your backend: it never grants access as a trader, and it stops working if the owner who created it stops being an owner. An owner calls it from a signed-in session on a trusted origin, since no key can create another, and the same `Idempotency-Key` sent again returns the same token and expiry. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueKeyIssueRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueKeyIssueResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`idempotency_conflict`: the `Idempotency-Key` already created a key with different fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/keys', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"name\": \"Account invitations\",\n    \"scopes\": [\n      \"account:read\",\n      \"grant:manage\"\n    ],\n    \"expiresInSeconds\": 86400\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/keys' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"name\":\"Account invitations\",\"scopes\":[\"account:read\",\"grant:manage\"],\"expiresInSeconds\":86400}'"}]},"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"List venue operator keys","description":"Lists the venue's keys, 100 to a page, with each key's name, scopes, expiry and revocation. The token itself is never returned. An owner calls it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"after","in":"query","required":false,"schema":{"type":"string","format":"uuid"},"description":"The `nextCursor` from the previous page, sent unchanged. A page holds at most 100 items."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueKeyListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/keys', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/keys' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/operator/venues/{venueId}/keys/{keyId}":{"delete":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Revoke a venue operator key","description":"Revokes a Venue key. Every later call with it is refused, including one already under way that hasn't reached its write yet. Send an empty JSON body; an owner calls it from a signed-in session on a trusted origin, and revoking again returns the original revocation time. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueKeyRevokeRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueKeyRevokeResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/keys/{keyId}', {\n  method: 'DELETE',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X DELETE 'https://app.trdrs.co/api/operator/venues/{venueId}/keys/{keyId}' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/operator/venues/{venueId}/connect/origins":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"List approved Connect origins","description":"Lists the web origins allowed to embed Connect Link for this venue, each with its review state. Origins are exact, with no wildcards. An owner calls it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectOriginListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/connect/origins', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/connect/origins' \\\n  -b \"session=$TRDRS_SESSION\""}]},"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Register a Connect origin","description":"Registers a web origin that may embed Connect Link for this venue. A sandbox origin is approved at once, and a production origin waits for review. An owner calls it from a signed-in session on a trusted trdrs origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectOriginRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectOriginResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/connect/origins', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"origin\": \"https://backoffice.example.com\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/connect/origins' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"origin\":\"https://backoffice.example.com\"}'"}]}},"/api/partner/venues/{venueId}/connect/sessions":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Create a Connect Link session","description":"Starts a Connect Link session from your backend, so a trader can connect a provider account inside your own site. The session is bound to this venue, one approved origin and the trader's email. The response carries a short-lived token you can hand to the browser, which your Venue key must never reach. Required scope: `connect:manage`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectSessionCreateRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectSessionIssuedResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/connect/sessions', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"origin\": \"https://backoffice.example.com\",\n    \"email\": \"trader@example.com\",\n    \"expiresInSeconds\": 300\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/connect/sessions' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"origin\":\"https://backoffice.example.com\",\"email\":\"trader@example.com\",\"expiresInSeconds\":300}'"}]}},"/api/partner/venues/{venueId}/connect/sessions/{sessionId}":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read a Connect Link outcome","description":"Reads how a Connect Link session ended: its status and the outcome, with sensitive details removed. Tokens, provider credentials and other accounts never appear in it. Required scope: `connect:manage`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"sessionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectSessionResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/connect/sessions/{sessionId}', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/connect/sessions/{sessionId}' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"delete":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Close a Connect Link session","description":"Closes a Connect Link session so its token can no longer be used. Send an empty JSON body. Closing twice changes nothing, and it can't undo a connection the trader already completed. Required scope: `connect:manage`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"sessionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectSessionCloseRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueConnectSessionResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/connect/sessions/{sessionId}', {\n  method: 'DELETE',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({}),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X DELETE 'https://app.trdrs.co/api/partner/venues/{venueId}/connect/sessions/{sessionId}' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{}'"}]}},"/api/connect-link/mount":{"post":{"tags":["Venue platform preview"],"security":[],"summary":"Mount a Connect Link token","description":"Exchanges the short-lived token your backend received for one popup handoff, from the page that embeds Connect Link. A request that carries a cookie or a bearer credential is refused, so the mount never borrows authority it wasn't given. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectLinkMountRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectLinkMountResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/connect-link/mount', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_API_KEY}`,\n  },\n  body: JSON.stringify({\n    \"token\": \"trdrs_connect_example\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/connect-link/mount' \\\n  -H \"Authorization: Bearer $TRDRS_API_KEY\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"token\":\"trdrs_connect_example\"}'"}]}},"/api/connect-link/sessions/{sessionId}/claim":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Claim a Connect popup handoff","description":"Claims the popup handoff for the signed-in trader. It needs a trdrs session with a verified email equal to the one the session was created for, and any other signed-in person is refused. Retrying is safe. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectLinkClaimRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectLinkClaimResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/connect-link/sessions/{sessionId}/claim', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"browserToken\": \"trdrs_browser_example\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/connect-link/sessions/{sessionId}/claim' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"browserToken\":\"trdrs_browser_example\"}'"}]}},"/api/connect-link/sessions/{sessionId}/complete":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Complete a Connect provider login","description":"Completes the Connect Link session once the trader has signed in to the provider. trdrs looks the account up in the trader's own connected accounts, so you can't name an account they don't hold. It needs the signed-in session of the trader the session was created for. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectLinkCompleteRequest"}}}},"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectLinkCompleteResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/connect-link/sessions/{sessionId}/complete', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"provider\": \"rithmic\",\n    \"accountNumber\": \"EVAL-7C21A9\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/connect-link/sessions/{sessionId}/complete' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"provider\":\"rithmic\",\"accountNumber\":\"EVAL-7C21A9\"}'"}]}},"/api/connect-link/sessions/{sessionId}":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read your Connect popup status","description":"Reads where the trader's Connect Link session stands and how it ended, with sensitive details removed. It needs the signed-in session of the trader the session was created for. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectLinkStatusResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/connect-link/sessions/{sessionId}', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/connect-link/sessions/{sessionId}' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/partner/venues/{venueId}/risk-policies":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"List the venue's risk policies","description":"Lists every risk policy the venue states, with its stored versions, its publications in order, and the version in force, which is the latest one published. Use it to see which terms your accounts are held to now. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskPolicyListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/risk-policies', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/risk-policies' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]},"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Store a risk policy version","description":"Stores one version of a risk policy: the margin, stop-out, valuation, settlement and posting terms your accounts are held to. A stored version applies to no account until you publish it, and it can never change, so a changed term is always a new version. The response names the version, and the same content sent again returns it with `created: false` and status `200`. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskPolicyStoreRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskPolicyStoreResponse"}}}},"400":{"description":"The policy breaks a rule of the risk policy contract, and `field` names the value refused. A figure marked unsourced can be stored, but never published.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`risk_policy_version_conflict`: the version is stored with other content. `risk_policy_owner_conflict`: the policy id belongs to another venue or to trdrs, since a policy's first version fixes its owner. `risk_policy_id_reserved`: the id starts with `trdrs-`. `risk_policy_posting_mismatch`: the posting term doesn't state each currency at the precision trdrs posts it in, two decimals for USD and six for USDC and USDT.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/risk-policies', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"policy\": {\n      \"policyId\": \"meridian-futures\",\n      \"version\": \"2026-10-01\",\n      \"authority\": {\n        \"kind\": \"firm\",\n        \"venueId\": \"00000000-0000-0000-0000-000000000001\",\n        \"name\": \"Meridian Futures\"\n      },\n      \"currency\": \"USD\",\n      \"thresholds\": {\n        \"version\": \"thresholds-2026-10-01\",\n        \"authority\": \"firm\",\n        \"source\": \"the venue's own terms\",\n        \"effectiveFrom\": \"2026-10-01T00:00:00.000Z\",\n        \"effectiveUntil\": null,\n        \"marginCall\": null,\n        \"stopOut\": \"1\",\n        \"recoveryLevel\": \"1.1\",\n        \"sources\": {\n          \"marginCall\": {\n            \"authority\": \"firm\",\n            \"source\": \"the venue's own terms\",\n            \"sourced\": true\n          },\n          \"stopOut\": {\n            \"authority\": \"firm\",\n            \"source\": \"the venue's own terms\",\n            \"sourced\": true\n          },\n          \"recoveryLevel\": {\n            \"authority\": \"firm\",\n            \"source\": \"the venue's own terms\",\n            \"sourced\": true\n          }\n        }\n      },\n      \"classes\": {\n        \"futures\": {\n          \"margin\": {\n            \"version\": \"margin-2026-10-01\",\n            \"authority\": \"firm\",\n            \"source\": \"the venue's own terms\",\n            \"effectiveFrom\": \"2026-10-01T00:00:00.000Z\",\n            \"effectiveUntil\": null,\n            \"asset\": \"USD\",\n            \"basis\": \"per_contract\",\n            \"window\": {\n              \"timeZone\": \"America/Chicago\",\n              \"startMinute\": 510,\n              \"exposureCutoffMinute\": 900,\n              \"endMinute\": 915,\n              \"weekdays\": [\n                1,\n                2,\n                3,\n                4,\n                5\n              ],\n              \"closedDates\": []\n            },\n            \"closeOnly\": \"at_roll\",\n            \"contracts\": [\n              {\n                \"contract\": \"CME:NQZ2026\",\n                \"root\": \"NQ\",\n                \"day\": {\n                  \"initial\": \"1000\",\n                  \"maintenance\": \"500\",\n                  \"sources\": {\n                    \"initial\": {\n                      \"authority\": \"firm\",\n                      \"source\": \"the venue's own terms\",\n                      \"sourced\": true\n                    },\n                    \"maintenance\": {\n                      \"authority\": \"firm\",\n                      \"source\": \"the venue's own terms\",\n                      \"sourced\": true\n                    }\n                  }\n                },\n                \"overnight\": {\n                  \"initial\": \"43207\",\n                  \"maintenance\": \"43207\",\n                  \"sources\": {\n                    \"initial\": {\n                      \"authority\": \"firm\",\n                      \"source\": \"the venue's own terms\",\n                      \"sourced\": true\n                    },\n                    \"maintenance\": {\n                      \"authority\": \"firm\",\n                      \"source\": \"the venue's own terms\",\n                      \"sourced\": true\n                    }\n                  }\n                }\n              }\n            ]\n          },\n          \"valuation\": {\n            \"version\": \"valuation-2026-10-01\",\n            \"authority\": \"firm\",\n            \"source\": \"the venue's own terms\",\n            \"effectiveFrom\": \"2026-10-01T00:00:00.000Z\",\n            \"effectiveUntil\": null,\n            \"maxAgeMs\": 5000\n          },\n          \"ticketHedging\": null\n        },\n        \"crypto_derivative\": null,\n        \"fx_cfd\": null\n      },\n      \"settlement\": {\n        \"version\": \"settlement-2026-10-01\",\n        \"authority\": \"firm\",\n        \"source\": \"the venue's own terms\",\n        \"effectiveFrom\": \"2026-10-01T00:00:00.000Z\",\n        \"effectiveUntil\": null,\n        \"kind\": \"settlement_asset\"\n      },\n      \"posting\": {\n        \"version\": \"posting-2026-10-01\",\n        \"authority\": \"firm\",\n        \"source\": \"the venue's own terms\",\n        \"effectiveFrom\": \"2026-10-01T00:00:00.000Z\",\n        \"effectiveUntil\": null,\n        \"currencies\": [\n          {\n            \"currency\": \"USD\",\n            \"decimals\": 2,\n            \"rounding\": \"half_even\",\n            \"source\": {\n              \"authority\": \"publisher\",\n              \"source\": \"ISO 4217: USD minor unit 2\",\n              \"sourced\": true,\n              \"document\": null\n            }\n          }\n        ]\n      }\n    }\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/risk-policies' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"policy\":{\"policyId\":\"meridian-futures\",\"version\":\"2026-10-01\",\"authority\":{\"kind\":\"firm\",\"venueId\":\"00000000-0000-0000-0000-000000000001\",\"name\":\"Meridian Futures\"},\"currency\":\"USD\",\"thresholds\":{\"version\":\"thresholds-2026-10-01\",\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"effectiveFrom\":\"2026-10-01T00:00:00.000Z\",\"effectiveUntil\":null,\"marginCall\":null,\"stopOut\":\"1\",\"recoveryLevel\":\"1.1\",\"sources\":{\"marginCall\":{\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"sourced\":true},\"stopOut\":{\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"sourced\":true},\"recoveryLevel\":{\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"sourced\":true}}},\"classes\":{\"futures\":{\"margin\":{\"version\":\"margin-2026-10-01\",\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"effectiveFrom\":\"2026-10-01T00:00:00.000Z\",\"effectiveUntil\":null,\"asset\":\"USD\",\"basis\":\"per_contract\",\"window\":{\"timeZone\":\"America/Chicago\",\"startMinute\":510,\"exposureCutoffMinute\":900,\"endMinute\":915,\"weekdays\":[1,2,3,4,5],\"closedDates\":[]},\"closeOnly\":\"at_roll\",\"contracts\":[{\"contract\":\"CME:NQZ2026\",\"root\":\"NQ\",\"day\":{\"initial\":\"1000\",\"maintenance\":\"500\",\"sources\":{\"initial\":{\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"sourced\":true},\"maintenance\":{\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"sourced\":true}}},\"overnight\":{\"initial\":\"43207\",\"maintenance\":\"43207\",\"sources\":{\"initial\":{\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"sourced\":true},\"maintenance\":{\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"sourced\":true}}}}]},\"valuation\":{\"version\":\"valuation-2026-10-01\",\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"effectiveFrom\":\"2026-10-01T00:00:00.000Z\",\"effectiveUntil\":null,\"maxAgeMs\":5000},\"ticketHedging\":null},\"crypto_derivative\":null,\"fx_cfd\":null},\"settlement\":{\"version\":\"settlement-2026-10-01\",\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"effectiveFrom\":\"2026-10-01T00:00:00.000Z\",\"effectiveUntil\":null,\"kind\":\"settlement_asset\"},\"posting\":{\"version\":\"posting-2026-10-01\",\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"effectiveFrom\":\"2026-10-01T00:00:00.000Z\",\"effectiveUntil\":null,\"currencies\":[{\"currency\":\"USD\",\"decimals\":2,\"rounding\":\"half_even\",\"source\":{\"authority\":\"publisher\",\"source\":\"ISO 4217: USD minor unit 2\",\"sourced\":true,\"document\":null}}]}}}'"}]}},"/api/partner/venues/{venueId}/risk-policies/{policyId}":{"get":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Read one risk policy","description":"Reads one of the venue's risk policies with the full content of each stored version, its publications and the version in force. Use it to check the exact terms before you publish. Required scope: `venue:read`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"policyId","in":"path","required":true,"schema":{"type":"string"},"description":"The policy's id, as you named it in its first version."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskPolicyReadResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue states no policy with that id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/risk-policies/{policyId}', {\n  headers: { Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}` },\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/partner/venues/{venueId}/risk-policies/{policyId}' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\""}]}},"/api/partner/venues/{venueId}/risk-policies/{policyId}/publications":{"post":{"tags":["Venue platform preview"],"security":[{"venueOperatorKey":[]}],"summary":"Publish a risk policy version","description":"Puts a stored version of a policy in force for every account held to the policy. An account holding an open position, a working order, a charge owed or an open liquidation takes it in the same write, and every other account before its next change, so no account holds anything under an earlier version. Nothing is backdated. The response is the publication, with its sequence number and how many accounts took it in the same write. Required scope: `venue:configure`. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"policyId","in":"path","required":true,"schema":{"type":"string"},"description":"The policy's id, as you named it in its first version."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"The publication's reference, 1 to 128 characters. The same key for the same version returns that publication again; for another version it's refused as `idempotency_conflict`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskPolicyPublishRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskPolicyPublishResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue states no such policy or version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`risk_policy_unsourced`: the version has a figure marked unsourced. `risk_policy_ticket_hedging_required`: the version states no ticket hedging for a product class it offers, and an account held to the policy holds independent tickets. `risk_policy_unchanged`: the version is already in force. `idempotency_conflict`: the key already published another version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"const res = await fetch('https://app.trdrs.co/api/partner/venues/{venueId}/risk-policies/{policyId}/publications', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    Authorization: `Bearer ${process.env.TRDRS_VENUE_KEY}`,\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  body: JSON.stringify({\n    \"version\": \"2026-10-01\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/partner/venues/{venueId}/risk-policies/{policyId}/publications' \\\n  -H \"Authorization: Bearer $TRDRS_VENUE_KEY\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"version\":\"2026-10-01\"}'"}]}},"/api/operator/venues/{venueId}/risk-policies":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"List the venue's risk policies","description":"Lists every risk policy the venue states, with its stored versions, its publications in order, and the version in force, which is the latest one published. Use it to see which terms your accounts are held to now. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskPolicyListResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/risk-policies', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/risk-policies' \\\n  -b \"session=$TRDRS_SESSION\""}]},"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Store a risk policy version","description":"Stores one version of a risk policy: the margin, stop-out, valuation, settlement and posting terms your accounts are held to. A stored version applies to no account until you publish it, and it can never change, so a changed term is always a new version. The response names the version, and the same content sent again returns it with `created: false` and status `200`. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"A key you choose, 1 to 128 characters, that identifies this write. Send the same key when you retry it, so the write is never applied twice."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskPolicyStoreRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskPolicyStoreResponse"}}}},"400":{"description":"The policy breaks a rule of the risk policy contract, and `field` names the value refused. A figure marked unsourced can be stored, but never published.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue, account or resource doesn't exist in this environment, or isn't yours to see.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`risk_policy_version_conflict`: the version is stored with other content. `risk_policy_owner_conflict`: the policy id belongs to another venue or to trdrs, since a policy's first version fixes its owner. `risk_policy_id_reserved`: the id starts with `trdrs-`. `risk_policy_posting_mismatch`: the posting term doesn't state each currency at the precision trdrs posts it in, two decimals for USD and six for USDC and USDT.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/risk-policies', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"policy\": {\n      \"policyId\": \"meridian-futures\",\n      \"version\": \"2026-10-01\",\n      \"authority\": {\n        \"kind\": \"firm\",\n        \"venueId\": \"00000000-0000-0000-0000-000000000001\",\n        \"name\": \"Meridian Futures\"\n      },\n      \"currency\": \"USD\",\n      \"thresholds\": {\n        \"version\": \"thresholds-2026-10-01\",\n        \"authority\": \"firm\",\n        \"source\": \"the venue's own terms\",\n        \"effectiveFrom\": \"2026-10-01T00:00:00.000Z\",\n        \"effectiveUntil\": null,\n        \"marginCall\": null,\n        \"stopOut\": \"1\",\n        \"recoveryLevel\": \"1.1\",\n        \"sources\": {\n          \"marginCall\": {\n            \"authority\": \"firm\",\n            \"source\": \"the venue's own terms\",\n            \"sourced\": true\n          },\n          \"stopOut\": {\n            \"authority\": \"firm\",\n            \"source\": \"the venue's own terms\",\n            \"sourced\": true\n          },\n          \"recoveryLevel\": {\n            \"authority\": \"firm\",\n            \"source\": \"the venue's own terms\",\n            \"sourced\": true\n          }\n        }\n      },\n      \"classes\": {\n        \"futures\": {\n          \"margin\": {\n            \"version\": \"margin-2026-10-01\",\n            \"authority\": \"firm\",\n            \"source\": \"the venue's own terms\",\n            \"effectiveFrom\": \"2026-10-01T00:00:00.000Z\",\n            \"effectiveUntil\": null,\n            \"asset\": \"USD\",\n            \"basis\": \"per_contract\",\n            \"window\": {\n              \"timeZone\": \"America/Chicago\",\n              \"startMinute\": 510,\n              \"exposureCutoffMinute\": 900,\n              \"endMinute\": 915,\n              \"weekdays\": [\n                1,\n                2,\n                3,\n                4,\n                5\n              ],\n              \"closedDates\": []\n            },\n            \"closeOnly\": \"at_roll\",\n            \"contracts\": [\n              {\n                \"contract\": \"CME:NQZ2026\",\n                \"root\": \"NQ\",\n                \"day\": {\n                  \"initial\": \"1000\",\n                  \"maintenance\": \"500\",\n                  \"sources\": {\n                    \"initial\": {\n                      \"authority\": \"firm\",\n                      \"source\": \"the venue's own terms\",\n                      \"sourced\": true\n                    },\n                    \"maintenance\": {\n                      \"authority\": \"firm\",\n                      \"source\": \"the venue's own terms\",\n                      \"sourced\": true\n                    }\n                  }\n                },\n                \"overnight\": {\n                  \"initial\": \"43207\",\n                  \"maintenance\": \"43207\",\n                  \"sources\": {\n                    \"initial\": {\n                      \"authority\": \"firm\",\n                      \"source\": \"the venue's own terms\",\n                      \"sourced\": true\n                    },\n                    \"maintenance\": {\n                      \"authority\": \"firm\",\n                      \"source\": \"the venue's own terms\",\n                      \"sourced\": true\n                    }\n                  }\n                }\n              }\n            ]\n          },\n          \"valuation\": {\n            \"version\": \"valuation-2026-10-01\",\n            \"authority\": \"firm\",\n            \"source\": \"the venue's own terms\",\n            \"effectiveFrom\": \"2026-10-01T00:00:00.000Z\",\n            \"effectiveUntil\": null,\n            \"maxAgeMs\": 5000\n          },\n          \"ticketHedging\": null\n        },\n        \"crypto_derivative\": null,\n        \"fx_cfd\": null\n      },\n      \"settlement\": {\n        \"version\": \"settlement-2026-10-01\",\n        \"authority\": \"firm\",\n        \"source\": \"the venue's own terms\",\n        \"effectiveFrom\": \"2026-10-01T00:00:00.000Z\",\n        \"effectiveUntil\": null,\n        \"kind\": \"settlement_asset\"\n      },\n      \"posting\": {\n        \"version\": \"posting-2026-10-01\",\n        \"authority\": \"firm\",\n        \"source\": \"the venue's own terms\",\n        \"effectiveFrom\": \"2026-10-01T00:00:00.000Z\",\n        \"effectiveUntil\": null,\n        \"currencies\": [\n          {\n            \"currency\": \"USD\",\n            \"decimals\": 2,\n            \"rounding\": \"half_even\",\n            \"source\": {\n              \"authority\": \"publisher\",\n              \"source\": \"ISO 4217: USD minor unit 2\",\n              \"sourced\": true,\n              \"document\": null\n            }\n          }\n        ]\n      }\n    }\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/risk-policies' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"policy\":{\"policyId\":\"meridian-futures\",\"version\":\"2026-10-01\",\"authority\":{\"kind\":\"firm\",\"venueId\":\"00000000-0000-0000-0000-000000000001\",\"name\":\"Meridian Futures\"},\"currency\":\"USD\",\"thresholds\":{\"version\":\"thresholds-2026-10-01\",\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"effectiveFrom\":\"2026-10-01T00:00:00.000Z\",\"effectiveUntil\":null,\"marginCall\":null,\"stopOut\":\"1\",\"recoveryLevel\":\"1.1\",\"sources\":{\"marginCall\":{\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"sourced\":true},\"stopOut\":{\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"sourced\":true},\"recoveryLevel\":{\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"sourced\":true}}},\"classes\":{\"futures\":{\"margin\":{\"version\":\"margin-2026-10-01\",\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"effectiveFrom\":\"2026-10-01T00:00:00.000Z\",\"effectiveUntil\":null,\"asset\":\"USD\",\"basis\":\"per_contract\",\"window\":{\"timeZone\":\"America/Chicago\",\"startMinute\":510,\"exposureCutoffMinute\":900,\"endMinute\":915,\"weekdays\":[1,2,3,4,5],\"closedDates\":[]},\"closeOnly\":\"at_roll\",\"contracts\":[{\"contract\":\"CME:NQZ2026\",\"root\":\"NQ\",\"day\":{\"initial\":\"1000\",\"maintenance\":\"500\",\"sources\":{\"initial\":{\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"sourced\":true},\"maintenance\":{\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"sourced\":true}}},\"overnight\":{\"initial\":\"43207\",\"maintenance\":\"43207\",\"sources\":{\"initial\":{\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"sourced\":true},\"maintenance\":{\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"sourced\":true}}}}]},\"valuation\":{\"version\":\"valuation-2026-10-01\",\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"effectiveFrom\":\"2026-10-01T00:00:00.000Z\",\"effectiveUntil\":null,\"maxAgeMs\":5000},\"ticketHedging\":null},\"crypto_derivative\":null,\"fx_cfd\":null},\"settlement\":{\"version\":\"settlement-2026-10-01\",\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"effectiveFrom\":\"2026-10-01T00:00:00.000Z\",\"effectiveUntil\":null,\"kind\":\"settlement_asset\"},\"posting\":{\"version\":\"posting-2026-10-01\",\"authority\":\"firm\",\"source\":\"the venue's own terms\",\"effectiveFrom\":\"2026-10-01T00:00:00.000Z\",\"effectiveUntil\":null,\"currencies\":[{\"currency\":\"USD\",\"decimals\":2,\"rounding\":\"half_even\",\"source\":{\"authority\":\"publisher\",\"source\":\"ISO 4217: USD minor unit 2\",\"sourced\":true,\"document\":null}}]}}}'"}]}},"/api/operator/venues/{venueId}/risk-policies/{policyId}":{"get":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Read one risk policy","description":"Reads one of the venue's risk policies with the full content of each stored version, its publications and the version in force. Use it to check the exact terms before you publish. In the back office, any member of the venue's organization can call it from a signed-in session. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"policyId","in":"path","required":true,"schema":{"type":"string"},"description":"The policy's id, as you named it in its first version."}],"responses":{"200":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskPolicyReadResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue states no policy with that id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The request conflicts with what is stored: the `Idempotency-Key` was used with a different body, or the version you sent is stale. The `error` code names the conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/risk-policies/{policyId}', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/operator/venues/{venueId}/risk-policies/{policyId}' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/operator/venues/{venueId}/risk-policies/{policyId}/publications":{"post":{"tags":["Venue platform preview"],"security":[{"sessionCookie":[]}],"summary":"Publish a risk policy version","description":"Puts a stored version of a policy in force for every account held to the policy. An account holding an open position, a working order, a charge owed or an open liquidation takes it in the same write, and every other account before its next change, so no account holds anything under an earlier version. Nothing is backdated. The response is the publication, with its sequence number and how many accounts took it in the same write. In the back office, an owner or operator of the venue's organization calls it from a signed-in session on a trusted origin. Preview: served on the sandbox to every venue, and production availability is arranged when a venue qualifies. Trading API keys and Partner keys do not authorize these routes.","parameters":[{"name":"venueId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"policyId","in":"path","required":true,"schema":{"type":"string"},"description":"The policy's id, as you named it in its first version."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":128},"description":"The publication's reference, 1 to 128 characters. The same key for the same version returns that publication again; for another version it's refused as `idempotency_conflict`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskPolicyPublishRequest"}}}},"responses":{"201":{"description":"Success. The response is sent with `Cache-Control: no-store`, so don't cache it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VenueRiskPolicyPublishResponse"}}}},"400":{"description":"The request is malformed: invalid JSON or input, a bad cursor, or a missing `Idempotency-Key` or `If-Match` header. When one value is refused, `field` names it where the check can say which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"The Venue key or the session is missing, malformed, revoked or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The credential is valid but can't do this: the key lacks the scope or its creator is no longer an owner, the email isn't verified, a reader tried to write, or the request came from an origin that isn't trusted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The venue states no such policy or version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"`risk_policy_unsourced`: the version has a figure marked unsourced. `risk_policy_ticket_hedging_required`: the version states no ticket hedging for a product class it offers, and an account held to the policy holds independent tickets. `risk_policy_unchanged`: the version is already in force. `idempotency_conflict`: the key already published another version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The body is larger than this route accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Send the body as JSON, with `Content-Type: application/json`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"trdrs can't complete the request right now, because a part of the venue platform or its credential store is unavailable. Don't assume a write happened: retry it with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/operator/venues/{venueId}/risk-policies/{policyId}/publications', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    \"Idempotency-Key\": \"example-request-1\",\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"version\": \"2026-10-01\"\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/operator/venues/{venueId}/risk-policies/{policyId}/publications' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'Idempotency-Key: example-request-1' \\\n  -H 'content-type: application/json' \\\n  -d '{\"version\":\"2026-10-01\"}'"}]}},"/api/challenges":{"get":{"tags":["Challenges"],"summary":"List challenge programs","description":"Returns the challenge programs open for enrollment. Draft programs are never listed.\n\n**Preview: outside the additive-only guarantee.** These shapes will change when challenges are rebuilt, so read them but don't build on them.\n\n**Served only where the engine runs with `CHALLENGES_ENABLED`.** Without it, these routes don't exist, and every path here answers `404`.\n\nRequires a signed-in session.","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"The programs open for enrollment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengesResponse"}}}},"404":{"description":"`CHALLENGES_ENABLED` is off, so the route doesn’t exist."}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/challenges', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/challenges' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/challenges/enroll":{"post":{"tags":["Challenges"],"summary":"Create an enrollment","description":"Enrolls you in a challenge: it issues the evaluation account into the venue group the program maps `size` to, under the stage that group runs, and creates the enrollment, all as one unit. Only a program priced at 0 can be enrolled in here, because this engine collects no fee.\n\n**Preview: outside the additive-only guarantee.** These shapes will change when challenges are rebuilt, so read them but don't build on them.\n\n**Served only where the engine runs with `CHALLENGES_ENABLED`.** Without it, these routes don't exist, and every path here answers `404`.\n\nRequires a signed-in session.","security":[{"sessionCookie":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeEnrollRequest"}}}},"responses":{"200":{"description":"You are enrolled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeEnrollResponse"}}}},"400":{"description":"`challengeId` or `size` is missing or invalid, `size` isn’t one of the program’s `accountSizes`, you have no trading profile, or the program’s currency isn’t issued here (`currency_not_issuable`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"You aren’t signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"The program’s `priceCents` isn’t 0, and this engine collects no fee.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No active challenge has that id, or `CHALLENGES_ENABLED` is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Nothing was written, and `code` says why: `venue_required` (the program maps no size to a group yet), `challenge_size_unmapped` (it doesn’t map this size), `challenge_group_unstaged` (the group runs no stage), `group_has_no_route`, `venue_risk_policy_unresolved` (the venue has no single risk policy in the program’s currency) or `enrollment_active` (you already have a `registered` or `in_progress` enrollment in the program).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/challenges/enroll', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n  },\n  credentials: 'include',\n  body: JSON.stringify({\n    \"challengeId\": \"3f8a1c2e-9b47-4d10-a3fe-2c61b7c90d84\",\n    \"size\": 50000\n  }),\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl -X POST 'https://app.trdrs.co/api/challenges/enroll' \\\n  -b \"session=$TRDRS_SESSION\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"challengeId\":\"3f8a1c2e-9b47-4d10-a3fe-2c61b7c90d84\",\"size\":50000}'"}]}},"/api/enrollments":{"get":{"tags":["Challenges"],"summary":"List your enrollments","description":"Returns your enrollments with their live progress. `progress` is present only while an enrollment is `registered` or `in_progress`, and a money value in it is null when it isn’t known: showing that null as 0 would show a trader a drawdown breach that didn’t happen.\n\n**Preview: outside the additive-only guarantee.** These shapes will change when challenges are rebuilt, so read them but don't build on them.\n\n**Served only where the engine runs with `CHALLENGES_ENABLED`.** Without it, these routes don't exist, and every path here answers `404`.\n\nRequires a signed-in session.","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Your enrollments. `totalFloor` is a static drawdown's equity level, and falling below it is a breach; it is null for a trailing drawdown.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrollmentsResponse"}}}},"400":{"description":"You have no trading profile.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"You aren’t signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"`CHALLENGES_ENABLED` is off, so the route doesn’t exist."}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/enrollments', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/enrollments' \\\n  -b \"session=$TRDRS_SESSION\""}]}},"/api/enrollments/events":{"get":{"tags":["Challenges"],"summary":"List enrollment events","description":"Returns the status history of one of your enrollments, with every threshold crossing as its own row, so an outcome can be traced exactly.\n\n**Preview: outside the additive-only guarantee.** These shapes will change when challenges are rebuilt, so read them but don't build on them.\n\n**Served only where the engine runs with `CHALLENGES_ENABLED`.** Without it, these routes don't exist, and every path here answers `404`.\n\nRequires a signed-in session.","security":[{"sessionCookie":[]}],"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","format":"uuid"},"description":"The enrollment’s id."}],"responses":{"200":{"description":"The status changes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrollmentEventsResponse"}}}},"400":{"description":"`id` is missing, or you have no trading profile.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"You aren’t signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No such enrollment, it belongs to someone else, or `CHALLENGES_ENABLED` is off. Someone else’s enrollment looks the same as one that doesn’t exist, so an id is never confirmed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"javascript","label":"TypeScript","source":"// Runs in a signed-in trdrs session, which sends its cookie. An API key cannot call this route.\nconst res = await fetch('https://app.trdrs.co/api/enrollments/events?id=e5c90b1a-7d34-4f6b-8a2e-91c8f0d47a53', {\n  credentials: 'include',\n})\nconst data = await res.json()"},{"lang":"shell","label":"cURL","source":"curl 'https://app.trdrs.co/api/enrollments/events?id=e5c90b1a-7d34-4f6b-8a2e-91c8f0d47a53' \\\n  -b \"session=$TRDRS_SESSION\""}]}}}}