bird

package module
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: Jul 28, 2026 License: MIT Imports: 24 Imported by: 0

README

Bird Go SDK

The official Go SDK for the Bird email platform.

go get github.com/messagebird/bird-sdk-go

Requires Go 1.24+.

This SDK is generated from Bird's public OpenAPI bundle inside Bird's internal monorepo, which is the single source of truth; this repository tracks tagged releases. Generation runs in the monorepo, so make generate won't work from a clone here — see CONTRIBUTING.md.

Overview

bird.NewClient(option.WithAPIKey(...)) returns a client whose region is inferred from the API key's prefix (bk_{region}_…); pass option.WithBaseURL or option.WithRegion to override. From there:

  • client.EmailSend, Get, List (auto-paginating; ListPage for manual cursors).
  • client.WhatsappSend (template messages), Get, List (auto-paginating; ListPage for manual cursors), ListEvents (a message's delivery timeline). client.WhatsappTemplates reads the template catalogue.
  • client.WebhooksUnwrap (verify a signed event into a typed value).
  • Typed errors. A failure is a *bird.APIError (or a richer *bird.RateLimitError / *bird.ValidationError) you branch on with errors.As. Transient failures (timeouts, 429, 5xx) are retried automatically with a reused idempotency key.
  • Options configure the client and override per call (option.WithEmailDefaults, WithTimeout, WithIdempotencyKey, …).
  • client.Get/Post/Put/Patch/Delete reach endpoints outside the curated surface.

Examples

Runnable, per-method examples live in example_test.go and render under each method on pkg.go.dev: sending (simple and rich), error handling, get, pagination, channel defaults, the webhook receiver, and the escape hatch.

Design

The wire types and a low-level client are generated from the OpenAPI spec into internal/oapi; this package is the hand-written idiomatic layer on top.

Documentation

Overview

Code generated by surface-gen; DO NOT EDIT.

Package bird is the Go SDK for the Bird email platform.

It offers a curated resource surface, a typed error hierarchy, context cancellation, functional options, safe retries with reused idempotency keys, range-over-func pagination, and webhook verification.

client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil { ... }
msg, err := client.Email.Send(ctx, bird.EmailSendParams{
	From: "hello@acme.com", To: []string{"customer@example.com"},
	Subject: "Welcome", HTML: "<h1>Hi</h1>",
})

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Example

Example constructs a client and sends an email. The region is taken from the API key's prefix; pass option.WithBaseURL or option.WithRegion to override.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	msg, err := client.Email.Send(context.Background(), bird.EmailSendParams{
		From:    "onboarding@messagebird.dev",
		To:      []string{"delivered@messagebird.dev"},
		Subject: "Hello from Bird",
		HTML:    "<p>My first Bird email.</p>",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(msg.Id)
}

Index

Examples

Constants

View Source
const (
	ErrorTypeBadRequest         = apierror.ErrorTypeBadRequest
	ErrorTypeAuth               = apierror.ErrorTypeAuth
	ErrorTypeBilling            = apierror.ErrorTypeBilling
	ErrorTypePermission         = apierror.ErrorTypePermission
	ErrorTypeNotFound           = apierror.ErrorTypeNotFound
	ErrorTypeConflict           = apierror.ErrorTypeConflict
	ErrorTypePrecondition       = apierror.ErrorTypePrecondition
	ErrorTypePayloadTooLarge    = apierror.ErrorTypePayloadTooLarge
	ErrorTypeMisdirected        = apierror.ErrorTypeMisdirected
	ErrorTypeValidation         = apierror.ErrorTypeValidation
	ErrorTypeRateLimit          = apierror.ErrorTypeRateLimit
	ErrorTypeInternal           = apierror.ErrorTypeInternal
	ErrorTypeNotImplemented     = apierror.ErrorTypeNotImplemented
	ErrorTypeServiceUnavailable = apierror.ErrorTypeServiceUnavailable
)

ErrorType values — the coarse categories clients branch on (ADR-0016).

Variables

This section is empty.

Functions

func Bool

func Bool(v bool) *bool

Bool returns a pointer to v.

func Int

func Int(v int) *int

Int returns a pointer to v.

func Ptr

func Ptr[T any](v T) *T

Ptr returns a pointer to v, for setting optional pointer fields inline. Bool, String, and Int are typed shorthands for the common cases:

bird.EmailSendParams{TrackOpens: bird.Bool(false)}

func String

func String(v string) *string

String returns a pointer to v.

Types

type APIError

type APIError = apierror.APIError

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type Audience added in v0.4.0

type Audience = oapi.Audience

Audience is a static audience of contacts; AudienceList is a page of audiences. AudienceMember pairs a contact with the time it joined; AudienceMemberList is a page of members.

type AudienceAddContactsParams added in v0.4.0

type AudienceAddContactsParams struct {
	// Contacts to add to the audience. Adding a contact that is already a member has no effect and keeps its original join time; duplicate IDs in the list are collapsed. If any ID does not exist in the workspace, the whole request fails with a validation error and no contacts are added.
	ContactIDs []string
}

AudienceAddContactsParams is the request body for add_contacts.

type AudienceCreateParams added in v0.4.0

type AudienceCreateParams struct {
	// Display name for the audience.
	Name string
	// Longer description of who this audience is.
	Description string
	// How the audience's recipients are determined. `static` (the default) is an explicit member list you manage via the API. `dynamic` and `external` are preview values and currently unavailable; creating an audience with either returns a validation error.
	Type *AudienceCreateRequestType
}

AudienceCreateParams is the request body for create.

type AudienceCreateRequestType added in v0.14.0

type AudienceCreateRequestType = oapi.AudienceCreateRequestType

type AudienceList added in v0.4.0

type AudienceList = oapi.AudienceList

Audience is a static audience of contacts; AudienceList is a page of audiences. AudienceMember pairs a contact with the time it joined; AudienceMemberList is a page of members.

type AudienceListContactsParams added in v0.4.0

type AudienceListContactsParams struct {
	// Case-insensitive substring match against the member's email address.
	Q string
	// Maximum number of items to return per page.
	Limit int
}

AudienceListContactsParams filters the list. Zero-value fields are omitted.

type AudienceListParams added in v0.4.0

type AudienceListParams struct {
	// Case-insensitive substring match against the audience's name.
	Q string
	// Maximum number of items to return per page.
	Limit int
}

AudienceListParams filters the list. Zero-value fields are omitted.

type AudienceMember added in v0.4.0

type AudienceMember = oapi.AudienceMember

Audience is a static audience of contacts; AudienceList is a page of audiences. AudienceMember pairs a contact with the time it joined; AudienceMemberList is a page of members.

type AudienceMemberList added in v0.4.0

type AudienceMemberList = oapi.AudienceMemberList

Audience is a static audience of contacts; AudienceList is a page of audiences. AudienceMember pairs a contact with the time it joined; AudienceMemberList is a page of members.

type AudienceRemoveContactsParams added in v0.4.0

type AudienceRemoveContactsParams struct {
	// Contacts to remove from the audience. Removing a contact that is not a member has no effect; duplicate IDs in the list are collapsed. If any ID does not exist in the workspace, the whole request fails with a validation error and no memberships are removed.
	ContactIDs []string
}

AudienceRemoveContactsParams is the request body for remove_contacts.

type AudienceUpdateParams added in v0.4.0

type AudienceUpdateParams struct {
	// New display name for the audience. Omit to keep the current name; the name cannot be cleared, and a whitespace-only value returns a validation error.
	Name string
	// Longer description of who this audience is. Set to null to clear.
	Description Nullable[string]
}

AudienceUpdateParams is the request body for update.

type AudiencesService added in v0.4.0

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

AudiencesService manages static audiences and their contact membership: create, read, update, delete, list, and add/remove contacts. Reach it via Client.Audiences.

func (*AudiencesService) AddContacts added in v0.4.0

func (s *AudiencesService) AddContacts(ctx context.Context, audienceId string, params AudienceAddContactsParams, opts ...option.RequestOption) error

AddContacts Add up to 1,000 existing contacts to a static audience by ID. Fails entirely if any contact ID does not exist.

Example

AddContacts adds up to 1,000 existing contacts to a static audience.

package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	err = client.Audiences.AddContacts(context.Background(), "adn_123", bird.AudienceAddContactsParams{
		ContactIDs: []string{"con_1", "con_2"},
	})
	if err != nil {
		log.Fatal(err)
	}
}

func (*AudiencesService) Create added in v0.4.0

Create Create an audience in the workspace. New audiences start empty; add contacts with `audiences.add_contacts` or `contacts.batch`. Only static audiences can be created today.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	audience, err := client.Audiences.Create(context.Background(), bird.AudienceCreateParams{
		Name: "Newsletter subscribers",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(audience.Id)
}

func (*AudiencesService) Delete added in v0.4.0

func (s *AudiencesService) Delete(ctx context.Context, audienceId string, opts ...option.RequestOption) error

Delete Delete an audience and its memberships; contacts themselves are not deleted. Fails while a broadcast targeting the audience is scheduled, accepted, sending, or canceling.

Example

Delete removes an audience. The contacts themselves are not deleted.

package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	if err := client.Audiences.Delete(context.Background(), "adn_123"); err != nil {
		log.Fatal(err)
	}
}

func (*AudiencesService) Get added in v0.4.0

func (s *AudiencesService) Get(ctx context.Context, audienceId string, opts ...option.RequestOption) (*Audience, error)

Get Get a single audience by ID: name, description, and type. Members are listed separately with `audiences.list_contacts`.

Example

Get returns a single audience by id.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	audience, err := client.Audiences.Get(context.Background(), "adn_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(audience.Name)
}

func (*AudiencesService) List added in v0.4.0

List List the workspace's audiences as a cursor page, newest first. Filter by name substring with `q`. Range over it; the second value is non-nil only on the iteration where a fetch failed.

Example

List auto-paginates: it lazily fetches each page and yields every matching audience across all of them.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	for audience, err := range client.Audiences.List(context.Background(), bird.AudienceListParams{Limit: 50}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(audience.Id, audience.Name)
	}
}

func (*AudiencesService) ListContacts added in v0.4.0

func (s *AudiencesService) ListContacts(ctx context.Context, audienceId string, params AudienceListContactsParams, opts ...option.RequestOption) iter.Seq2[*AudienceMember, error]

ListContacts List the contacts in a static audience by ID, as a cursor page ordered by when each contact joined (most recent first). Each entry pairs the contact with its join time. Range over it; the second value is non-nil only on the iteration where a fetch failed.

Example

ListContacts auto-paginates: it lazily fetches each page and yields every member of the audience across all of them.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	for member, err := range client.Audiences.ListContacts(context.Background(), "adn_123", bird.AudienceListContactsParams{Limit: 50}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(member.Contact.Id, member.Contact.Email)
	}
}

func (*AudiencesService) ListContactsPage added in v0.4.0

func (s *AudiencesService) ListContactsPage(ctx context.Context, audienceId string, params AudienceListContactsParams, startingAfter string, opts ...option.RequestOption) (*AudienceMemberList, error)

ListContactsPage fetches one page of results. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the first page.

func (*AudiencesService) ListPage added in v0.4.0

func (s *AudiencesService) ListPage(ctx context.Context, params AudienceListParams, startingAfter string, opts ...option.RequestOption) (*AudienceList, error)

ListPage fetches one page of results. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the first page.

func (*AudiencesService) RemoveContact added in v0.4.0

func (s *AudiencesService) RemoveContact(ctx context.Context, audienceId string, contactId string, opts ...option.RequestOption) error

RemoveContact Remove one contact's membership from an audience. The contact itself is not deleted and stays a member of any other audiences.

Example

RemoveContact removes one contact's membership in an audience. The contact itself is not deleted and remains a member of any other audiences.

package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	if err := client.Audiences.RemoveContact(context.Background(), "adn_123", "con_1"); err != nil {
		log.Fatal(err)
	}
}

func (*AudiencesService) RemoveContacts added in v0.4.0

func (s *AudiencesService) RemoveContacts(ctx context.Context, audienceId string, params AudienceRemoveContactsParams, opts ...option.RequestOption) error

RemoveContacts Remove up to 1,000 contacts from a static audience by ID. Fails entirely if any contact ID does not exist; contacts are not deleted.

Example

RemoveContacts removes up to 1,000 contacts from a static audience. The contacts themselves are not deleted.

package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	err = client.Audiences.RemoveContacts(context.Background(), "adn_123", bird.AudienceRemoveContactsParams{
		ContactIDs: []string{"con_1", "con_2"},
	})
	if err != nil {
		log.Fatal(err)
	}
}

func (*AudiencesService) Update added in v0.4.0

func (s *AudiencesService) Update(ctx context.Context, audienceId string, params AudienceUpdateParams, opts ...option.RequestOption) (*Audience, error)

Update Update an audience's name or description. Omitted fields are unchanged; a null description clears it.

Example

Update changes only the fields set in params; every other field is left unchanged.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	// Rename the audience and clear its description (Null sends an explicit JSON
	// null). Omit a field to leave it unchanged; bird.Value(...) sets a new value.
	audience, err := client.Audiences.Update(context.Background(), "adn_123", bird.AudienceUpdateParams{
		Name:        "Renamed",
		Description: bird.Null[string](),
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(audience.Id)
}

type Category

type Category = oapi.EmailMessageCategory

Category classifies a send's suppression policy.

const (
	CategoryTransactional Category = "transactional"
	CategoryMarketing     Category = "marketing"
)

type Client

type Client struct {
	Email                *EmailService
	Sms                  *SMSService
	SmsTemplates         *SMSTemplatesService
	Whatsapp             *WhatsAppService
	WhatsappTemplates    *WhatsAppTemplatesService
	Verify               *VerifyService
	Webhooks             *WebhookService
	Contacts             *ContactsService
	Audiences            *AudiencesService
	ContactProperties    *ContactPropertiesService
	Domains              *DomainsService
	Mailbox              *MailboxService
	MailboxReceiveRule   *MailboxReceiveRuleService
	MailboxThread        *MailboxThreadService
	MailboxThreadMessage *MailboxThreadMessageService
	// contains filtered or unexported fields
}

Client is the entry point to the SDK. Construct it with NewClient and reach the API through its resource fields.

func NewClient

func NewClient(opts ...option.RequestOption) (*Client, error)

NewClient builds a Client. An API key is required (option.WithAPIKey); the base URL is derived from the key's region prefix unless option.WithBaseURL or option.WithRegion is given.

func (*Client) Delete

func (c *Client) Delete(ctx context.Context, path string, out any, opts ...option.RequestOption) error

func (*Client) Do

func (c *Client) Do(ctx context.Context, method, path string, body, out any, opts ...option.RequestOption) error

Do is the low-level call the verb methods build on: it marshals body as JSON (when non-nil), runs the request lifecycle, and decodes a 2xx body into out (when non-nil).

func (*Client) Get

func (c *Client) Get(ctx context.Context, path string, out any, opts ...option.RequestOption) error

Get, Post, Put, Patch, and Delete are the escape hatch for endpoints outside the curated surface. They run through the same auth, retry, idempotency, and base-URL handling as the typed methods. body (if non-nil) is sent as JSON; a 2xx response is decoded into out (if non-nil).

var out SuppressionList
err := client.Get(ctx, "/v1/email/suppressions", &out)
Example

The verb methods reach endpoints outside the curated surface, decoding the response into a value you provide.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	var out struct {
		Data []struct {
			Recipient string `json:"recipient"`
		} `json:"data"`
	}
	if err := client.Get(context.Background(), "/v1/email/suppressions", &out); err != nil {
		log.Fatal(err)
	}
	fmt.Println(len(out.Data))
}

func (*Client) Patch

func (c *Client) Patch(ctx context.Context, path string, body, out any, opts ...option.RequestOption) error

func (*Client) Post

func (c *Client) Post(ctx context.Context, path string, body, out any, opts ...option.RequestOption) error

func (*Client) Put

func (c *Client) Put(ctx context.Context, path string, body, out any, opts ...option.RequestOption) error

type ConnectionError

type ConnectionError = apierror.ConnectionError

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type Contact added in v0.4.0

type Contact = oapi.Contact

Contact is a workspace contact; ContactList is a page of contacts; ContactUpsertResult is the result of a bulk upsert, with one ContactUpsertResultItem per submitted contact in submission order.

type ContactBatchParams added in v0.4.0

type ContactBatchParams struct {
	Contacts    []ContactCreateParams
	AudienceIDs []string // audiences every contact in the request is added to
	DataMode    string   // "merge" (default) or "replace"; how each contact's Data is applied to its existing stored values
}

ContactBatchParams bulk-upserts contacts matched by email address: existing contacts are updated with the supplied fields, new ones are created. AudienceIDs and DataMode are omitted from the request when left at their zero value.

type ContactCreateParams added in v0.4.0

type ContactCreateParams struct {
	// The contact's email address. Trimmed and lowercased before it is stored and checked for uniqueness. Unique within the workspace.
	Email string
	// The contact's first name.
	FirstName string
	// The contact's last name.
	LastName string
	// Your own identifier for this contact, such as a user ID in your system. Unique within the workspace when set.
	ExternalID string
	// Custom property values for this contact. Each key must be a property created via the contact properties API, and each value must be a string, number, or boolean matching the property's declared type (strings up to 500 characters); a null value is ignored. Unregistered or archived keys are rejected with a validation error. Total size is capped at 2 KB serialized.
	Data map[string]any
}

ContactCreateParams is the request body for create.

type ContactList added in v0.4.0

type ContactList = oapi.ContactList

Contact is a workspace contact; ContactList is a page of contacts; ContactUpsertResult is the result of a bulk upsert, with one ContactUpsertResultItem per submitted contact in submission order.

type ContactListParams added in v0.4.0

type ContactListParams struct {
	// Return the contact with exactly this email address (case-insensitive). Email is unique within a workspace, so this matches at most one contact.
	Email string
	// Return the contact with exactly this external_id (your own identifier for the contact). Unique within a workspace, so this matches at most one contact.
	ExternalID string
	// Case-insensitive substring match against the contact's email address.
	Q string
	// Maximum number of items to return per page.
	Limit int
}

ContactListParams filters the list. Zero-value fields are omitted.

type ContactPropertiesService added in v0.4.0

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

ContactPropertiesService manages workspace contact properties: create, read, update, list, archive, and unarchive. Reach it via Client.ContactProperties.

func (*ContactPropertiesService) Archive added in v0.4.0

func (s *ContactPropertiesService) Archive(ctx context.Context, propertyId string, opts ...option.RequestOption) (*ContactProperty, error)

Archive Archive a contact property: the key is rejected in new contact writes and stops rendering in templates, while stored values remain readable. The key stays reserved and counts toward the 200-property limit; reverse with `contact_properties.unarchive`.

Example

Archive archives a contact property: the key stops being accepted in new contact writes, but every value already stored on contacts is preserved.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	property, err := client.ContactProperties.Archive(context.Background(), "prp_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(property.Archived)
}

func (*ContactPropertiesService) Create added in v0.4.0

Create registers a contact property. Hand-written: FallbackValue is an arbitrary JSON value matching the declared Type, which the generator can't model. Retried safely: a single idempotency key is reused across attempts.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	property, err := client.ContactProperties.Create(context.Background(), bird.ContactPropertyCreateParams{
		Key:  "plan",
		Type: "string",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(property.Id)
}

func (*ContactPropertiesService) Get added in v0.4.0

Get Get a single contact property by ID: key, type, fallback value, and archived state.

Example

Get returns a single contact property by id.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	property, err := client.ContactProperties.Get(context.Background(), "prp_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(property.Key)
}

func (*ContactPropertiesService) List added in v0.4.0

List List the workspace's contact properties as a cursor page, newest first. Archived properties are included, marked by their archived flag. Range over it; the second value is non-nil only on the iteration where a fetch failed.

Example

List auto-paginates: it lazily fetches each page and yields every matching contact property across all of them.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	for property, err := range client.ContactProperties.List(context.Background(), bird.ContactPropertyListParams{Limit: 50}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(property.Id, property.Key)
	}
}

func (*ContactPropertiesService) ListPage added in v0.4.0

ListPage fetches one page of results. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the first page.

func (*ContactPropertiesService) Unarchive added in v0.4.0

func (s *ContactPropertiesService) Unarchive(ctx context.Context, propertyId string, opts ...option.RequestOption) (*ContactProperty, error)

Unarchive Reactivate an archived contact property so its key is accepted in contact writes and renders in templates again. Fails with a conflict if the property is not archived.

Example

Unarchive reactivates an archived contact property.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	property, err := client.ContactProperties.Unarchive(context.Background(), "prp_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(property.Archived)
}

func (*ContactPropertiesService) Update added in v0.4.0

Update changes a contact property's fallback value. Hand-written for the same arbitrary-value reason as Create. Retried safely with a reused idempotency key.

Example

Update changes a contact property's fallback value.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	property, err := client.ContactProperties.Update(context.Background(), "prp_123", bird.ContactPropertyUpdateParams{
		FallbackValue: "free",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(property.Id)
}

type ContactProperty added in v0.4.0

type ContactProperty = oapi.ContactProperty

ContactProperty is a custom contact property definition; ContactPropertyList is a page of properties.

type ContactPropertyCreateParams added in v0.4.0

type ContactPropertyCreateParams struct {
	Key           string // required; lowercase letters, digits, underscores, starting with a letter
	Type          string // required; "string", "number", or "boolean"
	FallbackValue any    // optional; matches the declared Type
}

ContactPropertyCreateParams registers a contact property. Key and Type are required; Type cannot be changed after creation.

type ContactPropertyList added in v0.4.0

type ContactPropertyList = oapi.ContactPropertyList

ContactProperty is a custom contact property definition; ContactPropertyList is a page of properties.

type ContactPropertyListParams added in v0.4.0

type ContactPropertyListParams struct {
	// Maximum number of items to return per page.
	Limit int
}

ContactPropertyListParams filters the list. Zero-value fields are omitted.

type ContactPropertyUpdateParams added in v0.4.0

type ContactPropertyUpdateParams struct {
	FallbackValue any // optional; nil leaves the fallback unchanged
}

ContactPropertyUpdateParams changes a contact property's fallback value.

type ContactUpdateParams added in v0.4.0

type ContactUpdateParams struct {
	Email      *string
	ExternalID Nullable[string]
	FirstName  Nullable[string]
	LastName   Nullable[string]
	Data       map[string]any
}

ContactUpdateParams is a partial update of a contact. Omit a field to leave it unchanged. Email is a pointer — nil leaves it unchanged, and a contact's email cannot be cleared. FirstName, LastName, and ExternalID are Nullable: bird.Value sets a value, bird.Null clears the field (explicit JSON null), and the zero value omits it. A key in Data set to nil removes that key from the contact's stored custom values; keys omitted from Data are left unchanged.

type ContactUpsertResult added in v0.4.0

type ContactUpsertResult = oapi.ContactUpsertResult

Contact is a workspace contact; ContactList is a page of contacts; ContactUpsertResult is the result of a bulk upsert, with one ContactUpsertResultItem per submitted contact in submission order.

type ContactUpsertResultItem added in v0.4.0

type ContactUpsertResultItem = oapi.ContactUpsertResultItem

Contact is a workspace contact; ContactList is a page of contacts; ContactUpsertResult is the result of a bulk upsert, with one ContactUpsertResultItem per submitted contact in submission order.

type ContactsService added in v0.4.0

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

ContactsService manages workspace contacts: create, read, update, delete, bulk upsert, and list. Reach it via Client.Contacts.

func (*ContactsService) Batch added in v0.4.0

Batch creates or updates up to a batch's worth of contacts in one request, matched by email address. Retried safely with a reused idempotency key.

Example

Batch creates or updates several contacts, matched by email address, in one request.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	result, err := client.Contacts.Batch(context.Background(), bird.ContactBatchParams{
		Contacts: []bird.ContactCreateParams{
			{Email: "a@x.com"},
		},
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, item := range result.Data {
		fmt.Println(item.Email, item.Status)
	}
}

func (*ContactsService) Create added in v0.4.0

Create Create a contact by email address in the workspace. Fails with a conflict if the email or external_id is already used by another contact. For bulk import or create-or-update semantics use `contacts.batch`.

Example

Create a contact. Unset optional fields are omitted from the request.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	contact, err := client.Contacts.Create(context.Background(), bird.ContactCreateParams{
		Email:     "jane@acme.com",
		FirstName: "Jane",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(contact.Id)
}

func (*ContactsService) Delete added in v0.4.0

func (s *ContactsService) Delete(ctx context.Context, contactId string, opts ...option.RequestOption) error

Delete Delete a contact and remove it from every audience it belongs to. Suppression records for the address are unaffected.

Example

Delete removes a contact.

package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	if err := client.Contacts.Delete(context.Background(), "con_123"); err != nil {
		log.Fatal(err)
	}
}

func (*ContactsService) Get added in v0.4.0

func (s *ContactsService) Get(ctx context.Context, contactId string, opts ...option.RequestOption) (*Contact, error)

Get Get a single contact by ID (`con_`-prefixed). Look up an ID by exact email or external_id with `contacts.list`.

Example

Get returns a single contact by id.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	contact, err := client.Contacts.Get(context.Background(), "con_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(contact.Email)
}

func (*ContactsService) List added in v0.4.0

List List the workspace's contacts as a cursor page, newest first. Look one up by exact email or external_id, or search by email substring. Range over it; the second value is non-nil only on the iteration where a fetch failed.

Example

List auto-paginates: it lazily fetches each page and yields every matching contact across all of them.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	for contact, err := range client.Contacts.List(context.Background(), bird.ContactListParams{Limit: 50}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(contact.Id, contact.Email)
	}
}

func (*ContactsService) ListPage added in v0.4.0

func (s *ContactsService) ListPage(ctx context.Context, params ContactListParams, startingAfter string, opts ...option.RequestOption) (*ContactList, error)

ListPage fetches one page of results. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the first page.

func (*ContactsService) Update added in v0.4.0

func (s *ContactsService) Update(ctx context.Context, id string, params ContactUpdateParams, opts ...option.RequestOption) (*Contact, error)

Update edits a contact. Only the fields set in params change. Retried safely with a reused idempotency key.

Example

Update changes only the fields set in params; every other field is left unchanged.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	// Set the first name and clear the last name (Null sends an explicit JSON
	// null); omit a field to leave it unchanged.
	contact, err := client.Contacts.Update(context.Background(), "con_123", bird.ContactUpdateParams{
		FirstName: bird.Value("Jane"),
		LastName:  bird.Null[string](),
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(contact.Id)
}

type DNSRecord added in v0.8.0

type DNSRecord = oapi.DNSRecord

Domain is a sending domain with its DNS records and per-capability status; DomainList is a page of domains. DNSRecord is one required DNS record and its verification state; DomainDKIM is the domain's active DKIM signing configuration; DomainCapabilities is the per-capability readiness breakdown. These are the read-side types; the write-side configs are the *Config structs in domains.go.

type Domain added in v0.8.0

type Domain = oapi.Domain

Domain is a sending domain with its DNS records and per-capability status; DomainList is a page of domains. DNSRecord is one required DNS record and its verification state; DomainDKIM is the domain's active DKIM signing configuration; DomainCapabilities is the per-capability readiness breakdown. These are the read-side types; the write-side configs are the *Config structs in domains.go.

type DomainCapabilities added in v0.8.0

type DomainCapabilities = oapi.DomainCapabilities

Domain is a sending domain with its DNS records and per-capability status; DomainList is a page of domains. DNSRecord is one required DNS record and its verification state; DomainDKIM is the domain's active DKIM signing configuration; DomainCapabilities is the per-capability readiness breakdown. These are the read-side types; the write-side configs are the *Config structs in domains.go.

type DomainCapability added in v0.8.0

type DomainCapability = oapi.DomainCapability

Domain is a sending domain with its DNS records and per-capability status; DomainList is a page of domains. DNSRecord is one required DNS record and its verification state; DomainDKIM is the domain's active DKIM signing configuration; DomainCapabilities is the per-capability readiness breakdown. These are the read-side types; the write-side configs are the *Config structs in domains.go.

type DomainCreateParams added in v0.8.0

type DomainCreateParams struct {
	Domain     string // required
	ReturnPath *DomainReturnPathConfig
	Tracking   *DomainTrackingConfig
	Dkim       *DomainDKIMConfig
	Settings   *DomainSettings
}

DomainCreateParams registers a sending domain. Domain is required; the config blocks are optional and default server-side when omitted.

type DomainDKIM added in v0.8.0

type DomainDKIM = oapi.DomainDKIM

Domain is a sending domain with its DNS records and per-capability status; DomainList is a page of domains. DNSRecord is one required DNS record and its verification state; DomainDKIM is the domain's active DKIM signing configuration; DomainCapabilities is the per-capability readiness breakdown. These are the read-side types; the write-side configs are the *Config structs in domains.go.

type DomainDKIMConfig added in v0.8.0

type DomainDKIMConfig struct {
	Mode string
}

DomainDKIMConfig configures DKIM signing. Mode is "" (default), "txt", or "delegated" ("delegated" is a preview value the server currently rejects).

type DomainFailedEvent

type DomainFailedEvent = oapi.EventDomainFailed

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type DomainInboundConfig added in v0.8.0

type DomainInboundConfig struct {
	Enabled bool
}

DomainInboundConfig enables or disables receiving on the domain.

type DomainList added in v0.8.0

type DomainList = oapi.DomainList

Domain is a sending domain with its DNS records and per-capability status; DomainList is a page of domains. DNSRecord is one required DNS record and its verification state; DomainDKIM is the domain's active DKIM signing configuration; DomainCapabilities is the per-capability readiness breakdown. These are the read-side types; the write-side configs are the *Config structs in domains.go.

type DomainListParams added in v0.8.0

type DomainListParams struct {
	Name  string // optional case-insensitive substring match on the domain name
	Limit int
}

DomainListParams filters the domain list. Zero-value fields are omitted.

type DomainReturnPathConfig added in v0.8.0

type DomainReturnPathConfig struct {
	Name string
}

DomainReturnPathConfig configures the return-path (bounce) domain. Provide only the name part; Bird appends the sending domain.

type DomainSettings added in v0.8.0

type DomainSettings struct {
	ClickTracking *bool
	OpenTracking  *bool
}

DomainSettings toggles per-domain sending behavior. Each field is a pointer: nil leaves it unchanged (on update) or defaults server-side (on create); point it at a value to set it. Enabling tracking requires a tracking domain, else the API returns 409.

type DomainStatus added in v0.8.0

type DomainStatus = oapi.DomainStatus

Domain is a sending domain with its DNS records and per-capability status; DomainList is a page of domains. DNSRecord is one required DNS record and its verification state; DomainDKIM is the domain's active DKIM signing configuration; DomainCapabilities is the per-capability readiness breakdown. These are the read-side types; the write-side configs are the *Config structs in domains.go.

type DomainTrackingConfig added in v0.8.0

type DomainTrackingConfig struct {
	Name string
}

DomainTrackingConfig configures the branded open/click tracking domain. Provide only the name part; Bird appends the sending domain (e.g. "links" on "mail.acme.com" becomes "links.mail.acme.com").

type DomainUpdateParams added in v0.8.0

type DomainUpdateParams struct {
	Settings      *DomainSettings
	ReturnPath    *DomainReturnPathConfig
	Tracking      *DomainTrackingConfig
	ClearTracking bool
	Dkim          *DomainDKIMConfig
	Inbound       *DomainInboundConfig
}

DomainUpdateParams is a partial update. Every field is optional: a nil config leaves that part unchanged. Set ClearTracking to remove the tracking domain (sends tracking: null) — both tracking toggles must be off first, else the API returns 409. ClearTracking takes precedence over Tracking.

type DomainVerifiedEvent

type DomainVerifiedEvent = oapi.EventDomainVerified

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type DomainsService added in v0.8.0

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

DomainsService manages sending domains: register, read, update, delete, list, and verify. Reach it via Client.Domains. Register a domain, publish the DNS records it returns, then call Verify until it is usable as a sender.

func (*DomainsService) Create added in v0.8.0

func (s *DomainsService) Create(ctx context.Context, params DomainCreateParams, opts ...option.RequestOption) (*Domain, error)

Create registers a sending domain. It returns in "pending" with the DNS records to publish; call Verify once they are in place. Retried safely: a single idempotency key is reused across attempts. Provide your own key with option.WithIdempotencyKey.

Example

Register a sending domain. It returns in "pending" with the DNS records to publish; call Verify once they are in place.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	domain, err := client.Domains.Create(context.Background(), bird.DomainCreateParams{
		Domain: "mail.acme.com",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(domain.Id, *domain.Status)
}

func (*DomainsService) Delete added in v0.8.0

func (s *DomainsService) Delete(ctx context.Context, id string, opts ...option.RequestOption) error

Delete removes a sending domain. Mail already accepted still sends; no new mail can be sent from it. Retried safely with a reused idempotency key.

Example

Delete removes a sending domain.

package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	if err := client.Domains.Delete(context.Background(), "dom_123"); err != nil {
		log.Fatal(err)
	}
}

func (*DomainsService) Get added in v0.8.0

func (s *DomainsService) Get(ctx context.Context, id string, opts ...option.RequestOption) (*Domain, error)

Get returns a single sending domain by id, with its DNS records and their per-record verification state.

Example

Get returns a single sending domain by id, with its DNS records.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	domain, err := client.Domains.Get(context.Background(), "dom_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(*domain.Domain)
}

func (*DomainsService) List added in v0.8.0

List walks every sending domain matching params, fetching pages lazily. Range over it; the second value is non-nil only on the iteration where a fetch failed.

Example

List auto-paginates: it lazily fetches each page and yields every sending domain across all of them.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	for domain, err := range client.Domains.List(context.Background(), bird.DomainListParams{Limit: 50}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(domain.Id, *domain.Status)
	}
}

func (*DomainsService) ListPage added in v0.8.0

func (s *DomainsService) ListPage(ctx context.Context, params DomainListParams, startingAfter string, opts ...option.RequestOption) (*DomainList, error)

ListPage fetches one page of sending domains. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the most recent.

func (*DomainsService) Update added in v0.8.0

func (s *DomainsService) Update(ctx context.Context, id string, params DomainUpdateParams, opts ...option.RequestOption) (*Domain, error)

Update edits a sending domain. Only the fields set in params change; settings apply immediately, while return-path/tracking/DKIM changes are staged until their new DNS records verify. Retried safely with a reused idempotency key.

Example

Update edits a sending domain. Only the fields you set change.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	domain, err := client.Domains.Update(context.Background(), "dom_123", bird.DomainUpdateParams{
		Settings: &bird.DomainSettings{ClickTracking: bird.Bool(true), OpenTracking: bird.Bool(true)},
		Tracking: &bird.DomainTrackingConfig{Name: "links"},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(domain.Id)
}

func (*DomainsService) Verify added in v0.8.0

func (s *DomainsService) Verify(ctx context.Context, id string, opts ...option.RequestOption) (*Domain, error)

Verify triggers a fresh DNS check and returns the refreshed domain with per-record results. Safe to repeat while waiting for DNS to propagate. Retried safely with a reused idempotency key.

Example

Verify triggers a fresh DNS check and returns the refreshed domain. Safe to repeat while waiting for DNS to propagate.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	domain, err := client.Domains.Verify(context.Background(), "dom_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(*domain.Status)
}

type EmailAcceptedEvent

type EmailAcceptedEvent = oapi.EventEmailAccepted

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailAttachment

type EmailAttachment = oapi.EmailAttachment

EmailAttachment is a file attachment on a send.

type EmailBatch added in v0.2.0

type EmailBatch = oapi.EmailMessageBatchResponse

EmailBatch is the result of a batch send: one item per submitted message, in submission order.

type EmailBatchItem added in v0.2.0

type EmailBatchItem = oapi.EmailMessageBatchItem

EmailBatchItem is a single message's entry in a batch send result.

type EmailBouncedEvent

type EmailBouncedEvent = oapi.EventEmailBounced

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailClickedEvent

type EmailClickedEvent = oapi.EventEmailClicked

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailComplainedEvent

type EmailComplainedEvent = oapi.EventEmailComplained

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailDefaults

type EmailDefaults = requestconfig.EmailDefaults

EmailDefaults are values applied to an email send when the per-send params leave the field unset. Configure with option.WithEmailDefaults.

Example

EmailDefaults set common send fields once; a per-send value always wins.

package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(
		option.WithAPIKey(os.Getenv("BIRD_API_KEY")),
		option.WithEmailDefaults(bird.EmailDefaults{
			From:     "hello@acme.com",
			Category: bird.CategoryTransactional,
		}),
	)
	if err != nil {
		log.Fatal(err)
	}
	// From is filled from the default.
	if _, err := client.Email.Send(context.Background(), bird.EmailSendParams{
		To: []string{"customer@example.com"}, Subject: "Hi", HTML: "<p>hi</p>",
	}); err != nil {
		log.Fatal(err)
	}
}

type EmailDeferredEvent

type EmailDeferredEvent = oapi.EventEmailDeferred

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailDeliveredEvent

type EmailDeliveredEvent = oapi.EventEmailDelivered

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailListParams

type EmailListParams struct {
	Limit         int
	Status        EmailStatus
	Category      Category
	Tag           string
	To            string
	From          string
	CreatedAfter  time.Time
	CreatedBefore time.Time
}

EmailListParams filters the message list. Zero-value fields are omitted.

type EmailListUnsubscribedEvent

type EmailListUnsubscribedEvent = oapi.EventEmailListUnsubscribed

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailMailboxLabelList added in v0.12.0

type EmailMailboxLabelList = oapi.EmailMailboxLabelList

EmailMailboxLabelList is the list of labels available in a mailbox.

type EmailMessage

type EmailMessage = oapi.EmailMessage

EmailMessage is a sent message with aggregate delivery status.

type EmailMessageList

type EmailMessageList = oapi.EmailMessageList

EmailMessageList is one page of messages plus its pagination cursors.

type EmailOpenedEvent

type EmailOpenedEvent = oapi.EventEmailOpened

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailOutOfBandBounceEvent

type EmailOutOfBandBounceEvent = oapi.EventEmailOutOfBandBounce

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailProcessedEvent

type EmailProcessedEvent = oapi.EventEmailProcessed

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailReceivedEvent

type EmailReceivedEvent = oapi.EventEmailReceived

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailRejectedEvent

type EmailRejectedEvent = oapi.EventEmailRejected

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailSendBatchParams added in v0.2.0

type EmailSendBatchParams struct {
	Messages []EmailSendParams
}

EmailSendBatchParams is a batch of email sends submitted in one request. Each Message is an individual send; the whole batch is validated before any item is queued. The result preserves submission order.

type EmailSendParams

type EmailSendParams struct {
	From        string            // sender; bare address or "Name <addr>" form; must be on a verified domain
	To          []string          // primary recipients; each may be bare or "Name <addr>" form
	Cc          []string          // optional; same syntax as To
	Bcc         []string          // optional; same syntax as To
	ReplyTo     []string          // optional Reply-To; same syntax as To
	Subject     string            // subject line
	HTML        string            // HTML body; at least one of HTML or Text is required
	Text        string            // plain-text body
	Tags        []EmailTag        // structured {name,value} labels for filtering and analytics
	Metadata    map[string]any    // arbitrary JSON, echoed on reads and in webhook payloads
	Headers     map[string]string // custom email headers
	Attachments []EmailAttachment // file attachments
	Category    Category          // transactional (default) or marketing
	IpPoolId    string            // IP pool ID (ipp_…); workspace default when empty
	// TrackOpens and TrackClicks are pointers because the server default is
	// true — a nil leaves the default, false explicitly disables tracking.
	TrackOpens  *bool
	TrackClicks *bool
	// Template, when set, sends a published template in place of inline content:
	// leave Subject/HTML/Text empty (the template supplies them) and personalize
	// with Parameters. The value is the template's ID (`emt_…`) or its name handle.
	Template string
	// Parameters holds template variables rendered into the subject and
	// body at send time; works with both inline content and a Template.
	Parameters map[string]any
}

EmailSendParams is an email send. Optional fields are omitted from the request when left at their zero value.

Address fields (From, To, Cc, Bcc, ReplyTo) accept either a bare email address or RFC 5322 mailbox syntax with a display name: "Support Team <support@example.com>".

type EmailService

type EmailService struct {

	// Stats reads aggregated delivery and engagement statistics.
	Stats *EmailStatsService
	// contains filtered or unexported fields
}

EmailService sends and reads email messages. Reach it via Client.Email.

func (*EmailService) Cancel added in v0.4.1

func (s *EmailService) Cancel(ctx context.Context, id string, opts ...option.RequestOption) error

Cancel cancels a message scheduled with ScheduledAt before it sends. Only a message that is still scheduled can be canceled; one that already started sending — or was previously canceled — returns a conflict error. It returns no content on success. Retries reuse one idempotency key; provide your own with option.WithIdempotencyKey.

func (*EmailService) Get

Get returns a single message by ID, with aggregate delivery status rolled up across recipients.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	msg, err := client.Email.Get(context.Background(), "em_abc123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(*msg.Status, *msg.DeliveredCount)
}

func (*EmailService) List

List walks every message matching params, fetching pages lazily. Range over it; the second value is non-nil only on the iteration where a fetch failed, after which the sequence ends.

for msg, err := range client.Email.List(ctx, bird.EmailListParams{Status: bird.EmailStatusBounced}) {
	if err != nil { return err }
	log.Println(msg.Id)
}
Example

List auto-paginates: it lazily fetches each page and yields every matching message across all of them.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	for msg, err := range client.Email.List(context.Background(), bird.EmailListParams{Status: bird.EmailStatusBounced}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(msg.Id)
	}
	page, err := client.Email.ListPage(context.Background(), bird.EmailListParams{}, "")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(len(page.Data)) // page.NextCursor carries the next starting_after
}

func (*EmailService) ListPage

func (s *EmailService) ListPage(ctx context.Context, params EmailListParams, startingAfter string, opts ...option.RequestOption) (*EmailMessageList, error)

ListPage fetches one page of messages. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the most recent.

func (*EmailService) Send

Send delivers an email and returns the created message. Sends are retried safely: a single idempotency key is reused across attempts, so a retry never double-delivers. Provide your own key with option.WithIdempotencyKey.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	msg, err := client.Email.Send(context.Background(), bird.EmailSendParams{
		From:    "onboarding@messagebird.dev",
		To:      []string{"delivered@messagebird.dev"},
		Subject: "Hello from Bird",
		HTML:    "<p>My first Bird email.</p>",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(msg.Id, *msg.Status)
}
Example (DisplayNames)

Send with display names: "Name <addr>" syntax in From and To.

package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	_, err = client.Email.Send(context.Background(), bird.EmailSendParams{
		From:    "Bird Support <support@acme.com>",
		To:      []string{"Jane Doe <jane@example.com>", "bob@example.com"},
		Subject: "Your order is confirmed",
		HTML:    "<p>Thanks for your order!</p>",
	})
	if err != nil {
		log.Fatal(err)
	}
}
Example (Errors)

Branch on the typed error hierarchy. The SDK already retries transient failures (timeouts, 429, 5xx), so a returned error is terminal — most callers just propagate it; branch only to act on a category.

package main

import (
	"context"
	"errors"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	_, err = client.Email.Send(context.Background(), bird.EmailSendParams{
		From: "onboarding@messagebird.dev", To: []string{"delivered@messagebird.dev"}, Subject: "Hello from Bird", HTML: "<p>My first Bird email.</p>",
	})
	if err != nil {
		var rle *bird.RateLimitError
		var ve *bird.ValidationError
		var ae *bird.APIError
		switch {
		case errors.As(err, &rle):
			fmt.Println("rate limited; retry after", rle.RetryAfter)
		case errors.As(err, &ve):
			for _, d := range ve.Details {
				fmt.Printf("%s: %s\n", d.Param, d.Message)
			}
		case errors.As(err, &ae):
			fmt.Printf("API error %s (status %d, request %s)\n", ae.Code, ae.StatusCode, ae.RequestID)
		default:
			log.Print(err) // transport: *bird.ConnectionError or *bird.TimeoutError
		}
	}
}
Example (Rich)

A richer send: cc/bcc, reply-to, tags, metadata, opt-out of click tracking, and an idempotency key (safe to retry — the server dedupes).

package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	_, err = client.Email.Send(context.Background(), bird.EmailSendParams{
		From:        "hello@acme.com",
		To:          []string{"a@example.com", "b@example.com"},
		Cc:          []string{"manager@example.com"},
		ReplyTo:     []string{"support@acme.com"},
		Subject:     "Your March invoice",
		HTML:        "<p>Attached.</p>",
		Tags:        []bird.EmailTag{{Name: "category", Value: "billing"}},
		Metadata:    map[string]any{"invoice_id": "inv_123"},
		TrackClicks: bird.Bool(false),
	}, option.WithIdempotencyKey("invoice-march/cust_1"))
	if err != nil {
		log.Fatal(err)
	}
}

func (*EmailService) SendBatch added in v0.2.0

func (s *EmailService) SendBatch(ctx context.Context, params EmailSendBatchParams, opts ...option.RequestOption) (*EmailBatch, error)

SendBatch queues multiple emails in one request and returns one result item per submitted message, in submission order. The whole batch is validated before any item is queued. Like Send, the batch is retried safely: a single idempotency key is reused across attempts, so a retry never double-delivers. Provide your own key with option.WithIdempotencyKey.

Example

SendBatch queues several emails in one request and returns one result item per message, in submission order.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	batch, err := client.Email.SendBatch(context.Background(), bird.EmailSendBatchParams{
		Messages: []bird.EmailSendParams{
			{
				From:    "onboarding@messagebird.dev",
				To:      []string{"alice@example.com"},
				Subject: "Hello, Alice",
				HTML:    "<p>Welcome!</p>",
			},
			{
				From:    "onboarding@messagebird.dev",
				To:      []string{"bob@example.com"},
				Subject: "Hello, Bob",
				HTML:    "<p>Welcome!</p>",
			},
		},
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, item := range batch.Data {
		fmt.Println(item.Id)
	}
}

type EmailStatsByBounceCodeParams added in v0.10.0

type EmailStatsByBounceCodeParams struct {
	// Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted.
	From time.Time
	// End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
	To time.Time
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
	Category string
	// Metric to rank rows by, applied descending. Defaults to `bounced`. Only bounce counts are sortable; this breakdown has no rates.
	Sort string
	// Maximum number of bounce-code rows to return, ranked by the `sort` field descending.
	Limit int
}

EmailStatsByBounceCodeParams filters the by_bounce_code read.

type EmailStatsByBounceCodeResponse added in v0.10.0

type EmailStatsByBounceCodeResponse = oapi.EmailStatsByBounceCodeResponse

Email statistics responses, returned by the Client.Email.Stats methods. Each is the read-side body for one breakdown.

type EmailStatsByBroadcastParams added in v0.10.0

type EmailStatsByBroadcastParams struct {
	// Start date (inclusive) in YYYY-MM-DD, UTC. Defaults to 30 days before `to` when omitted.
	From time.Time
	// End date (inclusive) in YYYY-MM-DD, UTC. Defaults to today (UTC) when omitted. Window may not exceed 365 days.
	To time.Time
	// Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
	Category string
	// Metric to rank rows by, applied descending. Any count or rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `processed`.
	Sort string
	// Maximum number of broadcast rows to return, ranked by the `sort` field descending.
	Limit int
	// Requests a per-row `trend` series. Not available for the broadcast breakdown; supplying `true` returns 422.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect on this breakdown, where `include_trend` is not available.
	TrendGrain string
}

EmailStatsByBroadcastParams filters the by_broadcast read.

type EmailStatsByBroadcastResponse added in v0.10.0

type EmailStatsByBroadcastResponse = oapi.EmailStatsByBroadcastResponse

Email statistics responses, returned by the Client.Email.Stats methods. Each is the read-side body for one breakdown.

type EmailStatsByCategoryParams added in v0.10.0

type EmailStatsByCategoryParams struct {
	// Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted; with `include_trend=true` and `trend_grain=hourly` the default tightens to 29 days before `to`, keeping the defaulted window within the 720-hour trend cap.
	From time.Time
	// End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
	To time.Time
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Metric to rank rows by, applied descending. Any count or rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `processed`.
	Sort string
	// Maximum number of category rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also carries a `trend` array: a short per-bucket series of that category's delivery and engagement rates over the window. Returned only when `limit` is 50 or fewer and the window is at most 90 days (trend_grain=daily) or 720 hours (trend_grain=hourly); a larger request returns 422. When `from` is omitted and `trend_grain=hourly`, the default window is 30 days (720 hours), so a request built entirely from defaults always fits the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain string
}

EmailStatsByCategoryParams filters the by_category read.

type EmailStatsByCategoryResponse added in v0.10.0

type EmailStatsByCategoryResponse = oapi.EmailStatsByCategoryResponse

Email statistics responses, returned by the Client.Email.Stats methods. Each is the read-side body for one breakdown.

type EmailStatsByClientParams added in v0.10.0

type EmailStatsByClientParams struct {
	// Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted.
	From time.Time
	// End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
	To time.Time
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
	Category string
	// Which reading-environment facet to group rows by. `email_client` (default) groups by mail client; `os` groups by operating system; `device_type` groups by device type. Each row populates the chosen facet and leaves the other two null.
	GroupBy string
	// Metric to rank rows by, applied descending. Defaults to `unique_opens`. Only engagement counts are sortable; this breakdown has no rates.
	Sort string
	// Maximum number of client rows to return, ranked by the `sort` field descending.
	Limit int
}

EmailStatsByClientParams filters the by_client read.

type EmailStatsByClientResponse added in v0.10.0

type EmailStatsByClientResponse = oapi.EmailStatsByClientResponse

Email statistics responses, returned by the Client.Email.Stats methods. Each is the read-side body for one breakdown.

type EmailStatsByComplaintTypeParams added in v0.10.0

type EmailStatsByComplaintTypeParams struct {
	// Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted.
	From time.Time
	// End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
	To time.Time
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
	Category string
	// Metric to rank rows by, applied descending. Defaults to `complained`, the only sortable metric for this breakdown.
	Sort string
	// Maximum number of complaint-type rows to return, ranked by `complained` descending.
	Limit int
}

EmailStatsByComplaintTypeParams filters the by_complaint_type read.

type EmailStatsByComplaintTypeResponse added in v0.10.0

type EmailStatsByComplaintTypeResponse = oapi.EmailStatsByComplaintTypeResponse

Email statistics responses, returned by the Client.Email.Stats methods. Each is the read-side body for one breakdown.

type EmailStatsByLocationParams added in v0.10.0

type EmailStatsByLocationParams struct {
	// Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted.
	From time.Time
	// End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
	To time.Time
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
	Category string
	// Location granularity for each row. `country` (default) groups by country; `region` groups by region within country; `city` groups by city within region. Each row reports the location hierarchy down to the chosen level.
	GroupBy string
	// Metric to rank rows by, applied descending. Defaults to `unique_opens`. Only engagement counts are sortable; this breakdown has no rates.
	Sort string
	// Maximum number of location rows to return, ranked by the `sort` field descending.
	Limit int
}

EmailStatsByLocationParams filters the by_location read.

type EmailStatsByLocationResponse added in v0.10.0

type EmailStatsByLocationResponse = oapi.EmailStatsByLocationResponse

Email statistics responses, returned by the Client.Email.Stats methods. Each is the read-side body for one breakdown.

type EmailStatsByMailboxProviderParams added in v0.10.0

type EmailStatsByMailboxProviderParams struct {
	// Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted; with `include_trend=true` and `trend_grain=hourly` the default tightens to 29 days before `to`, keeping the defaulted window within the 720-hour trend cap.
	From time.Time
	// End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
	To time.Time
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
	Category string
	// Metric to rank rows by, applied descending. Any count or rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `delivered`. `processed`, `rejected`, and `oob_bounces` are not part of this breakdown's rows, so they are not sortable here.
	Sort string
	// Maximum number of mailbox-provider rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also carries a `trend` array: a short per-bucket series of that provider's delivery and engagement rates over the window. Returned only when `limit` is 50 or fewer and the window is at most 90 days (trend_grain=daily) or 720 hours (trend_grain=hourly); a larger request returns 422. When `from` is omitted and `trend_grain=hourly`, the default window is 30 days (720 hours), so a request built entirely from defaults always fits the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain string
}

EmailStatsByMailboxProviderParams filters the by_mailbox_provider read.

type EmailStatsByMailboxProviderRegionParams added in v0.10.0

type EmailStatsByMailboxProviderRegionParams struct {
	// Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted; with `include_trend=true` and `trend_grain=hourly` the default tightens to 29 days before `to`, keeping the defaulted window within the 720-hour trend cap.
	From time.Time
	// End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
	To time.Time
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
	Category string
	// Metric to rank rows by, applied descending. Any count or rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `delivered`. `processed`, `rejected`, and `oob_bounces` are not part of this breakdown's rows, so they are not sortable here.
	Sort string
	// Maximum number of provider-region rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also carries a `trend` array: a short per-bucket series of that provider region's delivery and engagement rates over the window. Returned only when `limit` is 50 or fewer and the window is at most 90 days (trend_grain=daily) or 720 hours (trend_grain=hourly); a larger request returns 422. When `from` is omitted and `trend_grain=hourly`, the default window is 30 days (720 hours), so a request built entirely from defaults always fits the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain string
}

EmailStatsByMailboxProviderRegionParams filters the by_mailbox_provider_region read.

type EmailStatsByMailboxProviderRegionResponse added in v0.10.0

type EmailStatsByMailboxProviderRegionResponse = oapi.EmailStatsByMailboxProviderRegionResponse

Email statistics responses, returned by the Client.Email.Stats methods. Each is the read-side body for one breakdown.

type EmailStatsByMailboxProviderResponse added in v0.10.0

type EmailStatsByMailboxProviderResponse = oapi.EmailStatsByMailboxProviderResponse

Email statistics responses, returned by the Client.Email.Stats methods. Each is the read-side body for one breakdown.

type EmailStatsByRecipientDomainParams added in v0.10.0

type EmailStatsByRecipientDomainParams struct {
	// Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted; with `include_trend=true` and `trend_grain=hourly` the default tightens to 29 days before `to`, keeping the defaulted window within the 720-hour trend cap.
	From time.Time
	// End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
	To time.Time
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
	Category string
	// Metric to rank rows by, applied descending. Any count or rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `processed`.
	Sort string
	// Maximum number of recipient-domain rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also carries a `trend` array: a short per-bucket series of that recipient domain's delivery and engagement rates over the window. Returned only when `limit` is 50 or fewer and the window is at most 90 days (trend_grain=daily) or 720 hours (trend_grain=hourly); a larger request returns 422. When `from` is omitted and `trend_grain=hourly`, the default window is 30 days (720 hours), so a request built entirely from defaults always fits the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain string
}

EmailStatsByRecipientDomainParams filters the by_recipient_domain read.

type EmailStatsByRecipientDomainResponse added in v0.10.0

type EmailStatsByRecipientDomainResponse = oapi.EmailStatsByRecipientDomainResponse

Email statistics responses, returned by the Client.Email.Stats methods. Each is the read-side body for one breakdown.

type EmailStatsBySendingDomainParams added in v0.10.0

type EmailStatsBySendingDomainParams struct {
	// Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted; with `include_trend=true` and `trend_grain=hourly` the default tightens to 29 days before `to`, keeping the defaulted window within the 720-hour trend cap.
	From time.Time
	// End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
	To time.Time
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
	Category string
	// Metric to rank rows by, applied descending. Any count or rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `processed`.
	Sort string
	// Maximum number of domain rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also carries a `trend` array: a short per-bucket series of that row's delivery and engagement rates over the window. Returned only when `limit` is 50 or fewer and the window is at most 90 days (trend_grain=daily) or 720 hours (trend_grain=hourly); a larger request returns 422. When `from` is omitted and `trend_grain=hourly`, the default window is 30 days (720 hours), so a request built entirely from defaults always fits the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain string
}

EmailStatsBySendingDomainParams filters the by_sending_domain read.

type EmailStatsBySendingDomainResponse added in v0.10.0

type EmailStatsBySendingDomainResponse = oapi.EmailStatsBySendingDomainResponse

Email statistics responses, returned by the Client.Email.Stats methods. Each is the read-side body for one breakdown.

type EmailStatsBySendingIPParams added in v0.13.0

type EmailStatsBySendingIPParams struct {
	// Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted; with `include_trend=true` and `trend_grain=hourly` the default tightens to 29 days before `to`, keeping the defaulted window within the 720-hour trend cap.
	From time.Time
	// End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
	To time.Time
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
	Category string
	// Metric to rank IPs by, applied descending. `bounces.block` surfaces the IPs whose reputation is most likely degraded. Rows whose rate is undefined (zero denominator) sort last. Defaults to `delivered`. Engagement metrics (a sending IP carries no engagement), `processed`, `rejected`, and `oob_bounces` are not sortable here.
	Sort string
	// Maximum number of IP rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also carries a `trend` array: a short per-bucket series of that IP's delivery rates over the window (per-IP rows have no engagement, so each trend point's open and click rates read 0 in buckets that had deliveries and null in buckets that had none). Returned only when `limit` is 50 or fewer and the window is at most 90 days (trend_grain=daily) or 720 hours (trend_grain=hourly); a larger request returns 422. When `from` is omitted and `trend_grain=hourly`, the default window is 30 days (720 hours), so a request built entirely from defaults always fits the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain string
}

EmailStatsBySendingIPParams filters the by_sending_ip read.

type EmailStatsBySendingIPResponse added in v0.13.0

type EmailStatsBySendingIPResponse = oapi.EmailStatsBySendingIpResponse

Email statistics responses, returned by the Client.Email.Stats methods. Each is the read-side body for one breakdown.

type EmailStatsByTagParams added in v0.10.0

type EmailStatsByTagParams struct {
	// Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted; with `include_trend=true` and `trend_grain=hourly` the default tightens to 29 days before `to`, keeping the defaulted window within the 720-hour trend cap.
	From time.Time
	// End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
	To time.Time
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
	Category string
	// Metric to rank rows by, applied descending. Any count or rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `processed`.
	Sort string
	// Maximum number of tag rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also carries a `trend` array: a short per-bucket series of that row's delivery and engagement rates over the window. Returned only when `limit` is 50 or fewer and the window is at most 90 days (trend_grain=daily) or 720 hours (trend_grain=hourly); a larger request returns 422. When `from` is omitted and `trend_grain=hourly`, the default window is 30 days (720 hours), so a request built entirely from defaults always fits the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain string
}

EmailStatsByTagParams filters the by_tag read.

type EmailStatsByTemplateParams added in v0.10.0

type EmailStatsByTemplateParams struct {
	// Start date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted; with `include_trend=true` and `trend_grain=hourly` the default tightens to 29 days before `to`, keeping the defaulted window within the 720-hour trend cap.
	From time.Time
	// End date (inclusive) in YYYY-MM-DD, interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
	To time.Time
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Not supported on breakdown endpoints; supplying it returns 422. To compare categories use `GET /v1/email/stats/categories`; the summary, daily, and hourly statistics accept `category` as a filter.
	Category string
	// Metric to rank rows by, applied descending. Any count or rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `processed`.
	Sort string
	// Maximum number of template rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also carries a `trend` array: a short per-bucket series of that template's delivery and engagement rates over the window. Returned only when `limit` is 50 or fewer and the window is at most 90 days (trend_grain=daily) or 720 hours (trend_grain=hourly); a larger request returns 422. When `from` is omitted and `trend_grain=hourly`, the default window is 30 days (720 hours), so a request built entirely from defaults always fits the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain string
}

EmailStatsByTemplateParams filters the by_template read.

type EmailStatsByTemplateResponse added in v0.10.0

type EmailStatsByTemplateResponse = oapi.EmailStatsByTemplateResponse

Email statistics responses, returned by the Client.Email.Stats methods. Each is the read-side body for one breakdown.

type EmailStatsDailyParams added in v0.10.0

type EmailStatsDailyParams struct {
	// Start date (inclusive), YYYY-MM-DD. Interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to 30 days before `to` when omitted.
	From time.Time
	// End date (inclusive), YYYY-MM-DD. Interpreted as a calendar day in `timezone` (a UTC day when `timezone` is omitted). Defaults to today in that timezone when omitted. Window may not exceed 365 days.
	To time.Time
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Restrict the statistics to a single category: `transactional` or `marketing`. Mutually exclusive with the other dimension filters; only one may be set per request.
	Category string
	// Restrict the statistics to a single sending domain (the part of the From address after @). Mutually exclusive with the other dimension filters; only one may be set per request.
	SendingDomain string
	// Restrict the statistics to a single tag. Use `name` to match any value of a tag, or `name:value` for a specific pair (for example `campaign:spring_launch`). Mutually exclusive with the other dimension filters; only one may be set per request.
	Tag string
	// Restrict the statistics to a single sending IP. Mutually exclusive with the other dimension filters; only one may be set per request. A sending IP is only assigned once a message reaches delivery, so an IP-filtered result reports delivery-side metrics only: accepted, processed, rejected, complaint, and engagement counts are 0 and the processing latency is null; complaint, open, and click rates read 0 when there were deliveries and null when there were none.
	SendingIP string
	// Restrict the statistics to a single recipient mailbox domain (the part of the recipient address after the `@`, for example `gmail.com`). Mutually exclusive with the other dimension filters; only one may be set per request.
	RecipientDomain string
	// Restrict the statistics to a single template, by its ID (`emt_…`) or its name. Mutually exclusive with the other dimension filters; only one may be set per request.
	Template string
}

EmailStatsDailyParams filters the daily read.

type EmailStatsHourlyParams added in v0.10.0

type EmailStatsHourlyParams struct {
	// Start of the window (ISO 8601 instant). Rounded down to the start of its hour (the local hour when `timezone` is set, otherwise the UTC hour), and that hour is included. When `timezone` is set, a numeric UTC offset here (for example `+05:45`) is rejected; use a `Z` (UTC) instant. Defaults to 7 days before `to` when omitted.
	From time.Time
	// End of the window (ISO 8601 instant). Rounded down to the start of its hour (the local hour when `timezone` is set, otherwise the UTC hour), and that hour is included (both bounds inclusive). When `timezone` is set, a numeric UTC offset here is rejected; use a `Z` (UTC) instant. Defaults to the current hour when omitted. Window may not exceed 30 days (720 hours).
	To time.Time
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Restrict the statistics to a single category: `transactional` or `marketing`. Mutually exclusive with the other dimension filters; only one may be set per request.
	Category string
	// Restrict the statistics to a single sending domain (the part of the From address after @). Mutually exclusive with the other dimension filters; only one may be set per request.
	SendingDomain string
	// Restrict the statistics to a single tag. Use `name` to match any value of a tag, or `name:value` for a specific pair (for example `campaign:spring_launch`). Mutually exclusive with the other dimension filters; only one may be set per request.
	Tag string
	// Restrict the statistics to a single sending IP. Mutually exclusive with the other dimension filters; only one may be set per request. A sending IP is only assigned once a message reaches delivery, so an IP-filtered result reports delivery-side metrics only: accepted, processed, rejected, complaint, and engagement counts are 0 and the processing latency is null; complaint, open, and click rates read 0 when there were deliveries and null when there were none.
	SendingIP string
	// Restrict the statistics to a single recipient mailbox domain (the part of the recipient address after the `@`, for example `gmail.com`). Mutually exclusive with the other dimension filters; only one may be set per request.
	RecipientDomain string
	// Restrict the statistics to a single template, by its ID (`emt_…`) or its name. Mutually exclusive with the other dimension filters; only one may be set per request.
	Template string
}

EmailStatsHourlyParams filters the hourly read.

type EmailStatsResponse added in v0.10.0

type EmailStatsResponse = oapi.EmailStatsResponse

EmailStatsResponse is a time series of per-bucket points. Returned by Stats.Daily and Stats.Hourly.

type EmailStatsService added in v0.10.0

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

EmailStatsService reads aggregated email statistics. Reach it via Client.Email.Stats. Every method is a read; each takes a params struct whose fields are all optional (zero values are omitted, and the server applies its own defaults for the window, sort, and limit).

func (*EmailStatsService) ByBounceCode added in v0.10.0

ByBounceCode Bounce counts grouped by the SMTP error code the receiving server returned, with the hard/soft/admin/block/undetermined split; failure side only. Use it to find what is driving bounces; for bounces by destination use email_stats_by_recipient_domain or email_stats_by_mailbox_provider.

Example

ByBounceCode ranks bounce counts per SMTP error code.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	stats, err := client.Email.Stats.ByBounceCode(context.Background(), bird.EmailStatsByBounceCodeParams{})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(stats.Data)
}

func (*EmailStatsService) ByBroadcast added in v0.10.0

ByBroadcast Email delivery and engagement stats grouped by broadcast; only broadcast sends appear. Reflects roughly the last 30 days of activity; `include_trend` is not available here and returns 422.

Example

ByBroadcast ranks statistics per broadcast.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	stats, err := client.Email.Stats.ByBroadcast(context.Background(), bird.EmailStatsByBroadcastParams{
		Limit: 25,
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(stats.Data)
}

func (*EmailStatsService) ByCategory added in v0.10.0

ByCategory Email delivery and engagement stats grouped by category (`transactional` versus `marketing`), ranked by `sort` (default `processed`). `include_trend=true` adds a per-bucket rate series to each row.

Example

ByCategory ranks statistics per category.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	stats, err := client.Email.Stats.ByCategory(context.Background(), bird.EmailStatsByCategoryParams{})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(stats.Data)
}

func (*EmailStatsService) ByClient added in v0.10.0

ByClient Opens and clicks grouped by mail client, OS, or device type (`group_by`); engagement counts only, no delivery counts or rates. For engagement by geography use email_stats_by_location.

Example

ByClient ranks engagement statistics per reading environment.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	stats, err := client.Email.Stats.ByClient(context.Background(), bird.EmailStatsByClientParams{
		GroupBy: "email_client",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(stats.Data)
}

func (*EmailStatsService) ByComplaintType added in v0.10.0

ByComplaintType Spam-complaint counts grouped by the feedback-loop complaint type (for example `abuse`, `fraud`, `virus`); complaint side only. For complaints by destination use email_stats_by_mailbox_provider or email_stats_by_recipient_domain.

Example

ByComplaintType ranks complaint counts per complaint type.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	stats, err := client.Email.Stats.ByComplaintType(context.Background(), bird.EmailStatsByComplaintTypeParams{})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(stats.Data)
}

func (*EmailStatsService) ByLocation added in v0.10.0

ByLocation Opens and clicks grouped by country, region, or city (`group_by`); engagement counts only, no delivery counts or rates. For engagement by mail client or device use email_stats_by_client.

Example

ByLocation ranks engagement statistics per geographic location.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	stats, err := client.Email.Stats.ByLocation(context.Background(), bird.EmailStatsByLocationParams{
		GroupBy: "country",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(stats.Data)
}

func (*EmailStatsService) ByMailboxProvider added in v0.10.0

ByMailboxProvider Email delivery and engagement stats grouped by recipient mailbox provider (`gmail`, `microsoft`, `yahoo`, ...); covers the delivery stage onward, no accepted/processed counts. For a per-region split use email_stats_by_mailbox_provider_region; for exact destination domains use email_stats_by_recipient_domain.

Example

ByMailboxProvider ranks post-delivery statistics per mailbox provider.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	stats, err := client.Email.Stats.ByMailboxProvider(context.Background(), bird.EmailStatsByMailboxProviderParams{})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(stats.Data)
}

func (*EmailStatsService) ByMailboxProviderRegion added in v0.10.0

ByMailboxProviderRegion Email delivery and engagement stats grouped by mailbox provider and provider region pair (for example `gmail` in `NA`); covers the delivery stage onward, no accepted/processed counts. For the provider-level view use email_stats_by_mailbox_provider.

Example

ByMailboxProviderRegion ranks post-delivery statistics per provider region.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	stats, err := client.Email.Stats.ByMailboxProviderRegion(context.Background(), bird.EmailStatsByMailboxProviderRegionParams{})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(stats.Data)
}

func (*EmailStatsService) ByRecipientDomain added in v0.10.0

ByRecipientDomain Email delivery and engagement stats grouped by exact recipient mailbox domain (for example `gmail.com`). Finer-grained than email_stats_by_mailbox_provider, which buckets domains into providers.

Example

ByRecipientDomain ranks statistics per recipient mailbox domain.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	stats, err := client.Email.Stats.ByRecipientDomain(context.Background(), bird.EmailStatsByRecipientDomainParams{
		Limit: 20,
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(stats.Data)
}

func (*EmailStatsService) BySendingDomain added in v0.10.0

BySendingDomain Email delivery and engagement stats grouped by sending (`From`) domain; compare deliverability across the workspace's verified domains. For per-IP reputation use email_stats_by_sending_ip.

Example

BySendingDomain ranks statistics per sending domain.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	stats, err := client.Email.Stats.BySendingDomain(context.Background(), bird.EmailStatsBySendingDomainParams{})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(stats.Data)
}

func (*EmailStatsService) BySendingIP added in v0.13.0

BySendingIP Delivery and bounce stats grouped by sending IP; `sort=bounces.block` surfaces reputation-damaged IPs first. No engagement, complaint, or accepted/processed counts per IP; use email_stats_daily for workspace-wide figures.

Example

BySendingIP ranks delivery statistics per sending IP.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	stats, err := client.Email.Stats.BySendingIP(context.Background(), bird.EmailStatsBySendingIPParams{
		Sort: "bounced",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(stats.Data)
}

func (*EmailStatsService) ByTag added in v0.10.0

ByTag Email delivery and engagement stats grouped by tag, one row per `name:value` pair set at send time; ranked by `sort` (default `processed`). `include_trend=true` adds a per-bucket rate series to each row.

Example

ByTag ranks statistics per tag.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	stats, err := client.Email.Stats.ByTag(context.Background(), bird.EmailStatsByTagParams{
		Sort:  "opens",
		Limit: 10,
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(stats.Data)
}

func (*EmailStatsService) ByTemplate added in v0.10.0

ByTemplate Email delivery and engagement stats grouped by the template used at send time, keyed by template id (`emt_…`); only templated sends appear. To track a single template over time, pass `template` to email_stats_daily instead.

Example

ByTemplate ranks statistics per template.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	stats, err := client.Email.Stats.ByTemplate(context.Background(), bird.EmailStatsByTemplateParams{})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(stats.Data)
}

func (*EmailStatsService) Daily added in v0.10.0

Daily Per-day email stats series (counts, rates, latency percentiles), gap-filled with zero rows, max 365 days. At most one filter of `category`, `sending_domain`, `tag`, `sending_ip`, `recipient_domain`, `template`. For hour resolution use email_stats_hourly; for one aggregate row use email_stats_summary.

Example

Daily returns one row per calendar day in the window.

package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"time"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	series, err := client.Email.Stats.Daily(context.Background(), bird.EmailStatsDailyParams{
		From: time.Now().AddDate(0, 0, -7),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(series.Data)
}

func (*EmailStatsService) Hourly added in v0.10.0

Hourly Per-hour email stats series, gap-filled with zero rows, max 720 hours (30 days). Takes the same single-dimension filters as email_stats_daily; for longer ranges use email_stats_daily, for one aggregate row use email_stats_summary.

Example

Hourly returns one row per hour in the window (max 720 hours).

package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"time"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	series, err := client.Email.Stats.Hourly(context.Background(), bird.EmailStatsHourlyParams{
		From: time.Now().Add(-24 * time.Hour),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(series.Data)
}

func (*EmailStatsService) Summary added in v0.10.0

Summary Aggregate email KPIs for one period: sends, delivered, bounces, complaints, opens, clicks, their rates, and latency percentiles. `from`/`to` are both YYYY-MM-DD days or both RFC 3339 instants (hour grain); add `compare=previous_period` for deltas versus the prior window. For a per-day or per-hour series use email_stats_daily or email_stats_hourly.

Example

Summary returns the delivery, engagement, and latency totals for a window.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	summary, err := client.Email.Stats.Summary(context.Background(), bird.EmailStatsSummaryParams{
		From: "2026-05-01", // a calendar day for a day-grain window (up to 365 days), or
		To:   "2026-05-31", // an RFC 3339 instant (e.g. "2026-05-01T00:00:00Z") for hour-grain (up to 720 hours)
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(summary.SendsAccepted)
}

type EmailStatsSummary added in v0.10.0

type EmailStatsSummary = oapi.EmailStatsSummary

EmailStatsSummary is the delivery/engagement/latency totals for a window, optionally with a previous-period comparison. Returned by Stats.Summary.

type EmailStatsSummaryParams added in v0.10.0

type EmailStatsSummaryParams struct {
	// Inclusive start of the window: a calendar day (YYYY-MM-DD) or an RFC 3339 instant (rounded down to the hour). Interpreted in `timezone` (a calendar day names a local day; an instant is rounded down to the local hour), or in UTC when `timezone` is omitted. A numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant. Must use the same form as `to`. Defaults to 30 days before `to` for day windows, or 168 hours (7 days) before `to` for hour windows, when omitted.
	From string
	// Inclusive end of the window: a calendar day (YYYY-MM-DD) or an RFC 3339 instant (rounded down to the hour). Interpreted in `timezone` (a calendar day names a local day; an instant is rounded down to the local hour), or in UTC when `timezone` is omitted. A numeric UTC offset is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant. Must use the same form as `from`. Defaults to today for day windows, or the current hour for hour windows, in that timezone, when omitted. Day windows may not exceed 365 days; hour windows may not exceed 720 hours (30 days).
	To string
	// IANA timezone identifier (for example `Asia/Kathmandu` or `America/New_York`) to report the statistics in. It is the single source of timezone: day and hour boundaries, and the relative window defaults used when `from` and `to` are omitted, are computed in this timezone instead of UTC, so a timezone with a sub-hour offset (such as India at +05:30 or Nepal at +05:45) still gets correct local-day and local-hour totals. When it is set, a `from` or `to` given as a calendar day names a local day in this timezone, and one given as an instant stays an absolute point in time but is rounded down to its hour and bucketed in this timezone (so the hour boundaries are local, not UTC). To avoid specifying the zone twice, a `from` or `to` that carries its own numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; use a calendar day or a `Z` (UTC) instant instead. Defaults to UTC.
	Timezone string
	// Restrict the statistics to a single category: `transactional` or `marketing`. Mutually exclusive with the other dimension filters; only one may be set per request.
	Category string
	// Restrict the statistics to a single sending domain (the part of the From address after @). Mutually exclusive with the other dimension filters; only one may be set per request.
	SendingDomain string
	// Restrict the statistics to a single tag. Use `name` to match any value of a tag, or `name:value` for a specific pair (for example `campaign:spring_launch`). Mutually exclusive with the other dimension filters; only one may be set per request.
	Tag string
	// Restrict the statistics to a single sending IP. Mutually exclusive with the other dimension filters; only one may be set per request. A sending IP is only assigned once a message reaches delivery, so an IP-filtered result reports delivery-side metrics only: accepted, processed, rejected, complaint, and engagement counts are 0 and the processing latency is null; complaint, open, and click rates read 0 when there were deliveries and null when there were none.
	SendingIP string
	// Restrict the statistics to a single recipient mailbox domain (the part of the recipient address after the `@`, for example `gmail.com`). Mutually exclusive with the other dimension filters; only one may be set per request.
	RecipientDomain string
	// Restrict the statistics to a single template, by its ID (`emt_…`) or its name. Mutually exclusive with the other dimension filters; only one may be set per request.
	Template string
	// Set to `previous_period` to also include the same statistics for the immediately preceding window of equal length, plus the change between the two, so you can show "+X% vs last period" without a second request.
	Compare string
}

EmailStatsSummaryParams filters the summary read.

type EmailStatsTagsResponse added in v0.10.0

type EmailStatsTagsResponse = oapi.EmailStatsTagsResponse

EmailStatsTagsResponse is the ranked tag breakdown. Returned by Stats.ByTag.

type EmailStatus

type EmailStatus = oapi.EmailMessageStatus

EmailStatus is a message's aggregate delivery status.

const (
	EmailStatusAccepted       EmailStatus = "accepted"
	EmailStatusProcessed      EmailStatus = "processed"
	EmailStatusDelivered      EmailStatus = "delivered"
	EmailStatusDeferred       EmailStatus = "deferred"
	EmailStatusBounced        EmailStatus = "bounced"
	EmailStatusComplained     EmailStatus = "complained"
	EmailStatusRejected       EmailStatus = "rejected"
	EmailStatusPartialFailure EmailStatus = "partial_failure"
)

type EmailSuppressionCreatedEvent

type EmailSuppressionCreatedEvent = oapi.EventEmailSuppressionCreated

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type EmailTag

type EmailTag = oapi.Tag

EmailTag is a structured {Name, Value} label.

type EmailThread added in v0.12.0

type EmailThread = oapi.EmailThread

EmailThread is a conversation: a group of messages on the same topic.

type EmailThreadList added in v0.12.0

type EmailThreadList = oapi.EmailThreadList

EmailThreadList is one page of threads plus its pagination cursors.

type EmailThreadMessage added in v0.12.0

type EmailThreadMessage = oapi.EmailThreadMessage

EmailThreadMessage is a single message in a conversation.

type EmailThreadMessageAttachmentList added in v0.12.0

type EmailThreadMessageAttachmentList = oapi.EmailThreadMessageAttachmentList

EmailThreadMessageAttachmentList is the attachment manifest.

type EmailThreadMessageBody added in v0.12.0

type EmailThreadMessageBody = oapi.EmailThreadMessageBody

EmailThreadMessageBody is the parsed HTML and plain-text body.

type EmailThreadMessageList added in v0.12.0

type EmailThreadMessageList = oapi.EmailThreadMessageList

EmailThreadMessageList is one page of messages.

type EmailUnsubscribedEvent

type EmailUnsubscribedEvent = oapi.EventEmailUnsubscribed

Webhook event payloads, returned by Event.AsAny. Type-switch on these.

type ErrorDetail

type ErrorDetail = apierror.ErrorDetail

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type ErrorNextAction added in v0.2.2

type ErrorNextAction = apierror.ErrorNextAction

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type ErrorType

type ErrorType = apierror.ErrorType

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type Event

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

Event is a verified webhook event. Switch on Type, or call AsAny and type-switch on the concrete payload (e.g. EmailDeliveredEvent).

func (Event) AsAny

func (e Event) AsAny() (any, error)

AsAny decodes the event into its concrete payload type. An unknown future event type returns an error rather than a panic, so an older SDK keeps working against a newer server.

func (Event) Type

func (e Event) Type() WebhookEventType

Type returns the event's discriminant, e.g. EventTypeEmailDelivered.

type Mailbox added in v0.12.0

type Mailbox = oapi.Mailbox

Mailbox is a durable inbox on inbox.ai or a custom domain.

type MailboxComposeParams added in v0.12.0

type MailboxComposeParams struct {
	To       []string // required; plain address or "Name <addr>"
	Subject  string   // required
	HTML     string
	Text     string
	CC       []string
	BCC      []string
	ReplyTo  []string
	Category string // marketing | transactional
	Metadata map[string]any
}

MailboxComposeParams sends a new message from the mailbox.

type MailboxCreateParams added in v0.12.0

type MailboxCreateParams struct {
	LocalPart      string // address before @; omit to generate
	Domain         string // defaults to inbox.ai
	DisplayName    string
	DefaultReplyTo string
	ReceivePolicy  string // open | replies_only | allowlist | drop
	RetentionTier  string // 30d (only value today)
	Metadata       map[string]any
}

MailboxCreateParams creates a mailbox. All fields are optional; omit LocalPart to have Bird generate a random handle on inbox.ai.

type MailboxList added in v0.12.0

type MailboxList = oapi.MailboxList

MailboxList is one page of mailboxes plus its pagination cursors.

type MailboxListParams added in v0.12.0

type MailboxListParams struct {
	Q              string
	Address        string
	Domain         string
	State          string // active | suspended | deleted
	IncludeDeleted bool
	Limit          int
}

MailboxListParams filters the mailbox list.

type MailboxReceiveRuleCreateParams added in v0.12.0

type MailboxReceiveRuleCreateParams struct {
	Action string // allow | block; required
	Entry  string // address or domain to match; required
	Note   string // optional explanation
}

MailboxReceiveRuleCreateParams adds a rule to a mailbox.

type MailboxReceiveRuleListParams added in v0.12.0

type MailboxReceiveRuleListParams struct {
	Action string // allow | block
	Limit  int
}

MailboxReceiveRuleListParams filters the rule list.

type MailboxReceiveRuleService added in v0.12.0

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

MailboxReceiveRuleService manages per-sender allow/block rules on a mailbox. Reach it via Client.MailboxReceiveRule.

func (*MailboxReceiveRuleService) Create added in v0.12.0

Create adds an allow or block rule to a mailbox. Block rules always win. Retried safely with a reused idempotency key.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	rule, err := client.MailboxReceiveRule.Create(context.Background(), "mbx_123", bird.MailboxReceiveRuleCreateParams{
		Action: "block",
		Entry:  "spam.example.com",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(rule.Id)
}

func (*MailboxReceiveRuleService) Delete added in v0.12.0

func (s *MailboxReceiveRuleService) Delete(ctx context.Context, mailboxID, ruleID string, opts ...option.RequestOption) error

Delete removes a receive rule.

Example
package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	if err := client.MailboxReceiveRule.Delete(context.Background(), "mbx_123", "erl_456"); err != nil {
		log.Fatal(err)
	}
}

func (*MailboxReceiveRuleService) List added in v0.12.0

List walks every receive rule for a mailbox, fetching pages lazily.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	for rule, err := range client.MailboxReceiveRule.List(context.Background(), "mbx_123", bird.MailboxReceiveRuleListParams{}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(rule.Id, rule.Action, rule.Entry)
	}
}

func (*MailboxReceiveRuleService) ListPage added in v0.12.0

func (s *MailboxReceiveRuleService) ListPage(ctx context.Context, mailboxID string, params MailboxReceiveRuleListParams, startingAfter string, opts ...option.RequestOption) (*ReceiveRuleList, error)

ListPage fetches one page of rules for a mailbox.

type MailboxService added in v0.12.0

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

MailboxService manages agent mailboxes — durable inboxes on inbox.ai or your own domain that receive, store, and send email. Reach it via Client.Mailbox.

func (*MailboxService) Compose added in v0.12.0

func (s *MailboxService) Compose(ctx context.Context, mailboxID string, params MailboxComposeParams, opts ...option.RequestOption) (*EmailThreadMessage, error)

Compose sends a new email from the mailbox's own address, starting a new conversation. Retried safely with a reused idempotency key.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	msg, err := client.Mailbox.Compose(context.Background(), "mbx_123", bird.MailboxComposeParams{
		To:      []string{"customer@example.com"},
		Subject: "Following up",
		HTML:    "<p>Hi, just checking in.</p>",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(msg.Id)
}

func (*MailboxService) Create added in v0.12.0

func (s *MailboxService) Create(ctx context.Context, params MailboxCreateParams, opts ...option.RequestOption) (*Mailbox, error)

Create claims a new mailbox address and returns the mailbox. Retried safely with a reused idempotency key.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	mailbox, err := client.Mailbox.Create(context.Background(), bird.MailboxCreateParams{
		DisplayName: "Support",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(mailbox.Id, *mailbox.Address)
}

func (*MailboxService) Delete added in v0.12.0

func (s *MailboxService) Delete(ctx context.Context, mailboxID string, opts ...option.RequestOption) error

Delete soft-deletes the mailbox. The address is quarantined for 30 days and can be restored with Restore.

Example
package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	if err := client.Mailbox.Delete(context.Background(), "mbx_123"); err != nil {
		log.Fatal(err)
	}
}

func (*MailboxService) Get added in v0.12.0

func (s *MailboxService) Get(ctx context.Context, mailboxID string, opts ...option.RequestOption) (*Mailbox, error)

Get returns a single mailbox by id.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	mailbox, err := client.Mailbox.Get(context.Background(), "mbx_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(*mailbox.Address)
}

func (*MailboxService) Labels added in v0.12.0

func (s *MailboxService) Labels(ctx context.Context, mailboxID string, opts ...option.RequestOption) (*EmailMailboxLabelList, error)

Labels lists the labels available in this mailbox.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	labels, err := client.Mailbox.Labels(context.Background(), "mbx_123")
	if err != nil {
		log.Fatal(err)
	}
	for _, l := range labels.Data {
		fmt.Println(l.Name)
	}
}

func (*MailboxService) List added in v0.12.0

List walks every mailbox matching params, fetching pages lazily.

Example

List auto-paginates across all mailboxes in the workspace.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	for mailbox, err := range client.Mailbox.List(context.Background(), bird.MailboxListParams{}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(mailbox.Id)
	}
}

func (*MailboxService) ListPage added in v0.12.0

func (s *MailboxService) ListPage(ctx context.Context, params MailboxListParams, startingAfter string, opts ...option.RequestOption) (*MailboxList, error)

ListPage fetches one page of mailboxes. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the most recent.

func (*MailboxService) Restore added in v0.12.0

func (s *MailboxService) Restore(ctx context.Context, mailboxID string, opts ...option.RequestOption) (*Mailbox, error)

Restore recovers a deleted mailbox within its 30-day restore window.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	mailbox, err := client.Mailbox.Restore(context.Background(), "mbx_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(mailbox.Id)
}

func (*MailboxService) Resume added in v0.12.0

func (s *MailboxService) Resume(ctx context.Context, mailboxID string, opts ...option.RequestOption) (*Mailbox, error)

Resume reactivates a suspended mailbox.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	mailbox, err := client.Mailbox.Resume(context.Background(), "mbx_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(mailbox.Id)
}

func (*MailboxService) Stats added in v0.12.0

Stats returns per-mailbox email activity time series.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	stats, err := client.Mailbox.Stats(context.Background(), "mbx_123", bird.MailboxStatsParams{})
	if err != nil {
		log.Fatal(err)
	}
	if stats.Summary != nil {
		if d := stats.Summary.Delivery; d != nil {
			fmt.Println(d.Delivered, d.Bounced)
		}
	}
}

func (*MailboxService) Update added in v0.12.0

func (s *MailboxService) Update(ctx context.Context, mailboxID string, params MailboxUpdateParams, opts ...option.RequestOption) (*Mailbox, error)

Update edits a mailbox. Only the fields set in params change. Set params.Confirm = true when lowering the retention tier.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	mailbox, err := client.Mailbox.Update(context.Background(), "mbx_123", bird.MailboxUpdateParams{
		DisplayName: bird.Value("Sales"),
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(mailbox.Id)
}

type MailboxStatsParams added in v0.12.0

type MailboxStatsParams struct {
	From        string // YYYY-MM-DD or RFC3339 hour
	To          string
	Timezone    string
	Granularity string // day | hour
}

MailboxStatsParams bounds the stats window.

type MailboxStatsResponse added in v0.12.0

type MailboxStatsResponse = oapi.MailboxStatsResponse

MailboxStatsResponse is the stats time series for a mailbox.

type MailboxThreadListParams added in v0.12.0

type MailboxThreadListParams struct {
	MailboxID   string
	ContactID   string
	Label       []string // inbox | archive | spam | blocked | custom
	HasUnread   bool
	Participant string // address filter (contains-match)
	Subject     string // subject contains filter
	Limit       int
}

MailboxThreadListParams filters the thread list.

type MailboxThreadMessageListParams added in v0.12.0

type MailboxThreadMessageListParams struct {
	Label     string // inbox | archive | spam | blocked | trash | unread | custom
	Direction string // inbound | outbound
	Include   string // extracted_text
	Limit     int
}

MailboxThreadMessageListParams filters the message list.

type MailboxThreadMessageReplyParams added in v0.12.0

type MailboxThreadMessageReplyParams struct {
	Text     string // required if HTML is empty
	HTML     string // required if Text is empty
	ReplyAll bool
	Category string // marketing | transactional
	Metadata map[string]any
}

MailboxThreadMessageReplyParams sends a reply to a message.

type MailboxThreadMessageService added in v0.12.0

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

MailboxThreadMessageService reads messages in a conversation thread and sends replies. Reach it via Client.MailboxThreadMessage.

func (*MailboxThreadMessageService) Attachments added in v0.12.0

func (s *MailboxThreadMessageService) Attachments(ctx context.Context, threadID, messageID string, opts ...option.RequestOption) (*EmailThreadMessageAttachmentList, error)

Attachments lists the attachment manifest for a message.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	result, err := client.MailboxThreadMessage.Attachments(context.Background(), "thr_123", "rem_456")
	if err != nil {
		log.Fatal(err)
	}
	for _, a := range result.Data {
		fmt.Println(a.Filename, a.Size)
	}
}

func (*MailboxThreadMessageService) Body added in v0.12.0

func (s *MailboxThreadMessageService) Body(ctx context.Context, threadID, messageID string, opts ...option.RequestOption) (*EmailThreadMessageBody, error)

Body returns the parsed HTML and plain-text body of a message.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	body, err := client.MailboxThreadMessage.Body(context.Background(), "thr_123", "rem_456")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(body.Text)
}

func (*MailboxThreadMessageService) Get added in v0.12.0

func (s *MailboxThreadMessageService) Get(ctx context.Context, threadID, messageID string, opts ...option.RequestOption) (*EmailThreadMessage, error)

Get returns metadata for a single message (not the body; call Body for that).

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	msg, err := client.MailboxThreadMessage.Get(context.Background(), "thr_123", "rem_456")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(msg.Id, msg.Direction)
}

func (*MailboxThreadMessageService) List added in v0.12.0

List walks every message in a thread, fetching pages lazily.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	for msg, err := range client.MailboxThreadMessage.List(context.Background(), "thr_123", bird.MailboxThreadMessageListParams{}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(msg.Id, msg.Direction)
	}
}

func (*MailboxThreadMessageService) ListPage added in v0.12.0

ListPage fetches one page of messages in a thread.

func (*MailboxThreadMessageService) Reply added in v0.12.0

Reply sends a reply to a specific message from the mailbox's own address. Retried safely with a reused idempotency key.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	reply, err := client.MailboxThreadMessage.Reply(context.Background(), "thr_123", "rem_456", bird.MailboxThreadMessageReplyParams{
		Text: "Thanks for reaching out!",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(reply.Id)
}

type MailboxThreadService added in v0.12.0

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

MailboxThreadService reads and manages email conversation threads stored in mailboxes. Reach it via Client.MailboxThread.

func (*MailboxThreadService) Delete added in v0.12.0

func (s *MailboxThreadService) Delete(ctx context.Context, threadID string, permanent bool, opts ...option.RequestOption) error

Delete moves a thread and all its messages to trash. Pass permanent=true to delete immediately without a restore window.

Example
package main

import (
	"context"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	if err := client.MailboxThread.Delete(context.Background(), "thr_123", false); err != nil {
		log.Fatal(err)
	}
}

func (*MailboxThreadService) Get added in v0.12.0

func (s *MailboxThreadService) Get(ctx context.Context, threadID string, opts ...option.RequestOption) (*EmailThread, error)

Get returns a single thread by id.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	thread, err := client.MailboxThread.Get(context.Background(), "thr_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(thread.Id)
}

func (*MailboxThreadService) List added in v0.12.0

List walks every thread matching params, fetching pages lazily.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	for thread, err := range client.MailboxThread.List(context.Background(), bird.MailboxThreadListParams{}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(thread.Id)
	}
}

func (*MailboxThreadService) ListPage added in v0.12.0

func (s *MailboxThreadService) ListPage(ctx context.Context, params MailboxThreadListParams, startingAfter string, opts ...option.RequestOption) (*EmailThreadList, error)

ListPage fetches one page of threads matching params.

func (*MailboxThreadService) Update added in v0.12.0

Update applies label changes or contact link changes to a thread.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	thread, err := client.MailboxThread.Update(context.Background(), "thr_123", bird.MailboxThreadUpdateParams{
		AddLabels: []string{"urgent"},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(thread.Id)
}

type MailboxThreadUpdateParams added in v0.12.0

type MailboxThreadUpdateParams struct {
	AddLabels    []string
	RemoveLabels []string
	ContactID    *string // nil = unchanged; non-empty ptr = link contact. To unlink (send null) use client.Patch directly.
}

MailboxThreadUpdateParams applies label changes and contact links to a thread.

type MailboxUpdateParams added in v0.12.0

type MailboxUpdateParams struct {
	// DisplayName and DefaultReplyTo are Nullable: bird.Value sets a value,
	// bird.Null clears it (explicit JSON null), and the zero value omits it.
	DisplayName    Nullable[string]
	DefaultReplyTo Nullable[string]
	ReceivePolicy  *string
	RetentionTier  *string
	Metadata       map[string]any
	Confirm        bool // required when lowering retention_tier
}

MailboxUpdateParams is a partial update. Nil fields leave values unchanged.

type Nullable added in v0.14.0

type Nullable[T any] = nullable.Nullable[T]

Nullable is a nullable/clearable request-param field. It carries one of three states: a value, an explicit JSON null (clears the field), or unspecified (the zero value — omitted, leaving the field unchanged). Only request params use it; response fields stay plain pointers. Build it with Value or Null:

bird.AudienceUpdateParams{Description: bird.Null[string]()}   // clear
bird.AudienceUpdateParams{Description: bird.Value("Q4 leads")} // set

func Null added in v0.14.0

func Null[T any]() Nullable[T]

Null sets a Nullable request field to send an explicit JSON null, clearing it.

func Value added in v0.14.0

func Value[T any](v T) Nullable[T]

Value sets a Nullable request field to send v.

type RateLimitError

type RateLimitError = apierror.RateLimitError

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type ReceiveRule added in v0.12.0

type ReceiveRule = oapi.ReceiveRule

ReceiveRule is a per-sender allow or block rule on a mailbox.

type ReceiveRuleList added in v0.12.0

type ReceiveRuleList = oapi.ReceiveRuleList

ReceiveRuleList is one page of receive rules.

type Response

type Response = requestconfig.Response

Response is the transport metadata for one call, captured via option.WithResponseInto.

type SMSBatch added in v0.3.0

type SMSBatch = oapi.SMSMessageBatchResponse

SMSMessage is a sent or received SMS with its status, segment breakdown, and cost; SMSMessageList is a page of messages; SMSBatch is a batch-send result.

type SMSCategory added in v0.3.0

type SMSCategory = oapi.SMSMessageCategory

SMSCategory classifies a send for opt-out (STOP) policy, quiet hours, and per-country compliance.

const (
	SMSCategoryTransactional  SMSCategory = "transactional"
	SMSCategoryMarketing      SMSCategory = "marketing"
	SMSCategoryAuthentication SMSCategory = "authentication"
	SMSCategoryService        SMSCategory = "service"
)

type SMSMessage added in v0.3.0

type SMSMessage = oapi.SMSMessage

SMSMessage is a sent or received SMS with its status, segment breakdown, and cost; SMSMessageList is a page of messages; SMSBatch is a batch-send result.

type SMSMessageList added in v0.3.0

type SMSMessageList = oapi.SMSMessageList

SMSMessage is a sent or received SMS with its status, segment breakdown, and cost; SMSMessageList is a page of messages; SMSBatch is a batch-send result.

type SMSService added in v0.3.0

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

SMSService sends SMS messages — free text or by stored template — and reads them back. Reach it via Client.Sms.

func (*SMSService) Get added in v0.3.0

func (s *SMSService) Get(ctx context.Context, id string, opts ...option.RequestOption) (*SMSMessage, error)

Get returns a single SMS message with its current delivery status, segment breakdown, cost, and failure detail if it failed.

func (*SMSService) List added in v0.3.0

List walks every message matching params, fetching pages lazily. Range over it; the second value is non-nil only on the iteration where a fetch failed.

func (*SMSService) ListPage added in v0.3.0

func (s *SMSService) ListPage(ctx context.Context, params SmsListParams, startingAfter string, opts ...option.RequestOption) (*SMSMessageList, error)

ListPage fetches one page of messages. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the most recent.

func (*SMSService) Send added in v0.3.0

func (s *SMSService) Send(ctx context.Context, params SmsSendParams, opts ...option.RequestOption) (*SMSMessage, error)

Send sends one SMS message. Retried safely: a single idempotency key is reused across attempts. Provide your own key with option.WithIdempotencyKey.

Example

Send a free-text SMS.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	msg, err := client.Sms.Send(context.Background(), bird.SmsSendParams{
		To:       "+15551234567",
		Text:     "Your verification code is 123456.",
		Category: bird.SMSCategoryAuthentication,
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(msg.Id, *msg.Status)
}
Example (Template)

Send an SMS from a stored template, supplying its variables.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	msg, err := client.Sms.Send(context.Background(), bird.SmsSendParams{
		To:         "+15551234567",
		Template:   "bird_otp_verification",
		Parameters: map[string]any{"code": "123456"},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(msg.Id)
}

func (*SMSService) SendBatch added in v0.3.0

func (s *SMSService) SendBatch(ctx context.Context, params SmsSendBatchParams, opts ...option.RequestOption) (*SMSBatch, error)

SendBatch sends up to 100 independent SMS messages in one call. Each item is a full send with its own id, status, and cost; all items are validated before any are queued. Retried safely with a reused idempotency key.

type SMSStatus added in v0.3.0

type SMSStatus = oapi.SMSMessageStatus

SMSStatus is a message's delivery status.

type SMSTag added in v0.3.0

type SMSTag = oapi.Tag

SMSTag is a structured {name, value} label on an SMS send.

type SMSTemplate added in v0.3.0

type SMSTemplate = oapi.SMSTemplate

SMSTemplate is an SMS template with its body, variables, and available languages; SMSTemplateList is the (unpaginated) set of templates available to the workspace.

type SMSTemplateCategory added in v0.3.0

type SMSTemplateCategory string

SMSTemplateCategory filters templates by content classification.

const (
	SMSTemplateCategoryTransactional  SMSTemplateCategory = "transactional"
	SMSTemplateCategoryMarketing      SMSTemplateCategory = "marketing"
	SMSTemplateCategoryAuthentication SMSTemplateCategory = "authentication"
	SMSTemplateCategoryService        SMSTemplateCategory = "service"
)

type SMSTemplateList added in v0.3.0

type SMSTemplateList = oapi.SMSTemplateList

SMSTemplate is an SMS template with its body, variables, and available languages; SMSTemplateList is the (unpaginated) set of templates available to the workspace.

type SMSTemplateListParams added in v0.3.0

type SMSTemplateListParams struct {
	Scope    SMSTemplateScope    // filter by origin (system or workspace)
	Category SMSTemplateCategory // filter by content classification
	Language string              // keep only templates available in this BCP-47 language tag
}

SMSTemplateListParams filters the template list. Zero-value fields are omitted.

type SMSTemplateScope added in v0.3.0

type SMSTemplateScope string

SMSTemplateScope filters templates by origin: Bird's built-in templates (system) or the workspace's own (workspace).

const (
	SMSTemplateScopeSystem    SMSTemplateScope = "system"
	SMSTemplateScopeWorkspace SMSTemplateScope = "workspace"
)

type SMSTemplatesService added in v0.3.0

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

SMSTemplatesService reads the SMS templates available to a workspace — Bird's built-in templates and any the workspace authored. Reach it via Client.SMSTemplates. The catalogue is read-only through this SDK.

func (*SMSTemplatesService) Get added in v0.3.0

func (s *SMSTemplatesService) Get(ctx context.Context, templateRef string, opts ...option.RequestOption) (*SMSTemplate, error)

Get returns a single SMS template by its name or id, including its body and the variables it expects.

Example

Read one SMS template by its name (or id).

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	tpl, err := client.SmsTemplates.Get(context.Background(), "bird_otp_verification")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(tpl.Id, *tpl.Body)
}

func (*SMSTemplatesService) List added in v0.3.0

List returns the SMS templates available to the workspace, filtered by params. The catalogue is small and returned in full — this list is not paginated.

Example

List the SMS templates available to the workspace. The catalogue is small and returned in full — this list is not paginated.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	list, err := client.SmsTemplates.List(context.Background(), bird.SMSTemplateListParams{
		Scope: bird.SMSTemplateScopeSystem,
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, tpl := range list.Data {
		fmt.Println(tpl.Id, *tpl.Name)
	}
}

type SmsListParams added in v0.3.0

type SmsListParams struct {
	Direction     string      // "outbound" or "inbound"; empty for both
	Statuses      []string    // filter by any of several delivery statuses
	ErrorCodes    []string    // filter by any of several failure reasons
	Category      SMSCategory // filter by content classification
	To            string      // filter by recipient (E.164 exact match)
	From          string      // filter by sender (exact match)
	Tags          []string    // filter by tag name or name:value; AND-combined
	CreatedAfter  time.Time
	CreatedBefore time.Time
	Limit         int
}

SmsListParams filters the message list. Zero-value fields are omitted.

type SmsSendBatchParams added in v0.3.0

type SmsSendBatchParams struct {
	Messages []SmsSendParams
}

SmsSendBatchParams is a batch of up to 100 independent SMS sends.

type SmsSendParams added in v0.3.0

type SmsSendParams struct {
	To         string         // required; recipient phone number in E.164 format
	From       string         // optional sender; Bird selects one when empty
	Text       string         // free-text body (mutually exclusive with Template)
	Category   SMSCategory    // required with Text; omit on a template send
	Template   string         // stored template id (smt_…) or name (mutually exclusive with Text)
	Language   string         // template language as a BCP-47 tag; template sends only
	Parameters map[string]any // template variable values; template sends only
	Tags       []SMSTag       // structured {name, value} labels for filtering and analytics
	Metadata   map[string]any // arbitrary JSON stored on the message and echoed in webhooks
}

SmsSendParams is a single SMS send. Provide either Text (with Category) or a Template (by id or name, with Parameters) — the two are mutually exclusive. Zero-value fields are omitted from the request.

type TimeoutError

type TimeoutError = apierror.TimeoutError

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type UnmetGate added in v0.4.1

type UnmetGate = apierror.UnmetGate

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type ValidationError

type ValidationError = apierror.ValidationError

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type Verification added in v0.7.0

type Verification = oapi.Verification

Verification is a verification's current state (id, status, channel plan); VerificationCheckResult is a check outcome plus the verification's state.

type VerificationCheckParams added in v0.7.0

type VerificationCheckParams struct {
	Email string // recipient email the verification was started for
	Phone string // recipient phone the verification was started for
	Code  string // the passcode the recipient submitted
}

VerificationCheckParams checks a submitted passcode. Identify the verification by the same recipient it was started for.

type VerificationCheckResult added in v0.7.0

type VerificationCheckResult = oapi.VerificationCheckResult

Verification is a verification's current state (id, status, channel plan); VerificationCheckResult is a check outcome plus the verification's state.

type VerificationCreateParams added in v0.7.0

type VerificationCreateParams struct {
	Email      string         // recipient email address, verified over email
	Phone      string         // recipient phone number in E.164, verified over SMS
	CodeLength int            // passcode length 4–8, overriding the configured length
	Channels   []string       // delivery channels to try, in order; empty uses the configured order
	Metadata   map[string]any // arbitrary key/value pairs stored on the verification
}

VerificationCreateParams starts a verification. Provide Email, Phone, or both; zero-value fields are omitted from the request.

type VerificationsService added in v0.7.0

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

VerificationsService starts a verification — sending a one-time passcode — and checks the passcode a recipient submits.

func (*VerificationsService) Check added in v0.7.0

Check checks a passcode a recipient submitted. A wrong or expired code returns a result with Success false and a Reason — not an error; a verification already resolved is no longer checkable and returns a 404 error. Retried safely with a reused idempotency key.

Example

Check the passcode a recipient submitted, identified by the same recipient.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	result, err := client.Verify.Verifications.Check(context.Background(), bird.VerificationCheckParams{
		Phone: "+15551234567",
		Code:  "123456",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(*result.Success)
}

func (*VerificationsService) Create added in v0.7.0

Create starts a verification and sends a one-time passcode to the recipient. It is also the resend: starting again for the same recipient re-sends the code after the cooldown rather than opening a second verification. Retried safely — a single idempotency key is reused across attempts.

Example

Start a verification: send a one-time passcode over SMS.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	verification, err := client.Verify.Verifications.Create(context.Background(), bird.VerificationCreateParams{
		Phone: "+15551234567",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(verification.Id, *verification.Status)
}

type VerifyService added in v0.7.0

type VerifyService struct {
	// Verifications starts verifications and checks the passcodes recipients submit.
	Verifications *VerificationsService
}

VerifyService is the Verify product namespace. Reach it via Client.Verify.

type WebhookEventType

type WebhookEventType = oapi.WebhookEventType

WebhookEventType is a webhook event's discriminant. It is an open string: the known values are the EventType* constants, and an event type added by a newer server flows through Unwrap as a plain string.

const (
	EventTypeDomainFailed                    WebhookEventType = "domain.failed"
	EventTypeDomainVerified                  WebhookEventType = "domain.verified"
	EventTypeEmailAccepted                   WebhookEventType = "email.accepted"
	EventTypeEmailBounced                    WebhookEventType = "email.bounced"
	EventTypeEmailCanceled                   WebhookEventType = "email.canceled"
	EventTypeEmailClicked                    WebhookEventType = "email.clicked"
	EventTypeEmailComplained                 WebhookEventType = "email.complained"
	EventTypeEmailDeferred                   WebhookEventType = "email.deferred"
	EventTypeEmailDelivered                  WebhookEventType = "email.delivered"
	EventTypeEmailListUnsubscribed           WebhookEventType = "email.list_unsubscribed"
	EventTypeEmailMailboxMessageDelivered    WebhookEventType = "email_mailbox.message_delivered"
	EventTypeEmailMailboxMessageFailed       WebhookEventType = "email_mailbox.message_failed"
	EventTypeEmailMailboxMessageReceived     WebhookEventType = "email_mailbox.message_received"
	EventTypeEmailMailboxMessageSent         WebhookEventType = "email_mailbox.message_sent"
	EventTypeEmailMailboxSuspended           WebhookEventType = "email_mailbox.suspended"
	EventTypeEmailMailboxThreadCreated       WebhookEventType = "email_mailbox.thread_created"
	EventTypeEmailOpened                     WebhookEventType = "email.opened"
	EventTypeEmailOutOfBandBounce            WebhookEventType = "email.out_of_band_bounce"
	EventTypeEmailProcessed                  WebhookEventType = "email.processed"
	EventTypeEmailReceived                   WebhookEventType = "email.received"
	EventTypeEmailRejected                   WebhookEventType = "email.rejected"
	EventTypeEmailScheduled                  WebhookEventType = "email.scheduled"
	EventTypeEmailSuppressionCreated         WebhookEventType = "email_suppression.created"
	EventTypeEmailUnsubscribed               WebhookEventType = "email.unsubscribed"
	EventTypeRealtimeCacheChannels           WebhookEventType = "realtime.cache_channels"
	EventTypeRealtimeChannelExistence        WebhookEventType = "realtime.channel_existence"
	EventTypeRealtimeClientEvents            WebhookEventType = "realtime.client_events"
	EventTypeRealtimeConnectionCount         WebhookEventType = "realtime.connection_count"
	EventTypeRealtimePresence                WebhookEventType = "realtime.presence"
	EventTypeSmsAccepted                     WebhookEventType = "sms.accepted"
	EventTypeSmsDelivered                    WebhookEventType = "sms.delivered"
	EventTypeSmsExpired                      WebhookEventType = "sms.expired"
	EventTypeSmsFailed                       WebhookEventType = "sms.failed"
	EventTypeSmsRejected                     WebhookEventType = "sms.rejected"
	EventTypeSmsSent                         WebhookEventType = "sms.sent"
	EventTypeSmsTfnVerificationApproved      WebhookEventType = "sms.tfn_verification.approved"
	EventTypeSmsTfnVerificationInfoRequested WebhookEventType = "sms.tfn_verification.info_requested"
	EventTypeSmsTfnVerificationRejected      WebhookEventType = "sms.tfn_verification.rejected"
	EventTypeSmsTfnVerificationSubmitted     WebhookEventType = "sms.tfn_verification.submitted"
	EventTypeSmsUndelivered                  WebhookEventType = "sms.undelivered"
	EventTypeVerifyAttemptDelivered          WebhookEventType = "verify.attempt.delivered"
	EventTypeVerifyAttemptSent               WebhookEventType = "verify.attempt.sent"
	EventTypeVerifyAttemptUndelivered        WebhookEventType = "verify.attempt.undelivered"
	EventTypeVerifyVerificationCreated       WebhookEventType = "verify.verification.created"
	EventTypeVerifyVerificationVerified      WebhookEventType = "verify.verification.verified"
	EventTypeVoiceCallAnswered               WebhookEventType = "voice_call.answered"
	EventTypeVoiceCallEnded                  WebhookEventType = "voice_call.ended"
	EventTypeVoiceCallInitiated              WebhookEventType = "voice_call.initiated"
	EventTypeWhatsappAccepted                WebhookEventType = "whatsapp.accepted"
	EventTypeWhatsappDelivered               WebhookEventType = "whatsapp.delivered"
	EventTypeWhatsappFailed                  WebhookEventType = "whatsapp.failed"
	EventTypeWhatsappRead                    WebhookEventType = "whatsapp.read"
	EventTypeWhatsappRejected                WebhookEventType = "whatsapp.rejected"
	EventTypeWhatsappSent                    WebhookEventType = "whatsapp.sent"
)

Webhook event types known at this SDK version. WebhookEventType is an open string on the wire: a value added by a newer server flows through Unwrap unchanged, so switch on these constants with a default branch.

type WebhookService

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

WebhookService verifies inbound webhook deliveries. Reach it via Client.Webhooks. Configure the signing secret with option.WithWebhookSecret on the client (or per call on Unwrap). It is pure crypto — no transport.

func (*WebhookService) Unwrap

func (s *WebhookService) Unwrap(payload []byte, headers http.Header, opts ...option.RequestOption) (Event, error)

Unwrap verifies the Standard Webhooks signature over the raw request body and returns the decoded event. Hand it the exact bytes received — parsing and re-serializing before verifying breaks the signature.

Example

Unwrap verifies the Standard Webhooks signature over the raw request body and returns a typed event to dispatch on.

package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(
		option.WithAPIKey(os.Getenv("BIRD_API_KEY")),
		option.WithWebhookSecret(os.Getenv("BIRD_WEBHOOK_SECRET")),
	)
	if err != nil {
		log.Fatal(err)
	}
	http.HandleFunc("/webhooks/bird", func(w http.ResponseWriter, r *http.Request) {
		body, _ := io.ReadAll(r.Body)
		event, err := client.Webhooks.Unwrap(body, r.Header)
		if err != nil {
			http.Error(w, "invalid signature", http.StatusBadRequest)
			return
		}
		w.WriteHeader(http.StatusNoContent) // ack fast, then process

		payload, _ := event.AsAny()
		switch p := payload.(type) {
		case bird.EmailDeliveredEvent:
			fmt.Println("delivered:", p.Data.EmailId, p.Data.Recipient)
		case bird.EmailBouncedEvent:
			fmt.Println("bounced:", p.Type)
		}
	})
}

type WebhookVerificationError

type WebhookVerificationError = apierror.WebhookVerificationError

The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.

type WhatsAppEvent added in v0.6.0

type WhatsAppEvent = oapi.WhatsAppEvent

WhatsAppEvent is a single lifecycle event on a message's timeline; WhatsAppEventList is the (unpaginated) timeline for one message.

type WhatsAppEventList added in v0.6.0

type WhatsAppEventList = oapi.WhatsAppEventList

WhatsAppEvent is a single lifecycle event on a message's timeline; WhatsAppEventList is the (unpaginated) timeline for one message.

type WhatsAppMessage added in v0.6.0

type WhatsAppMessage = oapi.WhatsAppMessage

WhatsAppMessage is a sent or received WhatsApp message; WhatsAppMessageList is a page of messages.

type WhatsAppMessageList added in v0.6.0

type WhatsAppMessageList = oapi.WhatsAppMessageList

WhatsAppMessage is a sent or received WhatsApp message; WhatsAppMessageList is a page of messages.

type WhatsAppMessageStatus added in v0.6.0

type WhatsAppMessageStatus = oapi.WhatsAppMessageStatus

WhatsAppMessageStatus is a message's delivery status.

type WhatsAppMessageTemplateComponent added in v0.6.0

type WhatsAppMessageTemplateComponent = oapi.WhatsAppMessageTemplateComponent

WhatsAppMessageTemplateComponent is a filled-in template component — supplied on a template send and echoed back on the sent message. WhatsAppMessageTemplateComponentParameter is one of its placeholder values.

type WhatsAppMessageTemplateComponentParameter added in v0.6.0

type WhatsAppMessageTemplateComponentParameter = oapi.WhatsAppMessageTemplateComponentParameter

WhatsAppMessageTemplateComponent is a filled-in template component — supplied on a template send and echoed back on the sent message. WhatsAppMessageTemplateComponentParameter is one of its placeholder values.

type WhatsAppService added in v0.6.0

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

WhatsAppService sends WhatsApp template messages and reads them back. Reach it via Client.Whatsapp.

func (*WhatsAppService) Get added in v0.6.0

Get returns a single WhatsApp message with its current delivery status and failure detail if it failed.

Example

Read a single WhatsApp message by id.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	msg, err := client.Whatsapp.Get(context.Background(), "wam_01krdgeqcxet5s7t44vh8rt9mg")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(msg.Id, *msg.Status)
}

func (*WhatsAppService) List added in v0.6.0

List walks every message matching params, fetching pages lazily. Range over it; the second value is non-nil only on the iteration where a fetch failed.

Example

List WhatsApp messages to a given contact, paginating lazily.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	for msg, err := range client.Whatsapp.List(context.Background(), bird.WhatsappListParams{PhoneNumber: "+15551234567"}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(msg.Id)
	}
}

func (*WhatsAppService) ListEvents added in v0.6.0

ListEvents returns the lifecycle event timeline for a WhatsApp message, in chronological order. The timeline is bounded and returned in full — this list is not paginated.

Example

List the lifecycle events for a WhatsApp message, in chronological order.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	events, err := client.Whatsapp.ListEvents(context.Background(), "wam_01krdgeqcxet5s7t44vh8rt9mg", bird.WhatsappListEventsParams{})
	if err != nil {
		log.Fatal(err)
	}
	for _, e := range events.Data {
		fmt.Println(e.Id, *e.Type)
	}
}

func (*WhatsAppService) ListPage added in v0.6.0

func (s *WhatsAppService) ListPage(ctx context.Context, params WhatsappListParams, startingAfter string, opts ...option.RequestOption) (*WhatsAppMessageList, error)

ListPage fetches one page of messages. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the most recent.

func (*WhatsAppService) Send added in v0.6.0

Send sends one WhatsApp template message. Retried safely: a single idempotency key is reused across attempts. Provide your own key with option.WithIdempotencyKey.

Example

Send a WhatsApp template message. Templates are currently the only supported content type.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	msg, err := client.Whatsapp.Send(context.Background(), bird.WhatsappSendParams{
		To:       "+15551234567",
		Template: "bird_otp",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(msg.Id, *msg.Status)
}

type WhatsAppTemplate added in v0.6.0

type WhatsAppTemplate = oapi.WhatsAppTemplate

WhatsAppTemplate is a template available to the workspace; WhatsAppTemplateList is the (unpaginated) set of templates.

type WhatsAppTemplateList added in v0.6.0

type WhatsAppTemplateList = oapi.WhatsAppTemplateList

WhatsAppTemplate is a template available to the workspace; WhatsAppTemplateList is the (unpaginated) set of templates.

type WhatsAppTemplatesService added in v0.6.0

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

WhatsAppTemplatesService reads the WhatsApp templates available to a workspace — Bird's built-in templates and any the workspace authored. Reach it via Client.WhatsappTemplates. The catalogue is read-only through this SDK.

func (*WhatsAppTemplatesService) List added in v0.6.0

List returns the WhatsApp templates available to the workspace. The catalogue is small and returned in full — this list is not paginated.

Example

List the WhatsApp templates available to the workspace. The catalogue is small and returned in full — this list is not paginated.

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	bird "github.com/messagebird/bird-sdk-go"
	"github.com/messagebird/bird-sdk-go/option"
)

func main() {
	client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	list, err := client.WhatsappTemplates.List(context.Background())
	if err != nil {
		log.Fatal(err)
	}
	for _, tpl := range list.Data {
		fmt.Println(*tpl.Name)
	}
}

type WhatsappListEventsParams added in v0.6.0

type WhatsappListEventsParams struct {
	Type string // filter by event type (e.g. "whatsapp.delivered"); empty returns every event
}

WhatsappListEventsParams filters a message's event timeline. Zero-value fields are omitted.

type WhatsappListParams added in v0.6.0

type WhatsappListParams struct {
	Statuses      []WhatsAppMessageStatus // filter by any of several delivery statuses
	PhoneNumber   string                  // filter by contact phone number (E.164 exact match)
	Bsuid         string                  // filter by business-scoped user ID (Meta identifier)
	CreatedAfter  time.Time
	CreatedBefore time.Time
	Limit         int
}

WhatsappListParams filters the message list. Zero-value fields are omitted.

type WhatsappSendParams added in v0.6.0

type WhatsappSendParams struct {
	To         string                             // required; recipient phone number in E.164 format
	Template   string                             // required; the template's stable handle (e.g. bird_otp)
	Language   string                             // template language variant; omit when the template has a single language
	Components []WhatsAppMessageTemplateComponent // values that fill the template's placeholders
}

WhatsappSendParams is a single WhatsApp message send. Templates are currently the only supported content type, so Template is required; free-form content will be added in a future release. Zero-value fields are omitted from the request.

Directories

Path Synopsis
examples
internal
apierror
Package apierror holds the SDK's error model: the wire-error mapping and the typed error hierarchy returned to callers.
Package apierror holds the SDK's error model: the wire-error mapping and the typed error hierarchy returned to callers.
oapi
Package oapi provides primitives to interact with the openapi HTTP API.
Package oapi provides primitives to interact with the openapi HTTP API.
requestconfig
Package requestconfig holds the resolved per-request configuration.
Package requestconfig holds the resolved per-request configuration.
Package option carries the functional options that configure a bird.Client at construction and override settings for a single call.
Package option carries the functional options that configure a bird.Client at construction and override settings for a single call.

Jump to

Keyboard shortcuts

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