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 lettr.audience() service manages everything campaigns send to. Each kind is a sub-service:
import com.lettr.Lettr;

Lettr lettr = new Lettr("your-api-key");

lettr.audience().contacts();    // individual contacts
lettr.audience().lists();       // contact lists
lettr.audience().topics();      // subscription topics
lettr.audience().properties();  // custom contact properties
lettr.audience().segments();    // dynamic segments

Contacts

import com.lettr.services.audience.contacts.model.*;
import java.util.Map;

// Create (optionally attach to a list and set properties)
AudienceContactView contact = lettr.audience().contacts().create(
    CreateAudienceContactOptions.builder()
        .email("jane@example.com")
        .listId("list-uuid")
        .properties(Map.of("first_name", "Jane", "plan", "pro"))
        .build()
);
System.out.println(contact.getId() + " " + contact.getEmail() + " " + contact.getStatus());

// List with filters
ListAudienceContactsResponse page = lettr.audience().contacts().list(
    ListAudienceContactsParams.builder()
        .page(1)
        .perPage(50)
        .search("jane")
        .status(AudienceContactStatus.SUBSCRIBED)
        .listId("list-uuid")
        .build()
);

// Get, update, delete
lettr.audience().contacts().get("contact-uuid");
lettr.audience().contacts().update("contact-uuid",
    UpdateAudienceContactOptions.builder()
        .status(AudienceContactStatus.UNSUBSCRIBED)
        .properties(Map.of("plan", "enterprise"))
        .build()
);
lettr.audience().contacts().delete("contact-uuid");
Contact status values: SUBSCRIBED, UNSUBSCRIBED, BOUNCED, COMPLAINED, UNVERIFIED.

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:
lettr.audience().contacts().create(
    CreateAudienceContactOptions.builder()
        .email("jane@example.com")
        .doubleOptIn(DoubleOptInConfig.builder()
            .from("hello@example.com")
            .subject("Confirm your subscription")
            .templateSlug("email-confirmation")
            .redirectUrl("https://example.com/confirmed")
            .build())
        .build()
);

Bulk operations & membership

import java.util.List;

// Bulk create
lettr.audience().contacts().bulkCreate(
    BulkCreateAudienceContactsOptions.builder()
        .emails(List.of("a@example.com", "b@example.com"))
        .listId("list-uuid")
        .build()
);

// Single list / topic membership
lettr.audience().contacts().attachToList("contact-uuid", "list-uuid");
lettr.audience().contacts().detachFromList("contact-uuid", "list-uuid");
lettr.audience().contacts().subscribeToTopic("contact-uuid", "topic-uuid");
lettr.audience().contacts().unsubscribeFromTopic("contact-uuid", "topic-uuid");

// Bulk list membership (cartesian product of contactIds × listIds)
lettr.audience().contacts().bulkAttachToLists(
    BulkContactListsOptions.of(List.of("c1", "c2"), List.of("l1", "l2"))
);
lettr.audience().contacts().bulkDetachFromLists(
    BulkContactListsOptions.of(List.of("c1"), List.of("l1"))
);

Lists

import com.lettr.services.audience.lists.model.*;

AudienceListView list = lettr.audience().lists().create(
    CreateAudienceListOptions.of("Newsletter")
);
System.out.println(list.getId() + " " + list.getName() + " " + list.getContactsCount());

lettr.audience().lists().get("list-uuid");
lettr.audience().lists().update("list-uuid",
    UpdateAudienceListOptions.builder().name("Weekly digest").build());
lettr.audience().lists().delete("list-uuid");

// Bulk delete
lettr.audience().lists().bulkDelete(
    BulkDeleteAudienceListsOptions.of(List.of("l1", "l2"))
);

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. Build them with SegmentConditionsInput, SegmentConditionGroup, SegmentCondition, and the SegmentOperator enum.
import com.lettr.services.audience.segments.model.*;

lettr.audience().segments().create(
    CreateAudienceSegmentOptions.builder()
        .name("Pro users at example.com")
        .listId("list-uuid")  // optional: restrict to one list
        .conditions(SegmentConditionsInput.of(
            SegmentConditionGroup.of(
                SegmentCondition.of("email", SegmentOperator.ENDS_WITH, "@example.com"),
                SegmentCondition.of("plan", SegmentOperator.EQUALS, "pro")
            )
        ))
        .build()
);

lettr.audience().segments().get("segment-uuid");
lettr.audience().segments().delete("segment-uuid");

API Reference

GET /audience/segments

Topics

import com.lettr.services.audience.topics.model.*;

lettr.audience().topics().create(
    CreateAudienceTopicOptions.builder()
        .name("Product updates")
        .description("Occasional product news")
        .defaultSubscription(AudienceTopicDefaultSubscription.OPT_IN)  // immutable after creation
        .visibility(AudienceTopicVisibility.PUBLIC)
        .build()
);

lettr.audience().topics().get("topic-uuid");
lettr.audience().topics().delete("topic-uuid");

API Reference

GET /audience/topics

Properties

Custom contact properties have an immutable name and type; only the fallback can be updated.
import com.lettr.services.audience.properties.model.*;

lettr.audience().properties().create(
    CreateAudiencePropertyOptions.builder()
        .name("plan")
        .type(AudiencePropertyType.STRING)  // STRING | NUMBER | BOOLEAN | DATE | JSON
        .fallbackValue("free")
        .build()
);

lettr.audience().properties().get("property-uuid");
lettr.audience().properties().delete("property-uuid");

API Reference

GET /audience/properties

What’s Next

Campaigns

Send to your audience

API Reference

Full audience API reference