Skip to main content
What changed on the partner surface, newest first. The documented surface is additive-only from the current compatibility baseline, with the PREVIEW Challenges group as the one named exception. An entry marked breaking is one that moved that baseline, which can only happen before the first partner integration; Stability says where the baseline stands today.

2026-09-08

  • An account says which symbols it can trade. GET /api/account/instruments returns the symbols the resolved account can trade through this engine, one row per tradable symbol with the search catalog’s own display identity (symbol, name, exchange, type), plus a label for the account: the firm or system name where the engine stores one (Apex), else the account number. The set is the venue’s own — a futures account lists the contract catalog, a crypto venue account lists that venue’s perpetuals, and the demo lists both. Additive, and it takes the same broker/account selectors and answers the same errors as the other account reads.
Breaking. The word “claim” left the wire, and this entry moves the compatibility baseline. It lands before the first partner integration, which is why it lands at all; see Stability.
  • Connect speaks registration. On /api/partner/connect/accounts: the response fields claim and claims are now registration and registrations, claimedAt is linkedAt, and the status claimed is linked (the full set is pending, linked, revoked, expired). The schema names follow (PartnerRegistration*). Routes are unchanged.
  • Webhook event types follow. claim.claimed is now registration.linked and claim.revoked is registration.revoked; their payloads carry registrationId instead of claimId. The other event types are unchanged, and an endpoint registered with an empty filter receives the new names automatically.

2026-09-07

Breaking. The exit-plan placement shape changed, and this entry moves the compatibility baseline. There is no shim and no dual delivery. It lands before the first partner integration, which is why it lands at all; see Stability.
  • Protection is engine state, and it rides the account revision. GET /api/account/snapshot and GET /api/account/stream now carry brackets and managedExits: every bracket the engine holds with its legs and their states, and every breakeven or trailing stop it is running, with the phase reached and the reason it is paused where it is. Both lanes carry the same revision as the rest of the account, so a protective change and the order change that caused it are points on one line. GET /api/account/brackets and GET /api/account/managed-exits serve the same two lanes for a surface that wants only one of them; a client holding a snapshot already has them. A leg in pre_armed is recorded and priced but deliberately not resting yet, because the position it protects does not exist; arming it also RE-PARENTS it, so a leg protecting a position carries a null parentOrderId.
  • Saved exit plans are a principal-scoped catalog with conditional writes. GET /api/exit-plans lists the plans a trader holds and POST /api/exit-plans authors one. PUT /api/exit-plans/{id} and DELETE /api/exit-plans/{id} are CONDITIONAL: send back the opaque revision you read, and a stale one is refused with 409 and the revision the plan carries now, rather than overwriting an edit that arrived in between. A revision is a digest, not a counter — never construct one. Each plan reports the capabilities it requires, so a host can tell which plans a selected account can run before offering them.
  • A plan is placed by reference, and the engine resolves its legs. POST /api/account/exit-plans/preview prices the ladder from the account’s own instrument facts, says what it protects and what the order carries that it does not, and returns a token binding the ORDER — the account, the plan and its revision, the instrument, the side, the quantity and the entry. POST /api/trading/order then takes exitPlan: { planId, planRevision, previewToken } and no levels at all: the engine reloads the plan at that revision, re-resolves, and refuses an edited plan, a changed account, drift or an expiry. The resolved-leg request shape it replaces is gone, along with the browser arithmetic it carried.
  • The futures catalog states its fractional roots in executable form. A row of GET /api/instruments for a product the exchange quotes in thirty-seconds now carries priceFraction: denominator, the number of parts one point divides into (32, 64 or 128), and subFraction (2 or 4) where the writing divides one of those again. It comes from the same reading of the tick and the quotation convention that writes the fractional price format on GET /api/market/symbol-info, so a ticket sizes and snaps against the served fact rather than deriving a denominator of its own. A product quoted in decimals carries no priceFraction at all.
  • The order warnings are named for the plan. exit_plan_remainder_unplaced replaces atm_remainder_unplaced and exit_plan_not_recorded replaces atm_management_not_registered. Both still mean what they meant: the protected bracket is live either way, and the message says what did not happen.
  • A preview names the order it will be spent on. POST /api/account/exit-plans/preview takes the clientOrderId the placement will ride under, and the token binds it. A preview is therefore good for one submission rather than for any order until it expires. Generate the client order id before you preview and send the same one when you place.
  • The two protective one-shots carry the revision they were read at. GET /api/account/brackets and GET /api/account/managed-exits answer { revision, items }. The number is the account’s current one, read rather than allocated: these reads do not advance the sequence your stream folds.
  • Exit plans are reachable with a tenant key. The catalog and the preview take a tenant key as well as a signed-in session, because a saved plan belongs to a principal and a key is one. A key reaches only its own plans.
  • A capability descriptor says which parts of a plan the account can run. Every account frame’s capabilities carries exitPlanSupport: the subset of stop_loss, take_profit, multiple_targets, runner_leg, breakeven and trailing_stop this account can execute. Compare it against a plan’s requires to offer only the plans that will work.

2026-09-06

Breaking. The account stream changed shape, and this entry moves the compatibility baseline. There is no shim and no dual delivery. It lands before the first partner integration, which is why it lands at all; see Stability.
  • One event carries the whole account. GET /api/account/stream sends one account event, on connect and on every change alike, and it carries the summary, the positions and the working orders as they were at one moment, with the revision that names that moment. The snapshot, positions and orders events are gone. A client that switched on those event names, or that merged them into a picture of its own, must be changed: subscribe to account and replace your whole picture with each frame.
  • Fold by the revision and nothing else. Hold the newest frame you have received for an accountId. Drop a frame at or behind that revision. Replace everything with any frame ahead of it. A frame whose revision skips ahead is still complete, so there is no gap to detect and no resync to perform; a client written to resync on a jump should stop doing so. Never compute a revision of your own.
  • GET /api/account/snapshot serves the same body. Read it when you have no stream open, or when you come back after a disconnect. Combining the one-shot summary, positions and orders reads is no longer the way to build a picture: three reads are three moments, and nothing in them says whether they agree.
  • accountId is how an account is named. It is an opaque token on every frame. Key panels, subscriptions and state by it; it is not a structure and must not be taken apart. An account number is unique at its own firm and nowhere else.
  • capabilities says what the account supports. The frame carries what the broker adapter behind it implements, so you render only controls the venue can accept. A time-in-force absent from tifs is refused, never mapped to a different lifetime.
  • clock says what the revision counts. engine means trdrs owns the account’s state and the number is the account’s own history. observation means the account lives at a venue and the number stamps our reading of it, so the order of readings is exact and the interval is not.
  • positionModel says the book is net. One instrument in one account holds at most one signed position, so a frame carries at most one row per instrument.

2026-08-29

  • Connect makes the firm the only customer messenger. trdrs no longer sends account-ready emails on a firm’s behalf. POST /api/partner/connect/accounts no longer accepts handover, its response no longer includes emailSent, and claim reads no longer include handover. Requests that still send the retired field receive 400; there is no compatibility shim. Firms notify traders and deliver venue credentials through their own secure onboarding process. This contract correction landed before the first partner integration and is the Connect compatibility baseline.
  • The futures contract catalog joins the licensed surface. GET /api/instruments serves one row per futures product root — exchange, tick size and value, dollar multiplier, roll cycle, and the listed months of products whose roll is not modelled — the same static facts the trdrs order ticket sizes, snaps and prices with. Admission is the market-data model: your tenant key or your allowlisted origin.
  • Risk controls join the Account group. GET /api/risk reads an account’s five risk controls (daily and weekly loss limits, daily and weekly profit targets, the end-of-day close) together with its lock state; PUT /api/risk replaces the controls in one write, live from the moment it lands; POST /api/risk/unlock is the manual unlock. These are the controls behind every 423 risk_locked a trading route answers, and the lock object is the same one that streams as the lock event on /api/account/stream, so a front end holds one lock truth. Admission is the trading model exactly: your tenant key, acting as the accounts’ owner. broker is required on all three; account targets one account under a multi-account login.
  • News and economic calendar join the licensed surface. A new News group in API Reference: GET /api/news (aggregated market headlines, newest first, keyset-paged, scoped by futures root with instrument), GET /api/news/stream (SSE: news_item frames), GET /api/news/image/{id} (the keyless thumbnail proxy), GET /api/calendar (scheduled events in a bounded window, with impact tiers and display-string forecast/previous/actual), and GET /api/calendar/stream (SSE: calendar_update nudges). News and the calendar each carry their own live stream. Admission is the market-data model exactly: your tenant key or your allowlisted origin.

2026-08-28

  • Market data: one connection, many charts. GET /api/market/streams multiplexes up to 24 bar subscriptions over a single SSE connection: subs is a comma-separated list of INSTRUMENT~tf tokens, every event payload carries instrument and tf for demultiplexing, and a refused subscription becomes a tagged error event while the rest live on. Built for multi-chart layouts, where browsers cap concurrent connections per origin.
  • Market data: spread expressions are instruments. /api/market/history and the bar streams accept arithmetic over instruments — ES-NQ, 1/ESU6, (ES+NQ)/2; operators + - * / ^, parentheses, numeric literals, up to four legs. The engine evaluates server-side over the bucket intersection of the legs; spread bars carry volume 0, and a string that matches a catalog symbol exactly is always that symbol, never arithmetic.

2026-08-24

  • Webhooks: pushed events with signed delivery. A new Webhooks group. Register up to five https:// endpoints per firm with POST /api/partner/webhooks (optionally filtered to specific event types), list them with GET, and remove one with DELETE. Six event types in v1: claim.claimed, claim.revoked, account.reset, balance.recorded, risk.locked, and risk.unlocked. Every delivery is signed (trdrs-signature: HMAC-SHA256 over timestamp.body, so a replayed payload cannot wear a fresh clock) and retried on failure for ~9 hours across 6 attempts. POST /api/partner/webhooks/test delivers a signed ping right now and reports the outcome; GET /api/partner/webhooks/deliveries is the per-endpoint delivery log — every attempt’s status, response code, and error, kept for 60 days — so “did you get it” is answerable from your side.
  • Firm accounts: risk controls, trading halt, and balance operations. The control half of the Firm accounts group. GET/PUT /api/partner/accounts/risk reads and sets the five per-account risk controls (daily/weekly loss, daily/weekly profit, end-of-day auto-close) — the same controls the trader sees, enforced live by the risk monitor from the moment of the write. POST /api/partner/accounts/halt blocks all new orders until your firm’s own POST /api/partner/accounts/resume; the halt survives restarts, the trader cannot self-unlock it, and it never replaces a lock that is not yours. POST /api/partner/balance-op credits, debits, or adjusts an account outside of trading — ledger-first on your referenceId, so a retried payout can never fire twice.
  • Firm accounts: provision and reset evaluation accounts by API. A new route group for partner firms running traders on the trdrs venue. POST /api/partner/accounts batch-creates evaluation accounts for your traders by email (per-item results, idempotent on your own referenceId); GET /api/partner/accounts lists the accounts your firm provisioned, with live balances; and POST /api/partner/accounts/reset puts one back to its starting state, ledger-first so a retried reset can never fire twice. Every route is scoped to accounts your firm created through the API — an account the trader opened themselves is invisible here by construction.
  • GET /api/partner/usage/accounts is live. The drill-down behind the usage number: each account that counted in the month, with the real fills that made it count and their first/last timestamps. Computed from the same query as the count, so the list always sums to the billed number — invoice reconciliation without asking us for a breakdown, account by account.
  • GET /api/partner/usage is live. A firm can now pull its own metered usage for a month under its partner key: the distinct accounts that actually traded, the agreed per-account price, and the total. It is the same computation the trdrs invoice is built from, so a bill can be reconciled straight from the API. Scoped to the calling firm by its key, with no parameter that widens it, and read-only.
  • Keys, permissions, and data policy are documented. API Standards gained a Data policy page (what the engine stores, who sees what, and the per-trader market data rule), and the Keys page now covers all three permission levels, issuance, and revocation.
  • Programmatic accounts. Operator Concepts gained a guide to running Connect claim registration, listing, and revocation as an automated pipeline. Its initial handover modes were retired before the first partner integration on 2026-08-29.
  • The Quick Start examples now match the wire exactly. History takes instrument, tf, and countBack; orders take instrument and orderType with broker/account as query parameters. The previous examples used field names the engine never accepted.
  • Worked examples on every operation. All 38 operations now render one coherent trading session instead of placeholder payloads: real ES prices, a fill that reappears in the executions ledger, an evaluation whose drawdown floors follow from its program’s terms.
  • TypeScript and curl samples on every operation. Streaming routes show a real SSE reader, cookie-authenticated routes show first-party fetch, and every sample targets the production host with realistic parameter values.
  • The spec’s first server is production (https://app.trdrs.co), so generated snippets never point at a relative host.

2026-08-23

  • The docs moved to this site. Overview, Quick Start, API Standards, Conformance, Operator Concepts, HTTP clients, and the API Reference now live in one place with one sidebar; old guide URLs redirect.
  • GET /api/market/config declares what the engine accepts: the timeframe grammar with per-unit ceilings, the bars/symbols/quotes limits, and the asset classes this deployment serves. A client can validate an ask without a round trip.
  • The Connect partner routes document the key that actually works there. Partner routes are secured under the partner-scoped key in the spec itself; a tenant key is refused on /api/partner/ by design.

2026-08-22

  • The prop evaluation surface returned as a PREVIEW group. Challenges and enrollments are documented again, marked outside the additive-only guarantee, with the CHALLENGES_ENABLED gate stated on every operation.
  • The reference covers the whole licensed surface, grouped by tag (Market data, Trading, Account, Connect, Challenges), with an onboarding guide.

2026-08-14

  • The holiday calendar is served. GET /api/market/symbol-info carries the session model’s holiday table (sessionCalendar), so clients never ship their own calendar updates.
  • Trailing stops became exclusively engine-managed. The broker-native trailing_stop entry type is refused with a pointer at the ATM path, which manages trails identically on every venue.

2026-08-05

  • Market data became licensed surface. The market routes answer first-party origins and authenticated principals only, and are documented under the tenant key.