Skip to main content

Create Backtest Job

Submit a new backtest job. Returns the freshly created job object with status queued; the backtest runs asynchronously.

Endpoint

POST /v1/backtest/jobs

Weight: 20

Authentication: Required (signed)

Request body

NameTypeMandatoryDescription
template_idstringYesIdentifier of the strategy template (e.g. tpl_grid). See the Strategies overview for the catalog.
paramsobjectYesTemplate-specific parameters. Schema is opaque to the backtest service and validated by the template.
symbolsarray<string>YesUppercase exchange-style symbols (e.g. ["BTCUSDT"]). Multi-symbol backtests are supported by templates that opt-in.
timeframeenumYesBar interval. One of 1m, 5m, 15m, 1h, 4h, 1d.
startstring (ISO 8601 UTC)YesInclusive lower bound of the simulation window.
endstring (ISO 8601 UTC)YesInclusive upper bound. Must be > start; total span ≤ 5 years.
capitalstring (decimal)YesStarting account equity in quote currency. Quoted to preserve precision.
leverageintegerNoMaximum leverage applied to positions. Default 1.
fee_modelenumNoOne of none, fixed_bps, tiered_maker_taker, match_exchange. Default fixed_bps. See Overview → Fee model.
fee_bpsstring (decimal)NoPer-fill fee in basis points. Only honored when fee_model = "fixed_bps". Default "5".
strategy_idstringNoIf set, the corresponding strategy's stored config is loaded as a base; any of the fields above that are also passed in the request override the strategy's values. Useful for re-running an existing strategy over a custom window.

Response

{
"id": "bt_3c91ef",
"status": "queued",
"config": {
"template_id": "tpl_grid",
"params": {
"grid_levels": 8,
"upper_price": "72000",
"lower_price": "60000"
},
"symbols": ["BTCUSDT"],
"timeframe": "1h",
"start": "2025-01-01T00:00:00Z",
"end": "2025-12-31T23:59:59Z",
"capital": "10000.00",
"leverage": 1,
"fee_model": "fixed_bps",
"fee_bps": "5"
},
"submitted_at": "2026-04-29T10:15:00Z",
"started_at": null,
"finished_at": null,
"progress": 0,
"result": null,
"error": null
}

Response fields

FieldTypeDescription
idstringJob identifier of the form bt_<6-8 hex>.
statusenumOne of queued, running, done, failed, cancelled. New jobs return queued.
configobjectEchoes the resolved configuration the backtest will run with. If strategy_id was supplied, this reflects the merged config.
submitted_atstring (ISO 8601)Server-side acceptance timestamp.
started_atstring (ISO 8601) | nullSet when the job leaves the queue. null while queued.
finished_atstring (ISO 8601) | nullSet when the job reaches a terminal state.
progressnumberFractional progress in [0, 1]. 0 for newly queued jobs.
resultobject | nullnull until status is done; see Get Result.
errorobject | nullnull unless status is failed; contains { "code", "message" }.

Errors

HTTPCodeCause
400INVALID_PARAMETERMissing field, unknown template_id, invalid date range (e.g. end <= start, span > 5 years, end in the future), unsupported timeframe, or non-numeric capital.
409INVALID_STATEstrategy_id references a deleted or otherwise unusable strategy.
429RATE_LIMITEDThe user already has 5 jobs in queued or running state. Wait for one to finish or cancel one first.

See Errors for shared error semantics.

Example

curl -X POST https://api.pipai.example/v1/backtest/jobs \
-H "X-PipAI-API-Key: $API_KEY" \
-H "X-PipAI-Timestamp: $TS" \
-H "X-PipAI-Signature: $SIG" \
-H "Content-Type: application/json" \
-d '{
"template_id": "tpl_grid",
"params": {
"grid_levels": 8,
"upper_price": "72000",
"lower_price": "60000"
},
"symbols": ["BTCUSDT"],
"timeframe": "1h",
"start": "2025-01-01T00:00:00Z",
"end": "2025-12-31T23:59:59Z",
"capital": "10000.00",
"leverage": 1,
"fee_model": "fixed_bps",
"fee_bps": "5"
}'