Audiences: Segmentation
Create rule-based audiences for campaigns and flows
An audience is a group of contacts defined by rules. Use audiences to segment your contacts for targeted campaigns and flows.
Create an Audience
Define an audience using filtering rules.
cURL
curl -X POST https://api.tratto.email/v1/audiences \
-H "Authorization: Bearer tratto_live_..." \
-H "Content-Type: application/json" \
-d '{
"name":"VIP Newsletter Subscribers",
"rules":[
{"field":"status","operator":"equals","value":"subscribed"},
{"field":"tags","operator":"array_contains","value":"vip"}
]
}'Response:
{
"data": {
"id": "aud_abc123"
}
}rules-based audiences are materialized asynchronously right after creation
— fetch GET /v1/audiences/{id} a moment later for
the resolved contactCount.
Rule Types
Every rule is { field, operator, value }. Available operators: equals, not_equals, contains, not_contains, array_contains.
| Field | Valid operators | Example |
|---|---|---|
status | equals, not_equals | subscribed, bounced |
tags | array_contains only | Audience has contacts tagged "vip": tags is a list, so only array_contains produces a real match. equals/contains never match a list and silently return no results. |
contains/not_contains/array_contains compare strings case-insensitively.
Multiple Rules (AND Logic)
All rules must match:
{
"rules": [
{"field": "status", "operator": "equals", "value": "subscribed"},
{"field": "tags", "operator": "array_contains", "value": "newsletter"}
]
}This audience includes contacts that are:
- Status: subscribed AND
- Have tag: newsletter
Add Contacts Manually
In addition to rules, manually add specific contacts.
cURL
curl -X POST https://api.tratto.email/v1/audiences/aud_abc123/contacts \
-H "Authorization: Bearer tratto_live_..." \
-H "Content-Type: application/json" \
-d '{
"contactIds":["cont_abc123","cont_def456"]
}'Response:
{
"data": {
"added": 2,
"alreadyInAudience": 0,
"notFound": 0
}
}Dynamic vs Static
- Dynamic (has
rules): membership is reconciled automatically on every contact create/update/delete — a contact that starts (or stops) matching an audience's rules is added to (or removed from) it right away, no manual action needed. - Static (no
rules, contacts added via the endpoint above): fixed list, never changes on its own.
An audience is dynamic if it has rules, static otherwise — there's
no separate type field, it's inferred from whether rules is empty.
List Audiences
Get all audiences for your tenant.
cURL
curl https://api.tratto.email/v1/audiences \
-H "Authorization: Bearer tratto_live_..."Get Audience Details
Retrieve a specific audience.
cURL
curl https://api.tratto.email/v1/audiences/aud_abc123 \
-H "Authorization: Bearer tratto_live_..."Response:
{
"data": {
"id": "aud_abc123",
"name": "VIP Newsletter Subscribers",
"description": "",
"rules": [...],
"contactCount": 1250,
"createdAt": "2025-06-30T12:00:00Z"
}
}Update an Audience
Change the name, the description or the rules. Every field is optional; an
omitted field keeps its value. Requires contacts:write.
cURL
curl -X PATCH https://api.tratto.email/v1/audiences/aud_abc123 \
-H "Authorization: Bearer tratto_live_..." \
-H "Content-Type: application/json" \
-d '{
"name":"VIP Subscribers",
"rules":[
{"field":"status","operator":"equals","value":"subscribed"},
{"field":"tags","operator":"array_contains","value":"vip"}
]
}'The response is the updated audience, same shape as
Get Audience Details. name is 1 to 100 characters,
description up to 500.
Sending a non-empty rules list recomputes membership against every contact
before the response returns, so contactCount is already the new one.
Membership then follows the rules only: a contact you
added by hand that does not match them is removed.
Sending "rules": [] turns the audience static: the rules are cleared and the
current members stay, nothing is recomputed.
An unknown id answers 404.
Refresh a Rule-Based Audience
Recompute a dynamic audience against your contacts as they are now, and get
the resulting count. Requires contacts:write.
cURL
curl -X POST https://api.tratto.email/v1/audiences/aud_abc123/refresh \
-H "Authorization: Bearer tratto_live_..."Response:
{
"data": {
"contactCount": 1250
}
}Like a rules change, a refresh adds every contact that matches and removes
every member that does not, contacts added by hand included. On a static
audience (no rules) there is nothing to recompute and the call answers
422 VALIDATION_ERROR. An unknown id answers 404.
List Audience Members
Read the contacts in an audience, newest contact first. Requires
contacts:read.
cURL
curl "https://api.tratto.email/v1/audiences/aud_abc123/contacts?limit=50" \
-H "Authorization: Bearer tratto_live_..."Query parameters:
limit: Results per page, 1 to 100 (default 50)after: ThenextCursorof the previous page
Response:
{
"data": [
{
"id": "cont_abc123",
"email": "alice@example.com",
"firstName": "Alice",
"lastName": "Rossi",
"status": "subscribed"
}
],
"pagination": {
"hasMore": true,
"nextCursor": "cont_abc123"
}
}Keep passing nextCursor as after until hasMore is false, where
nextCursor is null. A cursor that does not match an existing contact is
ignored and the list starts again from the first page. An unknown audience id
answers 404.
Remove a Contact from an Audience
Take one contact out of an audience. The contact itself is not changed in any
other way. Requires contacts:write.
cURL
curl -X DELETE https://api.tratto.email/v1/audiences/aud_abc123/contacts/cont_abc123 \
-H "Authorization: Bearer tratto_live_..."Returns 204 No Content, also when the contact was not a member: removing it
twice is safe. An unknown contact id answers 404.
On a dynamic audience the removal lasts only until membership is recomputed: the next refresh or rules change adds the contact back if it still matches. To keep a contact out for good, change something the rules look at, such as a tag.
Delete an Audience
Permanently deletes the audience itself. Contacts are never touched: deleting an audience just removes that grouping; every contact that was a member keeps existing untouched, with all its data, tags and status intact.
cURL
curl -X DELETE https://api.tratto.email/v1/audiences/aud_abc123 \
-H "Authorization: Bearer tratto_live_..."Returns 204 No Content on success.
If the audience is still referenced by a campaign that hasn't finished
sending (draft, scheduled, sending or paused), the request is rejected
with 409 Conflict instead. Remove the audience from those campaigns first,
or wait until they complete.
Using Audiences in Campaigns
Send a campaign to an entire audience.
cURL
curl -X POST https://api.tratto.email/v1/campaigns \
-H "Authorization: Bearer tratto_live_..." \
-H "Content-Type: application/json" \
-d '{
"name":"Q3 VIP Offer",
"templateId":"tmpl_abc123",
"audienceId":"aud_abc123"
}'Using Audiences in Flows
Trigger a flow when a contact joins an audience.
{
"name": "Welcome VIP",
"trigger": {
"type": "contact_joins_audience",
"audienceId": "aud_abc123"
},
"steps": [...]
}See Flows for details.
Next Steps
Edit this page on GitHub
Last updated on