Mailing lists & subscribers
Manage your audience: lists, the subscribers on them, segments, and custom fields. Paths are relative to https://app.blacklistguard.com/api/v1.
Lists
GET /mailing-lists
POST /mailing-lists
PUT /mailing-lists/{id}
DELETE /mailing-lists/{id}
GET /mailing-lists/stats?window=30
Create a list with:
| Field | Description |
|---|---|
name | List name. |
description | Optional description. |
from_name / from_email | Default sender for campaigns to this list. |
reply_to_email | Default reply-to. |
opt_in_type | Opt-in label for your reference: single, double, api, or import. |
stats returns per-list metrics over the window: new_subscribers, unsubscribed, net_growth, engagement_rate, bounce_rate, complaint_rate (rates are 0–1 fractions), health_score (0–100), a daily sparkline, and the last_campaign. Match each row to a list by id.
Subscribers (per list)
GET /mailing-lists/{id}/subscribers?page&limit&status&search
POST /mailing-lists/{id}/subscribers
PUT /mailing-lists/{id}/subscribers/{subscriber_id}
DELETE /mailing-lists/{id}/subscribers/{subscriber_id}
PUT /mailing-lists/{id}/subscribers/{subscriber_id}/status
DELETE /mailing-lists/{id}/subscribers/all
Add a subscriber with { email, first_name, last_name, source, custom_fields }. On update, email is not editable; you can change first_name, last_name, status, and custom_fields. status is one of active, unsubscribed, bounced, complained.
{subscriber_id} is the subscriber's UUID (not the membership row id), and each returned row's custom_fields is a JSON string — parse it before use.Import & export
POST /mailing-lists/{id}/subscribers/import-async (multipart, field "csvFile")
POST /mailing-lists/{id}/subscribers/export-async
Both run as background jobs and return a job_id — track progress via the jobs endpoints. The import CSV needs a header row with an Email column; First/Last/Status are optional and extra columns map to the list's defined custom fields.
Subscribers (workspace-wide)
GET /subscribers?page&limit&status&search&list_id
GET /subscribers/{id}
GET /subscribers/{id}/segments
Lists every subscriber across the workspace with a summary and pagination (here custom_fields is a JSON object). get(id) returns full detail: identity, the lists they're on, lifetime stats, an engagement score, recent activity, and their bounces.
Segments
GET /segments?page&limit&search&list_id
GET /mailing-lists/{id}/segments
POST /mailing-lists/{id}/segments
PUT /mailing-lists/{id}/segments/{segment_id}
DELETE /mailing-lists/{id}/segments/{segment_id}
POST /mailing-lists/{id}/segments/preview
GET /mailing-lists/{id}/segments/{segment_id}/subscribers
A segment is a saved filter on a list. Create one with { name, description, conditions, is_active }. conditions uses a recursive { logic, rules } shape — logic is "and" or "or", and each rule is either a condition { field, operator, value } or a nested group with the same { logic, rules } shape:
{
"logic": "and",
"rules": [
{ "field": "country", "operator": "equals", "value": "US" },
{ "logic": "or", "rules": [
{ "field": "plan", "operator": "equals", "value": "growth" },
{ "field": "plan", "operator": "equals", "value": "scale" }
] }
]
}
preview takes the same conditions and returns { subscriber_count } without saving. Note is_active defaults to false unless you set it.
Rule operators
| Operator | Value | Use for |
|---|---|---|
equals, not_equals, contains, starts_with, ends_with | string | Text fields |
greater_than, less_than, greater_than_or_equal, less_than_or_equal | number | Numeric fields |
before, after | date / datetime string | Date fields |
in_last_days, not_in_last_days | integer (days) | Date fields |
in | array of strings | Text / select |
is_one_of, is_not_one_of | array of strings | e.g. email-domain match |
ends_with_any_of, does_not_end_with_any_of | array of strings | Suffix match |
is, is_not | scalar | Status / boolean fields |
is_in, is_not_in | a segment id | Segment membership |
is_active_in, is_not_active_in | a mailing-list id | Active membership in a list |
Custom fields
GET /mailing-lists/{id}/custom-fields
POST /mailing-lists/{id}/custom-fields
PUT /mailing-lists/{id}/custom-fields/{field_id}
DELETE /mailing-lists/{id}/custom-fields/{field_id}
GET /custom-fields/global (workspace-wide fields)
Required: field_name, field_label, field_type. The field_name is normalized (lowercased, spaces become underscores) and locked once created. field_type is one of text, textarea, number, date, email, url, boolean, select, multiselect; for select and multiselect you must also supply field_options (a JSON array of choices). Optional: placeholder, default_value, help_text, validation_rules, is_required, is_active, display_order. Global fields apply to every list.