Deltalytix
  • Support
Sign in

API documentation.

Authenticate with OAuth or personal access tokens, then read and write trades, accounts, connections, imports, and metrics through the Deltalytix Public API v1.

On this page

  • What you can do
  • Authentication
    • Get a token
    • OAuth 2.0
  • Trades
  • Accounts
  • Connections
  • Imports
  • Metrics
  • Errors
  • OpenAPI reference

What you can do

Each row opens the matching guide. Include that scope on your token.

You canScope
Read the authenticated user profileprofile:read
List tradestrades:read
Create tradestrades:write
List accounts and related metricsaccounts:read
List broker connectionsconnections:read
Create connections and trigger syncconnections:write
Upload import filesimports:write
Read summary, equity, and account metricsmetrics:read

Authentication

Get a token

You can generate or paste a token from any try panel when you need one.

Deltalytix is its own OAuth 2.0 authorization server. Humans still sign in with Supabase; API tokens are minted and validated by Deltalytix.

Every /api/v1/* request requires a Bearer token:

Authorization: Bearer dltx_at_…

REST endpoints are served from https://www.deltalytix.app under API v1 (/api/v1/*). List endpoints accept limit (default 100, max 500) and cursor. Timestamps are ISO 8601. Machine-readable discovery: /openapi.json, /.well-known/openid-configuration, /.well-known/oauth-protected-resource.

Token formats

Tokens are opaque strings. Deltalytix stores only SHA-256 hashes.

KindPrefixLifetime
Access tokendltx_at_<48 hex chars>3600 seconds
Refresh tokendltx_rt_<48 hex chars>30 days (rotated on use)
Personal access token (PAT)dltx_pat_<48 hex chars>No expiry until revoked
Client IDdltx_app_<24 hex chars>—
Client secretdltx_secret_<48 hex chars>Shown once at creation

Scopes

Request only the scopes your integration needs. Space-separate them in OAuth scope parameters. The full list is in what you can do.

Personal access tokens

PATs are ideal for scripts and private tools. Create and revoke them in Settings → Connections, choosing the scopes you need. The token value is shown once.

curl https://www.deltalytix.app/api/v1/me \
  -H "Authorization: Bearer dltx_pat_YOUR_TOKEN"

Demo token

The documentation playground can issue a short-lived, read-only demo token without signing in. It authenticates as a shared sample account (DEMO-001) so you can try GET routes. Write scopes require your own docs token or PAT. Signed-in docs playground tokens expire after 24 hours.

OAuth 2.0

Register your app on the Developers page to get a client_id and a client_secret.

1. Authorize

Send the user to the consent page (HTML). Unauthenticated users are redirected to /authentication?next=….

GET /oauth/authorize
  ?client_id=dltx_app_…
  &redirect_uri=https%3A%2F%2Fyour-app.example%2Fcallback
  &response_type=code
  &scope=profile%3Aread%20trades%3Aread
  &state=csrf-token
  &code_challenge=BASE64URL_SHA256_OF_VERIFIER
  &code_challenge_method=S256

Try this route

This authorization endpoint requires a browser redirect and user consent, so it can’t be sent as an API request here.

QueryRequiredNotes
client_idYesRegistered OAuth app
redirect_uriYesMust exactly match a registered URI
response_typeYesMust be code
scopeYesSpace-separated scopes
stateRecommendedCSRF protection; echoed on redirect
code_challengeRecommendedPKCE S256 challenge
code_challenge_methodWith challengeMust be S256

On approve, Deltalytix issues a single-use authorization code (10 minute TTL) and redirects. Re-approving the same app for the same user revokes that pair’s prior access and refresh tokens and invalidates unused authorization codes so only the new grant remains usable:

https://your-app.example/callback?code=…&state=…

On deny:

https://your-app.example/callback?error=access_denied&state=…

2. Exchange the code for tokens

POST /api/oauth/token accepts form-urlencoded or JSON.

Loading the live endpoint definition…
curl -X POST https://www.deltalytix.app/api/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTHORIZATION_CODE" \
  -d "redirect_uri=https://your-app.example/callback" \
  -d "client_id=dltx_app_…" \
  -d "client_secret=dltx_secret_…" \
  -d "code_verifier=PKCE_VERIFIER"

Every OAuth app is a confidential client. Send client_secret in the body (client_secret_post) or as Authorization: Basic (client_secret_basic) on the code exchange, on refresh, and on revoke. A missing or wrong secret returns 401 invalid_client. PKCE is still recommended: a code issued with a code_challenge also needs the matching code_verifier.

Success

{
  "access_token": "dltx_at_…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "dltx_rt_…",
  "scope": "profile:read trades:read"
}

OAuth errors follow RFC 6749:

Error

{
  "error": "invalid_grant",
  "error_description": "Invalid or expired authorization code"
}

3. Call the API

curl https://www.deltalytix.app/api/v1/trades?limit=10 \
  -H "Authorization: Bearer dltx_at_…"
const res = await fetch("https://www.deltalytix.app/api/v1/trades?limit=10", {
  headers: {
    Authorization: `Bearer ${accessToken}`,
  },
});

4. Refresh the access token

curl -X POST https://www.deltalytix.app/api/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "refresh_token",
    "refresh_token": "dltx_rt_…",
    "client_id": "dltx_app_…",
    "client_secret": "dltx_secret_…"
  }'

Refresh tokens rotate on use. Store the new refresh_token from each successful response.

5. Revoke a token

curl -X POST https://www.deltalytix.app/api/oauth/revoke \
  -H "Content-Type: application/json" \
  -d '{
    "token": "dltx_at_…",
    "client_id": "dltx_app_…",
    "client_secret": "dltx_secret_…"
  }'
Loading the live endpoint definition…

Revocation always returns 200, whether or not the token was found.

Resource-server failures

Missing or invalid Bearer tokens return 401:

Error

{
  "error": "unauthorized",
  "message": "…"
}

with a WWW-Authenticate header pointing at protected-resource metadata.

Valid tokens without the required scope return 403:

Error

{
  "error": "insufficient_scope",
  "message": "…"
}

Managing apps and tokens

On the Developers page you can:

  • Create OAuth apps (name, redirect URIs, allowed scopes) — client_id is always visible; client_secret is shown once. Redirect URIs must be absolute https URLs (plain http only on localhost) without a fragment.
  • Edit an app, regenerate its secret, or delete it

In Settings → Connections you can:

  • Create and revoke personal access tokens with chosen scopes — the PAT value is shown once
  • Revoke apps you authorized on your own account

Trades

List and create trades with filters, pagination, and the shared import/dedupe pipeline.

Manage the authenticated user’s trade history.

List trades

GET /api/v1/trades

Scope: trades:read

Loading the live endpoint definition…

Query parameters

ParameterDescription
accountNumberFilter by account number
instrumentFilter by instrument symbol
sideFilter by side
fromInclusive lower bound on entryDate (ISO 8601)
toInclusive upper bound on entryDate (ISO 8601)
cursorOpaque pagination cursor
limitPage size (default 100, max 500)

Example

curl "https://www.deltalytix.app/api/v1/trades?accountNumber=SIM-001&limit=50" \
  -H "Authorization: Bearer dltx_at_…"
const params = new URLSearchParams({
  accountNumber: "SIM-001",
  from: "2026-01-01T00:00:00.000Z",
  limit: "50",
});
 
const res = await fetch(`https://www.deltalytix.app/api/v1/trades?${params}`, {
  headers: { Authorization: `Bearer ${accessToken}` },
});
const page = await res.json();

Response 200

Success

{
  "data": [
    {
      "id": "trade_01HZX…",
      "accountNumber": "SIM-001",
      "instrument": "ES",
      "side": "long",
      "quantity": 2,
      "entryPrice": 5120.25,
      "closePrice": 5128.5,
      "entryDate": "2026-03-15T14:30:00.000Z",
      "closeDate": "2026-03-15T15:10:00.000Z",
      "pnl": 825,
      "commission": 8.64,
      "timeInPosition": 2400,
      "tags": ["breakout"],
      "comment": "Morning continuation",
      "createdAt": "2026-03-15T15:12:01.000Z"
    }
  ],
  "nextCursor": null
}

Create trades

POST /api/v1/trades

Scope: trades:write

Loading the live endpoint definition…

Creates one or more trades using the same dedupe pipeline as the dashboard (UUID v5 identity + createMany with skipDuplicates). Duplicate payloads are counted, not treated as hard failures.

Request body

{
  "trades": [
    {
      "accountNumber": "SIM-001",
      "instrument": "ES",
      "quantity": 2,
      "entryPrice": 5120.25,
      "closePrice": 5128.5,
      "entryDate": "2026-03-15T14:30:00.000Z",
      "closeDate": "2026-03-15T15:10:00.000Z",
      "pnl": 825,
      "side": "long",
      "commission": 8.64,
      "entryId": "optional-broker-entry-id",
      "closeId": "optional-broker-close-id",
      "timeInPosition": 2400,
      "tags": ["breakout"],
      "comment": "Morning continuation"
    }
  ]
}
FieldRequiredNotes
accountNumberYesTarget account
instrumentYesSymbol / contract
quantityYesSize
entryPriceYesEntry price
closePriceYesExit price
entryDateYesISO 8601
closeDateYesISO 8601
pnlYesRealized P&L
sideNoe.g. long / short
commissionNoFees
entryIdNoBroker entry identifier
closeIdNoBroker exit identifier
timeInPositionNoDuration in seconds
tagsNoString array
commentNoFree text

Example

curl -X POST https://www.deltalytix.app/api/v1/trades \
  -H "Authorization: Bearer dltx_at_…" \
  -H "Content-Type: application/json" \
  -d '{
    "trades": [
      {
        "accountNumber": "SIM-001",
        "instrument": "ES",
        "quantity": 2,
        "entryPrice": 5120.25,
        "closePrice": 5128.5,
        "entryDate": "2026-03-15T14:30:00.000Z",
        "closeDate": "2026-03-15T15:10:00.000Z",
        "pnl": 825,
        "side": "long",
        "commission": 8.64
      }
    ]
  }'

Response 201

Success

{
  "imported": 1,
  "duplicates": 0,
  "total": 1
}

If every row is a duplicate, the response still returns success with counts (for example "imported": 0, "duplicates": 3, "total": 3), not an error status.

Accounts

List trading accounts, payouts, and optional per-account performance metrics.

Read the authenticated user’s accounts and related payout information.

List accounts

GET /api/v1/accounts

Scope: accounts:read

Loading the live endpoint definition…

Query parameters

ParameterDescription
includeMetricsWhen true, attaches per-account metrics from computeMetricsForAccounts

Example

curl "https://www.deltalytix.app/api/v1/accounts?includeMetrics=true" \
  -H "Authorization: Bearer dltx_at_…"
const res = await fetch(
  "https://www.deltalytix.app/api/v1/accounts?includeMetrics=true",
  {
    headers: { Authorization: `Bearer ${accessToken}` },
  },
);
const payload = await res.json();

Response 200

Success

{
  "data": [
    {
      "id": "acc_01HZX…",
      "number": "SIM-001",
      "propfirm": "Topstep",
      "startingBalance": 50000,
      "createdAt": "2026-01-15T09:00:00.000Z",
      "hidden": false,
      "group": { "id": "grp_01HZX…", "name": "Evaluations" },
      "balance": 52480.12,
      "payouts": [
        {
          "id": "pay_01HZX…",
          "amount": 2500,
          "date": "2026-02-01T00:00:00.000Z",
          "status": "PAID"
        }
      ],
      "metrics": { "…": "…" }
    }
  ]
}

Hidden accounts

Every account is returned, including ones hidden in the dashboard. Hiding an account moves it into the Hidden Accounts group, so hidden is true for those accounts and group.name is "Hidden Accounts". Skip accounts where hidden is true to match what the dashboard shows. group is null for accounts that are not in any group.

metrics is present only when includeMetrics=true. Metric fields include balance, drawdown, consistency, and progress toward account targets.

For portfolio-level analytics across all accounts, prefer the Metrics endpoints.

Connections

List broker connections, create server-syncable connections, and trigger sync.

Broker connections sync trades into Deltalytix. Raw broker tokens are never returned by the API.

Server-syncable services in v1:

serviceCreateSyncNotes
ibkrtoken, queryIdyesIBKR Flex Web Service
dxfeedlogin, password, propFirmIdyesVolumetrica / DxFeed prop firms
rithmic-protocolusername, password, systemName, historyStartDate, optional gatewayIdyesRithmic Protocol gateway
tradovatedashboard OAuth onlyyesConnect in the Deltalytix dashboard, then list and sync via the API

Classic rithmic, thor, and etp may appear in GET listings but are not creatable or syncable through this API.

List connections

GET /api/v1/connections

Scope: connections:read

Loading the live endpoint definition…

Example

curl https://www.deltalytix.app/api/v1/connections \
  -H "Authorization: Bearer dltx_at_…"

Response 200

Success

{
  "data": [
    {
      "id": "conn_01HZX…",
      "service": "ibkr",
      "externalId": "flex-query-123",
      "lastSyncedAt": "2026-03-15T16:00:00.000Z",
      "environment": "live",
      "accountNumbers": ["U1234567"]
    }
  ],
  "nextCursor": null
}
FieldDescription
idConnection identifier
serviceProvider key (ibkr, tradovate, dxfeed, rithmic-protocol, …)
externalIdProvider-side identifier (never a secret token)
lastSyncedAtLast successful sync timestamp, or null
environmente.g. live / demo when applicable
accountNumbersLinked Deltalytix account numbers

Create a connection

POST /api/v1/connections

Scope: connections:write

Loading the live endpoint definition…

Body is discriminated by service. On success the API stores credentials (encrypted), links accounts when available, attempts an initial sync, and returns the connection without secrets.

IBKR Flex

{
  "service": "ibkr",
  "token": "<flex token>",
  "queryId": "<flex query id>"
}
curl -X POST https://www.deltalytix.app/api/v1/connections \
  -H "Authorization: Bearer dltx_at_…" \
  -H "Content-Type: application/json" \
  -d '{
    "service": "ibkr",
    "token": "YOUR_FLEX_TOKEN",
    "queryId": "YOUR_FLEX_QUERY_ID"
  }'

DxFeed

{
  "service": "dxfeed",
  "login": "trader@example.com",
  "password": "…",
  "propFirmId": "miltraders"
}

propFirmId must be an enabled firm id (for example miltraders, myfundedfutures, phoenixtraderfunding).

Rithmic Protocol

{
  "service": "rithmic-protocol",
  "username": "your-username",
  "password": "…",
  "systemName": "Rithmic Paper Trading",
  "historyStartDate": "2026-01-01",
  "gatewayId": "core"
}

historyStartDate is YYYY-MM-DD. gatewayId is optional (e.g. core, nyc, test).

Response 201

Success

{
  "id": "conn_01HZX…",
  "service": "ibkr",
  "externalId": "flex-query-123",
  "accountNumbers": ["U1234567"],
  "imported": 42,
  "duplicates": 3
}

If the connection is stored but the initial sync fails, the response still returns 201 with imported: 0 and a warning message.

Unsupported service → 422

Error

{
  "error": "unsupported_service",
  "message": "Only credential-based connection services can be created in v1",
  "details": {
    "supported": ["ibkr", "dxfeed", "rithmic-protocol"]
  }
}

Trigger a sync

POST /api/v1/connections/{id}/sync

Scope: connections:write

Loading the live endpoint definition…

Works for ibkr, dxfeed, rithmic-protocol, and tradovate connections that were already linked in the dashboard.

Example

curl -X POST https://www.deltalytix.app/api/v1/connections/conn_01HZX…/sync \
  -H "Authorization: Bearer dltx_at_…"

Response 200

Success

{
  "status": "completed",
  "imported": 42,
  "duplicates": 3
}

Imports

Upload CSV or XLSX trade files with AI mapping or platform-specific parsers.

Import trades from files without going through the dashboard UI.

Upload a file

POST /api/v1/imports

Scope: imports:write

Content-Type: multipart/form-data

Loading the live endpoint definition…

Form fields

FieldRequiredDescription
fileYes.csv or .xlsx file
typeYes"ai" or a platform name
accountNumberYesDestination account number

AI import (type=ai)

The server parses the file (Papa Parse for CSV, read-excel-file for XLSX), runs the same AI mapping and formatting pipeline used by the dashboard, then saves trades through the shared trades-save core.

curl -X POST https://www.deltalytix.app/api/v1/imports \
  -H "Authorization: Bearer dltx_at_…" \
  -F "file=@./trades.csv" \
  -F "type=ai" \
  -F "accountNumber=SIM-001"
const form = new FormData();
form.append("file", fileInput.files[0]);
form.append("type", "ai");
form.append("accountNumber", "SIM-001");
 
const res = await fetch("https://www.deltalytix.app/api/v1/imports", {
  method: "POST",
  headers: { Authorization: `Bearer ${accessToken}` },
  body: form,
});
const result = await res.json();

Platform import (type=<platform>)

When type is a platform key, the server uses a registered parser extracted from the dashboard import flow. Supported platforms depend on which parsers are available as pure functions (candidates include tradezella, tradovate, quantower, topstep, ftmo, atas, and others).

curl -X POST https://www.deltalytix.app/api/v1/imports \
  -H "Authorization: Bearer dltx_at_…" \
  -F "file=@./export.xlsx" \
  -F "type=tradovate" \
  -F "accountNumber=SIM-001"

Success response

Success

{
  "imported": 128,
  "duplicates": 4,
  "total": 132,
  "accountNumber": "SIM-001"
}

Unsupported platform → 422

Error

{
  "error": "unsupported_service",
  "message": "Unknown import type",
  "details": {
    "supported": ["ai", "tradovate", "tradezella", "quantower"]
  }
}

The exact details.supported list reflects the live parser registry.

Metrics

Summary statistics, equity curves, and per-account performance metrics.

Compute performance analytics from the authenticated user’s trades.

All metrics endpoints require the metrics:read scope.

Summary

GET /api/v1/metrics/summary
Loading the live endpoint definition…

Uses the same filters as GET /api/v1/trades. Statistics come from calculateStatistics plus the dashboard profit-factor formula (gross wins and losses net of commission).

Query parameters

ParameterDescription
accountNumberFilter by account
instrumentFilter by instrument
sideFilter by side
from / toBounds on entryDate
cursor / limitAccepted for consistency with trades filters where applicable

Example

curl "https://www.deltalytix.app/api/v1/metrics/summary?from=2026-01-01T00:00:00.000Z" \
  -H "Authorization: Bearer dltx_at_…"

Response 200

Success

{
  "totalPnl": 12450.5,
  "totalCommission": 312.4,
  "tradeCount": 186,
  "winCount": 102,
  "lossCount": 78,
  "breakevenCount": 6,
  "winRate": 0.5484,
  "profitFactor": 1.62,
  "averageWin": 215.3,
  "averageLoss": -142.1,
  "longCount": 110,
  "shortCount": 76,
  "tradingDays": 48
}

Equity curve

GET /api/v1/metrics/equity
Loading the live endpoint definition…

Builds daily equity points via computeEquityChartData.

Query parameters

ParameterDescription
fromStart date (ISO 8601)
toEnd date (ISO 8601)
accountNumbersComma-separated account numbers; when provided, also returns per-account series

Example

curl "https://www.deltalytix.app/api/v1/metrics/equity?accountNumbers=SIM-001,SIM-002&from=2026-01-01T00:00:00.000Z" \
  -H "Authorization: Bearer dltx_at_…"
const params = new URLSearchParams({
  accountNumbers: "SIM-001,SIM-002",
  from: "2026-01-01T00:00:00.000Z",
});
 
const res = await fetch(
  `https://www.deltalytix.app/api/v1/metrics/equity?${params}`,
  { headers: { Authorization: `Bearer ${accessToken}` } },
);
const equity = await res.json();

Response 200

Success

{
  "points": [
    {
      "date": "2026-01-02",
      "equity": 50120.5
    },
    {
      "date": "2026-01-03",
      "equity": 50385.25
    }
  ],
  "accounts": {
    "SIM-001": [
      { "date": "2026-01-02", "equity": 25050.0 },
      { "date": "2026-01-03", "equity": 25210.75 }
    ],
    "SIM-002": [
      { "date": "2026-01-02", "equity": 25070.5 },
      { "date": "2026-01-03", "equity": 25174.5 }
    ]
  }
}

The accounts object is included when accountNumbers is requested.

Account metrics

GET /api/v1/metrics/accounts
Loading the live endpoint definition…

Runs computeMetricsForAccounts for all of the user’s accounts.

Example

curl https://www.deltalytix.app/api/v1/metrics/accounts \
  -H "Authorization: Bearer dltx_at_…"

Response 200

Success

{
  "data": [
    {
      "accountNumber": "SIM-001",
      "balance": 52480.12,
      "drawdown": 3.4,
      "consistency": 0.82,
      "progress": 0.61
    }
  ]
}

Errors

REST error envelope, HTTP status codes, and OAuth error responses.

REST error envelope

API v1 errors use a consistent JSON body:

Error

{
  "error": "machine_code",
  "message": "Human-readable explanation",
  "details": {}
}
FieldDescription
errorStable machine-readable code
messageHuman-readable explanation
detailsOptional structured context (validation issues, supported values, …)

HTTP status codes

StatusTypical cause
400Validation error (malformed query/body)
401Missing, expired, revoked, or invalid Bearer token
403Authenticated but missing required scope
404Resource not found
422Semantically invalid request (unsupported service/type)
500Unexpected server error

Unauthorized (401)

Error

{
  "error": "unauthorized",
  "message": "Missing or invalid access token"
}

Responses include:

WWW-Authenticate: Bearer resource_metadata="https://www.deltalytix.app/.well-known/oauth-protected-resource"

Insufficient scope (403)

Error

{
  "error": "insufficient_scope",
  "message": "Token is missing required scope trades:write"
}

Unsupported service (422)

Error

{
  "error": "unsupported_service",
  "message": "Only credential-based connection services can be created in v1",
  "details": {
    "supported": ["ibkr", "dxfeed", "rithmic-protocol"]
  }
}

OAuth errors

Token endpoint failures use the RFC 6749 shape (not the REST envelope):

Error

{
  "error": "invalid_grant",
  "error_description": "Authorization code is invalid or expired"
}

Common OAuth error values include invalid_request, invalid_client, invalid_grant, unauthorized_client, unsupported_grant_type, and invalid_scope.

Authorization endpoint denials redirect to the registered redirect_uri with error=access_denied (and the original state when provided).

Non-error counts

Some write endpoints report duplicate or zero-import outcomes with HTTP success and count fields instead of an error body. For example, POST /api/v1/trades returns 201 with "imported": 0 when every row already exists.

Handling tips

  1. Branch first on HTTP status, then on error.
  2. Surface message to developers; use error for programmatic handling.
  3. Treat details.supported as the authoritative allow-list when present.
  4. On 401, refresh the OAuth access token or prompt for a new PAT; do not retry indefinitely.

OpenAPI reference

OpenAPI JSON

Paths, methods, parameters, and response codes from the live OpenAPI document.

Download openapi.json

Loading OpenAPI document…

Footer

Deltalytix

A trading journal for every futures account.

GitHubYouTubeDiscord

Product

  • Features
  • Pricing
  • Prop Firms Catalogue
  • Teams
  • Support
  • Documentation
  • API documentation

Company

  • About

Journals comparison

  • All journals
  • vs Trademetria
  • vs TradeZella
  • vs Tradervue

Legal

  • Privacy Policy
  • Settings
  • Terms of Service
  • Disclaimers
© 2026 Deltalytix. All rights reserved.
Trading in futures and forex markets involves significant risks and is not suitable for all investors. An investor could potentially lose all or a portion of their initial investment. Risk capital is money that can be lost without jeopardizing one's financial security or lifestyle. Only risk capital should be used for trading, and only those with sufficient risk capital should consider trading. Past performance is not necessarily indicative of future results.
Hypothetical performance results have many inherent limitations, some of which are described below. No representation is being made that any account will or is likely to achieve profits or losses similar to those shown; in fact, there are frequently sharp differences between hypothetical performance results and the actual results subsequently achieved by any particular trading program. One of the limitations of hypothetical performance results is that they are generally prepared with the benefit of hindsight. In addition, hypothetical trading does not involve financial risk, and no hypothetical trading record can completely account for the impact of financial risk in actual trading. For example, the ability to withstand losses or to adhere to a particular trading program in spite of trading losses are material points which can also adversely affect actual trading results. There are numerous other factors related to the markets in general or to the implementation of any specific trading program which cannot be fully accounted for in the preparation of hypothetical performance results and all of which can adversely affect actual trading results.