Overview & authentication

Base URL, auth, access levels, and conventions.

Everything you can do in the app, you can do over the HTTP + WebSocket API — create trading accounts, open sessions (practice or live), place orders, read positions, build and save strategies with their backtest results, and stream live data. This section is a practical reference; the full machine-readable specification lives at /openapi.yaml.

Base URL

https://api.0dtespx.com

A liveness probe is available at GET /health (no auth, returns 200).

Discovering the API

Three documents are served unauthenticated and are the canonical, always-current reference:

Document Contents
/openapi.yaml Full HTTP + WebSocket spec (OpenAPI 3.0.3)
API walkthrough End-to-end walkthrough with copy-pasteable curl
/llms.txt An llmstxt.org index for AI agents

Authentication

Authenticate with a bearer session token, obtained by logging in:

curl -s https://api.0dtespx.com/auth/sessions \
  -H 'Content-Type: application/json' \
  -d '{"email":"[email protected]","password":"…"}'
# → {"token":"8a4f3e21d6c94b0e9f2a1c5b7d8e4f60"}

Send the token as the bare value of the Authorization header — no Bearer prefix:

Authorization: 8a4f3e21d6c94b0e9f2a1c5b7d8e4f60

Auth endpoints

Method Path Purpose
POST /auth/check-email Is this email registered? (404 = free to register)
POST /auth/verify-email Send a 6-digit verification code (one request per 60 s)
POST /auth/register Create the account; returns your first session {token}
POST /auth/sessions Log in with password, or email + fresh verification code
DELETE /auth/sessions Log out (invalidate the token)
POST /auth/forgot-password Email a password-reset link (always 204; never reveals accounts)
POST /auth/reset-password Set a new password with the emailed reset token

Registration uses a 6-digit email verification code (POST /auth/verify-email then POST /auth/register). Codes expire after 15 minutes, lock after 5 failed submissions, and are single-use — registration consumes the code and returns the session token for your first session directly, so no separate login is needed (or possible with the same code). A password is optional: omit it at registration for a passwordless account that always logs in with a fresh code.

Registration is bounded two ways: one account per inbox — address aliases that deliver to the same mailbox (for Gmail, dots and +suffix variants of the local part) count as the same inbox and are rejected with 400 — and a small daily allowance of new accounts per network, rejected with 429 when exhausted. One account gives full access, so neither bound affects normal use.

Your profile is at GET /user — it reports your id, email, rate-limit usage_percent, your effective fee schedule, and your slippage setting. PATCH /user updates the email, password, fee schedule, or slippage.

Conventions

  • Content type — authenticated requests send Content-Type: application/json; responses are JSON unless noted.
  • Decimals — monetary values are JSON strings ("500000", "1.45") to preserve precision. Parse them with a decimal library, not a float.
  • Times — request timestamps are RFC 3339 with a timezone (2025-01-15T14:30:00Z); always include the Z or an offset. Snapshot timestamps in URL paths use YYYY-MM-DDTHH:MM:SS in UTC.
  • Errors — the status code carries the meaning; the body carries the reason. Most validation errors return a small JSON envelope ({"message": "…"}, or {"error": "<code>", …} for feature and rate-limit errors); two exceptions are relayed as short plain-text bodies: live-order rejections from the exchange and some auth-flow errors. Never parse error prose — branch on the status code (and the error code where present).

Access levels

There are exactly two levels of access — registration is free and nothing is paid:

Access Market data History Notes
Visitor 30-second Most recent completed session only Unauthenticated
Registered 1-second All dates Free account; accounts & sessions; custom fees

Today's in-progress session returns 1-second data to everyone until it closes. See Access & accounts for details.

Status codes

Status When
200 OK with body
201 Resource created
202 Accepted — queued for asynchronous processing (results updates, bot commands)
204 OK, no body
400 Validation error (reason in the body)
401 Missing or invalid auth
403 Forbidden for this account
404 Not found, not yours, or feature not yet launched (feature_unavailable)
409 Conflict — the resource's current state forbids it (e.g. order not pending)
422 Semantically invalid (e.g. portfolio member rules, session outside RTH)
429 Rate limit or concurrency cap hit
500 Server error
503 Live trading briefly unavailable — safe to retry; no state changed

Rate limiting

Market-data endpoints are rate-limited for all authenticated accounts via a credit budget; exceeding it returns 429. Visitor traffic isn't metered because it can only reach the most recent session at coarse resolution. See rate limits for the leaky-bucket mechanism and per-endpoint costs.

Feature flags

One documented surface is not yet launched: the Bots API. Until it goes live, its endpoints return 404 {"error":"feature_unavailable"}. Everything else on this reference is live today.

Where to go next