# Stratex API Reference

API base path: `/api/v1`. For AI agents and integration guides, see **[Agent Skill](/docs/agent-skill.md)** and **[Quickstart](/docs/quickstart.md)**.

---

## Authentication

Use an **API key** for all authenticated endpoints.

| Header | Example |
|--------|--------|
| **Authorization** (preferred) | `Authorization: Bearer sk_live_xxxxxxxx...` |
| **X-Api-Key** | `X-Api-Key: sk_live_xxxxxxxx...` |

Create and manage keys in the **Account Dashboard** after signup (API & Account → API Keys). The raw key is shown only once at creation; store it securely.

**Endpoints that do not require auth:** `GET /api/v1/agent-info`.

---

## Endpoints

### Discovery

| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/api/v1/agent-info` | None | Capabilities, pricing summary, doc URLs, `marketsUrl`. Does **not** include the markets payload. |
| GET | `/api/v1/markets` | API key or session | Ready backtest markets: `market` key, human `label` (from admin roster when set), overall `earliest`/`latest`, and `timeframes[]` with per-TF ranges. Count = ingested catalog data, not a fixed placeholder. |

---

### Setups

| Method | Path | Auth | Description |
|--------|------|------|-------------|
| POST | `/api/v1/service/setups` | API key or session | Create setup (structured body). Optional: `webhookUrl`, `webhookSecret`. |
| GET | `/api/v1/service/setups` | API key or session | List your setups. |
| GET | `/api/v1/service/setups/:id` | API key or session | Get one setup. |
| PATCH | `/api/v1/service/setups/:id` | API key or session | **Webhook only:** JSON body may include only `webhookUrl` and/or `webhookSecret` (empty string or null clears). Other setup changes require creating a new setup. |
| DELETE | `/api/v1/service/setups/:id` | API key or session | Delete a setup. |

**Create body (minimal):**

```json
{
  "name": "My GOLD BUY setup",
  "symbol": "GOLD",
  "direction": "BUY",
  "timeframe": "5m"
}
```

Optional: `webhookUrl`, `webhookSecret`, `entry` / `exit` (or `entryExpression` / `exitExpression`), `briefDescription`, `description`.

**Create response:** `setupId`, `description` (plain-English), and full setup object. On validation failure you receive a generic error (e.g. "Setup validation failed"); internal details are not exposed.

---

### Backtesting

| Method | Path | Auth | Description |
|--------|------|------|-------------|
| POST | `/api/v1/backtest/run` | API key or session | Run a backtest. |
| GET | `/api/v1/backtest/estimate` | API key or session | Preview resolved range + bar cost before running. |
| GET | `/api/v1/backtest/markets` | API key or session | Same ready-market list as `GET /api/v1/markets` (UI helper). |
| GET | `/api/v1/backtest/list` | API key or session | List your backtest runs. |
| GET | `/api/v1/backtest/:id` | API key or session | Get one run (full trades, summary). |
| GET | `/api/v1/backtest/:id/trades` | API key or session | Get trades for a run. |
| DELETE | `/api/v1/backtest/:id` | API key or session | Delete a run. |

**Run body:**

The window can be expressed two ways. **Recommended for agents: `endDate` + `lookbackBars`** — you specify how many bars back from the end you want on the setup's timeframe and the server resolves the start date for you. The classic `startDate` + `endDate` range still works.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| setupId | string | Yes | Setup ID from POST /api/v1/service/setups. |
| symbol | string | Yes | e.g. GOLD, SP500. |
| timeframe | string | Yes | One of: 1m, 5m, 15m, 30m, 1h, 4h, D1, W1, MN1. |
| endDate or end | string (ISO) | Yes | End of backtest range (clamped to the last available bar if later; max 2 years for date ranges). |
| lookbackBars | integer | One of these | Bars back from `endDate` on the setup timeframe. Capped to available bars (returns a warning) rather than failing. |
| startDate or start | string (ISO) | One of these | Start of backtest range (alternative to `lookbackBars`). |
| includeChartImage | boolean | No | If true, response includes base64 summary chart. Default: false. |

Provide **either** `lookbackBars` **or** `startDate`. If both are sent, `lookbackBars` takes precedence — the request is never rejected for sending both.

**Forgiving behaviour:** over-requesting more bars than exist, or an `endDate` past the last available bar, does **not** fail — the run is capped/clamped and a `warnings: string[]` array is included on the success response. A 403 is only returned for true insufficient backtest balance (with `required`, `remaining`, `paygRequiredCents`).

**Run response:** `runId` (same as `id`), `setupId`, full list of executed trades, summary stats, `summary` / `suggested_user_message` for agents, optional `warnings[]`. If `includeChartImage: true`, `chartImageBase64` (PNG). Responses include `X-Request-Id` when available for support.

**Estimate (`GET /api/v1/backtest/estimate`):** query params `market`, `timeframe`, and either `endDate` + `lookbackBars` or `startDate` + `endDate`. Returns `primaryBarCount`, `bars1mEquivalent`, `resolvedStartDate`, `resolvedEndDate`, `allowanceRemaining1m`, `wouldExceedAllowance`, `paygCostCents`, and `warnings[]`. Use it to preview cost before running; it never starts a run or blocks one.

---

### Alerts

| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/api/v1/alerts/pending` | API key | Poll pending triggers. Optional: `?since=<iso8601>`. Marks returned alerts as delivered. |

**Webhook (primary):** Set `webhookUrl` (and optionally `webhookSecret`) on create, or update them with **PATCH** `/api/v1/service/setups/:id` (those fields only). When the setup triggers, the service POSTs a minimal JSON payload to that URL. Signature: `X-Webhook-Signature: sha256=<hex>` (HMAC-SHA256 of body) when `webhookSecret` is set.

**Webhook payload (minimal):**

```json
{
  "triggered": true,
  "setupId": "...",
  "symbol": "GOLD",
  "timeframe": "5m",
  "timestamp": "2025-02-28T12:00:00.000Z",
  "triggerType": "SETUP_ENTRY_TRIGGER"
}
```

---

### Usage

| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/api/v1/usage` | API key | Current billing period: bars processed (backtest), setup evaluations by timeframe (1m, 5m, 15m+). |

Session users can use `GET /api/v1/account/usage` (session auth) for the same shape.

---

### API keys (session auth only)

Keys are created via the **dashboard** or:

| Method | Path | Auth | Description |
|--------|------|------|-------------|
| POST | `/api/v1/keys` | Session | Create key. Body: `{ "name": "...", "permissions": ["backtest", "alerts"] }`. |
| GET | `/api/v1/keys` | Session | List keys (no secret). |
| DELETE | `/api/v1/keys/:id` | Session | Revoke key. |

---

### Billing (session auth)

| Method | Path | Auth | Description |
|--------|------|------|-------------|
| POST | `/api/v1/billing/create-checkout-session` | Session | Create Stripe Checkout; body: `successUrl`, `cancelUrl`, `priceId`. |
| POST | `/api/v1/billing/create-portal-session` | Session | Create Stripe Customer Portal URL. |

Webhook: `POST /api/v1/billing/webhook` (Stripe; raw body, signature verified).

---

## Error codes

| Code | Meaning |
|------|--------|
| 400 | Bad Request — invalid body or query (e.g. missing field, invalid date). Body: `{ "error": "...", "message": "..." }`. |
| 401 | Unauthorized — missing or invalid API key. |
| 403 | Forbidden — authenticated but not allowed (e.g. over limit, no subscription). Body may include `reason`, `currentCount`, `max`. |
| 404 | Not Found — resource not found or not owned by you. |
| 429 | Too Many Requests — rate limited. Retry after the indicated delay. |
| 500 | Internal server error. |
| 503 | Service unavailable (e.g. billing not configured). |

**Setup creation:** On validation failure you receive a generic error; DSL and internal validation details are not exposed.

---

## Rate limits

Per API key: configurable (default 120 requests per minute). Exceeded requests return 429.

---

## CORS

Configured for allowed origins. Use server-to-server calls or allowed origins when calling from browsers.

---

## Links

- **[Agent Skill](/docs/agent-skill.md)** — How to use the API (workflow, examples, webhook vs polling).
- **[Quickstart](/docs/quickstart.md)** — Sign up → create key → first backtest → setup with webhook.
- **[AI Overview](/docs/ai-overview.md)** — For AI agents and discovery.
