Counting and retrieval
Which endpoint answers which question about the audience: the exact count of a filter, a quick search, a cursor traverse of a large result set, a single contact by id or identifier, and what the subscription plan lets each of them return.
Once a filter selects the right people, there are four different things you might want back, and they are four different endpoints with four different costs and permissions. Picking the wrong one is the usual cause of a 403 you did not expect or a page-two that never arrives.
Which endpoint for which question
| The question | Endpoint | What comes back |
|---|---|---|
| How many match this filter? | POST /audience/count | A single exact total, no contact rows |
| Show me a first page | POST /audience/search | Up to 50 contacts, from the beginning |
| Give me all of them | POST /audience/scroll | Up to 100 per page, cursor-paginated |
| All of them, inside a segment | POST /audience/segment/{uid}/scroll | Same, restricted to a segment |
| This one person | GET /audience/{audienceId} and the identifier lookups | One contact |
| A breakdown, not rows | POST /audience/aggregations | Aggregation results only |
Counting
POST /project/{project}/audience/count takes the audience query filter and returns only the total. It is the endpoint whose number you may act on: exact, uncapped and live, with no sampling anywhere near it.
The exact number of contacts matching a filter.
curl -X POST "$BASE/audience/count" \
-H "Authorization: Bearer $INSTASENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "filterCompliance": { "sms": "opt-out" } }'Four things worth knowing:
- An empty body counts the whole audience.
limitandoffsetare ignored. - It carries no contact data, which is why it stays available under the
anonymizeddata policy mode, where/audience/searchis disabled. For restricted credentials it is the supported way to answer "how many contacts match this". - To count who can actually receive, pass
filterCompliance. Without it the total is the raw audience, not a sending figure. The consent and reach rules are the same ones a campaign estimate applies. See Counting who can receive. - It is the endpoint that settles any number a probe suggested. Probes report shape and may be sampled; this is the size.
Searching and scrolling
Both take the same filter. They differ in how much they will give you and what it costs.
A first page of matching contacts, up to 50.
/audience/search uses offset/limit pagination, but the offset is always forced to 0: it is built for a quick look from the beginning, not for walking a result set. Its ceiling is 50 contacts per request and it needs PROJECT_AUDIENCE_READ.
A cursor traverse of the whole result set, 100 contacts at a time.
/audience/scroll is the one for large traverses. It returns a cursor in the response metadata that you pass back to get the next page, up to 100 contacts per request. The cursor is a base64 string holding the internal query state and expires after one minute of inactivity, so a traverse has to keep moving: a job that fetches a page, spends five minutes processing it and comes back will find the cursor gone.
It needs PROJECT_AUDIENCE_LIST, which is gated by the subscription plan. That is the usual reason a call that works for one organization is refused for another with the same code.
Retrieving one contact
When you already know who you are looking for, four direct lookups skip the filter entirely.
By audience contact id.
By the _user_id your systems use.
By phone number. URL-encode the leading plus as %2B.
By email address.
The id these return is the one every other per-contact call takes, including the contact's events and direct messaging.
Aggregations
POST /audience/aggregations runs your aggregations over the filtered audience and returns results only, with no contact rows and the limit pinned to zero. It needs PROJECT_AGGREGATIONS, which is not generally available and is granted manually by Instasent.
If what you want is a distribution over an attribute rather than a bespoke aggregation, /audience/coverage gives you one with the ordinary read scope, at the cost of being a probe: shape, possibly sampled, never a size.
What the plan lets you see
Two gates decide the fields on a returned contact, and both have to be open: the scopes on your token and the subscription plan of the organization.
| Level | Scope | Fields returned |
|---|---|---|
| Default | PROJECT_AUDIENCE_READ | Full name and user id only |
| Basic | PROJECT_AUDIENCE_DATA_BASIC | Phone, email, country, name, boolean fields |
| Full | PROJECT_AUDIENCE_DATA_FULL | Full contact data including PII |
What's next
- Query filter: the filter these endpoints take, including cursor mechanics and aggregation shapes.
- Segments: scrolling a saved segment, and reading its cached size.
- Probes: check the filter is selecting on something real before you count it.