# Backtest or optimize an idea

> Run the idea's current conveyor step: backtest first (rule to tested), then quant (tested to ready). One credit, refunded on failure.

Source: https://firmtape.com/docs/developers/lab/run

Run the idea's current conveyor step: `backtest` first (rule to tested), then `quant` (tested to ready). One credit, refunded on failure.

`POST /api/lab/run`

Plan LAB · Key scope lab · Limit 1 credit a run · Version 1.0.0 · Since 2026-08-12

**This endpoint serves:** [LAB: LAB from a script](https://firmtape.com/docs/lab#lab-api), [LAB: The LAB desk and the backtest](https://firmtape.com/docs/lab#backtester), [LAB: Quant optimize](https://firmtape.com/docs/lab#quant-optimize). **Plan:** [LAB](https://firmtape.com/features/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.

## Body

| Field | Meaning | Unit |
| --- | --- | --- |
| `id` (string) | Compiled LAB idea id |  |
| `kind` (backtest \| quant) | Run backtest first, then quant optimization |  |

## Response

`{ idea, result, state }`: the engine's verdict per leg and the balance after.

| Field | Meaning | Unit |
| --- | --- | --- |
| `idea` (object) | The idea after the step. |  |
| `result` (object) | Per leg: era tables (all, this year, holdout), the full rule against its baseline, and `verdict`. |  |
| `state` (object) | Balance and ideas. |  |

## Errors

| Status | Code | What to do |
| --- | --- | --- |
| 400 |  | A parameter is wrong. |
| 401 |  | No key, or an unknown or revoked one. Send a `lab` key. |
| 402 |  | No credits. Buy credits on the LAB page. |
| 404 |  | No such idea or job. Check the id. |
| 409 |  | Another idea holds the conveyor, or a step came out of order. Finish or drop the holder; run the steps in order. |
| 422 |  | The rule could not be compiled or was refused (refunded). Change the rule. |
| 502 |  | The engine failed (refunded); retry. Retry. |

## Request

```sh
curl -X POST \
  -H "Authorization: Bearer $FIRMTAPE_LAB_KEY" \
  "https://firmtape.com/api/lab/run"
```

```python
import os, requests

H = {"Authorization": f"Bearer {os.environ['FIRMTAPE_LAB_KEY']}"}
r = requests.post("https://firmtape.com/api/lab/run", headers=H)
print(r.status_code, r.text[:500])
```

```js
const r = await fetch("https://firmtape.com/api/lab/run", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.FIRMTAPE_LAB_KEY}` },
});
console.log(r.status, await r.text());
```

## Changes

- 2026-08-12: Added.
