Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.lettr.com/llms.txt

Use this file to discover all available pages before exploring further.

The client.audience service manages everything campaigns send to. Each kind is a sub-service:
use lettr::Lettr;

let client = Lettr::new("your-api-key");

client.audience.contacts;    // individual contacts
client.audience.lists;       // contact lists
client.audience.topics;      // subscription topics
client.audience.properties;  // custom contact properties
client.audience.segments;    // dynamic segments

Contacts

use std::collections::HashMap;
use lettr::audience::contacts::{
    CreateAudienceContactOptions, ListAudienceContactsOptions, UpdateAudienceContactOptions,
    AudienceContactStatus, UpdateAudienceContactStatus,
};

// Create (optionally attach to a list and set properties)
let options = CreateAudienceContactOptions::new("jane@example.com")
    .with_list_id("list-uuid")
    .with_properties(HashMap::from([
        ("first_name".to_string(), "Jane".to_string()),
        ("plan".to_string(), "pro".to_string()),
    ]));
let contact = client.audience.contacts.create(options).await?;
println!("{} {} {:?}", contact.id, contact.email, contact.status);

// List with filters
let page = client.audience.contacts.list(
    ListAudienceContactsOptions::new()
        .page(1)
        .per_page(50)
        .search("jane")
        .status(AudienceContactStatus::Subscribed)
        .list_id("list-uuid"),
).await?;

// Get, update, delete
client.audience.contacts.get("contact-uuid").await?;
client.audience.contacts.update(
    "contact-uuid",
    UpdateAudienceContactOptions::new().with_status(UpdateAudienceContactStatus::Unsubscribed),
).await?;
client.audience.contacts.delete("contact-uuid").await?;
The list filter uses AudienceContactStatus (Subscribed, Unsubscribed, Bounced, Complained, Unverified), while updates use the narrower UpdateAudienceContactStatus (Subscribed, Unsubscribed).

API Reference

GET /audience/contacts

Double opt-in

Pass a DoubleOptInConfig to create the contact as unverified and send a confirmation email — they become subscribed after clicking the link:
use lettr::audience::contacts::{CreateAudienceContactOptions, DoubleOptInConfig};

let options = CreateAudienceContactOptions::new("jane@example.com")
    .with_double_opt_in(DoubleOptInConfig::new(
        "hello@example.com",
        "Confirm your subscription",
        "email-confirmation",
        "https://example.com/confirmed",
    ));
client.audience.contacts.create(options).await?;

Bulk operations & membership

use lettr::audience::contacts::{BulkCreateAudienceContactsOptions, BulkContactListMembershipOptions};

// Bulk create
client.audience.contacts.bulk_create(
    BulkCreateAudienceContactsOptions::new(vec![
        "a@example.com".to_string(),
        "b@example.com".to_string(),
    ]).with_list_id("list-uuid"),
).await?;

// Single list / topic membership
client.audience.contacts.attach_to_list("contact-uuid", "list-uuid").await?;
client.audience.contacts.detach_from_list("contact-uuid", "list-uuid").await?;
client.audience.contacts.subscribe_to_topic("contact-uuid", "topic-uuid").await?;
client.audience.contacts.unsubscribe_from_topic("contact-uuid", "topic-uuid").await?;

// Bulk list membership (cartesian product of contact_ids × list_ids)
let options = BulkContactListMembershipOptions::new()
    .with_contact_ids(vec!["c1".to_string(), "c2".to_string()])
    .with_list_ids(vec!["l1".to_string(), "l2".to_string()]);
client.audience.contacts.bulk_attach_to_lists(options).await?;

Lists

use lettr::audience::lists::{CreateAudienceListOptions, UpdateAudienceListOptions, BulkDeleteAudienceListsOptions};

let list = client.audience.lists.create(CreateAudienceListOptions::new("Newsletter")).await?;
println!("{} {} {}", list.id, list.name, list.contacts_count);

client.audience.lists.get("list-uuid").await?;
client.audience.lists.update(
    "list-uuid",
    UpdateAudienceListOptions::new().with_name("Weekly digest"),
).await?;
client.audience.lists.delete("list-uuid").await?;

// Bulk delete
client.audience.lists.bulk_delete(
    BulkDeleteAudienceListsOptions::new(vec!["l1".to_string(), "l2".to_string()]),
).await?;

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.
use lettr::audience::segments::{
    CreateAudienceSegmentOptions, SegmentConditionsInput, SegmentConditionGroup,
    SegmentCondition, SegmentOperator,
};

let conditions = SegmentConditionsInput::new(vec![
    SegmentConditionGroup::new(vec![
        SegmentCondition::new("email", SegmentOperator::EndsWith, "@example.com"),
        SegmentCondition::new("plan", SegmentOperator::Equals, "pro"),
    ]),
]);

client.audience.segments.create(
    CreateAudienceSegmentOptions::new("Pro users at example.com", conditions)
        .with_list_id("list-uuid"),
).await?;

client.audience.segments.get("segment-uuid").await?;
client.audience.segments.delete("segment-uuid").await?;
Use SegmentCondition::unary(field, op) for value-less operators like SegmentOperator::IsTrue and SegmentOperator::IsFalse.

API Reference

GET /audience/segments

Topics

use lettr::audience::topics::{CreateAudienceTopicOptions, AudienceTopicDefaultSubscription, AudienceTopicVisibility};

client.audience.topics.create(
    CreateAudienceTopicOptions::new("Product updates")
        .with_description("Occasional product news")
        .with_default_subscription(AudienceTopicDefaultSubscription::OptIn)  // immutable after creation
        .with_visibility(AudienceTopicVisibility::Public),
).await?;

client.audience.topics.get("topic-uuid").await?;
client.audience.topics.delete("topic-uuid").await?;

API Reference

GET /audience/topics

Properties

Custom contact properties have an immutable name and type; only the fallback can be updated.
use lettr::audience::properties::{CreateAudiencePropertyOptions, AudiencePropertyType};

client.audience.properties.create(
    CreateAudiencePropertyOptions::new("plan", AudiencePropertyType::String)  // String, Number, Boolean, Date, Json
        .with_fallback_value("free"),
).await?;

client.audience.properties.get("property-uuid").await?;
client.audience.properties.delete("property-uuid").await?;

API Reference

GET /audience/properties

What’s Next

Campaigns

Send to your audience

API Reference

Full audience API reference