Find shopper profiles by what they answered
const url = 'https://api.octaneai.com/v1/profiles/search?limit=20';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"groups":[{"all":[{"component_key":"image_choice-48su5","kind":"choice","op":"in","option_labels":["Dry"],"page_key":"skin","quiz_id":"quiz_7c9e6679742540de944be07fc1f90ae7"},{"component_key":"number_input-re853","kind":"number","max":50,"min":30,"op":"between","page_key":"skin","quiz_id":"quiz_7c9e6679742540de944be07fc1f90ae7"}]},{"all":[{"dimension_id":"dry","kind":"points","op":"gt","quiz_id":"quiz_7c9e6679742540de944be07fc1f90ae7","value":10}]}],"match":"any_session"}'};
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/profiles/search?limit=20' \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "groups": [ { "all": [ { "component_key": "image_choice-48su5", "kind": "choice", "op": "in", "option_labels": [ "Dry" ], "page_key": "skin", "quiz_id": "quiz_7c9e6679742540de944be07fc1f90ae7" }, { "component_key": "number_input-re853", "kind": "number", "max": 50, "min": 30, "op": "between", "page_key": "skin", "quiz_id": "quiz_7c9e6679742540de944be07fc1f90ae7" } ] }, { "all": [ { "dimension_id": "dry", "kind": "points", "op": "gt", "quiz_id": "quiz_7c9e6679742540de944be07fc1f90ae7", "value": 10 } ] } ], "match": "any_session" }'Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”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”One page of the matching profiles, newest last-seen first; total is exact up to 5,000 and total_capped says when it stopped there.
object
object
object
A search stops counting at 5,000: total is then that cap, read it as 5,000+
Example
{ "data": [ { "completed_count": 1, "email": "shopper@example.com", "first_seen_at": "2026-09-01T12:00:00Z", "id": "prof_50e1b7e458f14dfca7a2a5b971af2821", "last_order_at": "2026-09-01T12:40:00Z", "last_seen_at": "2026-09-01T12:00:00Z", "orders_count": 1, "phone": "+14155552671", "quizzes": [ { "id": "quiz_7c9e6679742540de944be07fc1f90ae7", "name": "Find your routine" } ], "removed": false, "returning": false, "sessions_count": 1, "spent": { "amount": "79.97", "currency": "USD" } } ], "has_more": false, "returning_total": 0, "total": 1, "total_capped": false}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
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"}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"}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"}