REST API
The Tektii platform is backed by a versioned REST API at https://api.tektii.com. The CLI and MCP server are the recommended way to drive it, but the /v1 REST surface is a first-class contract you can call directly — handy for tight polling loops (e.g. waiting on a scenario to finish) or wiring Tektii into your own tooling.
The endpoints listed on this page under Supported endpoints are the public, supported subset of /v1. Anything else you may notice under /v1 serves the web app, is unsupported, and may change without notice.
Base URL
All requests go to the versioned /v1 prefix on the production host:
https://api.tektii.com/v1
For example, fetching a scenario:
GET https://api.tektii.com/v1/scenarios/{scenario_id}
Authentication
Authenticated endpoints require your API key in the X-API-Key request header:
curl https://api.tektii.com/v1/strategies \ -H "X-API-Key: your-api-key"
The same key the CLI uses (TEKTII_API_KEY) works here — see CLI Authentication for how the CLI reads it.
Getting an API key
API keys are minted in the web app:
- Log in to your Tektii account
- Go to Developers → API Keys
- Click Create New Key and copy it — it is shown only once
The key-management endpoints (/v1/api-keys) are authenticated with your web-app browser session (a JWT), not with an API key — so keys can only be created, listed, or revoked from the web app, not programmatically with an API key. This is by design: an API key cannot mint or revoke other keys.
Only the read-only reference endpoints are public and need no key: the instruments catalog (GET /v1/instruments and its sub-paths) and GET /v1/templates. Every other endpoint requires the X-API-Key header.
Supported endpoints
These are the public, supported endpoints. Path parameters are shown in {braces}.
Strategies
| Method | Path | Purpose |
|---|---|---|
GET | /v1/strategies | List your strategies |
POST | /v1/strategies | Create a strategy |
GET | /v1/strategies/{strategy_id} | Get one strategy |
PUT | /v1/strategies/{strategy_id} | Update a strategy |
DELETE | /v1/strategies/{strategy_id} | Delete a strategy |
PUT | /v1/strategies/{strategy_id}/auto-run-configs | Set the configurations auto-run on new versions |
Strategy versions
| Method | Path | Purpose |
|---|---|---|
GET | /v1/strategies/{strategy_id}/versions | List versions of a strategy |
POST | /v1/strategies/{strategy_id}/versions | Create a new version |
GET | /v1/strategies/{strategy_id}/versions/{version_id} | Get one version |
PATCH | /v1/strategies/{strategy_id}/versions/{version_id} | Update version metadata |
DELETE | /v1/strategies/{strategy_id}/versions/{version_id}/image | Evict a version's container image |
Versions are immutable once created — an evicted image is gone for good; upload a new version rather than expecting to restore one.
Scenarios
A scenario is one backtest run of a strategy version against a configuration.
| Method | Path | Purpose |
|---|---|---|
GET | /v1/scenarios/{scenario_id} | Get a scenario by ID (not scoped to a strategy) |
GET | /v1/strategies/{strategy_id}/scenarios | List a strategy's scenarios |
POST | /v1/strategies/{strategy_id}/scenarios | Create and queue a scenario |
POST | /v1/strategies/{strategy_id}/scenarios/batch | Create several scenarios in one call |
POST | /v1/strategies/{strategy_id}/scenarios/from-configs | Create scenarios from saved configurations |
GET | /v1/strategies/{strategy_id}/scenarios/{scenario_id} | Get a scenario (strategy-scoped) |
DELETE | /v1/strategies/{strategy_id}/scenarios/{scenario_id} | Delete a scenario |
POST | /v1/strategies/{strategy_id}/scenarios/{scenario_id}/cancel | Cancel a running scenario |
GET | /v1/strategies/{strategy_id}/scenarios/{scenario_id}/metadata | Scenario metadata |
GET | /v1/strategies/{strategy_id}/scenarios/{scenario_id}/metrics | Performance metrics |
GET | /v1/strategies/{strategy_id}/scenarios/{scenario_id}/trades | Executed trades |
GET | /v1/strategies/{strategy_id}/scenarios/{scenario_id}/timeseries | Equity / P&L time series |
POST | /v1/scenarios/compare | Compare metrics across scenarios |
The lightweight GET /v1/scenarios/{scenario_id} is the endpoint to poll while a backtest runs. Watch the response's state field: keep polling while it is QUEUED, PENDING, or RUNNING, and stop once it reaches a terminal state — COMPLETE, FAILED, or CANCELLED. When a run ends FAILED, the errorType field tells you where the fault lies: strategy means your strategy code raised the error (fix and re-run), platform means an infrastructure fault (safe to retry).
Scenario configurations
Reusable configuration objects (instrument, date window, costs, etc.) you can attach to scenarios.
| Method | Path | Purpose |
|---|---|---|
GET | /v1/configurations | List configurations |
POST | /v1/configurations | Create a configuration |
GET | /v1/configurations/{config_id} | Get one configuration |
PUT | /v1/configurations/{config_id} | Update a configuration |
DELETE | /v1/configurations/{config_id} | Delete a configuration |
POST | /v1/configurations/{config_id}/clone | Clone a configuration |
See Scenario Configuration for the config body schema.
Reference (read-only)
| Method | Path | Purpose |
|---|---|---|
GET | /v1/instruments | List available instruments (public, no key) |
GET | /v1/instruments/markets | List markets |
GET | /v1/instruments/search | Search instruments |
GET | /v1/instruments/{symbol} | Get one instrument |
GET | /v1/templates | List strategy starter templates |
See Available Instruments for the instrument response schema and symbol formats.
Errors
Every error response uses the same envelope — an error object with a machine-readable code, a human message, and optional details:
{
"error": {
"code": "NOT_FOUND",
"message": "scenario not found",
"details": null
}
}
details is an optional string (present only for a few codes, e.g. a serialized report); it is omitted when there's nothing to add. Branch on code, never on message — messages may be reworded, codes are stable.
Stable error codes
code | HTTP status | Meaning |
|---|---|---|
BAD_REQUEST | 400 | Malformed request, invalid field, or bad ID format |
UNAUTHORIZED | 401 | API key missing or invalid |
FORBIDDEN | 403 | Authenticated, but the resource belongs to another account |
NOT_FOUND | 404 | No resource with the given ID |
CONFLICT | 409 | State conflict (e.g. the resource is not in a modifiable state) |
IMAGE_EVICTED | 410 | The strategy version's container image has been evicted from the registry, so the run can never succeed — upload a new version |
SERVICE_UNAVAILABLE | 503 | Transient backend unavailability — safe to retry with backoff |
INTERNAL_ERROR | 500 | Unexpected server-side failure |
SERVICE_UNAVAILABLE is the only retryable code here — retry with exponential backoff. Everything else is terminal; surface it to the caller.
Stability
The /v1 surface is a committed contract, with a deliberately modest guarantee:
- Additive. New fields and new endpoints may appear within
/v1without a version bump — write clients that ignore unknown fields. - Breaking changes ship under a new version path. A backwards-incompatible change lands under a new prefix (e.g.
/v2), never as a silent change to/v1. - The published OpenAPI spec is the contract.
GET /v1/openapi.jsonpublishes the exact/v1shape as a machine-readable OpenAPI 3.1 document —openapi.jsonis the source of truth, not this page. - No formal deprecation-window SLA yet. We don't publish a guaranteed deprecation timeline. Treat the additive rule as the promise; watch release notes for anything larger.
The endpoint tables on this page track the supported surface.
Related
- CLI Overview — the recommended, higher-level way to drive the platform
- CLI Authentication — how the CLI reads your API key
- Available Instruments — the public instruments endpoint
- Scenario Configuration — the configuration body schema