Skip to content
Start Trading

Changelog

Notable additions and changes to the Clear Street Trading API.

Daily summary endpoint deprecated

GET /v1/market-data/daily-summary is deprecated and will be removed in a future release. Use GET /v1/market-data/snapshot instead, which now reports the same open, high, low, volume, and open-interest fields under session and top-level open_interest. The top-level cumulative_volume field on snapshots is also deprecated; use session.cumulative_volume.

The get_market_data_daily_summary MCP tool is removed. Use get_market_data_snapshot instead.

  • GET /v1/market-data/daily-summary
  • GET /v1/market-data/snapshot

Eligible-only last trade in market data

last_trade, change, and change_percent in a market data snapshot now reflect only a last-sale-eligible or last-trade-eligible print. An odd-lot or out-of-sequence print no longer appears as last_trade. When the most recent known print is ineligible, the snapshot omits last_trade, change, and change_percent instead of showing that print’s price.

The instrument screener’s price field follows the same rule: it now falls back to the previous close when the cached trade is ineligible.

  • GET /v1/market-data/snapshot
  • GET /v1/screener
  • POST /v1/screener

Live Rule 201 short sale state on market data snapshots

GET /v1/market-data/snapshot now returns short_sale_restricted, the live SEC Rule 201 short sale price test state for each security, sourced from the trading status feed.

"short_sale_restricted": true

The field is always present, and is one of:

  • true - the price test is in force, so non-exempt short sales at or below the national best bid will be rejected by the venue.
  • false - a trading status was received and the price test is not in force.
  • null - we have no reading, either because no trading status has been seen for this security yet, or because Rule 201 does not cover this security type. Options, indices and other non-equity instruments are always null.

null is not the same as false. Treat it as a prompt to check another source before shorting, not as confirmation that the security is clear.

The field reports the current state only, with no timestamps. Rule 201 is a live signal, so poll it again rather than trying to work out when a restriction lapses: a security still restricted the next day continues to report true, and one whose restriction has lapsed reports false.

Rule 201 is a live circuit breaker. It triggers intraday when a security falls 10% below its previous close, and lapses after the following trading day. It is distinct from is_short_prohibited on the instrument endpoints, which is a standing property of the security and does not change during the session.

  • GET /v1/market-data/snapshot

Locates and locate borrow rates

You can now query your locates and the cached locate borrow rates:

  • GET /v1/accounts/{account_id}/locates/{id} returns one locate. The id is matched against the locate request id, the locate id, and the client request id.
  • GET /v1/accounts/{account_id}/locates lists the account’s locates for one effective date, which defaults to the current date. Filter with comma-separated status and instrument_ids.
  • GET /v1/locates/rates returns cached borrow rates for up to 1,000 instruments. instrument_ids is required; instruments with no cached rate are omitted from the response.
  • GET /v1/locates/rates/{instrument_id} returns the cached borrow rate for one instrument, or 404 when none is cached.

Every instrument_ids value and the {instrument_id} path parameter accept an instrument ID (UUID) or a symbol; an unknown symbol returns 404.

A locate’s status is REQUESTED, ACCEPTED, REJECTED, or EXPIRED; an accepted locate reads EXPIRED once its effective_date has passed. The grant-side fields locate_id, quantity, used_quantity, and reserved_quantity are omitted until the locate is granted. Rates report the instrument, the borrow rate as a percentage, and the as_of time the rate was requested.

  • GET /v1/accounts/{account_id}/locates/{id}
  • GET /v1/accounts/{account_id}/locates
  • GET /v1/locates/rates
  • GET /v1/locates/rates/{instrument_id}

Machine-readable rejection codes on position instructions, business rejections now 422

Rejected position instructions now carry a machine-readable rejection object next to the existing rejection_reason text. Each rejection has a stable reason code (for example DNE_NOT_ON_EXPIRY, INSUFFICIENT_POSITION, OPTIONS_LEVEL_EXCEEDED, or EXERCISE_PAST_CUTOFF), a domain, and a metadata map of reason-specific parameters (for example available and requested, or expiry and business_date), typed as a string-to-string map. Branch on rejection.reason instead of parsing rejection_reason. The same rejection is returned when reading instructions (GET) as well as on submit and cancel, and the human rejection_reason on reads is the same canonical message, so a rejected instruction looks the same however you fetch it. The field is absent on accepted rows, on rejections that carry no structured code, and on instructions rejected before this shipped.

The HTTP status for a rejected instruction now reflects the specific cause. A well-formed instruction that is rejected on its merits — for example an exercise after expiry day, a do-not-exercise or contrary-exercise outside expiry day, insufficient position, an options-level limit, or a clearing rejection — now returns 422 Unprocessable Entity. This applies to a submission where every row is rejected for such a reason, and to a cancel that arrives too late or targets a terminal instruction. These cases previously returned 400 Bad Request. Duplicate (409), clearing-unavailable (503), and internal-fault (500) responses are unchanged. If your client keys on 400 to detect these rejections, update it to handle 422.

  • POST /v1/accounts/{account_id}/positions/instructions
  • DELETE /v1/accounts/{account_id}/positions/instructions/{instruction_id}
  • GET /v1/accounts/{account_id}/positions/instructions

More accurate previous close in screener and fundamentals

GET /v1/screener’s prev_day_close and GET /v1/instruments/{instrument_id}/fundamentals’s previous_close now resolve from the same close-price source as the rest of the platform, instead of a separate end-of-day feed anchored to a single global trade date.

Two effects follow from this. First, an instrument now reports its own most recent close even when it lags behind other instruments’ trade dates; previously this case returned no value. Second, an admin close-price correction or a corporate-action adjustment now appears in these fields, matching what other instrument endpoints already report.

Percent-change and 52-week gap fields (one_week_change_pct through one_year_change_pct, gap_from_52w_high_pct, gap_from_52w_low_pct) are unaffected and continue to compute from the prior close-price source.

  • GET /v1/screener
  • GET /v1/instruments/{instrument_id}/fundamentals

Non-trade activities endpoint

New endpoint returns non trade activities for an account. The results are in chronological descending order and paginated.

  • GET /v1/accounts/{account_id}/ntas

Snapshots add session OHLV and open interest

GET /v1/market-data/snapshot now reports the same open, high, low, volume, and open-interest fields previously available only from GET /v1/market-data/daily-summary:

  • session.open, session.high, session.low, and session.ohlv_date: the most recent session’s open/high/low prices and the date they apply to.
  • session.cumulative_volume: cumulative traded volume for the current session. Prefer this over the top-level cumulative_volume field, which is now deprecated.
  • session.ohlv_applicable: false for index instruments, whose price is a computed level rather than a traded security. When false, the OHLV fields above are always absent.
  • open_interest: open interest (outstanding contracts), populated for options only.

session is now always present in the response; each field inside it is independently nullable and omitted when absent.

GET /v1/market-data/snapshot now accepts at most 100 instrument_ids per request.

  • GET /v1/market-data/snapshot

Tick rules on instruments and options contracts

Instruments and options contracts now carry a tick_rules array describing the price increments the instrument can be quoted and traded in. Use it to constrain a limit price before you submit, instead of discovering the constraint from an INVALID_TICK_SIZE rejection.

The minimum increment depends on price, so the response returns the bands rather than a single current value. start_price is inclusive and end_price is exclusive, so every price falls in exactly one band. The last band has no end_price and runs without an upper bound. A price is valid when it is a whole multiple of that band’s tick_size.

A non-penny index option looks like this:

"tick_rules": [
{ "start_price": "0", "end_price": "3.0", "tick_size": "0.05" },
{ "start_price": "3.0", "tick_size": "0.10" }
]

The bands describe the instrument itself. On an equity they say nothing about that equity’s option chain, so read them from the contract you intend to trade.

tick_rules is absent when no schedule is available. That covers instruments we publish no schedule for, such as bonds and futures, and options whose penny-program status our reference data does not supply. Treat an absent field as unknown rather than unrestricted.

  • GET /v1/instruments
  • GET /v1/instruments/{instrument_id}
  • GET /v1/instruments/options/contracts

underlying_instrument_type added to positions, orders, and executions

GET /v1/positions, order responses, and execution responses now include underlying_instrument_type alongside underlying_instrument_id. Use it to tell an index underlier from an equity underlier without a separate lookup.

The field is null when the position, order, or execution is not an option, or when the underlier has not been resolved.

  • GET /v1/positions
  • GET /v1/orders
  • GET /v1/orders/{order_id}
  • POST /v1/orders
  • PATCH /v1/orders/{order_id}
  • DELETE /v1/orders/{order_id}
  • GET /v1/executions

AM-settled expiry dates follow the last trade cutoff

In the instrument endpoint’s option-expiry listing (include_options_expiry_dates=true), has_settles_on_open now counts only AM-settled contracts that you can still trade. AM-settled contracts stop trading at the close of the business day before settlement, so the flag becomes false before the expiry date arrives. Previously it stayed true until the date passed.

An expiry date is removed from options_contract_expiry_dates and from the deprecated options_expiry_dates field when no contract on that date can be traded in either settlement cycle. A date can therefore leave the response during a trading session. Request the listing again instead of caching it for the session.

has_settles_on_close is unchanged.

  • GET /v1/instruments/{instrument_id}

Account holder entity kind on accounts

Accounts now report account_holder_entity_kind, which tells you whether the account holder is a person or an organization. The field is always present and is one of:

  • NATURAL_PERSON — the account holder is a person.
  • LEGAL_ENTITY — the account holder is a corporation, partnership, LLC, trust, or fund.
  • OTHER — the account holder is neither, such as a joint or custody UGMA holder.
  • GET /v1/accounts
  • GET /v1/accounts/{account_id}

Market data endpoints report per-id resolution failures

GET /v1/market-data/snapshot and GET /v1/market-data/daily-summary now report which instrument_ids failed to resolve, instead of either failing the whole request or returning a null row.

  • If every requested id resolves, the response is unchanged: 200 with a full data array.
  • If some ids resolve and some do not, the response is 207 with data containing only the resolved instruments, and error set to a message and a structured details list of the failed ids (each entry has an instrument_id field).
  • If no id resolves, the response is 404 with the same error shape and no data.

Previously, GET /v1/market-data/snapshot returned 404 for the whole request if any single id failed to resolve. GET /v1/market-data/daily-summary returned 200 with a row with symbol and every market-data field null for each unresolved id; those rows are no longer returned — unresolved ids are reported in error instead.

  • GET /v1/market-data/snapshot
  • GET /v1/market-data/daily-summary

Overnight session added to market hours

The today_sessions and next_sessions objects returned by GET /v1/market-hours now include an overnight field. This field reports the overnight trading session for the US Equities market: the period from 20:00 ET on the prior evening through 04:00 ET the next morning.

The field follows the same structure as pre_market, regular, and after_hours. It is omitted when no overnight session is available for the requested date (for example, on holidays or for markets that do not support overnight trading).

The status.is_open field is true during the overnight session. The status.current_session field returns "overnight" during this period. The MarketSessionType enum now includes "overnight" as a possible value.

  • GET /v1/market-hours

Partial updates for saved screeners

PATCH /v1/saved-screeners/{screener_id} partially updates a saved screener. Every field is optional.

  • Omitting a field, or sending it as null, leaves the stored value unchanged.
  • Sending a field’s empty value clears it: columns: [] clears the stored columns, sorts: [] clears the stored sort, and filters: [] clears the stored filters.
  • name has no empty value that clears it. name: "" is rejected.
  • shared has no empty value either. shared: false sets it to false; it does not clear anything.
  • Unknown fields are rejected with a 422.

PUT /v1/saved-screeners/{screener_id} is now deprecated. Use PATCH instead. PUT still replaces the full screener configuration: an omitted columns, filters, or sorts field is cleared, not preserved. PUT’s behavior has not changed.

  • PATCH /v1/saved-screeners/{screener_id}
  • PUT /v1/saved-screeners/{screener_id} (deprecated)

Total count removed from news and financial statements

total_items and total_pages are no longer returned in the metadata of the four indicated as affected endpoints.

Use next_page_token to detect whether more results exist. Request the next page while next_page_token is present; stop when it is absent.

  • GET /v1/news
  • GET /v1/instruments/{instrument_id}/income-statements
  • GET /v1/instruments/{instrument_id}/balance-sheets
  • GET /v1/instruments/{instrument_id}/cash-flow-statements

Auction time-in-force values renamed to AT_OPEN and AT_CLOSE

The time_in_force values that select the opening and closing auctions have been shortened to AT_OPEN and AT_CLOSE.

  • Responses report AT_OPEN and AT_CLOSE; the previous AT_THE_OPENING and AT_THE_CLOSE are no longer returned, and the schema documents only the short values.
  • Submissions still accept AT_THE_OPENING and AT_THE_CLOSE as deprecated aliases, so existing integrations keep working. Move to the short values — the aliases will be removed in a future release.
  • POST /v1/accounts/{account_id}/orders
  • GET /v1/accounts/{account_id}/orders
  • GET /v1/accounts/{account_id}/orders/{order_id}

Position instructions: instruction_id renamed to client_instruction_id

The caller-supplied idempotency key on position instructions has been renamed from instruction_id to client_instruction_id, on both the submit request body and the instruction response. Update any requests and response parsing that use the old name.

A submit request that still sends the legacy instruction_id field now returns 400 Bad Request with a migration message, instead of silently ignoring the field and generating a server-side id in its place. The cancel path parameter {instruction_id} is unchanged; it is the server-assigned instruction id, not the caller-supplied key.

  • POST /v1/accounts/{account_id}/positions/instructions
  • GET /v1/accounts/{account_id}/positions/instructions
  • DELETE /v1/accounts/{account_id}/positions/instructions/{instruction_id}

Queued and PendingTrigger order statuses

Order status can now return two new values:

  • QUEUED — accepted by Clear Street and waiting for its scheduled release time.
  • PENDING_TRIGGER — accepted by Clear Street and held until its trigger condition is met, for example a trailing stop that has not yet been hit.

Both previously reported PENDING_NEW, so telling a held order apart from one already sent to the market meant reading queue_state. Orders held from a prior session now also report the correct status once they are loaded back.

queue_state is unchanged and still returned. It does not distinguish a scheduled release from a strategy trigger, so prefer status.

If you parse status into a fixed set of values, add the two new ones.

  • GET /v1/accounts/{account_id}/orders
  • GET /v1/accounts/{account_id}/orders/{order_id}
  • POST /v1/accounts/{account_id}/orders
  • PATCH /v1/accounts/{account_id}/orders/{order_id}
  • DELETE /v1/accounts/{account_id}/orders/{order_id}

Underlying instrument on position instructions, and a filter for it

Position instructions now include the option’s underlying_instrument_id on every response — list, submit, and cancel. The field is the identifier of the option’s underlying instrument, or null when the underlier is not available.

The list endpoint accepts a new underlying_instrument_id query parameter — an instrument id (UUID) or symbol — that returns only instructions whose contract has that underlier. It combines with the existing instrument_id filter as a logical AND.

  • GET /v1/accounts/{account_id}/positions/instructions
  • POST /v1/accounts/{account_id}/positions/instructions
  • DELETE /v1/accounts/{account_id}/positions/instructions/{instruction_id}

Option contracts: lookup by ID and settlement cycle filter

The options contracts endpoint accepts two new query parameters:

  • contract_ids — a comma-separated list of up to 100 instrument IDs or OSI option symbols — fetches specific contracts directly instead of listing a whole underlier’s chain. It’s mutually exclusive with underlier and underlying_instrument_id; unresolvable IDs are dropped rather than erroring.
  • is_settle_on_opentrue returns only early-settling (AM, settle-on-open) contracts, false returns normal (PM) contracts, and omitting it returns both. Contracts with no recorded settlement cycle are treated as PM.
  • GET /v1/instruments/options/contracts

Options expiry dates split by settlement cycle

The instrument endpoint’s option-expiry listing (include_options_expiry_dates=true) now returns options_contract_expiry_dates, an array of {date, has_settles_on_open, has_settles_on_close} entries showing which expiry dates have AM-settled (“settle on open”) vs. PM-settled (“settle on close”) contracts. The existing options_expiry_dates field is deprecated in favor of it; it’s unchanged in shape and still returns the union of both settlement cycles.

  • GET /v1/instruments/{instrument_id}

Order side reduced to BUY/SELL; single orders accept position_intent

The order side contract is BUY / SELL across all submission paths, and single-order submissions accept a new optional position_intent field.

  • SELL_SHORT is no longer accepted as a request side on any submission path; submitting it returns a 400.
  • Responses report short sells as SELL; other legacy sides (for example CROSS / UNDISCLOSED) are reported as OTHER. The schema documents only BUY and SELL.
  • A new optional position_intent field (OPEN / CLOSE) is accepted on single-order submissions. When present it specifies the intended position effect; when omitted, the position effect is determined automatically. There is no response change.
  • The omni OrderSide value SELL_SHORT has been removed. Short-sale orders placed through Omni now use SELL as their side.
  • POST /v1/accounts/{account_id}/orders
  • GET /v1/accounts/{account_id}/orders
  • DELETE /v1/accounts/{account_id}/orders (cancel-all side filter)
  • PUT /v1/accounts/{account_id}/orders/{order_id}

Order/underlier filters and venue on executions

The executions endpoint accepts two new query parameters: order_ids, a comma-separated set matching an execution’s engine or client order ID, and underlying_instrument_ids, a comma-separated set of instrument IDs or symbols (index aliases like SPX/SPXW expand automatically) that matches option fills by their resolved underlier. Each execution also gains optional venue and underlying_instrument_id fields.

  • GET /v1/accounts/{account_id}/executions

Screener field catalog endpoint

The Trading API now exposes a screener field catalog. GET /v1/screener/catalog returns the fields you can screen on (with their kinds, value types, periods, and lookbacks), the enum universes for enum-valued fields, the operators allowed for each value type, and the built-in date variables and modifiers usable in filter right values. It also lists the default response fields for POST /v1/screener.

Field references in POST /v1/screener requests are validated against this catalog, so clients can use it to compose valid screens.

  • GET /v1/screener/catalog

Shared saved screeners

Saved screeners accept a new shared field. It is optional on create and update; omitting it leaves the current value unchanged (a newly created screener defaults to false). When a screener is shared: true, any user may fetch it by id. Saved screeners still only appear in the list response to their owner.

  • POST /v1/saved-screeners
  • GET /v1/saved-screeners
  • GET /v1/saved-screeners/{screener_id}
  • PUT /v1/saved-screeners/{screener_id}

Snapshot change percent rounded to 6 decimal places

The change_percent field in the market-data snapshot session object is now rounded to 6 decimal places.

  • GET /v1/market-data/snapshot

Venue MICs and timestamps added to market data snapshots

GET /v1/market-data/snapshot now reports the venue and exchange timestamp behind each snapshot’s last quote and last trade:

  • last_quote gains bid_venue and ask_venue — the ISO 10383 Market Identifier Code (MIC) of the venue currently holding the national best bid and best offer (NBBO). Each is omitted when that side carries no venue.
  • last_quote gains bid_timestamp and ask_timestamp — the exchange time the best bid and best ask were set. Each is omitted when that side carries no timestamp.
  • last_trade gains venue — the MIC of the venue where the last-sale trade took place — and timestamp — the exchange time of the trade. Index levels are computed rather than traded: they have no venue, and their timestamp is the time the index level was computed.
  • GET /v1/market-data/snapshot

Snapshot session adds unadjusted previous close field

Market-data snapshots add a new optional session.previous_close_unadjusted field carrying the raw previous session close, present only when a corporate-action adjustment (stock dividends, cash dividends, and forward/reverse splits) exists for the previous close date. The existing session.previous_close, session.change, and session.change_percent fields are unchanged: previous_close remains the corporate-action-adjusted close when an adjustment exists for the previous close date and the raw close otherwise, and change/change_percent remain relative to it. This release also corrects the schema examples and field documentation to match that contract. Non-breaking.

  • GET /v1/market-data/snapshot

Deprecated day-trade and total P&L fields removed from balances

The following long-deprecated fields have been removed from the balances response:

  • daily_total_pnl — use daily_pnl instead. The two have always carried the same value; daily_total_pnl existed only to give clients time to migrate.

  • The start-of-day day_trade_buying_power field.

  • The day_trade_buying_power_usage, day_trade_count, and pattern_day_trader fields on margin_details.

  • The day_trade_buying_power_usage field on each margin top-contributor entry.

    The day-trade fields are no longer relevant after FINRA and the SEC removed the pattern-day-trader concept.

  • GET /v1/accounts/{account_id}/balances

Clearer order rejection reasons

Orders rejected by pre-trade risk checks now report plain-English reasons — for example, “Insufficient buying power” instead of “Buying Power: required > available”. The machine-readable codes were also revised: SUB_PENNY is now INVALID_TICK_SIZE, SSR_UPTICK was retired, and LIQUIDATION_ONLY was split into INSTRUMENT_LIQUIDATION_ONLY and ACCOUNT_LIQUIDATION_ONLY. Avoid matching on the human-readable text.

  • POST /v1/accounts/{account_id}/orders
  • GET /v1/accounts/{account_id}/orders/{order_id}

Event defaults anchored to the next trading day

When listing instrument events on a weekend or US market holiday, the default from/to date window is now resolved against the next trading day rather than the calendar date, so upcoming-event queries made over a weekend cover the next session.

  • GET /v1/instruments/events
  • GET /v1/instruments/{instrument_id}/events

Underlier populated for index-option contracts

underlying_instrument_id is now populated on option contracts whose underlier is an index; it was previously null for these contracts.

  • GET /v1/instruments/options/contracts

Account-holder details on Get Account

GET /v1/accounts/{account_id} now returns an enriched account object with the account holder’s reference details. Four new fields are included, each nullable and null when the information is not on file or reference data is unavailable:

  • mailing_address — a structured address (line1, line2, city, state, postal_code, country).
  • date_of_birth
  • phone_number
  • country_of_tax_residency

Existing fields are unchanged; the additions are purely additive.

  • GET /v1/accounts/{account_id}

Instrument fields removed; time-in-force locked on replace

Two removals to be aware of:

  • The long-deprecated expiry and strike_price fields (which had been returning null since 2026-06-17) have been removed from the instrument response. Read option contract details from the options endpoints instead.
  • time_in_force has been removed from the replace-order request body. Time in force can no longer be changed when replacing an order — submit a new order if you need a different TIF.
  • GET /v1/instruments
  • GET /v1/instruments/{instrument_id}
  • PATCH /v1/accounts/{account_id}/orders/{order_id}

Modify action in Omni prefill orders

Omni AI structured “prefill order” cards can now suggest a modify action (PrefillModifyOrderAction) in addition to the existing new-order and cancel-order actions, letting the assistant propose an amendment to a working order.

  • GET /v1/omni-ai/messages/{message_id}
  • GET /v1/omni-ai/threads/{thread_id}/messages

INDEX security type

INDEX is now a valid value in the security-type enum. It appears on instrument responses and is accepted by the instrument_type filter when listing or cancelling orders.

  • GET /v1/instruments
  • GET /v1/accounts/{account_id}/orders
  • DELETE /v1/accounts/{account_id}/orders

Order and fill instrument fields are now nullable

On order and execution (fill) responses, instrument_id, symbol, and (for orders) instrument_type are now nullable and no longer guaranteed present. They are null when an order or fill has no single resolvable instrument. Code that assumes these fields are always populated should add a null check.

  • GET /v1/accounts/{account_id}/orders
  • GET /v1/accounts/{account_id}/orders/{order_id}

Omni entitlements: trading_account_id renamed to account_id

On the Omni AI entitlements endpoint, the trading_account_id query parameter and the matching trading_account_id response field have both been renamed to account_id. Update any requests or response parsing that used the old name.

  • GET /v1/omni-ai/entitlements

Annual financials and earnings report timing

Two additions to instrument data:

  • The fiscal-period enum on fundamentals and financial-statement responses now includes ANNUAL (alongside the existing quarterly periods).
  • Earnings entries in instrument events now carry a nullable report_time field with values BMO (before market open) and AMC (after market close).
  • GET /v1/instruments/{instrument_id}/fundamentals
  • GET /v1/instruments/events
  • GET /v1/instruments/{instrument_id}/events

Symbols accepted more widely; market-hours date optional

Quality-of-life improvements to filtering:

  • instrument_ids and underlying_instrument_ids now accept instrument symbols (equity tickers or OSI option symbols) in addition to UUIDs on order, instrument-event, and market-data snapshot lookups.
  • The date parameter on the market-hours calendar is now optional and defaults to today.
  • GET /v1/accounts/{account_id}/orders
  • GET /v1/instruments/events
  • GET /v1/market-data/snapshot
  • GET /v1/calendars/market-hours

Tradability flag on option contracts

Option contract responses now include a required is_tradable boolean indicating whether the contract is currently tradable.

  • GET /v1/instruments/options/contracts

Clearer index snapshots

For index instruments, the market-data snapshot’s last-trade now reports the current index level in price with size always 0 (an index level is computed, not traded).

  • GET /v1/market-data/snapshot

Index-aware market data and fundamentals

Better handling for instruments that don’t have certain data by definition (for example, an index):

  • The daily-summary response gains a required not_applicable boolean that distinguishes “this instrument type has no daily summary” from “data not yet loaded.”
  • The fundamentals endpoint now returns a 400 for instruments whose type has no fundamentals.
  • GET /v1/market-data/daily-summary
  • GET /v1/instruments/{instrument_id}/fundamentals

position_effect removed from order submission

The position_effect request field (with its OPEN / CLOSE enum), previously required on options orders, has been removed from order submission. Remove it from your order payloads.

  • POST /v1/accounts/{account_id}/orders

Executions filter renamed to instrument_ids

On the executions endpoint, the instrument_id query parameter has been renamed to instrument_ids and now accepts a comma-separated list of instrument IDs or symbols, returning executions matching any of them.

  • GET /v1/accounts/{account_id}/executions

Screener field_filter and option position types removed

Two enum/field removals:

  • The deprecated field_filter property has been removed from the screener request and response schemas. Use columns for field selection instead.
  • The option-specific position types LONG_CALL, SHORT_CALL, LONG_PUT, and SHORT_PUT have been removed from the position type enum. Positions now report only LONG or SHORT.
  • POST /v1/screener
  • POST /v1/saved-screeners
  • GET /v1/saved-screeners
  • GET /v1/saved-screeners/{screener_id}
  • PUT /v1/saved-screeners/{screener_id}
  • GET /v1/accounts/{account_id}/positions

One-sided quotes in snapshots

The snapshot quote fields bid, ask, and midpoint are no longer required and may be null — for example, on a one-sided quote where only a bid or only an ask is present.

  • GET /v1/market-data/snapshot

Idle Omni threads return 200 instead of 404

Requesting the latest response for an idle thread now returns 200 with data: null rather than 404. A 404 from this endpoint now unambiguously means the thread was not found. If you previously treated 404 as “thread is idle,” switch to checking for a null data.

  • GET /v1/omni-ai/threads/{thread_id}/response

Filter accounts by id and name

Listing accounts now supports two optional query filters:

  • account_id — lexicographic prefix match on the decimal account id (e.g. 100 matches 100345 and 100567).
  • account_name — case-insensitive substring match on the account’s full name.

When both are supplied, an account must match both.

  • GET /v1/accounts

Filter orders by order_ids

The order-list endpoint accepts a new order_ids query parameter — a comma-separated set of order IDs — to fetch a specific group of orders in one call.

  • GET /v1/accounts/{account_id}/orders

Instrument expiry/strike_price and screener field_filter

Advance notice of fields being retired:

  • Instrument expiry and strike_price are deprecated and now always return null — read contract details from the options endpoints instead.
  • The screener field_filter request field is deprecated in favor of columns.
  • GET /v1/instruments
  • GET /v1/instruments/{instrument_id}
  • GET /v1/instruments/search
  • POST /v1/screener

Look up instruments by symbol

The instrument_ids filter on the instruments endpoint now accepts symbols (an equity symbol or an OSI option symbol) in addition to instrument UUIDs. Symbols are resolved server-side, so you no longer need a UUID round-trip to filter by ticker.

  • GET /v1/instruments

Screener

The Trading API now exposes a Screener for querying instruments against fundamental and reference criteria, plus the ability to save and reuse screens.

POST /v1/screener runs a structured screen and returns a columnar row/column result. Requests describe the fields to return (columns), filters (with a rich operator set), sorting, and pagination.

Persist a screen and manage it over time:

  • GET /v1/saved-screeners — list your saved screeners
  • POST /v1/saved-screeners — create one
  • GET /v1/saved-screeners/{screener_id} — fetch one
  • PUT /v1/saved-screeners/{screener_id} — replace one
  • DELETE /v1/saved-screeners/{screener_id} — delete one
  • POST /v1/screener
  • GET /v1/saved-screeners
  • POST /v1/saved-screeners
  • GET /v1/saved-screeners/{screener_id}
  • PUT /v1/saved-screeners/{screener_id}
  • DELETE /v1/saved-screeners/{screener_id}

Live P&L on balances and positions

New profit-and-loss fields, computed in real time:

  • Balances gains three required fields: unrealized_pnl (total unrealized P&L across open positions), daily_pnl (total P&L since start of day), and daily_change (current equity vs. start-of-day equity).
  • Each position gains an optional daily_realized_pnl, and the positions sort_by parameter accepts a new DAILY_REALIZED_PNL value.
  • GET /v1/accounts/{account_id}/balances
  • GET /v1/accounts/{account_id}/positions

ENGINE_REJECTED status removed

The ENGINE_REJECTED value has been removed from the position-instruction status enum. Instructions that fail pre-venue validation now report status: REJECTED with a rejection_reason. Note that instructions failing pre-acceptance validation (duplicate instruction_id, DNE/CEA on a non-expiry day, insufficient position, or an unresolvable instrument) are never persisted — they appear only in the submission response, not in the instructions list.

  • POST /v1/accounts/{account_id}/positions/instructions
  • GET /v1/accounts/{account_id}/positions/instructions

Per-session buying power on balances

The margin section of the balances response gains two required objects, intraday_details and overnight_details, each exposing that session’s buying_power and an optional margin multiplier.

  • GET /v1/accounts/{account_id}/balances

Day-trade fields on balances deprecated

Several day-trade fields on the balances response are deprecated and will be removed in a future release:

  • The start-of-day day_trade_buying_power, day_trade_buying_power_usage, day_trade_count, and pattern_day_trader fields.
  • The day_trade_buying_power_usage field on each margin top-contributor entry.
  • GET /v1/accounts/{account_id}/balances

Smarter option search

Instrument search now matches option contracts by OSI prefix — a root plus a YYMMDD expiry (e.g. AAPL 261217) — and by root-scoped phrases such as AAPL Dec 250 call, in addition to full OSI symbols.

  • GET /v1/instruments/search

Richer batch errors, typed deletes, multi-underlier filter

A set of refinements:

  • On position-instruction submissions where every row is rejected, the 400 / 409 / 503 responses now return the full per-row data list (each row carrying its status and rejection_reason) instead of a bare error, and a new 500 response covers an all-rows-rejected internal fault.
  • Delete endpoints now return a typed body (data: null) instead of an untyped empty response.
  • The underlying_instrument_ids order filter now accepts multiple underlier instrument IDs (array) rather than a single value.
  • POST /v1/accounts/{account_id}/positions/instructions
  • DELETE /v1/watchlists/{watchlist_id}
  • DELETE /v1/watchlists/{watchlist_id}/items/{item_id}
  • GET /v1/accounts/{account_id}/orders

Instrument restriction flag and security types removed

Removals to instrument data:

  • The is_restricted field has been removed from instrument and option-contract responses, along with the is_restricted filter on the instruments endpoint and the include_restricted parameter on instrument search.
  • PREFERRED_STOCK and OTHER have been removed from the security-type enum, which is now COMMON_STOCK, OPTION, CASH. This affects the instrument_type order filter and the security-type field on instrument responses.
  • GET /v1/instruments
  • GET /v1/instruments/{instrument_id}
  • GET /v1/instruments/search
  • GET /v1/instruments/options/contracts
  • GET /v1/accounts/{account_id}/orders

Option greeks in snapshots

Market-data snapshots for option instruments now include a greeks object with theo_price, iv, delta, gamma, vega, theta, rho, and a timestamp (per-share values). It is null for equities.

  • GET /v1/market-data/snapshot

Publicly-traded-partnership flag

Instruments now carry a required is_ptp boolean flagging publicly-traded partnerships (PTP sales are subject to 10% withholding for non-US tax residents). Related filters were added too:

  • is_ptp boolean filter on the instruments endpoint.
  • include_ptp on instrument search (default true; PTP instruments are penalized in ranking when included).
  • GET /v1/instruments
  • GET /v1/instruments/{instrument_id}
  • GET /v1/instruments/search
  • GET /v1/instruments/options/contracts

Executions endpoint

A new endpoint returns individual execution reports for an account. Each execution includes id, order_id, symbol, instrument_id, side, quantity, price, and transaction_time, ordered by transaction time (newest first), with instrument_id, from, to, and pagination filters.

  • GET /v1/accounts/{account_id}/executions

Latest Omni messages first

Fetching thread messages now returns the latest page of finalized messages by default (chronological within each page) instead of starting from the earliest message.

  • GET /v1/omni-ai/threads/{thread_id}/messages

Omni AI response format changes

Three changes that affect clients parsing Omni AI content:

  • Ticker references inside message text changed from XML-style tags (<ticker>AAPL</ticker>) to markdown links ([AAPL](ticker:AAPL)).
  • Entitlement request fields were renamed: trading_account_idsaccount_ids and requested_entitlement_codesentitlement_codes.
  • The symbolChart chart-card option and its SymbolChart schema were removed; chart cards now use the series-driven dataChart only.
  • GET /v1/omni-ai/threads/{thread_id}/messages
  • GET /v1/omni-ai/threads/{thread_id}/response
  • POST /v1/omni-ai/entitlements

Fractionable instrument flag

Instruments now include a required is_fractionable boolean indicating whether the instrument supports fractional-quantity orders.

  • GET /v1/instruments
  • GET /v1/instruments/{instrument_id}
  • GET /v1/instruments/search
  • GET /v1/instruments/options/contracts

Instrument type inferred on order submission

The instrument_type request field is no longer required on order submission — the security type is now inferred from the instrument you reference.

  • POST /v1/accounts/{account_id}/orders

Last-trade size in snapshots

The last_trade object in market-data snapshots gains a required size field — the share quantity of the most recent last-sale-eligible trade.

  • GET /v1/market-data/snapshot

Documented position-instruction lifecycle

The full lifecycle-status model for position instructions is now documented: SENT, ACCEPTED, REJECTED, CANCEL_REQUESTED, CANCELLED, CANCEL_FAILED, and UNKNOWN, along with typical rejection causes (duplicate instruction_id, DNE/CEA on a non-expiry day, insufficient position, unresolved instrument).

  • POST /v1/accounts/{account_id}/positions/instructions
  • GET /v1/accounts/{account_id}/positions/instructions

Batch position instructions and reporting currency

Two additions:

  • Batch submission semantics for position instructions are now defined: all rows accepted returns 200; partial success returns 207 (Multi-Status) with rejected rows carrying a rejection_reason; and all-rejected returns a 4xx/5xx (409 duplicate instruction_id, 400 validation failures, 503 clearing unavailable).
  • A nullable reporting_currency field was added to instrument events, analyst-reporting, and fundamentals responses.
  • POST /v1/accounts/{account_id}/positions/instructions
  • GET /v1/instruments/events
  • GET /v1/instruments/{instrument_id}/analyst-reporting
  • GET /v1/instruments/{instrument_id}/fundamentals

Top-level error removed from position instructions

The separate top-level error field has been removed from the position-instruction response object. Per-row rejection detail is now carried in each row’s rejection_reason.

  • POST /v1/accounts/{account_id}/positions/instructions
  • GET /v1/accounts/{account_id}/positions/instructions

Partial portfolio-history results

Portfolio history can now return a 207 (partial success) when one side of the fetch fails, delivering the available segments alongside a top-level error describing the portion that failed.

  • GET /v1/accounts/{account_id}/portfolio-history

Bidirectional pagination

page_token now supports paging backward as well as forward: a token can retrieve the next or the previous page of results. This applies to all paginated list endpoints (orders, executions, positions, instruments, events, news, Omni threads and messages, watchlists, and more). No request changes are required.

  • GET /v1/accounts/{account_id}/orders
  • GET /v1/instruments
  • GET /v1/news
  • GET /v1/omni-ai/threads/{thread_id}/messages

Initial release

First release of the Clear Street Trading API — a unified REST API covering order management, positions, market data, and account services.

  • Accounts — list and fetch accounts, update account settings, and read balances and portfolio history.
  • Orders — submit, list, fetch, replace, and cancel orders. Sides BUY, SELL, and SELL_SHORT; order types MARKET, LIMIT, STOP, and STOP_LIMIT; with support for trailing stops and extended-hours sessions.
  • Positions — list positions, close positions, and manage position instructions.
  • Instruments — look up and search instruments, list option contracts, and read corporate-action events.
  • Instrument data — fundamentals, income statements, balance sheets, cash-flow statements, analyst reporting, and news.
  • Market data — real-time snapshots and daily summaries.
  • Calendar — market clock and market-hours calendar.
  • Watchlists — create and manage watchlists and their items.
  • Omni AI — threads, messages, responses, feedback, and entitlements for Clear Street’s financial AI assistant.

See Get Started to make your first call.