Brokerage API ## Sections • [Overview](https://staging-docs.tradier.com/overview.md): Build on Tradier The Tradier API gives you direct access to a real brokerage for US stocks, ETFs, and options. You can pull real-time quotes, option chains with Greeks, and historical data. You can place everything from a simple equity order to a four-leg options spread or an OTOCO bracket, and preview every order before it goes out. Stream live quotes, trades, and account events over WebSocket or HTTP, or connect the Tradier MCP server to work with your account from Claude, ChatGPT, or Cursor. Every Tradier Brokerage account includes a paper trading sandbox, so you can build and test with no money at risk before you go live, and API access is included with your account at no extra charge. Get a Tradier Account Sign up today to get your API tokens and get started developing Start here I'm building for my own account Use the API token from your account's API Settings page. No OAuth needed. Start in the sandbox, then switch the base URL and token to go live. → Get Started I'm building an app for other Tradier users Public or distributed apps require Tradier Partner status and use the OAuth 2.0 Authorization Code flow. Contact sales@tradier.com to get started. → Contact us I want to use Tradier with AI Point your coding assistant at llms.txt, or connect the Tradier MCP server to Claude, ChatGPT, Cursor, and other MCP clients to work with your account in natural language. → Using AI I'm an RIA or platform operator The Advisor API adds account opening, ACH funding, documents, and multi-account data for registered advisors. → Advisor API What you can build Accounts Profile, balances, historical balances, order history, account activity, and gain/loss reports. Market Data Quotes, option chains, strikes, expirations, and Greeks, historical bars, time and sales, market clock and calendar, symbol search. Trading Equity, option, multileg, and combo orders, plus OCO, OTO, and OTOCO. Preview any order before sending it. Streaming Real-time quotes, trades, time and sales, and account events over HTTP streaming or WebSocket. Watchlists Create and manage symbol lists tied to the account. Positions Current positions and custom position groups. Environments Production Sandbox REST base URL https://api.tradier.com/v1/ https://sandbox.tradier.com/v1/ Market data Real-time (some index data delayed 15 min) Delayed 15 minutes Orders Live Orders: Equities, Options, ETFs Paper trades (filled against delayed data) Futures Not Available Not Available Tokens - Tokens are environment-specific. A sandbox token sent to api.tradier.com (or a production token sent to sandbox.tradier.com ) returns 401 . Quickstart Open a Tradier Brokerage account: Sign up today Copy your tokens: Find your production and sandbox tokens on your API Settings page ( web.tradier.com/user/api ). Make a request: Get a quote: Bash curl -X GET "https://api.tradier.com/v1/markets/quotes?symbols=AAPL" \ -H "Authorization: Bearer <API_TOKEN>" \ -H "Accept: application/json" Ready for more? Walk through placing an order, starting a market data stream, or pulling time and sales in Code Examples in each dedicated section of our documentation. Before you build Your token is full account access. Personal tokens don't expire until you regenerate them. Treat them like passwords and never commit them to a repository. Check order status after placing. The place-order endpoint can return `200` even when a downstream system rejects the order. Confirm with Get Single Order and inspect the status. Normalize arrays in JSON. A list with a single item can come back as a bare object instead of a one-element array. Rate limits return `400`, not `429`. Detect the `Quota Violation` body and use the `X-Ratelimit-*` headers to throttle. For quotes that change constantly, stream instead of polling. → Rate Limits Scope and coverage US equities, ETFs, and options only Market data is a consolidated feed. Level 1 (top-of-book) data only; no Level 2 / depth of book. Historical data isn't available for expired options. Pre- and post-market orders supported (07:00-09:24 and 16:00-19:55 ET) Without Partner status, API access is for personal use only; OAuth and token access scoping is only for partner applications. Any language that can make HTTPS requests works. Browser apps can call the REST APIs directly because CORS is supported (except OAuth exchanges). Resources API Explorer Try any endpoint with your own token. Download the OpenAPI spec Generate clients or import into your tooling. Download the spec from any API page. Libraries and open source Community SDKs for Python, .NET, C++, and more (not maintained by Tradier). API status Check current system status. Need help? Send the full request with parameters (never include your token) and the full response body to techsupport@tradier.com. For partnership or Advisor API inquiries, contact sales@tradier.com. • [Endpoints](https://staging-docs.tradier.com/overview/endpoints.md): Our endpoints require SSL encryption (TLS 1.2) and SNI support. Each endpoint corresponds to a particular product or service. All requests should be made using HTTPS. The Tradier API has two environments for our users to utilize. The production environment is for trading and real-time market data related to your live account. The sandbox is a paper trading account to test your integration with our API, including working with delayed market data and paper trades. All Tradier users are issued API tokens for both their live and sandbox accounts, both of which can be retrieved from your account API settings . Brokerage API (Live) You must have a Tradier Brokerage account , be a Tradier Partner , or a Tradier Advisor to use these APIs. Request/Response Calls such as those for quotes, account details, or trades will utilize this URL as a base: https://api.tradier.com/v1/ Streaming Streaming live data such as trades, quotes, etc, will utilize this URL: https://stream.tradier.com/v1/ Sandbox API Primarily used for paper trading accounts, you must sign up for a Tradier Brokerage account and create a paper trading access token to use these APIs. Request/Response https://sandbox.tradier.com/v1/ CORS Support All Brokerage APIs (except OAuth exchanges) support CORS requests. That means you can make requests directly from a web browser without requiring a backend service. For more information about CORS and how you can use it in your applications, see the links below: enable-cors.org MDN HTTP CORS Versioning Tradier's API is set up to be versioned via a path parameter. Versioning is something we'll use at our discretion and we'll communicate adequately in advance of breaking-changes or sunsetting versions. Some fundamental market data APIs may be offered in beta; where that applies, it is called out on that endpoint's individual documentation page rather than at a single dedicated beta base URL. • [Authentication](https://staging-docs.tradier.com/overview/authentication.md): For individual users, your API tokens (Live and Sandbox) are all you need to get started. With your tokens, which you can retrieve from the API Settings page on web.tradier.com , you can work directly with API calls, including those that you can run right from the API explorer in these docs. Individual developers do not need OAuth, your token is full access to your account from the moment it is created. As API tokens are full access and permanent until you regenerate a token, they should be treated like passwords and never shared with anyone, any application, or posted to any public repo. If you need to regenerate a token and invalidate your current one for any reason, you can do so on the API Settings page in your live profile on the web dashboard. If you have any questions, please reach out to techsupport@tradier.com Partner Applications and Connection: OAuth 2.0 The Tradier API uses OAuth 2.0 for authentication and authorization. We support the Authorization Code flow (server-side application), which provides secure access to trading accounts and market data. For an individual developer working on applications and algorithms for their use, OAuth is not necessary; all API calls can be made with your API Token (or Sandbox Token) found in your API Settings . If you are working on an application for public release, please reach out to our team at sales@tradier.com about becoming a Tradier partner. Overview OAuth 2.0 is a straightforward protocol that allows developers to integrate with Tradier's endpoints using standard client libraries. Once you are accepted as a Tradier partner, you will be invited to our partner developer portal, where you can register and maintain an application with us. The authentication process involves: Register your application with Tradier to get your clientID and clientSecret Redirect users to our authorization URL, where they will approve scopes for your application Parse the authorization code from the callback Exchange the authorization code for an access token Use the access token to make API requests Token Types and Lifespans Authorization Codes Lifespan : 10 minutes Purpose : Short-lived codes are provided after user authorization Usage : Exchanged for access tokens Access Tokens (Bearer Tokens) Lifespan : 24 hours Purpose : Used to authenticate API requests Usage : Include in the Authorization header as Bearer {token} Renewal : Must exchange a new authorization code when expired Refresh Tokens Lifespan : Do not expire Purpose : Generate new access tokens without user re-authorization Availability : Only available to approved Tradier Partners Approval : Contact techsupport@tradier.com to request access Authentication Flow Step 1: Get Authorization Code Required Parameters: client_id : Your application's client ID scope : Requested permissions (e.g., read , trade ) state : Random string for security validation Note: redirect_uri is not sent as a URL parameter in this request. Your redirect URI must be pre-registered with your application during the partner onboarding process; Tradier will redirect to that pre-registered URI after authorization. Scopes Scopes control the level of access granted to your application: **read** : Read access to account information, positions, and market data **write** : Write access to account data (does not include placing or updating trades) **market** : Access market data (does not include streaming) **trade** : Permission to place and manage trades **stream** : Access to real-time streaming data Users will be prompted to approve the requested scopes during authorization. Example Authorization URL: Plain text https://api.tradier.com/v1/oauth/authorize?client_id={clientId}&scope={scopes}&state={state} https://api.tradier.com/v1/oauth/authorize?client_id={clientId}&scope={scopes}&state={state} Response Since this call should be made in a browser, a successful response will be a 302 redirect to Tradier Brokerage’s website where the user can log in and authorize. Step 2: Handle Callback If the user authorizes your application, a call will be made to the callback URL registered with your application. That callback will look something like: Plain text http://your-callback-url.com?code={authorization_code}&state={state} http://your-callback-url.com?code={authorization_code}&state={state} code - Your authorization code state - The same unique string you sent in the request above Note: The reason the state is sent back to you is to make sure no-one is tampering with this exchange. If it’s different than the original you should abort the exchange and start over If everything checks out, you’ve got an authorization code you can exchange for an access token (Congrats!). This code expires in 10-minutes so be sure to move on to the next step efficiently. Step 3: Exchange Code for Access Token Make a POST request to exchange the authorization code: Plain text POST https://api.tradier.com/v1/oauth/accesstoken POST https://api.tradier.com/v1/oauth/accesstoken Authentication : HTTP Basic Authentication Your client ID Your client secret *You will need to base64 encode your clientID and clientSecret as clientID:clientSecret * Headers: Plain text Authorization: Basic {base64_encoded_credentials} Content-Type: application/x-www-form-urlencoded Accept: application/json Authorization: Basic {base64_encoded_credentials} Content-Type: application/x-www-form-urlencoded Accept: application/json Body Parameters: grant_type : Set to authorization_code code : The authorization code from Step 2 Example Request: Bash curl -X POST https://api.tradier.com/v1/oauth/accesstoken \ -H "Authorization: Basic {base64_credentials}" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code&code={auth_code}" Example Response: See the Access Token response reference for the full JSON response shape ( access_token , refresh_token , scope , issued_at , status , expires_in ). Step 4: Use Access Token Include the access token in API requests: Plain text Authorization: Bearer {access_token} Authorization: Bearer {access_token} Example API Request: Bash curl -X GET "https://api.tradier.com/v1/user/profile" \ -H 'Authorization: Bearer <TOKEN>' \ -H 'Accept: application/json' Refresh Token Flow (Partners Only) If you have refresh token access, you can obtain new access tokens without user re-authorization: Plain text POST https://api.tradier.com/v1/oauth/refreshtoken POST https://api.tradier.com/v1/oauth/refreshtoken Authentication : HTTP Basic Authentication (same as access token exchange) Body Parameters: grant_type : Set to refresh_token refresh_token : Your refresh token Example Request: Bash curl -X POST https://api.tradier.com/v1/oauth/refreshtoken \ -H "Authorization: Basic {base64_credentials}" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=refresh_token&refresh_token={your_refresh_token}" Example Response: Returns the same response shape as the initial token exchange — see the Access Token response reference for full field definitions. Security Best Practices Protect Access Tokens : Treat access tokens like passwords - never expose them in client-side code Validate State Parameters : Always verify the state parameter to prevent CSRF attacks Use HTTPS : All OAuth exchanges must use secure connections Store Secrets Securely : Keep client secrets in secure server-side storage Monitor Token Expiration : Implement proper token refresh logic Support For technical questions or to request refresh token access: Email : techsupport@tradier.com Partners : Access OAuth credentials through your organization's dashboard • [Rate Limits](https://staging-docs.tradier.com/overview/rate-limits.md): We implement rate limiting to make sure the API is responsive for all customers. The rate limits are set in a way to provide substantial functionality while trying to stifle abuse. Most times, a rate limit can be subverted by implementing a different API call or leveraging other API features (i.e., instead of polling for quotes, leverage the streaming API). How Rate Limits Work Two pieces of information to understand as it pertains to our limits: Interval: we aggregate limits over 1-minute intervals starting with the first request and reset 1 minute later Limit: this can vary (see categories below) For example: With a rate limit of 120 requests per minute, if you make a /quotes request every second for a minute, you would still have 60 requests left in that minute before hitting the limit. Should you be concerned about rate limits? Probably not. Polling for data, while not the best solution, is reasonably supported by our APIs. The limits exist with enough headroom to get up-to-date data and still have room to make other requests. The best way to know if your application will hit the limits is to build it and scale back. Limits Each limit is enforced by the minute and on a per-access-token basis. As such, the limits are enforced on a per-app and per-user basis. Standard This includes resources in /accounts, /watchlists, /users and /orders. This does NOT include placing orders. Production: 120 requests per minute. Sandbox: 60 requests per minute. Market Data This includes resources in /markets. Production: 120 requests per minute. Sandbox: 60 requests per minute. Trading This includes all resources in the “trade” scope. Production: 60 requests per minute. Sandbox: 60 requests per minute. Headers With each request that has a rate limit applied, a series of headers will be sent in the response. These headers should help you to gauge your usage and when to throttle your application. For example: Plain text X-Ratelimit-Allowed: 120 X-Ratelimit-Used: 1 X-Ratelimit-Available: 119 X-Ratelimit-Expiry: 1799200800000 X-Ratelimit-Allowed: 120 X-Ratelimit-Used: 1 X-Ratelimit-Available: 119 X-Ratelimit-Expiry: 1799200800000 Too Many Requests Confirmed via live testing: exceeding a rate limit does not return the conventional 429 Too Many Requests status. Instead, the API returns an HTTP 400 status with a plain-text (non-JSON) body: Plain text Quota Violation: Expires <epoch-ms-timestamp> Quota Violation: Expires <epoch-ms-timestamp> The Expires value is an epoch-millisecond timestamp, matching the semantics of the X-Ratelimit-Expiry header documented above. Note the response's Content-Type header for this case is plain/text (as actually returned by the API — this is a non-standard MIME type; the conventional value would be text/plain ). Since the status code doesn't match the documented 429, check for the literal substring Quota Violation in the response body — rather than relying on the HTTP status code alone — to reliably detect that a request was rejected for exceeding a rate limit. This was confirmed via live testing against the Market Data category ( /markets/quotes ) in production, using multiple concurrent clients in a tight loop with no delay between requests. • [Response Format](https://staging-docs.tradier.com/overview/response-format.md): Tradier supports a couple of different response formats. The way you should request a specific format is by using the standard HTTP header Accept. JSON JSON is the recommended and default format for the Tradier API. JSON format is lightweight and readable. You should use the following Accept header to get JSON: 'Accept: application/json' JSON format is supported through XML to JSON translation. Due to this conversion, there is a known issue where responses can change shape depending on the data, specifically for arrays: a field that normally returns a list of items may instead be returned as a single, bare object (rather than a one-element array) when there is only one item to return. For example, with two items the field looks like this: JSON { "orders": { "order": [ { "id": 123, "symbol": "AAPL" }, { "id": 456, "symbol": "MSFT" } ] } } But with only one item, the same field can be returned as a bare object instead of a one-element array: JSON { "orders": { "order": { "id": 123, "symbol": "AAPL" } } } Recommendation: always normalize the value to an array (e.g., wrap a bare object in a single-element array) before iterating over it, rather than assuming the field is always an array. XML XML is also supported due to its historical use in the financial space. You can use the following Accept header to get XML: 'Accept: application/xml' Note: XML format is deprecated in favor of JSON. New integrations should use JSON. Compression All APIs support GZip compression if sending the appropriate headers. For example: Accept-Encoding: gzip • [Error Responses](https://staging-docs.tradier.com/overview/error-responses.md): HTTP Status Codes API responses will yield appropriate status codes in most circumstances (see Order Related Errors below). In this case, if you receive a 400 response, you can check the body of the response and find an error message that will help decipher the error. In the event of a 401 response, this is related to authentication and entitlement. Make sure that you’re using the correct credentials and endpoint for your access. 500 errors typically mean that something isn’t working properly with the API. Please let us know by emailing techsupport@tradier.com . Title Description Code Meaning 200 Success - The server has received your properly formatted call and acknowledged 400 Bad Request - something in the URL or parameters is wrong. Also confirmed to be returned, with a plain-text "Quota Violation" body, when a rate limit is exceeded; see Rate Limiting for details. 401 The token is incorrect, you're missing 'Bearer', or you are trying to use a sandbox token with api.tradier.com/v1 or inverse sandbox.tradier.com/v1 with a production token 403 Access denied to the requested resource 404 Resource not found, you likely are using a URL for an endpoint that doesn't exist or have a typo in your call URL 429 Too Many Requests - the conventional meaning of this code. Note: live testing has confirmed that exceeding a rate limit on this API actually returns a 400 status with a plain-text "Quota Violation" body rather than 429; see Rate Limiting for details. 5XX Tradier/Server side errors, please reach out to techsupport@tradier.com Order Related Errors Presently, the place order API sends back a 200 response for any error that is thrown by downstream systems (risk management systems, market centers, etc). The process to check the order’s status is to use the GET an order endpoint, which will have a response body that will include an errors property with details about the error. This is most likely to occur on complex order placement, order modification, and order cancellation. In the event you receive this errors payload, it will typically include a description of the problem. In the event you receive an error code, here is a mapping table for errors you can expect: Title Description Code Description AccountDisabled Account is disabled for trading. Please contact 980-272-3880 for questions or concerns. AccountIsNotApproved Account is not approved for trading. Please contact 980-272-3880 for questions or concerns AccountMarginRuleViolation Margin rules prohibit this transaction. Please contact 980-272-3880 for questions or concerns AssetTradingNotConfiguredForAccount The order requested is not available for your account. Please contact 980-272-3880 for questions or concerns BuyStopOrderStopPriceLessAsk Buy Stop order must have a Stop price greater than the current Ask price ContingentOrderExecution Placement Condition: when {symbol} {order_type} is {condition} than {price} ExpirationDateUndefined Expiration date for option is not defined IncorrectOrderQuantity Quantity should be between 1 and 10,000,000 IncorrectTimeInForce Time In Force (Day or GTC) is not defined IndexOptionsOneExparyDate Multi Leg Orders with Index options must have all legs within 1 expiration date. Time spreads are not allowed on Index Options InitialMargin You do not have enough buying power to open this position (insufficient initial margin for this trade) InvalidOrderExpiration Expiration date must be greater than the current date LimitPriceUndefined Limit price is not valid. Please check the price entered LongOptionTradingDeniedForAccount Account is restricted for option trading. Please contact 980-272-3880 for questions or concerns LongPositionCrossZero Sell order is for more shares than your current long position; please review current position quantity along with open orders for security. MaintenanceMargin You do not have enough equity to keep this position open (insufficient maintenance margin to hold the position) MarketOrderIsGtc You cannot place market orders with GTC; only day orders are allowed OcoExpirationTypeNotTheSame Expiration type of OCO orders must be the same OcoOrderWithOppositeLegs You cannot place an OCO order with orders for the same security and with opposite trade direction OcoPriceDifferenceIsLessThanDelta OCO price difference should be at least $0 OmsInternalError Your order could not be processed. Please contact 980-272-3880 for questions or concerns OmsUnavailable Trading services are not available online currently; please contact 980-272-3880 for order requests OptionLevelRestriction Your account does not have the option level permission for this trade. Please contact 980-272-3880 for questions or concerns OptionTypeUndefined Type of option (call or put) is not defined OrderContingentChangeNotAllowed Change of order's contingent is not allowed OrderIsNotAllowedForAccount Order is not allowed. Account trading restriction: closing orders only OrderPriceIsInvalid Price of {price} {order_type} order is {condition} than market price OrderQuantity You cannot place orders with quantity less than 1 OrderWithDifferentSide You cannot have pending orders with different sides for selected symbol where one is a MARKET order. You must close another pending order in order to place a SHORT order, or try a limit order instead OtoFirstLegIsMarketNotAllowed First market order in OTO is not allowed OtoOcoMarketNotAllowed OCO market orders are not allowed OtoOcoTrailingNotAllowed OTO/OCO trailing orders are not allowed QuotePriceIsInvalid There is no quote for the symbol requested, please contact 980-272-3880 to place the order. SecurityUndefined Symbol does not exist. Please contact 980-272-3880 for questions or concerns SellShortOrderLastPriceBelow5 Sell Short order cannot be placed for stock priced below $5 SellStopOrderStopPriceGreaterBid Sell Stop order must have a Stop price less than the Bid price ShortOptionTradingDeniedForAccount Account is restricted for option trading. Please contact 980-272-3880 for questions or concerns ShortOrderIsGtc You cannot place short stock orders with GTC, only day orders are allowed ShortPositionCrossZero Buy order is for more shares than your current short position, please review current position quantity along with open orders for security. ShortStockTradingDeniedForAccount Account is restricted from short sales. Please contact 980-272-3880 for questions or concerns ShortTradingDeniedForSecurity This symbol is not available for short sales. Please contact 980-272-3880 for questions or concerns SpreadTradingDeniedForAccount Account is restricted for spread trading. Please contact 980-272-3880 for questions or concerns StopPriceUndefined Stop price is not defined StrikePriceUndefined Strike price for option leg is not defined TooSmallEquityForDayTrading Pattern Day Trader Rule violation: Equity balance fell below $25,000 TotalInitialMargin You do not have enough buying power for this trade when combined with the total initial margin required across all legs/positions in the order TradeNonStandardOptions You cannot place an order with non-standard options TradingDeniedForAccount Account is restricted for trading. Please contact 980-272-3880 for questions or concerns TradingDeniedForSecurity This asset class is restricted for trading UnexpectedBuyOrder Buy order cannot be placed to cover short position; order must be placed as a Buy to Cover UnexpectedBuyOrderOption Buy To Open order cannot be placed to close a short option position; order must be placed as a Buy to Close UnexpectedBuyToCoverOrder Buy To Cover order cannot be placed unless closing a short position; please check open orders. UnexpectedBuyToCoverOrderOption Buy To Close order cannot be placed unless closing a short option position; please check open orders. UnexpectedSellOrder Sell order cannot be placed unless you are closing a long position; please check open orders. UnexpectedSellOrderOption Sell to Close order cannot be placed unless you are closing a long option position; please check open orders. UnexpectedSellShortOrder Sell short order cannot be placed while you have a current long position; please check open orders. UnexpectedSellShortOrderOption Sell to Open order cannot be placed while you have a current long option position; please check open orders. UserDisabled Account is disabled for trading. Please contact 980-272-3880 for questions or concerns WashTradeAttempt You are unable to place orders on the same security and same price in different directions Additional Error Messages Note: The entries below do not have a distinct error code associated with them in this repo; they are matched by their message text rather than by a numeric or string code. Error Message Description Pre-market trading is currently unavailable. Tradier Brokerage does not accept opening orders for OTC-BB and Pink Sheet securities. Please contact us at (980)-272-3880 if you have any questions. Due to price volatility, a limit order must be placed. Outside of market hours, this order is required to be placed at a limit price. Order failed PriceRange - AGGRESSIVE: OrderPrice 1 RefPrice 2 Limit 3 aggressive • [Libraries and Open Source](https://staging-docs.tradier.com/overview/libraries-and-open-source.md): OAuth omniauth-tradier An Omniauth strategy used to connect to the Tradier API. passport-tradier A Passport strategy used to connect to the Tradier API. Clients LumiBot Lumibot is a fast library that will allow you to easily create trading robots for many different asset classes, including Stocks, Options, Futures, FOREX, and more. ( documentation ) lumiwealth-tradier A Python package that serves as a wrapper for the Tradier brokerage API, simplifying the process of making API requests, handling responses, and performing various trading and account management operations. ( documentation ) uvatradier A Python wrapper for the Tradier API built by Tom Hammons and students at the University of Virginia ( documentation ) python-tradier Python client for the Tradier API. TradierClient .NET API Client for Tradier API AndroidTradier Android wrapper library for the Tradier API PyTradier A Python library for interfacing with Tradier.com's trading API ( documentation ) tradier-dotnet-client Modern .NET API Client for Tradier API ( documentation ) libTradier A modern C++ library for the Tradier API, providing comprehensive access to market data, trading, account management, and real-time streaming. ( documentation ) If you have built (or are thinking of building) a library that interfaces with the Tradier API, let us know so we can list it on this page for others to use. Thanks! These libraries are not presently supported or endorsed by Tradier. They are provided as-is and the use of which is solely at the user's discretion. • [FAQ](https://staging-docs.tradier.com/overview/faq.md): Here are some of the most frequently asked questions to service and support representatives of the Tradier API. If you have a question and can't find your answer here, feel free to reach out to us using email at techsupport@tradier.com . Can I access streaming in the paper trading environment? Presently, we do not offer a delayed streaming endpoint for paper trading. Can I distribute my application? Unless you are a Tradier Partner, Tradier APIs are intended for personal use only. If you would like to become a Tradier Partner, please contact us using our contact form . Do you get data from foreign exchanges? We presently support US-based equities and options data only. This includes US-based ETFs. Do you offer Level 2 data? We offer Level 1 data only. Do you offer extended hours market trading? Yes, you can send pre- or post-market orders to trade during pre/post market sessions. How much is the data delayed in the sandbox? We delay our market data by the industry standard 15 minutes for all sandbox data. In the production environment, some index data is also subject to the 15-minute delay. I am getting an error from the API. Can you help? Yes, we can! However, most error messages from our API are descriptive enough to give you an idea of what's going on. If you want us to take a look, please send the error response and the API request URL to techsupport@tradier.com . Tokens expire in 24 hours, but I need continuous access. That is only the case for access tokens that our partner integrations use. If you are an individual user getting your API token from your settings page ( https://web.tradier.com/user/api ) your tokens never expire. For partners using OAuth this is the case, but if you need continuous access without a user continually authorizing your application, we can enable refresh tokens for your application. There is an approval process, so please email techsupport@tradier.com . What does it cost to use your API? We don't charge Tradier Brokerage account holders for API access to their account. What does this error mean: 'invalid api call as no apiproduct match found'? Most likely, you're either attempting a call to an API endpoint that does not exist or a production API endpoint with a paper trading access token. In either case, check the API call you're making for a valid URL and token. Where can I find my OAuth key/secret? If you're a Tradier Partner, you can find this information on your organization dashboard in the developer portal. If you're a Tradier Brokerage user, OAuth is not enabled for this type of API access as it is available for personal use only. Where is paper trading? All Tradier Brokerage account holders can create a paper trading account from the WebUI account drop-down, or via the API by using the prefix sandbox.tradier.com/v1 with any endpoint. Will you increase the rate limits for my application? Most likely not. The rate limits have proven to be loose enough to promote innovation without being too restrictive. Will your API work with my programming language? If your language can make HTTP requests, it can connect to the Tradier API. • [Brokerage API](https://staging-docs.tradier.com/getting-started.md): Welcome to the Tradier API! We're excited to help you build powerful trading applications and integrate market data into your projects. Whether you're creating a personal portfolio tracker, building algorithmic trading strategies, or developing the next great fintech application, our API provides the tools you need to succeed. What You Can Do The Tradier API opens up a world of possibilities for developers. Here are some of the key capabilities you'll have access to: Market Data & Analytics - Get real-time and historical stock quotes - Access options chains and pricing data - Stream market data directly Account Management - View account balances and buying power - Check current positions and holdings - Review trading history and performance Trading Operations - Place buy and sell orders for stocks and ETFs - Execute complex options strategies - Set up advanced order types like stop-loss and bracket orders Quick Start in 2 Easy Steps Getting started with the Tradier API is straightforward: Step 1: Create Your Account Head over to https://tradier.com and sign up for your free account. You'll get access to both live trading and our paper trading sandbox environment - perfect for testing your applications without any financial risk. Step 2: Get Your API Token Once your account is set up, visit the API Settings page: [https://web.tradier.com/user/api](https://web.tradier.com/user/api) to generate your API tokens: - Production Token: For live trading and real market data - Sandbox Token: For testing and development with paper trading That's it! With your token in hand, you're ready to start making API calls and building amazing applications. Your First API Call Here's a simple example to get you started - fetching a stock quote. Just replace `<TOKEN>` with your production token: Bash curl -X GET "https://api.tradier.com/v1/markets/quotes?symbols=AAPL&greeks=false" \ -H 'Authorization: Bearer <TOKEN>' \ -H 'Accept: application/json' What's Next? Check out the rest of our docs and get started coding with our API. We're here to support you every step of the way. If you have questions or need assistance, don't hesitate to reach out to our technical support team at techsupport@tradier.com Happy coding! 🚀 • [Advisor API](https://staging-docs.tradier.com/advisor-api.md): Tradier Advisor APIs were designed for registered entities (RIAs) to get up and running with their advisory or financial product without the need for complex clearing relationships and technology. Our brokerage and technical support teams will work with you through your launch and make sure you get to market as fast as possible. Account Opening Send new account applications for 7 different types of investment accounts. Asynchronous updates of the application approval process are sent to your platform in real time. Account Funding Electronically establish ACH profiles using bank information and be ready to send transactions within a day. Use APIs to complete ACH deposits and withdrawals, as well as check withdrawals. Documents Give customers access to their statements, confirmations, and tax documents with a secure and compliant workflow. We’ll also work with you regarding co-branding these documents and making sure customers get a great experience. User and Account Data You can fetch balances, positions, activity, and orders using a user or account number. This allows you to make the most efficient use of the API. Electronically fetch and deliver co-branded statements and confirmations. If you're interested in working with us to launch your advisor or platform, please contact us . Card Title Add description here Card Title Add description here • [Using AI](https://staging-docs.tradier.com/using-ai.md): AI & LLM Integration at Tradier Tradier is a leading technology company in the fintech space, committed to building infrastructure that meets developers where they are — including the rapidly evolving world of AI and large language models. This section covers how to use AI tools and agents effectively with the Tradier platform. Our approach to AI As LLMs become a core part of how developers build and how traders interact with financial platforms, Tradier is investing in first-class AI integration. Whether you’re using an AI coding assistant to build against our REST API or interacting with a natural language agent to execute trades and retrieve market data, we’ve built the infrastructure to support both workflows. We believe the best developer experience is one that meets you in your tool of choice — from your code editor’s AI assistant to conversational agents powered by models like Claude, ChatGPT, and others. New to AI tooling? If you're not sure where to start, we recommend checking out both routes below. Developers building integrations will find LLMs.txt most useful, while traders and power users exploring natural language interaction should start with the MCP server. Two routes to AI-powered access Depending on how you want to work with AI, Tradier supports two distinct entry points: For Developers Programming with AI LLMs.txt — AI-assisted coding Our llms.txt file provides a structured, machine-readable summary of the Tradier API designed for AI coding assistants. Drop it into your context window or point your AI tool at it to get accurate, up-to-date guidance on endpoints, authentication, and data models — without hallucination. Ideal for: building integrations, writing API wrappers, or asking your AI assistant how to place an order or stream quotes. https://docs.tradier.com/llms.txt For Users looking for Natural Language Use of an LLM MCP server — conversational API access The Tradier MCP (Model Context Protocol) server lets AI agents interact directly with your brokerage account using natural language. Connect it to a compatible AI assistant and ask things like "What are my open positions?" or "Buy 10 shares of AAPL" — no code required. Ideal for: power users, traders, and anyone who wants to interact with Tradier through an AI agent rather than writing code. https://docs.tradier.com/docs/tradier-mcp What’s coming next AI integration at Tradier is an active area of development. We’re continually expanding our MCP toolset, keeping our LLMs.txt in sync with API changes, and exploring deeper integrations with the AI platforms developers and traders use most. Check back in this section for updates, guides, and new capabilities as they launch. Have feedback on our AI tooling or want to request a specific integration? Reach out to the Tradier developer team. • [LLMs.txt](https://staging-docs.tradier.com/using-ai/llms-txt.md): The LLMs.txt standard is a plain-text file convention, similar in spirit to robots.txt, that gives AI and LLM tools a structured, machine-readable summary of a site's content. Rather than having an LLM guess at what's important by crawling and parsing full HTML pages, LLMs.txt gives it a curated overview it can use to answer questions more accurately. Tradier provides an LLMs.txt file so that AI tools and assistants can better understand our API's structure and capabilities when helping developers integrate with it. In addition to the API documentation we provide, we also have an LLMs.txt file located at: [https://docs.tradier.com/llms.txt](https://docs.tradier.com/llms.txt) If you are working with an LLM such as Claude, ChatGPT, Gemini, or others to help in your integration with our API, LLMs.txt is the best resource to make sure the model is giving you accurate information about our API. One of the first steps you should take when working with AI tools is to ask it to first take a look at our LLMs.txt page and make sure it really understands our API before answering your questions or vibe coding a solution for you. • [Tradier MCP](https://staging-docs.tradier.com/using-ai/tradier-mcp.md): What is MCP? The Model Context Protocol (MCP) is a powerful way to connect external tools and data sources directly to modern LLMs, transforming them from general assistants into fully interactive and specialized work partners. By integrating with common AI models and providing tools / greater context, MCP makes it easy to build rich workflows, automate routine tasks, and accelerate learning—without needing complex retraining. Tradier has taken this great step forward with its new custom MCP server, which seamlessly links brokerage capabilities to LLMs like ChatGPT, Claude, Cursor, and more. Through this tool, users can access real-time market data, retrieve account details, query documentation, and even place trades—all from within their AI assistant. It’s a major leap forward in blending financial technology with conversational AI, empowering traders, developers, and learners to work smarter, faster, and more intuitively. Tradier’s MCP Server supports the Streamable HTTP transport protocol, allowing seamless integration. Most Tradier MCP tools require an account number to operate. Before using account-specific or trading tools, run the get_user_profile tool first (e.g. by asking your AI assistant "What's my account profile?") to retrieve your account number(s). Available Tools The Tradier MCP Server provides comprehensive tools for trading, market data, and documentation. These tools can be accessed either with the tool name or with natural language in the connected AI tool. The Tradier MCP Server exposes 22 tools total: search_tradier_docs (documentation) plus the 21 brokerage tools below, covering account/portfolio data, market data, trading, and watchlists. Schema quirk: For several tools, the underlying JSON schema marks every parameter as required, even when that parameter's own description says it's optional and has a sensible default (e.g. page , limit , start , end on history-style endpoints). This is noted per-tool below wherever it applies. If you're calling these tools programmatically rather than through natural language, you may need to pass a value for fields the description calls optional, depending on how strictly your MCP client enforces the schema. All parameters are typed as string . Even logically numeric fields ( quantity , price , page , limit ) and logically boolean fields ( greeks , exactMatch ) are typed as plain strings in the tool schemas. Pass values as strings regardless of their semantic type (e.g. quantity: "10" , not quantity: 10 ). Summary Tool Name Description search_tradier_docs Searches Tradier's built-in documentation about API features and trading concepts. See "Documentation Tool" below. get_user_profile Retrieves the authenticated user's profile, including account number(s). Recommended as a first call since most other tools require an account number. No parameters. get_account_balances Balance info for an account: total equity, option/stock buying power, cash available, day-trading buying power, dividend balance. get_account_historical_balances Historical account balance data over a period: date, value, delta, delta_percent. get_account_history Historical account activity: trades, dividends, options, transfers, etc. get_gainloss Realized/unrealized profit-and-loss report for an account. get_positions Current positions for an account: symbol, quantity, cost basis, date acquired, current value. get_orders Orders for an account: order ID, symbol, side, quantity, price, type, status, date created. cancel_order Cancels an existing order. get_watchlists Retrieves all watchlists for the user. No parameters. add_to_watchlist Adds one or more symbols to a watchlist. get_market_quotes Quotes for specified symbols: last price, change, % change, volume, bid/ask. get_company_profile Company profile info (summary, website) for one or more symbols. get_historical_data Historical OHLCV price data for a symbol. get_market_calendar Trading days and holidays for a given month. get_options_chain Options chain for a symbol and expiration date. place_equity_order Places a stock buy/sell order. place_option_order Places a single-leg options order. place_multileg_option_order Places a multileg options order (spreads, straddles, etc.) — 2 to 4 legs. place_oco_order Places a One-Cancels-Other order — two orders where filling one cancels the other. place_oto_order Places a One-Triggers-Other order — a second order submits only after the first fills. place_otoco_order Places a One-Triggers-One-Cancels-Other order — order 1 triggers orders 2 and 3, which form an OCO pair. Account & Portfolio Tools get_account_balances — accountNumber (required) get_account_historical_balances — accountNumber (required); period (required — one of WEEK , MONTH , YEAR , YEAR_5 , YEAR_10 , YTD , ALL ) get_account_history — accountNumber (required). Schema marks all of the following as required, though their descriptions call them optional with defaults: page (default 1 ), limit (default 25 , max 100 ), type (one of trade , option , ach , wire , dividend , fee , tax , journal , check , transfer , adjustment , interest ), start (format yyyy-mm-dd , default account opening date), end (format yyyy-mm-dd , default end of current day), symbol , exactMatch (default false ) get_gainloss — accountNumber (required). Schema marks these as required, though their descriptions call them optional: page , limit get_positions — accountNumber (required) get_orders — accountNumber (required) cancel_order — accountNumber (required); orderId (required) Watchlist Tools get_watchlists — no parameters add_to_watchlist — watchlistId (required); symbols (required, comma-separated) Market Data Tools get_market_quotes — symbols (required, comma-separated, e.g. "AAPL,GOOGL,MSFT" ) get_company_profile — symbols (required, comma-separated) get_historical_data — symbol (required); interval (required — one of daily , weekly , monthly ). Schema marks these as required though their descriptions call them optional: start (format YYYY-MM-DD ), end (format YYYY-MM-DD ) get_market_calendar — Schema marks both as required, though their descriptions call them optional: month ( MM format, e.g. "12" ), year ( YYYY format) get_options_chain — symbol (required); expiration (required, YYYY-MM-DD ). Schema marks this as required though its description calls it optional: greeks ( "true" / "false" , default "false" ) Trading Tools place_equity_order — accountNumber , symbol , side ( buy / sell ), quantity , type ( market / limit / stop / stop_limit ), duration ( day / gtc / pre / post ) all required. Schema marks these as required though their descriptions call them optional (conditional on order type): price (for limit orders), stop (for stop orders) place_option_order — accountNumber , symbol (underlying), optionSymbol (full OCC symbol), side ( buy_to_open / buy_to_close / sell_to_open / sell_to_close ), quantity , type ( market / limit / stop / stop_limit ), duration ( day / gtc / pre / post ) all required. Schema marks this as required, though its description calls it optional: price (for limit orders) place_multileg_option_order — accountNumber , symbol (underlying), type ( market / debit / credit / even ), duration ( day / gtc ), leg1OptionSymbol / leg1Side / leg1Quantity , leg2OptionSymbol / leg2Side / leg2Quantity all required. Schema marks these as required, though their descriptions call them optional: price (needed for debit/credit types), leg3OptionSymbol / leg3Side / leg3Quantity (3rd leg), leg4OptionSymbol / leg4Side / leg4Quantity (4th leg). Supports 2 to 4 legs. place_oto_order — accountNumber required. For each of order1/order2: Class ( equity / option ), Symbol , OptionSymbol (required if Class is option ), Side , Quantity , Type , Duration ( day / gtc ) all required. Schema marks these as required though their descriptions call them optional: Price , Stop (per order) place_oco_order — same per-order field set as place_oto_order (order1/order2). The two orders must use different order types and must match on symbol/option symbol. place_otoco_order — same per-order field set as above, extended to order1/order2/order3. Order 1 triggers orders 2 and 3; orders 2 and 3 must share symbol/option symbol and use different order types. Documentation Tool The search_tradier_docs tool provides comprehensive, built-in documentation about Tradier API features and trading concepts. This helps AI assistants provide accurate, context-aware guidance. You can also point a general LLM tool first at our LLMs.txt in order to help it gather context on our API offering. Searchable Topics Order Types : OCO (One-Cancels-Other) orders OTO (One-Triggers-Other) orders OTOCO (One-Triggers-One-Cancels-Other) orders Multileg option orders Equity and option order basics Option Strategies : Iron Condor Vertical Spreads (Bull Call, Bear Put, etc.) Straddles and Strangles Butterfly Spreads Trading Concepts : Option symbol formatting (OCC standard) Account types and permissions Order types (Market, Limit, Stop, Stop Limit) Order duration (Day, GTC, Pre, Post) Order sides (Buy, Sell, Buy to Open, etc.) General Information : Getting started guide Common workflows Best practices Example Usage Plain text Query: "OCO orders" Returns: Detailed explanation of OCO orders, requirements, use cases, and examples Query: "iron condor" Returns: Complete strategy guide including structure, risk/reward, and implementation Query: "option symbols" Returns: OCC symbol format specification with examples Query: "OCO orders" Returns: Detailed explanation of OCO orders, requirements, use cases, and examples Query: "iron condor" Returns: Complete strategy guide including structure, risk/reward, and implementation Query: "option symbols" Returns: OCC symbol format specification with examples Live vs. Paper Trading For each integration, you can submit "PAPER_TRADING": true/false . Pass it as a string: "true" or "false" (see the configuration examples below, which pass it as a quoted string value rather than a boolean literal). If you wish to use your live account and live market data, you can submit your production API token and PAPER_TRADING: "false" . If you wish to work with your paper trading account you will submit your paper trading API token and "true" . You can always make these edits in the configuration files later to switch between the live and paper trading environments. Integrating Tradier MCP The Tradier MCP integration is currently available for ChatGPT, Claude Web and Desktop, Claude Code, Gemini CLI, and Cursor. We are working to integrate with the web versions of the most popular LLMs as well as additional tools like perplexity. Many popular LLMs require a subscription (beyond the free version) in order to integrate with MCP systems. Make sure to look up the requirements for the LLM you are working with. MCP/custom-connector support and requirements vary by subscription tier on each AI platform, and are subject to change. Check your specific plan's requirements on each platform before attempting setup. Retrieving Your API Tokens To get your API tokens, log in to your Tradier Brokerage account on tradier.com and visit your API settings, where you will find your live and paper trading tokens. Security guidance: Treat your API tokens like passwords. Where a platform supports it, store tokens in environment variables rather than hardcoding them directly in configuration files. Never commit configuration files that contain tokens (e.g. mcp.json , settings.json ) to version control. If a token is ever exposed or compromised, revoke it immediately from your account API settings page: https://web.tradier.com/user/api . ChatGPT Web and Desktop Log in to your ChatGPT subscription on chatgpt.com Go to settings > Apps > Advanced Settings and enable developer mode Back up a menu to Apps or go to settings > Apps > Create Custom App Enter the details of the custom MCP app you wish to add Name: Tradier MCP MCP Server URL: https://mcp.tradier.com/mcp?api_key={YOUR API KEY}&paper_trading=false Auth = No Auth Agree to the MCP Server risk statement Click create Once this is completed, Tradier MCP will also be available on ChatGPT desktop after a restart of the application. Claude Web and Desktop For Claude web and desktop MCP integrations, first log into your account on claude.ai Visit the settings page under your profile and then navigate to Connectors Click on add custom connector and add the following: For Name: Tradier MCP Remote MCP server URL: https://mcp.tradier.com/mcp?api_key={YOUR API KEY}&paper_trading=false Then click Add This will add the Tradier MCP server to your Claude connection and make it available in the web and desktop versions of Claude Claude Code If Claude Code is not already installed on your system: Plain text npm install -g @anthropic-ai/claude-code npm install -g @anthropic-ai/claude-code In a terminal run: Plain text claude mcp add --transport http tradier https://mcp.tradier.com/mcp \ --header "API_KEY: your_api_key_here" \ --header "PAPER_TRADING: false" claude mcp add --transport http tradier https://mcp.tradier.com/mcp \ --header "API_KEY: your_api_key_here" \ --header "PAPER_TRADING: false" Open Claude Code with command ‘claude’ in a terminal Once the MCP server is configured, Claude Code doesn’t use an @tool syntax like some other clients — instead, just ask it in natural language and it will autonomously call the appropriate configured MCP tool. For example, ask Claude Code: “What’s my account profile?” (this calls the get_user_profile tool behind the scenes and is a good place to start, as then you have your account number) Gemini CLI npm install -g @google/gemini-cli Edit ~/.gemini/settings.json adding: Plain text { "mcpServers": { "tradier": { "httpUrl": "https://mcp.tradier.com/mcp", "headers": { "API_KEY": "your_api_key_here", "PAPER_TRADING": "false" } } } } { "mcpServers": { "tradier": { "httpUrl": "https://mcp.tradier.com/mcp", "headers": { "API_KEY": "your_api_key_here", "PAPER_TRADING": "false" } } } } In a terminal, run gemini mcp list to confirm Tradier MCP is present Start Gemini and run commands like @tool get user profile is a good place to start, as then you have your account number Cursor Desktop App Download and install the Cursor desktop application. Go to ~/.cursor and check for a mcp.json file, if it doesn’t already exist, create one Add the following: Plain text { "mcpServers": { "tradier": { "url": "https://mcp.tradier.com/mcp", "headers": { "API_KEY": "your_api_key_here", "PAPER_TRADING": "false" }, "trust": false, "timeout": 600000 } } } { "mcpServers": { "tradier": { "url": "https://mcp.tradier.com/mcp", "headers": { "API_KEY": "your_api_key_here", "PAPER_TRADING": "false" }, "trust": false, "timeout": 600000 } } } Start the cursor application and confirm Tradier MCP through Cursor > Settings >Cursor Settings> Tools & MCP • [Accounts Details](https://staging-docs.tradier.com/accounts-details.md): The Accounts section enables you to access comprehensive information about brokerage accounts, including balances, positions, and transaction history. You can also manage position groups and monitor trade activity, gain/loss metrics, and order statuses to gain detailed insights and maintain control over your investment portfolio. • [Get User Profile](https://staging-docs.tradier.com/accounts-details/get-user-profile.md): Retrieve detailed profile information for the authenticated user, including account details and associated metadata. This allows you to access and display personalized user data within your application, enabling tailored experiences based on the user’s profile. • [Get Account Balance](https://staging-docs.tradier.com/accounts-details/get-account-balance.md): Retrieve detailed information about your account’s current financial status, including available balances, equity, and margin requirements. This allows you to monitor your funds, track open positions, and assess your buying power in real time. Bash curl -X GET "https://api.tradier.com/v1/accounts/VA000001/balances" \ -H "Authorization: Bearer <YOUR_TOKEN>" \ -H "Accept: application/json" Key response fields include `total_equity`, `total_cash`, `option_buying_power`, `stock_buying_power`, and `open_pl`. For margin accounts, a `margin` object is also returned; cash accounts return a `cash` object instead. • [Get Account's Balances Overtime](https://staging-docs.tradier.com/accounts-details/get-account-balance-overtime.md): Retrieve an account’s historical balance data to analyze changes in value over time. This section enables users to track balance trends and assess performance by accessing detailed records of balances and their corresponding dates. GET /v1/accounts/{account_id}/historical-balances?period= Supported period values: WEEK , MONTH , YEAR , YEAR_5 , YEAR_10 , YTD , ALL Bash curl -X GET "https://api.tradier.com/v1/accounts/VA000001/historical-balances?period=WEEK" \ -H "Authorization: Bearer <YOUR_TOKEN>" \ -H "Accept: application/json" Example Response: JSON { "historical_balances": { "balances": { "balance": [ { "date": "2026-07-06", "value": 15.94 }, { "date": "2026-07-07", "value": 15.94 }, { "date": "2026-07-08", "value": 15.94 }, { "date": "2026-07-09", "value": 15.95 } ] }, "delta": 0.01, "delta_percent": 0.06 } } Returns a historical_balances object containing a balances.balance array of { date, value } records for the requested period, plus a top-level delta (absolute change) and delta_percent (percentage change) comparing the first and last records. Note: per the API-wide single-element-array behavior, if the period only contains one record, balance may be returned as a single object rather than a one-element array — handle both defensively. • [Get Account History](https://staging-docs.tradier.com/accounts-details/get-account-history.md): Retrieve a detailed record of all past activities associated with a specific brokerage account. This section enables users to review transaction history, monitor account changes, and track events for auditing or analysis purposes. History for your account can be pulled for the previous 3 years. Title Description Parameter Description page Page number for pagination (default: 1 and only required if returning several thousand orders +) limit Results per page (default: 25, can be set to 1000 to get all orders at once without pagination) type Filter by type: trade , option , ach , wire , dividend , fee , tax , journal , check , transfer , adjustment start Start date in yyyy-mm-dd format end End date in yyyy-mm-dd format symbol Filter by specific security symbol exact_match Use exact symbol match (default: false) • [Get Account Orders](https://staging-docs.tradier.com/accounts-details/get-account-orders.md): Retrieve a list of orders for a specific account placed for the market session of the present calendar day. This section enables users to monitor and manage their open orders in real time, providing up-to-date order details tied to the account. Bash curl -X GET "https://api.tradier.com/v1/accounts/VA000001/orders" \ -H "Authorization: Bearer <YOUR_TOKEN>" \ -H "Accept: application/json" Each order returns the order ID, symbol, side (buy/sell), quantity, price, order type, status, and creation date. Note that a single order is returned as an object, while multiple orders are returned as an array. To fetch a specific order by ID: GET /v1/accounts/{account_id}/orders/{order_id} • [Get Single Order](https://staging-docs.tradier.com/accounts-details/get-single-order.md): Retrieve detailed information about a specific order within an account by providing its unique identifier. This allows users to access all relevant data associated with that order for review, tracking, or further processing. • [Get Account Gain/Loss](https://staging-docs.tradier.com/accounts-details/get-account-gain-loss.md): Retrieve detailed cost basis and realized gain/loss information for a specified account, covering all closed positions. This data enables users to accurately assess the account’s historical performance, with cost basis figures updated regularly through batch reconciliation with the clearing firm. curl -X GET "https://api.tradier.com/v1/accounts/VA000001/gainloss" \ -H "Authorization: Bearer <YOUR_TOKEN>" \ -H "Accept: application/json" Supports optional `page` and `limit` parameters for pagination when returning a high volume of results. You can also use the optional `sortBy` (`closedate`, `opendate`, `symbol`, or `gainloss`) and `sort` (`asc` or `desc`) parameters to control the ordering of returned results. Results include cost basis, proceeds, and realized P&L for each closed position. • [Positions](https://staging-docs.tradier.com/positions.md): Position groups let you logically organize related positions together. Position groups are organizational only — they do not affect order routing or margin calculations. Get All Position Groups GET /v1/accounts/{account_id}/position-groups Bash # Example: Get all position groups curl -X GET "https://api.tradier.com/v1/accounts/VA000001/position-groups" \ -H "Authorization: Bearer <YOUR_TOKEN>" \ -H "Accept: application/json" • [Get Account Positions](https://staging-docs.tradier.com/positions/get-account-positions.md): Retrieve a comprehensive list of all open positions held within a specified account. This section enables users to monitor current holdings, including details necessary for portfolio tracking and risk management. Bash curl -X GET "https://api.tradier.com/v1/accounts/VA000001/positions" \ -H "Authorization: Bearer <YOUR_TOKEN>" \ -H "Accept: application/json" Each position includes the symbol, quantity, cost basis, and date acquired. • [Get Account Position Groups](https://staging-docs.tradier.com/positions/get-account-position-groups.md): Retrieve a comprehensive list of all position groups associated with a specified account. This section enables users to view grouped positions, helping to analyze and manage portfolio allocations effectively. • [Create a New Position Group](https://staging-docs.tradier.com/positions/create-a-new-position-group.md): Use this section to create a new position group within a specified account, allowing you to organize and manage related positions efficiently. This enables better tracking and categorization of holdings tailored to your trading or investment strategies. • [Update Position Group](https://staging-docs.tradier.com/positions/update-position-group.md): Modify the details of an existing position group within a specific account to reflect updated holdings or configurations. This allows users to manage and organize their investment positions more effectively by adjusting group attributes and included items. • [Delete a Position Group](https://staging-docs.tradier.com/positions/delete-a-position-group.md): Remove an existing position group from a specified account to effectively manage and update your portfolio structure. This operation permanently deletes the position group, ensuring it is no longer associated with the account. Use it to maintain accurate and current position groupings within your brokerage management. • [Market Data](https://staging-docs.tradier.com/market-data.md): The Markets section provides access to real-time and historical market data, including quotes, options chains, strikes, expirations, and Greeks. Users can retrieve detailed information to analyze market conditions, track price movements, and evaluate options strategies across various securities. This enables informed decision-making and comprehensive market insights within the Brokerage API.Real-time data is available to all Tradier Brokerage account holders for US-based stocks and options. If you are not a Tradier Brokerage account holder, we are unable to provide you with any real-time data solution. We use standard symbols for most equities and ETFs. Options require the standard OCC symbology to be used. Investopedia has a good explanation of the symbol and its parts . Warrants and preferred class (and other specialized) securities will use a / in replacement of a . which is sometimes used at other brokers. For example: BRK.A should be BRK/A BRK.B should be BRK/B Note: There is a difference between the option root and the option underlying. For BRK/A options, the option root is still BRK.A whereas the underlying security is BRK/A. Realtime vs Delayed Real-time data is pulled from a consolidated feed from all exchanges. Delayed data is constructed from the same feed but is delayed industry-standard 15 minutes. Type Brokerage API Sandbox API Equities Realtime Delayed Options Realtime Delayed Indices Realtime* Not Available Mutual Funds Not Available Not Available Greeks Hourly Not Available *NDX, RUT, and COMP are derived values. Derived data refers to values produced by applying mathematical models, formulas, or transformations to underlying market data. In trading, this often includes forward-looking prices, implied metrics, or theoretical values calculated from inputs like spot prices, interest rates, dividends, and volatility. Learn more about Tradier-derived data. All other indexes that are in the CBOE main list are live values ( https://www.cboe.com/us/indices/ channel ‘main’). Any other index not in the main list is on a 15-minute delayed feed. Greeks Greeks and volatility data have been included courtesy of the ORATS APIs. In the Brokerage API, Greeks are updated once per hour starting at around 10:15. For real-time Greeks/IV and additional data, please check out their full offering of in-depth options data at https://orats.com/data-api Historical Quotes Historical pricing for a security consists of daily candles (OCHLV). This data will usually cover the entire lifetime of the company if sending reasonable start/end times. You can fetch historical pricing for options by passing the OCC option symbol (ex., AAPL251226C00270000) as the symbol. Notes: Historical data may not be dividend-adjusted, as this relies on the exchanges to report/adjust it properly. Historical options data is not available for expired options. Time & Sales Time and Sales (timesales) is typically used for charting purposes. It captures pricing across a time slice at predefined intervals. Tick data is also available through this endpoint. This results in a very large data set for high-volume symbols, so the time slice needs to be much smaller to keep downloads time reasonable. Note: tick data is not available in the sandbox/paper trading environment Whereas historical quotes are available across the lifetime of the security, time and sales data provides greater depth in time for larger intervals. Inteval Data Available (Open) Data Available (All) tick 5 Days N/A 1min 20 Days 10 Days 5min 40 Days 18 Days 15min 40 Days 18 Days • [Exchange Codes](https://staging-docs.tradier.com/market-data/exchange-codes.md): These codes are returned in the exch field of all market data requests. You can use this table to represent the exchange as text. ID Name A NYSE American B NASDAQ OMX BX C NYSE National D FINRA ADF E Market Independent (Generated by Nasdaq SIP) F Mutual Funds/Money Markets (NASDAQ) I International Securities Exchange J CBOE EDGA (formerly Direct Edge A) K CBOE EDGX (formerly Direct Edge X) L Long Term Stock Exchange M Chicago Stock Exchange N NYSE P NYSE Arca Q NASDAQ OMX S NASDAQ Small Cap T NASDAQ Int U OTCBB (Over-the-Counter Bulletin Board) — discontinued in 2014; retained here for historical data references V OTC other W CBOE X NASDAQ OMX PSX G GLOBEX Y CBOE BYX (formerly BATS Y-Exchange) Z CBOE BZX (formerly BATS) OPRA Feeds (Options) ID Name A NYSE Amex Options B BOX Options Exchange C Chicago Board Options Exchange (CBOE) H ISE Gemini I International Securities Exchange (ISE) M MIAX Options Exchange N NYSE Arca Options O Options Price Reporting Authority (OPRA) P MIAX PEARL Q NASDAQ Options Market T NASDAQ OMX BX W C2 Options Exchange X NASDAQ OMX PHLX Z BATS Options Market • [Get Quotes](https://staging-docs.tradier.com/market-data/get-quotes.md): Retrieve real-time market data for one or more symbols to stay informed on key trading metrics such as price, volume, and recent changes. This section enables users to access comprehensive quote information, empowering informed decision-making across multiple securities. • [Post Quotes](https://staging-docs.tradier.com/market-data/post-quotes.md): Retrieve market quotes for multiple symbols in a single request to efficiently obtain up-to-date pricing information. This section enables users to access detailed quote data, facilitating informed trading and analysis across a broader range of assets. • [Get Options Chains](https://staging-docs.tradier.com/market-data/get-options-chains.md): Retrieve detailed options chains for a specified underlying symbol and expiration date, including comprehensive Greek metrics and implied volatility data powered by ORATS. This enables users to analyze available options contracts, assess risk factors, and make informed trading decisions based on enriched market insights. **Tip:** The `expiration` parameter must be a date the underlying symbol actually has options listed for. Use the [options expirations endpoint](/markets/get-options-expirations) first to retrieve the list of valid expiration dates for a symbol, then pass one of those dates here. > **Silent failure warning:** Passing an `expiration` date that isn't a valid/listed expiration for the symbol does not return an error — it returns an empty response. If you get no results back, double-check the date against the options expirations endpoint before assuming something else is wrong. • [Get Options Strikes](https://staging-docs.tradier.com/market-data/get-options-strikes.md): Retrieve a list of available strike prices for a given underlying symbol and expiration date. This allows you to explore the range of option strikes you can trade or analyze for that specific market and timeframe. • [Get Options Expirations](https://staging-docs.tradier.com/market-data/get-options-expirations.md): Retrieve a list of available expiration dates for options tied to a specific underlying symbol. This enables users to explore and select valid expiration dates when analyzing or placing options trades. Additional response fields (confirmed against a live call): Passing contractSize=true , expirationType=true , and/or strikes=true adds the following fields to each expiration entry: contract_size (integer) — number of shares per contract, e.g. 100 . Added by contractSize=true . expiration_type (string) — one of standard , weeklys , quarterlys , or eom (end-of-month). Additional values may exist for other underlyings/products; this list reflects what's been observed so far. Added by expirationType=true . strikes.strike (array of numbers) — all available strike prices, in dollars, for options expiring on that date. Added by strikes=true . Example entry with contractSize=true and expirationType=true : { "date": "2026-07-31", "contract_size": 100, "expiration_type": "eom" } Example entry with strikes=true : { "date": "2026-07-17", "strikes": { "strike": [110.0, 115.0, 120.0, ...] } } • [Get Lookup Options Symbols](https://staging-docs.tradier.com/market-data/get-lookup-options-symbols.md): Retrieve all available option symbols for a specified underlying asset, including any additional option roots such as SPXW or RUTW when applicable. This allows users to explore the full range of tradable options tied to a particular market instrument. • [Get Option Greeks](https://staging-docs.tradier.com/market-data/get-option-greeks.md): Retrieve detailed Greek metrics for an entire option chain to analyze the sensitivity of option prices to various market factors. This allows you to assess risk and make informed decisions based on key indicators such as delta, gamma, theta, and vega across multiple options. • [Get Historical Pricing](https://staging-docs.tradier.com/market-data/get-historical-pricing.md): Retrieve comprehensive historical pricing data for a specified security, including stocks and options, to analyze its performance over time. This section enables you to access detailed daily price and volume information spanning the security’s lifetime, supporting informed investment and trading decisions. **Note:** Historical prices returned by this endpoint are adjusted for stock splits, but **not** for dividends. * **Split-adjusted (confirmed):** CRWD's 4-for-1 split took effect on 2026-07-02, and daily closes are continuous across that date (e.g. $193.19 on 2026-07-01 to $193.98 on 2026-07-02) rather than showing the ~4x jump that would appear in raw/unadjusted data. * **Not dividend-adjusted (confirmed):** FORTY paid a $13.045/share special dividend with an ex-dividend date of 2026-05-22. The data shows a real price drop landing on that date (close of $144.48 on 2026-05-18 to an open of $133.37 on 2026-05-22 — a ~$11 drop in the same range as the dividend), rather than a smoothed/restated series. If you need dividend-adjusted (total-return-style) pricing, you'll need to apply that adjustment yourself using dividend history. • [Get Time & Sales](https://staging-docs.tradier.com/market-data/get-time-and-sales.md): Retrieve detailed market pricing data aggregated over customizable time intervals to support precise charting and analysis. This section provides granular trade and quote information, including tick-level data, enabling users to visualize price movements and trading activity for a given symbol. **Payload size warning:** `tick` is the default interval. For actively traded, high-volume securities, requesting `tick`-level data — especially over a full trading day — can return tens of thousands of records in a single response, with no built-in limit on payload size. If you don't need trade-by-trade granularity, request a coarser interval (e.g. `1min`, `5min`, or `15min`) to keep response sizes manageable. • [Get ETB Securities](https://staging-docs.tradier.com/market-data/get-etb-securities.md): Retrieve a comprehensive list of securities eligible for short selling within a Tradier Brokerage account. This allows users to identify and access ETB (Easy-to-Borrow) securities available for trading. • [Get Market Clock](https://staging-docs.tradier.com/market-data/get-market-clock.md): Retrieve real-time information about the current intraday market status to determine whether the market is open or closed. This functionality enables users to make informed decisions and implement logic based on the market’s active state throughout the trading day. • [Get Market Calendar](https://staging-docs.tradier.com/market-data/get-market-calendar.md): Retrieve detailed market calendar information for the current or a specified month, including trading sessions and market status for each day. Use this data to plan trading activities by understanding market open, premarket, and postmarket hours along with relevant day descriptions. • [Get Market Search](https://staging-docs.tradier.com/market-data/get-market-search.md): Search for securities using partial matches on symbols or company names to quickly locate relevant market instruments. The results are ranked by average trading volume, enabling users to identify actively traded securities efficiently. This functionality supports straightforward and effective market search capabilities within the Brokerage API. **Search vs. Lookup:** Both endpoints accept a `q` query that can be a symbol or a company name. This endpoint (`/v1/markets/search`) is the broader of the two — it does not offer exchange or security-type filters, but does let you include or exclude indices from the results via the `indexes` parameter. If you need to narrow results to specific exchanges or security types (stock, etf, index), use the [lookup endpoint](/markets/get-lookup) instead. • [Get Market Lookup](https://staging-docs.tradier.com/market-data/get-market-lookup.md): Retrieve detailed information about securities by searching with full or partial ticker symbols. The results are ranked by average trading volume, enabling users to efficiently identify and explore active market instruments for investment or analysis. **Lookup vs. Search:** Both endpoints accept a `q` query that can be a symbol or a company name. This endpoint (`/v1/markets/lookup`) is the more targeted of the two, since it lets you narrow results with the `exchanges` and `types` filter parameters (e.g. restrict to a specific exchange, or to only `stock`, `etf`, or `index` security types). The [search endpoint](/markets/get-search) does not offer exchange/type filters but instead lets you include or exclude indices from results. • [Trading](https://staging-docs.tradier.com/trading.md): The Trading section enables users to create, modify, and cancel orders within their brokerage accounts. It provides the tools necessary to manage active trades efficiently, ensuring precise control over order execution and portfolio adjustments. Prerequisites You'll need: - A Tradier Brokerage account and an API access token from web.tradier.com/user/api - Your Account ID (e.g. 6YA00001), available from the User Profile endpoint All requests require: Authorization: Bearer <YOUR_TOKEN> Accept: application/json Content-Type: application/x-www-form-urlencoded Base URLs: Production: https://api.tradier.com/v1 Sandbox (paper trading): https://sandbox.tradier.com/v1 Tip: Always test your order logic against the sandbox environment before going live. The sandbox supports the full trading API with paper money and delayed market data. Previewing orders is also strongly recommended. Common Parameters These parameters apply across all order types: Parameter Required Description class Yes Order class: equity, option, multileg, combo, oto, oco, otoco symbol Yes Underlying ticker symbol (e.g. AAPL) type Yes Order type: market, limit, stop, stop_limit duration Yes How long the order stays active: day, gtc, pre, post quantity Yes Number of shares (whole numbers for equities) or contracts price Conditional Required for limit and stop_limit orders stop Conditional Required for stop and stop_limit orders tag No Optional user-defined label for the order preview No Set to true to validate without submitting (see Preview section) • [Place Order](https://staging-docs.tradier.com/trading/place-order.md): We tried our best to make the trading API as easy as possible to work with. There are some essential concepts to understand that have to do with a trading flow, but the calls themselves are very straightforward. Buying and Selling Equities Placing an order through the Trading API is very simple. There’s no FIXML to learn, no custom formats or XML. There are five required parameters: class - The kind of order to be placed. One of: equity, option, multileg, combo. symbol - The symbol to be ordered. duration - The time for which the order will remain in effect (Day or GTC). side - The side of the order (buy or sell). quantity - The number of shares to be ordered, in whole numbers. type - The type of order to be placed (market, limit, etc.) A properly composed order for 100 shares of AAPL looks like this: Bash curl --request POST \ --url https://api.tradier.com/v1/accounts/6YA00001/orders \ --header 'accept: application/json' \ --header 'authorization: Bearer {TOKEN}' \ --header 'content-type: application/x-www-form-urlencoded' \ --data-urlencode type=market \ --data-urlencode duration=day \ --data-urlencode preview=true \ --data-urlencode class=equity \ --data-urlencode symbol=AAPL \ --data-urlencode quantity=100 \ --data-urlencode side=buy Buying and Selling Options Placing an order for an option is very similar to that of a stock. There is only one additional field for placing a single-leg: option_symbol an OCC symbol (AAPL251219C00195000) for the option to be ordered. A properly composed order for 1 contract of an AAPL option looks like this. Note that options trade in contracts, not shares — each contract typically represents 100 shares of the underlying security. Bash curl --request POST \ --url https://api.tradier.com/v1/accounts/6YA00001/orders \ --header 'accept: application/json' \ --header 'authorization: Bearer <TOKEN>' \ --header 'content-type: application/x-www-form-urlencoded' \ --data-urlencode type=market \ --data-urlencode duration=day \ --data-urlencode class=option \ --data-urlencode symbol=AAPL \ --data-urlencode quantity=1 \ --data-urlencode option_symbol=AAPL261002C00335000 \ --data-urlencode side=buy_to_open Placing Multileg and Combo orders Placing multileg and combo orders uses the same framework and parameters as explained above for single-leg orders, with only slight modifications. Legs only have three specific data points: side, quantity, and symbol. For option legs, you should send option_symbol in the case of combo orders, equity legs should have option_symbol set to null as the underlying symbol will be used. In order to send multiple legs, we’ve adopted standard form-parameter notation: side[index], quantity[index], option_symbol[index], where index is the leg number (based at zero). side[index] The side of the leg. quantity[index] The quantity of shares/contracts for that leg option_symbol[index] The OCC symbol (AAPL251219C00195000) for the option. Should be null for equity legs. A properly composed multileg order looks like this: Bash curl -X POST "https://sandbox.tradier.com/v1/accounts/VA7341708/orders" \ -H "Authorization: Bearer mFm6k0W88fkWTcjBTFLDY6TYUpsx" \ -H "Accept: application/json" \ -d "class=multileg" -d "symbol=AAPL" -d "type=credit" \ -d "duration=day" -d "price=1.00" -d "preview=true" \ -d "option_symbol[0]=AAPL261120P00230000" -d "side[0]=buy_to_open" -d "quantity[0]=1" \ -d "option_symbol[1]=AAPL261120P00235000" -d "side[1]=sell_to_open" -d "quantity[1]=1" \ -d "option_symbol[2]=AAPL261120C00265000" -d "side[2]=sell_to_open" -d "quantity[2]=1" \ -d "option_symbol[3]=AAPL261120C00270000" -d "side[3]=buy_to_open" -d "quantity[3]=1" Pre/Post Market Sessions Pre- and post-market session orders are supported; however, some restrictions apply. Pre-market Session : 7:00 AM EST to 9:24 AM EST ; Post-market Session : 4:00 PM EST to 19:55 PM EST Some notes about orders placed for these sessions: Only equity orders are permitted. Order type must be limit Orders placed in the session will expire at the end of the session You cannot place orders for pre/post session outside the session window Previewing Orders It is in the investor’s best interest to preview an order before actually placing it. A preview call will return issues and warnings associated with the order (if applicable) as well as commission information should the order be executed. Previewing is also the best way to get started using the Trading API. By sending preview=true as a parameter to the Create Order call, you can run all validation checks against an order without actually submitting it. Bash curl --request POST \ --url https://api.tradier.com/v1/accounts/6YA000001/orders \ --header 'accept: application/json' \ --header 'authorization: Bearer <TOKEN>' \ --header 'content-type: application/x-www-form-urlencoded' \ --data-urlencode type=market \ --data-urlencode duration=day \ --data-urlencode preview=true \ --data-urlencode class=equity \ --data-urlencode symbol=AAPL \ --data-urlencode side=buy JSON { "order": { "status": "ok", "commission": 0, "cost": 332.79, "fees": 0, "symbol": "AAPL", "quantity": 1, "side": "buy", "type": "market", "duration": "day", "result": true, "order_cost": 332.79, "margin_change": 166.395, "request_date": "2026-10-02T13:45:06.213", "extended_hours": false, "class": "equity", "strategy": "equity", "day_trades": 0 } } Note: Preview orders are not required — but are recommended. There will be circumstances (i.e. algorithmic trading) where it is unreasonable to preview the order first. • [Preview Order](https://staging-docs.tradier.com/trading/preview-order.md): Previewing an order provides insight into the validation and cost an order might have on an account. We recommend that most developers and platforms leverage previews before placing orders. When previewing an order, all order validation rules are run, including buying power checks. All applicable fees and commissions are delivered in the response. Submit the order with all necessary parameters and include the additional parameter of preview=true Bash curl --request POST \ --url https://api.tradier.com/v1/accounts/6YA000001/orders \ --header 'accept: application/json' \ --header 'authorization: Bearer <TOKEN>' \ --header 'content-type: application/x-www-form-urlencoded' \ --data-urlencode type=market \ --data-urlencode duration=day \ --data-urlencode preview=true \ --data-urlencode class=equity \ --data-urlencode symbol=AAPL \ --data-urlencode quantity=1 \ --data-urlencode side=buy Response Plain text { "order": { "status": "ok", "commission": 0, "cost": 332.79, "fees": 0, "symbol": "AAPL", "quantity": 1, "side": "buy", "type": "market", "duration": "day", "result": true, "order_cost": 332.79, "margin_change": 166.395, "request_date": "2026-10-02T13:45:06.213", "extended_hours": false, "class": "equity", "strategy": "equity", "day_trades": 0 } } { "order": { "status": "ok", "commission": 0, "cost": 332.79, "fees": 0, "symbol": "AAPL", "quantity": 1, "side": "buy", "type": "market", "duration": "day", "result": true, "order_cost": 332.79, "margin_change": 166.395, "request_date": "2026-10-02T13:45:06.213", "extended_hours": false, "class": "equity", "strategy": "equity", "day_trades": 0 } } • [Change Order](https://staging-docs.tradier.com/trading/change-order.md): Update the details of an existing order to reflect changes in quantity, price, or other order attributes. This section enables users to modify active orders seamlessly, ensuring that the order information remains accurate and up to date within their account. Which fields can be modified Field Modifiable? type Yes — one of market, limit, stop, stop_limit, debit, credit duration Yes price Yes — required for limit and stop_limit orders stop Yes — required for stop and stop_limit orders quantity No — cancel and place a new order instead side No — cancel and place a new order instead symbol No — cancel and place a new order instead • [Cancel Order](https://staging-docs.tradier.com/trading/cancel-order.md): Use this section to cancel an existing order associated with a specific account. Once canceled, the order will no longer be processed or executed, allowing you to effectively manage and update your active trading positions. • [Advanced Orders](https://staging-docs.tradier.com/trading/advanced-orders.md): Getting Started with Advanced Orders Advanced orders allow one to place a sequence of orders in a single request. Typically, they rely on triggering conditions set with the market center that will take a particular action on the orders. Advanced Order Types One-triggers-other (OTO) - if the first order is filled, the second order is placed. One-cancels-other (OCO) - if the first order is filled, the second order is canceled. One-triggers-one-cancels-other (OTOCO) - if the first order is filled, a one-cancels-other (OCO) is placed. Requests Sending multiple orders is similar to sending multiple legs in that each order's property keys are indexed (symbol[2]) to specify the correct arrangement of the orders. Validations Advanced orders have some different validations than regular orders. Each order type, has some special validations that will be enforced on order placement. One-cancels-other (OCO) type must be different for both legs. If both orders are equities, the symbol must be the same. If both orders are options, the option_symbol must be the same. If sending duration per leg, both orders must have the same duration. One-triggers-one-cancels-other (OTOCO) If all equity orders, second and third orders must have the same symbol. If all option orders, second and third orders must have the same option_symbol. Second and third orders must always have a different type. If sending duration per leg, second and third orders must have the same duration. • [Tradelink](https://staging-docs.tradier.com/trading/tradelink.md): We developed Trade Link to satisfy the needs of partners that are eager to integrate and want to provide immediate trading functionality to their customers. It provides straight-forward link-based integrations for web, mobile and desktop applications. We’ve done our best to think through a lot of the use cases of these links, but if we missed something, please reach out to us at techsupport@tradier.com and let us know how we can help. How it works The Tradier Brokerage website has a pre-built trade ticket that implements equity, options, multileg and combo orders. Any account holder can use the Tradier Brokerage web site to execute orders. In an effort to build on the work we’ve already done with this ticket, we’ve provided an interface to allow external parties to pre-populate a trading ticket based off of parameters. You can use as few or as many parameters as needed to fill in the ticket. The only required parameters are the symbol and class of the order. Base URL https://web.tradier.com/tradelink Parameters Title Description Title Description Title Parameter Type Param Type Values/Example Default Class Query String equity, option, combo, multileg The class type of that order Symbol Query String Any security symbol An equity symbol Examples Equity Order Buy 100 SPY: https://web.tradier.com/tradelink?class=equity&symbol=spy&quantity=100&side=buy&type=market&duration=day Option Order Buy to Open 5 Contracts: https://web.tradier.com/tradelink?class=option&symbol=spy&option_symbol=SPY251219C00450000&quantity=5&side=buy_to_open&type=market&duration=day Multileg Order https://web.tradier.com/tradelink?class=multileg&symbol=AAPL&option_symbol[0]=AAPL251219C00165000&side[0]=buy_to_open&quantity[0]=1&option_symbol[1]=AAPL251219C00175000&side[1]=buy_to_close&quantity[1]=2&option_symbol[2]=AAPL251219P00135000&side[2]=sell_to_open&quantity[2]=3&option_symbol[3]=AAPL251219P00145000&side[3]=sell_to_close&quantity[3]=4 Combo Order https://web.tradier.com/tradelink?class=combo&symbol=AAPL&type=market&side[0]=buy&quantity[0]=230&option_symbol[1]=AAPL251219P00160000&side[1]=buy_to_open&quantity[1]=23 • [Place Equity Order](https://staging-docs.tradier.com/trading/place-equity-order.md): Place an equity order. Send to POST /v1/accounts/{account_id}/orders with class=equity . Which fields are required per order type type price required? stop required? market No No limit Yes No stop No Yes stop_limit Yes Yes • [Place Option Order](https://staging-docs.tradier.com/trading/place-option-order.md): Place a single-leg option order. Send to POST /v1/accounts/{account_id}/orders with class=option . Which fields are required per order type type price required? stop required? market No No limit Yes No stop No Yes stop_limit Yes Yes • [Place Multileg Order](https://staging-docs.tradier.com/trading/place-multileg-order.md): Place a multileg option order (up to 4 option legs). Send to POST /v1/accounts/{account_id}/orders with class=multileg . Understanding debit, credit, and even order types In addition to market , multileg orders support three order types that describe the net premium of the combined legs rather than a per-leg limit price: debit — the trader pays a net premium to enter the position (e.g. buying more option value than is sold). credit — the trader receives a net premium for entering the position (e.g. selling more option value than is bought). even — no net premium changes hands; the value of the legs bought and sold offsets to zero. For debit , credit , and even orders, the price field is interpreted as the net premium for the entire order (i.e. per one full set of legs), not a per-leg price. For example, a debit order with price=1.50 means the trader is willing to pay up to $1.50 net premium per contract set across all legs combined. Which fields are required per order type Multileg orders do not use a stop field; only price applies, and only for the non-market order types: type price required? market No debit Yes credit Yes even Yes • [Place Combo Order](https://staging-docs.tradier.com/trading/place-combo-order.md): Place a combo order consisting of one equity leg and one or two option legs. Send to POST /v1/accounts/{account_id}/orders with class=combo . Understanding debit, credit, and even order types In addition to market , combo orders support three order types that describe the net premium of the combined legs rather than a per-leg limit price: debit — the trader pays a net premium to enter the position. credit — the trader receives a net premium for entering the position. even — no net premium changes hands; the value of the legs bought and sold offsets to zero. For debit , credit , and even orders, the price field is interpreted as the net premium for the entire order across all legs combined, not a per-leg price. Which fields are required per order type Combo orders do not use a stop field; only price applies, and only for the non-market order types: type price required? market No debit Yes credit Yes even Yes • [Place OCO Order](https://staging-docs.tradier.com/trading/place-oco-order.md): Place a one-cancels-other (OCO) order composed of two simultaneous orders. If one executes, the other is automatically cancelled. Send to POST /v1/accounts/{account_id}/orders with class=oco . Validations: type must be different for both legs. If both orders are equities, the symbol must be the same. If both orders are options, the option_symbol must be the same. If sending duration per leg, both orders must have the same duration. Which fields are required per order type Each leg’s type[index] follows the same rule (note that market is not a valid type for either OCO leg — see below for why): Title Description Title type[index] price[index] required? stop[index] required? limit Yes No stop No Yes stop_limit Yes Yes Example: bracket-style take-profit / stop-loss A common use of OCO orders is a bracket exit on an existing position: place a limit order to take profit if the price rises to a target, and a stop order to cut losses if the price falls to a threshold — whichever happens first automatically cancels the other. For example, holding 10 shares of AAPL bought at $140, you could send an OCO order with: Leg 0: type[0]=limit , side[0]=sell , price[0]=150 — sell if AAPL rises to $150 (take profit). Leg 1: type[1]=stop , side[1]=sell , stop[1]=130 — sell if AAPL falls to $130 (stop loss). Whichever leg fills first, the other is automatically canceled. Why market orders are excluded from OCO legs A market order executes immediately and unconditionally at the best available price — it doesn’t wait for a trigger condition. Allowing a market type on an OCO leg would defeat the purpose of “one cancels other” conditional logic, since a market order would fill right away rather than waiting to see whether the opposing leg’s condition is met first. For this reason, only limit , stop , and stop_limit are valid types for OCO legs. • [Place OTO Order](https://staging-docs.tradier.com/trading/place-oto-order.md): Place a one-triggers-other (OTO) order composed of two orders. Both orders are submitted at the same time, but the second order is only released for execution once the first order fills completely — the second order is placed only after the first order executes. Send to POST /v1/accounts/{account_id}/orders with class=oto . Leg roles Title Description Leg Role [0] Triggering order — submitted immediately [1] Triggered order — placed automatically once leg [0] fills Which fields are required per order type Title Description Title type[index] price[index] required? stop[index] required? market (leg [1] only) No No limit Yes No stop No Yes stop_limit Yes Yes Note: market is only a valid type for the triggered order ( type[1] ); the triggering order ( type[0] ) must be limit , stop , or stop_limit . Example Buy 10 shares of AAPL with a limit order, and once that buy fills, automatically place a limit sell order to take profit: Leg 0 (triggering order): type[0]=limit , side[0]=buy , quantity[0]=10 , price[0]=130 — buy AAPL if it can be bought at $130 or better. Leg 1 (triggered order): type[1]=limit , side[1]=sell , quantity[1]=10 , price[1]=150 — once the buy fills, automatically place a sell order at $150. • [Place OTOCO Order](https://staging-docs.tradier.com/trading/place-otoco-order.md): Place a one-triggers-one-cancels-other (OTOCO) order composed of three orders. All three are submitted at the same time, but the second and third orders — which together form an OCO (one-cancels-other) pair — are only released for execution once the first order fills completely. Send to POST /v1/accounts/{account_id}/orders with class=otoco . Leg roles Leg Role [0] Triggering order — submitted immediately [1] First OCO leg — placed automatically once leg [0] fills [2] Second OCO leg — placed automatically once leg [0] fills; cancels leg [1] (or vice versa) once either fills Which fields are required per order type Because legs [1] and [2] form an OCO pair, market is not a valid type for either of them (see the OCO order documentation for why). The triggering order ( type[0] ) also cannot be market : type[index] price[index] required? stop[index] required? limit Yes No stop No Yes stop_limit Yes Yes Example: buy with an automatic take-profit / stop-loss bracket Buy 10 shares of AAPL with a limit order, and once that buy fills, automatically place a bracket (OCO) exit — a limit sell to take profit or a stop sell to cut losses, whichever triggers first: Leg 0 (triggering order): type[0]=limit , side[0]=buy , quantity[0]=10 , price[0]=130 — buy AAPL if it can be bought at $130 or better. Leg 1 (first OCO leg): type[1]=limit , side[1]=sell , quantity[1]=10 , price[1]=150 — once the buy fills, sell if AAPL rises to $150 (take profit). Leg 2 (second OCO leg): type[2]=stop , side[2]=sell , quantity[2]=10 , stop[2]=120 — once the buy fills, sell if AAPL falls to $120 (stop loss). Once leg 0 fills, legs 1 and 2 become active as an OCO pair: whichever fills first automatically cancels the other. • [Streaming](https://staging-docs.tradier.com/streaming.md): Real-time streaming of market data and account events over HTTP or WebSocket. Use this section to push live quotes, trades, and account activity to your application instead of polling the REST endpoints. This section covers two independent stream types, each requiring its own session: * **Market data streaming** — real-time quotes, trades, and summary events for symbols you subscribe to. Requires a session from [Create Market Session](create-market-session/index.md). * **Account event streaming** — real-time order and account activity for one or more of your accounts. Requires a session from [Create Account Session](create-account-session/index.md). Both stream types support HTTP streaming (chunked JSON over a long-lived connection) and WebSocket streaming (bidirectional, supports live symbol changes without reconnecting). See [Streaming](streaming/index.md) for the shared connection concepts and lifecycle, then the transport/stream-specific reference pages for request and response details: * [HTTP Streaming](http-streaming/index.md) * [WebSocket Market Data Streaming](websocket-market-data-streaming/index.md) * [WebSocket Account Data Streaming](websocket-account-data-streaming/index.md) — **note: this stream is presently in Beta**, available to Tradier Brokerage account holders only. Event payload field references: [Streaming Market Data](../responses/streaming-market-data/index.md) / [Streaming Account Events](../responses/streaming-account-events/index.md). • [Overview](https://staging-docs.tradier.com/streaming/overview-1.md): Tradier offers access to an HTTP and WebSocket streaming API. These streaming APIs allow you to receive updated market data and account information as these events occur. We process market data and account events as soon as they happen and send them downstream to anyone listening. This page covers the shared concepts across both transports. For request/response specifics, see: HTTP Streaming WebSocket Market Data Streaming WebSocket Account Data Streaming Streaming sessions In order to initiate streaming, you’ll need to create an authenticated streaming session via Create Market Session or Create Account Session . Once this session has been created, you can request the streaming API endpoints using the returned session identifier. Streaming session identifiers are short-lived — you have up to 5 minutes to connect before the session expires, so use it immediately after the request. 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. See HTTP Streaming for the full endpoint, headers, parameters, and examples. WebSocket streaming We offer a secure WebSocket connection that can be natively connected to directly via a browser using modern WebSocket APIs or through backend client libraries. An additional advantage of the WebSocket streaming APIs is that they don’t require reconnection to modify the streamed securities. Once a WebSocket connection is opened, you send a request payload to our servers, and we process your request and begin sending back data right away. Once connected and streaming data, you can change symbols (add or remove symbols without a new session) by resending your payload with the same sessionid . Exception: filter cannot be changed by resending the payload once the stream has started — see Market Data Streaming below. If your session ID has expired, you’ll need to get a new one and send it with your adjusted payload. In the event of validation issues with your WebSocket request, expect an error payload with details, e.g. {"error":"1234 is not a valid symbol"} . See WebSocket Market Data Streaming and WebSocket Account Data Streaming for the full payload formats, defaults, and examples for each stream type. Connection Lifecycle Reusing a session across reconnects: As long as your sessionid has not expired, you can close and reopen the WebSocket connection and resend the same request payload with the same sessionid to resume streaming — a simple reconnect does not require requesting a brand new session. When a new session is required: Streaming session identifiers are short-lived (see Streaming Sessions above), and HTTP streaming connections close automatically after 15 minutes of inactivity. If your sessionid has expired, you must call the appropriate session-creation endpoint to obtain a new sessionid before reconnecting. Detecting disconnection: Because both HTTP and WebSocket connections can drop without a clean close event, it’s recommended that you implement your own client-side heartbeat/timeout check. Account event streams send periodic heartbeat events (see the example in Streaming Account Events ) to confirm the connection is still active; if your client stops receiving heartbeat or data events within your expected interval, treat the connection as dropped and trigger your reconnection logic. Limits While we do not publish the symbol limits for these APIs, we do monitor for abuse to make sure people aren’t doing anything egregious (like asking for an entire exchange’s worth of symbols). Essentially, ask for what you need. Don’t abuse the APIs, and you should be fine. It is not permitted to open more than one session at a time, meaning you can have one market data stream and one account stream open at a time, not multiples of either type. Market Data Streaming When streaming market data, you can stream as few as a single symbol or in excess of several hundred symbols, with the limiting factor being your system’s ability to receive updates promptly. A few high-activity symbols will take up more bandwidth than many lower-activity symbols. You can send updated payloads to add or remove symbols from your stream without closing the stream or obtaining a new sessionid . Filters for market data include: trade , quote , summary , timesale , or tradex . You can include one or more of these filters when you create the stream initially, but once the stream is started, you cannot update the filter. Account Streaming Account event streaming is presently in Beta. It is only available to Tradier Brokerage account holders and should only be used in production applications with caution. Account streaming can include one or more of your Tradier accounts but is limited to live or sandbox, not both together. For example, if you have an individual cash account, an IRA, and a separate margin account, you can have a running stream to check for orders from one or more of those accounts in a single stream — by default the stream covers all accounts tied to the session’s token, and you can exclude specific ones (see WebSocket Account Data Streaming ). Currently, order events are the primary data point sent via account streaming. • [Create Market Session](https://staging-docs.tradier.com/streaming/create-market-session.md): Initiate a new market session to enable real-time streaming of market data. This allows users to receive continuous updates and events for dynamic market analysis and decision-making. Market data streaming is only available in the live environment, not in the sandbox environment. • [Create Account Session](https://staging-docs.tradier.com/streaming/create-account-session.md): Create an Account Session to initiate a real-time stream of events specific to a user’s account. This allows you to monitor account activity continuously and respond to updates as they occur. • [HTTP Streaming](https://staging-docs.tradier.com/streaming/http-streaming.md): 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 Plain text GET https://stream.tradier.com/v1/markets/events GET https://stream.tradier.com/v1/markets/events Headers Header Required Values/Example Default 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 Parameter Type Required Values/Example Default 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 Python 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 JSON {"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 Plain text POST https://stream.tradier.com/v1/markets/events POST https://stream.tradier.com/v1/markets/events Same headers and parameters as GET above, sent as form fields in the request body instead of the query string. Same return shape. • [WebSocket Market Data Streaming](https://staging-docs.tradier.com/streaming/websocket-market-data-streaming.md): Stream market updates using WebSocket streaming. You will receive a different payload depending on the market event that occurred — details about each event’s fields are in Streaming Market Data . You can continually update the data in your stream by resending this request payload using your existing sessionid . 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. Once connected and streaming data, to change the symbols you’re subscribed to, simply resend your request payload with an updated symbols list using the same sessionid — no reconnect required. If your sessionid has expired, you’ll need a new one. filter cannot be changed this way — it’s fixed for the lifetime of a given WebSocket connection (see Streaming for more on this distinction). While we do not publish exact symbol limits, we monitor for abuse (e.g. requesting an entire exchange’s worth of symbols). Ask for what you need and you should be fine. It is not permitted to open more than one session at a time. Note that WebSocket streaming uses a different host: wss://ws.tradier.com Plain text wss://ws.tradier.com/v1/markets/events wss://ws.tradier.com/v1/markets/events Request Payload Parameter Type Detail Required Values/Example Default symbols array List of symbols (equity or option) to subscribe to Yes ["AAPL", "TSLA250815C00150000"] N/A sessionid string Session ID retrieved from the create market session endpoint Yes "9D1C7018CFEB6F8ECF8CAA58B33" N/A filter array Types of payloads to include in the stream No ["trade","quote","summary","timesale","tradex"] All payload types linebreak boolean Insert a line break after a completed payload No true false validOnly boolean Include only ticks considered valid by the exchange No true true advancedDetails boolean Include advanced/extended details in timesale payloads No true false linebreak , validOnly , and advancedDetails are documented as JSON booleans, though examples elsewhere are sometimes shown as quoted strings ("true"/"false") — send actual boolean true / false values in your JSON payload. In the event of validation issues with your request, expect an error payload: JSON {"error":"1234 is not a valid symbol"} Code Example (Python) Python import asyncio import websockets async def ws_connect(): uri = "wss://ws.tradier.com/v1/markets/events" async with websockets.connect(uri, ssl=True, compression=None) as websocket: payload = '{"symbols": ["SPY"], "filter": ["quote"], "sessionid": "SESSION_ID", "linebreak": true}' await websocket.send(payload) async for message in websocket: print(f"<<< {message}") asyncio.run(ws_connect()) Response Example JSON {"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"} • [WebSocket Account Data Streaming](https://staging-docs.tradier.com/streaming/websocket-account-data-streaming.md): This API is presently in Beta. It is only available to Tradier Brokerage account holders and should only be used in production applications with caution. Stream account updates using WebSocket streaming. You will receive a different payload depending on the account event that occurred — details about each event’s fields are in Streaming Account Events . You can continually update the data in your stream by resending this request payload using your existing sessionid . Note: in order to stream data, you must first create a streaming session via Create Account Session . Upon receiving a sessionid , you have up to 5 minutes to connect to a streaming endpoint before the session expires. Once connected and streaming data, to make modifications to your current streaming connection, simply resend your request payload using the existing sessionid . If your sessionid has expired, you’ll need a new one. While we do not publish exact limits, we monitor for abuse. It is not permitted to open more than one session at a time. Note that WebSocket streaming uses a different host: wss://ws.tradier.com Plain text wss://ws.tradier.com/v1/accounts/events wss://ws.tradier.com/v1/accounts/events If you’re developing with a paper trading account, use wss://sandbox-ws.tradier.com instead (account data only — there is no market data streaming in the sandbox environment). Request Payload Parameter Type Required Values/Example events array Yes ["order"] sessionid string Yes "9D1C7018CFEB6F8ECF8CAA58B33" excludeAccounts array No ["6YA00001", "6YA00002"] The account-scoping field on this payload is excludeAccounts — an exclude list, not an include list. By default the stream covers all accounts associated with the session's token; list account numbers here only if you want to exclude them from the stream. (An earlier draft of this page incorrectly documented an accounts include-list field — that was never correct; this section reflects the real payload shape.) Code Example (Python) Python import asyncio import websockets async def connect_and_consume(): uri = "wss://ws.tradier.com/v1/accounts/events" async with websockets.connect(uri) as websocket: payload = '{"events": ["order"], "sessionid": "SESSION_ID", "excludeAccounts": []}' await websocket.send(payload) while True: response = await websocket.recv() print(f"< {response}") asyncio.run(connect_and_consume()) Return Examples JSON {"id": 1107075, "event": "order", "status": "open", "type": "limit", "price": 10.0, "stop_price": 0.0, "avg_fill_price": 0.0, "executed_quantity": 0.0, "last_fill_quantity": 0.0, "remaining_quantity": 2.0, "transaction_date": "2021-08-09T20:05:35.277Z", "create_date": "2021-08-09T20:05:35.277Z", "account": "6YA"} {"id": 1107075, "event": "order", "status": "pending", "type": "limit", "price": 10.0, "stop_price": 0.0, "avg_fill_price": 0.0, "executed_quantity": 0.0, "last_fill_quantity": 0.0, "remaining_quantity": 2.0, "transaction_date": "2021-08-09T20:05:35.277Z", "create_date": "2021-08-09T20:05:35.277Z", "account": "6YA"} {"id": 1107075, "event": "order", "status": "filled", "type": "limit", "price": 10.0, "stop_price": 0.0, "avg_fill_price": 10.0, "executed_quantity": 2.0, "last_fill_quantity": 0.0, "remaining_quantity": 0.0, "transaction_date": "2021-08-09T20:05:35.277Z", "create_date": "2021-08-09T20:05:35.277Z", "account": "6YA"} • [Watchlists](https://staging-docs.tradier.com/watchlists.md): Manage personalized collections of financial instruments to monitor and organize assets of interest. This section enables users to create, retrieve, update, and delete watchlists, as well as add or remove symbols within them for streamlined tracking and analysis. ### `id` vs. `public_id` Each watchlist has two identifiers: * **`id`** — the internal/private watchlist identifier, used when making authenticated API calls (e.g. `GET`/`PUT`/`DELETE /v1/watchlists/{watchlist_id}`) against your own watchlists. * **`public_id`** — a separate identifier used specifically for sharing a watchlist or generating a public URL to it. • [Get All Watchlists](https://staging-docs.tradier.com/watchlists/get-all-watchlists.md): Retrieve a complete list of all watchlists associated with a user’s account. This section allows users to view the watchlists they have created, enabling efficient management and monitoring of their tracked assets. Note: when only a single watchlist (or a single item within one) is returned, it may be presented as an object rather than an array. This is a known API-wide JSON conversion behavior — see the "Response Format" page in the Overview section for the general explanation and example. • [Create Watchlist](https://staging-docs.tradier.com/watchlists/create-watchlist.md): Create a new watchlist by specifying a name and optionally including symbols at the time of creation. This allows users to organize and monitor a customized set of securities within their brokerage account for easy access and tracking. • [Get Specific Watchlist](https://staging-docs.tradier.com/watchlists/get-specific-watchlist.md): Fetch detailed information about a specific watchlist using its unique identifier. This allows users to access the watchlist’s contents and metadata, enabling efficient tracking and management of selected assets. • [Update Watchlist](https://staging-docs.tradier.com/watchlists/update-watchlist.md): Modify an existing watchlist's name and/or symbol list. `name` is required on every request. `symbols` is optional — when provided, it is a comma-delimited list that replaces the full symbol list on the watchlist; omit it to leave the existing symbols untouched. • [Delete Watchlist](https://staging-docs.tradier.com/watchlists/delete-watchlist.md): Remove an existing watchlist from your account to stop tracking its associated assets. This action permanently deletes the specified watchlist and updates your active watchlists accordingly. • [Add Symbols to Watchlist](https://staging-docs.tradier.com/watchlists/add-symbols-to-watchlist.md): Add one or more symbols to an existing watchlist, updating its contents to reflect the latest selections. If a symbol already exists in the watchlist, it will be overwritten with the new data. This allows users to efficiently manage and customize their watchlists for real-time tracking. • [Remove Symbol from Watchlist](https://staging-docs.tradier.com/watchlists/remove-symbol-from-watchlist.md): Remove a symbol from an existing watchlist to keep your tracking focused and up-to-date. This operation updates the watchlist by eliminating the specified symbol, allowing you to manage and customize your watchlist contents efficiently. • [Responses](https://staging-docs.tradier.com/responses.md): These are common responses from our various API endpoints that we post here as examples for your reference. • [Access Token](https://staging-docs.tradier.com/responses/access-token.md): If using OAuth with the Tradier API, this is the structure and details JSON { "access_token": "0XcZIRtv12o89347S8B4GUu0K", "refresh_token": "MjAJkrGE90812jkOG7Rj3QGGl", "scope": "read write trade market", "issued_at": "2020-01-21T15:55:35.000-05:00", "status": "approved", "expires_in": 86399 } Field Description access_token The access token granted by this call refresh_token If your application is granted refresh tokens then one will also be included in this payload scope The scopes authorized to the access token (space-delimited). See [Scopes](../../overview/authentication/index.md) for what each value ( read , write , market , trade , stream ) grants. issued_at When the access token is granted status The status of the access token - For future use expires_in Time to expiration • [Balances](https://staging-docs.tradier.com/responses/balances.md): The return from the /balances endpoint Response: JSON { "balances": { "option_short_value": 0, "total_equity": 17798.360000000000000000000000, "account_number": "VA00000000", "account_type": "margin", "close_pl": -4813.000000000000000000, "current_requirement": 2557.00000000000000000000, "equity": 0, "long_market_value": 11434.50000000000000000000, "market_value": 11434.50000000000000000000, "open_pl": 546.900000000000000000000000, "option_long_value": 8877.5000000000000000000, "option_requirement": 0, "pending_orders_count": 0, "short_market_value": 0, "stock_long_value": 2557.00000000000000000000, "total_cash": 6363.860000000000000000000000, "uncleared_funds": 0, "pending_cash": 0, // if type is 'margin' "margin": { "fed_call": 0, "maintenance_call": 0, "option_buying_power": 6363.860000000000000000000000, "stock_buying_power": 12727.7200000000000000, "stock_short_value": 0, "sweep": 0 }, // if type is 'cash' "cash": { "cash_available": 4343.38000000, "sweep": 0, "unsettled_funds": 1310.00000000 }, // if type is 'pdt' "pdt": { "fed_call": 0, "maintenance_call": 0, "option_buying_power": 6363.860000000000000000000000, "stock_buying_power": 12727.7200000000000000, "stock_short_value": 0 } } } Definitions: Field Description `option_shot_value` Value of short option positions in the account total_equity Total account value account_number Account number account_type Type of the account close_pl Gain/Loss of current session's closed positions current_requirement Account's maintenance margin equity Equity value long_market_value Long market value market_value Market value open_pl Total gain/loss of current account's positions option_long_value Value of long option positions option_requirement Account's total option requirement pending_orders_count Count of all pending/open orders short_market_value Short market value stock_long_value Value of long equity positions total_cash Total cash in the account uncleared_funds Cash unavailable for trading in the account pending_cash Amount of cash being held for open orders If account is type ‘margin’: Field Description margin.fed_call Amount that the account is in deficit for trades that have occurred but not been paid for margin.maintenance_call The amount that the account is under the minimum equity required to support the current positions margin.option_buying_power Amount of funds available to purchase non-marginable securities margin.stock_buying_power Amount of funds available to purchase fully marginable securities margin.stock_short_value Value of short stocks margin.sweep Dollar amount of cash currently held in the sweep vehicle (e.g., money market fund). If account is type ‘cash’: Field Description cash.cash_available The cash currently available for trading cash.sweep Dollar amount of cash currently held in the sweep vehicle (e.g., money market fund). cash.unsettled_funds Cash that is in the account from recent stock or option sales, but has not yet settled; cash from stock and option sales occurring during the previous trading day. If account is type ‘pdt’: PDT = Pattern Day Trader. This object appears when an account has been flagged as a Pattern Day Trader (typically triggered by 4+ day trades within 5 business days in a margin account with less than $25,000 equity). Field Description pdt.fed_call Amount that the account is in deficit for trades that have occurred but not been paid for pdt.maintenance_call Amount that the account is under the minimum equity required in the account to support the current positions pdt.option_buying_power Amount of funds available to purchase non-marginable securities pdt.stock_buying_power Amount of funds available to purchase fully marginable securities pdt.stock_short_value Value of short stocks • [Calendar](https://staging-docs.tradier.com/responses/calendar.md): The return from the /calendar endpoint, which lists market days for a given month/year along with each day’s status and trading session hours. Response: JSON { "calendar": { "month": 4, "year": 2019, "days": { "day": [ { "date": "2019-04-01", "status": "open", "description": "Market is open", "premarket": { "start": "07:00", "end": "09:24" }, "open": { "start": "09:30", "end": "16:00" }, "postmarket": { "start": "16:00", "end": "20:00" }, ... ] } } } Definitions: Field Description date The date status Status of the market, one of: open, closed description Details about the market status start Time the market opens in Eastern Time (NYC) end Time the market closes in Eastern Time (NYC) • [Clock](https://staging-docs.tradier.com/responses/clock.md): Response: JSON { "clock": { "date": "2019-05-06", "description": "Market is open from 09:30 to 16:00", "state": "open", "timestamp": 1557156988, "next_change": "16:00", "next_state": "postmarket" } } Definitions: Field Description date Current date description Displayable description of the status state Market state, one of: premarket, open, postmarket, closed timestamp UNIX timestamp of the present time next_change Next state change in hours/min next_state Next state change • [Gainloss](https://staging-docs.tradier.com/responses/gainloss.md): Response JSON { "gainloss": { "closed_position": [ { "close_date": "2018-10-31T00:00:00.000Z", "cost": 12.7, "gain_loss": -2.64, "gain_loss_percent": -20.7874, "open_date": "2018-06-19T00:00:00.000Z", "proceeds": 10.06, "quantity": 1.0, "symbol": "GE", "term": 134 }, { "close_date": "2018-09-21T00:00:00.000Z", "cost": 3.05, "gain_loss": -3.05, "gain_loss_percent": -100.0, "open_date": "2018-09-18T00:00:00.000Z", "proceeds": 0.0, "quantity": 1.0, "symbol": "SNAP180921P00008500", "term": 3 }, { "close_date": "2018-09-19T00:00:00.000Z", "cost": 913.95, "gain_loss": 6.05, "gain_loss_percent": 0.662, "open_date": "2018-09-18T00:00:00.000Z", "proceeds": 920.0, "quantity": 100.0, "symbol": "SNAP", "term": 1 }, { "close_date": "2018-06-25T00:00:00.000Z", "cost": 25.05, "gain_loss": -25.05, "gain_loss_percent": -100.0, "open_date": "2018-06-22T00:00:00.000Z", "proceeds": 0.0, "quantity": 1.0, "symbol": "SPY180625C00276000", "term": 3 } ] } } Definitions Field Description close_date Date the position was closed cost Total cost basis of the position (purchase price times quantity, in dollars) gain_loss Gain or loss on the position gain_loss_percent Gain or loss represented as a percent open_date Date the position was opened proceeds Total amount received for the position quantity Quantity of shares/contracts symbol Symbol of the security held term Term in months the position was held • [History](https://staging-docs.tradier.com/responses/history.md): Response JSON { "history": { "event": [ { "amount": 10.06, "date": "2018-10-31T00:00:00Z", "type": "trade", "trade": { "commission": 0.0000000000, "description": "GENERAL ELECTRIC COMPANY", "price": 10.060000, "quantity": -1.00000000, "symbol": "GE", "trade_type": "Equity" } }, { "amount": 0.12, "date": "2018-10-25T00:00:00Z", "type": "dividend", "adjustment": { "description": "GENERAL ELECTRIC COMPANY", "quantity": 0.00000000 } }, { "amount": 0, "date": "2018-09-21T00:00:00Z", "type": "option", "option": { "option_type": "OPTEXP", "description": "Expired", "quantity": -1.00000000 } }, { "amount": -13.05, "date": "2018-06-19T00:00:00Z", "type": "trade", "trade": { "commission": 0.0000000000, "description": "GENERAL ELECTRIC COMPANY", "price": 13.050000, "quantity": 1.00000000, "symbol": "GE", "trade_type": "Equity" } }, { "amount": -129.05, "date": "2018-05-23T00:00:00Z", "type": "trade", "trade": { "commission": 0.0000000000, "description": "CALL GE 06\/22\/18 14", "price": 1.290000, "quantity": 1.00000000, "symbol": "GE180622C00014000", "trade_type": "Option" } }, { "amount": -51.05, "date": "2018-05-23T00:00:00Z", "type": "trade", "trade": { "commission": 0.0000000000, "description": "CALL GE 06\/22\/18 15", "price": 0.510000, "quantity": 1.00000000, "symbol": "GE180622C00015000", "trade_type": "Option" } }, { "amount": 99.95, "date": "2018-05-23T00:00:00Z", "type": "trade", "trade": { "commission": 0.0000000000, "description": "CALL GE 06\/22\/18 14", "price": 1.000000, "quantity": -1.00000000, "symbol": "GE180622C00014000", "trade_type": "Option" } }, { "amount": -3000.00, "date": "2018-05-23T00:00:00Z", "type": "journal", "journal": { "description": "6YA-00005 TO 6YA-00102", "quantity": 0.00000000 } }, { "amount": 187.82, "date": "2018-05-21T00:00:00Z", "type": "trade", "trade": { "commission": 0.0000000000, "description": "APPLE INC", "price": 187.820100, "quantity": -1.00000000, "symbol": "AAPL", "trade_type": "Equity" } }, { "amount": 2500.00, "date": "2018-05-11T00:00:00Z", "type": "journal", "journal": { "description": "TFR FROM ACCT VA-00000-0", "quantity": 0.00000000 } }, { "amount": -79.09, "date": "2018-04-19T00:00:00Z", "type": "trade", "trade": { "commission": 0.0000000000, "description": "EXXON MOBIL CORP", "price": 79.090000, "quantity": 1.00000000, "symbol": "XOM", "trade_type": "Equity" } }, { "amount": 0, "date": "2017-07-19T00:00:00Z", "type": "option", "option": { "option_type": "expiration", "description": "Expired", "quantity": -2.00000000 } }, { "amount": 0, "date": "2026-04-14T00:00:00Z", "type": "option", "option": { "symbol": "DRN260417C00009000", "description": "DRN260417C00009000", "quantity": 1, "option_type": "assignment" } } ] } } Definitions Each history event has a common top-level structure, plus a nested sub-object whose fields depend on the event’s type ( trade , dividend / adjustment , option , or journal ). Top-level fields Field Description amount Value of transaction date Date of event type Type of event that occurred. One of: trade, option, journal, dividend (dividend events nest their details under "adjustment") trade (nested under “trade” when type is “trade”) Field Description trade.commission Commission trade.description Text description of the traded security trade.price Price trade.quantity Quantity of shares/contracts trade.symbol Symbol of the security held trade.trade_type Security type of the trade (Equity, Option) adjustment (nested under “adjustment” when type is “dividend”) Field Description adjustment.description Text description of the dividend/adjustment event adjustment.quantity Quantity of shares/contracts affected option (nested under “option” when type is “option”) Field Description option.option_type Type of option event, e.g. OPTEXP, expiration option.description Text description of the option event option.quantity Quantity of contracts affected journal (nested under “journal” when type is “journal”) Field Description journal.description Text description of the journal entry (e.g. account transfer details) journal.quantity Quantity of shares/contracts affected (0 for cash-only journal entries) • [Historical Market Data](https://staging-docs.tradier.com/responses/historical-market-data.md): Response JSON { "history": { "day": [ { "date": "2019-01-02", "open": 154.89, "high": 158.85, "low": 154.23, "close": 157.92, "volume": 37039737 }, { "date": "2019-01-03", "open": 143.98, "high": 145.72, "low": 142.0, "close": 142.19, "volume": 91312195 }, { "date": "2019-01-04", "open": 144.53, "high": 148.5499, "low": 143.8, "close": 148.26, "volume": 58607070 } ... ] } } Definitions Field Description date Date of the data point open Open price high Highest price low lowest price close closing price volume volume • [Orders](https://staging-docs.tradier.com/responses/orders.md): Response JSON { "orders": { "order": [ { "id": 228175, "type": "limit", "symbol": "AAPL", "side": "buy", "quantity": 50.00000000, "status": "expired", "duration": "pre", "price": 22.0, "avg_fill_price": 0.00000000, "exec_quantity": 0.00000000, "last_fill_price": 0.00000000, "last_fill_quantity": 0.00000000, "remaining_quantity": 0.00000000, "create_date": "2018-06-01T12:02:29.682Z", "transaction_date": "2018-06-01T12:30:02.385Z", "class": "equity" }, { "id": 228749, "type": "market", "symbol": "SPY", "side": "buy_to_open", "quantity": 1.00000000, "status": "expired", "duration": "pre", "avg_fill_price": 0.00000000, "exec_quantity": 0.00000000, "last_fill_price": 0.00000000, "last_fill_quantity": 0.00000000, "remaining_quantity": 0.00000000, "create_date": "2018-06-06T20:16:17.342Z", "transaction_date": "2018-06-06T20:16:17.357Z", "class": "option", "option_symbol": "SPY180720C00274000" }, { "id": 229063, "type": "debit", "symbol": "SPY", "side": "buy", "quantity": 1.00000000, "status": "canceled", "duration": "pre", "price": 42.0, "avg_fill_price": 0.00, "exec_quantity": 0.00000000, "last_fill_price": 0.00000000, "last_fill_quantity": 0.00000000, "remaining_quantity": 0.00000000, "create_date": "2018-06-12T21:13:36.076Z", "transaction_date": "2018-06-12T21:18:41.604Z", "class": "combo", "num_legs": 2, "strategy": "covered call", "leg": [ { "id": 229064, "type": "debit", "symbol": "SPY", "side": "buy", "quantity": 100.00000000, "status": "canceled", "duration": "pre", "price": 42.0, "avg_fill_price": 0.00000000, "exec_quantity": 0.00000000, "last_fill_price": 0.00000000, "last_fill_quantity": 0.00000000, "remaining_quantity": 0.00000000, "create_date": "2018-06-12T21:13:36.076Z", "transaction_date": "2018-06-12T21:18:41.587Z", "class": "equity" }, { "id": 229065, "type": "debit", "symbol": "SPY", "side": "sell_to_close", "quantity": 1.00000000, "status": "canceled", "duration": "pre", "price": 42.0, "avg_fill_price": 0.00000000, "exec_quantity": 0.00000000, "last_fill_price": 0.00000000, "last_fill_quantity": 0.00000000, "remaining_quantity": 0.00000000, "create_date": "2018-06-12T21:13:36.076Z", "transaction_date": "2018-06-12T21:18:41.597Z", "class": "option", "option_symbol": "SPY180720C00274000" } ] }, { "id": 229123, "type": "credit", "symbol": "SPY", "side": "buy", "quantity": 1.00000000, "status": "expired", "duration": "pre", "price": 0.8, "avg_fill_price": 0.00, "exec_quantity": 0.00000000, "last_fill_price": 0.00000000, "last_fill_quantity": 0.00000000, "remaining_quantity": 0.00000000, "create_date": "2018-06-13T16:54:39.812Z", "transaction_date": "2018-06-13T20:55:00.069Z", "class": "multileg", "num_legs": 4, "strategy": "condor", "leg": [ { "id": 229124, "type": "credit", "symbol": "SPY", "side": "buy_to_open", "quantity": 1.00000000, "status": "expired", "duration": "pre", "price": 0.8, "avg_fill_price": 0.00000000, "exec_quantity": 0.00000000, "last_fill_price": 0.00000000, "last_fill_quantity": 0.00000000, "remaining_quantity": 0.00000000, "create_date": "2018-06-13T16:54:39.812Z", "transaction_date": "2018-06-13T20:55:00.069Z", "class": "option", "option_symbol": "SPY180720C00274000" }, { "id": 229125, "type": "credit", "symbol": "SPY", "side": "sell_to_open", "quantity": 1.00000000, "status": "expired", "duration": "pre", "price": 0.8, "avg_fill_price": 0.00000000, "exec_quantity": 0.00000000, "last_fill_price": 0.00000000, "last_fill_quantity": 0.00000000, "remaining_quantity": 0.00000000, "create_date": "2018-06-13T16:54:39.812Z", "transaction_date": "2018-06-13T20:55:00.069Z", "class": "option", "option_symbol": "SPY180720C00275000" }, { "id": 229126, "type": "credit", "symbol": "SPY", "side": "sell_to_open", "quantity": 1.00000000, "status": "expired", "duration": "pre", "price": 0.8, "avg_fill_price": 0.00000000, "exec_quantity": 0.00000000, "last_fill_price": 0.00000000, "last_fill_quantity": 0.00000000, "remaining_quantity": 0.00000000, "create_date": "2018-06-13T16:54:39.812Z", "transaction_date": "2018-06-13T20:55:00.069Z", "class": "option", "option_symbol": "SPY180720C00276000" }, { "id": 229127, "type": "credit", "symbol": "SPY", "side": "buy_to_open", "quantity": 1.00000000, "status": "expired", "duration": "pre", "price": 0.8, "avg_fill_price": 0.00000000, "exec_quantity": 0.00000000, "last_fill_price": 0.00000000, "last_fill_quantity": 0.00000000, "remaining_quantity": 0.00000000, "create_date": "2018-06-13T16:54:39.812Z", "transaction_date": "2018-06-13T20:55:00.069Z", "class": "option", "option_symbol": "SPY180720C00277000" } ] } ] } } Definitions Field Description id Unique identifier for the order type Single-leg, One of: market, limit, stop, stop_limit Multi-leg, One of: market, debit, credit, even symbol Security symbol or underlying security symbol side Equity, One of: buy, buy to cover, sell, sell_short Option, One of: buy to open, buy to close, sell to open, sell to close quantity Number of shares or contracts status One of: open, partially_filled, filled, expired, canceled, pending, rejected, error duration One of: day, pre, post, gtc price Limit price if applicable avg_fill_price Average fill price exec_quantity Total number of shares/contracts filled last_fill_price Last fill price last_fill_quantity Last fill quantity remaining_quantity Number of shares/contracts remaining create_date Date the order was created transaction_date Date the order was last updated class One of: equity, option, combo, multileg strategy One of: freeform, covered call, protective put, strangle, straddle, spread, collar, butterfly, condor, unknown option_symbol OCC option symbol stop_price Stop price if applicable reason_description Rejection details if applicable tag A user-created tag attached to the order at the time of submission, useful for tracking orders and strategies • [Positions](https://staging-docs.tradier.com/responses/positions.md): Response JSON { "positions": { "position": [ { "cost_basis": 207.01, "date_acquired": "2018-08-08T14:41:11.405Z", "id": 130089, "quantity": 1.00000000, "symbol": "AAPL" }, { "cost_basis": 1870.70, "date_acquired": "2018-08-08T14:42:00.774Z", "id": 130090, "quantity": 1.00000000, "symbol": "AMZN" }, { "cost_basis": 50.41, "date_acquired": "2019-01-31T17:05:44.674Z", "id": 133590, "quantity": 1.00000000, "symbol": "CAH" }, { "cost_basis": 173.04, "date_acquired": "2019-03-11T16:51:51.987Z", "id": 134134, "quantity": 1.00000000, "symbol": "FB" }, { "cost_basis": 9.87, "date_acquired": "2019-03-11T16:50:33.156Z", "id": 134132, "quantity": 1.00000000, "symbol": "GE" }, { "cost_basis": 1772.54, "date_acquired": "2018-06-05T13:45:12.385Z", "id": 129298, "quantity": 13.00000000, "symbol": "IBM" }, { "cost_basis": 338.64, "date_acquired": "2019-03-11T16:50:55.774Z", "id": 134133, "quantity": 3.00000000, "symbol": "MSFT" } ] } } Definitions Field Description cost_basis Cost of the position date_acquired Date position was acquired (or most recently updated) id Unique position identifier quantity Number of shares/contracts (positive numbers indicate long positions, negative numbers indicate short positions) symbol Security symbol • [Search/Lookup Symbol](https://staging-docs.tradier.com/responses/search-lookup-symbol.md): Response JSON { "securities": { "security": [ { "symbol": "GOOGL", "exchange": "Q", "type": "stock", "description": "Alphabet Inc" }, { "symbol": "GOOG", "exchange": "Q", "type": "stock", "description": "Alphabet Inc. - Class C Capital Stock" } ] } } Definitions Field Description symbol Security symbol exchange Exchange code of the symbol type Type, one of: stock, option, etf, index, mutual_fund description Security detailed name or description • [Streaming Market Data](https://staging-docs.tradier.com/responses/streaming-market-data.md): Note: the Streaming API uses different field names than the REST market data API for the same concepts. For example, the streaming quote event uses bidsz / asksz / biddate / askdate , while the REST quotes response uses bidsize / asksize / bid_date / ask_date . Keep this in mind when writing code that consumes both APIs. Response JSON { "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" } Definitions: Quote The quote event is issued when a viable quote has been created on an exchange. This represents the most current bid/ask pricing available. Field Description type Type of event symbol Security symbol bid Bid price bidsz Bid size bidexch Bid exchange biddate Bid date ask Ask price asksz Ask size askexch Ask exchange askdate Ask date Trade The trade event is sent for all trade events at exchanges. By default, the trade event is filtered to only include valid ticks (removing trade corrections, errors, etc). Field Description type Type of event symbol Security symbol exch The exchange the event is reported from price Last price available size Size of the trade event cvol Cumulative volume for the session date Trade date last Last price (this is a duplicate of price) Summary The summary event reports session-level statistics (open, high, low, close) for a symbol as they occur during the trading session. Field Description type Type of event symbol Security symbol open Opening price high Highest price this session low Lowest price this session prevClose Previous close price Timesale Time and Sale represents a trade or other market event with price, like market open/close price, etc. Time and Sales are intended to provide information about trades in a continuous time slice (unlike Trade events which are supposed to provide snapshot about the current last trade). Timesale events are uniquely sequenced. Field Description type Type of event symbol Security symbol exch The exchange the event is reported from bid Bid price ask Ask price last Last price size Size of the event date Date of the event seq Sequence number for where this event fits in the continuous sequence for ordering these events and charting flag Trade condition flag(s) reported by the exchange for this tick (e.g. indicating things like odd-lot, out-of-sequence, or other special trade conditions). Tradier does not publish an enumerated list of possible values — treat this as an opaque exchange-defined (SIP/UTP) pass-through string; the example payload shows it empty when no special condition applies. cancel Was this a cancel event correction Was this a correction event session Market session type of the event Tradex The trade event is sent for all trade events at exchanges. This payload has more accurate information during the pre/post market sessions. If you plan streaming market data during these sessions, you should use this payload over the trade payload. Field Description type Type of event symbol Security symbol exch The exchange the event is reported from price Last price available size Size of the trade event cvol Cumulative volume for the session date Trade date last Last price (this is a duplicate of price) • [Streaming Account Events](https://staging-docs.tradier.com/responses/streaming-account-events.md): Account streaming will return orders as they are received and each time a status updates such as open, pending, filled, rejcted, or cancelled. In order to keep the stream active and prevent inactivity closure, a heartbeat payload will be sent regularly. Response JSON >>> 2025-12-09 12:02:51.050755{"event":"heartbeat","status":"active","timestamp":"2025-12-10T18:02:51.028929606Z"} >>> 2025-12-09 12:03:51.053280{"event":"heartbeat","status":"active","timestamp":"2025-12-09T18:03:51.029067177Z"} >>> 2025-12-09 12:04:51.058830{"event":"heartbeat","status":"active","timestamp":"2025-12-09T18:04:51.028185434Z"} { "id":1107075, "event":"order", "status":"open", "type": "limit", "price":10.0, "stop_price":0.0, "avg_fill_price":0.0, "exec_quantity":0.0, "last_fill_quantity":0.0, "remaining_quantity":2.0, "transaction_date":"2025-12-09T12:05:35.277Z", "create_date":"2025-12-09T12:05:35.277Z", "account":"6YA" } { "id":1107075, "event":"order", "status":"pending", "type": "limit", "price":10.0, "stop_price":0.0, "avg_fill_price":0.0, "exec_quantity":0.0, "last_fill_quantity":0.0, "remaining_quantity":2.0, "transaction_date":"2025-12-09T12:05:35.277Z", "create_date":"2025-12-09T12:05:35.277Z", "account":"6YA" } { "id":1107075, "event":"order", "status":"filled", "type": "limit", "price":10.0, "stop_price":0.0, "avg_fill_price":10.0, "exec_quantity":2.0, "last_fill_quantity":0.0, "remaining_quantity":0.0, "transaction_date":"2025-12-09T12:05:35.277Z", "create_date":"2025-12-09T12:05:35.277Z", "account":"6YA" } Definitions: Field Description id Unique identifier for the order event Event type, One of: order, heartbeat parent_id Unique identifier for the parent order account Account number status Order status, One of: open, partially filled, filled, expired, canceled, pending, rejected, calculated, accepted for_bidding, error, held type Single-leg, One of: market, limit, stop, stop_limit Multi-leg, One of: market, debit, credit, even tag Order tag if available price Limit price stop_price Stop price avg_fill_price Average fill price exec_quantity Total number of shares/contracts filled last_fill_quantity Last fill quantity remaining_quantity Number of shares/contracts remaining create_date Date the order was created transaction_date Date the order was last updated • [Time and Sales](https://staging-docs.tradier.com/responses/time-and-sales.md): Response and definitions for the time and sales data Response JSON { "series": { "data": [ { "time": "2025-07-01T09:30:00", "timestamp": 1751376600, "price": 207.26004999999998, "open": 206.72, "high": 208.38, "low": 206.1401, "close": 207.53, "volume": 9876387, "vwap": 207.32529 }, { "time": "2025-07-01T09:45:00", "timestamp": 1751377500, "price": 208.29500000000002, "open": 207.53, "high": 209.11, "low": 207.48, "close": 209.0848, "volume": 6249782, "vwap": 208.49322 }, { "time": "2025-07-01T10:00:00", "timestamp": 1751378400, "price": 209.12, "open": 209.06, "high": 209.68, "low": 208.56, "close": 209.66, "volume": 4434833, "vwap": 209.1358 } ] } } Definitions: Timesale (1min, 5min, 15min) Field Description time Time of the interval timestamp UNIX timestamp of the interval price Last price of the interval open Open price of the interval high High price of the interval low Low price of the interval close Close price of the interval volume Volume of the interval vwap Volume-weighted average price of the interval Timesale (tick) Field Description time Time of the interval timestamp UNIX timestamp of the interval price Last price of the interval volume Volume of the interval • [Watchlists](https://staging-docs.tradier.com/responses/watchlists.md): Response A single watch list: JSON { "watchlist":{ "name":"default", "id":"default", "public_id":"public-atea42pd", "items":{ "item":[ { "symbol":"AAPL", "id":"aapl" }, { "symbol":"AMZN", "id":"amzn" } ] } } } Definitions: Field Description id The watchlist's ID public_id The watchlist's public ID to be used for sharing name Watchlist's name items An array of the watchlist items symbol Item's symbol id Item's ID Response All watch lists a user has created JSON { "watchlists":{ "watchlist":[ { "name":"default", "id":"default", "public_id":"public-atea42pd" }, { "name":"a c d", "id":"a-c-d", "public_id":"public-5672lg0a" } ] } } Definitions: Field Description watchlists An array of watchlists id The watchlist's ID name Watchlist's name public_id The watchlist's public ID to be used for sharing • [ETB List](https://staging-docs.tradier.com/responses/etb-list.md): Response The ETB list contains securities that are able to be sold short with a Tradier Brokerage account. The list is quite comprehensive and can result in a long download response time. JSON { "securities": { "security": [ { "symbol": "SCS", "exchange": "N", "type": "stock", "description": "Steelcase Inc" }, { "symbol": "EXAS", "exchange": "Q", "type": "stock", "description": "Exact Sciences Corp" }, { "symbol": "BBL", "exchange": "N", "type": "stock", "description": "BHP Group PlcSponsored ADR" }, { "symbol": "WLH", "exchange": "N", "type": "stock", "description": "William Lyon Homes" }, { "symbol": "IBKC", "exchange": "Q", "type": "stock", "description": "IBERIABANK Corp" }, { "symbol": "BBT", "exchange": "N", "type": "stock", "description": "BB&T Corp" } ] } } Definitions: Field Description symbol Security symbol exchange Exchange code of the security type Type, one of: stock, option, etf, index, mutual_fund description Security detailed name or description • [Preview and Order](https://staging-docs.tradier.com/responses/preview-and-order.md): Response JSON { "order": { "status": "ok", "commission": 3.49000000, "cost": 34.715100000000, "fees": 0, "symbol": "T", "quantity": 1, "side": "buy", "type": "market", "duration": "day", "result": true, "order_cost": 31.225100000000, "margin_change": 0, "request_date": "2019-05-14T15:56:47.371", "extended_hours": false, "class": "equity", "strategy": "equity", "day_trades": 3 } } Definitions: Field Description status ok ( No true status for the order, as this is a preview) commission Commission to be paid for this order cost Total cost of the order fees Fees charged for this order symbol Security symbol quantity Quantity side Side type type of order duration Duration result true ( no real result yet, as this is a preview of the order ) order_cost Cost of the position margin_change Margin change to the account request_date Date of the request extended_hours If the order was placed during extended hours class Class of the order strategy Strategy (if applicable) day_trades Number of day trades that have been placed on the account • [User Profile](https://staging-docs.tradier.com/responses/user-profile.md): Response JSON { "profile": { "account": [ { "account_number": "VA000001", "classification": "individual", "date_created": "2016-08-01T21:08:55.000Z", "day_trader": false, "option_level": 6, "status": "active", "type": "margin", "last_update_date": "2016-08-01T21:08:55.000Z" }, { "account_number": "VA000002", "classification": "traditional_ira", "date_created": "2016-08-05T17:24:34.000Z", "day_trader": false, "option_level": 3, "status": "active", "type": "margin", "last_update_date": "2016-08-05T17:24:34.000Z" }, { "account_number": "VA000003", "classification": "rollover_ira", "date_created": "2016-08-01T21:08:56.000Z", "day_trader": false, "option_level": 2, "status": "active", "type": "cash", "last_update_date": "2016-08-01T21:08:56.000Z" } ], "id": "id-gcostanza", "name": "George Costanza" } } Definitions: Field Description account_number Account Number classification Class of account. One of: individual cash, entity cash, entity margin, individual margin, joint margin survivor, joint cash survivor, traditional ira, roth ira, rollover ira, sep ira, custodial cash, traditional sep ira, joint margin_tenant date_created Date account was created day_trader Marked as day trader option_level Account option level (1-6) status Current status of the account: One of: active, closed type Type of the account. One of: cash, margin last_update_date Date account was last updated • [Quotes](https://staging-docs.tradier.com/responses/quotes.md): Response JSON "quote": [ { "symbol": "NVDA", "description": "NVIDIA Corp", "exch": "Q", "type": "stock", "last": 175.23, "change": -2.59, "volume": 55438109, "open": 175.67, "high": 176.58, "low": 174.51, "close": null, "bid": 175.23, "ask": 175.24, "change_percentage": -1.46, "average_volume": 9573901, "last_volume": 100, "trade_date": 1757948508561, "prevclose": 177.82, "week_52_high": 184.48, "week_52_low": 86.62, "bidsize": 8, "bidexch": "Q", "bid_date": 1757948508000, "asksize": 5, "askexch": "P", "ask_date": 1757948508000, "root_symbols": "NVDA" }, { "symbol": "NVDA250919C00175000", "description": "NVDA Sep 19 2025 $175.00 Call", "exch": "Z", "type": "option", "last": 2.87, "change": -1.78, "volume": 38156, "open": 3.25, "high": 3.7, "low": 2.58, "close": null, "bid": 2.86, "ask": 2.88, "underlying": "NVDA", "strike": 175.0, "greeks": { "delta": 0.5652816604132407, "gamma": 0.05728070476977678, "theta": -0.3341843583802417, "vega": 0.07455884071440669, "rho": 0.011592433738162022, "phi": -0.011991846484704638, "bid_iv": 0.354346, "mid_iv": 0.3577, "ask_iv": 0.361055, "smv_vol": 0.358, "updated_at": "2025-09-15 13:59:03" }, "change_percentage": -38.28, "average_volume": 0, "last_volume": 3, "trade_date": 1757948483351, "prevclose": 4.65, "week_52_high": 0.0, "week_52_low": 0.0, "bidsize": 239, "bidexch": "W", "bid_date": 1757948508000, "asksize": 17, "askexch": "Z", "ask_date": 1757948508000, "open_interest": 76023, "contract_size": 100, "expiration_date": "2025-09-19", "expiration_type": "standard", "option_type": "call", "root_symbol": "NVDA" } ] } } Definitions: Field Description symbol Security symbol description Security detailed name or description exch Exchange code of the security type Type, one of: stock, option, etf, index, mutual_fund last Last price change Change (in dollars) volume Current days volume open Open price of the current session high High price of the current session low Low price of the current session close Close price of the current session bid Bid price ask Ask Price underlying Underlying security of the option (if applicable) strike Strike price of the option (if applicable) change_percentage Change (in percent) average_volume 90 day average volume of the security last_volume Volume of the last price trade_date Most recent trade date prevclose Previous close price week_52_high 52-week high price week_52_low 52-week low price bidsize Size of bid (in hundreds) bidexch Bid exchange code bid_date Date of bid price asksize Size of ask (in hundreds) Option Quote Fields The following fields are only present in an option quote (in addition to the base fields above): Field Description open_interest Number of outstanding option contracts that have not been closed or exercised contract_size Number of underlying shares represented by one option contract expiration_date The expiration date of the option contract expiration_type Type of expiration, e.g. standard, weekly, quarterly option_type One of: call, put root_symbol The root/underlying symbol used in the option's OCC symbol Greeks Fields The greeks object is only present in an option quote and contains the following fields: Field Description greeks.delta Rate of change of the option's price relative to a $1 change in the underlying's price greeks.gamma Rate of change of delta relative to a $1 change in the underlying's price greeks.theta Rate of change of the option's price relative to a one-day decrease in time to expiration (time decay) greeks.vega Rate of change of the option's price relative to a 1% change in implied volatility greeks.rho Rate of change of the option's price relative to a 1% change in interest rates greeks.phi Rate of change of the option's price relative to a 1% change in the dividend yield greeks.bid_iv Implied volatility calculated from the option's bid price greeks.mid_iv Implied volatility calculated from the midpoint of the bid/ask greeks.ask_iv Implied volatility calculated from the option's ask price greeks.smv_vol Tradier's smoothed volatility (SMV) estimate for the option greeks.updated_at Timestamp of when the greeks were last calculated Please note that some fields are only present in an option quote. These fields are only relevant to options. • [Streaming Session ID](https://staging-docs.tradier.com/responses/streaming-session-id.md): Response JSON { "stream": { "url": "wss://ws.tradier.com/v1/markets/events", "sessionid": "123e4567-e89b-12d3-a456-426614174000", "expires": "" } } Definitions: Field Description stream The streaming session object returned by the create market session or create account session endpoints. stream.url The WebSocket URL to connect to for this streaming session (e.g. wss://ws.tradier.com/v1/markets/events for market data, or wss://ws.tradier.com/v1/accounts/events for account events). stream.sessionid The session ID to include in your WebSocket (or HTTP streaming) request payload to authorize and identify the stream. stream.expires The expiration time of the session. Note: streaming session identifiers are short-lived. Per the Streaming API documentation, a streaming connection using this session will close automatically after 15 minutes of inactivity (no data flowing), at which point a new session ID must be requested before you can reconnect. • [Code Examples](https://staging-docs.tradier.com/code-examples.md): In this section, our goal is to provide you with a few simple examples of working scripts that you can use, or at least see the flow of completing basic operations with the API. All of the following examples will have a section with the example code, a section with an example response when that code is run, and a breakdown of that code and each element's purpose. • [Get a Quote](https://staging-docs.tradier.com/code-examples/get-a-quote.md): Code Example Python #!/usr/bin/env python3 import json import requests import sys API_KEY = <TOKEN> SINGLE = "AAPL" TOP_FEW = "AAPL,MSFT,NVDA,AMZN,META,GGOGL,GOOG,BRK.B,LLY,AVGO,TSLA,JPM,UNH,XOM,V" response = requests.post('https://api.tradier.com/v1/markets/quotes', data={'symbols': SINGLE, 'greeks':'true'}, headers={'Authorization': f'Bearer {API_KEY}', 'Accept': 'application/json'} ) try: result = response.json() except Exception as e: print(f"Error: {response.status_code}") print (e) print(response.text) sys.exit(1) json_formatted_str = json.dumps(result, indent=2) print(response.status_code) print(json_formatted_str) Response Example JSON 200 { "quotes": { "quote": { "symbol": "AAPL", "description": "Apple Inc", "exch": "Q", "type": "stock", "last": 253.24, "change": 0.93, "volume": 21640078, "open": 253.205, "high": 254.32, "low": 251.712, "close": null, "bid": 253.22, "ask": 253.25, "change_percentage": 0.37, "average_volume": 57388452, "last_volume": 100, "trade_date": 1758819401268, "prevclose": 252.31, "week_52_high": 260.1, "week_52_low": 169.2101, "bidsize": 2, "bidexch": "Q", "bid_date": 1758819401000, "asksize": 1, "askexch": "Z", "ask_date": 1758819401000, "root_symbols": "AAPL" } } } Step-by-Step Explainer Imports We'll want the ability to make an HTTP request and interpret the JSON response, so we will need libraries or built-in functionality in our script. API token You'll need your API Token from your account ( https://web.tradier.com/user/api ) to authorize the API call Symbols You can get a quote for a single financial instrument, such as a single equity or option, or you can gather several quotes at once by putting everything in a single string with commas separating the different elements. Request The request is a GET or POST call to the quotes endpoint. Make sure to have the symbols or OCC symbols instantiating correctly for the symbols parameter and similarly for the API_KEY, make sure the Authorization parameter includes 'Bearer ' and your token correctly or you will get a 401. Error Handling We expect to get a JSON response of one or more quotes, so by attempting to store JSON in a variable, we verify if the call was successful or not. If there is an exception, we print the status code and error message so we know what went wrong. Output If the call is successful, we can do a bit of formatting to prettify the response and then print it out. • [Get Time and Sales Data](https://staging-docs.tradier.com/code-examples/get-time-and-sales-data.md): Code Example Python # Version 3.6.1 import csv from datetime import datetime, timedelta import json import requests import sys API_KEY = <TOKEN> response = requests.get('https://api.tradier.com/v1/markets/timesales', params={'symbol':'AAPL', 'interval': '1min', 'start': '2025-09-25 09:30', 'end': '2025-09-25 10:30', 'session_filter': 'open'}, headers={'Authorization': f'Bearer {API_KEY}', 'Accept': 'application/json'} ) try: json_response = response.json() except Exception as e: print (e) print(response) print(response.text) sys.exit(1) if 'series' in json_response.keys(): if json_response['series'] is None: print(json_response) print("json_response is None") else: data = json_response['series']['data'] if type(data) is list: for item in data: print(item) else: print(data) else: print(json_response) Response Example JSON {'time': '2025-09-25T09:30:00', 'timestamp': 1758807000, 'price': 253.41005, 'open': 253.35, 'high': 254.32, 'low': 252.5001, 'close': 252.6901, 'volume': 1234413, 'vwap': 253.42805} {'time': '2025-09-25T09:31:00', 'timestamp': 1758807060, 'price': 252.36, 'open': 252.7, 'high': 252.75, 'low': 251.97, 'close': 252.445, 'volume': 384715, 'vwap': 252.31268} {'time': '2025-09-25T09:32:00', 'timestamp': 1758807120, 'price': 252.56504999999999, 'open': 252.48, 'high': 252.98, 'low': 252.1501, 'close': 252.23, 'volume': 312947, 'vwap': 252.51962} {'time': '2025-09-25T09:33:00', 'timestamp': 1758807180, 'price': 252.51, 'open': 252.265, 'high': 252.83, 'low': 252.19, 'close': 252.56, 'volume': 249513, 'vwap': 252.53244} {'time': '2025-09-25T09:34:00', 'timestamp': 1758807240, 'price': 252.29, 'open': 252.57, 'high': 252.6, 'low': 251.98, 'close': 252.01, 'volume': 248885, 'vwap': 252.2196} {'time': '2025-09-25T09:35:00', 'timestamp': 1758807300, 'price': 252.006, 'open': 252.01, 'high': 252.3, 'low': 251.712, 'close': 252.14, 'volume': 384087, 'vwap': 251.94752} {'time': '2025-09-25T09:36:00', 'timestamp': 1758807360, 'price': 252.45, 'open': 252.15, 'high': 252.75, 'low': 252.15, 'close': 252.615, 'volume': 226746, 'vwap': 252.56814} {'time': '2025-09-25T09:37:00', 'timestamp': 1758807420, 'price': 252.855, 'open': 252.625, 'high': 253.23, 'low': 252.48, 'close': 253.15, 'volume': 403100, 'vwap': 252.87479} {'time': '2025-09-25T09:38:00', 'timestamp': 1758807480, 'price': 253.085, 'open': 253.1742, 'high': 253.34, 'low': 252.83, 'close': 252.9556, 'volume': 274522, 'vwap': 253.07665} {'time': '2025-09-25T09:39:00', 'timestamp': 1758807540, 'price': 252.88, 'open': 252.96, 'high': 253.16, 'low': 252.6, 'close': 252.88, 'volume': 217812, 'vwap': 252.8723} {'time': '2025-09-25T09:40:00', 'timestamp': 1758807600, 'price': 252.585, 'open': 252.8953, 'high': 252.96, 'low': 252.21, 'close': 252.28, 'volume': 262997, 'vwap': 252.53439} {'time': '2025-09-25T09:41:00', 'timestamp': 1758807660, 'price': 252.24995, 'open': 252.275, 'high': 252.4999, 'low': 252.0, 'close': 252.04, 'volume': 168365, 'vwap': 252.21551} {'time': '2025-09-25T09:42:00', 'timestamp': 1758807720, 'price': 252.05505, 'open': 252.04, 'high': 252.27, 'low': 251.8401, 'close': 252.2599, 'volume': 209794, 'vwap': 252.0595} {'time': '2025-09-25T09:43:00', 'timestamp': 1758807780, 'price': 252.57, 'open': 252.27, 'high': 252.92, 'low': 252.22, 'close': 252.835, 'volume': 199889, 'vwap': 252.58579} {'time': '2025-09-25T09:44:00', 'timestamp': 1758807840, 'price': 252.75560000000002, 'open': 252.835, 'high': 252.94, 'low': 252.5712, 'close': 252.71, 'volume': 195692, 'vwap': 252.74924} {'time': '2025-09-25T09:45:00', 'timestamp': 1758807900, 'price': 252.77499999999998, 'open': 252.7025, 'high': 253.04, 'low': 252.51, 'close': 252.72, 'volume': 238656, 'vwap': 252.75404} {'time': '2025-09-25T09:46:00', 'timestamp': 1758807960, 'price': 252.93, 'open': 252.715, 'high': 253.17, 'low': 252.69, 'close': 253.0, 'volume': 121497, 'vwap': 252.95766} {'time': '2025-09-25T09:47:00', 'timestamp': 1758808020, 'price': 253.17000000000002, 'open': 252.965, 'high': 253.43, 'low': 252.91, 'close': 253.24, 'volume': 208538, 'vwap': 253.14761} {'time': '2025-09-25T09:48:00', 'timestamp': 1758808080, 'price': 253.06005, 'open': 253.23, 'high': 253.23, 'low': 252.8901, 'close': 253.04, 'volume': 202516, 'vwap': 253.07784} {'time': '2025-09-25T09:49:00', 'timestamp': 1758808140, 'price': 253.16, 'open': 252.99, 'high': 253.34, 'low': 252.98, 'close': 253.14, 'volume': 299774, 'vwap': 253.11835} {'time': '2025-09-25T09:50:00', 'timestamp': 1758808200, 'price': 253.425, 'open': 253.15, 'high': 253.74, 'low': 253.11, 'close': 253.6003, 'volume': 216942, 'vwap': 253.51893} {'time': '2025-09-25T09:51:00', 'timestamp': 1758808260, 'price': 253.69, 'open': 253.63, 'high': 253.92, 'low': 253.46, 'close': 253.49, 'volume': 262413, 'vwap': 253.71556} {'time': '2025-09-25T09:52:00', 'timestamp': 1758808320, 'price': 253.39999999999998, 'open': 253.485, 'high': 253.6, 'low': 253.2, 'close': 253.27, 'volume': 141368, 'vwap': 253.44549} {'time': '2025-09-25T09:53:00', 'timestamp': 1758808380, 'price': 253.03005000000002, 'open': 253.28, 'high': 253.28, 'low': 252.7801, 'close': 253.035, 'volume': 233362, 'vwap': 252.96338} {'time': '2025-09-25T09:54:00', 'timestamp': 1758808440, 'price': 252.93995, 'open': 253.03, 'high': 253.0799, 'low': 252.8, 'close': 252.84, 'volume': 94228, 'vwap': 252.95363} {'time': '2025-09-25T09:55:00', 'timestamp': 1758808500, 'price': 252.76999999999998, 'open': 252.84, 'high': 252.89, 'low': 252.65, 'close': 252.76, 'volume': 109545, 'vwap': 252.7871} {'time': '2025-09-25T09:56:00', 'timestamp': 1758808560, 'price': 252.70499999999998, 'open': 252.7608, 'high': 252.79, 'low': 252.62, 'close': 252.7765, 'volume': 92301, 'vwap': 252.69461} {'time': '2025-09-25T09:57:00', 'timestamp': 1758808620, 'price': 252.6175, 'open': 252.765, 'high': 252.765, 'low': 252.47, 'close': 252.69, 'volume': 111904, 'vwap': 252.61064} {'time': '2025-09-25T09:58:00', 'timestamp': 1758808680, 'price': 252.395, 'open': 252.72, 'high': 252.74, 'low': 252.05, 'close': 252.1, 'volume': 213950, 'vwap': 252.31551} {'time': '2025-09-25T09:59:00', 'timestamp': 1758808740, 'price': 252.155, 'open': 252.1, 'high': 252.34, 'low': 251.97, 'close': 252.31, 'volume': 181803, 'vwap': 252.16738} {'time': '2025-09-25T10:00:00', 'timestamp': 1758808800, 'price': 252.37, 'open': 252.33, 'high': 252.62, 'low': 252.12, 'close': 252.6, 'volume': 230734, 'vwap': 252.37421} {'time': '2025-09-25T10:01:00', 'timestamp': 1758808860, 'price': 252.45, 'open': 252.63, 'high': 252.68, 'low': 252.22, 'close': 252.48, 'volume': 117218, 'vwap': 252.48093} {'time': '2025-09-25T10:02:00', 'timestamp': 1758808920, 'price': 252.66, 'open': 252.5, 'high': 252.89, 'low': 252.43, 'close': 252.7201, 'volume': 242630, 'vwap': 252.74441} {'time': '2025-09-25T10:03:00', 'timestamp': 1758808980, 'price': 252.83255, 'open': 252.735, 'high': 253.0951, 'low': 252.57, 'close': 252.9897, 'volume': 218655, 'vwap': 252.9188} {'time': '2025-09-25T10:04:00', 'timestamp': 1758809040, 'price': 253.065, 'open': 253.0, 'high': 253.22, 'low': 252.91, 'close': 253.115, 'volume': 117525, 'vwap': 253.0542} {'time': '2025-09-25T10:05:00', 'timestamp': 1758809100, 'price': 253.41575, 'open': 253.12, 'high': 253.73, 'low': 253.1015, 'close': 253.7, 'volume': 158109, 'vwap': 253.39952} {'time': '2025-09-25T10:06:00', 'timestamp': 1758809160, 'price': 253.72255, 'open': 253.7074, 'high': 253.8369, 'low': 253.6082, 'close': 253.625, 'volume': 142886, 'vwap': 253.72432} {'time': '2025-09-25T10:07:00', 'timestamp': 1758809220, 'price': 253.575, 'open': 253.625, 'high': 253.78, 'low': 253.37, 'close': 253.384, 'volume': 111817, 'vwap': 253.61335} {'time': '2025-09-25T10:08:00', 'timestamp': 1758809280, 'price': 253.425, 'open': 253.3801, 'high': 253.55, 'low': 253.3, 'close': 253.38, 'volume': 106751, 'vwap': 253.42198} {'time': '2025-09-25T10:09:00', 'timestamp': 1758809340, 'price': 253.44, 'open': 253.39, 'high': 253.51, 'low': 253.37, 'close': 253.465, 'volume': 73668, 'vwap': 253.44304} {'time': '2025-09-25T10:10:00', 'timestamp': 1758809400, 'price': 253.5215, 'open': 253.4788, 'high': 253.75, 'low': 253.293, 'close': 253.7092, 'volume': 90625, 'vwap': 253.50384} {'time': '2025-09-25T10:11:00', 'timestamp': 1758809460, 'price': 253.70499999999998, 'open': 253.735, 'high': 253.81, 'low': 253.6, 'close': 253.64, 'volume': 115508, 'vwap': 253.71066} {'time': '2025-09-25T10:12:00', 'timestamp': 1758809520, 'price': 253.67000000000002, 'open': 253.66, 'high': 253.78, 'low': 253.56, 'close': 253.585, 'volume': 86217, 'vwap': 253.64856} {'time': '2025-09-25T10:13:00', 'timestamp': 1758809580, 'price': 253.695, 'open': 253.585, 'high': 253.83, 'low': 253.56, 'close': 253.743, 'volume': 93591, 'vwap': 253.70504} {'time': '2025-09-25T10:14:00', 'timestamp': 1758809640, 'price': 253.675, 'open': 253.75, 'high': 253.8, 'low': 253.55, 'close': 253.56, 'volume': 88243, 'vwap': 253.66748} {'time': '2025-09-25T10:15:00', 'timestamp': 1758809700, 'price': 253.595, 'open': 253.6, 'high': 253.75, 'low': 253.44, 'close': 253.48, 'volume': 83634, 'vwap': 253.60733} {'time': '2025-09-25T10:16:00', 'timestamp': 1758809760, 'price': 253.46994999999998, 'open': 253.4647, 'high': 253.5999, 'low': 253.34, 'close': 253.4, 'volume': 62724, 'vwap': 253.42656} {'time': '2025-09-25T10:17:00', 'timestamp': 1758809820, 'price': 253.235, 'open': 253.38, 'high': 253.39, 'low': 253.08, 'close': 253.095, 'volume': 113498, 'vwap': 253.25974} {'time': '2025-09-25T10:18:00', 'timestamp': 1758809880, 'price': 253.255, 'open': 253.09, 'high': 253.42, 'low': 253.09, 'close': 253.42, 'volume': 104466, 'vwap': 253.23618} {'time': '2025-09-25T10:19:00', 'timestamp': 1758809940, 'price': 253.49435, 'open': 253.4, 'high': 253.6516, 'low': 253.3371, 'close': 253.45, 'volume': 81800, 'vwap': 253.47642} {'time': '2025-09-25T10:20:00', 'timestamp': 1758810000, 'price': 253.6, 'open': 253.49, 'high': 253.75, 'low': 253.45, 'close': 253.58, 'volume': 115745, 'vwap': 253.61796} {'time': '2025-09-25T10:21:00', 'timestamp': 1758810060, 'price': 253.66500000000002, 'open': 253.59, 'high': 253.78, 'low': 253.55, 'close': 253.735, 'volume': 95618, 'vwap': 253.69018} {'time': '2025-09-25T10:22:00', 'timestamp': 1758810120, 'price': 253.805, 'open': 253.73, 'high': 253.9, 'low': 253.71, 'close': 253.8627, 'volume': 74411, 'vwap': 253.81051} {'time': '2025-09-25T10:23:00', 'timestamp': 1758810180, 'price': 253.87005, 'open': 253.85, 'high': 253.97, 'low': 253.7701, 'close': 253.9, 'volume': 113618, 'vwap': 253.88546} {'time': '2025-09-25T10:24:00', 'timestamp': 1758810240, 'price': 253.97505, 'open': 253.9, 'high': 254.08, 'low': 253.8701, 'close': 253.99, 'volume': 125266, 'vwap': 253.9701} {'time': '2025-09-25T10:25:00', 'timestamp': 1758810300, 'price': 253.89499999999998, 'open': 253.985, 'high': 254.04, 'low': 253.75, 'close': 253.7669, 'volume': 104192, 'vwap': 253.90282} {'time': '2025-09-25T10:26:00', 'timestamp': 1758810360, 'price': 253.80925, 'open': 253.77, 'high': 253.8799, 'low': 253.7386, 'close': 253.84, 'volume': 584054, 'vwap': 253.8357} {'time': '2025-09-25T10:27:00', 'timestamp': 1758810420, 'price': 253.99005, 'open': 253.88, 'high': 254.12, 'low': 253.8601, 'close': 254.08, 'volume': 123190, 'vwap': 254.01178} {'time': '2025-09-25T10:28:00', 'timestamp': 1758810480, 'price': 253.98545000000001, 'open': 254.075, 'high': 254.1199, 'low': 253.851, 'close': 253.86, 'volume': 98039, 'vwap': 254.0116} {'time': '2025-09-25T10:29:00', 'timestamp': 1758810540, 'price': 253.91000000000003, 'open': 253.89, 'high': 254.05, 'low': 253.77, 'close': 254.0, 'volume': 104597, 'vwap': 253.9311} {'time': '2025-09-25T10:30:00', 'timestamp': 1758810600, 'price': 253.98005, 'open': 254.02, 'high': 254.1, 'low': 253.8601, 'close': 254.035, 'volume': 143318, 'vwap': 253.94105} Step-by-Step Explainer: Imports For our imports/libraries, we need the ability to make HTTP requests and to parse JSON so 'requests' and 'JSON' are necessary in Python and something similar in whatever language you are using. Other useful tools for time and sales data can include the datetime library if we want to capture slices of time that are dynamic rather than static, and a CSV library for outputting data in a useful format. API Token We will, of course, need your API token from https://web.tradier.com/settings/api to authenticate. Symbol We can enter the symbol for which we want time and sales data as a variable or we can hard-code it in our call. The Request For this request, we have simple parameters hard-coded, with the exception of our API token. The intent of the request is to gather 1-minute bars for a one-hour block of time. Check the Response We check for JSON in our response, and if the response is not in a JSON format, it must be an error, which can be found in the response.text Checking for data in the JSON response If there is data to be found, it will be nested under the key 'series'. If this key is none and you expected to have time and sales data, check your parameters and possibly reach out to the tech support team. Printing Good Data If we do have data attached to the 'series' key it will be further nested under the 'data' key, and the value of that will be a dict for a single item, such as a single bar or a list for multiple items. Fall back Always good to have a fallback where the response is just printed to see what it contains in the event of an edge case • [Place an Order](https://staging-docs.tradier.com/code-examples/place-an-order-1.md): Placing an order Python # Version 3.6.1 #Imports import json import requests import sys #Tokens and Account Numbers API_TOKEN = "<PRODUCTION TOKEN>" LIVE_ACCOUNT = "<PRODUCTION ACCOUNT NUMBER>" SANDBOX_TOKEN = "<SANDBOX TOKEN>" SANDBOX_ACCOUNT = "<SANDBOX ACCOUNT NUMBER>" #Endpoints ENDPOINT = "sandbox" # api or sandbox # Sample Orders TEST_EQUITY = {'class': 'equity', 'symbol': 'AAPL', 'side': 'buy', 'quantity': '1', 'type': 'market', 'duration': 'day', 'preview': 'false' } TEST_OPTION = {'class': 'option', 'symbol': 'AAPL', 'option_symbol': 'AAPL250926C00260000', 'side': 'buy_to_open', 'quantity': '1', 'type': 'limit', 'duration': 'day', 'price': '2.45' } TEST_OTOCO = {'class': 'otoco', 'symbol': 'AAPL', 'option_symbol[0]': 'AAPL250926C00210000', 'side[0]': 'buy_to_open', 'quantity[0]': '1', 'duration[0]': 'day', 'type[0]': 'limit', 'price[0]': '0.55', 'option_symbol[1]': 'AAPL250926C00210000', 'side[1]': 'sell_to_close', 'quantity[1]': '1', 'duration[1]': 'gtc', 'type[1]': 'limit', 'price[1]': '0.75', 'option_symbol[2]': 'AAPL250926C00210000', 'side[2]': 'sell_to_close', 'quantity[2]': '1', 'duration[2]': 'gtc', 'type[2]': 'stop', 'stop[2]' : '0.05', 'tag': 'TEST-OTOCO' } #Post Request response = requests.post(f'https://{ENDPOINT}.tradier.com/v1/accounts/{SANDBOX_ACCOUNT}/orders', data= TEST_EQUITY, headers={'Authorization': f'Bearer {SANDBOX_TOKEN}', 'Accept': 'application/json'} ) #Checking Order Submission try: result = response.json() except Exception as e: print ("Error: {}".format(e)) print(response) print(type(response)) print("Status: {} -- {}".format(response.status_code, response.text)) sys.exit(1) print(result) #Getting the order number try: ORDERNUM = result['order']['id'] except Exception as e: print ("Error: {}".format(e)) sys.exit(1) # Get the actual order status response = requests.get(f'https://{ENDPOINT}.tradier.com/v1/accounts/{SANDBOX_ACCOUNT}/orders/{ORDERNUM}', params={'includeTags': 'true'}, headers={'Authorization': f'Bearer {SANDBOX_TOKEN}', 'Accept': 'application/json'} ) #Checking the Order Response try: json_response = response.json() json_formatted_str = json.dumps(json_response, indent=2) except Exception as e: print (e) print(response) print(response.text) sys.exit(1) #Print Order Status print(response.status_code) print(json_formatted_str) Sample Response JSON {'order': {'id': 19803614, 'status': 'ok', 'partner_id': '3a8bbee1-5184-4ffe-8a0c-294fbad1aee9'}} 200 { "order": { "id": 19803614, "type": "market", "symbol": "AAPL", "side": "buy", "quantity": 1.0, "status": "filled", "duration": "day", "avg_fill_price": 255.01, "exec_quantity": 1.0, "last_fill_price": 255.01, "last_fill_quantity": 1.0, "remaining_quantity": 0.0, "create_date": "2025-09-26T15:09:09.685Z", "transaction_date": "2025-09-26T15:09:09.803Z", "class": "equity" } } Explaination Imports Whatever codebase you are using, make sure you have the ability to make HTTP requests and to parse JSON Tokens and Account Numbers Insert line top Insert line below Delete. Whether you are using your live account or your sandbox account, you'll need your matching API token and account number. Endpoint For ease of switching between live or paper trading, you can use an endpoint variable with values of "api" or "sandbox" Sample Orders There are some sample order payloads for an equity order, an option order, or an OTOCO. POST Request For our actual order submission, we use a post request and harness all our variables for easy future editing. In this order submission, we are using our sandbox account and purchasing one share of AAPL Checking order submission The first step in confirming our order is to check if we get back JSON as error payloads will come back in the response.text If we decode JSON we know we are on the right track and can skip to printing the response on line 74. If we catch an error with the JSON decoding, then we should check the error, the returned HTTP status code, and the response.text for clues as to what went wrong. If successful, we print the return from the order submission, which will have a status and an order number, among other details. NOTE - A 200 OK response from order submission is not an indication that the order was correct/valid, only that the request was valid and received by our OMS system. An order can still be rejected even if the HTTP request/submission was accepted. Getting the order number If we were successful in the POST request, then we should get back an order number if the order was accepted by the OMS system. To confirm this, we check for an order number in: "result['order']['id']" If we hit an exception here, we again throw an error and end the process. Get the Order Status With a valid order number, we can check the actual status of the order. Remember, the 200 OK from submission is not a validation of the order, only a validation of the HTTP request. Now we use the proper endpoint, account number, and order number to get the order status and check if it is pending, open, partially filled, filled, or rejected. Checking the Order Response Just like before, our first test is JSON decoding the response. If it isn't JSON, then something was wrong with our request, and we want to make sure we have properly captured a valid order number and properly called for just that order's details. Printing Order Status If we make it through the try/except, we have an order payload that we can print out to check the status of the order we just submitted. This is the best practice to be sure that you not only submitted an order via the HTTP POST but that your order was accepted and not rejected, and to confirm its current status.