Tradovate API Rate Limits: p-ticket, p-time, 429 and the 1,500/Hour Order Limit

What Tradovate's p-ticket, p-time, p-captcha and p-message fields mean, why placeorder stops at 1,500 requests an hour, how a 429 differs, and how to keep a copier clear.

Tradovate API rate limits: p-ticket, p-time and 429 errors

If you automate a Tradovate account long enough, you will eventually get a response that is not the one you asked for. Sometimes it is an HTTP 429. More often it is an HTTP 200 whose body holds a p-ticket, a p-time and a line like Rate limit exceeded: more than 1500 requests per hour. Both mean Tradovate decided your integration sent too many requests and is making you wait. Neither is an error in your order, and neither is an outage.

This guide explains what each of those fields means, the two separate limits behind them, the order placement limit Tradovate does not list in its published tables, why copiers and automated setups hit these limits, and what to do when one lands.

Tradovate has two rate limits, not one

Most confusion about Tradovate rate limits comes from treating them as a single number. They are two systems that fail differently.

The first is a user-level limit. Tradovate's partner documentation publishes it as 5,000 requests per hour for an authenticated user, counted across every endpoint. Cross it and you get an HTTP 429 Too Many Requests.

The second is a set of endpoint limits. Every endpoint has its own hourly count, and going over one does not produce an error at all. Tradovate answers with a penalty ticket, usually called a p-ticket, inside an otherwise normal HTTP 200 response.

Tradovate's older API FAQ still says its limits are variable by design and can change from one hour to the next. That remains true in spirit: Tradovate sets these numbers and can move them. Treat every figure here as what Tradovate publishes or reports today, not as a guarantee.

What p-ticket, p-time, p-captcha and p-message mean

A penalty ticket replaces the result you asked for with a few fields. A p-ticket on order placement looks like this:

{
  "p-ticket": "NTgsRzhnNFJS...",
  "p-time": 2,
  "p-message": "Rate limit exceeded: more than 1500 requests per hour"
}

p-ticket is the penalty ticket itself, an encrypted token tied to the caller's IP address. After waiting, the request is resent with the identical body plus the p-ticket as an extra field.

p-time is how many seconds to wait before that retry. It is additive: every further penalty ticket you collect inside the window adds another back-off to the time remaining. Retrying early does not get you in sooner. It makes the wait longer.

p-captcha, when it is true, means Tradovate wants a reCAPTCHA. No server-to-server integration can answer one, so the only fix is to stop and wait about an hour for that endpoint's count to clear.

p-message is Tradovate's description of the limit you crossed, such as "more than 1500 requests per hour". It can be general or missing, and Tradovate points to the failed call's violations and errorText fields for the detail.

Three things about penalty tickets catch people out. They arrive as HTTP 200, so a client that only checks status codes thinks the request worked. Endpoint counts run on a rolling 60-minute window, so calls age out about an hour after you make them instead of resetting at the top of the hour. And according to Tradovate's documentation they are keyed to the caller's IP address, specifically its /24 subnet, not to a user or API key. On most endpoints only failed calls count toward the limit: bad credentials, malformed requests, missing accounts, 4xx and 5xx responses, and 200 responses that carry a business error. A smaller set of sensitive endpoints counts every call.

The 1,500 requests per hour limit on placeorder

Tradovate's published endpoint table does not list order placement. The API publishes the limit anyway, one penalty ticket at a time. When POST /order/placeorder is over its count, the p-message reads Rate limit exceeded: more than 1500 requests per hour. Traders running large clusters of evaluation accounts under one Tradovate login have reported hitting the same ceiling on the Tradovate community forum.

1,500 placements an hour sounds like plenty until you multiply. A copier leader that places 100 orders an hour with 15 followers on the same login sends 1,500 placements, before counting bracket orders, re-entries, or the copier's own corrections. Rejected orders count as well, so a follower that keeps getting refused for margin or a prop firm lock burns through the hour without ever placing a trade.

What a Tradovate 429 means

An HTTP 429 is the user-level limit, the broader of the two. It comes back with an empty body: no p-time, no header, nothing to tell you how long to wait. Tradovate's guidance is to stop calling for a full hour, and every request you send during that hour, even a test, restarts the clock. A 429 cannot be cleared programmatically, and retrying through penalty tickets instead of waiting them out is the usual way to earn one.

You will also see "80 requests per minute" quoted on forums and prop firm help pages. That figure does not appear in Tradovate's published limits. Plan around the hourly numbers.

Why automated accounts hit them

A person clicking in the Tradovate app rarely gets near a limit. Automation multiplies requests in ways that are easy to miss.

Copying multiplies everything. One alert sent to three accounts, each with two copier followers, is nine orders' worth of requests arriving within a second, and every follower on a login draws on the same placement limit.

Trailing stops are chatty. A stop that follows price sends a steady stream of modify requests while the trade is open.

Sweeping costs one request per order. Tradovate has no bulk-cancel endpoint, so cancelling all working orders costs one request for each order that is working.

Composite commands are several calls. A cancel-and-rebracket on a busy contract can take ten or more broker calls plus checks that the orders settled.

Background reads add up. Every risk monitor and copier follower adds its own recurring reads to the same login's hourly budget.

How CrossTrade keeps you clear

CrossTrade paces every request to Tradovate through a governor for each linked login. It spreads bursts out so a copier fan-out to many accounts clears quickly, keeps capacity in reserve for liquidations and reconciliation, and puts urgent actions ahead of background reads.

When Tradovate does issue a penalty, CrossTrade does three things. It stops background reads and slows everything else for that login until the p-time expires, then makes a single retry with the p-ticket attached rather than letting every request pile in at once. It does not blindly resend an order whose outcome is uncertain, because a retry storm makes the penalty worse and a resent order that already reached the broker is a double fill. And it records the outcome where you will look for it: Tradovate's reason on the signal in Alert History, and the per-follower result in the copier's Copy Log.

If you call CrossTrade's REST API yourself, a Tradovate penalty comes back as broker_rate_limited, separate from CrossTrade's own API limit, with a Retry-After value taken from the remaining penalty time when it is known. The full mechanics are in the Tradovate rate limits section of the docs.

How to stay clear of penalties

Do the placement math per login. Leader orders per hour times followers on that login, plus brackets, is what placeorder sees. Keep it well under 1,500.

Fix what keeps getting rejected. Failed calls count toward endpoint limits, so an account that keeps rejecting orders spends your budget for nothing.

Scope your cancels. Prefer a cancel narrowed to one account and one instrument over a global sweep.

Keep frequent alerts simple. A plain place is usually one broker request. Save composite commands for alerts that fire rarely.

Throttle a noisy strategy at the source. CrossTrade's rate_limit and id alert fields drop repeat signals before they ever reach Tradovate.

Send exact contracts in high-frequency alerts. ESZ6 skips the front-month lookup that ES1! needs.

What to do after a p-ticket or a 429

For a p-ticket, wait the full p-time before trying again, and do not retry early. For a 429, stop calling for an hour. Then, before resending anything that changes a position, read the account: check open orders and positions in Tradovate or through the API. If the first attempt reached the broker, resending it doubles your exposure. If automation stays blocked and you hold a position that needs managing, manage it directly in Tradovate.

For the broker's own explanation, read Tradovate's Penalty Tickets and Rate Limits pages in its partner documentation, and its older guide to handling request limits.

Frequently asked questions

What is Tradovate's API rate limit?

Tradovate publishes a user-level limit of 5,000 requests per hour for an authenticated user across all endpoints, plus a separate hourly limit on each endpoint. Order placement is limited to 1,500 requests per hour, a figure Tradovate reports in its penalty tickets rather than in its published tables.

What does "Rate limit exceeded: more than 1500 requests per hour" mean?

It is the p-message Tradovate sends when order placement is over its hourly count. Wait out the p-time, then reduce placements on that login: fewer followers per login, fewer re-entries, and fewer orders that get rejected.

What is a p-ticket in Tradovate?

A penalty ticket. When an endpoint is over its limit, Tradovate returns HTTP 200 with a p-ticket token, a p-time wait in seconds and usually a p-message, instead of the result you asked for. After the wait, the request is resent with the p-ticket attached.

What do p-time and p-captcha mean?

p-time is the number of seconds to wait before retrying, and it grows with every early retry. p-captcha set to true means Tradovate wants a reCAPTCHA that no automated integration can answer, so you have to wait about an hour.

What does a Tradovate 429 error mean?

Your login went over Tradovate's user-level limit across all endpoints. A 429 has no wait time in it. Tradovate's guidance is to stop calling for a full hour, because every call during that hour restarts the clock.

Why does my trade copier hit Tradovate rate limits?

Copying multiplies every placement by the number of followers, and every follower on a login draws on the same 1,500 per hour placement limit. Trailing stops, global cancels and repeatedly rejected orders add more.

Does CrossTrade retry orders after a p-ticket or a 429?

Not blindly. It waits out the penalty, makes a single ticketed retry, and will not resend an order whose outcome is uncertain, because that risks a double fill. Penalties are recorded in Alert History and the Copy Log.

Automate Tradovate without the guesswork

If you are new to CrossTrade, start a free 7-day trial, and bring rate-limit questions to the CrossTrade Discord.

CrossTrade is execution and automation software, not a broker, financial adviser, or trading strategy. Tradovate sets and changes its own limits. Futures trading involves substantial risk. Test every automated workflow in simulation and verify orders at your broker.