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.

FieldValid operatorsExample
statusequals, not_equalssubscribed, bounced
tagsarray_contains onlyAudience 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: The nextCursor of 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

  • Send to an audience? Go to Campaigns
  • Trigger flows on audience join? See Flows
  • Tag contacts? Go back to Contacts

Edit this page on GitHub

Last updated on