Audiences
Create static and dynamic audiences, set their conditions, and read their members.
An audience is a saved group of contacts that a campaign can target. A static audience holds a fixed set of contacts. A dynamic audience matches contacts against saved conditions each time you read its members.
| Endpoint | Request |
|---|---|
| List audiences | GET/v1/audiences |
| Get an audience | GET/v1/audiences/{id} |
| Create an audience | POST/v1/audiences |
| Update an audience | PATCH/v1/audiences/{id} |
| Delete an audience | DEL/v1/audiences/{id} |
| List audience members | GET/v1/audiences/{id}/members |
The audience object
Audience fields use snake_case.
Attributes
idstringrequirednamestringrequireddescriptionstring | nullnull.typestringrequiredstatic or dynamic.criteriaobject | nullnull for a static audience.sizeintegerrequiredpagination.total from the members route.tagsstring[]requiredis_activebooleanrequiredcreated_atstringrequiredupdated_atstringrequiredConditions
Conditions are a group. A group's conditions array holds rules, and an and group can also hold nested groups. Send them as conditions or as criteria, but not both. The audience object always returns them as criteria, with lowercase operators and each rule's fieldType filled in.
{
"operator": "and",
"conditions": [
{ "field": "tags", "operator": "contains", "value": ["vip"] },
{ "field": "created_at", "operator": "within_days", "value": 90 },
{
"operator": "and",
"conditions": [
{ "field": "email", "operator": "exists" },
{ "field": "company", "operator": "contains", "value": "Example" }
]
}
]
}Group
operatorstringrequiredand or or, in either letter case.conditionsarrayrequiredRule
fieldstringrequiredoperatorstringrequiredvalueanyfieldTypestringstring, date, array or object. Optional. If you send it, it must match the field's type.Limits
- Groups can be nested up to 5 levels deep.
- A group can have up to 50 items.
- All groups together can have up to 100 rules.
- A string value can be up to 500 characters, and a list can have up to 100 items.
Fields
| Type | Fields |
|---|---|
string | email, phone, phone_number, name, first_name, last_name, company, contact_type, timezone, external_id |
string | marketing_consent->sms_marketing_consent->state, marketing_consent->email_marketing_consent->state |
string | metadata->commerce_profile->country_code, metadata->commerce_profile->postal_code |
date | created_at, updated_at |
array | tags, metadata.tags |
object | commerce_events |
Any other field returns 400. That includes other keys inside metadata.
Tag rules match a normalized form of the tag. Renewal Q4 becomes renewal_q4: lowercase, with spaces replaced by underscores and other symbols removed.
Operators
| Field type | Operator | value |
|---|---|---|
string | equals, not_equals, ilike, not_ilike, contains, starts_with, ends_with | A string. |
string | in, not_in | A non-empty list of strings. |
string | exists, not_exists | None. |
date | equals, before, after | An ISO 8601 date. |
date | between | A list of exactly two ISO 8601 dates. |
date | within_days, more_than_days_ago | A whole number from 1 to 36,500. |
date | in_last_day, in_last_week, in_last_month, exists, not_exists | None. |
array | contains, contains_any, overlaps, not_contains | A string, or a non-empty list of strings. |
array | is_empty, is_not_empty | None. |
object | event_frequency | An object. See Commerce events. |
OR groups
An or group is more limited than an and group:
- It can't hold nested groups.
- It can't hold
daterules. - Its
stringrules can only useequals,not_equals,ilike,contains,starts_with,ends_with,existsandnot_exists.
To combine these, put them in an and group.
Commerce events
The commerce_events field matches contacts by what they did in a connected store.
{
"field": "commerce_events",
"operator": "event_frequency",
"value": {
"event": "placed_order",
"frequencyOperator": "is_at_least",
"frequencyValue": 2,
"timeRangeType": "in_the_last",
"timeValue": 30,
"timeUnit": "days"
}
}value
eventstringrequiredcustomer_created, customer_updated, placed_order, fulfilled_order, cancelled_order, refunded_order, checkout_started or ordered_product.frequencyOperatorstringrequiredat_least_once, zero_times, equals, does_not_equal, is_at_least, is_greater_than, is_less_than or is_at_most.frequencyValueinteger | nulltimeRangeTypestringrequiredin_the_last, over_all_time, after or before.timeValueinteger | nulltimeUnitstring | nullhours, days or weeks.List audiences
/v1/audiencesread keyReturns your audiences, most recently updated first.
Query parameters
limitintegerdefault 50offsetintegerdefault 0Paging values outside those ranges return 400.
curl "https://backend.synthesys.app/api/v1/audiences?limit=10" \
-H "SYNTH_API_KEY: YOUR_API_KEY"{
"success": true,
"data": [
{
"id": "8a1d4f2c-3b6e-4c7a-8d90-1e2f3a4b5c6d",
"name": "VIP customers",
"description": "Contacts tagged VIP",
"type": "dynamic",
"criteria": {
"operator": "and",
"conditions": [
{ "field": "tags", "fieldType": "array", "operator": "contains", "value": ["vip"] }
]
},
"size": 42,
"tags": [],
"is_active": true,
"created_at": "2026-09-01T10:00:00.000Z",
"updated_at": "2026-10-01T10:00:00.000Z"
}
],
"pagination": { "total": 1, "limit": 10, "offset": 0 }
}Get an audience
/v1/audiences/{id}read keyReturns one audience.
Path parameters
idstringrequiredReturns 404 if the audience doesn't exist or belongs to another account. An id that isn't a valid UUID returns 400.
curl https://backend.synthesys.app/api/v1/audiences/8a1d4f2c-3b6e-4c7a-8d90-1e2f3a4b5c6d \
-H "SYNTH_API_KEY: YOUR_API_KEY"{
"success": true,
"data": {
"id": "8a1d4f2c-3b6e-4c7a-8d90-1e2f3a4b5c6d",
"name": "Spring list",
"description": null,
"type": "static",
"criteria": null,
"size": 120,
"tags": [],
"is_active": true,
"created_at": "2026-09-01T10:00:00.000Z",
"updated_at": "2026-10-01T10:00:00.000Z"
}
}{
"success": false,
"error": "Audience not found",
"code": "NOT_FOUND",
"requestId": "e3a1c5d7-2b4f-4a6c-9d8e-1f2a3b4c5d6e",
"timestamp": "2026-10-31T14:02:11.482Z"
}Create an audience
/v1/audienceswrite keyCreates an audience and returns it with status 201.
Body parameters
namestringrequireddescriptionstringtypestringstatic or dynamic. If you leave it out, an audience with conditions is dynamic, and one without is static.conditionsobjectcriteriaobjectconditions. Send one or the other.Errors:
400: a field fails validation, including an unsupported field or operator in a rule.details.issuesgives the path to it.409: an audience with this name already exists.
curl -X POST https://backend.synthesys.app/api/v1/audiences \
-H "SYNTH_API_KEY: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "VIP customers",
"description": "Contacts tagged VIP",
"conditions": {
"operator": "and",
"conditions": [
{ "field": "tags", "operator": "contains", "value": ["vip"] }
]
}
}'{
"success": true,
"data": {
"id": "8a1d4f2c-3b6e-4c7a-8d90-1e2f3a4b5c6d",
"name": "VIP customers",
"description": "Contacts tagged VIP",
"type": "dynamic",
"criteria": {
"operator": "and",
"conditions": [
{ "field": "tags", "fieldType": "array", "operator": "contains", "value": ["vip"] }
]
},
"size": 42,
"tags": [],
"is_active": true,
"created_at": "2026-10-31T10:00:00.000Z",
"updated_at": "2026-10-31T10:00:00.000Z"
}
}{
"success": false,
"error": "The request is invalid.",
"code": "VALIDATION_ERROR",
"requestId": "e3a1c5d7-2b4f-4a6c-9d8e-1f2a3b4c5d6e",
"timestamp": "2026-10-31T14:02:11.482Z",
"details": {
"issues": [
{ "path": "conditions.conditions.0.operator", "message": "Operator is not supported for a date field" }
]
}
}Update an audience
/v1/audiences/{id}write keyChanges an audience's name, description or conditions, and returns the audience. Send at least one. New conditions replace the old ones, and size is recalculated.
Path parameters
idstringrequiredBody parameters
namestringdescriptionstringconditionsobjectcriteriaobjectconditions. Send one or the other.An audience's type can't change.
Errors:
400: a field fails validation, the body is empty, or you sent conditions for a static audience.404: the audience doesn't exist or belongs to another account.409: an audience with this name already exists.
curl -X PATCH https://backend.synthesys.app/api/v1/audiences/8a1d4f2c-3b6e-4c7a-8d90-1e2f3a4b5c6d \
-H "SYNTH_API_KEY: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "VIP customers 2026",
"conditions": {
"operator": "or",
"conditions": [
{ "field": "tags", "operator": "contains", "value": ["vip"] },
{ "field": "company", "operator": "equals", "value": "Example Inc" }
]
}
}'{
"success": true,
"data": {
"id": "8a1d4f2c-3b6e-4c7a-8d90-1e2f3a4b5c6d",
"name": "VIP customers 2026",
"description": "Contacts tagged VIP",
"type": "dynamic",
"criteria": {
"operator": "or",
"conditions": [
{ "field": "tags", "fieldType": "array", "operator": "contains", "value": ["vip"] },
{ "field": "company", "fieldType": "string", "operator": "equals", "value": "Example Inc" }
]
},
"size": 58,
"tags": [],
"is_active": true,
"created_at": "2026-09-01T10:00:00.000Z",
"updated_at": "2026-10-31T14:05:00.000Z"
}
}Delete an audience
/v1/audiences/{id}delete keyPermanently removes the audience and its membership records. It can't be restored. The contacts themselves aren't changed.
Path parameters
idstringrequiredReturns 404 if the audience doesn't exist or belongs to another account. An id that isn't a valid UUID returns 400.
curl -X DELETE https://backend.synthesys.app/api/v1/audiences/8a1d4f2c-3b6e-4c7a-8d90-1e2f3a4b5c6d \
-H "SYNTH_API_KEY: YOUR_API_KEY"{ "success": true, "message": "Audience deleted successfully" }List audience members
/v1/audiences/{id}/membersread keyReturns the active contacts in an audience. A dynamic audience evaluates its conditions on each request and returns the newest contacts first. A static audience has no guaranteed order. pagination.total is the true number of members.
Path parameters
idstringrequiredQuery parameters
limitintegerdefault 50offsetintegerdefault 0Members use the same fields as the contact object, with these differences:
tagsisn't included. CallGET /v1/contacts/{id}to read a member's tags.name,phone_numbers,emailsand similar fields are returned as stored, so they aren't reformatted and can benull.
Returns 404 if the audience doesn't exist or belongs to another account. An id that isn't a valid UUID returns 400.
curl "https://backend.synthesys.app/api/v1/audiences/8a1d4f2c-3b6e-4c7a-8d90-1e2f3a4b5c6d/members?limit=50&offset=0" \
-H "SYNTH_API_KEY: YOUR_API_KEY"{
"success": true,
"data": [
{
"id": "3f2b8c1e-7a4d-4e9b-9c10-5d6e7f8a9b0c",
"first_name": "Jane",
"last_name": "Doe",
"name": "Jane Doe",
"phone": "+12025550123",
"phone_number": "+12025550123",
"phone_numbers": ["+12025550123"],
"email": "jane@example.com",
"emails": ["jane@example.com"],
"company": "Example Inc",
"contact_type": "other",
"timezone": "UTC",
"metadata": { "crm_id": "A-1001" },
"created_at": "2026-10-01T09:30:00.000Z",
"updated_at": "2026-10-01T09:30:00.000Z"
}
],
"pagination": { "total": 1, "limit": 50, "offset": 0 }
}