Strategy specs are immutable, versioned records. Once a spec is persisted, it cannot be mutated — a new version is created instead. This guarantees that a backtest run always references an exact, reproducible input.
List strategies
GET /api/strategies
Authorization: Bearer <token>
Returns all strategy specs for the tenant, with their latest version.
Response
{
"strategies": [
{
"id": "spec_xyz",
"version": 3,
"tenant_id": "tnt_abc",
"name": "Semis momentum 60/20",
"spec_version": "1.0",
"created_at": "2025-01-15T12:00:00Z"
}
]
}
Propose a strategy
POST /api/strategies
Authorization: Bearer <token>
Content-Type: application/json
The body is a full StrategySpec. See StrategySpec for the schema.
{
"spec_version": "1.0",
"name": "Semis momentum 60/20",
"universe": { "symbols": ["NVDA", "AMD"], "source": "polygon" },
"strategy": { "id": "momentum", "params": { "lookback": 60 } },
"construction": { "scheme": "equal_weight", "long_only": true, "gross": 1.0 },
"risk": { "max_gross": 1.05, "max_net": 1.0, "max_name_pct": 0.25 },
"execution": { "cost_bps": 5.0, "algo": "twap", "rebalance": "weekly" },
"resources": { "tier": "prod" },
"seed": 42
}
Proposing a strategy requires the strategy:author scope. Without it the request is rejected with 403.
Server-stamped fields
The server assigns id, version, and tenant_id. If the request body includes any of these, they are silently ignored. See StrategySpec.
Response
{
"id": "spec_xyz",
"version": 1,
"tenant_id": "tnt_abc",
"name": "Semis momentum 60/20",
"spec_version": "1.0",
"created_at": "2025-01-15T12:00:00Z"
}
Immutability
A strategy spec is write-once. To “edit” a spec, you propose it again with the same name; the server creates a new row with an incremented version. Backtest runs pin a specific spec_id + spec_version, so they always reference the exact spec they were run against.
This means you can safely re-run an old backtest months later and get the same result — the spec it references hasn’t changed.
Validation errors
If the spec fails schema validation, the response is 422 with field-level details:
{
"error": {
"code": "validation_error",
"message": "schema validation failed",
"details": {
"fields": [
{ "path": "strategy.params.fast", "issue": "required for ma_cross" }
]
}
}
}