Trading App API

REST API documentation for the Trading Application

Authentication

Protected endpoints use cookie-based auth. Log in via /api/auth/login to receive the auth_token httpOnly cookie.

The auth_token cookie is set automatically on login and sent with every same-origin request — no Authorization header is needed for browser-based access.

Base URL

https://api.PLACEHOLDER.com

Production — replace PLACEHOLDER with the assigned domain before go-live

http://10.200.0.52:3000

VPN (internal development)

http://localhost:3000

Local development

Errors

All error responses share the same JSON envelope:

{
  "error": "Description of what went wrong",
  "code":  "400"
}
HTTP StatusMeaning
400Bad Request — invalid parameters
401Unauthorized — missing or invalid auth
403Forbidden — insufficient permissions
404Not Found
409Conflict — resource already exists
500Internal Server Error

Admin

GET/admin/users

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl https://<host>/api/admin/users \
  -b cookies.txt

Example Response

{
  "users": [
    {
      "userId": "cm1abc123xyz",
      "email": "admin@havencap.io",
      "role": "ADMIN",
      "status": "ACTIVE",
      "createdAt": "2026-01-01T00:00:00.000Z"
    },
    {
      "userId": "cm1def456uvw",
      "email": "trader@havencap.io",
      "role": "PENDING",
      "status": "PENDING",
      "createdAt": "2026-05-01T09:00:00.000Z"
    }
  ]
}
PATCH/admin/users/{userId}

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

// Approve a pending user and assign OPERATOR role:
curl -X PATCH https://<host>/api/admin/users/cm1def456uvw \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "role": "OPERATOR",
    "status": "ACTIVE"
  }'

Example Response

{
  "user": {
    "userId": "cm1def456uvw",
    "email": "trader@havencap.io",
    "role": "OPERATOR",
    "status": "ACTIVE",
    "createdAt": "2026-05-01T09:00:00.000Z"
  }
}

Auth

POST/auth/login

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl -X POST https://<host>/api/auth/login \
  -H "Content-Type: application/json" \
  -c cookies.txt \
  -d '{
    "email": "trader@havencap.io",
    "password": "mypassword123"
  }'

Example Response

{
  "user": {
    "userId": "cm1abc123xyz",
    "email": "trader@havencap.io",
    "role": "OPERATOR",
    "createdAt": "2026-04-01T09:00:00.000Z"
  },
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
POST/auth/logout

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl -X POST https://<host>/api/auth/logout \
  -b cookies.txt

Example Response

{
  "message": "Logged out"
}
GET/auth/me

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl https://<host>/api/auth/me \
  -b cookies.txt

Example Response

{
  "user": {
    "userId": "cm1abc123xyz",
    "email": "trader@havencap.io",
    "role": "OPERATOR",
    "createdAt": "2026-04-01T09:00:00.000Z"
  }
}
GET/auth/refresh

Used by the middleware redirect flow: GET /api/auth/refresh?callbackUrl=/markets

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

// Browser redirect flow — used by middleware:
GET /api/auth/refresh?callbackUrl=/markets

Example Response

// 302 redirect to /markets with refreshed auth_token cookie set
POST/auth/refresh

Used by client-side fetch interceptors: POST /api/auth/refresh

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl -X POST https://<host>/api/auth/refresh \
  -b cookies.txt

Example Response

{
  "user": {
    "userId": "cm1abc123xyz",
    "email": "trader@havencap.io",
    "role": "OPERATOR",
    "createdAt": "2026-04-01T09:00:00.000Z"
  }
}
POST/auth/register

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl -X POST https://<host>/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "trader@havencap.io",
    "password": "mypassword123"
  }'

Example Response

// First registered user — becomes ADMIN and receives a token:
{
  "user": {
    "userId": "cm1abc123xyz",
    "email": "trader@havencap.io",
    "role": "ADMIN",
    "createdAt": "2026-05-01T09:00:00.000Z"
  },
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

// Subsequent registrations — account awaits admin approval:
{
  "message": "Registration successful. Your account is pending admin approval."
}

Devbe

GET/devbe/data/{queryType}

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl "https://<host>/api/devbe/data/walletSummary?walletId=1" \
  -b cookies.txt

Example Response

// Response structure varies by queryType.
// Returns the raw result from the DevBE data service.
GET/devbe/run/{script}

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl "https://<host>/api/devbe/run/verifySignature?address=0xd8dA...&message=hello&signature=0xsig..." \
  -b cookies.txt

Example Response

// Response structure varies by script.
// Returns the raw result from the DevBE script runner.

Droids

GET/droids

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl https://<host>/api/droids \
  -b cookies.txt

Example Response

{
  "droids": [
    {
      "id": 1,
      "blockChain": "ethereum",
      "active": 1,
      "poolId": 42,
      "fundingUSD": 50000,
      "triggerType": "EMA",
      "tickBuckets": 10,
      "bucketOffset": 0,
      "fundingCurveType": "LINEAR",
      "maxBots": 5,
      "maxPrice": 4000.00,
      "minPrice": 2500.00,
      "fallingRebalanceTrigger": 0.03,
      "risingRebalanceTrigger": 0.05,
      "maxGasPrice": 50,
      "txPriority": 1,
      "derivativeThreshold": 0.01,
      "ladderPercMargin": 0.02,
      "createdAt": "2026-01-15T08:00:00.000Z"
    }
  ]
}
POST/droids

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl -X POST https://<host>/api/droids \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "poolId": 42,
    "fundingUSD": 50000,
    "triggerType": "EMA",
    "tickBuckets": 10,
    "bucketOffset": 0,
    "fundingCurveType": "LINEAR",
    "maxBots": 5,
    "maxPrice": 4000.00,
    "minPrice": 2500.00,
    "gasBudgetLimit": 100,
    "maxGasPrice": 50,
    "txPriority": 1,
    "derivativeThreshold": 0.01,
    "ladderPercMargin": 0.02,
    "fallingRebalanceTrigger": 0.03,
    "risingRebalanceTrigger": 0.05
  }'

Example Response

{
  "id": 1
}
GET/droids/{id}

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl https://<host>/api/droids/1 \
  -b cookies.txt

Example Response

{
  "droid": {
    "id": 1,
    "active": 1,
    "poolId": 42,
    "fundingUSD": 50000,
    ...
  },
  "sessions": [
    {
      "id": 101,
      "startedAt": "2026-04-30T12:00:00.000Z",
      "stoppedAt": null,
      "status": "RUNNING"
    }
  ],
  "bots": [
    {
      "id": 201,
      "positionId": "0xabc...",
      "status": "ACTIVE"
    }
  ]
}
GET/droids/accounts

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl https://<host>/api/droids/accounts \
  -b cookies.txt

Example Response

{
  "accounts": [
    { "id": 1 },
    { "id": 2 }
  ]
}
GET/droids/pools

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl https://<host>/api/droids/pools \
  -b cookies.txt

Example Response

{
  "pools": [
    {
      "id": 42,
      "poolAddress": "0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8",
      "feeTier": 3000
    },
    {
      "id": 43,
      "poolAddress": "0x4e68ccd3e89f51c3074ca5072bbac773960dfa36",
      "feeTier": 3000
    }
  ]
}
PATCH/droids/{id}/active

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

// Set droid to running (OPERATOR+):
curl -X PATCH https://<host>/api/droids/1/active \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{ "active": 1 }'

// Pause droid (OPERATOR+):   { "active": 0 }
// Reset droid (ADMIN only):  { "active": 2 }
// Close all + stop (ADMIN):  { "active": 3 }

Example Response

{
  "id": 1,
  "active": 1
}
PATCH/droids/{id}/config

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl -X PATCH https://<host>/api/droids/1/config \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "fallingRebalanceTrigger": 0.03,
    "risingRebalanceTrigger": 0.06,
    "maxBots": 8,
    "maxPrice": 4500.00,
    "minPrice": 2000.00,
    "maxGasPrice": 60,
    "txPriority": 2,
    "fundingUSD": 75000,
    "derivativeThreshold": 0.01,
    "ladderPercMargin": 0.02
  }'

Example Response

{
  "id": 1,
  "fallingRebalanceTrigger": 0.03,
  "risingRebalanceTrigger": 0.06,
  "maxBots": 8,
  "maxPrice": 4500.00,
  "minPrice": 2000.00,
  "maxGasPrice": 60,
  "txPriority": 2,
  "fundingUSD": 75000,
  "derivativeThreshold": 0.01,
  "ladderPercMargin": 0.02
}
GET/droids/{id}/history

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl https://<host>/api/droids/1/history \
  -b cookies.txt

Example Response

{
  "history": [
    {
      "id": 501,
      "timeStamp": "2026-05-01T09:00:00.000Z",
      "aum": 51240.75,
      "price": 3215.50,
      "token0Positions": 8.42,
      "token1Positions": 24112.30,
      "ethWallet": 0.18
    },
    {
      "id": 500,
      "timeStamp": "2026-05-01T08:00:00.000Z",
      "aum": 50980.10,
      "price": 3198.00,
      "token0Positions": 8.55,
      "token1Positions": 23880.00,
      "ethWallet": 0.18
    }
  ]
}

Orders

GET/orders

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl https://<host>/api/orders \
  -b cookies.txt

Example Response

{
  "orders": [
    {
      "orderId": "cm2ord456abc",
      "userId": "cm1abc123xyz",
      "market": "ETH_USDC",
      "side": "BUY",
      "orderType": "LIMIT",
      "quantity": 1.5,
      "price": 3200.00,
      "stopPrice": null,
      "timeInForce": "GTC",
      "status": "OPEN",
      "expiresAt": null,
      "createdAt": "2026-05-01T10:30:00.000Z"
    }
  ]
}
POST/orders

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl -X POST https://<host>/api/orders \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{
    "market": "ETH_USDC",
    "side": "BUY",
    "orderType": "LIMIT",
    "quantity": 1.5,
    "price": 3200.00,
    "timeInForce": "GTC",
    "stopPrice": null,
    "expiresAt": null
  }'

Example Response

{
  "order": {
    "orderId": "cm2ord456abc",
    "userId": "cm1abc123xyz",
    "market": "ETH_USDC",
    "side": "BUY",
    "orderType": "LIMIT",
    "quantity": 1.5,
    "price": 3200.00,
    "stopPrice": null,
    "timeInForce": "GTC",
    "status": "OPEN",
    "expiresAt": null,
    "createdAt": "2026-05-01T10:30:00.000Z"
  }
}
GET/orders/{orderId}

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl https://<host>/api/orders/cm2ord456abc \
  -b cookies.txt

Example Response

{
  "order": {
    "orderId": "cm2ord456abc",
    "userId": "cm1abc123xyz",
    "market": "ETH_USDC",
    "side": "BUY",
    "orderType": "LIMIT",
    "quantity": 1.5,
    "price": 3200.00,
    "stopPrice": null,
    "timeInForce": "GTC",
    "status": "OPEN",
    "expiresAt": null,
    "createdAt": "2026-05-01T10:30:00.000Z"
  }
}
DEL/orders/{orderId}

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl -X DELETE https://<host>/api/orders/cm2ord456abc \
  -b cookies.txt

Example Response

{
  "order": {
    "orderId": "cm2ord456abc",
    "status": "CANCELLED",
    ...
  }
}

User

GET/user/token

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl https://<host>/api/user/token \
  -b cookies.txt

Example Response

// Token exists:
{
  "exists": true,
  "createdAt": "2026-04-15T14:22:00.000Z"
}

// No token issued yet:
{
  "exists": false
}
POST/user/token

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl -X POST https://<host>/api/user/token \
  -b cookies.txt

Example Response

// Raw token — shown once, store it securely:
{
  "token": "hc_live_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
}
DEL/user/token

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl -X DELETE https://<host>/api/user/token \
  -b cookies.txt

Example Response

{
  "message": "Token revoked"
}

V1

GET/v1/health

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl https://<host>/api/v1/health \
  -H "Authorization: Bearer <your_token>"

Example Response

{
  "status": "ok",
  "last_indexed_block": 22450100,
  "last_indexed_timestamp": "2026-04-30T14:22:00Z",
  "chain_tip_block": 22450112,
  "ingestion_lag_seconds": 144.0
}
GET/v1/transactions

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl -G https://<host>/api/v1/transactions \
  -H "Authorization: Bearer <your_token>" \
  --data-urlencode "address=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" \
  --data-urlencode "from_date=2026-04-01T00:00:00Z" \
  --data-urlencode "sort=-timestamp" \
  --data-urlencode "page_size=20"

Example Response

{
  "data": [
    {
      "hash": "0xabc123...",
      "block_number": 22400001,
      "block_timestamp": "2026-04-30T12:00:12Z",
      "from_address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "to_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
      "value_native": "0.00 ETH",
      "value_usd": 0.00,
      "gas_used": 65000,
      "gas_price_gwei": 12.5,
      "gas_fee_usd": 2.44,
      "status": "success",
      "token_transfers": [
        {
          "token_symbol": "USDC",
          "amount_display": "250.00 USDC",
          "amount_usd": 250.00
        }
      ]
    }
  ],
  "page": 1,
  "page_size": 20,
  "total_results": 142,
  "total_pages": 8,
  "next_page_url": "https://<host>/api/v1/transactions?...&page=2",
  "prev_page_url": null
}
GET/v1/blocks/{block_number}

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl https://<host>/api/v1/blocks/22400001 \
  -H "Authorization: Bearer <your_token>"

Example Response

{
  "block_number": 22400001,
  "block_timestamp": "2026-04-30T12:00:12Z",
  "transaction_count": 3,
  "transaction_hashes": [
    "0xabc123...",
    "0xdef456...",
    "0x789abc..."
  ]
}
GET/v1/tokens/{contract_address}

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl https://<host>/api/v1/tokens/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
  -H "Authorization: Bearer <your_token>"

Example Response

{
  "contract_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  "symbol": "USDC",
  "name": "USD Coin",
  "decimals": 6
}
GET/v1/transactions/{hash}

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl https://<host>/api/v1/transactions/0xabc123def456... \
  -H "Authorization: Bearer <your_token>"

Example Response

{
  "hash": "0xabc123def456...",
  "block_number": 22400001,
  "block_timestamp": "2026-04-30T12:00:12Z",
  "from_address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
  "to_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  "value_native": "0.00 ETH",
  "value_usd": 0.00,
  "gas_used": 65000,
  "gas_price_gwei": 12.5,
  "gas_fee_eth": 0.0008125,
  "gas_fee_usd": 2.44,
  "status": "success",
  "token_transfers": [
    {
      "contract_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
      "token_symbol": "USDC",
      "token_name": "USD Coin",
      "token_standard": "ERC-20",
      "from_address": "0xd8dA6BF...",
      "to_address": "0xRecipient...",
      "amount_display": "250.00 USDC",
      "amount_usd": 250.00,
      "token_id": null
    }
  ],
  "price_source": "uniswap_v3",
  "price_timestamp": "2026-04-30T12:00:12Z"
}
GET/v1/transactions/address/{address}

Responses

StatusDescription
400Bad Request — invalid parameters
500Internal Server Error

Example Request

curl "https://<host>/api/v1/transactions/address/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045?page_size=10" \
  -H "Authorization: Bearer <your_token>"

Example Response

{
  "data": [ /* array of Transaction objects */ ],
  "page": 1,
  "page_size": 10,
  "total_results": 38,
  "total_pages": 4,
  "next_page_url": "https://<host>/api/v1/transactions/address/0xd8dA...?page=2",
  "prev_page_url": null
}