> ## 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.

# Campaigns

> List, inspect, send now, schedule, and unschedule email campaigns with the Lettr Java SDK Campaigns service.

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`.

```java theme={null}
import com.lettr.Lettr;
import com.lettr.services.campaigns.model.*;

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

## List Campaigns

```java theme={null}
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());
```

<Card title="API Reference" icon="book" href="/api-reference/campaigns/list-campaigns">
  GET /campaigns
</Card>

## 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.

```java theme={null}
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());
```

<Card title="API Reference" icon="book" href="/api-reference/campaigns/show-a-campaign">
  GET /campaigns/{campaignId}
</Card>

## 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.

```java theme={null}
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);
```

<Card title="API Reference" icon="book" href="/api-reference/campaigns/list-campaign-engagement-events">
  GET /campaigns/{campaignId}/events
</Card>

## Send / Schedule / Unschedule

```java theme={null}
// 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());
```

<CardGroup cols={3}>
  <Card title="Send" icon="paper-plane" href="/api-reference/campaigns/send-a-campaign-now">
    POST /campaigns/{id}/send
  </Card>

  <Card title="Schedule" icon="clock" href="/api-reference/campaigns/schedule-a-campaign">
    POST /campaigns/{id}/schedule
  </Card>

  <Card title="Unschedule" icon="ban" href="/api-reference/campaigns/unschedule-a-campaign">
    POST /campaigns/{id}/unschedule
  </Card>
</CardGroup>

## What's Next

<CardGroup cols={2}>
  <Card title="Audience" icon="users" href="/quickstart/java/audience">
    Manage the contacts campaigns send to
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/campaigns/list-campaigns">
    Full campaigns API reference
  </Card>
</CardGroup>
