HTTP Streaming
HTTP Streaming involves opening an HTTP connection that does not close. Instead, data is continually transmitted to the HTTP client in “chunks” which can be parsed and processed. The value of an HTTP stream (as opposed to a raw TCP or binary stream) is the inherent convenience of using a well-established protocol, built-in encryption, and battle-tested clients that are readily available.
Note: the HTTP stream delivers JSON objects sent as HTTP response body chunks (Content-Type: application/json) over a single long-lived connection — it is not Server-Sent Events (SSE, text/event-stream). Do not use a browser EventSource client to consume this stream, since EventSource expects the text/event-stream format; instead, use an HTTP client capable of reading a chunked response body incrementally and parse each JSON chunk as it arrives.
As long as data is flowing across the HTTP connection, the request will stay open. If you’re streaming very inactive symbols and don’t receive data for 15 minutes, the session will close automatically. It is critical to implement reconnection logic into your streaming interface, since many things can cause an HTTP connection to close.
Stream market updates using HTTP streaming. You will receive a different payload depending on the market event that occurred (quote, trade, summary, timesale, or tradex) — details about each event’s fields are in Streaming Market Data.
Note: in order to stream data, you must first create a streaming session via Create Market Session. Upon receiving a sessionid, you have up to 5 minutes to connect to a streaming endpoint before the session expires.
Note that streaming uses a different host than the rest of the API: https://stream.tradier.com
For HTTP streaming, you can use either GET or POST to initiate a stream. GET is more concise and works well for a shorter symbol list; POST allows a longer list of symbols in the request body. Both return the same streaming data.
GET
GET https://stream.tradier.com/v1/markets/eventsHeaders
Accept | Optional | application/json, application/xml | application/xml |
Authorization | Required | Bearer <API_TOKEN> | N/A |
Unlike the rest of this API, the streaming endpoint's default Accept value is application/xml, not JSON. If you want JSON responses, pass Accept: application/json explicitly.
Query Parameters
symbols | string | Yes | "AAPL,TSLA250815C00150000" | N/A |
sessionid | string | Yes | "9D1C7018CFEB6F8ECF8CAA58B33" | N/A |
filter | string | No | "trade,quote,summary,timesale,tradex" | All payload types |
linebreak | string | No | "true" | "false" |
validOnly | string | No | "true" | "true" |
advancedDetails | string | No | "true" | "false" |
Code Example
import json
import requests
headers = {'Accept': 'application/json'}
payload = {'sessionid': 'SESSION_ID', 'symbols': 'SPY', 'linebreak': True}
r = requests.get('https://stream.tradier.com/v1/markets/events', stream=True, params=payload, headers=headers)
for line in r.iter_lines():
if line:
print(json.loads(line))
Return Example
{"type": "quote", "symbol": "SPY", "bid": 281.84, "bidsz": 60, "bidexch": "M", "biddate": "1557757189000", "ask": 281.85, "asksz": 6, "askexch": "Z", "askdate": "1557757190000"}
{"type": "trade", "symbol": "SPY", "exch": "J", "price": "281.85", "size": "100", "cvol": "27978993", "date": "1557757190000", "last": "281.85"}
{"type": "summary", "symbol": "SPY", "open": "282.42", "high": "283.49", "low": "281.07", "prevClose": "288.1"}
{"type": "timesale", "symbol": "SPY", "exch": "Q", "bid": "282.08", "ask": "282.09", "last": "282.09", "size": "100", "date": "1557758874355", "seq": 352795, "flag": "", "cancel": false, "correction": false, "session": "normal"}
{"type": "tradex", "symbol": "SPY", "exch": "J", "price": "281.85", "size": "100", "cvol": "27978993", "date": "1557757190000", "last": "281.85"}
Note: the flag field on timesale events reports exchange trade-condition codes; the standard example payload shows it empty (no special condition on that tick). The full set of possible values is exchange-defined (SIP/UTP trade condition codes) rather than published in this documentation — treat it as an opaque pass-through string and match against the specific values you observe/need to handle.
POST
POST https://stream.tradier.com/v1/markets/eventsSame headers and parameters as GET above, sent as form fields in the request body instead of the query string. Same return shape.
On this page
- HTTP Streaming