For Developers
Outreach

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.

EndpointRequest
List audiencesGET/v1/audiences
Get an audienceGET/v1/audiences/{id}
Create an audiencePOST/v1/audiences
Update an audiencePATCH/v1/audiences/{id}
Delete an audienceDEL/v1/audiences/{id}
List audience membersGET/v1/audiences/{id}/members

The audience object

Audience fields use snake_case.

Attributes

idstringrequired
The audience's UUID.
namestringrequired
The audience's name. Names are unique within an account and case-sensitive.
descriptionstring | null
A description. An empty description returns null.
typestringrequired
static or dynamic.
criteriaobject | null
The conditions for a dynamic audience, in the form described below. null for a static audience.
sizeintegerrequired
Stored member count. For a dynamic audience it is refreshed when its conditions change, so it can lag behind your contacts. For a current count, read pagination.total from the members route.
tagsstring[]required
Tags used to organize audiences.
is_activebooleanrequired
Whether the audience is active.
created_atstringrequired
When the audience was created.
updated_atstringrequired
When the audience last changed.

Conditions

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.

JSON
{
  "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

operatorstringrequired
and or or, in either letter case.
conditionsarrayrequired
Rules or nested groups. It can't be empty.

Rule

fieldstringrequired
The contact field to test. See Fields.
operatorstringrequired
The comparison, in either letter case. See Operators.
valueany
The value to compare against. Its form depends on the operator.
fieldTypestring
string, 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

TypeFields
stringemail, phone, phone_number, name, first_name, last_name, company, contact_type, timezone, external_id
stringmarketing_consent->sms_marketing_consent->state, marketing_consent->email_marketing_consent->state
stringmetadata->commerce_profile->country_code, metadata->commerce_profile->postal_code
datecreated_at, updated_at
arraytags, metadata.tags
objectcommerce_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 typeOperatorvalue
stringequals, not_equals, ilike, not_ilike, contains, starts_with, ends_withA string.
stringin, not_inA non-empty list of strings.
stringexists, not_existsNone.
dateequals, before, afterAn ISO 8601 date.
datebetweenA list of exactly two ISO 8601 dates.
datewithin_days, more_than_days_agoA whole number from 1 to 36,500.
datein_last_day, in_last_week, in_last_month, exists, not_existsNone.
arraycontains, contains_any, overlaps, not_containsA string, or a non-empty list of strings.
arrayis_empty, is_not_emptyNone.
objectevent_frequencyAn 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 date rules.
  • Its string rules can only use equals, not_equals, ilike, contains, starts_with, ends_with, exists and not_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.

JSON
{
  "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

eventstringrequired
customer_created, customer_updated, placed_order, fulfilled_order, cancelled_order, refunded_order, checkout_started or ordered_product.
frequencyOperatorstringrequired
at_least_once, zero_times, equals, does_not_equal, is_at_least, is_greater_than, is_less_than or is_at_most.
frequencyValueinteger | null
The count to compare with, from 0 upward.
timeRangeTypestringrequired
in_the_last, over_all_time, after or before.
timeValueinteger | null
The size of the time range, from 0 upward.
timeUnitstring | null
hours, days or weeks.

List audiences

GET/v1/audiencesread key

Returns your audiences, most recently updated first.

Query parameters

limitintegerdefault 50
Maximum results, from 1 to 100.
offsetintegerdefault 0
Number of results to skip, up to 1,000,000.

Paging values outside those ranges return 400.

Request
curl "https://backend.synthesys.app/api/v1/audiences?limit=10" \
  -H "SYNTH_API_KEY: YOUR_API_KEY"
Response
{
  "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

GET/v1/audiences/{id}read key

Returns one audience.

Path parameters

idstringrequired
The audience's UUID.

Returns 404 if the audience doesn't exist or belongs to another account. An id that isn't a valid UUID returns 400.

Request
curl https://backend.synthesys.app/api/v1/audiences/8a1d4f2c-3b6e-4c7a-8d90-1e2f3a4b5c6d \
  -H "SYNTH_API_KEY: YOUR_API_KEY"
Response
{
  "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"
  }
}
Not found (404)
{
  "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

POST/v1/audienceswrite key

Creates an audience and returns it with status 201.

Body parameters

namestringrequired
The audience's name, from 1 to 255 characters. It must be unique within your account.
descriptionstring
A description, up to 1,000 characters.
typestring
static or dynamic. If you leave it out, an audience with conditions is dynamic, and one without is static.
conditionsobject
The conditions for a dynamic audience. A dynamic audience must have them, and a static audience can't.
criteriaobject
Another name for conditions. Send one or the other.

Errors:

  • 400: a field fails validation, including an unsupported field or operator in a rule. details.issues gives the path to it.
  • 409: an audience with this name already exists.
Request
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"] }
      ]
    }
  }'
Response (201)
{
  "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"
  }
}
Unsupported field (400)
{
  "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

PATCH/v1/audiences/{id}write key

Changes 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

idstringrequired
The audience's UUID.

Body parameters

namestring
A new name, from 1 to 255 characters.
descriptionstring
A new description, up to 1,000 characters. An empty string clears it.
conditionsobject
New conditions. Dynamic audiences only.
criteriaobject
Another name for conditions. 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.
Request
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" }
      ]
    }
  }'
Response
{
  "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

DEL/v1/audiences/{id}delete key

Permanently removes the audience and its membership records. It can't be restored. The contacts themselves aren't changed.

Path parameters

idstringrequired
The audience's UUID.

Returns 404 if the audience doesn't exist or belongs to another account. An id that isn't a valid UUID returns 400.

Request
curl -X DELETE https://backend.synthesys.app/api/v1/audiences/8a1d4f2c-3b6e-4c7a-8d90-1e2f3a4b5c6d \
  -H "SYNTH_API_KEY: YOUR_API_KEY"
Response
{ "success": true, "message": "Audience deleted successfully" }

List audience members

GET/v1/audiences/{id}/membersread key

Returns 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

idstringrequired
The audience's UUID.

Query parameters

limitintegerdefault 50
Maximum results, from 1 to 100.
offsetintegerdefault 0
Number of results to skip, up to 1,000,000.

Members use the same fields as the contact object, with these differences:

  • tags isn't included. Call GET /v1/contacts/{id} to read a member's tags.
  • name, phone_numbers, emails and similar fields are returned as stored, so they aren't reformatted and can be null.

Returns 404 if the audience doesn't exist or belongs to another account. An id that isn't a valid UUID returns 400.

Request
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"
Response
{
  "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 }
}