Tradovate API

Tradovate 'Not Found: md/subscribeQuote' Fix

Your auth flow works, your account socket is humming, and md/subscribeQuote still comes back Not found even though the endpoint is right there in the docs. You sent the request to the wrong WebSocket.

Verificato dal Trading Systems Team di PickMyTrade Ultimo aggiornamento
· 7 min read
Tradovate WebSocket client showing a Not found: md/subscribeQuote error response

Your auth flow worked, your account socket is humming along, and then you fire off a md/subscribeQuote to start streaming live prices and the server hands you back Not found: md/subscribeQuote, often mangled into something like "\"Not found: md/subscribeQuote\"" with escape characters piled on. The endpoint is right there in the docs. So why does Tradovate act like it doesn't exist?

Here's the short version: you sent the request to the wrong WebSocket. Quote subscriptions don't live on the same connection you use to sync your account or place orders. Fix which socket the request goes to and the error clears. Let's walk through exactly why this happens, how to route it correctly, and what tends to break next once the frame finally lands.

What “Not Found” Actually Means Here

Treat this like a 404 on a REST call. A 404 says the URL path doesn't exist on that server. Over Tradovate's WebSocket the logic is identical: every frame you send names an endpoint, and if the socket you're connected to doesn't serve that endpoint, the server replies Not found with the endpoint name echoed back at you.

Read that carefully, because it rules a lot out. It's not telling you your symbol is bad. It's not telling you your token expired. It's not telling you your JSON is malformed. It's telling you one thing: “there's no route for md/subscribeQuote on this connection.” And there's exactly one common reason for that.

The Cause: You're on the Account Socket, Not the Market-Data Socket

Tradovate runs two separate WebSocket services, and they are not interchangeable. People wire up the first one, get it authorized, watch account and order data flow perfectly, and then assume that same connection handles everything. It doesn't.

  • The account / API socket handles orders, positions, fills, account sync, and the rest of the entity data. This is where user/syncRequest, order/placeOrder, and account/list belong. Live is wss://live.tradovateapi.com/v1/websocket; demo is wss://demo.tradovateapi.com/v1/websocket.
  • The market-data socket handles live prices, quotes, the DOM, charts, histograms. This is where every md/ endpoint lives, including md/subscribeQuote, md/subscribeDOM, and md/getChart. Live is wss://md.tradovateapi.com/v1/websocket; demo is wss://md-demo.tradovateapi.com/v1/websocket.

Send md/subscribeQuote to the account socket and there's simply no matching route, so back comes Not found: md/subscribeQuote. The account socket won't drop a hint that you're knocking on the wrong door, it just reports the endpoint as missing. Here's the full host map so you can line up your environment:

Purpose Demo / Simulation Live
REST auth basehttps://demo.tradovateapi.com/v1/https://live.tradovateapi.com/v1/
Account / API socket (user/syncRequest, order/placeOrder)wss://demo.tradovateapi.com/v1/websocketwss://live.tradovateapi.com/v1/websocket
Market-data socket (md/subscribeQuote, md/getChart)wss://md-demo.tradovateapi.com/v1/websocketwss://md.tradovateapi.com/v1/websocket
Tradovate authentication response JSON showing both accessToken and mdAccessToken fields

The Fix: Open and Authorize a Second Socket for Quotes

You don't move your account socket. You add a market-data socket alongside it. Keep the account connection for orders and sync; open a brand-new WebSocket to the market-data host for prices. Here's the sequence that clears the error.

1

Grab both tokens from your auth response

When you authenticate, Tradovate's response carries more than one token. Alongside the usual accessToken you'll see an mdAccessToken and an expirationTime. That second token isn't decoration, it's issued specifically for the market-data feed. Hold onto it.

2

Open the market-data WebSocket

Connect to the market-data host that matches your environment: wss://md-demo.tradovateapi.com/v1/websocket if your token came from the demo auth endpoint, or wss://md.tradovateapi.com/v1/websocket if it came from live. Crossing a live token with the demo host (or the reverse) gets you bounced before the subscription ever matters. Wait for the socket's opening o frame before you send anything.

3

Authorize the socket first

This is the step people skip. A fresh socket answers nothing until you authorize it. The very first frame you send must be the authorize frame carrying your token, use the mdAccessToken for the market-data connection. Tradovate frames are newline-delimited text, not raw JSON: the endpoint, the request id, an (often empty) query line, then the body. Send the authorize frame, wait for the response confirming the socket is authorized, and only then move on. Fire a subscription before this handshake completes and it won't be honored.

4

Now send md/subscribeQuote

With the socket open and authorized, the subscription finally has a route. Send it as a frame in the same shape, with a JSON body naming a single contract. You can name the contract by its symbol string (like ESU6 for the September 2026 E-mini S&P) or by its numeric contract id, both work. The server acknowledges the request and then starts pushing quote events with the bid, ask, and last price for that contract. The Not found error is gone because the endpoint exists on the connection you're now using.

Authorize frame:
authorize
1

<yourMdAccessToken>


Subscribe frame:
md/subscribeQuote
2

{"symbol":"ESU6"}

Authorize frame sent to the Tradovate md-demo market-data WebSocket with a market-data access token

Subscribe Once Per Symbol, Not in Bulk

A quick trap worth naming: md/subscribeQuote takes a single symbol per call. There's no array form where you hand it a list and get everything at once. If you want to follow ES, NQ, and CL together, send three separate subscribe frames over the same market-data socket, each with its own request id. One socket can carry many live quote subscriptions at the same time, you just register them one at a time. When you're done with a contract, unsubscribe with md/unsubscribeQuote so you're not paying to receive a stream you no longer read.

What Breaks Next: the Socket's Right, But No Prices Show

Once the not-found error clears, the next class of problem is different in nature. The request reaches the market-data engine now, so any failure from here is about what you asked for and whether you're entitled to it, not about a missing route.

“Symbol is inaccessible”

If the subscribe call comes back with an inaccessible or unknown-symbol response, two things are usually in play. First, the symbol has to be a real, fully qualified front-month contract, ESU6, not the bare ES root, and not a contract that already expired and rolled to the next quarter. Second, your account needs the entitlements to see that data at all: the Contract Library plus an active exchange market-data subscription. Without those, a perfectly formed request still returns nothing usable. This is a distinct issue with its own fix.

The socket keeps dropping

Tradovate's WebSocket expects a periodic heartbeat. If you connect, authorize, subscribe, and then go quiet, the server closes the connection and your quotes stop cold. Send an empty heartbeat frame on the interval Tradovate specifies (a short one, on the order of a couple of seconds) so the market-data socket stays open for as long as you need prices. A lot of “it worked for a minute then died” reports trace straight back to a missing heartbeat.

The token expired mid-session

Access tokens don't last forever. If your market-data socket authorized fine at the start of the session and later stops responding, your token may simply have aged out. Renew it before it expires rather than waiting for calls to fail, then re-authorize the socket with the fresh token.

Tradovate market-data socket streaming live quote events with bid, ask, and last price after a successful subscription

A Quick Checklist to Clear the Error

Check What to confirm
Right socketmd/subscribeQuote goes to md.tradovateapi.com (live) or md-demo.tradovateapi.com (demo), never the account socket.
Matching environmentLive token → live market-data host; demo token → demo host.
Authorize firstSend the authorize frame with your mdAccessToken before any md/ request.
Full contract symbolUse a fully qualified front-month symbol like ESU6, not the ES root or an expired contract.
One symbol per callSend a separate subscribe frame per contract; there's no bulk array form.
Heartbeats + tokenKeep the socket alive with heartbeats and renew the token before it expires.

Skip the Raw Socket Wiring

Most people who hit Not found: md/subscribeQuote aren't chasing a data-vendor project, they just want a strategy to trade on Tradovate without babysitting two sockets, two tokens, heartbeats, and frame formats. If that's you, there's a much shorter path than hand-coding the whole WebSocket layer.

For the problems that tend to show up right after this one, these guides go deeper: if your symbols come back inaccessible rather than not-found, that's a separate entitlement and symbol-format issue; to get real-time prices flowing in the first place, subscribing to Tradovate real-time market data is the starting point; and if your socket authorizes fine then quietly stops answering, that's usually the 90-minute access token expiring mid-session.

Skip the Raw Socket Wiring

Want your TradingView strategy to trade Tradovate without wiring a single WebSocket frame yourself? See how PickMyTrade automates the whole order flow.

Start Your Free 5-Day Trial

Frequently Asked Questions

Because md/subscribeQuote only exists on Tradovate's market-data WebSocket, not the account socket you use for user/syncRequest and order/placeOrder. Send an md/ request to the account socket and the server has no route for it on that connection, so it echoes back Not found: md/subscribeQuote. Open a second connection to the market-data host and send the subscription there.

Live market data uses wss://md.tradovateapi.com/v1/websocket and demo uses wss://md-demo.tradovateapi.com/v1/websocket. Those are separate hosts from the account sockets. Confirm the current hostnames in Tradovate's developer docs before you commit them to code, since they can change.

Tradovate's auth response returns two tokens, accessToken and mdAccessToken, plus an expiration time. The mdAccessToken is issued for the market-data feed, so use it to authorize the market-data socket. Each socket needs its own authorize frame first; an unauthorized socket answers nothing.

That's a different problem. Once the request reaches the market-data engine it needs a valid, fully qualified front-month symbol plus entitlements: the Contract Library and an active exchange market-data subscription. Without those, the symbol comes back inaccessible even with a correct frame. On a prop or evaluation account, the firm usually controls that data.

No. Each md/subscribeQuote request takes a single symbol. To follow several contracts, send one subscribe request per symbol over the same market-data socket, each with its own request id. Keep the connection alive with heartbeats and one socket can hold many quote subscriptions at once.

This guide is for educational and informational purposes only and is not financial, investment, or trading advice. Trading futures and other leveraged products carries a substantial risk of loss and is not suitable for every investor. PickMyTrade is an independent third-party automation platform and is not affiliated with, endorsed by, or sponsored by Tradovate, Inc. or Bookmap. All related names, logos, and trademarks are the property of their respective owners. Platform features and steps change over time, so always confirm the current process in the official platform documentation before acting.