Skip to Content
Segments

Segments

A segment is a saved filter over one audience. It’s live: membership is computed at read time, never stored, so there is nothing to refresh.

Target a campaign with one, or pass ?segment_id= when listing contacts.

The Segment object

{ "id": "seg_456m9x4v0dz1", "object": "segment", "name": "Pro-plan customers", "filter": { "match": "all", "conditions": [ { "field": "plan", "op": "equals", "value": "pro" }, { "field": "company", "op": "is_set" } ] }, "created_at": "2026-05-01T10:00:00.000Z", "updated_at": "2026-05-01T10:00:00.000Z" }

The filter contract

filter is the whole contract, and it’s stable.

KeyValues
match"all" or "any".
conditions1 to 10 conditions, each { field, op, value? }.

field is email, first_name, last_name, or any custom attribute key.

opTakes valueNotes
equalsYes
not_equalsYes
containsYesSubstring.
not_containsYes
is_setNoHas any non-empty value.
is_not_setNo
greater_thanYesNumeric comparison.
less_thanYesNumeric comparison.

Operators may be added, never removed.

value is always a JSON string, even for greater_than and less_than. Send "5", never 5: a bare number is 400 invalid_request. The comparison is still numeric, so "5" and "40" order correctly. A stored value that isn’t a number doesn’t match.

A missing attribute counts as empty, so plan not_equals pro includes contacts with no plan at all. Check that before targeting a send.

A filter rejected on write is 400 invalid_request, with param naming the exact path, such as filter.conditions.0.value. invalid_filter is the read side: a stored filter no longer parses, so listing its members fails instead of quietly matching everyone.

List segments

GET/v1/audiences/{audience_id}/segments

Create a segment

POST/v1/audiences/{audience_id}/segments
curl -X POST https://go.day3.app/api/v1/audiences/aud_123/segments \ -H "Authorization: Bearer $DAY3_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Pro customers", "filter": { "match": "all", "conditions": [ { "field": "plan", "op": "equals", "value": "pro" }, { "field": "company", "op": "is_set" } ] } }'
FieldTypeRequired
namestringYes
filterobjectYes

Retrieve a segment

GET/v1/audiences/{audience_id}/segments/{segment_id}

Update a segment

PATCH/v1/audiences/{audience_id}/segments/{segment_id}

name, filter, or both. A new filter replaces the old one whole. No merge.

Delete a segment

DELETE/v1/audiences/{audience_id}/segments/{segment_id}

Deletes the filter. Contacts are untouched.

List the members of a segment

GET/v1/audiences/{audience_id}/segments/{segment_id}/contacts

Current matches as Contact objects, paginated. Same as listing contacts with ?segment_id=seg_456.

curl "https://go.day3.app/api/v1/audiences/aud_123/segments/seg_456/contacts?limit=100" \ -H "Authorization: Bearer $DAY3_API_KEY"

Errors

StatusCodeCause
400invalid_requestThe filter failed validation on write. param names the path.
400invalid_filterA stored filter no longer parses, so its members can’t be listed.
Last updated on