The official Go SDK for Lettermint.
- Go 1.21 or higher
go get github.com/lettermint/lettermint-goimport lettermint "github.com/lettermint/lettermint-go"
client, err := lettermint.New("your-api-token")
if err != nil {
log.Fatal(err)
}The SDK provides a fluent interface for sending emails:
ctx := context.Background()
resp, err := client.Email(ctx).
From("sender@example.com").
To("recipient@example.com").
Subject("Hello from Lettermint").
Text("This is a test email sent using the Lettermint Go SDK.").
Send()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Email sent with ID: %s\n", resp.MessageID)
fmt.Printf("Status: %s\n", resp.Status)resp, err := client.Email(ctx).
From("John Doe <sender@example.com>").
To("recipient1@example.com", "recipient2@example.com").
CC("cc@example.com").
BCC("bcc@example.com").
ReplyTo("reply@example.com").
Subject("Hello from Lettermint").
HTML("<h1>Hello</h1><p>This is an HTML email.</p>").
Text("This is a plain text version of the email.").
Headers(map[string]string{
"X-Custom-Header": "Custom Value",
}).
Attach("attachment.txt", base64EncodedContent).
AttachWithContentID("logo.png", base64EncodedLogo, "logo"). // Inline attachment
IdempotencyKey("unique-id-123").
Metadata(map[string]string{
"user_id": "12345",
}).
Tag("campaign-123").
Send()You can embed images and other content in your HTML emails using Content-IDs:
resp, err := client.Email(ctx).
From("sender@example.com").
To("recipient@example.com").
Subject("Email with inline image").
HTML(`<p>Here is an image: <img src="cid:logo"></p>`).
AttachWithContentID("logo.png", base64EncodedImage, "logo").
Send()To ensure that duplicate requests are not processed, you can use an idempotency key:
resp, err := client.Email(ctx).
From("sender@example.com").
To("recipient@example.com").
Subject("Hello from Lettermint").
Text("Hello! This is a test email.").
IdempotencyKey("unique-request-id-123").
Send()The idempotency key should be a unique string that you generate for each unique email you want to send. If you make the same request with the same idempotency key, the API will return the same response without sending a duplicate email.
For more information, refer to the documentation.
Verify webhook signatures to ensure the authenticity of webhook requests:
func webhookHandler(w http.ResponseWriter, r *http.Request) {
event, err := lettermint.VerifyWebhookFromRequest(
r,
"your-webhook-secret",
lettermint.DefaultWebhookTolerance,
)
if err != nil {
http.Error(w, "Invalid signature", http.StatusUnauthorized)
return
}
// Process the event
switch event.Event {
case "message.delivered":
log.Printf("Email delivered to %s", event.Data.Recipient)
case "message.hard_bounced":
log.Printf("Hard bounce for %s", event.Data.Recipient)
case "message.soft_bounced":
log.Printf("Soft bounce for %s", event.Data.Recipient)
}
w.WriteHeader(http.StatusOK)
}client, err := lettermint.New("your-api-token",
lettermint.WithBaseURL("https://api.lettermint.co/v1"), // Optional
lettermint.WithTimeout(30*time.Second), // Optional
lettermint.WithHTTPClient(customHTTPClient), // Optional
)From(email string): Set the sender email addressTo(emails ...string): Set one or more recipient email addressesSubject(subject string): Set the email subjectHTML(html string): Set the HTML body of the emailText(text string): Set the plain text body of the emailCC(emails ...string): Set one or more CC email addressesBCC(emails ...string): Set one or more BCC email addressesReplyTo(emails ...string): Set one or more Reply-To email addressesHeader(key, value string): Set a custom headerHeaders(headers map[string]string): Set multiple custom headersAttach(filename, base64Content string): Attach a fileAttachWithContentID(filename, content, contentID string): Attach an inline fileRoute(route string): Set the routing keyIdempotencyKey(key string): Set an idempotency keyMetadata(metadata map[string]string): Set metadataMetadataValue(key, value string): Set a single metadata valueTag(tag string): Set a tagSend() (*SendResponse, error): Send the email
The SDK provides structured error types:
resp, err := client.Email(ctx).From("...").To("...").Subject("...").HTML("...").Send()
if err != nil {
// Check for specific error types
var apiErr *lettermint.APIError
if errors.As(err, &apiErr) {
fmt.Printf("API Error (%d): %s\n", apiErr.StatusCode, apiErr.Message)
fmt.Printf("Validation errors: %v\n", apiErr.Errors)
}
// Check for error categories using errors.Is()
if errors.Is(err, lettermint.ErrValidation) {
// Handle validation errors (422)
} else if errors.Is(err, lettermint.ErrUnauthorized) {
// Handle authentication errors (401)
} else if errors.Is(err, lettermint.ErrTimeout) {
// Handle timeout errors
} else if errors.Is(err, lettermint.ErrRateLimited) {
// Handle rate limit errors (429)
}
}go test ./...Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.