Docs·Visitors and people
/api/v1/spreelytics/people/query/membersList people who match
Lists who matches a people-query, a page at a time, with the details the app shows on a segment's Members tab. Identified people come back under their person id and anonymous ones under their visitor id; identified says which. Rows are ordered by that id, so paging is stable, but they are not ranked.
The body is the same people-query POST /people/query takes, and search and filter narrow the list. When the workspace is past its plan's allowance, nothing after the moment it ran out is counted. It is a read sent as a POST, so every role can call it, Viewer included.
Keys: an account key or an audience key. Getting started explains both kinds.
Parameters
| Prop | In | Type | Notes |
|---|---|---|---|
contactListId | query | string | The audience id, a UUID. With an audience key it must be that key's own audience. |
page? | query | number | Page number, starting at 0. Defaults to 0. |
pageSize? | query | number | Members per page, 1 to 100 (other values are clamped). Defaults to 25. |
search? | query | string | Optional. Keeps identified people whose name or email contains this text, ignoring case. Anonymous members never match a search, and only the first 2,000 name or email matches are considered. |
filter? | query | string | Optional. The same filter the web analytics endpoints take: a URL-encoded JSON array of [dimension, values, operator] entries, for example [["country",["US"]]] (leave the operator out to mean is). A person passes when at least one of their visits matches it. |
Request body
| Prop | Type | Notes |
|---|---|---|
conditions | PeopleQueryConditionDto[] | Required: 1 to 5 conditions. Each has "source": "internal" and a kind of event, property or revenue. The Cohorts API page describes the fields of each. |
match? | ``all` \ | `any`` |
breakdown? | ``channel` \ | country \ |
startDate? | string | Optional outer window for every condition, sent together with endDate. An ISO 8601 date or timestamp (a bare date is midnight UTC), included. Leave both out for all time. An event condition can carry its own timeframe instead. |
endDate? | string | The end of the outer window, not included. It must come after startDate, or the call answers 400. |
Response
| Prop | Type | Notes |
|---|---|---|
content | PeopleQueryMemberDto[] | The members. Each has contactIdentityId, identified, emails, name (first and last name, empty when unknown) and display (the name, else the first email, else the id). country (a two-letter code), city, channel, browser, os and device come from their latest visit (the latest one that passes filter, when you send one), and countries, channels, browsers, oses and devices list every value across those visits. sessions, pageviews, events and spent (net revenue) are lifetime totals, and firstSeen and lastSeen are ISO timestamps, empty when they have no visits. |
size | number | The page size used. |
page | number | The page returned, counted from 0. |
totalItems | number | How many members there are across all pages. |
totalPages | number | How many pages there are at this page size. |
Each item in content
| Prop | Type | Notes |
|---|---|---|
contactIdentityId | string | |
emails | string[] | |
name | string | The contact's own first + last name, '' when it has neither. |
display | string | Best label: name, else the first email, else the id. |
identified | boolean | |
country | string | |
city | string | |
channel | string | |
browser | string | |
os | string | |
device | string | |
channels | string[] | Every value across the visits this row describes, the single value above included. A row is a |
| PERSON, and identify() binds several devices to one contact, so an identified user on a laptop | ||
| and a phone genuinely has two of each. The table shows the single value plus a "+N". | ||
countries | string[] | |
browsers | string[] | |
oses | string[] | |
devices | string[] | |
sessions | number | |
pageviews | number | |
events | number | |
spent | number | |
firstSeen | string | |
lastSeen | string |
Request
curl -X POST 'https://app.spreelytics.com/api/v1/spreelytics/people/query/members?contactListId=…' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{ … }'
const res = await fetch('https://app.spreelytics.com/api/v1/spreelytics/people/query/members', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ /* see Request body above */ }),
});
const data = await res.json();
import requests
res = requests.post(
"https://app.spreelytics.com/api/v1/spreelytics/people/query/members",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={}, # see Request body above
)
data = res.json()
Response
{
"content": [
{
"contactIdentityId": "string",
"emails": [
"string"
],
"name": "string",
"display": "string",
"identified": true,
"country": "string",
"city": "string",
"channel": "string",
"browser": "string",
"os": "string",
"device": "string",
"channels": [
"string"
],
"countries": [
"string"
],
"browsers": [
"string"
],
"oses": [
"string"
],
"devices": [
"string"
],
"sessions": 0,
"pageviews": 0,
"events": 0,
"spent": 0,
"firstSeen": "string",
"lastSeen": "string"
}
],
"size": 0,
"page": 0,
"totalItems": 0,
"totalPages": 0
}