Developers menu
Developers / LAB
Markdown copyLAB: LAB API
LAB from a script, with a lab key: the same conveyor the terminal drives, spending the same credits. Developing an idea is free; a backtest or an optimize pass is one credit, refunded on failure.
This product serves
Plan: LAB. LAB credits: developing an idea is free, a backtest or an optimize pass is one credit, the desk is free once an idea is tested. LIVE includes 5 credits a month. Pricing.
The conveyor. An idea walks one road in order: chat (free) compiles plain words into a rule; POST /api/lab/run with kind: "backtest" (1 credit) moves it from rule to tested; kind: "quant" (1 credit) from tested to ready; POST /api/lab/idea with action: "desk" (free) parks it. A step out of order is refused.
One idea at a time. A run on a second idea while one is mid-test answers 409 with the holder; desk or drop the first.
The verdict. interesting is true only when the rule clears costs out of sample, beats its core-only baseline there, and does it by more than its own error bar (net_rr_t of 2 or more, the error clustered by session). The optimize returns every variant, never a picked winner, with the overfitting it cost (pbo, dsr).
import os, requests
H = {"Authorization": f"Bearer {os.environ['FIRMTAPE_LAB_KEY']}"}
BASE = "https://firmtape.com"
r = requests.post(f"{BASE}/api/lab/chat", headers=H, json={"message": "fade a +3 sigma stretch above vwap on top-decile volume; 15 minute horizon"}).json()
if r["kind"] != "spec":
raise SystemExit(r["say"]) # LAB asked a question
idea = r["idea"]["id"]
bt = requests.post(f"{BASE}/api/lab/run", headers=H, json={"id": idea, "kind": "backtest"}).json()
qo = requests.post(f"{BASE}/api/lab/run", headers=H, json={"id": idea, "kind": "quant"}).json()
requests.post(f"{BASE}/api/lab/idea", headers=H, json={"id": idea, "action": "desk"})
Endpoints
| Request | What it gives | Plan | Key scope |
|---|---|---|---|
| POST /api/lab/chat | Develop or amend an idea | LAB | lab |
| POST /api/lab/run | Backtest or optimize an idea | LAB | lab |
| GET /api/lab/state | Ideas, conveyor and balance | LAB | lab |
| GET /api/lab/thread | An idea's chat thread | LAB | lab |
| POST /api/lab/idea | Desk actions on an idea | LAB | lab |
| GET /api/lab/vocabulary | The LAB vocabulary | Free | none |
| POST /api/struct/run | Test an options structure over the archive | LAB | lab |
| GET /api/struct/job | Poll an options run | LAB | lab |
More
- LAB over MCP: The MCP server's
lab_tools andoptions_strategy_testdrive the same conveyor from an assistant, with alabkey or after signing in through OAuth.
Limits
| What | Limit | Notes |
|---|---|---|
| LAB API | Credits: a backtest or an optimize pass is 1 credit, an OPTIONS archive run 10 | Developing an idea is free but needs a positive balance. One idea holds the conveyor at a time. A failed job refunds its credit. |
Measurements of dealer positioning, never a forecast or a trade call. This page is built from FirmTape's public contract, the same files the OpenAPI document is built from; the tests hold them against the route code. Markdown: /docs/developers/lab.md.