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.campaigns() service gives you read access to campaigns plus lifecycle actions — send now, schedule, and unschedule. Campaigns are authored in the Lettr app; the API does not expose create, update, or delete. Reads require an API key with the campaigns:read scope; actions require campaigns:write.
import com.lettr.Lettr;
import com.lettr.services.campaigns.model.*;

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

List Campaigns

ListCampaignsResponse campaigns = lettr.campaigns().list();

// With filters
ListCampaignsResponse drafts = lettr.campaigns().list(
    ListCampaignsParams.builder()
        .status(CampaignStatus.DRAFT)
        .perPage(50)
        .build()
);

for (CampaignView c : drafts.getCampaigns()) {
    System.out.println(c.getName() + " - " + c.getStatus() + " (sent: " + c.getSentCount() + ")");
}
System.out.println("Page " + drafts.getPagination().getCurrentPage()
        + " of " + drafts.getPagination().getLastPage());

API Reference

GET /campaigns

Get a Campaign

get() returns CampaignDetail, which extends CampaignView and adds htmlContent. The action endpoints (send, schedule, unschedule) and list() return the base CampaignView, so they cannot accidentally expose HTML content.
CampaignDetail campaign = lettr.campaigns().get("0193e6a8-1f3a-7c2a-b9e2-1aa1d2e5d3f0");

System.out.println("Status: " + campaign.getStatus());
System.out.println("HTML: " + campaign.getHtmlContent());  // null for drafts with no rendered content yet

CampaignStats stats = campaign.getStats();
System.out.println("Opens: " + stats.getUniqueOpens() + " / Clicks: " + stats.getUniqueClicks());

API Reference

GET /campaigns/

List Campaign Events

Events use cursor-based pagination. Keep requesting with the returned cursor until it is null. A filtered page may come back with no events but a non-null cursor — that means more pages remain, so keep going.
String cursor = null;
do {
    ListCampaignEventsResponse page = lettr.campaigns().listEvents(
        campaign.getId(),
        ListCampaignEventsParams.builder()
            .eventType(CampaignEventType.CLICK)
            .startDate("2026-05-01")
            .limit(100)
            .cursor(cursor)
            .build()
    );

    for (CampaignEvent event : page.getEvents()) {
        System.out.println(event.getEventType() + " at " + event.getTimestamp()
                + " -> " + event.getTargetLinkUrl());
    }

    cursor = page.getNextCursor();
} while (cursor != null);

API Reference

GET /campaigns//events

Send / Schedule / Unschedule

// Immediately dispatches a draft; the campaign transitions to "preparing".
CampaignView sending = lettr.campaigns().send(campaign.getId());

// Schedule (or reschedule) for future delivery. Include a timezone offset.
CampaignView scheduled = lettr.campaigns().schedule(
    campaign.getId(),
    ScheduleCampaignOptions.of("2026-06-01T09:00:00+00:00")
);

// Cancel a scheduled send, returning the campaign to "draft".
CampaignView draft = lettr.campaigns().unschedule(campaign.getId());

Send

POST /campaigns//send

Schedule

POST /campaigns//schedule

Unschedule

POST /campaigns//unschedule

What’s Next

Audience

Manage the contacts campaigns send to

API Reference

Full campaigns API reference