Language SDKs
Go
Send transactional email from Go with Sendery templates.
go get github.com/sendery-co/[email protected]Requirements
Go 1.26+. Install the SDK from a project with a go.mod file.
Set up
Publish a welcome template with name and action_url variables, and create a project API key. Store it as SENDERY_API_KEY on your server.
export SENDERY_API_KEY="your_project_api_key"Send an email
The response contains the accepted email’s ID and Status. Set Locale to choose a template language. Omit Data when the template has no variables; it is sent as an empty JSON object.
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/sendery-co/sendery-go"
)
func main() {
client, err := sendery.NewClient(os.Getenv("SENDERY_API_KEY"))
if err != nil {
log.Fatal(err)
}
receipt, err := client.Send(context.Background(), sendery.SendEmailInput{
To: "[email protected]",
Template: "welcome",
Data: map[string]any{
"name": "Alex",
"action_url": "https://example.com/start",
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(receipt.ID)
}Retrieve an email
Use the returned ID to check delivery status.
message, err := client.Get(context.Background(), receipt.ID)
if err != nil {
log.Fatal(err)
}
fmt.Println(message.Status)Retry a send
Use a key such as welcome-123 for one email, and keep the payload unchanged on retries. Prepare saves a copy of the payload. WithRetries(3) allows up to three additional attempts for temporary failures; the default is one attempt. Read the key with email.IdempotencyKey().
email, err := client.Prepare(sendery.SendEmailInput{
To: "[email protected]",
Template: "welcome",
Data: map[string]any{
"name": "Alex",
"action_url": "https://example.com/start",
},
}, sendery.WithIdempotencyKey("welcome-123"), sendery.WithRetries(3))
if err != nil {
log.Fatal(err)
}
receipt, err := email.Send(context.Background())
if err != nil {
log.Fatal(err)
}
fmt.Println(receipt.ID)Handle errors
Use errors.As to inspect the status, code, and field errors. RetryAfter is a *time.Duration, or nil when no delay is supplied. The example uses the prepared email from the retry example above.
// Add "errors" to your imports.
receipt, err := email.Send(context.Background())
if err != nil {
var apiError *sendery.APIError
if errors.As(err, &apiError) {
log.Printf("%d: %s", apiError.Status, apiError.Code)
for field, messages := range apiError.Errors {
log.Printf("%s: %v", field, messages)
}
if apiError.RetryAfter != nil {
log.Printf("Retry after %s", *apiError.RetryAfter)
}
}
log.Fatal(err)
}
fmt.Println(receipt.ID)Set a deadline
Pass a context to Send or Get to cancel a request or limit its duration. The default HTTP timeout is 10 seconds per attempt. A context deadline also limits retry waits. Cancellation returns context.Canceled or context.DeadlineExceeded; the email may already have been accepted, so reuse its key and payload if you try again.
// Add "time" to your imports. In an HTTP handler, use r.Context()
// as the parent context so requests stop when the caller disconnects.
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
receipt, err := email.Send(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Println(receipt.ID)