Create a draft experiment
const url = 'https://api.octaneai.com/v1/experiments';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"ai_fallback":"when_clear","ai_max_runs":1,"ai_trigger":"when_clear","control_weight":1,"decision_date":"2026-04-15","decision_metric":{"kind":"completion_rate","target":{"additionalProperty":"example"}},"decision_option":"manual","fallback":"keep","long_run_reminders":true,"merchant_note":"example","name":"example","protect_metrics":["completion_rate"],"quiz_id":"quiz_7c9e6679742540de944be07fc1f90ae7","revenue_tiers":["added_from_quiz"],"timezone":"UTC","variant":{"version_id":"ver_7c9e6679742540de944be07fc1f90ae7","weight":1},"weekly_digest":true}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.octaneai.com/v1/experiments \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "ai_fallback": "when_clear", "ai_max_runs": 1, "ai_trigger": "when_clear", "control_weight": 1, "decision_date": "2026-04-15", "decision_metric": { "kind": "completion_rate", "target": { "additionalProperty": "example" } }, "decision_option": "manual", "fallback": "keep", "long_run_reminders": true, "merchant_note": "example", "name": "example", "protect_metrics": [ "completion_rate" ], "quiz_id": "quiz_7c9e6679742540de944be07fc1f90ae7", "revenue_tiers": [ "added_from_quiz" ], "timezone": "UTC", "variant": { "version_id": "ver_7c9e6679742540de944be07fc1f90ae7", "weight": 1 }, "weekly_digest": true }'Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
After that many runs: decide at the first clear result without the AI, or wait for you
The live version’s share of the split, a whole number weighed against the variant’s
Manual: the merchant decides. when_clear: publish at the first clear result. on_date: decide on a date. ai: the AI decides.
What happens on the date without a clear result: keep running, put the live version back, or tell the merchant and wait.
Whether reminder emails go out six weeks after the start and every two weeks after until it ends
The kinds of revenue counted: added_from_quiz | shown_bought_later | bought_not_shown
IANA name of the timezone decision_date is read in
object
The arm’s share of the split, a whole number weighed against the other arm’s
Whether a weekly email reports where the test stands
Responses
Section titled “Responses”A draft with the live version and one variant.
object
After that many runs: decide at the first clear result without the AI, or wait for you
object
0 for the live version, 1 for the variant
The arm’s share of the split, a whole number weighed against the other arm’s
Completion_rate | email_opt_in | order_conversion | rpv | aov | phone_opt_in | reached_page | product_page_clicked | custom_url_clicked | button_clicked | chose_answer
Manual: the merchant decides. when_clear: publish at the first clear result. on_date: decide on a date. ai: the AI decides.
What happens on the date without a clear result: keep running, put the live version back, or tell the merchant and wait.
Whether reminder emails go out six weeks after the start and every two weeks after until it ends
The current counting period: 0 on a draft, 1 once started, one higher each time a new one opens
Why a counting period began.
The metrics the test watches for harm: completion_rate | email_opt_in | order_conversion | rpv | aov | phone_opt_in | reached_page | product_page_clicked | custom_url_clicked | button_clicked | chose_answer
The kinds of revenue counted: added_from_quiz | shown_bought_later | bought_not_shown
A number that goes up with every change to the test
Draft: set up, not started. running: shoppers are being split. waiting: still splitting, automatic decisions paused. ended: no longer assigning.
IANA name of the timezone decision_date is read in
Whether a weekly email reports where the test stands
Example
{ "ai_fallback": "when_clear", "app_id": "quiz_7c9e6679742540de944be07fc1f90ae7", "arms": [ { "id": "arm_00000000000000000000000000000001", "is_control": true, "label": "Live version", "position": 0, "version_id": "ver_00000000000000000000000000000001", "version_number": 1, "weight": 1 }, { "id": "arm_00000000000000000000000000000002", "is_control": false, "label": "Variant B", "position": 1, "version_id": "ver_00000000000000000000000000000002", "version_number": 2, "weight": 1 } ], "created_at": "2026-09-16T12:00:00Z", "decision_metric": "completion_rate", "decision_option": "when_clear", "fallback": "notify", "id": "expt_7c9e6679742540de944be07fc1f90ae7", "long_run_reminders": true, "name": "Skip the email page", "period": 0, "period_reason": "started", "protect_metrics": [], "revenue_tiers": [ "added_from_quiz", "shown_bought_later", "bought_not_shown" ], "revision": 0, "status": "draft", "timezone": "UTC", "updated_at": "2026-09-16T12:00:00Z", "weekly_digest": true}The key is missing, malformed, revoked or expired.
The body of every non-2xx response.
object
What went wrong, for people
object
The input that failed, as a dotted path (body.label, query.from)
Why it failed
The same value as the Request-Id header; quote it to support
The HTTP status of the response
The machine-readable error code; the Errors guide lists every one
A stable URI naming the error, on this API’s public host
Example
{ "detail": "The API key is missing, malformed, revoked or expired", "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "status": 401, "title": "invalid_api_key", "type": "https://api.octaneai.com/errors/invalid_api_key"}Headers
Section titled “Headers”Example
BearerThe store’s plan has no API access, or the key lacks the scope.
The body of every non-2xx response.
object
What went wrong, for people
object
The input that failed, as a dotted path (body.label, query.from)
Why it failed
The same value as the Request-Id header; quote it to support
The HTTP status of the response
The machine-readable error code; the Errors guide lists every one
A stable URI naming the error, on this API’s public host
Examples
{ "detail": "The API key does not carry the scope this route needs", "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "required": [ "experiments:write" ], "status": 403, "title": "insufficient_scope", "type": "https://api.octaneai.com/errors/insufficient_scope"}{ "detail": "The merchant API is available on the Plus and Enterprise plans", "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "status": 403, "title": "plan_required", "type": "https://api.octaneai.com/errors/plan_required"}Not found
The body of every non-2xx response.
object
What went wrong, for people
object
The input that failed, as a dotted path (body.label, query.from)
Why it failed
The same value as the Request-Id header; quote it to support
The HTTP status of the response
The machine-readable error code; the Errors guide lists every one
A stable URI naming the error, on this API’s public host
Example
{ "detail": "Not found", "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "status": 404, "title": "not_found", "type": "https://api.octaneai.com/errors/not_found"}A test is already open on this quiz; end it before starting another.
The body of every non-2xx response.
object
What went wrong, for people
object
The input that failed, as a dotted path (body.label, query.from)
Why it failed
The same value as the Request-Id header; quote it to support
The HTTP status of the response
The machine-readable error code; the Errors guide lists every one
A stable URI naming the error, on this API’s public host
Example
{ "detail": "A test is already open on this quiz; end it before starting another.", "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "status": 409, "title": "conflict", "type": "https://api.octaneai.com/errors/conflict"}Automatic decisions wait a full seven days, whatever the numbers look like earlier.
The body of every non-2xx response.
object
What went wrong, for people
object
The input that failed, as a dotted path (body.label, query.from)
Why it failed
The same value as the Request-Id header; quote it to support
The HTTP status of the response
The machine-readable error code; the Errors guide lists every one
A stable URI naming the error, on this API’s public host
Example
{ "detail": "Automatic decisions wait a full seven days, whatever the numbers look like earlier.", "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "status": 422, "title": "invalid_experiment", "type": "https://api.octaneai.com/errors/invalid_experiment"}The key’s or the store’s bucket is full; Retry-After says when to try again.
The body of every non-2xx response.
object
What went wrong, for people
object
The input that failed, as a dotted path (body.label, query.from)
Why it failed
The same value as the Request-Id header; quote it to support
The HTTP status of the response
The machine-readable error code; the Errors guide lists every one
A stable URI naming the error, on this API’s public host
Example
{ "detail": "Too many requests", "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "retry_after": 1, "status": 429, "title": "rate_limited", "type": "https://api.octaneai.com/errors/rate_limited"}Request limits cannot be checked right now; retry shortly.
The body of every non-2xx response.
object
What went wrong, for people
object
The input that failed, as a dotted path (body.label, query.from)
Why it failed
The same value as the Request-Id header; quote it to support
The HTTP status of the response
The machine-readable error code; the Errors guide lists every one
A stable URI naming the error, on this API’s public host
Example
{ "detail": "Request limits cannot be checked right now; retry shortly", "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "status": 503, "title": "limiter_unavailable", "type": "https://api.octaneai.com/errors/limiter_unavailable"}The request timed out.
The body of every non-2xx response.
object
What went wrong, for people
object
The input that failed, as a dotted path (body.label, query.from)
Why it failed
The same value as the Request-Id header; quote it to support
The HTTP status of the response
The machine-readable error code; the Errors guide lists every one
A stable URI naming the error, on this API’s public host
Example
{ "detail": "The request timed out.", "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "status": 504, "title": "timeout", "type": "https://api.octaneai.com/errors/timeout"}