Skip to main content
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" }
      ]
    }
  }
}