/changelog/rss.xml.
2026-10-29
Cumulative and annualised returns side by side
New API version
2026-10-29. See Versioning to migrate.mwrr and twrr are now objects that carry both figures, so you can show the return over the period and the annual rate without checking a flag. Requests pinned to 2026-10-01 or earlier keep the flat shape.Breaking- Account returns and position returns return
mwrrandtwrras objects with two fields:cumulative: the return over the period as a decimal, never annualised.annualised: the annual rate as a decimal, set only for periods of a year or longer. It’snullfor shorter periods.
- The top-level
annualisedboolean is removed. To migrate, readmwrr.cumulative/twrr.cumulativewhere you showed the rate for periods under a year, andmwrr.annualised/twrr.annualisedwhere you showed it for a year or longer.
- On
2026-10-01and earlier, account and position returns also carrymwrr_periodandtwrr_period(cumulative over the period) andmwrr_annualisedandtwrr_annualised(annual rate,nullfor periods under a year), next to the existingmwrr,twrr, andannualisedfields.
additions
Performance and return metrics enhancements
We’ve expanded earnings and returns endpoints with new fields for simpler return calculations and clearer annualization behavior.Addedmoney_inon account earnings and position earnings: the total amount deposited into the account or position over the period, each deposit converted at the exchange rate of its own day. Over the account’s whole life, this is the total deposited.simple_returnandsimple_return_annualisedon account and position earnings:simple_returnisnetdivided bymoney_in, andsimple_return_annualisedapplies annual compounding. Both arenullwhen nothing was put in.annualisedon account returns and position returns: a boolean indicating whether the return rates are annualized (true for periods of a year or longer) or cumulative over the period.rate_limitederror code, returned when too many requests are made in a short period.
- Descriptions for
mwrrandtwrron account returns and position returns now clarify that they’re annualized for periods of a year or longer and cumulative over the period otherwise (seeannualised).
2026-10-01
Trading configuration and consistent order validation
New API version
2026-10-01. See Versioning to migrate.trading_configuration object, split into buy and sell. Quotes run the same checks as placement, so a quote fails exactly where the order it previews would. When a quoted order breaks a sizing rule, you get the quote back with the rule it breaks, so you can show your users what to change before they place it. Requests pinned to 2026-09-28 or earlier keep the legacy instrument fields and the previous error responses.Breaking- Instruments, wherever we return them (on their own or embedded in positions, orders, quotes, transactions, and valuations), no longer carry
minimum_trading_quantity,minimum_initial_cash_investment,required_cash_increment, orenforce_trading_rules. Read the rules fromtrading_configurationinstead:minimum_initial_cash_investmentistrading_configuration.buy.min_initial_cash_amount.minimum_trading_quantityistrading_configuration.buy.min_cash_amount.required_cash_incrementandenforce_trading_ruleshave no replacement. We use null in the trading configuration when no rule applies.
- Get an order quote returns
200instead of400for an order that breaks a sizing rule: a quantity off the trading increment, a cash amount that buys less than one trading increment, or a minimum intrading_configuration. The quote carries itsestimateas usual, withis_placeable: falseand the rule inblockers. Placing the order as quoted still fails with the same error. - Get an order quote and Place an order return
trading_rule_violatedinstead ofinvalid_requestwhen an order breaks a rule intrading_configuration.context.rulenames the rule (for examplebuy.min_initial_cash_amount), withcontext.requiredandcontext.actual.paramsstill points at the field the order was sized by.
trading_configurationon instruments, on every API version.buycarriesmodes,min_cash_amount,min_initial_cash_amount,min_quantity, andmin_initial_quantity;sellcarriesmodes,min_cash_amount, andmin_quantity. Anullminimum isn’t applied, and a sell minimum never blocks selling a whole position. Cash amounts are in the instrument’s trading currency.is_placeableandblockerson every order quote. Each blocker carries thecodeanddetailplacement would return, and acontextwithrule,required,actual, andrequired_cash_amount: on a cash buy, the smallestcash_amount(fees included) that meets every buy rule.trading_rule_violatederror code.insufficient_fundsandinsufficient_unitsblocker codes on order quotes. When a quote returns these blockers, thecontexttells you the balance check that failed:availableandrequestedamounts, and the accountcurrency(for funds) or the position’s available units (for units). You can use this to prompt users to add funds or adjust their position size before placing the order.
- Get an order quote runs the same instrument and account checks as placement, so it can now return
instrument_not_trading,instrument_buy_only,instrument_sell_only,instrument_too_close_to_maturity,currency_not_supported,insufficient_units,buy_order_forbidden,sell_order_forbidden, andprofessional_trader_required. - A
quantitymust be a multiple of the instrument’strading_increment, on quotes and orders. We reject a quantity off the increment rather than trimming it. - Cash buys are sized by rounding the quantity down to the instrument’s
trading_incrementinstead of to whole units. The quote’sestimate.quantitynow matches the quantity the order executes, including the price buffer we apply. - Buy minimums apply to the cash the buy invests, net of fees. Quotes for limit cash buys now check them too. Rollover orders are exempt.
- We no longer enforce a cash increment on buys. On
2026-09-28and earlier,required_cash_incrementis always0andenforce_trading_rulesis alwaysfalse. - An order that sends both
cash_amountandquantityis rejected withinvalid_paramonquantity. Previously,quantitysilently took precedence. - Selling an instrument the account holds no position in returns
insufficient_unitswithcontext.availableof"0". trading_incrementon instruments is returned at full precision (for example"0.00010000") instead of rounded to two decimal places.
additions
Order validation error codes
We’ve added new error codes to provide clearer feedback when orders conflict with instrument trading restrictions.Addedinstrument_buy_onlyerror code when you attempt to sell an instrument that only accepts buy orders.instrument_sell_onlyerror code when you attempt to buy an instrument that only accepts sell orders.
insufficient_unitserrors reportcontext.availableas an exact decimal string (for example"0.5") instead of a number rounded down to whole units.- Get an order quote errors for a cash buy that misses the instrument’s minimum initial investment or cash increment now point at
body.cash_amountinstead ofbody.quantity.
2026-09-28
Redesigned earnings responses
New API version
2026-09-28. See Versioning to migrate.2026-09-02 or earlier keep the previous flat field layout, without this breakdown.Breaking- Retrieve account earnings (P&L) returns
gross,fees, andnetat the top level, plus apositionsblock and acashblock. The flatgross_*,net_*,realized_*, andunrealized_*fields are gone.netisgrossminusfees.grossispositions.grosspluscash.gross. - The realized/unrealized and capital/income split moved under
positions.attribution, which separates aninvestmenteffect (price changes and income, with exchange-rate movements stripped out) from acurrencyeffect (exchange-rate movements on the money invested in positions). Each effect carriestotal,realized.capital,realized.income,unrealized.capital, andunrealized.income, all in the account’s currency. Thecurrencyeffect is zero when everything is in the account’s currency. position_earningsis no longer included in the account response by default. Passinclude_positionsto get each position’s earnings inline, as Retrieve position earnings (P&L) returns them.- The position response returns two views instead of one flat grid:
trading, in the instrument’s own currency, andreporting, in the account’s base currency.currency,cost_basis, andgrossnow live inside each view rather than at the top level, andgross_unrealized_percentageis nowtrading.unrealized_percentage. trading.attributionholds only aninvestmenteffect, since exchange rates play no part in the instrument’s own currency.reporting.attributionholds bothinvestmentandcurrencyeffects, with each leg converted at the exchange rate of the day it happened rather than a single period-end rate. Summed over all positions, thereportingfigures give the account’spositionsfigures.
trading view:The account response follows the same pattern, with
gross_total becoming gross, net_total becoming net, and the four buckets living under positions.attribution.investment and positions.attribution.currency.Addedaccounton position earnings responses (from2026-09-28), the ID of the account holding the position.cashon account earnings responses (from2026-09-28): what uninvested foreign-currency cash gained or lost from exchange-rate movements, ascash.grossandcash.attribution.currency.total. It isn’t split into realized and unrealized.
- Account earnings totals now include exchange-rate gains and losses on uninvested foreign-currency cash, on every API version. On
2026-09-02and earlier this meansgross_totalandnet_totalcan differ fromgross_realizedplusgross_unrealizedby that cash currency effect.
additions
Instrument client categories and deposit status tracking
We now return client category information on instruments to support MiFID II compliance, and provide expanded deposit statuses for better visibility into their lifecycle.Addedtarget_client_categorieson instrument responses, returning an array of client categories (retail, professional per se, professional on request) the instrument is intended for.- New deposit statuses:
held,returning,returned, andcancelled, providing better tracking of the deposit lifecycle. restrictedas a new instrument rollout stage.
- Fee charge
amountfield description now clarifies it reflects the notional the fee was priced on; it’s null when the amount doesn’t depend on a notional (as with flat fees).
additions
Instrument asset class allocation
We now return asset class allocation data for all instruments, showing how they split across equity, fixed income, cash, alternatives, or uninvested categories.Addedasset_classon instrument responses, showing how the instrument splits across asset classes (equity, fixed income, cash, alternatives, uninvested) with the weight in each class.
2026-09-02
Redesigned order quote responses
New API version
2026-09-02. See Versioning to migrate.POST /accounts/{account_id}/order-quotesno longer returns a single genericOrderQuoteobject. It returns a union discriminated onquote_type, with one variant per instrument and order mode:amc_market_cash,bill_market_cash,bond_fixed_coupon_market_cash,bond_zero_coupon_market_cash,etf_market_cash,etf_limit_cash,etf_market_quantity,etf_limit_quantity,mmf_market_cash, orsell. Switch onquote_typebefore reading a quote.- The flat economics fields moved under an
estimateobject and dropped theestimated_prefix:estimated_price,estimated_quantity, andestimated_cashare nowestimate.price,estimate.quantity, andestimate.cash.fees,net_cash_amount,max_cost, andmin_proceedsmoved underestimatetoo. Each variant only carries the fields that apply to it. instrumentis now the full instrument object instead of an ID string.
order_typeon every variant, indicating whether the quote is for a market or limit order.currencyon every variant.- Instrument-specific economics in
estimate:yield,annual_income, andaccrued_interestfor fixed income, plusnotional,cost,price_buffer_percentage, andasofwhere they apply. reservationobject on every variant with what a placement would set aside: a cash amount vs a unit quantity (amount,denomination).created_aton every variant.fee_breakdownon every estimate, providing an itemized list of fees. Each line includes alabel(the fee category),display_name(a human-readable name), andamount(the fee value in the quote’s currency). The line amounts sum to the totalfeesexactly.
additions
Enhanced idempotency key error handling
We now return more specific error codes when idempotency keys have conflicts or have expired, giving you better visibility into retry scenarios.Addedidempotency_key_conflicterror code when the Idempotency-Key was already used for a resource outside the scope of this request.idempotency_key_expirederror code when the Idempotency-Key was already used, and the resource it created is older than the replay window.
additions
Fee charge collection tracking and earnings breakdowns
Fee charges now track how much has been collected and what’s outstanding, and earnings responses include gross capital and income fields for finer-grained reporting.Addedcollected_amounton Retrieve a fee charge for the cash collected so far.outstanding_amounton Retrieve a fee charge for what’s still owed on the charge.collectionsarray on Retrieve a fee charge with a history of collection events per fee charge.gross_capitalon earnings responses for capital gains before fees and taxes.gross_incomeon earnings responses for income earnings before fees and taxes.
additions
Document references and confirmation type
Account documents can now point at the related order or object, and confirmation documents include anorder_confirmation type.Addedreferenceon List account documents responses for the order or object the document evidences (order ID for confirmations, null for period documents).order_confirmationonDocumentTypefor account document requests and responses.position_not_openerror code when you try to update a closed or closing position.
additions
additions
Enhanced fund details and fee variant support
We expanded ETF attributes to surface fund display metadata and currency details, and added a new endpoint to retrieve fees with their scoped variants.Added- New fields on ETF instrument responses:
display_name,headline,currency_sentence,rhp_years, andfund_base_currency. - Retrieve a fee endpoint to look up a specific fee by ID, including its variants.
variantsarray on Fee objects containing scoped fee variants per instrument, instrument type, portfolio type, or transaction type.
additions
OAuth token endpoint RFC 6749 compliance
ThePOST /auth/token endpoint now returns RFC 6749-compliant error responses
so you can distinguish between bad requests and authentication failures.Added401 Unauthorizedresponse for client authentication failures on Issue an OAuth token, with anOAuthErrorBodypayload following RFC 6749 §5.2.
400 Bad Requestresponse onPOST /auth/tokennow usesOAuthErrorBodyschema witherroranderror_descriptionfields (RFC 6749 §5.2) instead of the standard error envelope.
additions
Permissions and reference expansion
You can now query your effective permissions in the current realm, and we supportportfolio_transfer as a reference type for activity tracking.Added- List permissions to retrieve effective permissions for the authenticated actor, including scope and conditional details.
portfolio_transferenum value on reference types for tracking portfolio transfers.
additions
Identify the end person on each request
When a call concerns an end person, sendPerson-Id so we can attribute the
action for compliance. Client-User-Id is optional and helps with debugging.AddedPerson-Idrequest header for our person ID (per_…) you’re acting on behalf of. Send this whenever the request concerns an end person. See Attribution.- Optional
Client-User-Idrequest header for your own identifier of the same end user, for log correlation and support. - Error codes
person_id_too_longandclient_user_id_too_longwhen either header exceeds 255 characters.
additions
Fixed person reads
Fixed- Retrieve a person no longer returns
500when optional person columns are null in storage.
additions
More reliable valuation
Instrument responses carry more ETF detail, and account valuation reads are more consistent across price providers.Addedtrading_incrementon instrument responses.
GET /accounts/{account_id}/valuationuses the latest price per timestamp across providers.
- Unrealized earnings percentage on
GET /accounts/{account_id}/earningsno longer errors on zero cost basis.
additions
On-the-run bills and fixed-income pricing detail
You can look up the current on-the-run treasury bill per maturity period, and price responses now include accrued interest for bonds and bills.AddedGET /bills/otrto retrieve the on-the-run bill matrix for an issuer country. Periods with no matching bill are omitted.- ETF as an instrument type on List instruments and Retrieve an instrument.
accrued_interestonGET /pricesresponses.next_coupon_dateon fixed income instruments.
additions
Person creation and claim history
You can create persons directly and see the full claim audit trail by default when listing claims.Added- Create a person to create a person from claims with verification evidence. See Persons.
joint_customeras a customer type on Retrieve a customer.archived_atandlifecycleon person claim responses.- Idempotent onboarding submissions: a duplicate pending Submit an onboarding application returns
409 conflict.
- List claims for a person now defaults to
include_history=true(full audit trail, newest first). Pass?include_history=falseto collapse to the current pending and verified row per claim type. See Claims.
additions
Events, legal documents, and lifecycle webhooks
We added event polling, versioned legal document reads, and a broader set of webhook event types so you can react to orders, trades, positions, and accounts without polling.AddedGET /legal-documentsand related version and file download endpoints.- Retrieve a person claim.
- Webhook event types delivered to your registered endpoints:
order.placed,order.pending,order.executing,order.filled,order.settled,order.cancelled,trade.executed,trade.settled,position.opened,position.closing,position.closed,account.opened,account.suspended,account.activated,account.closing,account.closed, andcustomer.closed. See Webhooks.
POST /auth/tokenaccepts only theclient_credentialsgrant.purposeis required onPOST /signed-uploads.
additions
Event reads and webhook delivery
You can list events from the API, and we started delivering webhook payloads automatically with retries.Added- List events for tenant-scoped event reads.
- Automatic webhook delivery with retries for subscribed event types. See Deliveries.
2026-01-01
Initial API release
New API version
2026-01-01. See Versioning.2026-01-01.Added- Authentication with bearer tokens. See Authentication.
- Onboarding for persons, claims, and applications. See Onboarding.
- Trading, holdings, valuation, and payments endpoints across accounts.
- Webhooks with at-least-once delivery, signature verification, and automatic retries. See Webhooks.
- Idempotency support for write requests. See Idempotency.