Documentation

Strategy Storage API

Full reference for the Strategy Storage API — endpoints, request schema, response schema, and error codes.

Overview

The Strategy Storage API stores a Strategy DSL object as a first-class, standalone asset — independent of any one backtest or live subscription. Save a strategy once to get a stable id, then reference that id (or just pass its definition straight through) when submitting to the Backtesting API or the Live Execution API.

Base URL: https://strategy.emidlabs.com/api/public/v1

All /strategies requests require the x-api-key header with a valid API key scoped for the strategy service. Keys are generated in the Console.
💡
This service is pure storage — it never runs a strategy, and it never interprets the DSL beyond checking it's well-formed JSON. What riskManagement/entryFeePct actually do depends entirely on where you submit the strategy afterward, not on this API.

#POST /strategies — Save

POST/strategies

Save a new strategy.

Request body

FieldTypeRequiredDescription
namestringYesHuman-readable name for this strategy.
descriptionstringNoFree-text notes about this strategy.
definitionstringYesThe Strategy DSL object, serialized as a JSON string — see the Strategy System page for the full shape.
tagsarray of stringNoFreeform labels for filtering later via GET /strategies.

Response

FieldTypeDescription
idstring (UUID)Unique identifier for the strategy.
namestringEchoes the request.
statusstring"Active" immediately after creation.
createdAtUtcstringTimestamp of creation in UTC.

#GET /strategies/:id — Fetch

GET/strategies/{id}

Fetch a saved strategy by id, including its full definition.

Response

FieldTypeDescription
idstring (UUID)Unique identifier for the strategy.
namestring
descriptionstring | null
definitionstringThe Strategy DSL object, serialized as a JSON string.
tagsarray of string
statusstring"Active" or "Archived".
createdAtUtcstring
updatedAtUtcstring

#GET /strategies — List

GET/strategies

List strategies for this account, paginated.

Query parameters

ParameterTypeDefaultDescription
pagenumber11-indexed page number.
pageSizenumber20Items per page. Clamped to the 1–100 range.
tagstring(none)Exact-match filter — only strategies carrying this tag.
statusstring"Active""Active" or "Archived". Defaults to Active-only when omitted.
💡
Omitting status returns Active strategies only — pass status=Archivedexplicitly to see ones you've archived.

Response

FieldTypeDescription
itemsarrayOne entry per strategy on this page — same shape as GET /strategies/:id.
totalCountnumberTotal strategies matching the filter, across all pages.
page / pageSize / totalPagesnumberStandard pagination fields.

#PUT /strategies/:id — Update

PUT/strategies/{id}

Update a saved strategy's fields. Overwrites in place — there is no version history.

Request body

All fields optional — present means "change this", absent means "leave it as-is". Sending tags replaces the tag list entirely, it does not merge with the existing one.

FieldTypeRequiredDescription
namestringNoNew name.
descriptionstringNoNew description.
definitionstringNoNew Strategy DSL object, serialized as a JSON string.
tagsarray of stringNoNew tag list — replaces the existing one.

Response

Same shape as GET /strategies/:id, reflecting the fields you changed.

#DELETE /strategies/:id — Archive

DELETE/strategies/{id}

Archives a strategy — soft-delete, never a hard delete.

An archived strategy still exists and is still fetchable via GET /strategies/:id— it's just excluded from GET /strategies's default listing. There is no endpoint to permanently delete a strategy or to un-archive one.

Response

FieldTypeDescription
idstring (UUID)
statusstring"Archived".

#GET /dsl-core-reference

GET/dsl-core-reference

The genuinely-shared slice of the Strategy DSL reference, as plain text/markdown.

Unauthenticated — no x-api-key needed, same treatment as /health. Covers the inputs/conditions/scoresection (built-in functions, candlestick catalog, expression syntax) — the part of the DSL that means the exact same thing no matter where a strategy ends up running. Consumed at runtime by all three MCP servers' strategy-dsl-spec resource instead of each hand-copying it. Not meant to be called directly for normal use — it exists so configuration/decision/riskManagement, which mean different things depending on the target, can stay documented locally by whichever server actually implements that behavior.

#Error Codes

Every error response has the same shape: { "error": "<code>", "message": "<text>" }.

StatusCodeDescription
400invalid_payloadThe request body is malformed, missing required fields, or the definition fails structural validation — check the message field for specifics.
401api_key_missingThe x-api-key header wasn't provided.
401api_key_invalidThe provided API key is invalid, revoked, or inactive.
403service_not_enabledThe API key is valid but not scoped for the strategy service.
429rate_limit_exceededToo many requests for this account. Back off and retry.
500execution_failedServer-side error.