LAB API

Run your ideas from a script instead of the terminal. Same conveyor, same credits — a labk_ token stands in for your account.

The API is the exact machinery behind the LAB tab: you describe an idea, backtest it, optimize it, and read the honest verdict — over HTTP. Base URL https://gex.live; every body and response is JSON.

Create a token About LAB

Authentication

Create a token on your account page (the LAB & API section). It is shown once; store it like a password. Send it as a Bearer token on every request:

Authorization: Bearer labk_your_token_here

A token is your account for LAB: jobs run over it spend your credit balance, whether they came from the browser or a script. It is scoped to LAB only — it cannot open the paid live stream — so a leaked token cannot cost you a subscription. Revoke it any time from the account page. No CSRF token or cookie is needed for Bearer requests.

Credits

  • Developing an idea is free/api/lab/chat spends nothing, but it requires a positive balance (each message is an LLM call on our side).
  • Each job costs one credit — a backtest or an optimize pass. A failed job refunds its credit automatically.
  • Out of credits → 402 {"error":"no credits","buy":"lab"}. Buy more on the LAB page.

The conveyor

An idea is not tested with a single call — it is walked down a conveyor, and each step is a separate /api/lab/run that must come in order:

  chat  ─▶  BACKTEST  ─▶  QUANT OPTIMIZE  ─▶  ADD TO DESK
 (free)     1 credit        1 credit          free
  rule       tested          ready             desk

Backtest, then optimize — not one or the other. The backtest checks the rule as you wrote it against an honest baseline. The optimize ("quant") then varies every filter and shows whether any variant does better out of sample. You run the backtest first (it moves the idea rule → tested); only a tested idea can be optimized (tested → ready); only a ready idea can go to the desk. Calling a step out of order is refused.

One idea occupies the conveyor at a time. A run against a second idea while one is mid-test returns 409 {"holder":"i_..."} — finish it (to the desk) or drop the first.

Quickstart (Python)

Describe the idea, then walk it: backtest → optimize → desk.

import os, requests

TOKEN = os.environ["GEX_LAB_TOKEN"]          # labk_...
H = {"Authorization": f"Bearer {TOKEN}"}
BASE = "https://gex.live"

def show(result):
    for leg in result["legs"]:
        v = leg["verdict"]
        print(" ", leg["title"], "->", "PASS" if v["interesting"] else "fail")

# 1. chat (free): describe the idea; LAB compiles it into a rule.
r = requests.post(f"{BASE}/api/lab/chat", headers=H, json={
    "message": "fade a +3 sigma stretch above vwap when a 5-point candle "
               "prints on top-decile volume; 15 minute horizon",
}).json()
if r["kind"] != "spec":
    raise SystemExit(f"not compilable yet: {r['say']}")   # LAB asked a question
idea = r["idea"]["id"]
print("compiled:", r["idea"]["name"])

# 2. BACKTEST (1 credit): the rule as written, against its honest baseline.
bt = requests.post(f"{BASE}/api/lab/run", headers=H,
                   json={"id": idea, "kind": "backtest"}).json()
print("backtest:"); show(bt["result"])

# 3. QUANT OPTIMIZE (1 credit): vary every filter. Do this AFTER the backtest.
qo = requests.post(f"{BASE}/api/lab/run", headers=H,
                   json={"id": idea, "kind": "quant"}).json()
print("optimize:", qo["result"]["variants_tried"], "variants tried")

# 4. ADD TO DESK (free): park the tested idea; frees the conveyor for the next one.
requests.post(f"{BASE}/api/lab/idea", headers=H,
              json={"id": idea, "action": "desk"})

Endpoints

POST /api/lab/chat

Compile a plain-words idea into a rule, or amend an existing one. Free, needs a positive balance.

{ "message": "fade a +3 sigma stretch ...", "id": "i_xxx (optional, to amend)" }

Returns one of:

{ "kind": "spec", "idea": { "id": "i_...", "name": "...", "spec": {...} }, "say": "..." }
{ "kind": "chat", "say": "which threshold do you mean?" }     // needs clarifying
{ "kind": "error", "say": "...", "errors": [ ... ] }          // could not compile

Any chat on an idea resets it to the start of the conveyor (a re-test is owed).

POST /api/lab/run

Run the idea's current conveyor step. Spends one credit; refunded on failure. kind is not a menu — it is the step you are performing, and it must match the idea's stage:

{ "id": "i_...", "kind": "backtest" }   // stage rule -> tested   (do this FIRST)
{ "id": "i_...", "kind": "quant" }      // stage tested -> ready  (then this)
{ "idea": { ... }, "result": { ...engine output... }, "state": { ...balance, ideas... } }

The result is the engine's verdict — per leg: an era table (all / this year / holdout), each with the full rule vs its core-only baseline, and a verdict (interesting is true only when the rule clears cost out-of-sample AND beats its baseline there). The optimize adds every variant, never a winner.

GET /api/lab/state

Everything in one call: your ideas, the conveyor holder, and your balance.

{ "ideas": [ { "id": "i_...", "name": "...", "stage": "desk", "spec": {...}, "results": {...} } ],
  "conveyor": "i_... | null",
  "balance": { "monthly": 0, "purchased": 100, "total": 100 } }

GET /api/lab/thread?id=i_...

The chat thread for one idea.

POST /api/lab/idea

Desk actions on an idea you own.

{ "id": "i_...", "action": "desk" }     // ready -> on the desk, frees the conveyor
{ "id": "i_...", "action": "drop" }     // return to the start, free the conveyor
{ "id": "i_...", "action": "delete" }
{ "id": "i_...", "action": "set", "on": true, "draw": "rails", "alert": "sound" }

curl

# compile an idea
curl -s https://gex.live/api/lab/chat \
  -H "Authorization: Bearer $GEX_LAB_TOKEN" \
  -H "content-type: application/json" \
  -d '{"message":"fade a +3 sigma stretch above vwap on top-decile volume"}'

# run a backtest, then optimize the same idea
curl -s https://gex.live/api/lab/run -H "Authorization: Bearer $GEX_LAB_TOKEN" \
  -H "content-type: application/json" -d '{"id":"i_xxx","kind":"backtest"}'
curl -s https://gex.live/api/lab/run -H "Authorization: Bearer $GEX_LAB_TOKEN" \
  -H "content-type: application/json" -d '{"id":"i_xxx","kind":"quant"}'

Errors

401missing, unknown, or revoked token
402no credits — {"buy":"lab"}
404no such idea (or not yours)
409another idea is on the conveyor — {"holder":"i_..."}
422the engine rejected the rule (refunded)
502the engine failed (refunded) — retry

Not investment advice. Options trading carries substantial risk of loss. Backtested performance does not guarantee future results.