Notix
Guides

Send to part of a contact book.

Build live segments from contact details, properties and email activity, then use them for campaigns, journeys and exports. Every endpoint named here is in the API reference.

A segment is a saved filter on one contact book, such as "subscribers on the Pro plan who opened an email in the last 30 days". Segments are live: Notix works out who matches each time you use one, so a contact who changes plan moves in or out without you rebuilding a list.

You can use a segment to:

  • Send a campaign to only the contacts who match it.
  • Limit a journey so it enrols only matching contacts, and optionally removes contacts who stop matching.
  • Filter and export the contact list in the console.
  • Read who matches through the API and the SDKs.

Build a segment in the console

  1. Open Contacts and choose a contact book.
  2. Switch to Segments and choose New segment.
  3. Give it a name, choose All or Any, and add conditions. Add group nests a set of conditions with its own All or Any, for rules like "on the Pro plan, and opened *or* clicked recently".
  4. Watch the live count and the preview of the first 25 matching contacts, then Save segment.

View contacts on a saved segment opens the contact list filtered to it, and Export downloads that filtered list as CSV.

The rule language

Through the API a segment is JSON. match is all or any, and conditions holds conditions or groups. A group is { "type": "group", "match": "all" | "any", "conditions": [...] } and cannot contain another group.

json
{
  "version": 1,
  "match": "all",
  "conditions": [
    { "type": "property", "key": "plan", "op": "equals", "value": "Pro" },
    {
      "type": "group",
      "match": "any",
      "conditions": [
        { "type": "email_activity", "event": "opened", "op": "in_last_days", "days": 30 },
        { "type": "email_activity", "event": "clicked", "op": "in_last_days", "days": 30 }
      ]
    }
  ]
}
ConditionOperatorsExample
emailequals, not_equals, contains, ends_with{ "type": "email", "op": "ends_with", "value": "@acme.com" }
first_name, last_nameequals, not_equals, contains, is_set, is_empty{ "type": "first_name", "op": "is_set" }
subscribedis{ "type": "subscribed", "op": "is", "value": true }
addedbefore, after (a date), in_last_days (a number of days){ "type": "added", "op": "in_last_days", "value": 14 }
propertyequals, not_equals, contains, is_set, is_empty, gt, gte, lt, lte{ "type": "property", "key": "seats", "op": "gte", "value": 10 }
email_activityever, never, in_last_days with days; event is received, opened or clicked; campaignId is optional{ "type": "email_activity", "event": "clicked", "campaignId": "cmp_123", "op": "ever" }
email_problemever, never; event is bounced or complained{ "type": "email_problem", "event": "bounced", "op": "never" }
journeyis_in, completed, exited, not_in{ "type": "journey", "journeyId": "jrn_123", "op": "completed" }

Text comparisons ignore case. A property condition must name a variable registered on the contact book (see Campaign personalisation); gt, gte, lt and lte compare numbers, and a contact whose value is not a number does not match. A campaign or journey a condition names must belong to your team, and a journey must use the same contact book.

Create a segment with the API

bash
curl -X POST https://app.usenotix.dev/api/v1/contactBooks/cb_123/segments \
  -H "Authorization: Bearer $NOTIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Engaged Pro users",
    "definition": {
      "version": 1,
      "match": "all",
      "conditions": [
        { "type": "property", "key": "plan", "op": "equals", "value": "Pro" },
        { "type": "email_activity", "event": "opened", "op": "in_last_days", "days": 30 }
      ]
    }
  }'

The same call with the Node.js SDK:

javascript
import { Notix } from "notix-js";

const notix = new Notix(process.env.NOTIX_API_KEY);

const { data: segment } = await notix.segments.create("cb_123", {
  name: "Engaged Pro users",
  definition: {
    version: 1,
    match: "all",
    conditions: [
      { type: "property", key: "plan", op: "equals", value: "Pro" },
      { type: "email_activity", event: "opened", op: "in_last_days", days: 30 },
    ],
  },
});

Read who matches with `GET /v1/contactBooks/{contactBookId}/segments/{segmentId}/contacts`, a page of up to 100 contacts at a time with a nextCursor and the total. The Python and PHP SDKs have the same segments resource.

Send a campaign to a segment

In the console, open a draft campaign and choose the segment under Send to. Through the API, pass segmentId when you create the campaign:

javascript
await notix.campaigns.create({
  name: "Pro tips",
  from: "hello@acme.com",
  subject: "Three things Pro users miss",
  contactBookId: "cb_123",
  segmentId: segment.id,
  html: '<p>Hi {{firstName}}</p><a href="{{notix_unsubscribe_url}}">Unsubscribe</a>',
});

When the send starts, Notix saves the list of subscribed contacts who match at that moment and sends to that list, so the campaign's total stays fixed while it runs. Pausing and resuming keep the list. Contacts who unsubscribe or are suppressed before their batch are still skipped.

Limit a journey to a segment

Open the journey, and under Trigger choose a Segment for its contact book. Only contacts who match when they are added are enrolled. Turn on Exit contacts who stop matching to check again before each email: a contact who no longer matches leaves the journey with the exit reason LEFT_SEGMENT, and a journey.exited webhook is sent.

Enrolling a contact who does not match through `POST /v1/journeys/{id}/enroll` answers 409 with the code NOT_IN_SEGMENT. Enrolling by email still adds the address to the contact book.

Limits and safety

  • A contact book holds at most 100 segments, and a segment at most 20 conditions, counting those inside groups.
  • A segment used by a scheduled or running campaign, or by an active, paused or held journey, cannot be deleted or have its conditions changed. The error names the campaign or journey. Renaming is always allowed.
  • If a segment uses a property you later remove from the contact book, it matches nobody and shows Needs fixing in the console, with the reason in problems in the API. Campaigns refuse to send to it, and journeys neither enrol nor remove anyone by it until you fix it.
  • A segment that takes longer than 10 seconds to evaluate answers 422 with a message asking you to narrow a time window or remove a condition.