Developers/Nexus Trades API (paper trading, Beta)

Test orders

Rehearse your bot against the live market and your real accounts without placing anything.

Add "test": true to an open, an exit, a close or a cancel. The order is checked and priced exactly like the real one, at that moment: same request checks, same market hours, same live price, same size limits, same buying power, same account and rules. Then it isn't placed.

You get back what a real order returns, with "test": true on it and meta.test: true. If the real order would've been refused, the test is refused with the same status and the same code. So a test order answers one question: would this have worked right now, and at what price?

GET /api/nexus/v1/trading/capabilities says "testOrders": true when test orders are on.

What it never touches

A test order is never a trade and never an order on an account. It doesn't move your paper wallet, a futures balance or a position. It doesn't reach an evaluation's rules. It doesn't show up in your stats, your rank, the feed, your journal, notifications, Discord or copy trading. It's one line in your test log, and that's the only place it exists.

(One small exception: if you've never opened your futures practice account, a test order that names it sets up the empty account for you. No balance moves and nothing trades.)

The test log

Your test log keeps your 10 newest test orders. When the 11th comes in, the oldest drops off.

Terminal
# Read the log, newest first
curl -s "https://app.skylit.ai/api/nexus/v1/trades?test=true" \
  -H "Authorization: Bearer $SKYLIT_API_KEY"
JSON
{
  "data": [
    {
      "id": "9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d",
      "assetClass": "futures",
      "source": "api",
      "account": { "id": "0b6f3c1e-8a52-4d0e-9c1a-2f4f6f1f7a10", "kind": "practice", "name": "Paper" },
      "symbol": "NQZ26",
      "side": "buy",
      "quantity": 1,
      "role": "entry",
      "orderType": "market",
      "status": "filled",
      "fillPrice": 25311.5,
      "placedAt": "2026-10-09T14:33:02Z",
      "filledAt": "2026-10-09T14:33:02Z",
      "test": true
    }
  ],
  "meta": { "limit": 50, "maxRows": 10, "offset": 0, "test": true, "total": 1 }
}

"status": "filled" on a test order means "this would have filled at this price". Nothing was booked.

  • status, limit and offset work as they do on the normal list. A futures test order is neither open nor closed, so it only shows under status=all (the default).
  • GET /api/nexus/v1/trades/{id} reads one test order by its id.
  • ?test= must be true or false. Anything else answers 400 bad_request.

Rehearse open, trim, close (options and stocks)

An options or stock test trade stays open in the log until you exit it, so your bot can run its whole routine:

Terminal
# 1. Test open
curl -s -X POST "https://app.skylit.ai/api/nexus/v1/trades" \
  -H "Authorization: Bearer $SKYLIT_API_KEY" -H "Content-Type: application/json" \
  -d '{"contract":"SPY 600C 10/16","quantity":2,"test":true,"clientOrderId":"t-open-1"}'
# Returns a trade with "test": true. Say its id is TEST_ID.

# 2. Test trim. The id is a test order, so this exit is a test. No "test" field needed.
curl -s -X POST "https://app.skylit.ai/api/nexus/v1/trades/TEST_ID/exits" \
  -H "Authorization: Bearer $SKYLIT_API_KEY" -H "Content-Type: application/json" \
  -d '{"quantity":1,"clientOrderId":"t-trim-1"}'

# 3. Test close
curl -s -X POST "https://app.skylit.ai/api/nexus/v1/trades/TEST_ID/exits" \
  -H "Authorization: Bearer $SKYLIT_API_KEY" -H "Content-Type: application/json" \
  -d '{"closeAll":true,"clientOrderId":"t-close-1"}'

Rehearse futures

Terminal
# A test order into the evaluation
curl -s -X POST "https://app.skylit.ai/api/nexus/v1/trades" \
  -H "Authorization: Bearer $SKYLIT_API_KEY" -H "Content-Type: application/json" \
  -d '{"assetClass":"futures","ticker":"NQ","side":"buy","quantity":1,"account":"evaluation","test":true}'

# A test close. It previews closing what the account REALLY holds right now.
curl -s -X POST "https://app.skylit.ai/api/nexus/v1/trading/accounts/evaluation/close" \
  -H "Authorization: Bearer $SKYLIT_API_KEY" -H "Content-Type: application/json" \
  -d '{"ticker":"NQ","test":true}'

A test close answers in the close's own shape, with "test": true on the response and on each order in closed. Nothing is closed and no resting order is cancelled.

Test orders on the resting-order routes

"test": true works on a futures limit order, a stop order and a bracket. The order gets the same checks as a real one, then it's kept in your test log as working, with its bracket. Nothing ever fills a test order, so it stays that way.

  • Read it: GET .../orders/{orderId} with a test order's id answers with the test order, marked "test": true.
  • Cancel it: POST .../orders/{orderId}/cancel with a test order's id cancels it in the test log. You don't need to send test. The id says it's a test.
  • Cancel them all: POST .../orders/cancel with "test": true cancels your test orders for that account and nothing else.
  • You can't move it. POST .../orders/{orderId}/modify on a test order answers 400 test_modify_unavailable. Cancel it and send a new test order at the new price.
  • "test": true never touches a real order. Aim it at a real order's id and you get 404 order_not_found.

Its limits

Know these before you trust a green test run:

  1. Tests are checked against your real positions and buying power, not against each other. Each one is a dry run on the account as it really is.
  2. Options and stocks: one open test position per contract. While a test trade is open in the log, a second test open on the same contract answers 409 duplicate_position, like a real one would. You also get it if you really hold that contract.
  3. Futures test orders don't net. A test sell after a test buy is checked as if the buy never happened. A test close previews closing what you really hold. There's no futures test P/L.
  4. A test on an evaluation or funded account can't run the rule judgment. A real order that opens exposure there first judges the account's loss rules at the latest price. A test sees the account as it was last judged, and the response says so: meta.notChecked contains "account_rules_judgment". Everything else is checked: the contract, the session, the live price, the size cap, the account's status, your own risk rules.
  5. A test market order with a bracket, on an account that already holds that contract, has meta.notChecked: ["bracket_netting"]. A real fill would fold the new stop and target into the ones the position already has. The test shows them as you sent them.
  6. The cap of 50 open API positions applies to test opens too. It counts your real open API trades.
  7. A test closeAll uses one log row per position. An account holding 4 contracts uses 4 of your 10 rows.
  8. Test ids don't last as long. A test clientOrderId is remembered only while its test order is still in your 10, and 24 hours at most. Test ids never block or replay a real order with the same id.
  9. A test proves "right now". The price and your account can change a second later. A test passing doesn't promise the real one will.

Last updated

Was this page helpful?