Developer reference · REST
Keyed REST API
Ordinary HTTP against a bearer key. The same records the application and the MCP connector read, exposed as 13 routes under /api/v2.
Authentication
Send a key as a bearer credential. The key resolves the organization, and the brand comes from the key or from the request. No route takes a brand id in its path.
curl https://app.optimly.ai/api/v2/brand \
-H "Authorization: Bearer $OPTIMLY_KEY" \
-H "X-Optimly-Brand: $BRAND_ID"
Every brand in the organization
An sk_live_… key created under Connections, shown once, with its scope left on every brand — the default. Each request selects one with an X-Optimly-Brand header, and GET /api/v2/brands lists the ids it accepts. The same key works on the MCP connector, where the tool call carries the brand instead of a header.
One brand
The same key, created with a single brand chosen. It pins that brand, so no request needs to name one, and a selector naming a different brand is ignored rather than obeyed.
Routes
| Method | Path | Returns |
|---|---|---|
GET |
/api/v2/brands |
Every brand in the key's org, ordered by name — the ids an `X-Optimly-Brand` selector accepts. A brand-scoped key sees only its own brand. |
GET |
/api/v2/brand |
Identity meta: name, canonical domain, slugs, and claim state. |
GET |
/api/v2/vault |
The active vault — every section with its `publish_state`, plus competitors and disambiguation. |
PUT |
/api/v2/vault |
Update and publish. Partial updates are allowed: sections you omit copy forward. Recorded with `origin_source='api'`. |
GET |
/api/v2/recommendations |
Every recommendation for the key's brand. |
PATCH |
/api/v2/recommendations/{rec_id} |
Act on a recommendation. `acted_by` stays NULL — the key acted, not a signed-in user — so the attribution overlay reads `acted_at` alone. |
GET |
/api/v2/reports |
Every report for the key's brand, newest version first. |
GET |
/api/v2/reports/{report_id} |
Report detail: the frozen summary metrics and the run's panel snapshot. |
GET |
/api/v2/reports/{report_id}/questions |
Question Analysis: every question with its per-model answers and judgments. |
GET |
/api/v2/reports/{report_id}/sources |
Sources: per-domain citation aggregation with owned / competitor / third-party classification. |
GET |
/api/v2/attribution |
The attribution overlay: the metric trend across the brand's report versions plus the acted-on recommendation timeline. |
GET |
/api/v2/vault/versions |
Version metadata for the key's brand, newest first. |
GET |
/api/v2/vault/versions/{version} |
One version snapshot: its metadata plus the full section rows. |
Conventions
Reports are read-only
Every route that returns report data is a GET. No route starts a run: measurement runs on schedules set in the application, so a report appears when the schedule produces it.
Writing is two verbs
PUT /api/v2/vault publishes a brand profile and PATCH /api/v2/recommendations/{rec_id} acts on a recommendation. Partial vault updates are allowed — sections you omit copy forward — and the write is recorded with its origin, so an API-authored change is distinguishable from one made in the application.
Rate limit
60 requests per minute per key. Every response carries X-RateLimit-* headers; a request over the limit answers 429.
Errors
Failures share one envelope with a machine-readable code, a human message, and any details the specific failure adds. The same envelope is what the MCP connector surfaces as a tool error, so an agent sees the same message a script would.
The previous version
Anything under /api/v1 answers 410 Gone. Use /api/v2.
Related
The MCP connector covers the same records for MCP clients, and is usually the shorter path for an agent.