client.audience service manages everything campaigns send to. Each kind is a sub-service:
Contacts
AudienceContactStatus (Subscribed, Unsubscribed, Bounced, Complained, Unverified), while updates use the narrower UpdateAudienceContactStatus (Subscribed, Unsubscribed).
API Reference
GET /audience/contacts
Double opt-in
Pass aDoubleOptInConfig to create the contact as unverified and send a confirmation email — they become subscribed after clicking the link:
Bulk create contacts
bulk_create() takes up to 1000 contacts per request in one of two shapes. BulkCreateAudienceContactsOptions::new() takes a flat list of addresses that all share the batch-wide lists, properties and topics:
::for_contacts() addresses each contact individually. Row-level list ids and topics are applied on top of the batch-wide ones, and a row’s property key overrides the batch-wide value for that key:
with_update_existing(false) is the default: existing contacts keep their properties (they are still attached to the requested lists). Pass true to merge properties — submitted keys overwrite, absent keys are preserved. It governs properties only: a row-level opt-out drops an existing subscription either way.
Handling the result
error_code is a BulkAudienceContactErrorCode: missing_email, invalid_email, invalid_property_value, unknown_property_key, unknown_list, unknown_topic, or invalid_topic_subscription.
already_existed 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.Bulk membership
result.contact_ids() from a bulk_create() feeds straight into the bulk membership calls, so no id lookup is needed in between:
contact_ids × topic_ids combination, up to 1000 contacts × 50 topics. Unsubscribing ignores pairs that don’t exist, so unsubscribed can be lower than total_pairs.
bulk_unsubscribe_from_topics() and bulk_detach_from_lists() issue a DELETE with a request body. reqwest handles that, but a proxy in front of your app may not.API Reference
POST /audience/contacts/bulk
Lists
API Reference
GET /audience/lists
Segments
A segment is a dynamic group defined by conditions. Groups are joined by OR; conditions within a group by AND.SegmentCondition::unary(field, op) for value-less operators like SegmentOperator::IsTrue and SegmentOperator::IsFalse.
API Reference
GET /audience/segments
Topics
API Reference
GET /audience/topics
Properties
Custom contact properties have an immutable name and type; only the fallback can be updated.API Reference
GET /audience/properties
What’s Next
Campaigns
Send to your audience
API Reference
Full audience API reference