Segments & topics
The segment filter format and segment routes, topics, subscriber import/export and bulk labels.
Segments
/api/v1/segments — saved filters you can send to (segmentId), leave out of a send (excludeSegmentId), or attach to an RSS feed or a recurring schedule. A segment's filters, and the inline filters / excludeFilters of a send, use one format:
{ "match": "all", // "all" = every rule must match (default), "any" = at least one
"rules": [
{ "field": "country", "op": "in", "value": ["IN", "US"] },
{ "field": "tag:plan", "op": "eq", "value": "pro" },
{ "field": "tag:vip", "op": "exists" }
] }| Part | Values |
|---|---|
field | country (the 2-letter upper-case code from the visitor's IP), language, url (the subscriber's last page), external_id (or externalId), or tag:KEY for one of your tags. An unknown field matches nobody (the rule fails closed, so a typo can't turn a targeted send into a send to everyone). |
op | eq (default; also used for an unknown op), neq, contains (case-insensitive), in (value is a list), exists, not_exists (no value needed). For a tag, neq also matches subscribers without that tag. |
value | Compared as text, exactly: eq, neq and in are case-sensitive (only contains ignores case), so write country codes in upper case, e.g. "IN". For country, language, url and external_id, neq doesn't match subscribers who have no value. |
| Request | What it does |
|---|---|
GET /api/v1/segments | { segments: [{ id, name, filters, created_at }] }, newest first. |
POST /api/v1/segments | Body { name, filters } → 201 { segment }. 400 name_required without a name. A segment needs at least one complete rule (a field — a tag: field with its key — and a value, unless the op is exists / not_exists): otherwise 400 segment_needs_a_rule, because a segment with no rules would include every subscriber. |
PUT /api/v1/segments/:id | Changes name and/or filters (the same rule check) → { segment }. 400 nothing_to_update when neither is sent; 404 not_found for another website's id. |
DELETE /api/v1/segments/:id | { ok: true }. While an enabled RSS feed, an enabled recurring schedule, or a scheduled or queued send uses it (to include or to exclude), it answers 409 { "error": "segment_in_use", "feeds", "schedules", "pending" } with how many of each. |
POST /api/v1/segments/preview | Body { filters, topicId? } → { count }: how many subscribed browsers match right now (a person on two devices counts twice), optionally within a topic (id or slug). |
GET /api/v1/audience/segments | Your saved segments with their size: { segments: [{ id, name, filters, created_at, count, lastUsedAt, sends, usedBy: { feeds, schedules } }] }. count is the same number /segments/preview gives. Needs subscribers:read. |
Writes need segments:write. A send that names a segment which isn't in this website is refused (400 segment_not_found), and one whose segment is deleted before it goes out ends failed with segment_missing — a missing segment never means "everyone".
Topics
/api/v1/topics — preference-center categories. GET lists { id, name, slug, created_at, subscribers }; POST { name, slug? } creates one (the slug is made from the name when left out; posting an existing slug renames that topic); PUT /:id { name } renames it (the slug never changes, since subscribers opt in by slug); DELETE /:id. Writes need settings:write. Subscribers opt in via RelayBell.setTopics(["slug"]) / showPreferences(); target a send with topicId (id or slug).
Subscribers
GET /api/v1/subscribers/export— CSV of subscribers.GET /api/v1/subscribers/recent?limit=25— the newest ones (up to 100).POST /api/v1/subscribers/import— body{ subscribers: [{ externalId, tags: { … }, topics: ["slug"] }] }(up to 10,000 rows) creates or enriches subscribers by external id →{ ok, processed }(400 no_subscribersfor an empty list). Push subscriptions themselves can't be imported: each browser must opt in on your site.GET /api/v1/subscribers/:externalId/profile— one person (by external id or relaybell id):{ subscriber, tags, endpoints, topics, sends, events, stats }, with their last 50 deliveries/clicks and events;/dataandDELETEare under Compliance.GET /api/v1/audience/subscribers— the dashboard's paged, filterable list;POST /api/v1/audience/subscribers/bulk-tag{ ids, set: { key: value }, remove: [key] }(at most 20 labels at a time;rb_keys are reserved) and/bulk-delete{ ids }→{ ok, deleted }.