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:
import lettr "github.com/lettr-com/lettr-go"

client := lettr.NewClient("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
Like the other services, every method takes a context.Context as its first argument.

Contacts

// Create (optionally attach to a list and set properties)
listID := "list-uuid"
contact, err := client.Audience.Contacts.Create(ctx, &lettr.CreateAudienceContactRequest{
    Email:      "jane@example.com",
    ListID:     &listID,
    Properties: map[string]string{"first_name": "Jane", "plan": "pro"},
})
fmt.Println(contact.Data.ID, contact.Data.Email, contact.Data.Status)

// List with filters
page, err := client.Audience.Contacts.List(ctx, &lettr.ListAudienceContactsParams{
    Page:    1,
    PerPage: 50,
    Search:  "jane",
    Status:  lettr.ContactStatusSubscribed,
    ListID:  "list-uuid",
})

// Get, update, delete
_, err = client.Audience.Contacts.Get(ctx, "contact-uuid")
_, err = client.Audience.Contacts.Update(ctx, "contact-uuid", &lettr.UpdateAudienceContactRequest{
    Status: lettr.ContactStatusUnsubscribed,
})
err = client.Audience.Contacts.Delete(ctx, "contact-uuid")
Contact status constants: ContactStatusSubscribed, ContactStatusUnsubscribed, ContactStatusBounced, ContactStatusComplained, ContactStatusUnverified.

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:
_, err = client.Audience.Contacts.Create(ctx, &lettr.CreateAudienceContactRequest{
    Email: "jane@example.com",
    DoubleOptIn: &lettr.DoubleOptInConfig{
        From:         "hello@example.com",
        Subject:      "Confirm your subscription",
        TemplateSlug: "email-confirmation",
        RedirectURL:  "https://example.com/confirmed",
    },
})

Bulk operations & membership

// Bulk create
listID := "list-uuid"
_, err = client.Audience.Contacts.BulkCreate(ctx, &lettr.BulkCreateAudienceContactsRequest{
    Emails: []string{"a@example.com", "b@example.com"},
    ListID: &listID,
})

// Single list / topic membership
_, err = client.Audience.Contacts.AttachToList(ctx, "contact-uuid", "list-uuid")
err = client.Audience.Contacts.DetachFromList(ctx, "contact-uuid", "list-uuid")
_, err = client.Audience.Contacts.SubscribeToTopic(ctx, "contact-uuid", "topic-uuid")
err = client.Audience.Contacts.UnsubscribeFromTopic(ctx, "contact-uuid", "topic-uuid")

// Bulk list membership (cartesian product of ContactIDs × ListIDs)
_, err = client.Audience.Contacts.BulkAttachToLists(ctx, &lettr.BulkContactsListsRequest{
    ContactIDs: []string{"c1", "c2"},
    ListIDs:    []string{"l1", "l2"},
})
_, err = client.Audience.Contacts.BulkDetachFromLists(ctx, &lettr.BulkContactsListsRequest{
    ContactIDs: []string{"c1"},
    ListIDs:    []string{"l1"},
})

Lists

list, err := client.Audience.Lists.Create(ctx, &lettr.CreateAudienceListRequest{Name: "Newsletter"})
fmt.Println(list.Data.ID, list.Data.Name, list.Data.ContactsCount)

_, err = client.Audience.Lists.Get(ctx, "list-uuid")
_, err = client.Audience.Lists.Update(ctx, "list-uuid", &lettr.UpdateAudienceListRequest{Name: "Weekly digest"})
err = client.Audience.Lists.Delete(ctx, "list-uuid")

// Bulk delete (takes a slice of IDs directly)
_, err = client.Audience.Lists.BulkDelete(ctx, []string{"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.
value := "@example.com"
plan := "pro"
_, err = client.Audience.Segments.Create(ctx, &lettr.CreateAudienceSegmentRequest{
    Name: "Pro users at example.com",
    Conditions: lettr.SegmentConditionsInput{
        Groups: []lettr.SegmentConditionGroup{
            {
                Conditions: []lettr.SegmentCondition{
                    {Field: "email", Operator: lettr.SegmentOperatorEndsWith, Value: &value},
                    {Field: "plan", Operator: lettr.SegmentOperatorEquals, Value: &plan},
                },
            },
        },
    },
})

_, err = client.Audience.Segments.Get(ctx, "segment-uuid")
err = client.Audience.Segments.Delete(ctx, "segment-uuid")
Operator constants include SegmentOperatorEquals, SegmentOperatorContains, SegmentOperatorEndsWith, SegmentOperatorIsTrue, and others.

API Reference

GET /audience/segments

Topics

_, err = client.Audience.Topics.Create(ctx, &lettr.CreateAudienceTopicRequest{
    Name:                "Product updates",
    DefaultSubscription: lettr.TopicDefaultSubscriptionOptIn,  // immutable after creation
    Visibility:          lettr.TopicVisibilityPublic,
})

_, err = client.Audience.Topics.Get(ctx, "topic-uuid")
err = client.Audience.Topics.Delete(ctx, "topic-uuid")

API Reference

GET /audience/topics

Properties

Custom contact properties have an immutable name and type; only the fallback can be updated.
_, err = client.Audience.Properties.Create(ctx, &lettr.CreateAudiencePropertyRequest{
    Name: "plan",
    Type: lettr.PropertyTypeString,  // String, Number, Boolean, Date, JSON
})

_, err = client.Audience.Properties.Get(ctx, "property-uuid")
err = client.Audience.Properties.Delete(ctx, "property-uuid")

API Reference

GET /audience/properties

What’s Next

Campaigns

Send to your audience

API Reference

Full audience API reference