Request an export
const url = 'https://api.octaneai.com/v1/exports';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"dataset":"profiles","format":"csv","from":"2026-04-15","quiz_id":"quiz_7c9e6679742540de944be07fc1f90ae7","search":{"from":"2026-04-15","groups":[{"all":[{"component_key":"example","dimension_id":"example","kind":"choice","max":1,"min":1,"op":"in","option_ids":["example"],"option_labels":["example"],"page_key":"example","quiz_id":"quiz_7c9e6679742540de944be07fc1f90ae7","value":1}]}],"has_email":true,"has_marketing_consent":true,"has_order":true,"has_phone":true,"is_returning":true,"match":"any_session","quiz_id":"quiz_7c9e6679742540de944be07fc1f90ae7","to":"2026-04-15"},"to":"2026-04-15","tz":"example"}'};
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/exports \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "dataset": "profiles", "format": "csv", "from": "2026-04-15", "quiz_id": "quiz_7c9e6679742540de944be07fc1f90ae7", "search": { "from": "2026-04-15", "groups": [ { "all": [ { "component_key": "example", "dimension_id": "example", "kind": "choice", "max": 1, "min": 1, "op": "in", "option_ids": [ "example" ], "option_labels": [ "example" ], "page_key": "example", "quiz_id": "quiz_7c9e6679742540de944be07fc1f90ae7", "value": 1 } ] } ], "has_email": true, "has_marketing_consent": true, "has_order": true, "has_phone": true, "is_returning": true, "match": "any_session", "quiz_id": "quiz_7c9e6679742540de944be07fc1f90ae7", "to": "2026-04-15" }, "to": "2026-04-15", "tz": "example" }'Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
Profiles or responses need profiles:read; quiz_analytics needs analytics:read
Csv: one row per line behind a UTF-8 byte-order mark; json: one object {dataset, filters, generated_at, items} whose items are the rows as the API returns them
Who to find: the list filters of GET /v1/profiles except q, plus person facts and an answer filter, an OR of AND groups. Send the same body with every page; the cursor is positional only.
object
object
Every slot must hold: a term, or {any: [terms]}
object
Choice | number | date | text | email | phone: a question of the quiz (page_key + component_key); points: a dimension (dimension_id); formula: a formula component (page_key + component_key); winner: the top dimension (dimension ids in option_ids); session: how the shopper’s session ended (value completed | abandoned, page_key the page they left on)
Choice: in | not_in; number, points, formula: eq | lt | gt | between; date: eq | before | after | between; text: contains | equals | matches | answered | not_answered; email, phone: answered | not_answered; winner: in; session: equals. not_in means answered the question and picked none of these; not_answered means took the quiz and left the question unanswered.
object
At least one of these terms must hold; plain terms only
object
Choice | number | date | text | email | phone: a question of the quiz (page_key + component_key); points: a dimension (dimension_id); formula: a formula component (page_key + component_key); winner: the top dimension (dimension ids in option_ids); session: how the shopper’s session ended (value completed | abandoned, page_key the page they left on)
Choice: in | not_in; number, points, formula: eq | lt | gt | between; date: eq | before | after | between; text: contains | equals | matches | answered | not_answered; email, phone: answered | not_answered; winner: in; session: equals. not_in means answered the question and picked none of these; not_answered means took the quiz and left the question unanswered.
Any_session: any time they took the quiz counts; latest_completed_per_quiz: only their latest completed take of each quiz
Responses
Section titled “Responses”The export is queued. Poll urls.self until status is completed, then follow download_url.
object
object
Who to find: the list filters of GET /v1/profiles except q, plus person facts and an answer filter, an OR of AND groups. Send the same body with every page; the cursor is positional only.
object
object
Every slot must hold: a term, or {any: [terms]}
object
Choice | number | date | text | email | phone: a question of the quiz (page_key + component_key); points: a dimension (dimension_id); formula: a formula component (page_key + component_key); winner: the top dimension (dimension ids in option_ids); session: how the shopper’s session ended (value completed | abandoned, page_key the page they left on)
Choice: in | not_in; number, points, formula: eq | lt | gt | between; date: eq | before | after | between; text: contains | equals | matches | answered | not_answered; email, phone: answered | not_answered; winner: in; session: equals. not_in means answered the question and picked none of these; not_answered means took the quiz and left the question unanswered.
object
At least one of these terms must hold; plain terms only
object
Choice | number | date | text | email | phone: a question of the quiz (page_key + component_key); points: a dimension (dimension_id); formula: a formula component (page_key + component_key); winner: the top dimension (dimension ids in option_ids); session: how the shopper’s session ended (value completed | abandoned, page_key the page they left on)
Choice: in | not_in; number, points, formula: eq | lt | gt | between; date: eq | before | after | between; text: contains | equals | matches | answered | not_answered; email, phone: answered | not_answered; winner: in; session: equals. not_in means answered the question and picked none of these; not_answered means took the quiz and left the question unanswered.
Any_session: any time they took the quiz counts; latest_completed_per_quiz: only their latest completed take of each quiz
object
Example
{ "dataset": "profiles", "expires_at": "2026-10-01T12:00:00Z", "filters": { "from": "2026-08-01", "quiz_id": "quiz_7c9e6679742540de944be07fc1f90ae7", "to": "2026-08-31" }, "format": "csv", "id": "exp_3f2504e04f8911d39a0c0305e82c3301", "requested_at": "2026-09-01T12:00:00Z", "source": "api", "status": "pending", "urls": { "self": "https://api.octaneai.com/v1/exports/exp_3f2504e04f8911d39a0c0305e82c3301" }}Headers
Section titled “Headers”Example
https://api.octaneai.com/v1/exports/exp_3f2504e04f8911d39a0c0305e82c3301The 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
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
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": [ "quizzes:read" ], "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
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"}An export of this dataset is still being built; wait for it to finish.
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
A stable URI naming the error, on this API’s public host
Example
{ "detail": "An export of this dataset is already being built; wait for it to finish", "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "status": 409, "title": "conflict", "type": "https://api.octaneai.com/errors/conflict"}A request parameter is invalid.
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
A stable URI naming the error, on this API’s public host
Example
{ "detail": "A request parameter is invalid.", "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "status": 422, "title": "validation_error", "type": "https://api.octaneai.com/errors/validation_error"}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
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
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
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"}