Lettr::audience():
list() endpoints are paginated and return a response object exposing the data collection, a pagination object, and a hasMore() helper.
Contacts
A contact is an email address with optional custom properties, optionally attached to a list on creation.status is one of Subscribed, Unsubscribed, Bounced, Complained, or Unverified.
API Reference
GET /audience/contacts
Double opt-in
Pass aDoubleOptInConfig to create the contact as unverified and trigger a confirmation email — the contact becomes subscribed once they click the link.
Bulk create contacts
bulkCreate() takes up to 1000 contacts per request in one of two shapes. forEmails() builds the flat shape, where every address shares the batch-wide lists, properties and topics:
forContacts() addresses each contact individually. Row-level listIds and topics are applied on top of the batch-wide ones, and a row’s properties key overrides the batch-wide value for that key:
updateExisting defaults to false, which leaves existing contacts’ properties alone (they are still attached to the requested lists). Set it to true to merge properties — submitted keys overwrite, absent keys are preserved — and to let an opt-out drop an existing subscription.
Handling the result
$error->errorCode is a Lettr\Enums\BulkAudienceContactErrorCode (or a plain string for a code added server-side): missing_email, invalid_email, invalid_property_value, unknown_property_key, unknown_list, unknown_topic, or invalid_topic_subscription.
alreadyExisted and updated overlap by design — “was the address already in the audience?” versus “did this request change the contact?” — so they don’t sum to the row count. A contact that already existed and got attached to a list is counted in both.Membership
$result->contactIds() from a bulkCreate() feeds straight into the bulk membership calls, so no id lookup is needed in between:
unsubscribed can be lower than totalPairs.
API Reference
POST /audience/contacts/bulk
Lists
A list is a static collection of contacts.API Reference
GET /audience/lists
Segments
A segment is a dynamic group defined by conditions. Groups are joined by OR, and conditions within a group are joined by AND.SegmentOperator::IsTrue, SegmentOperator::IsFalse) report this via requiresValue().
API Reference
GET /audience/segments
Topics
Topics are subscription categories contacts can opt in or out of.API Reference
GET /audience/topics
Properties
Custom contact properties have an immutablename (must match ^[a-z][a-z0-9_]*$) and an immutable type. Only the fallback value can be updated.
API Reference
GET /audience/properties
What’s Next
Campaigns
Send to your audience
API Reference
Full audience API reference