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 theZor an offset. Snapshot timestamps in URL paths useYYYY-MM-DDTHH:MM:SSin 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 theerrorcode 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
- API walkthrough — the guided end-to-end tutorial.
- Rate limits — the credit budget and per-endpoint costs.
- Accounts & sessions API — create accounts, open sessions, drive the clock.
- Orders API — place, preview, and cancel orders.
- Positions & transactions — read computed state.
- Market data API — sessions, strikes, snapshots.
- Live trading API — trade today's session on a live account.
- Strategies API — strategies and their backtest results.
- Portfolios API — aggregate strategies at read time.
- WebSocket streams — real-time data and events.