Strategy

Get a strategy by id, including its validation state

Reports that the strategy is registered — implied by a 200 at all — and what validating it found.

A 404 means one thing: no such registered strategy for this user. It is never a stale or expired answer; registration and verdict are stored durably, not cached.

get/strategy/{strategyId}

Request

  • Base URL: https://api.qtsurfer.net/v1
  • URL: https://api.qtsurfer.net/v1/strategy/{strategyId}
  • Auth: HTTP bearer

Path parameters

strategyIdstring required

Unique identifier for a compiled strategy, derived from the source itself: the same code always yields the same id, for every caller. How much formatting the id ignores depends on the language — see POST /strategy for exactly which rewrites preserve it and which do not.

Example:6bsh31ikwkuivhtgcoa6s4

The id returned by POST /strategy

Response

Strategy state

strategyIdstring required

Unique identifier for a compiled strategy, derived from the source itself: the same code always yields the same id, for every caller. How much formatting the id ignores depends on the language — see POST /strategy for exactly which rewrites preserve it and which do not.

validation'not_validated' | 'pending' | 'passed' | 'failed' required
  • not_validated — registered, never checked. POST /strategy/{strategyId}/validate checks it.
  • pending — a check was asked for and has not answered yet.
  • passed — the class loaded and survived its first event.
  • failed — it did not; detail says how.
compiledAtstring date-time

When the live compilation was produced.

requiredSourcesstring[]

The market data a strategy needs, read off the compiled class rather than off anything you sent — TickerStrategy, KlineStrategy and FundingRateStrategy each declare one, and a MultiSourceStrategy declares a set.

Absent is not "needs nothing". A strategy always needs market data, so an absent field never means an empty requirement — it means the platform could not establish the answer without constructing your strategy, which it will not do to fill in a field. That happens for a MultiSourceStrategy, for a class that overrides getMarketDataSource(), and for anything registered before this field existed; re-registering the source fills it in.

validatedAtstring date-time

When the verdict was recorded. Absent until there is one.

detailstring

Why validation failed, or why a queued check has not reported. Present on failed, and alongside validationStalled.

noticesTruncatedinteger

How many notices were dropped past the cap. Absent when none were.

dryRunIncompleteboolean

The check did not finish its budget — it ran out of time, was refused because the platform was already holding too many unfinishable runs, or hit a failure attributable to the synthetic instrument rather than to your strategy. The verdict stands as far as it went; it simply reached less than a full run would.

validationStalledboolean

A queued check has not reported for far longer than one takes. Nothing is disproved about the strategy — the check has not run. Stop waiting and re-request it later.

Example response

{
  "strategyId": "6bsh31ikwkuivhtgcoa6s4",
  "validation": "passed",
  "compiledAt": "2026-08-04T16:23:04Z",
  "requiredSources": [
    "Ticker"
  ],
  "validatedAt": "2026-08-04T16:24:11Z",
  "notices": [
    {
      "level": "WARN",
      "code": "indicator.bar-data-on-ticker-path",
      "message": "Indicator requires bar data but is on the ticker path",
      "provenance": "compile-dry-run"
    }
  ],
  "_links": {
    "code": {
      "href": "/v1/strategy/6bsh31ikwkuivhtgcoa6s4/code"
    }
  }
}

Changes

No operation changes recorded.