Subscribers
Add, update and remove the subscribers of an audience.
Add a subscriber
Adds a contact to an audience by email address.
/audiences/{audience_id}/subscribersRequires a full API key. If no contact has this email yet, Emailit creates one. If the contact exists, the names and custom fields you send overwrite its current values. A contact that had unsubscribed from the audience is subscribed again and the response is 200; a contact that’s already subscribed returns 409.
Each audience can hold as many subscribers as your plan allows; past that, the request returns 422 with your usage. Fires subscriber.created, or subscriber.updated and subscriber.resubscribed for a resubscribe.
With double_opt_in, the person gets the audience’s double opt-in email and joins when they click it, so the response is 202 and no subscriber exists yet.
Path parameters
audience_idstringrequiredaud_…) or its name.Body parameters
emailstringrequiredfirst_namestringlast_namestringcustom_fieldsobjectCustom field values by key, such as {"company": "Analytical Engines"}. Replaces the contact’s existing custom fields.
double_opt_inbooleandefault: false422. A person who is already subscribed gets 409 as usual.send_confirmation_emailbooleandefault: falseReturns
Returns 201 with the subscriber object, or 200 when an unsubscribed contact was subscribed again. With double_opt_in, returns 202 with object: "subscriber_confirmation", status: "pending", audience_id, contact_id and email. If the double opt-in email can’t be sent, the request returns 422 with a code such as unverified_domain or insufficient_credits.
{
"object": "subscriber",
"id": "sub_4KECYl5AwXEy8ezswYRhuddttxo",
"audience_id": "aud_4KbFmQPy1feMCGAY8F8pAhiZ1u2",
"contact_id": "con_4K9kQdrXth7am0TPKvPrR5yd2oo",
"email": "ada@example.com",
"first_name": "Ada",
"last_name": "Lovelace",
"custom_fields": {
"company": "Analytical Engines"
},
"subscribed": true,
"subscribed_at": "2026-10-01T10:20:31.000000Z",
"unsubscribed_at": null,
"created_at": "2026-10-01T10:20:31.000000Z",
"updated_at": "2026-10-01T10:20:31.000000Z"
}{
"object": "subscriber_confirmation",
"status": "pending",
"audience_id": "aud_4KbFmQPy1feMCGAY8F8pAhiZ1u2",
"contact_id": "con_4K9kQdrXth7am0TPKvPrR5yd2oo",
"email": "ada@example.com",
"message": "A double opt-in email was sent. They join the audience when they click its link."
}{
"error": "Audience not found"
}{
"error": "Contact is already subscribed to this audience",
"existing": {
"object": "subscriber",
"id": "sub_4KECYl5AwXEy8ezswYRhuddttxo",
"audience_id": "aud_4KbFmQPy1feMCGAY8F8pAhiZ1u2",
"contact_id": "con_4K9kQdrXth7am0TPKvPrR5yd2oo",
"email": "ada@example.com",
"first_name": "Ada",
"last_name": "Lovelace",
"custom_fields": { "company": "Analytical Engines" },
"subscribed": true,
"subscribed_at": "2026-10-01T10:20:31.000Z",
"unsubscribed_at": null,
"created_at": "2026-10-01T10:20:31.000Z",
"updated_at": "2026-10-01T10:20:31.000Z"
}
}{
"error": "Pro includes 50,000 subscribers per audience.",
"usage": {
"used": 50000,
"limit": 50000,
"plan": "pro"
}
}Retrieve a subscriber
Retrieves a contact’s membership in an audience.
/audiences/{audience_id}/subscribers/{id}Requires a full API key. A subscriber links one contact to one audience. The email, names and custom fields belong to the contact, and subscribed belongs to this audience only.
Path parameters
audience_idstringrequiredaud_…) or its name.idstringrequiredsub_…) or the contact’s email address, URL-encoded.Returns
Returns the subscriber object.
objectstringsubscriber.idstringaudience_idstringcontact_idstringemailstringfirst_namestring | nulllast_namestring | nullcustom_fieldsobject | nullsubscribedbooleantrue if the contact is subscribed to this audience, false if they unsubscribed.subscribed_atstring | nullunsubscribed_atstring | nullnull.created_atstringupdated_atstring{
"object": "subscriber",
"id": "sub_4KECYl5AwXEy8ezswYRhuddttxo",
"audience_id": "aud_4KbFmQPy1feMCGAY8F8pAhiZ1u2",
"contact_id": "con_4K9kQdrXth7am0TPKvPrR5yd2oo",
"email": "ada@example.com",
"first_name": "Ada",
"last_name": "Lovelace",
"custom_fields": {
"company": "Analytical Engines"
},
"subscribed": true,
"subscribed_at": "2026-10-01T10:20:31.000000Z",
"unsubscribed_at": null,
"created_at": "2026-10-01T10:20:31.000000Z",
"updated_at": "2026-10-01T10:20:31.000000Z"
}{
"error": "Subscriber not found"
}Update a subscriber
Changes a subscriber’s status in the audience, or the details of its contact.
/audiences/{audience_id}/subscribers/{id}Requires a full API key. Send only the fields you want to change. subscribed applies to this audience only. email, first_name, last_name and custom_fields change the contact itself, so the change shows up in every audience the contact belongs to. Fires a subscriber.updated event.
Path parameters
audience_idstringrequiredaud_…) or its name.idstringrequiredsub_…) or the contact’s email address, URL-encoded.Body parameters
subscribedbooleanfalse to unsubscribe the contact from this audience, true to subscribe them again. The subscriber stays in the audience either way.emailstringfirst_namestringlast_namestringcustom_fieldsobjectReturns
Returns the updated subscriber object. A request without any of these fields returns 400.
curl -X POST https://api.emailit.com/v2/audiences/aud_4KbFmQPy1feMCGAY8F8pAhiZ1u2/subscribers/ada%40example.com \
-H "Authorization: Bearer $EMAILIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"subscribed": false}'{
"object": "subscriber",
"id": "sub_4KECYl5AwXEy8ezswYRhuddttxo",
"audience_id": "aud_4KbFmQPy1feMCGAY8F8pAhiZ1u2",
"contact_id": "con_4K9kQdrXth7am0TPKvPrR5yd2oo",
"email": "ada@example.com",
"first_name": "Ada",
"last_name": "Lovelace",
"custom_fields": {
"company": "Analytical Engines"
},
"subscribed": false,
"subscribed_at": "2026-10-01T10:20:31.000000Z",
"unsubscribed_at": "2026-10-02T08:14:55.000000Z",
"created_at": "2026-10-01T10:20:31.000000Z",
"updated_at": "2026-10-02T08:14:55.000000Z"
}{
"error": "No valid fields provided for update. Provide at least one of: email, first_name, last_name, custom_fields, subscribed"
}{
"error": "Subscriber not found"
}List subscribers
Returns a page of an audience’s subscribers, newest first.
/audiences/{audience_id}/subscribersRequires a full API key. The list includes contacts who unsubscribed from the audience unless you filter them out with subscribed=true.
Path parameters
audience_idstringrequiredaud_…) or its name.Query parameters
pageintegerdefault: 1limitintegerdefault: 25per_page works too.subscribedstringtrue for subscribed contacts only, false for unsubscribed ones only.engagementstringunengaged for subscribers who count as unengaged in the audience’s window, engaged for the rest. Combine with subscribed=true to leave out people who already unsubscribed.searchstringmatchstringdefault: allall or or. How the filters below combine.orderstringdirectionstringasc or desc.Filters
Add filters as key.condition=value, for example email.ends_with=@acme.com. See Filtering.
| Key | Type | Notes |
|---|---|---|
email |
string | |
first_name |
string | |
last_name |
string | |
subscribed |
boolean | |
subscribed_at |
date | When the subscription last started. |
last_engaged_at |
date | The contact’s latest open or click. Empty values sort last. |
created_at |
date | When the contact joined the audience. |
Every key is also a sort key.
Returns
dataobject[]last_opened_at, last_clicked_at and last_engaged_at (the contact’s latest open, click and either, or null) and unengaged.total_recordsintegernext_page_urlstring | nullnull. It keeps subscribed and engagement but not your other filters. See Pagination.previous_page_urlstring | nullnull.usageobjectused (subscribers in the audience), limit (the most your plan allows per audience, or null) and plan.curl -G https://api.emailit.com/v2/audiences/aud_4KbFmQPy1feMCGAY8F8pAhiZ1u2/subscribers \
-H "Authorization: Bearer $EMAILIT_API_KEY" \
-d subscribed=true \
-d limit=100{
"data": [
{
"object": "subscriber",
"id": "sub_4KECYl5AwXEy8ezswYRhuddttxo",
"audience_id": "aud_4KbFmQPy1feMCGAY8F8pAhiZ1u2",
"contact_id": "con_4K9kQdrXth7am0TPKvPrR5yd2oo",
"email": "ada@example.com",
"first_name": "Ada",
"last_name": "Lovelace",
"custom_fields": {
"company": "Analytical Engines"
},
"subscribed": true,
"subscribed_at": "2026-10-01T10:20:31.000000Z",
"unsubscribed_at": null,
"last_opened_at": "2026-10-06T08:14:02.000000Z",
"last_clicked_at": null,
"last_engaged_at": "2026-10-06T08:14:02.000000Z",
"unengaged": false,
"created_at": "2026-10-01T10:20:31.000000Z",
"updated_at": "2026-10-01T10:20:31.000000Z"
},
{
"object": "subscriber",
"id": "sub_4KnmYprkoMRytdkm3tAHIfPW0Vh",
"audience_id": "aud_4KbFmQPy1feMCGAY8F8pAhiZ1u2",
"contact_id": "con_4KiXIs4xLTcJIAHnKJaLcnMZYh7",
"email": "grace@example.com",
"first_name": "Grace",
"last_name": "Hopper",
"custom_fields": null,
"subscribed": false,
"subscribed_at": "2026-09-28T07:55:02.000000Z",
"unsubscribed_at": "2026-09-30T18:11:40.000000Z",
"last_opened_at": null,
"last_clicked_at": null,
"last_engaged_at": null,
"unengaged": false,
"created_at": "2026-09-28T07:55:02.000000Z",
"updated_at": "2026-09-30T18:11:40.000000Z"
}
],
"total_records": 2,
"next_page_url": null,
"previous_page_url": null,
"usage": {
"used": 2,
"limit": 50000,
"plan": "pro"
}
}{
"error": "Audience not found"
}Bulk update subscribers
Subscribes, unsubscribes or removes many subscribers of one audience.
/audiences/{audience_id}/subscribers/bulkRequires a full API key. Pick the subscribers by ids, or set all_matching to act on everyone matching the filters, up to 10,000 people. Each change fires the same event as changing one subscriber: subscriber.updated for subscribe and unsubscribe, subscriber.deleted for delete. Unsubscribing keeps people on the list with subscribed: false; deleting removes their membership and keeps the contacts. See Bulk actions.
Path parameters
audience_idstringrequiredaud_…) or its name.Body parameters
actionstringrequiredsubscribe, unsubscribe or delete.idsstring[]sub_…), up to 1,000. All must belong to the audience, or nothing changes and the request returns 404 with the missing IDs.all_matchingbooleandefault: falseids. More than 10,000 matches return 422.engagementstringsubscribedbooleanall_matching: only subscribed (true) or unsubscribed (false) people.searchstringall_matching: case-insensitive match on the email address, first name or last name.Returns
objectstringsubscriber_bulk.actionstringaudience_idstringprocessedintegerchangedinteger{
"object": "subscriber_bulk",
"action": "unsubscribe",
"audience_id": "aud_4KbFmQPy1feMCGAY8F8pAhiZ1u2",
"processed": 212,
"changed": 212
}{
"error": "One or more subscribers were not found",
"missing": ["sub_4KnmYprkoMRytdkm3tAHIfPW0Vh"]
}{
"error": "More than 10000 subscribers match. Narrow the filter and try again."
}Delete a subscriber
Removes a contact from an audience.
/audiences/{audience_id}/subscribers/{id}Requires a full API key. The contact itself isn’t deleted and stays in its other audiences. To keep a record that someone opted out, unsubscribe them with subscribed: false instead. Fires a subscriber.deleted event.
Path parameters
audience_idstringrequiredaud_…) or its name.idstringrequiredsub_…) or the contact’s email address, URL-encoded.Returns
objectstringsubscriber.idstringaudience_idstringcontact_idstringemailstringdeletedbooleantrue.{
"object": "subscriber",
"id": "sub_4KECYl5AwXEy8ezswYRhuddttxo",
"audience_id": "aud_4KbFmQPy1feMCGAY8F8pAhiZ1u2",
"contact_id": "con_4K9kQdrXth7am0TPKvPrR5yd2oo",
"email": "ada@example.com",
"deleted": true
}{
"error": "Subscriber not found"
}