Skip to main content
Broadcasts allow you to send email campaigns to all contacts in a segment. This guide covers creating, scheduling, sending, and managing broadcast campaigns with the Resend Go SDK.

Overview

Broadcasts enable you to:
  • Send mass email campaigns to segments
  • Schedule campaigns for future delivery
  • Create draft campaigns for review
  • Track campaign status and delivery
  • Manage campaign lifecycle from creation to deletion

Creating a Broadcast

Create a broadcast campaign targeting a specific segment.
import (
    "github.com/resend/resend-go/v3"
)

client := resend.NewClient("re_123456789")

params := &resend.CreateBroadcastRequest{
    SegmentId: "seg-123456",
    From:      "[email protected]",
    Subject:   "Monthly Newsletter",
    Html:      "<h1>This Month's Updates</h1><p>Content here...</p>",
    Name:      "Monthly Newsletter - January 2024",
}

broadcast, err := client.Broadcasts.Create(params)
if err != nil {
    panic(err)
}

fmt.Println("Created broadcast ID:", broadcast.Id)

Request Parameters

SegmentId
string
required
The ID of the segment to send the broadcast to. All contacts in this segment will receive the email.
From
string
required
The sender email address (e.g., “[email protected]” or “Sender Name <[email protected]>”).
Subject
string
required
The email subject line.
Html
string
The HTML version of the email content.
Text
string
The plain text version of the email content.
Name
string
Internal name for the broadcast campaign (for your reference).
ReplyTo
[]string
Array of reply-to email addresses.
Send
bool
If true, sends the broadcast immediately. If false or omitted, creates a draft.
ScheduledAt
string
Schedule the broadcast for later delivery. Accepts ISO 8601 format (e.g., “2024-08-05T11:52:01.858Z”) or natural language (e.g., “in 1 hour”). Only valid when Send is true.
Deprecated: AudienceId is still supported for backward compatibility, but use SegmentId for new integrations.

Retrieving a Broadcast

Get details about a specific broadcast including its status and content.
Get Broadcast
broadcast, err := client.Broadcasts.Get("brd-123456")
if err != nil {
    panic(err)
}

fmt.Println("Name:", broadcast.Name)
fmt.Println("Status:", broadcast.Status)
fmt.Println("Segment ID:", broadcast.SegmentId)
fmt.Println("From:", broadcast.From)
fmt.Println("Subject:", broadcast.Subject)
fmt.Println("Created At:", broadcast.CreatedAt)
fmt.Println("Scheduled At:", broadcast.ScheduledAt)
fmt.Println("Sent At:", broadcast.SentAt)

Broadcast Status Values

Broadcasts can have the following statuses:
  • draft - Created but not sent
  • scheduled - Scheduled for future delivery
  • sending - Currently being sent
  • sent - Successfully sent to all recipients
  • failed - Failed to send

Listing Broadcasts

Retrieve all broadcasts in your account with optional pagination.
broadcasts, err := client.Broadcasts.List()
if err != nil {
    panic(err)
}

fmt.Printf("You have %d broadcast(s)\n", len(broadcasts.Data))

for _, b := range broadcasts.Data {
    fmt.Printf("\n[%s] %s\n", b.Status, b.Name)
    fmt.Printf("  Subject: %s\n", b.Subject)
    fmt.Printf("  Created: %s\n", b.CreatedAt)
}

Updating a Broadcast

Update a draft broadcast before sending. Only draft broadcasts can be updated.
Update Broadcast
updateParams := &resend.UpdateBroadcastRequest{
    BroadcastId: "brd-123456",
    Name:        "Updated Campaign Name",
    Subject:     "New Subject Line",
    Html:        "<h1>Updated Content</h1>",
    From:        "[email protected]",
}

updated, err := client.Broadcasts.Update(updateParams)
if err != nil {
    panic(err)
}

fmt.Println("Updated broadcast:", updated.Id)
You can only update broadcasts with draft status. Scheduled or sent broadcasts cannot be modified.

Sending a Broadcast

Send a draft broadcast immediately or schedule it for later.
sendParams := &resend.SendBroadcastRequest{
    BroadcastId: "brd-123456",
}

sent, err := client.Broadcasts.Send(sendParams)
if err != nil {
    panic(err)
}

fmt.Println("Broadcast sent:", sent.Id)
The ScheduledAt field accepts both ISO 8601 format and natural language expressions like “in 1 hour”, “tomorrow at 9am”, etc.

Canceling a Scheduled Broadcast

To cancel a scheduled broadcast, delete it before it’s sent.
Cancel Scheduled Broadcast
// Check if broadcast is scheduled
broadcast, err := client.Broadcasts.Get("brd-123456")
if err != nil {
    panic(err)
}

if broadcast.Status == "scheduled" {
    removed, err := client.Broadcasts.Remove(broadcast.Id)
    if err != nil {
        panic(err)
    }
    fmt.Println("Canceled scheduled broadcast")
}

Deleting a Broadcast

Delete a draft broadcast. Only draft broadcasts can be deleted.
Delete Broadcast
removed, err := client.Broadcasts.Remove("brd-123456")
if err != nil {
    panic(err)
}

fmt.Printf("Broadcast %s deleted: %v\n", removed.Id, removed.Deleted)
Only broadcasts with draft status can be deleted. Sent broadcasts cannot be removed from your account.

Complete Example

Here’s a complete workflow demonstrating broadcast campaign management:
Complete Broadcast Workflow
package main

import (
    "context"
    "fmt"
    "os"
    "time"
    
    "github.com/resend/resend-go/v3"
)

func main() {
    ctx := context.Background()
    apiKey := os.Getenv("RESEND_API_KEY")
    client := resend.NewClient(apiKey)

    // 1. Create a segment
    segment, err := client.Segments.CreateWithContext(ctx, &resend.CreateSegmentRequest{
        Name: "Newsletter Subscribers",
    })
    if err != nil {
        panic(err)
    }
    fmt.Printf("Created segment: %s\n", segment.Id)

    // 2. Add contacts to the segment
    contact, err := client.Contacts.CreateWithContext(ctx, &resend.CreateContactRequest{
        Email:     "[email protected]",
        FirstName: "John",
        LastName:  "Doe",
    })
    if err != nil {
        panic(err)
    }

    _, err = client.Contacts.Segments.AddWithContext(ctx, &resend.AddContactSegmentRequest{
        ContactId: contact.Id,
        SegmentId: segment.Id,
    })
    if err != nil {
        panic(err)
    }
    fmt.Println("Added contact to segment")

    // 3. Create a draft broadcast
    createParams := &resend.CreateBroadcastRequest{
        SegmentId: segment.Id,
        From:      "[email protected]",
        Subject:   "Monthly Update - January 2024",
        Html:      "<h1>Happy New Year!</h1><p>Here's what's new this month...</p>",
        Text:      "Happy New Year! Here's what's new this month...",
        ReplyTo:   []string{"[email protected]"},
        Name:      "January 2024 Newsletter",
    }

    broadcast, err := client.Broadcasts.CreateWithContext(ctx, createParams)
    if err != nil {
        panic(err)
    }
    fmt.Printf("\nCreated draft broadcast: %s\n", broadcast.Id)

    // 4. Review the broadcast
    retrieved, err := client.Broadcasts.GetWithContext(ctx, broadcast.Id)
    if err != nil {
        panic(err)
    }
    fmt.Printf("\nBroadcast Details:\n")
    fmt.Printf("  Name: %s\n", retrieved.Name)
    fmt.Printf("  Status: %s\n", retrieved.Status)
    fmt.Printf("  Subject: %s\n", retrieved.Subject)
    fmt.Printf("  Segment: %s\n", retrieved.SegmentId)

    // 5. Update the broadcast (optional)
    updateParams := &resend.UpdateBroadcastRequest{
        BroadcastId: broadcast.Id,
        Subject:     "Monthly Update - Happy New Year!",
    }

    updated, err := client.Broadcasts.UpdateWithContext(ctx, updateParams)
    if err != nil {
        panic(err)
    }
    fmt.Printf("\nUpdated broadcast: %s\n", updated.Id)

    // 6. Schedule the broadcast for later
    scheduleTime := time.Now().Add(24 * time.Hour).Format(time.RFC3339)
    sendParams := &resend.SendBroadcastRequest{
        BroadcastId: broadcast.Id,
        ScheduledAt: scheduleTime,
    }

    sent, err := client.Broadcasts.SendWithContext(ctx, sendParams)
    if err != nil {
        panic(err)
    }
    fmt.Printf("\nBroadcast scheduled: %s\n", sent.Id)

    // 7. List all broadcasts
    broadcasts, err := client.Broadcasts.ListWithContext(ctx)
    if err != nil {
        panic(err)
    }
    fmt.Printf("\nTotal broadcasts: %d\n", len(broadcasts.Data))
    for _, b := range broadcasts.Data {
        fmt.Printf("  - [%s] %s\n", b.Status, b.Name)
    }

    // 8. Cancel the scheduled broadcast (for demo purposes)
    removed, err := client.Broadcasts.RemoveWithContext(ctx, broadcast.Id)
    if err != nil {
        panic(err)
    }
    fmt.Printf("\nCanceled broadcast: %v\n", removed.Deleted)

    // Clean up
    client.Contacts.RemoveWithContext(ctx, &resend.RemoveContactOptions{Id: contact.Id})
    client.Segments.RemoveWithContext(ctx, segment.Id)
    fmt.Println("\nCleanup complete")
}

Broadcast Campaign Patterns

Newsletter Campaign

Newsletter Pattern
// Create recurring newsletter broadcasts
for month := 1; month <= 12; month++ {
    name := fmt.Sprintf("Newsletter - %s 2024", time.Month(month).String())
    
    broadcast, err := client.Broadcasts.Create(&resend.CreateBroadcastRequest{
        SegmentId: "newsletter-subscribers",
        From:      "[email protected]",
        Subject:   fmt.Sprintf("%s Newsletter", time.Month(month).String()),
        Html:      generateNewsletterHTML(month),
        Name:      name,
    })
    
    if err != nil {
        fmt.Printf("Failed to create %s: %v\n", name, err)
        continue
    }
    
    fmt.Printf("Created draft: %s\n", broadcast.Id)
}

Product Announcement

Product Announcement
// Send immediate product announcement
broadcast, err := client.Broadcasts.Create(&resend.CreateBroadcastRequest{
    SegmentId: "all-customers",
    From:      "Product Team <[email protected]>",
    Subject:   "🚀 Introducing Our New Feature!",
    Html:      loadTemplate("product-announcement.html"),
    Text:      loadTemplate("product-announcement.txt"),
    ReplyTo:   []string{"[email protected]"},
    Name:      "Feature Launch - Q1 2024",
    Send:      true, // Send immediately
})

if err != nil {
    panic(err)
}

fmt.Println("Announcement sent to all customers")

Scheduled Campaign Series

Drip Campaign
// Create a series of scheduled broadcasts
schedules := []struct {
    delay   time.Duration
    subject string
    content string
}{
    {0, "Welcome to Our Platform!", "welcome.html"},
    {24 * time.Hour, "Getting Started Guide", "getting-started.html"},
    {3 * 24 * time.Hour, "Pro Tips and Tricks", "pro-tips.html"},
    {7 * 24 * time.Hour, "We'd Love Your Feedback", "feedback.html"},
}

for i, schedule := range schedules {
    sendTime := time.Now().Add(schedule.delay).Format(time.RFC3339)
    
    broadcast, err := client.Broadcasts.Create(&resend.CreateBroadcastRequest{
        SegmentId: "new-users",
        From:      "[email protected]",
        Subject:   schedule.subject,
        Html:      loadTemplate(schedule.content),
        Name:      fmt.Sprintf("Onboarding Email %d", i+1),
        Send:      true,
        ScheduledAt: sendTime,
    })
    
    if err != nil {
        fmt.Printf("Failed to schedule email %d: %v\n", i+1, err)
        continue
    }
    
    fmt.Printf("Scheduled: %s for %s\n", broadcast.Id, sendTime)
}

Error Handling

Robust Error Handling
broadcast, err := client.Broadcasts.Create(params)
if err != nil {
    fmt.Printf("Failed to create broadcast: %v\n", err)
    // Handle specific errors
    return
}

// Verify broadcast was created
if broadcast.Id == "" {
    fmt.Println("Broadcast created but no ID returned")
    return
}

// Check status before sending
retrieved, err := client.Broadcasts.Get(broadcast.Id)
if err != nil {
    fmt.Printf("Failed to retrieve broadcast: %v\n", err)
    return
}

if retrieved.Status != "draft" {
    fmt.Printf("Cannot send broadcast with status: %s\n", retrieved.Status)
    return
}

// Attempt to send
sent, err := client.Broadcasts.Send(&resend.SendBroadcastRequest{
    BroadcastId: broadcast.Id,
})
if err != nil {
    fmt.Printf("Failed to send broadcast: %v\n", err)
    return
}

fmt.Printf("Successfully sent broadcast: %s\n", sent.Id)

Best Practices

Test Before Sending

Create a test segment with your own email to preview broadcasts before sending to large audiences.

Use Descriptive Names

Give broadcasts clear internal names to track campaigns effectively (e.g., “Q1 Newsletter - March 2024”).

Include Plain Text

Always include a Text version for better deliverability and accessibility.

Set Reply-To Addresses

Configure ReplyTo to handle customer responses effectively.

Schedule Wisely

Schedule campaigns for optimal send times based on your audience’s timezone and habits.

Monitor Status

Check broadcast status and use webhooks to track delivery and engagement.

Next Steps

Segments

Learn how to organize contacts into segments

Webhooks

Track broadcast events with webhooks

Broadcasts Example

View the complete broadcasts example

API Reference

View the complete Broadcasts API reference

Build docs developers (and LLMs) love