SonarSend API Contacts & audience Lists & Segments

Lists & Segments

SonarSend uses the same broad audience system for static lists and dynamic segments.

In the external API:

  • lists are static segments
  • segments are rule-based dynamic audiences

Both are referenced with friendly keys instead of raw UUIDs.

Public identifier#

Use:

  • segment_key

In broadcast payloads, use:

  • include_segment_keys
  • exclude_segment_keys

Required scopes#

  • lists:read
  • lists:write
  • segments:read
  • segments:write

The scope needed depends on whether the object is a static list or a dynamic segment.

List all visible audiences#

GET /api/segments

For API-key callers, SonarSend filters the response by the key’s scopes:

  • a key with only lists:read sees static lists
  • a key with only segments:read sees dynamic segments
  • a key with both sees both

Get one list or segment#

GET /api/segments/:segment_key

Example:

GET /api/segments/vip-list

The response includes cached member counts and a count field for compatibility.

Create a dynamic segment#

POST /api/segments

A definition is a rule tree: a top-level { logic, conditions } where logic is and or or, and each condition carries a type that selects its shape (field, custom_field, event, subscription, segment, visit, page_view, activity, or a nested group). It is recursive — a group condition nests another { logic, conditions }.

Example — contacts who opened any email in the last 30 days:

{
  "name": "Openers last 30 days",
  "type": "dynamic",
  "definition": {
    "logic": "and",
    "conditions": [
      {
        "type": "event",
        "event_type": "email_opened",
        "frequency": "exists",
        "time_window": { "type": "relative", "direction": "within", "value": 30, "unit": "days" }
      }
    ]
  }
}

The definition is stored as sent and is not schema-validated on write, so a malformed tree is accepted here but fails when the segment is evaluated. Build it in the app once and copy the shape if you are unsure.

Required scope:

  • segments:write

Create a static list#

POST /api/segments

Example:

{
  "name": "VIP List",
  "type": "static"
}

Required scope:

  • lists:write

Update a list or segment#

PUT /api/segments/:segment_key

The allowed write scope depends on the target object:

  • static list -> lists:write
  • dynamic segment -> segments:write

Refresh counts#

POST /api/segments/:segment_key/refresh-count

Use this when you want SonarSend to recompute cached counts for a dynamic audience.

Create a segment from broadcast engagement#

POST /api/segments/from-broadcast

Example:

{
  "name": "Clicked April launch",
  "broadcast_id": "8b11b2d7-e546-4a0f-a959-c7c7796fdb10",
  "criterion": "clickers"
}

Returns the created segment, keyed by segment_key like every other segment response — use it as the path parameter on the endpoints above.

Required scope:

  • segments:write

Static list member operations#

These endpoints only apply to static lists.

Add members#

POST /api/segments/:segment_key/members

Example:

{
  "contact_ids": [
    "2ec8d707-7b2d-451f-b5ec-e4f041d2b844",
    "39de8127-0e65-4e72-b344-b9017608fe35"
  ]
}

Remove members#

DELETE /api/segments/:segment_key/members

List members#

GET /api/segments/:segment_key/members

Supported query parameters:

  • cursor
  • limit
  • search

Required scopes:

  • lists:write for add/remove
  • lists:read for list members

List membership check#

POST /api/segments/membership-check

Example:

{
  "contact_ids": [
    "2ec8d707-7b2d-451f-b5ec-e4f041d2b844"
  ]
}

This returns each contact’s static list memberships using segment_key.

Integration guidance#

  • Use segment keys in your own config instead of storing raw segment UUIDs.
  • Use static lists when your integration owns exact membership.
  • Use dynamic segments when SonarSend should evaluate rules over time.
  • Keep list membership operations separate from dynamic segment management in your integration logic.