The Topstep API costs $14.50 a month with the promo code. A market order takes exactly four HTTP calls: log in, find your account, find the contract, place the trade. So why do so many traders stall before the first order ever leaves their machine?
Table of Contents
- What is the Topstep API, exactly?
- What do you need before you start?
- Step 1: How do you get a Topstep API key?
- Which site does what
- What it costs next to the alternative
- Step 2: How do you authenticate and get a session token?
- Step 3: Find your account ID and the contract ID
- Step 4: How do you place your first order, then flatten it?
- Which Topstep rules apply to API trading?
- Do you need to write this code at all?
- Why is your first Topstep API call failing?
- Frequently asked questions
- Next steps
- Complete source code
Because the pieces live in three places. You buy the subscription on the ProjectX Dashboard, generate the key inside TopstepX, and read the reference docs on a ProjectX domain that never says “Topstep” anywhere. Topstep tucks the rule that matters most, which account types you’re allowed to automate, into a help article about a different account.
We connect TopstepX accounts through this same API every day, and first attempts fail in the same handful of places almost every time. This guide walks those places in order: key, token, one protected trade placed and flattened on a Practice account.
Then the rules, before you point anything at an evaluation. If you’d rather settle the strategy question first, our earlier piece on why the raw API isn’t a turnkey solution covers that ground.
Key Takeaways
- The Topstep API is the ProjectX Gateway API at api.topstepx.com: $29 a month, $14.50 with code
topstep, one key for all your accounts.- Four calls place a trade: Auth/loginKey, Account/search, Contract/search, Order/place. Tokens expire after 24 hours.
- Topstep allows bots in the Trading Combine and Express Funded Account, not the Live Funded Account, and never from a VPS.
What is the Topstep API, exactly?
The Topstep API is the ProjectX Gateway API at api.topstepx.com: a REST interface plus two real-time hubs for order and market events. It’s the same engine behind the TopstepX platform, so anything you place through it shows up in TopstepX. Rate limits are 200 requests per 60 seconds for most endpoints, and 50 per 30 seconds for historical bars.
Here’s the naming trap. ProjectX used to power a dozen prop firms, so most 2025 tutorials call this the “ProjectX API” and show Bulenox or Tradeify screenshots. Since February 28, 2026, ProjectX runs exclusively for Topstep.
Every one of those guides now applies to exactly one firm, so when you read “ProjectX API”, read “Topstep API”. The ProjectX vs. Tradovate comparison explains how the two stacks differ once you’re past the naming.
What can it actually do? Search accounts and contracts, then place, modify and cancel orders. Read open positions and trade history, pull historical bars, and stream live quotes and fills over SignalR from rtc.topstepx.com.
What it can’t do is pretend. There’s no sandbox, and Topstep’s own advice is to test on a Practice account, which is what we’ll do below.
One subscription and one API key cover every eligible account under your Topstep profile. A trader running five Express Funded Accounts pays the same $14.50 as a trader running one, which matters once you start fanning a single signal across accounts.
Budget your calls, though. A polling loop eats 200 a minute faster than you’d think. Our guide to API rate limits in trading automation shows where they go.
What do you need before you start?
You’ll need an active Topstep account, a payment card for the API subscription, and about 20 minutes. Level 1 market data is already included with every Trading Combine, so there’s nothing extra to license before quotes and fills start flowing.
Checklist:
- A Topstep login with at least one account visible in TopstepX. A Practice account is ideal for the first trade.
- A card for the ProjectX API Access subscription: $29 a month, $14.50 with the code.
- curl on any operating system, or Python 3.10+ with the
requestspackage installed. - Your exact TopstepX username. The login call needs it alongside the key, and it isn’t your email address.
- Time: about 20 minutes. Difficulty: beginner, if you can paste into a terminal.
Every request body below is taken from the official ProjectX reference, and every URL points at the TopstepX environment. Run them against a Practice account first, during regular CME hours, so a fill actually comes back.
Why a Practice account and not the evaluation you’re paying for? Because API orders are final, and in our experience the first mistake is almost always a flipped side or an oversized size, not a strategy problem.

Step 1: How do you get a Topstep API key?
Getting a Topstep API key takes four screens across two websites, and you pay for the subscription on a site you may never have visited. That split is why so many traders end up staring at a greyed-out API tab. Do it in this order and it takes under ten minutes.
- In TopstepX, open Settings (the gear icon), then the API tab. Under ProjectX Linking, click Link. You’ll land on dashboard.projectx.com.
- Register on the ProjectX Dashboard with an email, a username and a password, then verify the email.
- In the Dashboard’s left menu, open Subscriptions and choose ProjectX API Access. Enter the code topstep at checkout. It cuts the price from $29 to $14.50 a month, recurs every month, and has no end date. The charge shows on your statement as “Sim2Funded Solutions”, not Topstep.
- Back in TopstepX, return to Settings → API, confirm the link in the popup, then click Add API Key. Copy the key and store it wherever you’d store a password.
Which site does what
| Where | What it does | What you get |
|---|---|---|
| ProjectX Dashboard | Holds the API subscription and billing | An active ProjectX API Access plan |
| TopstepX Settings → API | Links your Topstep profile to that plan | The Add API Key button, then the key itself |
Verify it worked: the API tab shows the ProjectX link as active and lists your new key. If Add API Key is still greyed out, you haven’t linked the subscription yet, so go back to the Dashboard and check that the plan is live.
Watch out: write your exact TopstepX username down next to the key. The login call needs both, and a typo in either returns the same generic failure, which sends people hunting for a key problem that doesn’t exist.
What it costs next to the alternative
Is the subscription worth it? Compare it with the other route into automated futures. Building against Tradovate’s API with live data means paying for a CME non-display license on top of the API fee, and that stack runs about $427 a month.
Step 2: How do you authenticate and get a session token?
One POST to /api/Auth/loginKey with your username and API key returns a session token that stays valid for 24 hours. Every other call carries that token in an Authorization header, so this is the only request in which the raw key ever travels over the wire.
curl -X POST "https://api.topstepx.com/api/Auth/loginKey" \
-H "accept: text/plain" \
-H "Content-Type: application/json" \
-d '{"userName": "YOUR_TOPSTEPX_USERNAME", "apiKey": "YOUR_API_KEY"}'Expected output:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"success": true,
"errorCode": 0,
"errorMessage": null
}In Python, the same call plus the header you’ll reuse for everything that follows:
# topstep_auth.py
import os
import requests
BASE = "https://api.topstepx.com"
resp = requests.post(f"{BASE}/api/Auth/loginKey", json={
"userName": os.environ["TSX_USER"], # your TopstepX username
"apiKey": os.environ["TSX_KEY"], # the key from Settings -> API
}, timeout=10)
body = resp.json()
assert body["success"], body["errorMessage"]
TOKEN = body["token"]
HEADERS = {"Authorization": f"Bearer {TOKEN}"}
print("authenticated")What just happened: the API checked your username and key, minted a JSON Web Token, and handed it back. Check that success is true and errorCode is 0 before you store anything. A wrong key doesn’t throw an HTTP error; it returns success: false with a message.
Heads up: the token dies 24 hours after login, usually in the middle of tomorrow’s session. Any bot that runs longer than a day has to call
POST /api/Auth/validatewith the current token before then and swap in thenewTokenfrom the response. Skip this and your bot goes quiet at the same hour every day.

Step 3: Find your account ID and the contract ID
An order needs two identifiers that the TopstepX interface never shows you: a numeric account ID and a contract ID string such as CON.F.US.MNQ.Z26. Two search calls return both, and they’re the same two calls PickMyTrade makes on your behalf every time an alert lands.
First, the accounts. Set onlyActiveAccounts to true and read the list:
curl -X POST "https://api.topstepx.com/api/Account/search" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"onlyActiveAccounts": true}'{
"accounts": [
{ "id": 1, "name": "TEST_ACCOUNT_1", "balance": 50000, "canTrade": true, "isVisible": true }
],
"success": true,
"errorCode": 0,
"errorMessage": null
}Which entry do you pick? The one whose name matches your Practice account and whose canTrade is true. That id is your accountId for everything that follows.
Now the contract. Search by symbol with live set to false, which selects the sim data feed that Practice and evaluation accounts run on:
curl -X POST "https://api.topstepx.com/api/Contract/search" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"searchText": "NQ", "live": false}'{
"contracts": [
{
"id": "CON.F.US.MNQ.Z26",
"name": "MNQZ6",
"description": "Micro E-mini Nasdaq-100: December 2026",
"tickSize": 0.25,
"tickValue": 0.5,
"activeContract": true,
"symbolId": "F.US.MNQ"
}
],
"success": true,
"errorCode": 0,
"errorMessage": null
}The search returns up to 20 matches, so “NQ” brings back both the E-mini and the Micro across several expiries. Take the one whose activeContract is true and whose name starts with MNQ. Note the tickValue of $0.50, because the bracket orders in the next step are measured in ticks, not dollars.
Watch out: the letter in the contract ID is the expiry month (Z is December, H is March), so a hard-coded
contractIdbreaks at every quarterly roll. From what we’ve seen, that’s the usual reason a bot that worked in August dies in September. Look the active contract up at startup instead of pasting it into your code. We compared how well each vendor documents this in our Rithmic vs. ProjectX API documentation review.
Step 4: How do you place your first order, then flatten it?
A market order is a POST to /api/Order/place with five required fields, and the response returns an orderId in the same call. Set size to 1 and attach stop-loss and take-profit brackets in ticks, so your very first automated trade is protected before it fills.
The two integer fields trip everyone up, so here’s the map:
| Field | Value | Meaning |
|---|---|---|
type | 1 | Limit |
type | 2 | Market |
type | 4 | Stop |
type | 5 | Trailing stop |
type | 6 / 7 | Join bid / Join ask |
side | 0 | Buy (bid) |
side | 1 | Sell (ask) |
Buy one MNQ at market with a 40-tick stop ($20 at $0.50 a tick) and an 80-tick target ($40):
curl -X POST "https://api.topstepx.com/api/Order/place" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"accountId": 1,
"contractId": "CON.F.US.MNQ.Z26",
"type": 2,
"side": 0,
"size": 1,
"stopLossBracket": { "ticks": 40, "type": 4 },
"takeProfitBracket": { "ticks": 80, "type": 1 }
}'{ "orderId": 9056, "success": true, "errorCode": 0, "errorMessage": null }What just happened: the market order went in, and the API attached a stop order 40 ticks below and a limit order 80 ticks above as a bracket. Open TopstepX and check the Positions panel: the position and both working orders should be there. That’s your verification.
Done? Not quite. Close it, because a Practice account shouldn’t sit with an open position you forgot about:
curl -X POST "https://api.topstepx.com/api/Position/closeContract" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"accountId": 1, "contractId": "CON.F.US.MNQ.Z26"}'A success: true back means you’re flat. There’s a closeContractPosition endpoint for partial exits too, but flattening everything is the right first habit.
Before you scale: orders executed through the API are final. Topstep doesn’t review, adjust or reverse them, which is exactly why the first one goes on a Practice account and why
sizestarts at 1. Before you raise it, check the contract ceiling for your account size below.
Which Topstep rules apply to API trading?
Topstep allows custom bots through the API in the Trading Combine and the Express Funded Account, subject to the standard rules and a ban on high-frequency trading. In the Live Funded Account, it prohibits API automation entirely. And wherever you run it, the code has to run from your personal device.
| Account | API automation | Notes |
|---|---|---|
| Practice | Allowed | No sandbox exists, so this is where you test |
| Trading Combine ($50K / $100K / $150K) | Allowed | Standard rules apply, including the 50% consistency target |
| Express Funded Account | Allowed | Up to five accounts per trader |
| Live Funded Account | Prohibited | No API automation, no exceptions listed |
So where is the code allowed to run? Topstep’s terms bar VPS, VPN and remote servers for trading, and the help center says running automation on one can lead to suspension. A personal server is fine only for jobs that never send an order: backtesting, analytics, a read-only dashboard.
Then there’s the sim-abuse list. Scalping algorithms built to exploit unrealistic simulated fills are prohibited by name. So are hundreds of rapid trades that lean on sim queue position, and stops that only work because a sim has no slippage.
If the edge disappears on a live exchange, it isn’t an edge Topstep will pay for.
Two more things you own outright. Topstep won’t help you set up or troubleshoot a bot. You’re responsible for everything it does, including keeping your best day under 50% of the profit target.
Want to see how this compares with Apex or Tradeify before you commit? Our list of prop firms that allow automated trading puts the policies side by side.
Do you need to write this code at all?
Not if your signals already come from TradingView, because PickMyTrade authenticates with the same Topstep API key you just created. It turns a TradingView alert into a bracketed TopstepX order, with under 200 milliseconds of processing on its side. It costs $50 a month, with a 5-day free trial and no card required.
Think about what the script above still doesn’t handle: the 24-hour token refresh, the quarterly contract roll, backing off when a 429 comes back, and sending one signal to five Express Funded Accounts with different sizes. Each is a small job on its own. Together, from what we’ve seen, they’re the reason “my bot stopped trading at 9:40” is such a common message.
Setup is three fields. Create a connection, pick Topstep as the prop firm, and paste the TopstepX username and API key from Step 1. The Topstep API access guide in our docs shows each screen.
From there, a TradingView alert with a JSON message carries the symbol, side, size, stop and target. The TradingView to TopstepX integration does the four calls for you. If shaving milliseconds off that path matters to you, we’ve mapped where the time goes in our trading API latency guide.
One honest caveat. A hosted bridge that authenticates to your account with your own key is a different setup from a trader-run VPS. It’s the setup PickMyTrade is built around.
But Topstep writes and changes its own policy. Confirm it in writing with Topstep support before you point any automation at an evaluation you care about, and keep it off a Live Funded Account entirely.
Ready to skip the token loop? Start my free 5-day trial on Topstep connects one TopstepX account in about five minutes. After that, pricing is $50 a month with unlimited accounts on the connection.
Why is your first Topstep API call failing?
Here are the six failures we see most on a first Topstep API run, and the fix for each.
| Problem | What you see | Fix |
|---|---|---|
| Wrong username or key | success: false from loginKey | Use your TopstepX username, not your email; generate a fresh key if in doubt |
| Token expired | HTTP 401 on any call | Call /api/Auth/validate before 24 hours are up, or log in again |
| Add API Key greyed out | No key button in Settings → API | The Dashboard subscription isn’t linked; redo the Link step |
| Too many requests | HTTP 429 | Stay under 200 calls a minute; poll less, or stream from the hubs instead |
| Contract not found | Empty contracts array | Check searchText, and set live to false for sim accounts |
| Order rejected | success: false from Order/place | Check canTrade, the contract limit for your account size, and market hours |
Still stuck? Topstep runs an #api-trading channel in its Discord. The endpoint reference lives at gateway.docs.projectx.com, and a Swagger console at api.topstepx.com/swagger lets you try calls in the browser.
Frequently asked questions
ProjectX API Access is $29 a month, and Topstep traders get 50% off forever with the code topstep, which makes it $14.50 a month. It’s billed separately from your Topstep subscription, under the name Sim2Funded Solutions, and one subscription covers every TopstepX account linked to your profile.
Yes on an Express Funded Account, where Topstep allows custom bots under the standard rules and you can run up to five accounts at once. No on a Live Funded Account, where it prohibits automated trading through the ProjectX API. Trading Combine evaluations and Practice accounts both allow it.
No, Topstep provides no sandbox environment, and it states that orders sent through the API are final, with no review or reversal. The intended test bed is a Practice account, which uses the sim data feed and behaves like an evaluation without the consequences. Our ProjectX setup checklist covers what to verify there before going further.
The session token expires 24 hours after you log in, and POST /api/Auth/validate returns a fresh one. Topstep’s documentation doesn’t put a time limit on the API key itself, so treat it like a password and generate a new one from Settings → API if it’s ever exposed.
Not directly, because TradingView can’t call the Topstep API; it can only send a webhook when an alert fires. A bridge such as PickMyTrade receives that webhook, authenticates with your Topstep API key, and places the order, which is how most traders send their first automated trade without touching the endpoints above. Our webhook vs. API comparison explains when each route makes sense.
Next steps
You now have a Topstep API key, a working token, and one round-trip trade behind you on a Practice account. Here’s how to build on it.
- Stream instead of poll. Connect to the user hub at rtc.topstepx.com/hubs/user for fills and order updates, and the market hub for quotes, so you stop spending your 200-a-minute budget on status checks.
- Add the token loop. Schedule a
validatecall well inside every 24-hour window and log the swap, so tomorrow’s session doesn’t start with a 401. - Move up deliberately. Practice first, then a Trading Combine, then an Express Funded Account, and never a Live Funded Account. Confirm Topstep’s current automation policy in writing before each step.
If you’d rather spend the time on the strategy than the plumbing, who builds PickMyTrade and how to reach us are one click away. Either way, the first trade is the hardest one, and you’ve just placed it.
Complete source code
topstep_first_trade.py: authenticate, find IDs, place one bracketed order, flatten
# topstep_first_trade.py
# Run with: TSX_USER=... TSX_KEY=... TSX_ACCOUNT=... python topstep_first_trade.py
# Use a Practice account the first time. API orders are final.
import os
import sys
import time
import requests
BASE = "https://api.topstepx.com"
session = requests.Session()
def call(path, payload=None):
"""POST to the Topstep API, retry once on 429, fail loudly on success=false."""
r = session.post(f"{BASE}{path}", json=payload or {}, timeout=10)
if r.status_code == 429:
time.sleep(2)
r = session.post(f"{BASE}{path}", json=payload or {}, timeout=10)
r.raise_for_status()
body = r.json()
if not body.get("success"):
sys.exit(f"{path} failed: {body.get('errorMessage')} (errorCode {body.get('errorCode')})")
return body
# 1. Authenticate with the API key. The token lasts 24 hours.
auth = call("/api/Auth/loginKey", {
"userName": os.environ["TSX_USER"],
"apiKey": os.environ["TSX_KEY"],
})
session.headers["Authorization"] = f"Bearer {auth['token']}"
# 2. Find the account to trade. Set TSX_ACCOUNT to its exact name.
accounts = call("/api/Account/search", {"onlyActiveAccounts": True})["accounts"]
wanted = os.environ.get("TSX_ACCOUNT")
if not wanted:
for a in accounts:
print(f"{a['id']:>8} {a['name']} canTrade={a['canTrade']} balance={a['balance']}")
sys.exit("Set TSX_ACCOUNT to one of the account names above and run again.")
account = next(a for a in accounts if a["name"] == wanted and a["canTrade"])
# 3. Find the active MNQ contract on the sim data feed.
contracts = call("/api/Contract/search", {"searchText": "NQ", "live": False})["contracts"]
mnq = next(c for c in contracts if c["activeContract"] and c["name"].startswith("MNQ"))
print(f"trading {mnq['name']} ({mnq['id']}), tick value ${mnq['tickValue']}")
# 4. Buy 1 MNQ at market with a 40-tick stop and an 80-tick target.
order = call("/api/Order/place", {
"accountId": account["id"],
"contractId": mnq["id"],
"type": 2, # market
"side": 0, # 0 = buy (bid), 1 = sell (ask)
"size": 1,
"stopLossBracket": {"ticks": 40, "type": 4}, # stop order
"takeProfitBracket": {"ticks": 80, "type": 1}, # limit order
})
print("orderId:", order["orderId"])
# 5. Flatten so nothing is left open.
input("Check the position in TopstepX, then press Enter to flatten... ")
call("/api/Position/closeContract", {"accountId": account["id"], "contractId": mnq["id"]})
print("flat.")Disclaimer:
This content is for informational purposes only and does not constitute financial, investment, or trading advice. Trading and investing in financial markets involve risk, and it is possible to lose some or all of your capital. Always perform your own research and consult with a licensed financial advisor before making any trading decisions. The mention of any proprietary trading firms, brokers, does not constitute an endorsement or partnership. Ensure you understand all terms, conditions, and compliance requirements of the firms and platforms you use.
Also Checkout: TradingView Pine Script to Automated Bot for Prop Firm Accounts
Connect your alerts with PickMyTrade — automated trade execution, no coding required. Start free →
