Optimizations
Endpoints for creating, managing, and serving optimizations.
All endpoints are under /api/v2/optimizations. Unless noted otherwise, requests require an Authorization: Bearer <token> header.
List optimizations
GET /api/v2/optimizationsAuth: Required
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 10 | Maximum number of results (1--100) |
order_by | string | updated_at | Sort field: updated_at or created_at |
include_archived | boolean | false | Include archived optimizations |
Response:
{
"optimizations": [
{
"id": "699ede80-c94b-4f98-9c79-dd3e07748703",
"name": "Landing Page Hero",
"status": "live",
"model_status": "trained",
"model_id": "4754cae0-9a5d-4691-91af-6d15ccc1f82e",
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-03-28T14:22:00Z",
"summary": {
"variants_count": 6,
"lift": 8.2,
"confidence": 0.87,
"exposures": 1250
}
}
],
"meta": {
"request_id": "req_abc123",
"organization_id": "org_xyz"
}
}The summary object is null for optimizations that have not been trained yet.
Get optimization
GET /api/v2/optimizations/:idAuth: Required
Path parameters:
| Parameter | Type | Description |
|---|---|---|
id | string (UUID) | Optimization ID |
Response: Returns the full optimization object including training_data_config, linked metrics, and current status.
Create optimization
POST /api/v2/optimizationsAuth: Required
Request body:
{
"name": "Landing Page Hero",
"model_type": "cmab",
"training_data_config": {
"reward": {
"name": "signup",
"type": "bool"
},
"design_factors": [
{
"name": "headline",
"dtype": "str",
"levels": ["Ship faster", "Save time", "Build better"]
},
{
"name": "cta_text",
"dtype": "str",
"levels": ["Start free", "Try it now"]
}
],
"context_factors": [
{
"name": "device",
"dtype": "str",
"levels": ["mobile", "desktop"]
}
],
"attribution": {
"type": "last_touch",
"conversion_window_hours": 24
}
},
"reward_metric_id": "metric-uuid",
"holdout_percentage": 10
}| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Human-readable name |
description | string | No | Optional description (max 1000 characters) |
model_type | string | No | mab or cmab (default: cmab) |
training_data_config.reward | object | No | Reward definition with name and type (bool or numeric). Defaults to {"name": "reward", "type": "bool"} |
training_data_config.design_factors | array | Yes | Variables you control. Each has name, dtype, and levels |
training_data_config.context_factors | array | No | Contextual variables for personalization. Same shape as design factors |
training_data_config.attribution | object | No | Attribution model. type is last_touch, conversion_window_hours sets the lookback (default: 24) |
reward_metric_id | string (UUID) | Yes | Link a reward metric at creation time |
assignment_source_id | string (UUID) | No | Link an assignment source. If omitted, Levered auto-creates one pointing to an exposures table in your warehouse |
holdout_percentage | integer | No | Percentage of traffic to hold out for control (0--50, default: 10) |
guardrails | array | No | Guardrail definitions to attach at creation time |
Response:
{
"id": "699ede80-c94b-4f98-9c79-dd3e07748703",
"model_id": "4754cae0-9a5d-4691-91af-6d15ccc1f82e",
"meta": {
"request_id": "req_abc123",
"organization_id": "org_xyz"
}
}Update optimization
PATCH /api/v2/optimizations/:idAuth: Required
Request body:
{
"name": "Updated Name",
"status": "completed"
}Status transitions follow the lifecycle: live -> completed -> archived. You cannot move backward (e.g., archived back to live).
Delete (archive) optimization
DELETE /api/v2/optimizations/:idAuth: Required
Archives the optimization. Data is retained but the optimization is hidden from default list views. Equivalent to setting status to archived.
Response:
{
"id": "699ede80-c94b-4f98-9c79-dd3e07748703",
"status": "archived",
"meta": {
"request_id": "req_abc123",
"organization_id": "org_xyz"
}
}Serve variant
POST /api/v2/optimizations/:id/serveAuth: Not required (public endpoint). Rate limited to 300 requests/min per IP.
Serves the best variant for a user based on the current model. This is the primary endpoint for real-time variant delivery.
Request body:
{
"anonymous_id": "user-abc",
"context": {
"device": "mobile"
},
"n_variants": 1
}| Field | Type | Required | Description |
|---|---|---|---|
anonymous_id | string | Yes | Stable user identifier — required so the exposure can be joined with rewards in your warehouse |
context | object | No | Context factor values for personalization |
n_variants | integer | No | Number of variants to return (default 1) |
Response:
{
"variants": [
{
"props": { "headline": "Ship faster", "cta_text": "Start free" },
"expected_reward": 0.31
}
],
"optimization_id": "699ede80-c94b-4f98-9c79-dd3e07748703",
"model_type": "cmab",
"ready": true,
"meta": {
"request_id": "req_abc123",
"organization_id": "org_xyz"
}
}| Field | Type | Description |
|---|---|---|
variants | array | Ranked variant assignments with design factor values and expected reward |
optimization_id | string | The optimization that served this variant |
model_type | string | mab, cmab, or holdout (if the request was routed to the holdout group) |
ready | boolean | true if the model has been trained, false if it fell back to random sampling from the prior |
Best variant (SDK endpoint)
POST /api/v2/optimizations/best-variantAuth: Not required (public endpoint). Rate limited to 300 requests/min per IP.
Used by the SDK to fetch the best variant. Instead of specifying an optimization ID, the SDK sends the design factor names and Levered matches them to a live optimization automatically.
Request body:
{
"anonymous_id": "user-abc",
"props": ["headline", "cta_text"],
"context": {
"device": "mobile"
},
"control": {
"n_variants": 1
}
}| Field | Type | Required | Description |
|---|---|---|---|
anonymous_id | string | Yes | Stable user identifier |
props | string[] | Yes | Array of design factor names. Levered finds the live optimization whose design factors match this set. |
context | object | No | Context factor values for personalization |
control.n_variants | integer | No | Number of variants to return (default 1) |
Response:
Same shape as the /serve endpoint:
{
"variants": [
{
"props": { "headline": "Build better", "cta_text": "Try it now" },
"expected_reward": 0.29
}
],
"optimization_id": "699ede80-c94b-4f98-9c79-dd3e07748703",
"model_type": "cmab",
"ready": true,
"meta": {
"request_id": "req_abc123",
"organization_id": "org_xyz"
}
}