Documentation

WaiTrade API Reference.

A REST API for browsing algorithms, managing your watchlist and portfolio, and recording backtest runs. All endpoints return JSON.

Introduction

The base URL for all requests is your deployment origin — for local development, http://localhost:3000. Endpoints under /api/algorithms are public and read-only. Endpoints that read or write account data require an authenticated session and are marked Session or Admin below.

Authentication

WaiTrade uses cookie-based sessions (Auth.js). Log in via /login in the browser, or authenticate programmatically against /api/auth/callback/credentials with your email and password. The session cookie is then sent automatically on subsequent requests from the same client. There is no separate API key — session-protected endpoints check the same cookie the web app uses.

Algorithms

GET/api/algorithmsPublic

List algorithms. Supports filtering by asset, risk, and performance thresholds.

?asset=?risk=?featured=?minReturn=?maxDrawdown=?limit=
Response
{
  "data": [
    {
      "id": "aurum-drift",
      "name": "Aurum Drift",
      "developer": "Halcyon Quant",
      "asset": "XAUUSD",
      "risk": "Low",
      "returnPct": 34.2,
      "maxDrawdownPct": 7.8,
      "sharpe": 2.11,
      "price": 249
      // ...full algorithm fields
    }
  ],
  "count": 12
}
GET/api/algorithms/:idPublic

Fetch a single algorithm by its id.

Response
{
  "data": {
    "id": "aurum-drift",
    "name": "Aurum Drift",
    "equity": [1000, 1012, 998, ...]
    // ...full algorithm fields
  }
}

Watchlist

GET/api/watchlistSession

List the current user's watchlist.

Response
{ "data": [ { "algorithmId": "aurum-drift", "algorithm": { /* ... */ } } ] }
POST/api/watchlistSession

Add an algorithm to the current user's watchlist.

Request body
{ "algorithmId": "aurum-drift" }
Response
{ "data": { "id": "...", "algorithmId": "aurum-drift" } }
DELETE/api/watchlistSession

Remove an algorithm from the current user's watchlist.

Request body
{ "algorithmId": "aurum-drift" }
Response
{ "ok": true }

Portfolio

Adding an algorithm to your portfolio activates it on your dashboard with live P&L tracking. This is a platform-level activation — it does not move funds or deploy to an MT5 account.

GET/api/user-algorithmsSession

List the current user's active portfolio holdings.

Response
{ "data": [ { "algorithmId": "obsidian-swing", "allocation": 34, "status": "live", "pnl": 1842.5 } ] }
POST/api/user-algorithmsSession

Add an algorithm to the current user's portfolio ('Get Access').

Request body
{ "algorithmId": "obsidian-swing", "allocation": 20 }
Response
{ "data": { "id": "...", "allocation": 20, "status": "live" } }
DELETE/api/user-algorithmsSession

Remove an algorithm from the current user's portfolio.

Request body
{ "algorithmId": "obsidian-swing" }
Response
{ "ok": true }

Backtests

GET/api/backtestsSession

List the current user's backtest run history, most recent first.

Response
{ "data": [ { "algorithmName": "Obsidian Swing", "asset": "XAUUSD", "months": 24, "resultPct": 12.4 } ] }
POST/api/backtestsSession

Record a backtest run against the current user's history.

Request body
{
  "algorithmName": "Obsidian Swing",
  "algorithmId": "obsidian-swing",
  "asset": "XAUUSD",
  "months": 24,
  "resultPct": 12.4
}
Response
{ "data": { "id": "...", "resultPct": 12.4 } }

Admin

Admin endpoints require the current session's user to have the admin role. Attempting to call these without admin access returns 403.

GET/api/admin/usersAdmin

List all registered users and their subscription plan.

Response
{ "data": [ { "id": "...", "email": "...", "role": "trader", "plan": "free" } ] }
PATCH/api/admin/users/:idAdmin

Change a user's role. Admins cannot demote their own account.

Request body
{ "role": "developer" }
Response
{ "data": { "id": "...", "role": "developer" } }
DELETE/api/admin/users/:idAdmin

Delete a user account. Admins cannot delete their own account here.

Response
{ "ok": true }

Errors

Errors are returned as JSON with a non-2xx status code and an error message.

Example — 401 Unauthorized
{ "error": "You must be logged in." }
400
Bad request
401
Not authenticated
403
Not authorized
404
Not found