Skip to content
Back to App

Authentication

The TopStep Simulator API uses bearer token authentication. You generate an API key in the TestMax web app, exchange it for a token via the Auth/loginKey endpoint, and then include that token in every subsequent request.

Authentication flow

  1. Generate an API key

    Log into testmax.io and navigate to Settings > API Keys. Click Generate New Key. Copy the key immediately — it will not be shown again.

  2. Exchange the API key for a token

    Call POST Auth/loginKey with your email address and API key. The response contains a bearer token.

  3. Include the token in all requests

    Pass the token in the Authorization header:

    Authorization: Bearer <your-token>
  4. Refresh or validate as needed

    Use POST Auth/validate to check if a token is still valid or to refresh it. Use POST Auth/logout to invalidate a token when done.


POST Auth/loginKey

Authenticate with your email address and API key to receive a bearer token.

URL: POST /api/topstep-sim/Auth/loginKey

Request body

{
"userName": "your@email.com",
"apiKey": "your-api-key-here"
}
FieldTypeRequiredDescription
userNamestringYesYour TestMax account email address
apiKeystringYesThe API key generated in Settings

Response

{
"success": true,
"errorCode": 0,
"errorMessage": null,
"token": "eyJhbGciOiJIUzI1NiIs..."
}
FieldTypeDescription
tokenstringBearer token to use in subsequent requests

Example

import urllib.request
import json
API_URL = "https://api.test-max.com/api/topstep-sim"
# Step 1: Authenticate
login_data = json.dumps({
"userName": "your@email.com",
"apiKey": "your-api-key-here"
}).encode()
req = urllib.request.Request(
f"{API_URL}/Auth/loginKey",
data=login_data,
headers={"Content-Type": "application/json"}
)
resp = json.loads(urllib.request.urlopen(req).read())
if resp["success"]:
token = resp["token"]
print(f"Authenticated. Token: {token[:20]}...")
else:
print(f"Login failed: {resp['errorMessage']}")

Error responses

ScenarioerrorCodeerrorMessage
Invalid API key1"Invalid credentials"
Missing fields1"userName and apiKey are required"
Account disabled1"Account is disabled"

POST Auth/validate

Validate an existing token. Returns the same token if valid, or a refreshed token if the original is close to expiration.

URL: POST /api/topstep-sim/Auth/validate

Request headers

Authorization: Bearer <your-token>
Content-Type: application/json

Request body

{}

An empty JSON body is required.

Response

{
"success": true,
"errorCode": 0,
"errorMessage": null,
"token": "eyJhbGciOiJIUzI1NiIs..."
}
FieldTypeDescription
tokenstringThe validated (or refreshed) token

Example

req = urllib.request.Request(
f"{API_URL}/Auth/validate",
data=b"{}",
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
)
resp = json.loads(urllib.request.urlopen(req).read())
if resp["success"]:
token = resp["token"] # Use the refreshed token
print("Token is valid")
else:
print("Token expired — re-authenticate")

POST Auth/logout

Invalidate a token. After logout, the token can no longer be used for any API calls.

URL: POST /api/topstep-sim/Auth/logout

Request headers

Authorization: Bearer <your-token>
Content-Type: application/json

Request body

{}

Response

{
"success": true,
"errorCode": 0,
"errorMessage": null
}

Example

req = urllib.request.Request(
f"{API_URL}/Auth/logout",
data=b"{}",
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
)
resp = json.loads(urllib.request.urlopen(req).read())
print("Logged out" if resp["success"] else "Logout failed")

GET Status/ping

Health check endpoint. Returns a simple response indicating the API is operational. No authentication required.

URL: GET /api/topstep-sim/Status/ping

Response

{
"success": true,
"errorCode": 0,
"errorMessage": null
}

Example

Terminal window
curl https://api.test-max.com/api/topstep-sim/Status/ping

Using the token in your scripts

Once authenticated, include the token in every request:

import urllib.request
import json
API_URL = "https://api.test-max.com/api/topstep-sim"
TOKEN = "your-token-here"
def api(path, body=None):
"""Call any TopStep Simulator API endpoint."""
data = json.dumps(body).encode() if body else None
req = urllib.request.Request(
f"{API_URL}/{path}",
data=data,
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {TOKEN}"
}
)
return json.loads(urllib.request.urlopen(req).read())
# Now use it for any endpoint
accounts = api("Account/search", {"onlyActiveAccounts": True})
contracts = api("Contract/search", {"searchText": "NQ"})

Security best practices

  • Never hardcode API keys in your scripts. Use environment variables: os.environ["TESTMAX_API_KEY"]
  • Do not commit tokens or keys to version control. Add them to .gitignore or use a .env file
  • Rotate keys periodically in Settings > API Keys. Old keys can be revoked at any time
  • Log out when done by calling Auth/logout to invalidate tokens after a script completes
  • Use one key per integration so you can revoke access to a single script without affecting others