lettr

package module
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2026 License: MIT Imports: 11 Imported by: 0

README

lettr-go

The official Go SDK for the Lettr Email API. A typed client for emails, templates, domains, webhooks, audience, and campaigns.

Installation

go get github.com/lettr-com/lettr-go

Requires Go 1.21 or later.

Quick Start

package main

import (
	"context"
	"fmt"
	"log"

	lettr "github.com/lettr-com/lettr-go"
)

func main() {
	client := lettr.NewClient("your-api-key")

	resp, err := client.Emails.Send(context.Background(), &lettr.SendEmailRequest{
		From:    "sender@example.com",
		To:      []string{"recipient@example.com"},
		Subject: "Hello from Lettr",
		Html:    "<h1>Hello!</h1>",
	})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Email sent! Request ID: %s\n", resp.Data.RequestID)
}

Methods return a wrapped response (read resp.Data) and a structured error.

Error Handling

The SDK returns typed errors you can inspect with helper predicates:

resp, err := client.Emails.Send(ctx, req)
if err != nil {
	switch {
	case lettr.IsValidationError(err):
		apiErr := err.(*lettr.Error)
		for field, messages := range apiErr.Errors {
			fmt.Printf("%s: %v\n", field, messages)
		}
	case lettr.IsUnauthorized(err):
		fmt.Println("Invalid API key")
	case lettr.IsNotFound(err):
		fmt.Println("Resource not found")
	default:
		fmt.Printf("Error: %v\n", err)
	}
}

See Error Handling for the full set of predicates.

Documentation

Full guides for every service, with complete request/response details, live in the docs:

📚 docs.lettr.com/quickstart/go

Topic Guide
Install, client, sending Quickstart
Batch sending, context & timeouts, error handling Advanced
Manage Lettr templates & merge tags Templates
Add, verify, and manage sending domains Domains
Webhook endpoints for delivery & engagement events Webhooks
Lists, contacts, topics, properties, segments Audience
List, send, and schedule campaigns Campaigns
Endpoint reference (params & schemas) API Reference

Versioning & Releases

This project follows Semantic Versioning.

License

MIT

Documentation

Overview

Package lettr provides a Go client for the Lettr Email API.

Create a client with your API key, then use the service objects to interact with the API:

client := lettr.NewClient("your-api-key")
sent, err := client.Emails.Send(ctx, &lettr.SendEmailRequest{
    From:    "sender@example.com",
    To:      []string{"recipient@example.com"},
    Subject: "Hello from Lettr",
    Html:    "<h1>Hello!</h1>",
})

Index

Constants

View Source
const (
	ContactStatusSubscribed   = "subscribed"
	ContactStatusUnsubscribed = "unsubscribed"
	ContactStatusBounced      = "bounced"
	ContactStatusComplained   = "complained"
	ContactStatusUnverified   = "unverified"
)

Contact subscription status values returned by the API.

View Source
const (
	TopicOptIn  = "opt_in"
	TopicOptOut = "opt_out"
)

Topic subscription states for a write request. These say what a request should *do* with a topic, and are distinct from a topic's DefaultSubscription, which describes how the topic behaves for a contact that says nothing.

TopicOptOut also cancels the auto-subscription a topic whose default is opt-out would otherwise give a newly created contact, so a create and an unsubscribe fit in one request.

View Source
const (
	BulkContactErrorMissingEmail             = "missing_email"
	BulkContactErrorInvalidEmail             = "invalid_email"
	BulkContactErrorInvalidPropertyValue     = "invalid_property_value"
	BulkContactErrorUnknownPropertyKey       = "unknown_property_key"
	BulkContactErrorUnknownList              = "unknown_list"
	BulkContactErrorUnknownTopic             = "unknown_topic"
	BulkContactErrorInvalidTopicSubscription = "invalid_topic_subscription"
)

Reasons a single row was skipped during a bulk create. These are per-row codes reported inside a 201 body — not the top-level Error.ErrorCode of a failed request.

View Source
const (
	PropertyTypeString  = "string"
	PropertyTypeNumber  = "number"
	PropertyTypeBoolean = "boolean"
	PropertyTypeDate    = "date"
	PropertyTypeJSON    = "json"
)

Data-type values for audience properties.

View Source
const (
	SegmentOperatorContains           = "contains"
	SegmentOperatorNotContains        = "not_contains"
	SegmentOperatorEquals             = "equals"
	SegmentOperatorNotEquals          = "not_equals"
	SegmentOperatorStartsWith         = "starts_with"
	SegmentOperatorNotStartsWith      = "not_starts_with"
	SegmentOperatorEndsWith           = "ends_with"
	SegmentOperatorNotEndsWith        = "not_ends_with"
	SegmentOperatorIsTrue             = "is_true"
	SegmentOperatorIsFalse            = "is_false"
	SegmentOperatorGreaterThan        = "greater_than"
	SegmentOperatorGreaterThanOrEqual = "greater_than_or_equal"
	SegmentOperatorLessThan           = "less_than"
	SegmentOperatorLessThanOrEqual    = "less_than_or_equal"
	SegmentOperatorBefore             = "before"
	SegmentOperatorAfter              = "after"
)

Segment condition operator values.

View Source
const (
	TopicDefaultSubscriptionOptIn  = "opt_in"
	TopicDefaultSubscriptionOptOut = "opt_out"
)

Default-subscription values for audience topics.

View Source
const (
	TopicVisibilityPrivate = "private"
	TopicVisibilityPublic  = "public"
)

Visibility values for audience topics.

View Source
const (
	CampaignStatusDraft     = "draft"
	CampaignStatusScheduled = "scheduled"
	CampaignStatusPreparing = "preparing"
	CampaignStatusInReview  = "in_review"
	CampaignStatusSending   = "sending"
	CampaignStatusSent      = "sent"
	CampaignStatusFailed    = "failed"
)

Campaign status values.

View Source
const (
	CampaignEventTypeInjection       = "injection"
	CampaignEventTypeDelivery        = "delivery"
	CampaignEventTypeBounce          = "bounce"
	CampaignEventTypeSpamComplaint   = "spam_complaint"
	CampaignEventTypeOpen            = "open"
	CampaignEventTypeClick           = "click"
	CampaignEventTypeListUnsubscribe = "list_unsubscribe"
)

Campaign engagement event types.

View Source
const (
	EventMessageInjection       = "message.injection"
	EventMessageDelivery        = "message.delivery"
	EventMessageBounce          = "message.bounce"
	EventMessageDelay           = "message.delay"
	EventMessageOutOfBand       = "message.out_of_band"
	EventMessageSpamComplaint   = "message.spam_complaint"
	EventMessagePolicyRejection = "message.policy_rejection"

	EventEngagementClick          = "engagement.click"
	EventEngagementOpen           = "engagement.open"
	EventEngagementInitialOpen    = "engagement.initial_open"
	EventEngagementAmpClick       = "engagement.amp_click"
	EventEngagementAmpOpen        = "engagement.amp_open"
	EventEngagementAmpInitialOpen = "engagement.amp_initial_open"

	EventGenerationFailure   = "generation.generation_failure"
	EventGenerationRejection = "generation.generation_rejection"

	EventUnsubscribeList = "unsubscribe.list_unsubscribe"
	EventUnsubscribeLink = "unsubscribe.link_unsubscribe"

	EventRelayInjection = "relay.relay_injection"
	EventRelayRejection = "relay.relay_rejection"
	EventRelayDelivery  = "relay.relay_delivery"
	EventRelayTempfail  = "relay.relay_tempfail"
	EventRelayPermfail  = "relay.relay_permfail"
)

Webhook event-type constants. The Lettr API uses namespaced strings (e.g. "message.delivery") on both request and response sides.

View Source
const ErrorCodeResourceAlreadyExists = "resource_already_exists"

ErrorCodeResourceAlreadyExists is the machine-readable code the API sends when a create collides with an existing resource.

View Source
const (
	// Version is the current version of this SDK.
	Version = "1.4.0"
)

Variables

This section is empty.

Functions

func IsConflict added in v1.4.0

func IsConflict(err error) bool

IsConflict returns true if the error is a 409 Conflict error.

func IsContactAlreadyExists added in v1.4.0

func IsContactAlreadyExists(err error) bool

IsContactAlreadyExists returns true if the error is the 409 that AudienceContactService.Create returns when the email is already in the team's audience.

_, err := client.Audience.Contacts.Create(ctx, &lettr.CreateAudienceContactRequest{Email: email})
if lettr.IsContactAlreadyExists(err) {
	// Client-correctable: update the existing contact instead.
}

This is not a retryable failure. The API used to let a duplicate escape as an HTTP 500 with the misleading "send_error" code (it names email delivery, which is not involved here); a retry-on-5xx policy would retry it pointlessly. It is now a 409, and a 409 here must not be retried.

A 409 that carries no error code also counts, so the check still works against an API deployment that predates the change.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound returns true if the error is a 404 Not Found error.

func IsUnauthorized

func IsUnauthorized(err error) bool

IsUnauthorized returns true if the error is a 401 Unauthorized error.

func IsValidationError

func IsValidationError(err error) bool

IsValidationError returns true if the error is a 422 Validation Error.

Types

type AttachContactResponse added in v1.2.0

type AttachContactResponse struct {
	Message string `json:"message"`
}

AttachContactResponse is the response from attaching a contact to a list or subscribing a contact to a topic. The endpoint returns only a status message; no payload data is sent.

type Attachment

type Attachment struct {
	// Name is the filename of the attachment.
	Name string `json:"name"`

	// Type is the MIME type of the attachment (e.g. "application/pdf").
	Type string `json:"type"`

	// Data is the base64-encoded content of the attachment.
	Data string `json:"data"`
}

Attachment represents a file attachment on an email.

type AudienceContact added in v1.2.0

type AudienceContact struct {
	ID         string                     `json:"id"`
	Email      string                     `json:"email"`
	Status     string                     `json:"status"`
	Properties ContactProperties          `json:"properties"`
	CreatedAt  string                     `json:"created_at"`
	Lists      []AudienceContactListLink  `json:"lists"`
	Topics     []AudienceContactTopicLink `json:"topics"`
}

AudienceContact represents a contact in the team's audience.

type AudienceContactListLink struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

AudienceContactListLink is a short reference to a list the contact belongs to.

type AudienceContactResponse added in v1.2.0

type AudienceContactResponse struct {
	Message string          `json:"message"`
	Data    AudienceContact `json:"data"`
}

AudienceContactResponse is the response from endpoints that return a single contact (Create, Get, Update).

type AudienceContactService added in v1.2.0

type AudienceContactService struct {
	// contains filtered or unexported fields
}

AudienceContactService handles communication with the audience-contact endpoints of the Lettr API.

func (*AudienceContactService) AttachToList added in v1.2.0

func (s *AudienceContactService) AttachToList(ctx context.Context, contactID, listID string) (*AttachContactResponse, error)

AttachToList adds a contact to a list. Returns 201 when the contact is newly attached or 200 when the contact was already in the list.

func (*AudienceContactService) BulkAttachToLists added in v1.2.0

BulkAttachToLists attaches every combination of contact_ids × list_ids (up to 1000 contacts × 50 lists).

func (*AudienceContactService) BulkCreate added in v1.2.0

BulkCreate creates up to 1000 contacts in a single request.

Rows that fail validation are skipped, not fatal: the call still returns HTTP 201 and reports them in Data.Errors. A nil error does not mean every row landed — check Data.HasErrors.

func (*AudienceContactService) BulkDetachFromLists added in v1.2.0

BulkDetachFromLists detaches every combination of contact_ids × list_ids.

func (*AudienceContactService) BulkSubscribeToTopics added in v1.4.0

BulkSubscribeToTopics subscribes every combination of contact_ids × topic_ids (up to 1000 contacts × 50 topics).

Pass BulkCreateAudienceContactsData.ContactIDs from a bulk create — no ID lookup needed.

func (*AudienceContactService) BulkUnsubscribeFromTopics added in v1.4.0

BulkUnsubscribeFromTopics unsubscribes every combination of contact_ids × topic_ids. Pairs that do not exist are ignored.

This is a DELETE carrying a request body, as BulkDetachFromLists already is.

func (*AudienceContactService) Create added in v1.2.0

Create creates a single contact. When params.DoubleOptIn is set, the contact is created in "unverified" status and the confirmation email is sent.

An email already in the team's audience comes back as a 409 with error code "resource_already_exists" — use IsContactAlreadyExists to detect it. That is a client-correctable condition, not an outage: do not retry it. Update the existing contact with Update, or use BulkCreate with UpdateExisting set.

func (*AudienceContactService) Delete added in v1.2.0

func (s *AudienceContactService) Delete(ctx context.Context, contactID string) error

Delete permanently deletes a contact.

func (*AudienceContactService) DetachFromList added in v1.2.0

func (s *AudienceContactService) DetachFromList(ctx context.Context, contactID, listID string) error

DetachFromList removes a contact from a list. The operation is idempotent.

func (*AudienceContactService) Get added in v1.2.0

Get retrieves a single contact by ID.

func (*AudienceContactService) List added in v1.2.0

List retrieves a paginated, filterable list of audience contacts.

Pass nil for params to use defaults.

func (*AudienceContactService) SubscribeToTopic added in v1.2.0

func (s *AudienceContactService) SubscribeToTopic(ctx context.Context, contactID, topicID string) (*AttachContactResponse, error)

SubscribeToTopic subscribes a contact to a topic. Returns 201 when the subscription is newly created or 200 when it already existed.

func (*AudienceContactService) UnsubscribeFromTopic added in v1.2.0

func (s *AudienceContactService) UnsubscribeFromTopic(ctx context.Context, contactID, topicID string) error

UnsubscribeFromTopic removes a contact's subscription from a topic. The operation is idempotent.

func (*AudienceContactService) Update added in v1.2.0

Update partially updates a contact.

type AudienceContactTopicLink struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

AudienceContactTopicLink is a short reference to a topic the contact is subscribed to.

type AudienceList added in v1.2.0

type AudienceList struct {
	ID            string `json:"id"`
	Name          string `json:"name"`
	ContactsCount int    `json:"contacts_count"`
}

AudienceList represents an audience list.

type AudienceListResponse added in v1.2.0

type AudienceListResponse struct {
	Message string       `json:"message"`
	Data    AudienceList `json:"data"`
}

AudienceListResponse is the response from endpoints that return a single audience list (Create, Get, Update).

type AudienceListService added in v1.2.0

type AudienceListService struct {
	// contains filtered or unexported fields
}

AudienceListService handles communication with the audience-list endpoints of the Lettr API.

func (*AudienceListService) BulkDelete added in v1.2.0

BulkDelete deletes up to 50 audience lists in a single request.

func (*AudienceListService) Create added in v1.2.0

Create creates a new audience list.

func (*AudienceListService) Delete added in v1.2.0

func (s *AudienceListService) Delete(ctx context.Context, listID string) error

Delete permanently deletes an audience list.

func (*AudienceListService) Get added in v1.2.0

Get retrieves a single audience list by ID.

func (*AudienceListService) List added in v1.2.0

List retrieves a paginated list of audience lists.

Pass nil for params to use defaults.

func (*AudienceListService) Update added in v1.2.0

Update partially updates an audience list.

type AudienceProperty added in v1.2.0

type AudienceProperty struct {
	ID            string  `json:"id"`
	Name          string  `json:"name"`
	Type          string  `json:"type"`
	FallbackValue *string `json:"fallback_value"`
	CreatedAt     string  `json:"created_at"`
}

AudienceProperty represents a custom property definition that contacts can hold.

type AudiencePropertyResponse added in v1.2.0

type AudiencePropertyResponse struct {
	Message string           `json:"message"`
	Data    AudienceProperty `json:"data"`
}

AudiencePropertyResponse is the response from endpoints that return a single property.

type AudiencePropertyService added in v1.2.0

type AudiencePropertyService struct {
	// contains filtered or unexported fields
}

AudiencePropertyService handles communication with the audience-property endpoints of the Lettr API.

func (*AudiencePropertyService) Create added in v1.2.0

Create creates a new property definition.

func (*AudiencePropertyService) Delete added in v1.2.0

func (s *AudiencePropertyService) Delete(ctx context.Context, propertyID string) error

Delete permanently deletes a property definition.

func (*AudiencePropertyService) Get added in v1.2.0

Get retrieves a single property by ID.

func (*AudiencePropertyService) List added in v1.2.0

List retrieves a paginated list of property definitions.

Pass nil for params to use defaults.

func (*AudiencePropertyService) Update added in v1.2.0

Update updates a property's fallback value.

type AudienceSegment added in v1.2.0

type AudienceSegment struct {
	ID                  string                  `json:"id"`
	Name                string                  `json:"name"`
	ListID              *string                 `json:"list_id"`
	ListName            *string                 `json:"list_name"`
	ConditionGroups     []SegmentConditionGroup `json:"condition_groups"`
	CachedContactsCount *int                    `json:"cached_contacts_count"`
	CreatedAt           string                  `json:"created_at"`
}

AudienceSegment represents an audience segment.

type AudienceSegmentResponse added in v1.2.0

type AudienceSegmentResponse struct {
	Message string          `json:"message"`
	Data    AudienceSegment `json:"data"`
}

AudienceSegmentResponse is the response from endpoints that return a single segment.

type AudienceSegmentService added in v1.2.0

type AudienceSegmentService struct {
	// contains filtered or unexported fields
}

AudienceSegmentService handles communication with the audience-segment endpoints of the Lettr API.

func (*AudienceSegmentService) Create added in v1.2.0

Create creates a new segment.

func (*AudienceSegmentService) Delete added in v1.2.0

func (s *AudienceSegmentService) Delete(ctx context.Context, segmentID string) error

Delete permanently deletes a segment.

func (*AudienceSegmentService) Get added in v1.2.0

Get retrieves a single segment by ID.

func (*AudienceSegmentService) List added in v1.2.0

List retrieves a paginated list of segments.

Pass nil for params to use defaults.

func (*AudienceSegmentService) Update added in v1.2.0

Update partially updates a segment.

type AudienceService added in v1.2.0

type AudienceService struct {
	Lists      *AudienceListService
	Contacts   *AudienceContactService
	Topics     *AudienceTopicService
	Properties *AudiencePropertyService
	Segments   *AudienceSegmentService
}

AudienceService groups all audience-related operations under one namespace. The endpoint methods live on its sub-services: Lists, Contacts, Topics, Properties, and Segments.

Example:

lists, err := client.Audience.Lists.List(ctx, nil)
contact, err := client.Audience.Contacts.Get(ctx, "0193e6b0-9c1d-7d4f-a8f1-cef9a1b2d3e4")

type AudienceTopic added in v1.2.0

type AudienceTopic struct {
	ID                  string  `json:"id"`
	Name                string  `json:"name"`
	Description         *string `json:"description"`
	DefaultSubscription string  `json:"default_subscription"`
	Visibility          string  `json:"visibility"`
	ContactsCount       int     `json:"contacts_count"`
	CreatedAt           *string `json:"created_at"`
}

AudienceTopic represents a topic that contacts can subscribe to.

type AudienceTopicResponse added in v1.2.0

type AudienceTopicResponse struct {
	Message string        `json:"message"`
	Data    AudienceTopic `json:"data"`
}

AudienceTopicResponse is the response from endpoints that return a single topic.

type AudienceTopicService added in v1.2.0

type AudienceTopicService struct {
	// contains filtered or unexported fields
}

AudienceTopicService handles communication with the audience-topic endpoints of the Lettr API.

func (*AudienceTopicService) Create added in v1.2.0

Create creates a new topic.

func (*AudienceTopicService) Delete added in v1.2.0

func (s *AudienceTopicService) Delete(ctx context.Context, topicID string) error

Delete permanently deletes a topic.

func (*AudienceTopicService) Get added in v1.2.0

Get retrieves a single topic by ID.

func (*AudienceTopicService) List added in v1.2.0

List retrieves a paginated list of topics.

Pass nil for params to use defaults.

func (*AudienceTopicService) Update added in v1.2.0

Update partially updates a topic.

type AudienceTopicSubscription added in v1.4.0

type AudienceTopicSubscription struct {
	ID string `json:"id"`

	// Subscription is TopicOptIn or TopicOptOut. Empty means opt-in server-side.
	Subscription string `json:"subscription,omitempty"`
}

AudienceTopicSubscription is a topic and the subscription state to apply to it. Used batch-wide on BulkCreateAudienceContactsRequest and per row on BulkAudienceContactRow. A row-level opt-out wins over a batch-level opt-in for that contact.

Build them with SubscribeTopic / UnsubscribeTopic for readability at the call site.

func SubscribeTopic added in v1.4.0

func SubscribeTopic(topicID string) AudienceTopicSubscription

SubscribeTopic returns a subscription that opts the contact in to topicID.

func UnsubscribeTopic added in v1.4.0

func UnsubscribeTopic(topicID string) AudienceTopicSubscription

UnsubscribeTopic returns a subscription that opts the contact out of topicID, including a topic that would otherwise auto-subscribe new contacts.

type AuthCheckData

type AuthCheckData struct {
	TeamID    int    `json:"team_id"`
	Timestamp string `json:"timestamp"`
}

AuthCheckData contains the auth check details.

type AuthCheckResponse

type AuthCheckResponse struct {
	Message string        `json:"message"`
	Data    AuthCheckData `json:"data"`
}

AuthCheckResponse is the response from the auth check endpoint.

type BulkAttachContactsToListsData added in v1.2.0

type BulkAttachContactsToListsData struct {
	Attached        int `json:"attached"`
	AlreadyAttached int `json:"already_attached"`
	TotalPairs      int `json:"total_pairs"`
}

BulkAttachContactsToListsData holds the counts from a bulk-attach operation.

type BulkAttachContactsToListsResponse added in v1.2.0

type BulkAttachContactsToListsResponse struct {
	Message string                        `json:"message"`
	Data    BulkAttachContactsToListsData `json:"data"`
}

BulkAttachContactsToListsResponse is the response from bulk attach.

type BulkAudienceContactError added in v1.4.0

type BulkAudienceContactError struct {
	// Index is the zero-based position of the row in the submitted slice.
	Index int `json:"index"`

	Email string `json:"email"`

	// ErrorCode is one of the BulkContactError* constants. It is a plain string
	// so a code added server-side is still readable here.
	ErrorCode string `json:"error_code"`

	Error string `json:"error"`
}

BulkAudienceContactError is a row that was skipped during a bulk create.

type BulkAudienceContactRef added in v1.4.0

type BulkAudienceContactRef struct {
	ID    string `json:"id"`
	Email string `json:"email"`

	// Created is true when this request created the contact, false when it
	// already existed.
	Created bool `json:"created"`
}

BulkAudienceContactRef identifies a contact that exists after a bulk create, so a caller can chain into the bulk list and topic endpoints without a follow-up lookup.

type BulkAudienceContactRow added in v1.4.0

type BulkAudienceContactRow struct {
	Email string `json:"email"`

	// Properties keys must each match a property defined for the team.
	Properties map[string]string `json:"properties,omitempty"`

	// ListIDs is up to 50 list IDs for this row, on top of the batch-wide ones.
	ListIDs []string `json:"list_ids,omitempty"`

	// Topics is up to 50 topic subscriptions for this row.
	Topics []AudienceTopicSubscription `json:"topics,omitempty"`
}

BulkAudienceContactRow is one contact in a bulk-create payload.

ListIDs and Topics here are applied on top of the batch-wide ones on BulkCreateAudienceContactsRequest; a Properties key here overrides the batch-wide value for the same key.

A row that fails validation is skipped rather than failing the request — it comes back in BulkCreateAudienceContactsData.Errors.

type BulkContactsListsRequest added in v1.2.0

type BulkContactsListsRequest struct {
	// ContactIDs is 1-1000 contact IDs.
	ContactIDs []string `json:"contact_ids"`
	// ListIDs is 1-50 list IDs.
	ListIDs []string `json:"list_ids"`
}

BulkContactsListsRequest is the body for bulk attach/detach between contacts and lists. Every contact × list combination is processed.

type BulkContactsTopicsRequest added in v1.4.0

type BulkContactsTopicsRequest struct {
	// ContactIDs is 1-1000 contact IDs.
	ContactIDs []string `json:"contact_ids"`
	// TopicIDs is 1-50 topic IDs.
	TopicIDs []string `json:"topic_ids"`
}

BulkContactsTopicsRequest is the body for bulk subscribe/unsubscribe between contacts and topics. Every contact × topic combination is processed.

type BulkCreateAudienceContactsData added in v1.2.0

type BulkCreateAudienceContactsData struct {
	Created        int `json:"created"`
	AlreadyExisted int `json:"already_existed"`

	// Updated counts existing contacts this request changed — properties
	// merged, a list or topic attached, or a subscription dropped.
	Updated int `json:"updated"`

	// ErrorCount is the number of skipped rows.
	ErrorCount int `json:"error_count"`

	Errors []BulkAudienceContactError `json:"errors"`

	// Contacts lists every contact that exists after the request, in
	// submission order.
	Contacts []BulkAudienceContactRef `json:"contacts"`
}

BulkCreateAudienceContactsData holds the results of a bulk-create operation.

A bulk create can partially succeed: rows that fail validation are skipped and reported in Errors while the rest of the batch is written, and the call still returns HTTP 201. A nil error from BulkCreate therefore does not mean every row landed — check HasErrors.

AlreadyExisted and Updated overlap by design. They answer different questions ("was the address already in the audience?" vs "did this request change the contact?"), so they do not sum to the row count: a contact that already existed and got attached to a list is counted in both.

func (BulkCreateAudienceContactsData) ContactIDs added in v1.4.0

func (d BulkCreateAudienceContactsData) ContactIDs() []string

ContactIDs returns the IDs of every contact that exists after the request, in submission order — ready to pass to BulkAttachToLists or BulkSubscribeToTopics.

func (BulkCreateAudienceContactsData) HasErrors added in v1.4.0

func (d BulkCreateAudienceContactsData) HasErrors() bool

HasErrors reports whether any row was skipped. Always check this — a bulk create reports partial failures in the body, not in the HTTP status.

func (BulkCreateAudienceContactsData) IDFor added in v1.4.0

IDFor looks up the ID for a submitted address, reporting whether it was found. Matching is case-insensitive because the API normalizes addresses before storing them.

type BulkCreateAudienceContactsRequest added in v1.2.0

type BulkCreateAudienceContactsRequest struct {
	// Emails is 1-1000 email addresses. They are normalized and deduplicated
	// server-side. Leave nil when using Contacts.
	Emails []string `json:"emails,omitempty"`

	// ListID is a single batch-wide list, folded into ListIDs server-side.
	ListID *string `json:"list_id,omitempty"`

	// Properties applies to every contact in the batch; a row's own key wins.
	Properties map[string]string `json:"properties,omitempty"`

	// Contacts is 1-1000 rows. Alternative to Emails.
	Contacts []BulkAudienceContactRow `json:"contacts,omitempty"`

	// ListIDs is up to 50 batch-wide lists.
	ListIDs []string `json:"list_ids,omitempty"`

	// Topics is up to 50 batch-wide topic subscriptions.
	Topics []AudienceTopicSubscription `json:"topics,omitempty"`

	// UpdateExisting merges properties into contacts that already exist
	// (submitted keys overwrite, absent keys are preserved) and allows dropping
	// a subscription via an opt-out. Defaults to false, in which case existing
	// contacts keep their properties but are still attached to the requested
	// lists. Omitted from the payload when false, so a legacy request stays
	// byte-identical on the wire.
	UpdateExisting bool `json:"update_existing,omitempty"`
}

BulkCreateAudienceContactsRequest is the body for bulk-creating contacts.

Two shapes are supported, and exactly one of them must be filled in:

  • Emails — a flat list of addresses that all share the batch-wide ListID / ListIDs, Properties and Topics. The original shape, unchanged.
  • Contacts — one BulkAudienceContactRow per contact, each with its own properties, lists and topic subscriptions.

Batch-wide ListIDs and Topics are unioned into every row; a row-level property key or opt-out wins over the batch-wide value.

type BulkCreateAudienceContactsResponse added in v1.2.0

type BulkCreateAudienceContactsResponse struct {
	Message string                         `json:"message"`
	Data    BulkCreateAudienceContactsData `json:"data"`
}

BulkCreateAudienceContactsResponse is the response from a bulk create.

type BulkDeleteAudienceListsData added in v1.2.0

type BulkDeleteAudienceListsData struct {
	Deleted int `json:"deleted"`
}

BulkDeleteAudienceListsData holds the counts from a bulk-delete operation.

type BulkDeleteAudienceListsRequest added in v1.2.0

type BulkDeleteAudienceListsRequest struct {
	// ListIDs is 1-50 list IDs to delete.
	ListIDs []string `json:"list_ids"`
}

BulkDeleteAudienceListsRequest is the body for bulk-deleting audience lists.

type BulkDeleteAudienceListsResponse added in v1.2.0

type BulkDeleteAudienceListsResponse struct {
	Message string                      `json:"message"`
	Data    BulkDeleteAudienceListsData `json:"data"`
}

BulkDeleteAudienceListsResponse is the response from a bulk delete.

type BulkDetachContactsFromListsData added in v1.2.0

type BulkDetachContactsFromListsData struct {
	Detached   int `json:"detached"`
	NotPresent int `json:"not_present"`
	TotalPairs int `json:"total_pairs"`
}

BulkDetachContactsFromListsData holds the counts from a bulk-detach operation.

type BulkDetachContactsFromListsResponse added in v1.2.0

type BulkDetachContactsFromListsResponse struct {
	Message string                          `json:"message"`
	Data    BulkDetachContactsFromListsData `json:"data"`
}

BulkDetachContactsFromListsResponse is the response from bulk detach.

type BulkSubscribeContactsToTopicsData added in v1.4.0

type BulkSubscribeContactsToTopicsData struct {
	Subscribed        int `json:"subscribed"`
	AlreadySubscribed int `json:"already_subscribed"`
	TotalPairs        int `json:"total_pairs"`
}

BulkSubscribeContactsToTopicsData holds the counts from a bulk-subscribe operation.

type BulkSubscribeContactsToTopicsResponse added in v1.4.0

type BulkSubscribeContactsToTopicsResponse struct {
	Message string                            `json:"message"`
	Data    BulkSubscribeContactsToTopicsData `json:"data"`
}

BulkSubscribeContactsToTopicsResponse is the response from a bulk subscribe.

type BulkUnsubscribeContactsFromTopicsData added in v1.4.0

type BulkUnsubscribeContactsFromTopicsData struct {
	Unsubscribed int `json:"unsubscribed"`
	TotalPairs   int `json:"total_pairs"`
}

BulkUnsubscribeContactsFromTopicsData holds the counts from a bulk-unsubscribe operation. Pairs that did not exist are ignored, so Unsubscribed can be lower than TotalPairs.

type BulkUnsubscribeContactsFromTopicsResponse added in v1.4.0

type BulkUnsubscribeContactsFromTopicsResponse struct {
	Message string                                `json:"message"`
	Data    BulkUnsubscribeContactsFromTopicsData `json:"data"`
}

BulkUnsubscribeContactsFromTopicsResponse is the response from a bulk unsubscribe.

type Campaign added in v1.3.0

type Campaign struct {
	ID              string        `json:"id"`
	Name            string        `json:"name"`
	Subject         *string       `json:"subject"`
	FromEmail       *string       `json:"from_email"`
	FromName        *string       `json:"from_name"`
	ReplyTo         *string       `json:"reply_to"`
	Status          string        `json:"status"`
	ScheduledAt     *string       `json:"scheduled_at"`
	TotalRecipients *int          `json:"total_recipients"`
	SentCount       int           `json:"sent_count"`
	SentAt          *string       `json:"sent_at"`
	CreatedAt       string        `json:"created_at"`
	Stats           CampaignStats `json:"stats"`
}

Campaign is a campaign summary with embedded engagement stats. Nullable fields are represented as pointers.

type CampaignActionResponse added in v1.3.0

type CampaignActionResponse struct {
	Message string    `json:"message"`
	Data    *Campaign `json:"data"`
}

CampaignActionResponse is the response from the send, schedule, and unschedule actions. Data carries the updated campaign on success; it is nil in the rare case the campaign cannot be re-read immediately after the action (e.g. it was concurrently deleted), in which case the server omits the key.

type CampaignDetail added in v1.3.0

type CampaignDetail struct {
	Campaign
	HTMLContent *string `json:"html_content"`
}

CampaignDetail is the full campaign representation, extending Campaign with the rendered HTML content of the campaign email.

type CampaignEvent added in v1.3.0

type CampaignEvent struct {
	EventID   string `json:"event_id"`
	EventType string `json:"event_type"`
	Email     string `json:"email"`
	Timestamp string `json:"timestamp"`
	// BounceClass is the SparkPost bounce classification code, serialised as
	// a string by the campaigns API (note this differs from EmailEvent's *int
	// BounceClass — see emails.go — which is the same underlying code but
	// kept as the type the /emails/events endpoint emits).
	BounceClass   *string `json:"bounce_class"`
	Reason        *string `json:"reason"`
	TargetLinkURL *string `json:"target_link_url"`
	UserAgent     *string `json:"user_agent"`
}

CampaignEvent is a single campaign engagement event. Fields that only apply to certain event types are represented as pointers.

type CampaignResponse added in v1.3.0

type CampaignResponse struct {
	Message string         `json:"message"`
	Data    CampaignDetail `json:"data"`
}

CampaignResponse is the response from Get, returning a single campaign with its rendered HTML content.

type CampaignService added in v1.3.0

type CampaignService struct {
	// contains filtered or unexported fields
}

CampaignService handles communication with the campaign endpoints of the Lettr API.

func (*CampaignService) Get added in v1.3.0

func (s *CampaignService) Get(ctx context.Context, campaignID string) (*CampaignResponse, error)

Get retrieves a single campaign by ID, including its rendered HTML content.

func (*CampaignService) List added in v1.3.0

List retrieves a paginated list of campaigns with embedded engagement stats.

Pass nil for params to use defaults.

func (*CampaignService) ListEvents added in v1.3.0

ListEvents retrieves a page of engagement events (opens, clicks, bounces, etc.) for a campaign using cursor-based pagination.

Pass nil for params to use defaults.

func (*CampaignService) Schedule added in v1.3.0

func (s *CampaignService) Schedule(ctx context.Context, campaignID string, params *ScheduleCampaignRequest) (*CampaignActionResponse, error)

Schedule schedules a campaign for future delivery, or reschedules one that is already scheduled. The campaign is dispatched automatically at the given time. Not available to sandbox keys.

func (*CampaignService) Send added in v1.3.0

func (s *CampaignService) Send(ctx context.Context, campaignID string) (*CampaignActionResponse, error)

Send immediately dispatches a draft campaign. The campaign must have a subject, sender email, and content. Sending is asynchronous; the campaign transitions to the "preparing" status. Not available to sandbox keys.

func (*CampaignService) Unschedule added in v1.3.0

func (s *CampaignService) Unschedule(ctx context.Context, campaignID string) (*CampaignActionResponse, error)

Unschedule cancels a scheduled send and returns the campaign to the "draft" status. The campaign must currently be scheduled. Not available to sandbox keys.

type CampaignStats added in v1.3.0

type CampaignStats struct {
	Injections     int `json:"injections"`
	Deliveries     int `json:"deliveries"`
	Bounces        int `json:"bounces"`
	SpamComplaints int `json:"spam_complaints"`
	Opens          int `json:"opens"`
	UniqueOpens    int `json:"unique_opens"`
	Clicks         int `json:"clicks"`
	UniqueClicks   int `json:"unique_clicks"`
	Unsubscribes   int `json:"unsubscribes"`
}

CampaignStats holds aggregated engagement statistics for a campaign.

type CancelScheduledResponse added in v0.2.0

type CancelScheduledResponse struct {
	Message string `json:"message"`
}

CancelScheduledResponse is the response from cancelling a scheduled email.

type Client

type Client struct {

	// Services for different API resources.
	Emails    *EmailService
	Domains   *DomainService
	Webhooks  *WebhookService
	Templates *TemplateService
	Projects  *ProjectService
	Audience  *AudienceService
	Campaigns *CampaignService
	// contains filtered or unexported fields
}

Client manages communication with the Lettr API.

func NewClient

func NewClient(apiKey string) *Client

NewClient creates a new Lettr API client with the given API key. It uses a default HTTP client with a 30-second timeout.

func NewClientWithHTTPClient

func NewClientWithHTTPClient(apiKey string, httpClient *http.Client) *Client

NewClientWithHTTPClient creates a new Lettr API client with a custom HTTP client. This is useful for testing or for configuring custom timeouts and transports.

func (*Client) HealthCheck

func (c *Client) HealthCheck(ctx context.Context) (*HealthCheckResponse, error)

HealthCheck verifies that the Lettr API is reachable.

func (*Client) SetBaseURL

func (c *Client) SetBaseURL(rawURL string) error

SetBaseURL overrides the default base URL. Useful for testing against a mock server.

func (*Client) ValidateAPIKey

func (c *Client) ValidateAPIKey(ctx context.Context) (*AuthCheckResponse, error)

ValidateAPIKey checks whether the configured API key is valid and returns the associated team information.

type ContactProperties added in v1.2.0

type ContactProperties map[string]string

ContactProperties holds a contact's custom property key-value pairs. It is a map[string]string with a tolerant UnmarshalJSON: when the API returns an empty associative array as `[]` (a PHP/Laravel serialization quirk for empty maps), it decodes to an empty ContactProperties instead of erroring.

func (*ContactProperties) UnmarshalJSON added in v1.2.0

func (p *ContactProperties) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler. It accepts both a JSON object (`{...}`) and an empty JSON array (`[]`) for the empty-map case.

type CreateAudienceContactRequest added in v1.2.0

type CreateAudienceContactRequest struct {
	Email       string             `json:"email"`
	ListID      *string            `json:"list_id,omitempty"`
	Properties  map[string]string  `json:"properties,omitempty"`
	DoubleOptIn *DoubleOptInConfig `json:"double_opt_in,omitempty"`
}

CreateAudienceContactRequest is the body for creating a single contact.

type CreateAudienceListRequest added in v1.2.0

type CreateAudienceListRequest struct {
	// Name must be unique within the team (max 255 chars).
	Name string `json:"name"`
}

CreateAudienceListRequest is the body for creating an audience list.

type CreateAudiencePropertyRequest added in v1.2.0

type CreateAudiencePropertyRequest struct {
	Name          string  `json:"name"`
	Type          string  `json:"type"`
	FallbackValue *string `json:"fallback_value,omitempty"`
}

CreateAudiencePropertyRequest is the body for creating a property. Name must match the pattern ^[a-z][a-z0-9_]*$.

type CreateAudienceSegmentRequest added in v1.2.0

type CreateAudienceSegmentRequest struct {
	Name       string                 `json:"name"`
	ListID     *string                `json:"list_id,omitempty"`
	Conditions SegmentConditionsInput `json:"conditions"`
}

CreateAudienceSegmentRequest is the body for creating a segment.

type CreateAudienceTopicRequest added in v1.2.0

type CreateAudienceTopicRequest struct {
	Name string `json:"name"`
	// Description is optional. Set to a pointer to an empty string for empty,
	// or omit to leave unset.
	Description *string `json:"description,omitempty"`
	// DefaultSubscription defaults to "opt_in" server-side when omitted.
	DefaultSubscription string `json:"default_subscription,omitempty"`
	// Visibility defaults to "private" server-side when omitted.
	Visibility string `json:"visibility,omitempty"`
}

CreateAudienceTopicRequest is the body for creating a topic.

type CreateDomainData

type CreateDomainData struct {
	Domain      string      `json:"domain"`
	Status      string      `json:"status"`
	StatusLabel string      `json:"status_label"`
	DKIM        *DomainDKIM `json:"dkim"`
}

CreateDomainData contains the result of creating a domain.

type CreateDomainRequest

type CreateDomainRequest struct {
	// Domain is the domain name to register (e.g. "example.com").
	Domain string `json:"domain"`
}

CreateDomainRequest represents the request body for creating a domain.

type CreateDomainResponse

type CreateDomainResponse struct {
	Message string           `json:"message"`
	Data    CreateDomainData `json:"data"`
}

CreateDomainResponse is the response from creating a domain.

type CreateTemplateData

type CreateTemplateData struct {
	ID            int        `json:"id"`
	Name          string     `json:"name"`
	Slug          string     `json:"slug"`
	ProjectID     int        `json:"project_id"`
	FolderID      int        `json:"folder_id"`
	ActiveVersion int        `json:"active_version"`
	MergeTags     []MergeTag `json:"merge_tags"`
	CreatedAt     string     `json:"created_at"`
}

CreateTemplateData contains the result of creating a template.

type CreateTemplateRequest

type CreateTemplateRequest struct {
	// Name is the template name (required).
	Name string `json:"name"`

	// Html is the HTML content for the template. Mutually exclusive with Json.
	Html string `json:"html,omitempty"`

	// Json is the Topol editor JSON content. Mutually exclusive with Html.
	Json string `json:"json,omitempty"`

	// ProjectID specifies which project to create the template in.
	ProjectID *int `json:"project_id,omitempty"`

	// FolderID specifies which folder within the project.
	FolderID *int `json:"folder_id,omitempty"`
}

CreateTemplateRequest represents the request body for creating a template.

type CreateTemplateResponse

type CreateTemplateResponse struct {
	Message string             `json:"message"`
	Data    CreateTemplateData `json:"data"`
}

CreateTemplateResponse is the response from creating a template.

type CreateWebhookRequest added in v0.2.0

type CreateWebhookRequest struct {
	Name              string   `json:"name"`
	URL               string   `json:"url"`
	AuthType          string   `json:"auth_type"`
	AuthUsername      string   `json:"auth_username,omitempty"`
	AuthPassword      string   `json:"auth_password,omitempty"`
	OAuthClientID     string   `json:"oauth_client_id,omitempty"`
	OAuthClientSecret string   `json:"oauth_client_secret,omitempty"`
	OAuthTokenURL     string   `json:"oauth_token_url,omitempty"`
	EventsMode        string   `json:"events_mode"`
	Events            []string `json:"events,omitempty"`
}

CreateWebhookRequest represents the request body for creating a webhook.

type CreateWebhookResponse added in v0.2.0

type CreateWebhookResponse struct {
	Message string  `json:"message"`
	Data    Webhook `json:"data"`
}

CreateWebhookResponse is the response from creating a webhook.

type CursorPagination

type CursorPagination struct {
	NextCursor *string `json:"next_cursor"`
	PerPage    int     `json:"per_page"`
}

CursorPagination holds cursor-based pagination info.

type DeleteTemplateParams added in v0.2.0

type DeleteTemplateParams struct {
	// ProjectID is the project containing the template.
	ProjectID int
}

DeleteTemplateParams contains optional query parameters for deleting a template.

type DeleteTemplateResponse added in v0.2.0

type DeleteTemplateResponse struct {
	Message string `json:"message"`
}

DeleteTemplateResponse is the response from deleting a template.

type DeleteWebhookResponse added in v0.2.0

type DeleteWebhookResponse struct {
	Message string `json:"message"`
}

DeleteWebhookResponse is the response from deleting a webhook.

type DmarcValidationResult added in v0.2.0

type DmarcValidationResult struct {
	IsValid               bool    `json:"is_valid"`
	Status                string  `json:"status"`
	FoundAtDomain         *string `json:"found_at_domain"`
	Record                *string `json:"record"`
	Policy                *string `json:"policy"`
	SubdomainPolicy       *string `json:"subdomain_policy"`
	Error                 *string `json:"error"`
	CoveredByParentPolicy bool    `json:"covered_by_parent_policy"`
}

DmarcValidationResult contains DMARC validation details.

type DnsProviderInfo added in v0.2.0

type DnsProviderInfo struct {
	Provider      string   `json:"provider"`
	ProviderLabel string   `json:"provider_label"`
	Nameservers   []string `json:"nameservers"`
	Error         *string  `json:"error"`
}

DnsProviderInfo contains detected DNS provider information for a domain.

type Domain

type Domain struct {
	Domain      string  `json:"domain"`
	Status      string  `json:"status"`
	StatusLabel string  `json:"status_label"`
	CanSend     bool    `json:"can_send"`
	CnameStatus *string `json:"cname_status"`
	DkimStatus  *string `json:"dkim_status"`
	CreatedAt   string  `json:"created_at"`
	UpdatedAt   string  `json:"updated_at"`
}

Domain represents a sending domain.

type DomainDKIM

type DomainDKIM struct {
	Selector      string `json:"selector"`
	Public        string `json:"public"`
	Headers       string `json:"headers,omitempty"`
	SigningDomain string `json:"signing_domain,omitempty"`
}

DomainDKIM contains the DKIM DNS record details.

type DomainDNS

type DomainDNS struct {
	DKIM *DomainDKIM `json:"dkim"`
}

DomainDNS contains the DNS records for a domain.

type DomainDetail

type DomainDetail struct {
	Domain          string           `json:"domain"`
	Status          string           `json:"status"`
	StatusLabel     string           `json:"status_label"`
	CanSend         bool             `json:"can_send"`
	CnameStatus     *string          `json:"cname_status"`
	DkimStatus      *string          `json:"dkim_status"`
	SpfStatus       *string          `json:"spf_status"`
	DmarcStatus     *string          `json:"dmarc_status"`
	TrackingDomain  *string          `json:"tracking_domain"`
	DnsProvider     *DnsProviderInfo `json:"dns_provider"`
	IsPrimaryDomain bool             `json:"is_primary_domain"`
	DNS             *DomainDNS       `json:"dns"`
	CreatedAt       string           `json:"created_at"`
	UpdatedAt       string           `json:"updated_at"`
}

DomainDetail represents detailed information about a sending domain, including DNS records and tracking domain configuration.

type DomainDnsVerificationView added in v0.2.0

type DomainDnsVerificationView struct {
	SpfRecord   *string `json:"spf_record,omitempty"`
	SpfError    *string `json:"spf_error,omitempty"`
	DkimRecord  *string `json:"dkim_record,omitempty"`
	DkimError   *string `json:"dkim_error,omitempty"`
	CnameRecord *string `json:"cname_record,omitempty"`
	CnameError  *string `json:"cname_error,omitempty"`
	DmarcRecord *string `json:"dmarc_record,omitempty"`
	DmarcError  *string `json:"dmarc_error,omitempty"`
}

DomainDnsVerificationView contains DNS verification error details.

type DomainService

type DomainService struct {
	// contains filtered or unexported fields
}

DomainService handles communication with the domain-related endpoints of the Lettr API.

func (*DomainService) Create

Create registers a new sending domain with your account. The domain will start in a pending state until verified.

Example:

created, err := client.Domains.Create(ctx, &lettr.CreateDomainRequest{
    Domain: "example.com",
})

func (*DomainService) Delete

func (s *DomainService) Delete(ctx context.Context, domain string) error

Delete removes a sending domain. The domain will no longer be available for sending emails.

Example:

err := client.Domains.Delete(ctx, "example.com")

func (*DomainService) Get

func (s *DomainService) Get(ctx context.Context, domain string) (*GetDomainResponse, error)

Get retrieves details of a single sending domain including DNS records.

Example:

domain, err := client.Domains.Get(ctx, "example.com")

func (*DomainService) List

List retrieves all sending domains registered with your account.

Example:

domains, err := client.Domains.List(ctx)

func (*DomainService) Verify added in v0.2.0

func (s *DomainService) Verify(ctx context.Context, domain string) (*VerifyDomainResponse, error)

Verify triggers DNS record verification for a domain.

Example:

result, err := client.Domains.Verify(ctx, "example.com")

type DomainVerificationView added in v0.2.0

type DomainVerificationView struct {
	Domain            string                     `json:"domain"`
	DkimStatus        string                     `json:"dkim_status"`
	CnameStatus       string                     `json:"cname_status"`
	DmarcStatus       string                     `json:"dmarc_status"`
	SpfStatus         string                     `json:"spf_status"`
	IsPrimaryDomain   bool                       `json:"is_primary_domain"`
	OwnershipVerified *string                    `json:"ownership_verified"`
	Dmarc             *DmarcValidationResult     `json:"dmarc,omitempty"`
	Spf               *SpfValidationResult       `json:"spf,omitempty"`
	DNS               *DomainDnsVerificationView `json:"dns,omitempty"`
}

DomainVerificationView contains domain verification results.

type DoubleOptInConfig added in v1.2.0

type DoubleOptInConfig struct {
	From         string  `json:"from"`
	FromName     *string `json:"from_name,omitempty"`
	Subject      string  `json:"subject"`
	TemplateSlug string  `json:"template_slug"`
	RedirectURL  string  `json:"redirect_url"`
}

DoubleOptInConfig configures the confirmation email sent when a contact is created with double opt-in. When provided, the contact is created in "unverified" status until they click the confirmation link.

type EmailEvent

type EmailEvent struct {
	EventID               string  `json:"event_id"`
	Type                  string  `json:"type,omitempty"`
	Timestamp             string  `json:"timestamp"`
	RequestID             *string `json:"request_id"`
	MessageID             *string `json:"message_id"`
	Subject               *string `json:"subject"`
	FriendlyFrom          *string `json:"friendly_from"`
	SendingDomain         *string `json:"sending_domain"`
	RcptTo                *string `json:"rcpt_to"`
	RawRcptTo             *string `json:"raw_rcpt_to"`
	RecipientDomain       *string `json:"recipient_domain"`
	MailboxProvider       *string `json:"mailbox_provider"`
	MailboxProviderRegion *string `json:"mailbox_provider_region"`
	SendingIP             *string `json:"sending_ip"`
	ClickTracking         *bool   `json:"click_tracking"`
	OpenTracking          *bool   `json:"open_tracking"`
	Transactional         *bool   `json:"transactional"`
	MsgSize               *int    `json:"msg_size"`
	InjectionTime         *string `json:"injection_time"`
	Reason                *string `json:"reason"`
	RawReason             *string `json:"raw_reason"`
	ErrorCode             *string `json:"error_code"`
	BounceClass           *int    `json:"bounce_class,omitempty"`
	// RcptMeta is polymorphic per spec: an object (in /emails list items)
	// or an array (in event-stream payloads like /emails/events), or null.
	// Type-assert to map[string]interface{} or []interface{} as appropriate.
	RcptMeta        interface{}      `json:"rcpt_meta"`
	TemplateID      *string          `json:"template_id,omitempty"`
	TemplateVersion *string          `json:"template_version,omitempty"`
	DelvMethod      *string          `json:"delv_method,omitempty"`
	RecvMethod      *string          `json:"recv_method,omitempty"`
	RoutingDomain   *string          `json:"routing_domain,omitempty"`
	ScheduledTime   *string          `json:"scheduled_time,omitempty"`
	CampaignID      *string          `json:"campaign_id,omitempty"`
	AbTestID        *string          `json:"ab_test_id,omitempty"`
	AbTestVersion   *string          `json:"ab_test_version,omitempty"`
	AmpEnabled      *bool            `json:"amp_enabled,omitempty"`
	RcptType        *string          `json:"rcpt_type,omitempty"`
	RcptTags        []string         `json:"rcpt_tags,omitempty"`
	IpPool          *string          `json:"ip_pool,omitempty"`
	MsgFrom         *string          `json:"msg_from,omitempty"`
	QueueTime       *int             `json:"queue_time,omitempty"`
	OutboundTls     *string          `json:"outbound_tls,omitempty"`
	InitialPixel    *bool            `json:"initial_pixel,omitempty"`
	NumRetries      *int             `json:"num_retries,omitempty"`
	DeviceToken     *string          `json:"device_token,omitempty"`
	TargetLinkURL   *string          `json:"target_link_url,omitempty"`
	TargetLinkName  *string          `json:"target_link_name,omitempty"`
	UserAgent       *string          `json:"user_agent,omitempty"`
	UserAgentParsed *UserAgentParsed `json:"user_agent_parsed,omitempty"`
	GeoIp           *GeoIp           `json:"geo_ip,omitempty"`
	IpAddress       *string          `json:"ip_address,omitempty"`
}

EmailEvent represents a single event in an email's lifecycle (injection, delivery, bounce, open, click, etc).

type EmailService

type EmailService struct {
	// contains filtered or unexported fields
}

EmailService handles communication with the email-related endpoints of the Lettr API.

func (*EmailService) CancelScheduled added in v0.2.0

func (s *EmailService) CancelScheduled(ctx context.Context, transmissionID string) (*CancelScheduledResponse, error)

CancelScheduled cancels a pending scheduled email transmission.

Example:

resp, err := client.Emails.CancelScheduled(ctx, "transmission-123")

func (*EmailService) Get

func (s *EmailService) Get(ctx context.Context, requestID string, params *GetEmailParams) (*GetEmailResponse, error)

Get retrieves all events for a specific email by its request ID (the transmission ID returned when sending).

Example:

details, err := client.Emails.Get(ctx, "12345678901234567890", nil)

func (*EmailService) GetScheduled added in v0.2.0

func (s *EmailService) GetScheduled(ctx context.Context, transmissionID string) (*GetScheduledEmailResponse, error)

GetScheduled retrieves details of a scheduled email transmission.

Example:

scheduled, err := client.Emails.GetScheduled(ctx, "transmission-123")

func (*EmailService) List

List retrieves a paginated list of sent emails.

Pass nil for params to use defaults.

Example:

emails, err := client.Emails.List(ctx, &lettr.ListEmailsParams{
    PerPage: 10,
})

func (*EmailService) ListEvents added in v0.2.0

ListEvents retrieves email delivery events (opens, bounces, clicks, etc.) with optional filtering.

Pass nil for params to use defaults.

Example:

events, err := client.Emails.ListEvents(ctx, &lettr.ListEmailEventsParams{
    Events:  []string{"delivery", "bounce"},
    PerPage: 50,
})

func (*EmailService) Schedule added in v0.2.0

Schedule queues an email for future delivery.

Example:

resp, err := client.Emails.Schedule(ctx, &lettr.ScheduleEmailRequest{
    SendEmailRequest: lettr.SendEmailRequest{
        From:    "sender@example.com",
        To:      []string{"recipient@example.com"},
        Subject: "Scheduled Hello",
        Html:    "<h1>Hello!</h1>",
    },
    ScheduledAt: "2024-12-25T10:00:00Z",
})

func (*EmailService) Send

Send sends an email with the given parameters.

Example:

resp, err := client.Emails.Send(ctx, &lettr.SendEmailRequest{
    From:    "sender@example.com",
    To:      []string{"recipient@example.com"},
    Subject: "Hello from Lettr",
    Html:    "<h1>Hello!</h1>",
})

type Error

type Error struct {
	// StatusCode is the HTTP status code of the response.
	StatusCode int `json:"-"`

	// Message is a human-readable error message.
	Message string `json:"message"`

	// ErrorCode is a machine-readable error code (e.g. "validation_error", "not_found").
	ErrorCode string `json:"error_code,omitempty"`

	// Errors contains field-level validation errors (for 422 responses).
	Errors map[string][]string `json:"errors,omitempty"`
}

Error represents an error returned by the Lettr API.

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface.

func (*Error) UnmarshalJSON added in v1.2.0

func (e *Error) UnmarshalJSON(data []byte) error

UnmarshalJSON tolerates a PHP/Laravel serialization quirk where an empty associative array can come over the wire as `[]` instead of `{}`. For Error.Errors that means a 422 response with no field-level errors may carry `"errors": []`; without this tolerance the standard library would fail with "cannot unmarshal array into Go struct field … of type map[string][]string" and the SDK would surface a confusing decode error instead of the real 422.

type GeoIp added in v0.2.0

type GeoIp struct {
	Country    string  `json:"country,omitempty"`
	Region     string  `json:"region,omitempty"`
	City       string  `json:"city,omitempty"`
	PostalCode string  `json:"postal_code,omitempty"`
	Zip        string  `json:"zip,omitempty"`
	Latitude   float64 `json:"latitude,omitempty"`
	Longitude  float64 `json:"longitude,omitempty"`
}

GeoIp contains geolocation data derived from IP address of open/click events.

type GetDomainResponse

type GetDomainResponse struct {
	Message string       `json:"message"`
	Data    DomainDetail `json:"data"`
}

GetDomainResponse is the response from getting a single domain.

type GetEmailParams added in v0.2.0

type GetEmailParams struct {
	// From is the start date for event search range (ISO 8601). Defaults to 10 days ago.
	From string

	// To is the end date for event search range (ISO 8601). Defaults to now.
	To string
}

GetEmailParams contains optional query parameters for getting email details.

type GetEmailResponse

type GetEmailResponse struct {
	Message string                `json:"message"`
	Data    ScheduledTransmission `json:"data"`
}

GetEmailResponse is the response from getting email details. The data shape matches ShowScheduledTransmissionResponse — transmission metadata plus the full list of delivery events.

type GetMergeTagsData added in v0.2.0

type GetMergeTagsData struct {
	ProjectID    int        `json:"project_id"`
	TemplateSlug string     `json:"template_slug"`
	Version      int        `json:"version"`
	MergeTags    []MergeTag `json:"merge_tags"`
}

GetMergeTagsData contains merge tags for a template version.

type GetMergeTagsParams added in v0.2.0

type GetMergeTagsParams struct {
	// ProjectID is the project containing the template.
	ProjectID int

	// Version is the template version number. Uses active version if not set.
	Version int
}

GetMergeTagsParams contains optional query parameters for getting merge tags.

type GetMergeTagsResponse added in v0.2.0

type GetMergeTagsResponse struct {
	Message string           `json:"message"`
	Data    GetMergeTagsData `json:"data"`
}

GetMergeTagsResponse is the response from getting merge tags.

type GetScheduledEmailResponse added in v0.2.0

type GetScheduledEmailResponse struct {
	Message string                `json:"message"`
	Data    ScheduledTransmission `json:"data"`
}

GetScheduledEmailResponse is the response from getting a scheduled email.

type GetTemplateHtmlData added in v0.2.0

type GetTemplateHtmlData struct {
	Html      string         `json:"html"`
	MergeTags []HtmlMergeTag `json:"merge_tags"`
	Subject   *string        `json:"subject,omitempty"`
}

GetTemplateHtmlData contains the HTML content and merge tags of a template.

type GetTemplateHtmlParams added in v0.2.0

type GetTemplateHtmlParams struct {
	// ProjectID is the project containing the template (required).
	ProjectID int

	// Slug is the template slug identifier (required).
	Slug string
}

GetTemplateHtmlParams contains the query parameters for getting template HTML.

type GetTemplateHtmlResponse added in v0.2.0

type GetTemplateHtmlResponse struct {
	Success bool                `json:"success"`
	Data    GetTemplateHtmlData `json:"data"`
}

GetTemplateHtmlResponse is the response from getting template HTML.

type GetTemplateParams added in v0.2.0

type GetTemplateParams struct {
	// ProjectID is the project to look in. Uses team's default if not set.
	ProjectID int
}

GetTemplateParams contains optional query parameters for getting a template.

type GetTemplateResponse added in v0.2.0

type GetTemplateResponse struct {
	Message string         `json:"message"`
	Data    TemplateDetail `json:"data"`
}

GetTemplateResponse is the response from getting a single template.

type GetWebhookResponse

type GetWebhookResponse struct {
	Message string  `json:"message"`
	Data    Webhook `json:"data"`
}

GetWebhookResponse is the response from getting a single webhook.

type HealthCheckData

type HealthCheckData struct {
	Status    string `json:"status"`
	Timestamp string `json:"timestamp"`
}

HealthCheckData contains the health check status information.

type HealthCheckResponse

type HealthCheckResponse struct {
	Message string          `json:"message"`
	Data    HealthCheckData `json:"data"`
}

HealthCheckResponse is the response from the health check endpoint.

type HtmlMergeTag added in v0.2.0

type HtmlMergeTag struct {
	Key      string `json:"key"`
	Name     string `json:"name"`
	Required bool   `json:"required"`
}

HtmlMergeTag represents a merge tag in the template HTML response. This differs from MergeTag by including a Name field.

type ListAudienceContactsData added in v1.2.0

type ListAudienceContactsData struct {
	Contacts   []AudienceContact `json:"contacts"`
	Pagination PagePagination    `json:"pagination"`
}

ListAudienceContactsData contains the paginated list of contacts.

type ListAudienceContactsParams added in v1.2.0

type ListAudienceContactsParams struct {
	// PerPage is the number of results per page (1-100, default 20).
	PerPage int

	// Page is the page number (default 1).
	Page int

	// Search filters by email or contact name (max 255 chars).
	Search string

	// Status filters by contact status. Use the ContactStatus* constants.
	Status string

	// ListID filters to contacts in a specific list.
	ListID string

	// SegmentID filters to contacts matching a specific segment.
	SegmentID string
}

ListAudienceContactsParams contains the query parameters for listing contacts.

type ListAudienceContactsResponse added in v1.2.0

type ListAudienceContactsResponse struct {
	Message string                   `json:"message"`
	Data    ListAudienceContactsData `json:"data"`
}

ListAudienceContactsResponse is the response from listing audience contacts.

type ListAudienceListsData added in v1.2.0

type ListAudienceListsData struct {
	Lists      []AudienceList `json:"lists"`
	Pagination PagePagination `json:"pagination"`
}

ListAudienceListsData contains the paginated list of audience lists.

type ListAudienceListsParams added in v1.2.0

type ListAudienceListsParams struct {
	// PerPage is the number of results per page (1-100, default 20).
	PerPage int

	// Page is the page number (default 1).
	Page int
}

ListAudienceListsParams contains the query parameters for listing audience lists.

type ListAudienceListsResponse added in v1.2.0

type ListAudienceListsResponse struct {
	Message string                `json:"message"`
	Data    ListAudienceListsData `json:"data"`
}

ListAudienceListsResponse is the response from listing audience lists.

type ListAudiencePropertiesData added in v1.2.0

type ListAudiencePropertiesData struct {
	Properties []AudienceProperty `json:"properties"`
	Pagination PagePagination     `json:"pagination"`
}

ListAudiencePropertiesData contains the paginated list of properties.

type ListAudiencePropertiesParams added in v1.2.0

type ListAudiencePropertiesParams struct {
	PerPage int
	Page    int
}

ListAudiencePropertiesParams contains the query parameters for listing properties.

type ListAudiencePropertiesResponse added in v1.2.0

type ListAudiencePropertiesResponse struct {
	Message string                     `json:"message"`
	Data    ListAudiencePropertiesData `json:"data"`
}

ListAudiencePropertiesResponse is the response from listing properties.

type ListAudienceSegmentsData added in v1.2.0

type ListAudienceSegmentsData struct {
	Segments   []AudienceSegment `json:"segments"`
	Pagination PagePagination    `json:"pagination"`
}

ListAudienceSegmentsData contains the paginated list of segments.

type ListAudienceSegmentsParams added in v1.2.0

type ListAudienceSegmentsParams struct {
	PerPage int
	Page    int

	// ListID filters segments to those restricted to a specific list.
	ListID string
}

ListAudienceSegmentsParams contains the query parameters for listing segments.

type ListAudienceSegmentsResponse added in v1.2.0

type ListAudienceSegmentsResponse struct {
	Message string                   `json:"message"`
	Data    ListAudienceSegmentsData `json:"data"`
}

ListAudienceSegmentsResponse is the response from listing segments.

type ListAudienceTopicsData added in v1.2.0

type ListAudienceTopicsData struct {
	Topics     []AudienceTopic `json:"topics"`
	Pagination PagePagination  `json:"pagination"`
}

ListAudienceTopicsData contains the paginated list of topics.

type ListAudienceTopicsParams added in v1.2.0

type ListAudienceTopicsParams struct {
	PerPage int
	Page    int
}

ListAudienceTopicsParams contains the query parameters for listing topics.

type ListAudienceTopicsResponse added in v1.2.0

type ListAudienceTopicsResponse struct {
	Message string                 `json:"message"`
	Data    ListAudienceTopicsData `json:"data"`
}

ListAudienceTopicsResponse is the response from listing topics.

type ListCampaignEventsData added in v1.3.0

type ListCampaignEventsData struct {
	Events     []CampaignEvent `json:"events"`
	NextCursor *string         `json:"next_cursor"`
}

ListCampaignEventsData contains a page of campaign events. An empty Events slice together with a non-nil NextCursor means more pages exist; NextCursor is nil when there are no more events.

Note: this endpoint does not nest its cursor under a "pagination" envelope (and does not echo per_page) the way /emails/events does, so it cannot directly reuse CursorPagination — the wire shape genuinely differs.

type ListCampaignEventsParams added in v1.3.0

type ListCampaignEventsParams struct {
	// EventType filters by event type (e.g. CampaignEventTypeOpen). Optional.
	EventType string

	// Email filters events to a single recipient address. Optional.
	Email string

	// StartDate is the start of the date range (ISO 8601). A date-only value
	// is treated as the start of that day in UTC. Optional.
	StartDate string

	// EndDate is the end of the date range (ISO 8601). A date-only value
	// covers the whole day in UTC. Optional.
	EndDate string

	// Limit is the number of events per page (1-100, default 25).
	Limit int

	// Cursor is the pagination cursor returned as NextCursor by a prior call.
	Cursor string
}

ListCampaignEventsParams contains the query parameters for listing campaign engagement events.

type ListCampaignEventsResponse added in v1.3.0

type ListCampaignEventsResponse struct {
	Message string                 `json:"message"`
	Data    ListCampaignEventsData `json:"data"`
}

ListCampaignEventsResponse is the response from listing campaign events.

type ListCampaignsData added in v1.3.0

type ListCampaignsData struct {
	Campaigns  []Campaign     `json:"campaigns"`
	Pagination PagePagination `json:"pagination"`
}

ListCampaignsData contains the paginated list of campaigns.

type ListCampaignsParams added in v1.3.0

type ListCampaignsParams struct {
	// Page is the page number (default 1).
	Page int

	// PerPage is the number of results per page (1-100, default 20).
	PerPage int

	// Status filters by campaign status (e.g. CampaignStatusSent). Optional.
	Status string
}

ListCampaignsParams contains the query parameters for listing campaigns.

type ListCampaignsResponse added in v1.3.0

type ListCampaignsResponse struct {
	Message string            `json:"message"`
	Data    ListCampaignsData `json:"data"`
}

ListCampaignsResponse is the response from listing campaigns.

type ListDomainsData

type ListDomainsData struct {
	Domains []Domain `json:"domains"`
}

ListDomainsData contains the list of domains.

type ListDomainsResponse

type ListDomainsResponse struct {
	Message string          `json:"message"`
	Data    ListDomainsData `json:"data"`
}

ListDomainsResponse is the response from listing domains.

type ListEmailEventsData added in v0.2.0

type ListEmailEventsData struct {
	Events ListEmailEventsEvents `json:"events"`
}

ListEmailEventsData wraps the paginated email events returned by the API.

type ListEmailEventsEvents added in v0.2.0

type ListEmailEventsEvents struct {
	Data       []EmailEvent     `json:"data"`
	TotalCount int              `json:"total_count"`
	From       string           `json:"from"`
	To         string           `json:"to"`
	Pagination CursorPagination `json:"pagination"`
}

ListEmailEventsEvents contains the paginated list of email events plus the query date range echoed back by the API.

type ListEmailEventsParams added in v0.2.0

type ListEmailEventsParams struct {
	// Events filters by event types (e.g. "delivery", "bounce", "open", "click").
	Events []string

	// Recipients filters by recipient email addresses.
	Recipients []string

	// Transmissions filters by transmission ID.
	Transmissions string

	// BounceClasses filters by bounce classification codes.
	BounceClasses []int

	// From is the start date for events (ISO 8601). Defaults to 10 days ago.
	From string

	// To is the end date for events (ISO 8601). Defaults to now.
	To string

	// PerPage is the number of events per page.
	PerPage int

	// Cursor is the pagination cursor from a previous response.
	Cursor string
}

ListEmailEventsParams contains the query parameters for listing email events.

type ListEmailEventsResponse added in v0.2.0

type ListEmailEventsResponse struct {
	Message string              `json:"message"`
	Data    ListEmailEventsData `json:"data"`
}

ListEmailEventsResponse is the response from listing email events.

type ListEmailsData

type ListEmailsData struct {
	Events ListEmailsEvents `json:"events"`
}

ListEmailsData wraps the paginated email events returned by the API.

type ListEmailsEvents added in v0.2.0

type ListEmailsEvents struct {
	Data       []EmailEvent     `json:"data"`
	TotalCount int              `json:"total_count"`
	From       string           `json:"from"`
	To         string           `json:"to"`
	Pagination CursorPagination `json:"pagination"`
}

ListEmailsEvents contains the paginated list of email events plus the query date range echoed back by the API.

type ListEmailsParams

type ListEmailsParams struct {
	// PerPage is the number of results per page (1-100, default 25).
	PerPage int

	// Cursor is the pagination cursor from a previous response.
	Cursor string

	// Recipients filters by recipient email address.
	Recipients string

	// From filters emails sent on or after this date (ISO 8601, e.g. "2024-01-15").
	From string

	// To filters emails sent on or before this date (ISO 8601, e.g. "2024-01-31").
	To string
}

ListEmailsParams contains the query parameters for listing emails.

type ListEmailsResponse

type ListEmailsResponse struct {
	Message string         `json:"message"`
	Data    ListEmailsData `json:"data"`
}

ListEmailsResponse is the response from listing emails.

type ListProjectsData added in v0.2.0

type ListProjectsData struct {
	Projects   []Project      `json:"projects"`
	Pagination PagePagination `json:"pagination"`
}

ListProjectsData contains the paginated list of projects.

type ListProjectsParams added in v0.2.0

type ListProjectsParams struct {
	// PerPage is the number of results per page (1-100, default 25).
	PerPage int

	// Page is the page number (default 1).
	Page int
}

ListProjectsParams contains the query parameters for listing projects.

type ListProjectsResponse added in v0.2.0

type ListProjectsResponse struct {
	Message string           `json:"message"`
	Data    ListProjectsData `json:"data"`
}

ListProjectsResponse is the response from listing projects.

type ListTemplatesData

type ListTemplatesData struct {
	Templates  []Template     `json:"templates"`
	Pagination PagePagination `json:"pagination"`
}

ListTemplatesData contains the paginated list of templates.

type ListTemplatesParams

type ListTemplatesParams struct {
	// ProjectID is the project to retrieve templates from. Uses the team's
	// default project if not set.
	ProjectID int

	// PerPage is the number of results per page (1-100, default 25).
	PerPage int

	// Page is the page number (default 1).
	Page int
}

ListTemplatesParams contains the query parameters for listing templates.

type ListTemplatesResponse

type ListTemplatesResponse struct {
	Message string            `json:"message"`
	Data    ListTemplatesData `json:"data"`
}

ListTemplatesResponse is the response from listing templates.

type ListWebhooksData

type ListWebhooksData struct {
	Webhooks []Webhook `json:"webhooks"`
}

ListWebhooksData contains the list of webhooks.

type ListWebhooksResponse

type ListWebhooksResponse struct {
	Message string           `json:"message"`
	Data    ListWebhooksData `json:"data"`
}

ListWebhooksResponse is the response from listing webhooks.

type MergeTag

type MergeTag struct {
	Key      string          `json:"key"`
	Required bool            `json:"required"`
	Type     string          `json:"type,omitempty"`
	Children []MergeTagChild `json:"children,omitempty"`
}

MergeTag represents a merge tag extracted from template content.

type MergeTagChild added in v0.2.0

type MergeTagChild struct {
	Key  string `json:"key"`
	Type string `json:"type,omitempty"`
}

MergeTagChild represents a child merge tag within a loop block.

type NullString added in v1.2.0

type NullString struct {
	String string
	// Valid indicates whether String is the value to send. When false, the
	// NullString marshals to JSON null regardless of String.
	Valid bool
}

NullString lets PATCH callers distinguish three intents for a nullable string field on the wire. Field names and zero-value semantics mirror database/sql's NullString: the zero value is null.

  • nil *NullString → omit the field entirely (server keeps the existing value)
  • &NullString{} → send JSON null (server clears the field)
  • &NullString{Valid: true, String: "x"} → send the JSON string "x" (use NewNullString as shorthand)

Plain Go *string + ,omitempty cannot represent the three states because the json package treats a nil pointer the same as a missing field. NullString fills that gap for the audience PATCH endpoints where the API distinguishes "field omitted" (no change) from "field is null" (clear).

func NewNullString added in v1.2.0

func NewNullString(s string) *NullString

NewNullString returns a NullString that marshals to the given JSON string. It is shorthand for &NullString{Valid: true, String: s}.

func (*NullString) MarshalJSON added in v1.2.0

func (n *NullString) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

type PagePagination

type PagePagination struct {
	Total       int `json:"total"`
	PerPage     int `json:"per_page"`
	CurrentPage int `json:"current_page"`
	LastPage    int `json:"last_page"`
}

PagePagination holds page-based pagination info.

type Project added in v0.2.0

type Project struct {
	ID        int     `json:"id"`
	Name      string  `json:"name"`
	TeamID    int     `json:"team_id"`
	CreatedAt string  `json:"created_at"`
	UpdatedAt string  `json:"updated_at"`
	Emoji     *string `json:"emoji"`
}

Project represents a project.

type ProjectService added in v0.2.0

type ProjectService struct {
	// contains filtered or unexported fields
}

ProjectService handles communication with the project-related endpoints of the Lettr API.

func (*ProjectService) List added in v0.2.0

List retrieves a paginated list of projects associated with the team.

Pass nil for params to use defaults.

Example:

projects, err := client.Projects.List(ctx, nil)

type ScheduleCampaignRequest added in v1.3.0

type ScheduleCampaignRequest struct {
	// ScheduledAt is the future delivery time (ISO 8601). Include a timezone
	// offset (e.g. "+02:00" or "Z"); a value without an offset is interpreted
	// as UTC. Must be in the future.
	ScheduledAt string `json:"scheduled_at"`
}

ScheduleCampaignRequest is the body for scheduling a campaign.

type ScheduleEmailData added in v0.2.0

type ScheduleEmailData struct {
	// RequestID is the unique transmission ID for the scheduled email.
	RequestID string `json:"request_id"`

	// Accepted is the number of recipients that were accepted.
	Accepted int `json:"accepted"`

	// Rejected is the number of recipients that were rejected.
	Rejected int `json:"rejected"`
}

ScheduleEmailData contains the result of scheduling an email.

type ScheduleEmailRequest added in v0.2.0

type ScheduleEmailRequest struct {
	SendEmailRequest

	// ScheduledAt is the time to send the email (ISO 8601).
	// Must be at least 5 minutes in the future and at most 3 days.
	ScheduledAt string `json:"scheduled_at"`
}

ScheduleEmailRequest represents the request body for scheduling an email for future delivery.

type ScheduleEmailResponse added in v0.2.0

type ScheduleEmailResponse struct {
	Message string            `json:"message"`
	Data    ScheduleEmailData `json:"data"`
}

ScheduleEmailResponse is the response from scheduling an email.

type ScheduledTransmission added in v0.2.0

type ScheduledTransmission struct {
	TransmissionID string       `json:"transmission_id"`
	State          string       `json:"state"`
	ScheduledAt    *string      `json:"scheduled_at"`
	From           string       `json:"from"`
	FromName       *string      `json:"from_name"`
	Subject        string       `json:"subject"`
	Recipients     []string     `json:"recipients"`
	NumRecipients  int          `json:"num_recipients"`
	Events         []EmailEvent `json:"events"`
}

ScheduledTransmission represents a scheduled email transmission.

type SegmentCondition added in v1.2.0

type SegmentCondition struct {
	Field    string  `json:"field"`
	Operator string  `json:"operator"`
	Value    *string `json:"value,omitempty"`
}

SegmentCondition is a single field/operator/value match. Value is optional and not required when Operator is "is_true" or "is_false".

type SegmentConditionGroup added in v1.2.0

type SegmentConditionGroup struct {
	Conditions []SegmentCondition `json:"conditions"`
}

SegmentConditionGroup is a set of conditions joined by AND. Multiple groups within a segment are joined by OR.

type SegmentConditionsInput added in v1.2.0

type SegmentConditionsInput struct {
	Groups []SegmentConditionGroup `json:"groups"`
}

SegmentConditionsInput is the request-side wrapper for segment conditions.

type SendEmailData

type SendEmailData struct {
	// RequestID is the unique transmission ID for the sent email.
	RequestID string `json:"request_id"`

	// Accepted is the number of recipients that were accepted.
	Accepted int `json:"accepted"`

	// Rejected is the number of recipients that were rejected.
	Rejected int `json:"rejected"`
}

SendEmailData contains the result of a send operation.

type SendEmailOptions

type SendEmailOptions struct {
	// ClickTracking enables or disables click tracking.
	ClickTracking *bool `json:"click_tracking,omitempty"`

	// OpenTracking enables or disables open tracking.
	OpenTracking *bool `json:"open_tracking,omitempty"`

	// Transactional marks the email as transactional.
	Transactional *bool `json:"transactional,omitempty"`

	// InlineCss enables inlining CSS styles in HTML content.
	InlineCss *bool `json:"inline_css,omitempty"`

	// PerformSubstitutions enables variable substitutions in content.
	PerformSubstitutions *bool `json:"perform_substitutions,omitempty"`
}

SendEmailOptions contains optional send settings.

type SendEmailRequest

type SendEmailRequest struct {
	// From is the sender email address (required).
	From string `json:"from"`

	// FromName is the sender display name (optional).
	FromName string `json:"from_name,omitempty"`

	// To is the list of recipient email addresses (required, max 50).
	To []string `json:"to"`

	// Cc is the list of carbon copy recipient email addresses (optional).
	Cc []string `json:"cc,omitempty"`

	// Bcc is the list of blind carbon copy recipient email addresses (optional).
	Bcc []string `json:"bcc,omitempty"`

	// Subject is the email subject line (required unless using template_slug).
	Subject string `json:"subject,omitempty"`

	// Html is the HTML body content. At least one of Html or Text is required.
	Html string `json:"html,omitempty"`

	// Text is the plain text body content. At least one of Html or Text is required.
	Text string `json:"text,omitempty"`

	// AmpHtml is the AMP HTML content for supported email clients (optional).
	AmpHtml string `json:"amp_html,omitempty"`

	// ReplyTo is the reply-to email address (optional).
	ReplyTo string `json:"reply_to,omitempty"`

	// ReplyToName is the reply-to display name (optional).
	ReplyToName string `json:"reply_to_name,omitempty"`

	// TemplateSlug is the slug of a pre-defined template to use.
	TemplateSlug string `json:"template_slug,omitempty"`

	// TemplateVersion is the specific version of the template to use.
	TemplateVersion *int `json:"template_version,omitempty"`

	// ProjectID is the project to source the template from.
	ProjectID *int `json:"project_id,omitempty"`

	// Attachments is a list of file attachments (base64-encoded).
	Attachments []Attachment `json:"attachments,omitempty"`

	// SubstitutionData contains key-value pairs for template variable replacement.
	SubstitutionData map[string]string `json:"substitution_data,omitempty"`

	// Metadata contains custom key-value pairs stored with the email.
	Metadata map[string]string `json:"metadata,omitempty"`

	// Tag is a tag for tracking and analytics (optional).
	Tag string `json:"tag,omitempty"`

	// Headers contains custom email headers (up to 10, optional).
	Headers map[string]string `json:"headers,omitempty"`

	// Options contains tracking and delivery options.
	Options *SendEmailOptions `json:"options,omitempty"`
}

SendEmailRequest represents the request body for sending an email.

type SendEmailResponse

type SendEmailResponse struct {
	Message string        `json:"message"`
	Data    SendEmailData `json:"data"`
}

SendEmailResponse is the response from sending an email.

type SpfValidationResult added in v0.2.0

type SpfValidationResult struct {
	IsValid           bool    `json:"is_valid"`
	Status            string  `json:"status"`
	Record            *string `json:"record"`
	Error             *string `json:"error"`
	IncludesSparkpost bool    `json:"includes_sparkpost"`
}

SpfValidationResult contains SPF validation details.

type Template

type Template struct {
	ID        int    `json:"id"`
	Name      string `json:"name"`
	Slug      string `json:"slug"`
	ProjectID int    `json:"project_id"`
	FolderID  int    `json:"folder_id"`
	CreatedAt string `json:"created_at"`
	UpdatedAt string `json:"updated_at"`
}

Template represents an email template.

type TemplateDetail added in v0.2.0

type TemplateDetail struct {
	ID            int    `json:"id"`
	Name          string `json:"name"`
	Slug          string `json:"slug"`
	ProjectID     int    `json:"project_id"`
	FolderID      int    `json:"folder_id"`
	ActiveVersion *int   `json:"active_version"`
	VersionsCount int    `json:"versions_count"`
	Html          string `json:"html,omitempty"`
	Json          string `json:"json,omitempty"`
	CreatedAt     string `json:"created_at"`
	UpdatedAt     string `json:"updated_at"`
}

TemplateDetail represents detailed information about a template, including version info and content.

type TemplateService

type TemplateService struct {
	// contains filtered or unexported fields
}

TemplateService handles communication with the template-related endpoints of the Lettr API.

func (*TemplateService) Create

Create creates a new email template with HTML or Topol JSON content.

Example:

template, err := client.Templates.Create(ctx, &lettr.CreateTemplateRequest{
    Name: "Welcome Email",
    Html: "<h1>Hello {{FIRST_NAME}}!</h1>",
})

func (*TemplateService) Delete added in v0.2.0

Delete permanently removes a template.

Pass nil for params to use the team's default project.

Example:

resp, err := client.Templates.Delete(ctx, "welcome-email", nil)

func (*TemplateService) Get added in v0.2.0

Get retrieves details of a single template by its slug.

Pass nil for params to use the team's default project.

Example:

template, err := client.Templates.Get(ctx, "welcome-email", nil)

func (*TemplateService) GetHtml added in v0.2.0

GetHtml retrieves the rendered HTML content of a template.

Example:

html, err := client.Templates.GetHtml(ctx, &lettr.GetTemplateHtmlParams{
    ProjectID: 1,
    Slug:      "welcome-email",
})

func (*TemplateService) GetMergeTags added in v0.2.0

func (s *TemplateService) GetMergeTags(ctx context.Context, slug string, params *GetMergeTagsParams) (*GetMergeTagsResponse, error)

GetMergeTags retrieves the merge tags for a template.

Pass nil for params to use defaults (team's default project, active version).

Example:

tags, err := client.Templates.GetMergeTags(ctx, "welcome-email", nil)

func (*TemplateService) List

List retrieves a paginated list of email templates.

Pass nil for params to use defaults.

Example:

templates, err := client.Templates.List(ctx, nil)

func (*TemplateService) Update added in v0.2.0

Update modifies an existing template's name or content.

Example:

updated, err := client.Templates.Update(ctx, "welcome-email", &lettr.UpdateTemplateRequest{
    Html: "<h1>Updated Hello {{FIRST_NAME}}!</h1>",
})

type UpdateAudienceContactRequest added in v1.2.0

type UpdateAudienceContactRequest struct {
	Email      string             `json:"email,omitempty"`
	Status     string             `json:"status,omitempty"`
	Properties map[string]*string `json:"properties,omitempty"`
}

UpdateAudienceContactRequest is the body for partially updating a contact. A property set to a nil pointer in Properties is sent as JSON null and removes that property from the contact server-side.

type UpdateAudienceListRequest added in v1.2.0

type UpdateAudienceListRequest struct {
	Name string `json:"name,omitempty"`
}

UpdateAudienceListRequest is the body for partially updating an audience list.

type UpdateAudiencePropertyRequest added in v1.2.0

type UpdateAudiencePropertyRequest struct {
	FallbackValue *NullString `json:"fallback_value,omitempty"`
}

UpdateAudiencePropertyRequest is the body for updating a property's fallback value. The name and type fields are immutable.

FallbackValue is a nullable PATCH field: leave it nil to omit, NewNullString("x") to replace, or &NullString{} (zero value) to clear the existing fallback server-side.

type UpdateAudienceSegmentRequest added in v1.2.0

type UpdateAudienceSegmentRequest struct {
	Name       string                  `json:"name,omitempty"`
	ListID     *NullString             `json:"list_id,omitempty"`
	Conditions *SegmentConditionsInput `json:"conditions,omitempty"`
}

UpdateAudienceSegmentRequest is the body for partially updating a segment.

ListID is a nullable PATCH field: leave it nil to omit, NewNullString(uuid) to restrict, or &NullString{} (zero value) to clear the list restriction (so the segment matches across all lists).

type UpdateAudienceTopicRequest added in v1.2.0

type UpdateAudienceTopicRequest struct {
	Name        string      `json:"name,omitempty"`
	Description *NullString `json:"description,omitempty"`
	Visibility  string      `json:"visibility,omitempty"`
}

UpdateAudienceTopicRequest is the body for partially updating a topic. The default_subscription field is immutable and cannot be sent.

Description is a nullable PATCH field: leave it nil to omit, NewNullString("x") to replace, or &NullString{} (zero value) to clear the existing description server-side.

type UpdateTemplateData added in v0.2.0

type UpdateTemplateData struct {
	ID            int        `json:"id"`
	Name          string     `json:"name"`
	Slug          string     `json:"slug"`
	ProjectID     int        `json:"project_id"`
	FolderID      int        `json:"folder_id"`
	ActiveVersion int        `json:"active_version"`
	MergeTags     []MergeTag `json:"merge_tags"`
	CreatedAt     string     `json:"created_at"`
	UpdatedAt     string     `json:"updated_at"`
}

UpdateTemplateData contains the result of updating a template.

type UpdateTemplateRequest added in v0.2.0

type UpdateTemplateRequest struct {
	// Name is the new name for the template.
	Name string `json:"name,omitempty"`

	// Html is new HTML content (creates a new active version).
	Html string `json:"html,omitempty"`

	// Json is new Topol editor JSON content (creates a new active version).
	Json string `json:"json,omitempty"`

	// ProjectID is the project containing the template.
	ProjectID *int `json:"project_id,omitempty"`
}

UpdateTemplateRequest represents the request body for updating a template.

type UpdateTemplateResponse added in v0.2.0

type UpdateTemplateResponse struct {
	Message string             `json:"message"`
	Data    UpdateTemplateData `json:"data"`
}

UpdateTemplateResponse is the response from updating a template.

type UpdateWebhookRequest added in v0.2.0

type UpdateWebhookRequest struct {
	Name string `json:"name,omitempty"`
	// URL is the destination endpoint for webhook deliveries.
	URL string `json:"url,omitempty"`
	// Deprecated: use URL instead. Target is retained for backwards compatibility
	// and will be removed in a future major release.
	Target            string   `json:"target,omitempty"`
	AuthType          string   `json:"auth_type,omitempty"`
	AuthUsername      string   `json:"auth_username,omitempty"`
	AuthPassword      string   `json:"auth_password,omitempty"`
	OAuthClientID     string   `json:"oauth_client_id,omitempty"`
	OAuthClientSecret string   `json:"oauth_client_secret,omitempty"`
	OAuthTokenURL     string   `json:"oauth_token_url,omitempty"`
	Events            []string `json:"events,omitempty"`
	Active            *bool    `json:"active,omitempty"`
}

UpdateWebhookRequest represents the request body for updating a webhook.

type UpdateWebhookResponse added in v0.2.0

type UpdateWebhookResponse struct {
	Message string  `json:"message"`
	Data    Webhook `json:"data"`
}

UpdateWebhookResponse is the response from updating a webhook.

type UserAgentParsed added in v0.2.0

type UserAgentParsed struct {
	AgentFamily  string `json:"agent_family,omitempty"`
	OsFamily     string `json:"os_family,omitempty"`
	OsVersion    string `json:"os_version,omitempty"`
	DeviceFamily string `json:"device_family,omitempty"`
	DeviceBrand  string `json:"device_brand,omitempty"`
	IsMobile     bool   `json:"is_mobile,omitempty"`
	IsProxy      bool   `json:"is_proxy,omitempty"`
	IsPrefetched bool   `json:"is_prefetched,omitempty"`
}

UserAgentParsed contains parsed user agent information from open/click events.

type VerifyDomainResponse added in v0.2.0

type VerifyDomainResponse struct {
	Message string                 `json:"message"`
	Data    DomainVerificationView `json:"data"`
}

VerifyDomainResponse is the response from verifying a domain.

type Webhook

type Webhook struct {
	ID                 string    `json:"id"`
	Name               string    `json:"name"`
	URL                string    `json:"url"`
	Enabled            bool      `json:"enabled"`
	EventTypes         *[]string `json:"event_types"`
	AuthType           string    `json:"auth_type"`
	HasAuthCredentials bool      `json:"has_auth_credentials"`
	LastSuccessfulAt   *string   `json:"last_successful_at"`
	LastFailureAt      *string   `json:"last_failure_at"`
	LastStatus         *string   `json:"last_status"`
}

Webhook represents a webhook configuration.

type WebhookService

type WebhookService struct {
	// contains filtered or unexported fields
}

WebhookService handles communication with the webhook-related endpoints of the Lettr API.

func (*WebhookService) Create added in v0.2.0

Create creates a new webhook for event notifications.

Event names use the namespaced form ("message.delivery", "engagement.click", etc.) — see the Event* constants in this package.

Example:

webhook, err := client.Webhooks.Create(ctx, &lettr.CreateWebhookRequest{
    Name:       "My Webhook",
    URL:        "https://example.com/webhook",
    AuthType:   "none",
    EventsMode: "selected",
    Events: []string{
        lettr.EventMessageDelivery,
        lettr.EventMessageBounce,
    },
})

func (*WebhookService) Delete added in v0.2.0

func (s *WebhookService) Delete(ctx context.Context, webhookID string) (*DeleteWebhookResponse, error)

Delete removes a webhook.

Example:

resp, err := client.Webhooks.Delete(ctx, "webhook-abc123")

func (*WebhookService) Get

func (s *WebhookService) Get(ctx context.Context, webhookID string) (*GetWebhookResponse, error)

Get retrieves details of a single webhook.

Example:

webhook, err := client.Webhooks.Get(ctx, "webhook-abc123")

func (*WebhookService) List

List retrieves all webhooks configured for your account.

Example:

webhooks, err := client.Webhooks.List(ctx)

func (*WebhookService) Update added in v0.2.0

func (s *WebhookService) Update(ctx context.Context, webhookID string, params *UpdateWebhookRequest) (*UpdateWebhookResponse, error)

Update modifies an existing webhook's settings.

Use the URL field for the destination endpoint; the Target field is deprecated and retained only for backwards compatibility.

Example:

active := false
updated, err := client.Webhooks.Update(ctx, "webhook-abc123", &lettr.UpdateWebhookRequest{
    URL:    "https://example.com/new-webhook",
    Active: &active,
})

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL