bird

package module
v0.41.0 Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2026 License: MIT Imports: 25 Imported by: 0

README

Bird Go SDK

The official Go SDK for the Bird API: email, SMS, WhatsApp, verification, and Realtime, over one typed client.

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.SmsSend (free text or a stored template), SendBatch, Get, List (auto-paginating; ListPage for manual cursors). client.SmsTemplates (List, Get) browses the templates a send can name.
  • client.WhatsappSend (a template, or free-form text/media/location), Get, List (auto-paginating; ListPage for manual cursors), ListEvents (a message's delivery timeline). Browse your workspace's approved templates in the Bird dashboard.
  • client.VerifyVerifications.Create (send a one-time passcode) and Verifications.Check (validate the code a recipient submitted).
  • client.LookupPhoneNumber (what a number is: country, serving network, line type, plus paid properties named in Type) and Email (whether an address is worth sending to). Every answer is billed: the base number lookup once plus once per delivered property, an email lookup once per answered address. Only a property block whose Status is "ok" carries a value, and only that one is billed, so read the status before the value.
  • client.RealtimePublish, PublishBatch, plus Channels (List, Get, Members) and Members.Disconnect. Every call takes the Realtime app id and needs the app's own credentials on top of the API key: option.WithRealtimeCredentials(key, secret), at construction or per call.
  • client.ContactsCreate, Get, Update, Delete, Batch, List (auto-paginating). client.Audiences groups them (Create, Get, Update, Delete, List, plus ListContacts, AddContacts, RemoveContacts, RemoveContact), and client.ContactProperties defines the fields a contact carries (Create, Get, Update, List, Archive, Unarchive).
  • client.DomainsCreate, Get, Update, Delete, List, and Verify (check a sending domain's DNS).
  • 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 official Go SDK for the Bird API.

It covers email, SMS, WhatsApp, verification, and Realtime on one typed client, and 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.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

Code generated by surface-gen; DO NOT EDIT.

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.

View Source
const (
	EventTypeDomainFailed                 = oapi.EventTypeDomainFailed
	EventTypeDomainVerified               = oapi.EventTypeDomainVerified
	EventTypeEmailAccepted                = oapi.EventTypeEmailAccepted
	EventTypeEmailBounced                 = oapi.EventTypeEmailBounced
	EventTypeEmailCanceled                = oapi.EventTypeEmailCanceled
	EventTypeEmailClicked                 = oapi.EventTypeEmailClicked
	EventTypeEmailComplained              = oapi.EventTypeEmailComplained
	EventTypeEmailDeferred                = oapi.EventTypeEmailDeferred
	EventTypeEmailDelivered               = oapi.EventTypeEmailDelivered
	EventTypeEmailListUnsubscribed        = oapi.EventTypeEmailListUnsubscribed
	EventTypeEmailMailboxMessageDelivered = oapi.EventTypeEmailMailboxMessageDelivered
	EventTypeEmailMailboxMessageFailed    = oapi.EventTypeEmailMailboxMessageFailed
	EventTypeEmailMailboxMessageReceived  = oapi.EventTypeEmailMailboxMessageReceived
	EventTypeEmailMailboxMessageSent      = oapi.EventTypeEmailMailboxMessageSent
	EventTypeEmailMailboxSuspended        = oapi.EventTypeEmailMailboxSuspended
	EventTypeEmailMailboxThreadCreated    = oapi.EventTypeEmailMailboxThreadCreated
	EventTypeEmailOpened                  = oapi.EventTypeEmailOpened
	EventTypeEmailOutOfBandBounce         = oapi.EventTypeEmailOutOfBandBounce
	EventTypeEmailProcessed               = oapi.EventTypeEmailProcessed
	EventTypeEmailReceived                = oapi.EventTypeEmailReceived
	EventTypeEmailRejected                = oapi.EventTypeEmailRejected
	EventTypeEmailScheduled               = oapi.EventTypeEmailScheduled
	EventTypeEmailSuppressionCreated      = oapi.EventTypeEmailSuppressionCreated
	EventTypeEmailUnsubscribed            = oapi.EventTypeEmailUnsubscribed
	EventTypePreferenceDeleted            = oapi.EventTypePreferenceDeleted
	EventTypePreferenceGranted            = oapi.EventTypePreferenceGranted
	EventTypePreferenceRevoked            = oapi.EventTypePreferenceRevoked
	EventTypeSmsAccepted                  = oapi.EventTypeSmsAccepted
	EventTypeSmsDelivered                 = oapi.EventTypeSmsDelivered
	EventTypeSmsExpired                   = oapi.EventTypeSmsExpired
	EventTypeSmsFailed                    = oapi.EventTypeSmsFailed
	EventTypeSmsReceived                  = oapi.EventTypeSmsReceived
	EventTypeSmsRejected                  = oapi.EventTypeSmsRejected
	EventTypeSmsSent                      = oapi.EventTypeSmsSent
	EventTypeSmsSuppressionCreated        = oapi.EventTypeSmsSuppressionCreated
	EventTypeSmsUndelivered               = oapi.EventTypeSmsUndelivered
	EventTypeVerifyAttemptDelivered       = oapi.EventTypeVerifyAttemptDelivered
	EventTypeVerifyAttemptSent            = oapi.EventTypeVerifyAttemptSent
	EventTypeVerifyAttemptUndelivered     = oapi.EventTypeVerifyAttemptUndelivered
	EventTypeVerifyVerificationCreated    = oapi.EventTypeVerifyVerificationCreated
	EventTypeVerifyVerificationFailed     = oapi.EventTypeVerifyVerificationFailed
	EventTypeVerifyVerificationVerified   = oapi.EventTypeVerifyVerificationVerified
	EventTypeVoiceCallAnswered            = oapi.EventTypeVoiceCallAnswered
	EventTypeVoiceCallEnded               = oapi.EventTypeVoiceCallEnded
	EventTypeVoiceCallInitiated           = oapi.EventTypeVoiceCallInitiated
	EventTypeWhatsappAccepted             = oapi.EventTypeWhatsappAccepted
	EventTypeWhatsappDelivered            = oapi.EventTypeWhatsappDelivered
	EventTypeWhatsappFailed               = oapi.EventTypeWhatsappFailed
	EventTypeWhatsappRead                 = oapi.EventTypeWhatsappRead
	EventTypeWhatsappReceived             = oapi.EventTypeWhatsappReceived
	EventTypeWhatsappRejected             = oapi.EventTypeWhatsappRejected
	EventTypeWhatsappSent                 = oapi.EventTypeWhatsappSent
	EventTypeWhatsappSuppressionCreated   = oapi.EventTypeWhatsappSuppressionCreated
)

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.

View Source
const (
	EmailEventTypeEmailAccepted         = oapi.EmailEventTypeEmailAccepted
	EmailEventTypeEmailBounced          = oapi.EmailEventTypeEmailBounced
	EmailEventTypeEmailCanceled         = oapi.EmailEventTypeEmailCanceled
	EmailEventTypeEmailClicked          = oapi.EmailEventTypeEmailClicked
	EmailEventTypeEmailComplained       = oapi.EmailEventTypeEmailComplained
	EmailEventTypeEmailDeferred         = oapi.EmailEventTypeEmailDeferred
	EmailEventTypeEmailDelivered        = oapi.EmailEventTypeEmailDelivered
	EmailEventTypeEmailListUnsubscribed = oapi.EmailEventTypeEmailListUnsubscribed
	EmailEventTypeEmailOpened           = oapi.EmailEventTypeEmailOpened
	EmailEventTypeEmailOutOfBandBounce  = oapi.EmailEventTypeEmailOutOfBandBounce
	EmailEventTypeEmailProcessed        = oapi.EmailEventTypeEmailProcessed
	EmailEventTypeEmailRejected         = oapi.EmailEventTypeEmailRejected
	EmailEventTypeEmailScheduled        = oapi.EmailEventTypeEmailScheduled
	EmailEventTypeEmailUnsubscribed     = oapi.EmailEventTypeEmailUnsubscribed
)
View Source
const (
	EmailLookupFlagDisposable   = oapi.EmailLookupFlagDisposable
	EmailLookupFlagFreeProvider = oapi.EmailLookupFlagFreeProvider
	EmailLookupFlagRole         = oapi.EmailLookupFlagRole
)
View Source
const (
	EmailLookupReasonInvalidDomain    = oapi.EmailLookupReasonInvalidDomain
	EmailLookupReasonInvalidRecipient = oapi.EmailLookupReasonInvalidRecipient
	EmailLookupReasonInvalidSyntax    = oapi.EmailLookupReasonInvalidSyntax
)
View Source
const (
	EmailLookupResultNeutral       = oapi.EmailLookupResultNeutral
	EmailLookupResultRisky         = oapi.EmailLookupResultRisky
	EmailLookupResultTypo          = oapi.EmailLookupResultTypo
	EmailLookupResultUndeliverable = oapi.EmailLookupResultUndeliverable
	EmailLookupResultValid         = oapi.EmailLookupResultValid
)
View Source
const (
	LookupPropertyStatusInconclusive = oapi.LookupPropertyStatusInconclusive
	LookupPropertyStatusOk           = oapi.LookupPropertyStatusOk
	LookupPropertyStatusUnavailable  = oapi.LookupPropertyStatusUnavailable
)
View Source
const (
	NumberCapabilityMms   = oapi.NumberCapabilityMms
	NumberCapabilitySms   = oapi.NumberCapabilitySms
	NumberCapabilityVoice = oapi.NumberCapabilityVoice
)
View Source
const (
	NumberTypeLocal         = oapi.NumberTypeLocal
	NumberTypeMobile        = oapi.NumberTypeMobile
	NumberTypeNational      = oapi.NumberTypeNational
	NumberTypeShortCode     = oapi.NumberTypeShortCode
	NumberTypeShortCodeFteu = oapi.NumberTypeShortCodeFteu
	NumberTypeTollFree      = oapi.NumberTypeTollFree
)
View Source
const (
	NumbersOrderStatusCharging  = oapi.NumbersOrderStatusCharging
	NumbersOrderStatusCompleted = oapi.NumbersOrderStatusCompleted
	NumbersOrderStatusFailed    = oapi.NumbersOrderStatusFailed
	NumbersOrderStatusOrdering  = oapi.NumbersOrderStatusOrdering
	NumbersOrderStatusPending   = oapi.NumbersOrderStatusPending
)
View Source
const (
	PreferenceChannelEmail    = oapi.PreferenceChannelEmail
	PreferenceChannelSms      = oapi.PreferenceChannelSms
	PreferenceChannelWhatsapp = oapi.PreferenceChannelWhatsapp
)
View Source
const (
	PreferenceOriginApiKey           = oapi.PreferenceOriginApiKey
	PreferenceOriginImport           = oapi.PreferenceOriginImport
	PreferenceOriginKeyword          = oapi.PreferenceOriginKeyword
	PreferenceOriginPreferencePage   = oapi.PreferenceOriginPreferencePage
	PreferenceOriginUnsubscribeEvent = oapi.PreferenceOriginUnsubscribeEvent
	PreferenceOriginUnsubscribeLink  = oapi.PreferenceOriginUnsubscribeLink
	PreferenceOriginUser             = oapi.PreferenceOriginUser
)
View Source
const (
	SMSErrorCodeBlockedByCarrier    = oapi.SMSErrorCodeBlockedByCarrier
	SMSErrorCodeBlockedByRecipient  = oapi.SMSErrorCodeBlockedByRecipient
	SMSErrorCodeContentRejected     = oapi.SMSErrorCodeContentRejected
	SMSErrorCodeInsufficientBalance = oapi.SMSErrorCodeInsufficientBalance
	SMSErrorCodeInvalidDestination  = oapi.SMSErrorCodeInvalidDestination
	SMSErrorCodeLandlineUnreachable = oapi.SMSErrorCodeLandlineUnreachable
	SMSErrorCodeProviderUnavailable = oapi.SMSErrorCodeProviderUnavailable
	SMSErrorCodeRecipientOptedOut   = oapi.SMSErrorCodeRecipientOptedOut
	SMSErrorCodeSenderUnregistered  = oapi.SMSErrorCodeSenderUnregistered
	SMSErrorCodeUnknown             = oapi.SMSErrorCodeUnknown
	SMSErrorCodeUnreachable         = oapi.SMSErrorCodeUnreachable
)
View Source
const (
	SMSKeywordOperationConfirm = oapi.SMSKeywordOperationConfirm
	SMSKeywordOperationCustom  = oapi.SMSKeywordOperationCustom
	SMSKeywordOperationHelp    = oapi.SMSKeywordOperationHelp
	SMSKeywordOperationInfo    = oapi.SMSKeywordOperationInfo
	SMSKeywordOperationStart   = oapi.SMSKeywordOperationStart
	SMSKeywordOperationStop    = oapi.SMSKeywordOperationStop
)
View Source
const (
	SMSSuppressionCoverageAll              = oapi.SMSSuppressionCoverageAll
	SMSSuppressionCoverageNonTransactional = oapi.SMSSuppressionCoverageNonTransactional
)
View Source
const (
	SMSSuppressionEndReasonApiKey         = oapi.SMSSuppressionEndReasonApiKey
	SMSSuppressionEndReasonCarrierCleared = oapi.SMSSuppressionEndReasonCarrierCleared
	SMSSuppressionEndReasonKeywordStart   = oapi.SMSSuppressionEndReasonKeywordStart
	SMSSuppressionEndReasonUser           = oapi.SMSSuppressionEndReasonUser
)
View Source
const (
	SMSSuppressionOriginApiKey   = oapi.SMSSuppressionOriginApiKey
	SMSSuppressionOriginDlrEvent = oapi.SMSSuppressionOriginDlrEvent
	SMSSuppressionOriginKeyword  = oapi.SMSSuppressionOriginKeyword
	SMSSuppressionOriginUser     = oapi.SMSSuppressionOriginUser
)
View Source
const (
	SMSSuppressionReasonCarrierOptedOut = oapi.SMSSuppressionReasonCarrierOptedOut
	SMSSuppressionReasonKeywordStop     = oapi.SMSSuppressionReasonKeywordStop
	SMSSuppressionReasonManual          = oapi.SMSSuppressionReasonManual
)
View Source
const (
	TemplateLanguageStatusDraft      = oapi.TemplateLanguageStatusDraft
	TemplateLanguageStatusLive       = oapi.TemplateLanguageStatusLive
	TemplateLanguageStatusSuperseded = oapi.TemplateLanguageStatusSuperseded
)
View Source
const (
	TemplateStatusActive   = oapi.TemplateStatusActive
	TemplateStatusDraft    = oapi.TemplateStatusDraft
	TemplateStatusInactive = oapi.TemplateStatusInactive
	TemplateStatusPending  = oapi.TemplateStatusPending
	TemplateStatusRejected = oapi.TemplateStatusRejected
)
View Source
const (
	VerificationAttemptFailureReasonCarrierRejected    = oapi.VerificationAttemptFailureReasonCarrierRejected
	VerificationAttemptFailureReasonChannelDisabled    = oapi.VerificationAttemptFailureReasonChannelDisabled
	VerificationAttemptFailureReasonChannelUnavailable = oapi.VerificationAttemptFailureReasonChannelUnavailable
	VerificationAttemptFailureReasonDeliveryTimeout    = oapi.VerificationAttemptFailureReasonDeliveryTimeout
	VerificationAttemptFailureReasonHardBounce         = oapi.VerificationAttemptFailureReasonHardBounce
	VerificationAttemptFailureReasonNotBillable        = oapi.VerificationAttemptFailureReasonNotBillable
	VerificationAttemptFailureReasonSoftBounce         = oapi.VerificationAttemptFailureReasonSoftBounce
	VerificationAttemptFailureReasonUndelivered        = oapi.VerificationAttemptFailureReasonUndelivered
)
View Source
const (
	VerificationChannelEmail    = oapi.VerificationChannelEmail
	VerificationChannelSms      = oapi.VerificationChannelSms
	VerificationChannelTelegram = oapi.VerificationChannelTelegram
	VerificationChannelWhatsapp = oapi.VerificationChannelWhatsapp
)
View Source
const (
	VerificationTerminalReasonAttemptsExhausted = oapi.VerificationTerminalReasonAttemptsExhausted
	VerificationTerminalReasonTtlElapsed        = oapi.VerificationTerminalReasonTtlElapsed
	VerificationTerminalReasonUndeliverable     = oapi.VerificationTerminalReasonUndeliverable
)
View Source
const (
	WhatsAppErrorCodeInsufficientBalance  = oapi.WhatsAppErrorCodeInsufficientBalance
	WhatsAppErrorCodeInternalError        = oapi.WhatsAppErrorCodeInternalError
	WhatsAppErrorCodeMediaRejected        = oapi.WhatsAppErrorCodeMediaRejected
	WhatsAppErrorCodePriceNotFound        = oapi.WhatsAppErrorCodePriceNotFound
	WhatsAppErrorCodeRateLimited          = oapi.WhatsAppErrorCodeRateLimited
	WhatsAppErrorCodeRecipientSuppressed  = oapi.WhatsAppErrorCodeRecipientSuppressed
	WhatsAppErrorCodeServiceWindowExpired = oapi.WhatsAppErrorCodeServiceWindowExpired
	WhatsAppErrorCodeUndeliverable        = oapi.WhatsAppErrorCodeUndeliverable
)
View Source
const (
	WhatsAppEventTypeWhatsappAccepted  = oapi.WhatsAppEventTypeWhatsappAccepted
	WhatsAppEventTypeWhatsappDelivered = oapi.WhatsAppEventTypeWhatsappDelivered
	WhatsAppEventTypeWhatsappFailed    = oapi.WhatsAppEventTypeWhatsappFailed
	WhatsAppEventTypeWhatsappRead      = oapi.WhatsAppEventTypeWhatsappRead
	WhatsAppEventTypeWhatsappReceived  = oapi.WhatsAppEventTypeWhatsappReceived
	WhatsAppEventTypeWhatsappRejected  = oapi.WhatsAppEventTypeWhatsappRejected
	WhatsAppEventTypeWhatsappSent      = oapi.WhatsAppEventTypeWhatsappSent
)
View Source
const (
	WhatsAppTemplateCategoryAuthentication = oapi.WhatsAppTemplateCategoryAuthentication
	WhatsAppTemplateCategoryMarketing      = oapi.WhatsAppTemplateCategoryMarketing
	WhatsAppTemplateCategoryUtility        = oapi.WhatsAppTemplateCategoryUtility
)
View Source
const (
	WhatsAppTemplateParameterTypeDocument = oapi.WhatsAppTemplateParameterTypeDocument
	WhatsAppTemplateParameterTypeGif      = oapi.WhatsAppTemplateParameterTypeGif
	WhatsAppTemplateParameterTypeImage    = oapi.WhatsAppTemplateParameterTypeImage
	WhatsAppTemplateParameterTypeLocation = oapi.WhatsAppTemplateParameterTypeLocation
	WhatsAppTemplateParameterTypeText     = oapi.WhatsAppTemplateParameterTypeText
	WhatsAppTemplateParameterTypeVideo    = oapi.WhatsAppTemplateParameterTypeVideo
)
View Source
const (
	LookupFlagPorted = oapi.LookupFlagPorted
)

Variables

This section is empty.

Functions

func Bool

func Bool(v bool) *bool

Bool returns a pointer to v.

func Email added in v0.22.0

func Email(v string) *openapi_types.Email

Email returns a pointer to v as an email-typed field. A schema's `format: email` property is its own type on the wire, so bird.String does not fit one and Ptr needs the conversion spelled out:

bird.VerificationTo{Email: bird.Email("user@example.com")}

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, Int, and Email 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` is an explicit member list you manage by adding and removing contacts.
	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 a contact's email address or the digits in its international phone number.
	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. To add contacts you have not created yet, use `contacts.batch` with `audience_ids` instead: it matches or creates each contact by email address and assigns it to the audience in one call.

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 AvailableNumber added in v0.34.0

type AvailableNumber = oapi.AvailableNumber

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. The write-side *Config aliases accompany DomainCreateParams / DomainUpdateParams.

type AvailableNumberList added in v0.34.0

type AvailableNumberList = oapi.AvailableNumberList

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. The write-side *Config aliases accompany DomainCreateParams / DomainUpdateParams.

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
	SmsSuppressions   *SmsSuppressionsService
	SmsKeywordRules   *SmsKeywordRulesService
	Whatsapp          *WhatsappService
	Voice             *VoiceService
	Verify            *VerifyService
	Webhooks          *WebhookService
	Contacts          *ContactsService
	Audiences         *AudiencesService
	ContactProperties *ContactPropertiesService
	Domains           *DomainsService
	Realtime          *RealtimeService
	Lookup            *LookupService
	Numbers           *NumbersService
	Preferences       *PreferencesService
	// 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 to create or update, matched automatically against every identifier an entry supplies. Existing contacts are updated with the fields each entry supplies; omitted fields keep their stored values, so an entry can set fields but never clear them. Unmatched entries create contacts.
	Contacts []ContactCreateRequest
	// Audiences every contact in this request is added to. Contacts that are already members are left in place. Every listed audience must exist, or the whole request fails with a validation error and nothing is written.
	AudienceIDs []string
	// Optional field used to match every entry to an existing contact. Every entry must include this field when set. When omitted, each entry is matched against all identifiers it supplies. No match creates a contact, one match updates it, and identifiers that match multiple contacts return an error naming each contact.
	MatchOn *ContactMatchKey
	// How a supplied `data` object is applied to an existing contact. The default `merge` mode adds the supplied keys to the contact's stored custom values. A key with a `null` value deletes that key. The `replace` mode overwrites the whole stored `data` map with the supplied map. In both modes a contact that omits `data` keeps its stored values unchanged, so an import that touches one attribute never wipes the others.
	DataMode *ContactUpsertRequestDataMode
}

ContactBatchParams is the request body for batch.

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. Supply an email address, a phone number, or both.
	Email string
	// The contact's phone number in E.164 format, including the leading `+` and country code. Spaces and punctuation are accepted and stripped; the number is stored in its canonical form, which may differ from what you send, and is unique within the workspace. An empty string is treated as if the field were omitted. Supply an email address, a phone number, or both.
	PhoneNumber 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 an active contact property. Each value must match the property's declared type: string, number, boolean, or RFC 3339 datetime. Strings can contain up to `500` characters, and a `null` value is ignored. Unregistered or archived keys return a validation error. The serialized data is limited to 2 KB.
	Data map[string]any
}

ContactCreateParams is the request body for create.

type ContactCreateRequest added in v0.16.0

type ContactCreateRequest = oapi.ContactCreateRequest

type ContactIdentifierFilter added in v0.27.0

type ContactIdentifierFilter = oapi.ContactIdentifierFilter

ContactIdentifierFilter is which identifier a contact has on file, used by the read filters.

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. An empty value is a validation error, never an unfiltered page.
	Email string
	// Return the contacts with exactly this phone number in international E.164 form. Repeat the parameter to match any of up to 50 numbers. Set `limit` to at least the number of values you pass. The default `limit` is 25, and a page cut short by it looks exactly like numbers that matched nothing. Different identifier parameters still combine with AND, so `phone_number=a&phone_number=b&email=c` asks for a contact whose phone number is `a` or `b` and whose email is `c`. Encode the leading plus sign as `%2B` (an unencoded `+` arrives as a space and is rejected). Phone numbers are unique within a workspace, so each value matches at most one contact. Non-canonical forms of the same number match the contact they canonicalize to; a value that is not a phone number shape, or an empty value, is a validation error, never an unfiltered page.
	PhoneNumber []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. An empty value is a validation error, never an unfiltered page.
	ExternalID string
	// Case-insensitive substring match against the contact's email address, first name, last name, or phone number. Phone matching is over the digits of the international form, so a full pasted number, a formatted number, or trailing digits all match; a national form with a leading trunk zero does not.
	Q string
	// Filter to contacts that have a specific identifier on file.
	Identifier ContactIdentifierFilter
	// Maximum number of items to return per page.
	Limit int
	// When true, the response includes a `total` field with the total number of items matching the request's filters across all pages.
	IncludeTotal bool
}

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

type ContactMatchKey added in v0.24.0

type ContactMatchKey = oapi.ContactMatchKey

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 Define a custom contact property (key + value type) that becomes available in contact data and as a broadcast template variable. The key and type cannot change after creation; a workspace holds at most 200 properties, archived included.

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 Update a contact property's fallback value. Only the fallback value can change; the key and type are fixed at creation, so a different key or type needs a new property.

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 {
	// The property key, used as the key in contact data and as the attribute in the `bird.contact.<key>` broadcast template variable. Lowercase letters, digits, and underscores, starting with a letter. Cannot be changed after creation.
	Key string
	// The value type every contact must use for a property. Cannot be changed after creation. `datetime` values are RFC 3339 timestamps with an explicit offset. Examples include `2024-01-15T09:30:00Z` and `2024-01-15T11:30:00+02:00`. A bare date or a time with no offset is rejected. The value is normalized to UTC with second precision on write, so `2024-01-15T11:30:00+02:00` is stored and returned as `2024-01-15T09:30:00Z`, and any fractional seconds are dropped.
	Type ContactPropertyType
	// Default used when a contact has no value for this property and the template does not supply an inline fallback. A string, number, boolean, or RFC 3339 datetime matching the declared type (strings up to `500` characters), or `null` for no fallback; a value of another type returns a validation error.
	FallbackValue any
}

ContactPropertyCreateParams is the request body for create.

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 ContactPropertyType added in v0.16.0

type ContactPropertyType = oapi.ContactPropertyType

type ContactPropertyUpdateParams added in v0.4.0

type ContactPropertyUpdateParams struct {
	// Default used when a contact has no value for this property and the template does not supply an inline fallback. A string, number, boolean, or RFC 3339 datetime matching the declared type (strings up to `500` characters); a value of another type returns a validation error. Set to `null` to remove the fallback.
	FallbackValue any
}

ContactPropertyUpdateParams is the request body for update.

type ContactUpdateParams added in v0.4.0

type ContactUpdateParams struct {
	// New email address for the contact. Trimmed and lowercased before it is stored and checked for uniqueness. Must not be in use by another contact in the workspace. Omit to keep the current address; set to `null` to remove it, as long as the contact keeps at least one identifier.
	Email Nullable[string]
	// New phone number for the contact, in E.164 format with the leading `+` and country code. Spaces and punctuation are accepted and stripped. Stored in its canonical form, which may differ from what you send, and unique within the workspace. Omit to keep the current number; set to `null` to remove it, as long as the contact keeps at least one identifier. An empty string behaves as `null`.
	PhoneNumber Nullable[string]
	// The contact's first name. Set to `null` to clear.
	FirstName Nullable[string]
	// The contact's last name. Set to `null` to clear.
	LastName Nullable[string]
	// Your own identifier for this contact. Unique within the workspace when set. Set to `null` to clear.
	ExternalID Nullable[string]
	// Custom property values to merge into the contact's existing data. Supplied keys are set, keys with a `null` value are removed, and omitted keys remain unchanged. Each key must be an active contact property. Each value must match the property's declared type: string, number, boolean, or RFC 3339 datetime. Strings can contain up to `500` characters. An unregistered or archived key returns a validation error. The serialized result is limited to 2 KB.
	Data map[string]any
}

ContactUpdateParams is the request body for update.

type ContactUpsertRequestDataMode added in v0.16.0

type ContactUpsertRequestDataMode = oapi.ContactUpsertRequestDataMode

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 ContactsPreferencesListParams added in v0.41.0

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

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

type ContactsPreferencesService added in v0.41.0

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

ContactsPreferencesService reads a contact's own stated messaging preferences across every channel. Reach it via Client.Contacts.Preferences.

func (*ContactsPreferencesService) List added in v0.41.0

List List the recorded messaging preferences for a contact's own handles (their email address and phone number) across every channel, as a cursor page. Range over it; the second value is non-nil only on the iteration where a fetch failed.

Example

List reads the messaging preferences recorded for a contact's own handles across every channel.

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 pref, err := range client.Contacts.Preferences.List(context.Background(), "con_01krdgeqcxet5s7t44vh8rt9mg", bird.ContactsPreferencesListParams{}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(*pref.Channel, *pref.Status)
	}
}

func (*ContactsPreferencesService) ListPage added in v0.41.0

func (s *ContactsPreferencesService) ListPage(ctx context.Context, contactId string, params ContactsPreferencesListParams, startingAfter string, opts ...option.RequestOption) (*PreferenceList, error)

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

type ContactsService added in v0.4.0

type ContactsService struct {

	// Preferences reads a contact's own stated messaging preferences across
	// every channel.
	Preferences *ContactsPreferencesService
	// 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 Create or update up to 1,000 contacts in one request. Match each entry against every supplied identifier (`email`, `phone_number`, and `external_id`), or set `match_on` to use one identifier. Optionally add all successful contacts to up to 10 audiences. Results follow submission order.

Example

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

package main

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

	openapi_types "github.com/oapi-codegen/runtime/types"

	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.ContactCreateRequest{
			{Email: bird.Ptr(openapi_types.Email("a@x.com"))},
		},
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, item := range result.Data {
		email := ""
		if item.Entry.Email != nil {
			email = *item.Entry.Email
		}
		fmt.Println(email, item.Status)
	}
}

func (*ContactsService) Create added in v0.4.0

Create Create a contact identified by an email address, an E.164 phone number, or both. Fails with a conflict if the email, phone_number, 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. Look up an ID by exact email, phone_number, 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, phone_number, or external_id, repeating phone_number to resolve up to 50 numbers in one call (raise limit to match), or search by email, name, or phone substring. Pass include_total for a total count. 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, contactId string, params ContactUpdateParams, opts ...option.RequestOption) (*Contact, error)

Update Update a contact's name, `external_id`, email, `phone_number`, or custom data. Only supplied fields change; custom data keys are merged, with `null` removing a key. A contact keeps at least one identifier: clearing both email and `phone_number` is rejected.

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. The write-side *Config aliases accompany DomainCreateParams / DomainUpdateParams.

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. The write-side *Config aliases accompany DomainCreateParams / DomainUpdateParams.

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. The write-side *Config aliases accompany DomainCreateParams / DomainUpdateParams.

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. The write-side *Config aliases accompany DomainCreateParams / DomainUpdateParams.

type DomainCreateParams added in v0.8.0

type DomainCreateParams struct {
	// The domain you send from: the domain of your `from` addresses. Use a dedicated subdomain (for example, `mail.acme.com`) rather than your registered domain so sending reputation stays separate from other services on the domain.
	Domain string
	// Return-path (bounce) domain configuration. The return-path domain receives bounce and complaint notifications for mail sent from this domain and is what mailbox providers check for SPF. Provide only the name part; we add the sending domain automatically.
	ReturnPath *DomainReturnPathConfig
	// Tracking domain configuration for branded open and click tracking URLs. Provide only the name part; we add the sending domain automatically. A domain created with no tracking configuration defaults to `links`. Tracked links are served over HTTPS after the tracking record verifies.
	Tracking *DomainTrackingConfig
	// DKIM signing configuration.
	Dkim *DomainDKIMConfig
	// Per-domain behavior toggles. Changes apply immediately to new sends.
	Settings *DomainSettings
}

DomainCreateParams is the request body for create.

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. The write-side *Config aliases accompany DomainCreateParams / DomainUpdateParams.

type DomainDKIMConfig added in v0.8.0

type DomainDKIMConfig = oapi.DomainDKIMConfig

type DomainDKIMConfigMode added in v0.15.0

type DomainDKIMConfigMode = oapi.DomainDKIMConfigMode
const (
	DomainDKIMConfigModeTxt       DomainDKIMConfigMode = "txt"
	DomainDKIMConfigModeDelegated DomainDKIMConfigMode = "delegated"
)

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 = oapi.DomainInboundConfig

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. The write-side *Config aliases accompany DomainCreateParams / DomainUpdateParams.

type DomainListParams added in v0.8.0

type DomainListParams struct {
	// Substring match against the domain name (case-insensitive).
	Name string
	// Field to sort by. Defaults to `created_at`.
	Sort string
	// Sort direction. Defaults to `desc`, which sorts from newest to oldest or largest to smallest, depending on the selected sort field.
	Order string
	// Maximum number of items to return per page.
	Limit int
	// When true, the response includes a `total` field with the total number of items matching the request's filters across all pages.
	IncludeTotal bool
}

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

type DomainReturnPathConfig added in v0.8.0

type DomainReturnPathConfig = oapi.DomainReturnPathConfig

type DomainSettings added in v0.8.0

type DomainSettings = oapi.DomainSettings

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. The write-side *Config aliases accompany DomainCreateParams / DomainUpdateParams.

type DomainTrackingConfig added in v0.8.0

type DomainTrackingConfig = oapi.DomainTrackingConfig

type DomainUpdateParams added in v0.8.0

type DomainUpdateParams struct {
	// Per-domain behavior toggles. Changes apply immediately to new sends.
	Settings *DomainSettings
	// Change the return-path name part. Cannot be removed: the return-path is required for sending.
	ReturnPath *DomainReturnPathConfig
	// Set or change the tracking name part, or remove tracking by passing `null`. Removal requires `click_tracking` and `open_tracking` to be disabled first, and returns `409` otherwise. After removal, links in previously sent email keep resolving while the tracking records are reported as `deprecated`.
	Tracking Nullable[DomainTrackingConfig]
	// Change how the DKIM key is published. The current key keeps signing until the new configuration verifies, so mail is never sent unsigned during the transition.
	Dkim *DomainDKIMConfig
	// Enable or disable receiving on this domain. Enabling claims the domain for inbound and moves `capabilities.inbound.status` from `not_configured` to `pending`, then `verified` once the MX records resolve to us. The MX records to publish are always present under `dns_records` (`purpose: inbound_mx`) as a regional reference. Their presence does not mean receiving is enabled; enable the domain whenever `capabilities.inbound.status` is `not_configured`. Enabling requires the domain's DKIM to be verified first. A fresh enable on a domain whose DKIM is not verified returns `422` with `E05019` and claims nothing. A domain already receiving inbound for another organization returns `422` with `E05018`.
	Inbound *DomainInboundConfig
}

DomainUpdateParams is the request body for update.

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 Register a new sending domain and get the DNS records to publish. Verification is a second step: the records go live at the DNS provider, then email_domains_verify confirms them. Propagation takes minutes to hours, so the first verify often still reports unverified and a later one succeeds.

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, domainId string, opts ...option.RequestOption) error

Delete Delete a sending domain by ID. Revokes its sender authorization: new sends from the domain are rejected afterward, while historical statistics and events for past sends are preserved. Destructive.

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, domainId string, opts ...option.RequestOption) (*Domain, error)

Get Fetch one sending domain: verification status and the DNS records with their individual verification states.

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 List the workspace's sending domains with their verification status, as a cursor page. 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 results. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the first page.

func (*DomainsService) Update added in v0.8.0

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

Update Update a sending domain's tracking and inbound configuration. Tracking: click_tracking and open_tracking apply immediately to new sends, and the tracking domain can be set, changed, or removed (the name part only, and the sending domain is appended for you). Enabling either toggle with no tracking domain configured returns 409, and removing the tracking domain while either toggle is still on also returns 409. Tracking-domain changes on a verified domain are staged behind DNS verification, so the current config keeps serving until the new records verify. Inbound receiving: inbound.enabled starts or stops receiving mail for the domain. Enabling requires the domain's DKIM to be verified first (a fresh enable on an unverified domain returns 422), and a domain already receiving inbound for another organization returns 422. The MX records to publish are always listed in dns_records regardless, marked optional until inbound.enabled is set, so receiving starts only once you set it even when those records are already published. Publishing them earlier is not free: on a domain at the zone apex they replace the MX records carrying its existing mail, changing where that mail is delivered.

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.Value(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, domainId string, opts ...option.RequestOption) (*Domain, error)

Verify Trigger a DNS verification check for a sending domain and return the refreshed domain with per-record results. Safe to repeat while waiting for DNS propagation.

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 EmailEngagementSortMetric added in v0.16.0

type EmailEngagementSortMetric = oapi.EmailEngagementSortMetric

EmailEngagementSortMetric is the engagement metric a breakdown sorts by.

type EmailEventType added in v0.19.0

type EmailEventType = oapi.EmailEventType

EmailEventType is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the EmailEventType* constants with a default branch rather than treating the set as closed.

type EmailLabelsUpdate added in v0.16.0

type EmailLabelsUpdate = oapi.EmailLabelsUpdate

type EmailListParams

type EmailListParams struct {
	// Maximum number of items to return per page.
	Limit int
	// Limits the response to resources created at or after this timestamp. Combine it with `created_before` to select a time window. Use an RFC 3339 timestamp with a timezone offset.
	CreatedAfter time.Time
	// Limits the response to resources created before this timestamp. Combine it with `created_after` to select a time window. Use an RFC 3339 timestamp with a timezone offset.
	CreatedBefore time.Time
	// Filter by aggregate delivery status.
	Status EmailMessageStatus
	// Filter by tag. Accepts `name` to match any record carrying that tag name, or `name:value` to match a specific tag pair (for example `category:welcome`). Repeat the parameter to add more tags. A record must match every tag listed to be returned.
	Tag []string
	// Filter by category.
	Category EmailMessageCategory
	// Filter by recipient address. Exact match against any `to`/`cc`/`bcc` recipient on the message. The address is normalized to lowercase before comparison.
	To string
	// Filter by sender address. Exact match against the message `from` field. The address is normalized to lowercase before comparison.
	From string
}

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

type EmailListUnsubscribedEvent

type EmailListUnsubscribedEvent = oapi.EventEmailListUnsubscribed

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

type EmailLookup added in v0.31.0

type EmailLookup = oapi.EmailLookup

PhoneNumberLookup is what we know about a phone number; EmailLookup is the verdict on an email address. Every block a phone lookup carries reports its own status, so a partial answer is visible rather than silent.

type EmailLookupFlag added in v0.31.0

type EmailLookupFlag = oapi.EmailLookupFlag

EmailLookupFlag is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the EmailLookupFlag* constants with a default branch rather than treating the set as closed.

type EmailLookupReason added in v0.31.0

type EmailLookupReason = oapi.EmailLookupReason

EmailLookupReason is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the EmailLookupReason* constants with a default branch rather than treating the set as closed.

type EmailLookupResult added in v0.31.0

type EmailLookupResult = oapi.EmailLookupResult

EmailLookupResult is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the EmailLookupResult* constants with a default branch rather than treating the set as closed.

type EmailMailboxLabelList added in v0.12.0

type EmailMailboxLabelList = oapi.EmailMailboxLabelList

EmailMailboxLabelList is the list of labels available in a mailbox.

type EmailMailboxProviderSortMetric added in v0.16.0

type EmailMailboxProviderSortMetric = oapi.EmailMailboxProviderSortMetric

EmailMailboxProviderSortMetric is the metric a mailbox-provider breakdown sorts by.

type EmailMailboxesCreateParams added in v0.17.0

type EmailMailboxesCreateParams struct {
	// The local part of the mailbox address (the part before `@`). Letters, digits, dots, underscores, and hyphens. Stored lowercase. On the shared `inbox.ai` domain, separators must sit between letters or digits. Leading, trailing, and repeated separators are not allowed. Reserved names such as `postmaster` and `abuse` are unavailable. Choosing your own local part uses one of your plan's custom-handle allowance slots; generated addresses remain available. Omit this field to generate a random local part.
	LocalPart string
	// The domain the address lives under. Defaults to `inbox.ai`, our shared mailbox domain. Creating a mailbox claims the shared address for your organization on a first-come, first-served basis. The address remains reserved to your organization after the mailbox is deleted. You can instead use one of your own domains enabled for receiving email.
	Domain string
	// Display name used as the sender name on mail from this mailbox.
	DisplayName string
	// Default `Reply-To` address stamped on mail sent from this mailbox.
	DefaultReplyTo string
	// Which inbound mail the mailbox accepts: - `open`: Accepts everything not blocked by a rule. - `replies_only`: Accepts only replies to messages this mailbox has sent. A reply must match a message the mailbox sent. Landing in an existing thread by itself does not count. - `allowlist`: Accepts only senders matching an allow rule. - `drop`: Stores nothing.
	ReceivePolicy *MailboxCreateReceivePolicy
	// How long the mailbox remembers message metadata and extracted text. Original rendered source is always available for 30 days regardless of tier.
	RetentionTier *MailboxCreateRetentionTier
	// Your own key/value data to attach to the mailbox. Up to 2 KB. Keys starting with `__bird` are reserved.
	Metadata map[string]any
}

EmailMailboxesCreateParams is the request body for create.

type EmailMailboxesListParams added in v0.17.0

type EmailMailboxesListParams struct {
	// Filter to the mailbox with exactly this address.
	Address string
	// Case-insensitive search matching the mailbox's address or display name (substring).
	Q string
	// Return only `active` or `suspended` mailboxes. Use `include_deleted` for restorable deleted mailboxes.
	State string
	// Filter to mailboxes whose address is on this domain.
	Domain string
	// Include mailboxes deleted within their 30-day restore window. Defaults to false, so only active and suspended mailboxes are returned. A deleted mailbox has `deleted_at` set.
	IncludeDeleted bool
	// Maximum number of items to return per page.
	Limit int
}

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

type EmailMailboxesMessagesCreateParams added in v0.17.0

type EmailMailboxesMessagesCreateParams 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
	Tags     []EmailTag
	Metadata map[string]any
}

EmailMailboxesMessagesCreateParams sends a new message from the mailbox.

type EmailMailboxesMessagesService added in v0.17.0

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

EmailMailboxesMessagesService sends messages from a mailbox's own address. Reach it via Client.Email.Mailboxes.Messages.

func (*EmailMailboxesMessagesService) Create added in v0.17.0

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.Email.Mailboxes.Messages.Create(context.Background(), "mbx_123", bird.EmailMailboxesMessagesCreateParams{
		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)
}

type EmailMailboxesReceiveRulesCreateParams added in v0.17.0

type EmailMailboxesReceiveRulesCreateParams struct {
	// What the rule does when it matches. Block rules always win. To flip an entry's action, delete the existing rule and re-create it.
	Action ReceiveRuleCreateAction
	// The sender address (`alice@example.com`) or domain (`example.com`) to match. Domains also match their subdomains. Stored lowercase.
	Entry string
	// Your own note about why the rule exists.
	Note string
}

EmailMailboxesReceiveRulesCreateParams is the request body for create.

type EmailMailboxesReceiveRulesListParams added in v0.17.0

type EmailMailboxesReceiveRulesListParams struct {
	// Return only `allow` or `block` rules; omit to return both actions.
	Action string
	// Maximum number of items to return per page.
	Limit int
}

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

type EmailMailboxesReceiveRulesService added in v0.17.0

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

EmailMailboxesReceiveRulesService manages per-sender allow/block rules on a mailbox. Reach it via Client.Email.Mailboxes.ReceiveRules.

func (*EmailMailboxesReceiveRulesService) Create added in v0.17.0

Create Add an allow or block rule for a sender address or domain to a mailbox. Block always wins. Up to 200 rules per 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)
	}
	rule, err := client.Email.Mailboxes.ReceiveRules.Create(context.Background(), "mbx_123", bird.EmailMailboxesReceiveRulesCreateParams{
		Action: "block",
		Entry:  "spam.example.com",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(rule.Id)
}

func (*EmailMailboxesReceiveRulesService) Delete added in v0.17.0

func (s *EmailMailboxesReceiveRulesService) Delete(ctx context.Context, mailboxId string, ruleId string, opts ...option.RequestOption) error

Delete Remove a receive rule from a mailbox. Rules have no update operation, so a rule's allow or block action cannot be changed after it is created.

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.Email.Mailboxes.ReceiveRules.Delete(context.Background(), "mbx_123", "erl_456"); err != nil {
		log.Fatal(err)
	}
}

func (*EmailMailboxesReceiveRulesService) List added in v0.17.0

List List a mailbox's allow/block receive rules as a cursor page, oldest first. Filter by action. Range over it; the second value is non-nil only on the iteration where a fetch failed.

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.Email.Mailboxes.ReceiveRules.List(context.Background(), "mbx_123", bird.EmailMailboxesReceiveRulesListParams{}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(rule.Id, rule.Action, rule.Entry)
	}
}

func (*EmailMailboxesReceiveRulesService) ListPage added in v0.17.0

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

type EmailMailboxesService added in v0.17.0

type EmailMailboxesService struct {

	// Messages sends new messages from the mailbox's own address.
	Messages *EmailMailboxesMessagesService

	// ReceiveRules manages per-sender allow/block rules on the mailbox.
	ReceiveRules *EmailMailboxesReceiveRulesService
	// contains filtered or unexported fields
}

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

func (*EmailMailboxesService) Create added in v0.17.0

Create Create a mailbox: a durable agent identity that owns an email address, groups mail into conversations, and remembers conversations for its 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.Email.Mailboxes.Create(context.Background(), bird.EmailMailboxesCreateParams{
		DisplayName: "Support",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(mailbox.Id, *mailbox.Address)
}

func (*EmailMailboxesService) Delete added in v0.17.0

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

Delete Delete a mailbox. The address stops receiving immediately and is quarantined. The mailbox and its remembered messages stay restorable for 30 days through the restore endpoint, then are permanently deleted.

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.Email.Mailboxes.Delete(context.Background(), "mbx_123"); err != nil {
		log.Fatal(err)
	}
}

func (*EmailMailboxesService) Get added in v0.17.0

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

Get Read one mailbox by ID. A mailbox deleted within its 30-day restore window is still returned, with `deleted_at` set. Once that window closes it is gone and this returns `404`.

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.Email.Mailboxes.Get(context.Background(), "mbx_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(*mailbox.Address)
}

func (*EmailMailboxesService) Labels added in v0.17.0

Labels List the labels available in a mailbox: the built-in system labels (inbox, archive, spam, blocked, sent, trash, unread) plus every custom label in use.

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.Email.Mailboxes.Labels(context.Background(), "mbx_123")
	if err != nil {
		log.Fatal(err)
	}
	for _, l := range labels.Data {
		fmt.Println(l.Name)
	}
}

func (*EmailMailboxesService) List added in v0.17.0

List List the workspace's mailboxes as a cursor page, newest first. Search addresses and display names with q, or filter by exact address, state, or domain. Range over it; the second value is non-nil only on the iteration where a fetch failed.

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.Email.Mailboxes.List(context.Background(), bird.EmailMailboxesListParams{}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(mailbox.Id)
	}
}

func (*EmailMailboxesService) ListPage added in v0.17.0

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

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

func (*EmailMailboxesService) Restore added in v0.17.0

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

Restore Restore a mailbox deleted less than 30 days ago: the address starts receiving again and the remembered messages are back. Past the window the mailbox is permanently deleted and returns `404`. A mailbox that is not deleted returns `409`.

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.Email.Mailboxes.Restore(context.Background(), "mbx_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(mailbox.Id)
}

func (*EmailMailboxesService) Resume added in v0.17.0

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

Resume Resume a suspended mailbox so it can send and receive again and its conversations become visible. Fails if your plan does not have room for another active mailbox (or another custom inbox.ai handle). Delete an active mailbox or upgrade first. A mailbox that is not suspended returns `409`.

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.Email.Mailboxes.Resume(context.Background(), "mbx_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(mailbox.Id)
}

func (*EmailMailboxesService) Stats added in v0.17.0

Stats Read a mailbox's sent and received email statistics over a window: a period summary plus a bucketed series. Rows are bucketed by event time rather than send time, so engagement that arrived during the period for messages sent earlier is counted here. Both window bounds must use the same form, calendar days or RFC 3339 instants, matching the granularity.

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.Email.Mailboxes.Stats(context.Background(), "mbx_123", bird.EmailMailboxesStatsParams{})
	if err != nil {
		log.Fatal(err)
	}
	if stats.Summary != nil {
		if d := stats.Summary.Delivery; d != nil {
			fmt.Println(d.Delivered, d.Bounced)
		}
	}
}

func (*EmailMailboxesService) Update added in v0.17.0

Update Update a mailbox's display name, reply-to, receive policy, retention tier, IP pool, or metadata. Lowering the retention tier requires `confirm=true` when it would delete remembered messages older than the new cutoff.

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.Email.Mailboxes.Update(context.Background(), "mbx_123", bird.EmailMailboxesUpdateParams{
		DisplayName: bird.Value("Sales"),
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(mailbox.Id)
}

type EmailMailboxesStatsParams added in v0.17.0

type EmailMailboxesStatsParams struct {
	// Inclusive start of the window: a calendar day (`YYYY-MM-DD`, `day` granularity only) or an RFC 3339 instant rounded down to the hour (`hour` granularity only). Interpreted in `timezone`, 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 `to`. Defaults to 30 days before `to` at `day` granularity and 7 days before `to` at `hour`, when omitted.
	From string
	// Inclusive end of the window: a calendar day (`YYYY-MM-DD`, `day` granularity only) or an RFC 3339 instant rounded down to the hour (`hour` granularity only). Interpreted in `timezone`, 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 (day) or the current hour (hour) in that timezone when omitted. Window may not exceed 365 days at `day` or 30 days at `hour` granularity.
	To string
	// IANA timezone identifier used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Granularity of the series: `day` (default) or `hour`. Echoed back as `period.grain`.
	Granularity string
}

EmailMailboxesStatsParams filters the stats read.

type EmailMailboxesUpdateParams added in v0.17.0

type EmailMailboxesUpdateParams struct {
	// Display name used as the sender name on mail from this mailbox. `null` clears it.
	DisplayName Nullable[string]
	// Default `Reply-To` address stamped on mail sent from this mailbox. `null` clears it.
	DefaultReplyTo Nullable[string]
	// Which inbound mail the mailbox accepts: - `open`: Accepts everything not blocked by a rule. - `replies_only`: Accepts only replies to messages this mailbox has sent. A reply must match a message the mailbox sent. Landing in an existing thread by itself does not count. - `allowlist`: Accepts only senders matching an allow rule. - `drop`: Stores nothing.
	ReceivePolicy *MailboxUpdateReceivePolicy
	// How long the mailbox remembers message metadata and extracted text. Lowering the tier deletes remembered messages older than the new horizon, and requires `confirm=true` when that would happen.
	RetentionTier *MailboxUpdateRetentionTier
	// Replaces the mailbox's key/value data. Up to 2 KB. Keys starting with `__bird` are reserved.
	Metadata map[string]any
	// Set to `true` when lowering `retention_tier` would delete remembered messages older than the new cutoff. The request is rejected without it in that case.
	Confirm bool
}

EmailMailboxesUpdateParams is the request body for update.

type EmailMessage

type EmailMessage = oapi.EmailMessage

EmailMessage is a sent message with aggregate delivery status.

type EmailMessageCategory added in v0.16.0

type EmailMessageCategory = oapi.EmailMessageCategory

EmailMessageCategory is an alias of Category, used by the read filters.

type EmailMessageList

type EmailMessageList = oapi.EmailMessageList

EmailMessageList is one page of messages plus its pagination cursors.

type EmailMessageStatus added in v0.16.0

type EmailMessageStatus = oapi.EmailMessageStatus

EmailMessageStatus is an alias of EmailStatus, used by the read filters.

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 sets suppression policy. Unset sends as marketing, which every
	// suppression reason holds back; transactional delivers through complaint and
	// unsubscribe suppressions, so operational mail (password resets, receipts) has
	// to say so. A Template send with no Category takes the template's own.
	Category Category
	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 slug handle.
	Template string
	// Language selects which of the template's languages to send, as a BCP-47 tag
	// (e.g. "en", "pt-BR"). Template sends only. Omit it to send the template's
	// default language, unless the template's language_source_required is true, in
	// which case a send naming none is rejected. A language the template doesn't
	// carry is resolved by the template's own on_missing_language setting
	// (fallback to the closest match, or fail the send).
	Language 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
	// ScheduledAt holds the message until a future instant instead of sending
	// it immediately: at least 30 seconds and at most 30 days ahead, and
	// mutually exclusive with Template. Only a single send accepts it; a batch
	// item that sets one is rejected with a 422.
	ScheduledAt time.Time
}

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

	// Mailboxes manages durable agent mailboxes that receive, store, and send email.
	Mailboxes *EmailMailboxesService

	// Threads reads and manages email conversations across every mailbox.
	Threads *EmailThreadsService
	// 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, messageId string, opts ...option.RequestOption) error

Cancel Cancel a scheduled email before it sends. Only works while the message's `status` is still `scheduled`. Once it starts sending, or was already canceled, the call returns a conflict error. Canceling does not return consumed scheduled-send quota.

Example

Cancel stops a message that has not left yet, including a scheduled send before its send time or a queued message still awaiting delivery.

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.Email.Cancel(context.Background(), "em_abc123"); err != nil {
		log.Fatal(err)
	}
}

func (*EmailService) Get

func (s *EmailService) Get(ctx context.Context, messageId string, opts ...option.RequestOption) (*EmailMessage, error)

Get Fetch one email message by `id`, with aggregate delivery status and per-state recipient counts. The message body (`html`, `text`) is not returned. Per-recipient delivery statuses and the event log are separate sub-resources: `GET /v1/email/messages/{message_id}/recipients` and `GET /v1/email/messages/{message_id}/events`.

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 List sent email messages, newest first, as a cursor page (`{data, next_cursor, …}`). Pass `next_cursor` back as `starting_after` to fetch the next page. Filter by creation time with the half-open range `created_after` (inclusive) and `created_before` (exclusive). For a single UTC day, `created_after` is that day at 00:00:00Z and `created_before` is the next day at 00:00:00Z. 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 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 results. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the first page.

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 (Bounce)

Sending to the sandbox bounce address, which hard-bounces every time. The tag and metadata are what make the resulting event findable in the logs.

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{"bounce+signup-flow@messagebird.dev"},
		Subject:  "Sandbox bounce test",
		HTML:     "<p>This message will hard-bounce.</p>",
		Tags:     []bird.Tag{{Name: "flow", Value: "signup"}},
		Metadata: map[string]any{"test_run": "docs-capture-1"},
	})
	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. Propagate it unless you need 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)
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)
	}
}
Example (Template)

A richer send: cc/bcc, reply-to, tags, metadata, opt-out of click tracking, and an idempotency key. The server deduplicates the request, so it is safe to retry. Send a published template in place of inline content. The template supplies the subject and bodies; Parameters fills 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.Email.Send(context.Background(), bird.EmailSendParams{
		From:       "onboarding@messagebird.dev",
		To:         []string{"delivered@messagebird.dev"},
		Category:   "transactional",
		Template:   "welcome-email",
		Parameters: map[string]any{"first_name": "Jane"},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(msg.Id, *msg.Status)
}

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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	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. It defaults to `bounced`. Only the bounce counts are sortable here, because this breakdown has no rate fields.
	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 a `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 EmailStatsSortMetric
	// Maximum number of broadcast rows to return, ranked by the `sort` field descending.
	Limit int
}

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). It defaults to 30 days before `to` when you leave it out. When `include_trend=true` and `trend_grain=hourly`, that default tightens to 29 days before `to` instead, so the defaulted window still fits inside 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Metric to rank rows by, applied descending. Any count or rate in the response can be used. A row whose rate is undefined because its denominator is zero sorts last. It defaults to `processed`.
	Sort EmailStatsSortMetric
	// Maximum number of category rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also gets a `trend` array: a short per-bucket series showing that category's delivery and engagement rates over the window. This only works when `limit` is 50 or fewer and the window is at most 90 days for `trend_grain=daily` or 720 hours for `trend_grain=hourly`. Ask for more and you get a `422`. When you leave `from` out and use `trend_grain=hourly`, the default window tightens to 29 days before `to` (720 hours total), so a request built entirely from defaults always fits inside the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain StatsTrendGrain
}

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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	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. It defaults to `unique_opens`. Only engagement counts are sortable. This breakdown has no rates.
	Sort EmailEngagementSortMetric
	// 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	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. It 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	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. It defaults to `unique_opens`. Only engagement counts are sortable. This breakdown has no rates.
	Sort EmailEngagementSortMetric
	// 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). It defaults to 30 days before `to` when you leave it out. When `include_trend=true` and `trend_grain=hourly`, that default tightens to 29 days before `to` instead, so the defaulted window still fits inside 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	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 can be used. A row whose rate is undefined because its denominator is zero sorts last. It defaults to `delivered`. `processed`, `rejected`, and `oob_bounces` are not part of this breakdown's rows, so they are not sortable here.
	Sort EmailMailboxProviderSortMetric
	// Maximum number of mailbox-provider rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also gets a `trend` array: a short per-bucket series showing that provider's delivery and engagement rates over the window. This only works when `limit` is 50 or fewer and the window is at most 90 days for `trend_grain=daily` or 720 hours for `trend_grain=hourly`. Ask for more and you get a `422`. When you leave `from` out and use `trend_grain=hourly`, the default window tightens to 29 days before `to` (720 hours total), so a request built entirely from defaults always fits inside the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain StatsTrendGrain
}

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). It defaults to 30 days before `to` when you leave it out. When `include_trend=true` and `trend_grain=hourly`, that default tightens to 29 days before `to` instead, so the defaulted window still fits inside 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	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 can be used. A row whose rate is undefined because its denominator is zero sorts last. It defaults to `delivered`. `processed`, `rejected`, and `oob_bounces` are not part of this breakdown's rows, so they are not sortable here.
	Sort EmailMailboxProviderSortMetric
	// Maximum number of provider-region rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also gets a `trend` array: a short per-bucket series showing that provider region's delivery and engagement rates over the window. This only works when `limit` is 50 or fewer and the window is at most 90 days for `trend_grain=daily` or 720 hours for `trend_grain=hourly`. Ask for more and you get a `422`. When you leave `from` out and use `trend_grain=hourly`, the default window tightens to 29 days before `to` (720 hours total), so a request built entirely from defaults always fits inside the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain StatsTrendGrain
}

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). It defaults to 30 days before `to` when you leave it out. When `include_trend=true` and `trend_grain=hourly`, that default tightens to 29 days before `to` instead, so the defaulted window still fits inside 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	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 can be used. A row whose rate is undefined because its denominator is zero sorts last. It defaults to `processed`.
	Sort EmailStatsSortMetric
	// Maximum number of recipient-domain rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also gets a `trend` array: a short per-bucket series showing that recipient domain's delivery and engagement rates over the window. This only works when `limit` is 50 or fewer and the window is at most 90 days for `trend_grain=daily` or 720 hours for `trend_grain=hourly`. Ask for more and you get a `422`. When you leave `from` out and use `trend_grain=hourly`, the default window tightens to 29 days before `to` (720 hours total), so a request built entirely from defaults always fits inside the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain StatsTrendGrain
}

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). It defaults to 30 days before `to` when you leave it out. When `include_trend=true` and `trend_grain=hourly`, that default tightens to 29 days before `to` instead, so the defaulted window still fits inside 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	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 can be used. A row whose rate is undefined because its denominator is zero sorts last. It defaults to `processed`.
	Sort EmailStatsSortMetric
	// Maximum number of domain rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also gets a `trend` array: a short per-bucket series showing that domain's delivery and engagement rates over the window. This only works when `limit` is 50 or fewer and the window is at most 90 days for `trend_grain=daily` or 720 hours for `trend_grain=hourly`. Ask for more and you get a `422`. When you leave `from` out and use `trend_grain=hourly`, the default window tightens to 29 days before `to` (720 hours total), so a request built entirely from defaults always fits inside the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain StatsTrendGrain
}

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). It defaults to 30 days before `to` when you leave it out. When `include_trend=true` and `trend_grain=hourly`, that default tightens to 29 days before `to` instead, so the defaulted window still fits inside 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	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. Sorting by `bounces.block` puts the IPs whose reputation is most likely degraded at the top. A row whose rate is undefined because its denominator is zero sorts last. It defaults to `delivered`. A sending IP has no engagement, so engagement metrics aren't sortable here, and neither are `processed`, `rejected`, or `oob_bounces`.
	Sort string
	// Maximum number of IP rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also gets a `trend` array: a short per-bucket series showing that IP's delivery rates over the window. A trend point's open and click rates read `0` in a bucket that had deliveries and `null` in one that had none, because a sending IP has no engagement data. This only works when `limit` is 50 or fewer and the window is at most 90 days for `trend_grain=daily` or 720 hours for `trend_grain=hourly`. Ask for more and you get a `422`. When you leave `from` out and use `trend_grain=hourly`, the default window tightens to 29 days before `to` (720 hours total), so a request built entirely from defaults always fits inside the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain StatsTrendGrain
}

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). It defaults to 30 days before `to` when you leave it out. When `include_trend=true` and `trend_grain=hourly`, that default tightens to 29 days before `to` instead, so the defaulted window still fits inside 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	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 can be used. A row whose rate is undefined because its denominator is zero sorts last. It defaults to `processed`.
	Sort EmailStatsSortMetric
	// Maximum number of tag rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also gets a `trend` array: a short per-bucket series showing that tag's delivery and engagement rates over the window. This only works when `limit` is 50 or fewer and the window is at most 90 days for `trend_grain=daily` or 720 hours for `trend_grain=hourly`. Ask for more and you get a `422`. When you leave `from` out and use `trend_grain=hourly`, the default window tightens to 29 days before `to` (720 hours total), so a request built entirely from defaults always fits inside the cap.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain StatsTrendGrain
}

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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	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 EmailStatsSortMetric
	// Maximum number of template rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also has 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 start tightens to 29 days before `to`, keeping the window inside 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 StatsTrendGrain
}

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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	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 assigned only after a message reaches delivery, so this filter reports delivery-side metrics only. Accepted, processed, rejected, complaint, and engagement counts are `0`, and processing latency is `null`. Complaint, open, and click rates are `0` when deliveries exist and `null` otherwise.
	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
	// Restricts the statistics to one template, identified by its ID (`emt_…`) or name. This parameter is mutually exclusive with other dimension filters.
	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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	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 assigned only after a message reaches delivery, so this filter reports delivery-side metrics only. Accepted, processed, rejected, complaint, and engagement counts are `0`, and processing latency is `null`. Complaint, open, and click rates are `0` when deliveries exist and `null` otherwise.
	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
	// Restricts the statistics to one template, identified by its ID (`emt_…`) or name. This parameter is mutually exclusive with other dimension filters.
	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 mail server returned. Each row also breaks the bounce down into its hard, soft, admin, block, and undetermined split. It omits delivered, open, and click counts because a bounce code only appears on a bounce event. For bounces broken down by destination instead, 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.

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, meaning `transactional` compared with `marketing`. Rows are ranked by `sort`, `processed` by default. Set `include_trend=true` to add 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, operating system, or device type, whichever you choose with `group_by`. It only has engagement counts, no delivery counts or rates. For engagement grouped by geography instead, 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`, or `virus`. This complaint-only breakdown omits delivery and engagement counts. For complaints broken down by destination instead, 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, whichever you choose with `group_by`. It only has engagement counts, no delivery counts or rates. For engagement grouped by mail client or device instead, 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, for example `gmail`, `microsoft`, or `yahoo`. It covers the delivery stage onward and omits accepted or processed counts. For a per-region split within a provider, use `email.stats.by_mailbox_provider_region`; for exact destination domains instead, 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 a mailbox provider and provider region pair, for example `gmail` in `NA`. It covers the delivery stage onward and omits accepted or processed counts. For the provider-level view without the region split, 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, so you can compare deliverability across your workspace's verified domains. For per-IP reputation instead, 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, with deferral counts alongside them. `sort=bounces.block` surfaces reputation-damaged IPs first. Engagement, accepted, and processed counts aren't available per IP, and complaint and out-of-band bounce counts always read `0` here. For workspace-wide figures, use `email.stats.daily`.

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. Rows are ranked by `sort`, `processed` by default. Set `include_trend=true` to add 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. A single template's trend over time comes from `email.stats.daily` with its `template` filter.

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. The `from` and `to` values 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 EmailStatsSortMetric added in v0.16.0

type EmailStatsSortMetric = oapi.EmailStatsSortMetric

EmailStatsSortMetric is the metric an email-stats breakdown sorts by.

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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	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 assigned only after a message reaches delivery, so this filter reports delivery-side metrics only. Accepted, processed, rejected, complaint, and engagement counts are `0`, and processing latency is `null`. Complaint, open, and click rates are `0` when deliveries exist and `null` otherwise.
	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
	// Restricts the statistics to one template, identified by its ID (`emt_…`) or name. This parameter is mutually exclusive with other dimension filters.
	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 (
	EmailStatusScheduled      EmailStatus = "scheduled"
	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"
	EmailStatusCanceled       EmailStatus = "canceled"
)

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 EmailThreadsDeleteParams added in v0.17.0

type EmailThreadsDeleteParams struct {
	// Permanently delete the conversation and its messages immediately instead of moving them to the trash.
	Permanent bool
}

EmailThreadsDeleteParams holds the delete's query filters.

type EmailThreadsListParams added in v0.17.0

type EmailThreadsListParams struct {
	// Filter to conversations in a specific mailbox.
	MailboxID string
	// Filter to conversations linked to a specific contact.
	ContactID string
	// Filter to conversations that have this label. Repeat the parameter to ask for more than one: only conversations that have every label you list are returned. A placement label picks a folder: `inbox`, `archive`, `spam`, or `blocked`. A custom label matches a conversation in any folder. Leave this out and you get the inbox.
	Label []string
	// When `true`, only conversations with unread messages are returned. This filters on the conversation's unread state, so you can combine it with `label`, for example to get unread conversations in the archive. The `unread` label itself lives on individual messages; this filter uses the conversation's aggregate unread state.
	HasUnread bool
	// Conversations involving this address, matching the sender or any recipient. The match is case-insensitive and matches on any part of the address, so a fragment works as well as the whole address.
	Participant string
	// Conversations whose subject contains this text (case-insensitive).
	Subject string
	// Filter to conversations whose most recent message is at or after this time. Use the response cursors for pagination.
	After time.Time
	// Filter to conversations whose most recent message is at or before this time. Use the response cursors for pagination.
	Before time.Time
	// Maximum number of items to return per page.
	Limit int
}

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

type EmailThreadsMessagesListParams added in v0.17.0

type EmailThreadsMessagesListParams struct {
	// Filter to received (`inbound`) or sent (`outbound`) messages.
	Direction MessageDirection
	// Filter to messages that have this label. `trash` lists trashed messages. Any other label, whether that is `archive`, `spam`, `blocked`, `unread` or one of your own, lists the messages that have it and are not in the trash. When omitted, every message that is not trashed is returned, whichever folder the conversation is in.
	Label string
	// Set to `extracted_text` to inline each message's extracted plain text.
	Include string
	// Maximum number of items to return per page.
	Limit int
}

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

type EmailThreadsMessagesReplyParams added in v0.17.0

type EmailThreadsMessagesReplyParams struct {
	// HTML body of the reply. At least one of html or text must be provided.
	HTML string
	// Plain-text body of the reply. At least one of html or text must be provided.
	Text string
	// Also send the reply to the original To and Cc recipients, minus the mailbox's own address.
	ReplyAll *bool
	// Structured `{name, value}` labels for filtering and analytics on the sent-message log. Cap: 20 tags per send.
	Tags []Tag
	// Arbitrary JSON object stored on the send and echoed in webhook payloads. Cap: 2 KB serialized.
	Metadata map[string]any
	// Content classification, which controls suppression policy: - `marketing`: Blocks on all suppression reasons. - `transactional`: Allows delivery through complaint and unsubscribe suppressions, for receipts, password resets, and similar operational mail.
	Category *EmailMessageCategory
	// File attachments to include with the reply. The send is rejected when the estimated generated message size exceeds 20 MB (bodies plus all attachments after base64 encoding). Keep total raw attachment content at or below 15 MB for reliable headroom. Attachment metadata stays on the message's `attachment_manifest`, and the bytes are downloadable for 30 days.
	Attachments []EmailAttachment
}

EmailThreadsMessagesReplyParams is the request body for reply.

type EmailThreadsMessagesService added in v0.17.0

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

EmailThreadsMessagesService reads messages in a conversation thread and sends replies. Reach it via Client.Email.Threads.Messages.

func (*EmailThreadsMessagesService) Attachments added in v0.17.0

Attachments List the attachments on a conversation message. Bytes are downloadable for 30 days, and the metadata stays readable afterward on the message's attachment_manifest.

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.Email.Threads.Messages.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 (*EmailThreadsMessagesService) Body added in v0.17.0

Body Get the original rendered HTML and plain-text body of a conversation message. Available for 30 days. After that, use the message's extracted_text.

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.Email.Threads.Messages.Body(context.Background(), "thr_123", "rem_456")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(body.Text)
}

func (*EmailThreadsMessagesService) Get added in v0.17.0

Get Get one conversation message with its extracted plain text, readable for the mailbox's full retention tier without MIME parsing.

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.Threads.Messages.Get(context.Background(), "thr_123", "rem_456")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(msg.Id, msg.Direction)
}

func (*EmailThreadsMessagesService) List added in v0.17.0

List List the messages in a conversation newest first, both directions. Page older messages with `starting_after`, and pass `include=extracted_text` to inline each message's extracted plain text. Range over it; the second value is non-nil only on the iteration where a fetch failed.

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.Email.Threads.Messages.List(context.Background(), "thr_123", bird.EmailThreadsMessagesListParams{}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(msg.Id, msg.Direction)
	}
}

func (*EmailThreadsMessagesService) ListPage added in v0.17.0

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

func (*EmailThreadsMessagesService) Reply added in v0.17.0

Reply Reply to a specific conversation message from the mailbox's own address. To reply to a conversation, target its newest received message. Recipients, subject, and threading headers are derived automatically.

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.Email.Threads.Messages.Reply(context.Background(), "thr_123", "rem_456", bird.EmailThreadsMessagesReplyParams{
		Text: "Thanks for reaching out!",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(reply.Id)
}

type EmailThreadsService added in v0.17.0

type EmailThreadsService struct {

	// Messages reads and replies to the messages in a conversation.
	Messages *EmailThreadsMessagesService
	// contains filtered or unexported fields
}

EmailThreadsService reads and manages email conversation threads stored in mailboxes. Reach it via Client.Email.Threads.

func (*EmailThreadsService) Delete added in v0.17.0

func (s *EmailThreadsService) Delete(ctx context.Context, threadId string, params EmailThreadsDeleteParams, opts ...option.RequestOption) error

Delete Move a conversation and all its messages to trash (purged after 30 days), or delete permanently with `?permanent=true`.

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.Email.Threads.Delete(context.Background(), "thr_123", bird.EmailThreadsDeleteParams{Permanent: true}); err != nil {
		log.Fatal(err)
	}
}

func (*EmailThreadsService) Get added in v0.17.0

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

Get Get one conversation: participants, counts, labels, read state. Fetch its messages with the thread messages endpoint.

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.Email.Threads.Get(context.Background(), "thr_123")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(thread.Id)
}

func (*EmailThreadsService) List added in v0.17.0

List List mailbox conversations as a cursor page, most recently active first. `label` selects the view: inbox (default), archive, spam, blocked, or a custom label. Filter by mailbox, contact, participant address, or subject substring. Range over it; the second value is non-nil only on the iteration where a fetch failed.

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.Email.Threads.List(context.Background(), bird.EmailThreadsListParams{}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(thread.Id)
	}
}

func (*EmailThreadsService) ListPage added in v0.17.0

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

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

func (*EmailThreadsService) Update added in v0.17.0

Update Add or remove labels on a conversation, or link and unlink a contact. Adding `spam` files it as spam, `archive` clears it out of the inbox, and `inbox` brings it back.

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.Email.Threads.Update(context.Background(), "thr_123", bird.EmailThreadsUpdateParams{
		Labels: &bird.EmailLabelsUpdate{Add: &[]string{"urgent"}},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(thread.Id)
}

type EmailThreadsUpdateParams added in v0.17.0

type EmailThreadsUpdateParams struct {
	// Label changes to apply. Labels in `add` are applied and labels in `remove` are taken off; other labels are left untouched. Adding a label that is already present, or removing one that is not, has no effect. System labels express state changes. On a conversation, adding `spam` files it as spam. Adding `archive` files it away without deleting it. Adding `inbox`, or removing `spam`, `blocked`, or `archive`, returns it to the inbox. Removing `unread` marks all retained received messages as read in one call. On a message, adding or removing `unread` flips read state. Adding or removing `trash` moves it to or out of the trash. The API rejects changes that contradict this model. A request cannot add more than one placement label. It cannot add `blocked`, because blocking a sender is a receive-rule decision. Removing `inbox` requires adding a destination. A conversation cannot add `trash` or `unread`; removing `unread` is the mark-all-read shortcut, and `trash` uses the `DELETE` verb. A message cannot use placement labels; move its conversation instead. A sent message cannot use `unread`. Custom labels are 1-64 characters with no commas, control characters, or leading or trailing whitespace. System label names and a small reserved set (`all`, `archived`, `deleted`, `draft`, `drafts`, `flagged`, `important`, `junk`, `muted`, `none`, `outbox`, `pinned`, `read`, `scheduled`, `snoozed`, `starred`) cannot be used as custom labels, in any casing. A conversation or message has at most 20 labels, system labels included.
	Labels *EmailLabelsUpdate
	// Contact to link this conversation to, or null to unlink the current contact.
	ContactID Nullable[string]
}

EmailThreadsUpdateParams is the request body for update.

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 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 LookupEmailParams added in v0.31.0

type LookupEmailParams struct {
	// The email address to look up. Send it exactly as you hold it. The part before the `@` is case-sensitive, so the API does not lowercase it. A display-name form such as `Aisha <aisha@example.com>` is rejected rather than unwrapped.
	Email string
}

LookupEmailParams is the request body for email.

type LookupFlag added in v0.31.0

type LookupFlag = oapi.LookupFlag

LookupFlag is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the LookupFlag* constants with a default branch rather than treating the set as closed.

type LookupPhoneNumberParams added in v0.31.0

type LookupPhoneNumberParams struct {
	// The phone number to look up, in international format: the country calling code, then the national number. The leading `+` is optional, and `00` works in its place, so `+31612345678`, `31612345678` and `0031612345678` are all the same number. A number written for dialling inside one country, with no country code, is rejected rather than guessed at.
	PhoneNumber string
	// Properties to add to the base lookup. Omit this field or send an empty array to request only the base lookup. Each delivered property is billed in addition to the base lookup. A property that could not be answered is returned with its status and is not billed.
	Type []LookupProperty
}

LookupPhoneNumberParams is the request body for phone_number.

type LookupProperty added in v0.31.0

type LookupProperty = oapi.LookupProperty

type LookupPropertyStatus added in v0.31.0

type LookupPropertyStatus = oapi.LookupPropertyStatus

LookupPropertyStatus is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the LookupPropertyStatus* constants with a default branch rather than treating the set as closed.

type LookupService added in v0.31.0

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

LookupService looks up what a phone number is and whether an email address is worth sending to. Reach it via Client.Lookup.

func (*LookupService) Email added in v0.31.0

Email Create a deliverability lookup for one email address. Returns `result`, `delivery_confidence`, address `flags`, an undeliverable `reason`, and `did_you_mean` when a correction is available. Treat unknown `result` and `reason` values as valid additions and use `delivery_confidence` as the fallback; each completed lookup incurs the same charge.

Example

Email tells you whether an address is worth sending to before you send.

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)
	}
	answer, err := client.Lookup.Email(context.Background(), bird.LookupEmailParams{
		Email: "aisha.khan@example.com",
	})
	if err != nil {
		log.Fatal(err)
	}
	// result is an open vocabulary; delivery_confidence is always comparable.
	fmt.Println(*answer.Result, *answer.DeliveryConfidence)
}

func (*LookupService) PhoneNumber added in v0.31.0

PhoneNumber Create a lookup for a phone number's networks, porting state, country, and line type. Pass `type` to request separately billed `classification`, `porting`, `presence`, `roaming`, `sim_swap`, or `score` blocks. Each block reports its own status, and only blocks with an `ok` status add a charge; the lookup does not contact the number.

Example

PhoneNumber returns the free baseline plus whichever paid blocks you ask for.

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)
	}
	answer, err := client.Lookup.PhoneNumber(context.Background(), bird.LookupPhoneNumberParams{
		PhoneNumber: "+31612345678",
		Type:        []bird.LookupProperty{"classification", "score"},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(*answer.CountryCode, *answer.LineType)
	// Only a block whose status is ok carries a value, and only that one is billed.
	if answer.Score != nil && *answer.Score.Status == "ok" {
		fmt.Println(*answer.Score.Value)
	}
}

type Mailbox added in v0.12.0

type Mailbox = oapi.Mailbox

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

type MailboxCreateReceivePolicy added in v0.16.0

type MailboxCreateReceivePolicy = oapi.MailboxCreateReceivePolicy

type MailboxCreateRetentionTier added in v0.16.0

type MailboxCreateRetentionTier = oapi.MailboxCreateRetentionTier

type MailboxList added in v0.12.0

type MailboxList = oapi.MailboxList

MailboxList is one page of mailboxes plus its pagination cursors.

type MailboxStatsResponse added in v0.12.0

type MailboxStatsResponse = oapi.MailboxStatsResponse

MailboxStatsResponse is the stats time series for a mailbox.

type MailboxUpdateReceivePolicy added in v0.16.0

type MailboxUpdateReceivePolicy = oapi.MailboxUpdateReceivePolicy

type MailboxUpdateRetentionTier added in v0.16.0

type MailboxUpdateRetentionTier = oapi.MailboxUpdateRetentionTier

type MessageDirection added in v0.16.0

type MessageDirection = oapi.MessageDirection

MessageDirection is whether a message was sent or received.

type NextAction added in v0.32.0

type NextAction = apierror.NextAction

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 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 Number added in v0.34.0

type Number = oapi.Number

Number is a number the workspace holds; NumberList is a page of them. AvailableNumber is one on sale and AvailableNumberList a page of those. NumbersOrder is a purchase and NumbersOrderList a page of purchases.

type NumberCapability added in v0.34.0

type NumberCapability = oapi.NumberCapability

NumberCapability is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the NumberCapability* constants with a default branch rather than treating the set as closed.

type NumberList added in v0.34.0

type NumberList = oapi.NumberList

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. The write-side *Config aliases accompany DomainCreateParams / DomainUpdateParams.

type NumberType added in v0.34.0

type NumberType = oapi.NumberType

NumberType is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the NumberType* constants with a default branch rather than treating the set as closed.

type NumbersAvailableListParams added in v0.34.0

type NumbersAvailableListParams struct {
	// ISO 3166-1 alpha-2 country code to search in.
	CountryCode string
	// Return only numbers of this physical type after applying the country and prefix filters.
	NumberType NumberType
	// Return only numbers that start with these digits, matched right after the country dial code: with `country_code=US`, `prefix=212` matches +1 212 area-code numbers and `prefix=833` matches 833 toll-free numbers. Digits only. Leave out the country dial code and any national dialing prefix such as a leading 0. Short codes never match a prefix search.
	Prefix string
	// Filter by capability. Repeat the parameter to require several at once: `capabilities=sms&capabilities=voice` returns only numbers that support both.
	Capabilities []string
	// Maximum number of items to return per page.
	Limit int
}

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

type NumbersAvailableService added in v0.34.0

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

NumbersAvailableService searches numbers on sale. Reach it via Client.Numbers.Available.

func (*NumbersAvailableService) Get added in v0.34.0

Get Re-checks one number from `numbers.available.list` against the carrier, so a stale search result is caught before it is ordered.

Example

Get checks one number is still for sale. A number a carrier supplies is only on sale while the carrier still has it, so a 404 means someone else took it.

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)
	}
	candidate, err := client.Numbers.Available.Get(context.Background(), "+447700900201")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(candidate.CountryCode)
}

func (*NumbersAvailableService) List added in v0.34.0

List Searches one country's numbers on sale. Our own inventory answers first and pages; the last page can carry a live carrier snapshot, so a number seen here may be gone by the time it is ordered. Range over it; the second value is non-nil only on the iteration where a fetch failed.

Example

AvailableList finds numbers on sale in one country. The search is always country-scoped, so CountryCode is required.

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 candidate, err := range client.Numbers.Available.List(context.Background(), bird.NumbersAvailableListParams{
		CountryCode:  "GB",
		Capabilities: []string{"sms", "voice"},
	}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(candidate.Number, candidate.NumberType)
	}
}

func (*NumbersAvailableService) ListPage added in v0.34.0

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

type NumbersListParams added in v0.34.0

type NumbersListParams struct {
	// Return only the number matching these digits. Give a full number with its country code, however your own records spell it: `+12025550188`, `12025550188`, `0012025550188`, and `+1 202 555 0188` all resolve to the same number. Spacing and punctuation are fine once a leading `+` or `00` marks the country code, or when `country_code` names the country; a grouped spelling without either is refused rather than guessed at, and a national spelling (bare digits without the country code) matches only when `country_code` names the country. A short code is matched on its bare digits instead, and since the same short code can be allocated in more than one country, pass `country_code` alongside it to name which one. This filter narrows the list like the others rather than replacing them, so a country or capability filter still applies. To match a range of numbers rather than one, use `prefix`.
	Number string
	// Filter by the country a number belongs to, as an ISO 3166-1 alpha-2 code.
	CountryCode string
	// Return only allocated numbers of this physical type after applying the country and prefix filters.
	NumberType NumberType
	// Return only numbers that start with these digits, matched right after the country dial code: with `country_code=US`, `prefix=212` returns the +1 212 area-code numbers allocated to you. Digits only, and `country_code` is required alongside it, since the digits are national ones. Leave out the country dial code and any national dialing prefix such as a leading 0. Short codes never match a prefix search.
	Prefix string
	// Filter by capability. Repeat the parameter to require several at once: `capabilities=sms&capabilities=voice` returns only numbers that support both.
	Capabilities []string
	// Maximum number of items to return per page.
	Limit int
}

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

type NumbersOrder added in v0.34.0

type NumbersOrder = oapi.NumbersOrder

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. The write-side *Config aliases accompany DomainCreateParams / DomainUpdateParams.

type NumbersOrderList added in v0.34.0

type NumbersOrderList = oapi.NumbersOrderList

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. The write-side *Config aliases accompany DomainCreateParams / DomainUpdateParams.

type NumbersOrderStatus added in v0.34.0

type NumbersOrderStatus = oapi.NumbersOrderStatus

NumbersOrderStatus is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the NumbersOrderStatus* constants with a default branch rather than treating the set as closed.

type NumbersOrdersCreateParams added in v0.34.0

type NumbersOrdersCreateParams struct {
	// The number to acquire, in E.164 format, as returned by `GET /v1/numbers/available`.
	Number string
}

NumbersOrdersCreateParams is the request body for create.

type NumbersOrdersListParams added in v0.34.0

type NumbersOrdersListParams struct {
	// Return only orders with status `charging`, `ordering`, `pending`, `completed`, or `failed`.
	Status NumbersOrderStatus
	// Maximum number of items to return per page.
	Limit int
}

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

type NumbersOrdersService added in v0.34.0

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

NumbersOrdersService buys numbers and reads purchases. Reach it via Client.Numbers.Orders.

func (*NumbersOrdersService) Create added in v0.34.0

Create Buys a number and starts its monthly charge. Most orders settle inline; one waiting on a carrier comes back pending and is followed with `numbers.orders.get`. A setup fee already taken is not refunded if the order then fails.

Example

Create buys a number. Most orders finish inside 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)
	}
	order, err := client.Numbers.Orders.Create(context.Background(), bird.NumbersOrdersCreateParams{
		Number: "+447700900201",
	})
	if err != nil {
		log.Fatal(err)
	}
	// An order that has to wait on a carrier comes back without a NumberId.
	// Poll it until it is completed or failed.
	fmt.Println(order.Status, order.Id)
}

func (*NumbersOrdersService) Get added in v0.34.0

Get Reads one order's current state, and the number it produced once completed. This is the poll for an order that came back pending.

Example

Get polls an order that did not finish inline.

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)
	}
	order, err := client.Numbers.Orders.Get(context.Background(), "nor_01krdgeqcxet5s7t44vh8rt9mg")
	if err != nil {
		log.Fatal(err)
	}
	// FailureReason says what went wrong, and only ever on a failed order.
	fmt.Println(order.Status)
}

func (*NumbersOrdersService) List added in v0.34.0

List Pages the workspace's purchase attempts, newest first, filtered by status. An order outlives its attempt, so a failure stays readable with the reason it carried. Range over it; the second value is non-nil only on the iteration where a fetch failed.

Example

List finds the purchases that did not complete.

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 order, err := range client.Numbers.Orders.List(context.Background(), bird.NumbersOrdersListParams{
		Status: "failed",
	}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(order.Number)
	}
}

func (*NumbersOrdersService) ListPage added in v0.34.0

func (s *NumbersOrdersService) ListPage(ctx context.Context, params NumbersOrdersListParams, startingAfter string, opts ...option.RequestOption) (*NumbersOrderList, error)

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

type NumbersService added in v0.34.0

type NumbersService struct {

	// Available searches the numbers on sale in a country.
	Available *NumbersAvailableService
	// Orders buys a number and reports where a purchase stands.
	Orders *NumbersOrdersService
	// contains filtered or unexported fields
}

NumbersService is the numbers a workspace holds, plus the Available search and the Orders that turn one into the other. Reach it via Client.Numbers.

Buying is an order rather than a direct create: most complete inside the request, but one that has to wait on a carrier comes back pending and is polled through Client.Numbers.Orders.Get.

func (*NumbersService) Get added in v0.34.0

func (s *NumbersService) Get(ctx context.Context, numberId string, opts ...option.RequestOption) (*Number, error)

Get Reads one allocated number by the id `numbers.list` returns. Carries its status and, where a country demands ownership paperwork, what is still outstanding on it.

Example

Get reads one number allocated to 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)
	}
	allocated, err := client.Numbers.Get(context.Background(), "nda_01krdgeqcxet5s7t44vh8rt9mg")
	if err != nil {
		log.Fatal(err)
	}
	// A country that asks for ownership paperwork answers on Ownership; most
	// answer nil.
	fmt.Println(allocated.Status)
}

func (*NumbersService) List added in v0.34.0

List Pages the numbers allocated to the workspace, dedicated and shared alike. Narrows on country, type, prefix and capability, so one number is reached without walking every page. Range over it; the second value is non-nil only on the iteration where a fetch failed.

Example

List walks the numbers allocated to 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 allocated, err := range client.Numbers.List(context.Background(), bird.NumbersListParams{
		CountryCode: "GB",
	}) {
		if err != nil {
			log.Fatal(err)
		}
		// Kind distinguishes a number you bought from one Bird manages.
		fmt.Println(allocated.Number, allocated.Kind, allocated.Status)
	}
}

func (*NumbersService) ListPage added in v0.34.0

func (s *NumbersService) ListPage(ctx context.Context, params NumbersListParams, startingAfter string, opts ...option.RequestOption) (*NumberList, error)

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

func (*NumbersService) Release added in v0.34.0

func (s *NumbersService) Release(ctx context.Context, numberId string, opts ...option.RequestOption) error

Release Gives a dedicated number back and stops its monthly charge. Irreversible: the number leaves the workspace and the channels built on it stop sending. A shared number cannot be released.

Example

Release gives a dedicated number back, stopping its monthly charge.

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)
	}
	// Only a dedicated number can be released; a shared one answers E14002.
	if err := client.Numbers.Release(context.Background(), "nda_01krdgeqcxet5s7t44vh8rt9mg"); err != nil {
		log.Fatal(err)
	}
}

type PhoneNumberLookup added in v0.31.0

type PhoneNumberLookup = oapi.PhoneNumberLookup

PhoneNumberLookup is what we know about a phone number; EmailLookup is the verdict on an email address. Every block a phone lookup carries reports its own status, so a partial answer is visible rather than silent.

type Preference added in v0.41.0

type Preference = oapi.Preference

Preference is one recorded consent grant or opt-out; PreferenceList is a page of them.

type PreferenceChannel added in v0.41.0

type PreferenceChannel = oapi.PreferenceChannel

PreferenceChannel is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the PreferenceChannel* constants with a default branch rather than treating the set as closed.

type PreferenceCoverage added in v0.41.0

type PreferenceCoverage = oapi.PreferenceCoverage

PreferenceCoverage is how much traffic a statement covers: non_transactional keeps transactional messages such as receipts and verification codes flowing; all covers every message.

const (
	PreferenceCoverageAll              PreferenceCoverage = "all"
	PreferenceCoverageNonTransactional PreferenceCoverage = "non_transactional"
)

type PreferenceList added in v0.41.0

type PreferenceList = oapi.PreferenceList

Preference is one recorded consent grant or opt-out; PreferenceList is a page of them.

type PreferenceOrigin added in v0.41.0

type PreferenceOrigin = oapi.PreferenceOrigin

PreferenceOrigin is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the PreferenceOrigin* constants with a default branch rather than treating the set as closed.

type PreferenceStatus added in v0.41.0

type PreferenceStatus = oapi.PreferenceStatus

PreferenceStatus is what a statement says: granted records consent to receive messages, revoked records an opt-out.

const (
	PreferenceStatusGranted PreferenceStatus = "granted"
	PreferenceStatusRevoked PreferenceStatus = "revoked"
)

type PreferenceWriteResult added in v0.41.0

type PreferenceWriteResult = oapi.PreferenceWriteResult

PreferenceWriteResult is the outcome of a preference create or delete. Applied true means the write took effect; applied false means it was refused as older than the key's current statement, and Preference then carries the statement that survived.

type PreferencesCreateParams added in v0.41.0

type PreferencesCreateParams struct {
	// Channel the statement applies to.
	Channel PreferenceChannel
	// Handle is who the statement is about: an email address on the email
	// channel, an E.164 phone number on SMS and WhatsApp.
	Handle string
	// Status is what the statement says: granted or revoked.
	Status PreferenceStatus
	// Coverage is how much traffic the statement covers. Defaults to
	// non_transactional server-side when left unset.
	Coverage PreferenceCoverage
	// SenderScope limits the statement to one sender instead of the whole
	// channel. Not supported on email.
	SenderScope string
	// Source is a free-form note on where the statement came from: a form
	// name, an import batch, a campaign.
	Source string
	// ConsentedAt is when the person consented, required evidence when
	// granting over a stored opt-out: the grant applies only if this is later
	// than the opt-out it reverses. Omitted from the request when zero.
	ConsentedAt time.Time
}

PreferencesCreateParams records one preference statement. Channel, Handle, and Status are required; the rest are optional and omitted from the request at their zero value.

type PreferencesListParams added in v0.41.0

type PreferencesListParams struct {
	// Return only preferences on this channel.
	Channel PreferenceChannel
	// Return only preferences for this exact handle: an email address or an E.164 phone number. Requires `channel`, since a handle only means something on its channel.
	Handle string
	// Maximum number of items to return per page.
	Limit int
}

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

type PreferencesService added in v0.41.0

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

PreferencesService reads and writes the workspace's stated messaging preferences: consent grants and opt-outs keyed by channel and handle, and optionally scoped to one sender. Reach it via Client.Preferences.

func (*PreferencesService) Create added in v0.41.0

Create records a preference statement: a consent grant or opt-out for a handle on a channel, optionally scoped to one sender. The write is an ordered upsert keyed by channel, handle, and sender scope: a statement older than the one already on record is not an error, it comes back with Applied false and Preference set to the statement that survived. The HTTP status (200 for an existing key, 201 for a fresh one) does not change what is returned, so callers never need to branch on it. Retried safely with a reused idempotency key.

Example

Create records a consent grant, with the evidence needed to override a stored opt-out on the same number.

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)
	}
	result, err := client.Preferences.Create(context.Background(), bird.PreferencesCreateParams{
		Channel:     bird.PreferenceChannelEmail,
		Handle:      "recipient@example.com",
		Status:      bird.PreferenceStatusGranted,
		Source:      "signup-form-v2",
		ConsentedAt: time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	// A newer statement already on file answers Applied false instead of an
	// error, with the surviving statement in Preference.
	if result.Applied != nil && *result.Applied {
		fmt.Println("grant recorded")
	}
}

func (*PreferencesService) Delete added in v0.41.0

func (s *PreferencesService) Delete(ctx context.Context, preferenceId string, opts ...option.RequestOption) (*PreferenceWriteResult, error)

Delete removes a preference statement by ID. The delete is conditional: if a newer statement has since been recorded on the same key, the delete is refused rather than applied, and the returned write result carries Applied false with Preference set to the statement that survived — a person's own opt-out is refused the same way, since it cannot be overridden or deleted through this API. Applied true with a nil Preference means the key now has no record. Retried safely with a reused idempotency key.

Example

Delete removes a preference statement 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)
	}
	result, err := client.Preferences.Delete(context.Background(), "prf_01krdgeqcxet5s7t44vh8rt9mg")
	if err != nil {
		log.Fatal(err)
	}
	// A newer statement recorded since refuses the delete: Applied comes back
	// false and Preference carries the statement that survived.
	switch {
	case result.Applied == nil:
	case !*result.Applied && result.Preference != nil:
		fmt.Println("delete refused, surviving statement:", result.Preference.Id)
	default:
		fmt.Println("deleted")
	}
}

func (*PreferencesService) Get added in v0.41.0

func (s *PreferencesService) Get(ctx context.Context, preferenceId string, opts ...option.RequestOption) (*Preference, error)

Get Read one recorded preference by ID: the channel and handle it is about, whether it grants or revokes, how much traffic it covers, and where the statement came from.

Example

Get reads one recorded preference 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)
	}
	pref, err := client.Preferences.Get(context.Background(), "prf_01krdgeqcxet5s7t44vh8rt9mg")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(*pref.Status, *pref.Coverage)
}

func (*PreferencesService) List added in v0.41.0

List List the workspace's stated messaging preferences (consent grants and opt-outs) as a cursor page. Filter by channel, and by handle within a channel, to look up one person before messaging them. Range over it; the second value is non-nil only on the iteration where a fetch failed.

Example

List looks up the messaging preferences recorded for one handle on one channel.

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 pref, err := range client.Preferences.List(context.Background(), bird.PreferencesListParams{
		Channel: bird.PreferenceChannelSms,
		Handle:  "+15550001234",
	}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(pref.Id, *pref.Status)
	}
}

func (*PreferencesService) ListPage added in v0.41.0

func (s *PreferencesService) ListPage(ctx context.Context, params PreferencesListParams, startingAfter string, opts ...option.RequestOption) (*PreferenceList, error)

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

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 RealtimeBatchEventParams added in v0.15.0

type RealtimeBatchEventParams struct {
	// The event name clients bind to. Application event names are free-form; the `bird:` and `bird_internal:` prefixes are reserved for the protocol and rejected.
	Event string
	// A Realtime channel name. Only letters, digits, and _ - = @ , . ; Prefix with `private-` or `presence-` for authenticated channels, or `private-encrypted-` for channels whose payloads are end-to-end encrypted with a key only you hold.
	Channel string
	// Arbitrary JSON payload delivered as the event data — an object, array, or scalar. Cap: 10 KB serialized.
	Data any
	// Exclude this connection from delivery, to avoid echoing a change back to the client that triggered it. The value is the client's connection id, assigned when its connection is established.
	ExcludeConnectionID string
	// Attributes of this event's channel to return alongside the publish (same semantics and validation errors as on the channel endpoints). Requesting attributes counts as one additional message toward usage.
	Include []RealtimeChannelInclude
}

RealtimeBatchEventParams is one events item.

type RealtimeBatchPublishResult added in v0.15.0

type RealtimeBatchPublishResult = oapi.RealtimeBatchPublishResult

Realtime read and publish results. RealtimePublishResult and RealtimeBatchPublishResult carry per-channel counts only when the call asked for them via Include. RealtimeChannelsList is the app's occupied channels (unpaginated); RealtimeChannelInfo is one channel's state; RealtimeChannelMembers is the members present on a presence channel.

type RealtimeBatchPublishResultItem added in v0.15.0

type RealtimeBatchPublishResultItem = oapi.RealtimeBatchPublishResultItem

Realtime read and publish results. RealtimePublishResult and RealtimeBatchPublishResult carry per-channel counts only when the call asked for them via Include. RealtimeChannelsList is the app's occupied channels (unpaginated); RealtimeChannelInfo is one channel's state; RealtimeChannelMembers is the members present on a presence channel.

type RealtimeChannelAuthorization added in v0.33.0

type RealtimeChannelAuthorization struct {
	// The <key>:<signature> pair the Realtime edge verifies.
	Auth string `json:"auth"`
	// Echo of the signed member data, on a presence channel.
	MemberData string `json:"member_data,omitempty"`
	// The channel's decryption key, base64, on a private-encrypted- channel.
	SharedSecret string `json:"shared_secret,omitempty"`
}

RealtimeChannelAuthorization is the body your auth endpoint returns to the browser client. The JSON tags are the wire spelling the client expects, so it can be marshaled as-is.

type RealtimeChannelAuthorizationParams added in v0.33.0

type RealtimeChannelAuthorizationParams struct {
	// The subscribing connection's id.
	ConnectionID string
	// The channel being subscribed.
	ChannelName string
	// Presence channels: the member-identity JSON to sign and echo, carrying
	// member_id and optionally member_info. Signed and returned byte-identical,
	// so hand over the exact string the client will see.
	MemberData string
}

RealtimeChannelAuthorizationParams identifies the subscription to sign. Both ids come from the body the browser client POSTs to your auth endpoint.

type RealtimeChannelGetParams added in v0.15.0

type RealtimeChannelGetParams struct {
	// Attributes to include. Repeatable. Requesting `member_count` for a non-presence channel, or `connection_count` when the app's connection-counting flag is off, returns a validation error (400).
	Include []RealtimeChannelInclude
}

RealtimeChannelGetParams filters the get read.

type RealtimeChannelInclude added in v0.15.0

type RealtimeChannelInclude = oapi.RealtimeChannelInclude

RealtimeChannelInclude names a per-channel attribute to return alongside a publish or channel read.

const (
	// RealtimeIncludeMemberCount is presence-channels only.
	RealtimeIncludeMemberCount RealtimeChannelInclude = "member_count"
	// RealtimeIncludeConnectionCount requires the app's connection-counting flag.
	RealtimeIncludeConnectionCount RealtimeChannelInclude = "connection_count"
)

type RealtimeChannelInfo added in v0.15.0

type RealtimeChannelInfo = oapi.RealtimeChannelInfo

Realtime read and publish results. RealtimePublishResult and RealtimeBatchPublishResult carry per-channel counts only when the call asked for them via Include. RealtimeChannelsList is the app's occupied channels (unpaginated); RealtimeChannelInfo is one channel's state; RealtimeChannelMembers is the members present on a presence channel.

type RealtimeChannelListItem added in v0.15.0

type RealtimeChannelListItem = oapi.RealtimeChannelListItem

Realtime read and publish results. RealtimePublishResult and RealtimeBatchPublishResult carry per-channel counts only when the call asked for them via Include. RealtimeChannelsList is the app's occupied channels (unpaginated); RealtimeChannelInfo is one channel's state; RealtimeChannelMembers is the members present on a presence channel.

type RealtimeChannelListParams added in v0.15.0

type RealtimeChannelListParams struct {
	// Only channels whose name starts with this prefix (for example, `presence-`).
	Prefix string
	// Per-channel attributes to include. Repeatable. Requesting `member_count` without a presence-channel `prefix`, or `connection_count` when the app's connection-counting flag is off, returns a validation error (400).
	Include []RealtimeChannelInclude
}

RealtimeChannelListParams filters the list read.

type RealtimeChannelMember added in v0.15.0

type RealtimeChannelMember = oapi.RealtimeChannelMember

Realtime read and publish results. RealtimePublishResult and RealtimeBatchPublishResult carry per-channel counts only when the call asked for them via Include. RealtimeChannelsList is the app's occupied channels (unpaginated); RealtimeChannelInfo is one channel's state; RealtimeChannelMembers is the members present on a presence channel.

type RealtimeChannelMembers added in v0.15.0

type RealtimeChannelMembers = oapi.RealtimeChannelMembers

Realtime read and publish results. RealtimePublishResult and RealtimeBatchPublishResult carry per-channel counts only when the call asked for them via Include. RealtimeChannelsList is the app's occupied channels (unpaginated); RealtimeChannelInfo is one channel's state; RealtimeChannelMembers is the members present on a presence channel.

type RealtimeChannelsList added in v0.15.0

type RealtimeChannelsList = oapi.RealtimeChannelsList

Realtime read and publish results. RealtimePublishResult and RealtimeBatchPublishResult carry per-channel counts only when the call asked for them via Include. RealtimeChannelsList is the app's occupied channels (unpaginated); RealtimeChannelInfo is one channel's state; RealtimeChannelMembers is the members present on a presence channel.

type RealtimeChannelsService added in v0.15.0

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

RealtimeChannelsService reads channel state. Reach it via Client.Realtime.Channels.

func (*RealtimeChannelsService) Get added in v0.15.0

func (s *RealtimeChannelsService) Get(ctx context.Context, realtimeAppId string, channelName string, params RealtimeChannelGetParams, opts ...option.RequestOption) (*RealtimeChannelInfo, error)
Example

Get reads one channel's occupancy, plus any counts named in Include.

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")),
		option.WithRealtimeCredentials(os.Getenv("BIRD_REALTIME_KEY"), os.Getenv("BIRD_REALTIME_SECRET")),
	)
	if err != nil {
		log.Fatal(err)
	}
	channel, err := client.Realtime.Channels.Get(context.Background(), "rap_123", "presence-lobby", bird.RealtimeChannelGetParams{
		Include: []bird.RealtimeChannelInclude{bird.RealtimeIncludeMemberCount},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(channel.Occupied, channel.MemberCount)
}

func (*RealtimeChannelsService) List added in v0.15.0

Example

List returns the app's occupied channels. The Realtime service does not paginate this listing, so one response holds every occupied channel.

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")),
		option.WithRealtimeCredentials(os.Getenv("BIRD_REALTIME_KEY"), os.Getenv("BIRD_REALTIME_SECRET")),
	)
	if err != nil {
		log.Fatal(err)
	}
	channels, err := client.Realtime.Channels.List(context.Background(), "rap_123", bird.RealtimeChannelListParams{
		Prefix:  "presence-",
		Include: []bird.RealtimeChannelInclude{bird.RealtimeIncludeMemberCount},
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, ch := range channels.Data {
		fmt.Println(ch.Name, ch.MemberCount)
	}
}

func (*RealtimeChannelsService) Members added in v0.15.0

func (s *RealtimeChannelsService) Members(ctx context.Context, realtimeAppId string, channelName string, opts ...option.RequestOption) (*RealtimeChannelMembers, error)
Example

Members lists the members present on a presence channel.

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")),
		option.WithRealtimeCredentials(os.Getenv("BIRD_REALTIME_KEY"), os.Getenv("BIRD_REALTIME_SECRET")),
	)
	if err != nil {
		log.Fatal(err)
	}
	members, err := client.Realtime.Channels.Members(context.Background(), "rap_123", "presence-lobby")
	if err != nil {
		log.Fatal(err)
	}
	for _, m := range members.Members {
		fmt.Println(m.MemberId)
	}
}

type RealtimeMemberSendParams added in v0.21.0

type RealtimeMemberSendParams struct {
	// The event name clients bind to. Application event names are free-form; the `bird:` and `bird_internal:` prefixes are reserved for the protocol and rejected.
	Event string
	// Arbitrary JSON payload delivered as the event data: an object, array, or scalar. Cap: 10 KB serialized.
	Data any
}

RealtimeMemberSendParams is the request body for send.

type RealtimeMembersService added in v0.15.0

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

RealtimeMembersService acts on the connections of one member. Reach it via Client.Realtime.Members.

func (*RealtimeMembersService) Disconnect added in v0.15.0

func (s *RealtimeMembersService) Disconnect(ctx context.Context, realtimeAppId string, memberId string, opts ...option.RequestOption) error
Example

Disconnect closes every connection belonging to one member. Use it for a sign-out or ban flow.

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.WithRealtimeCredentials(os.Getenv("BIRD_REALTIME_KEY"), os.Getenv("BIRD_REALTIME_SECRET")),
	)
	if err != nil {
		log.Fatal(err)
	}
	if err := client.Realtime.Members.Disconnect(context.Background(), "rap_123", "member:42"); err != nil {
		log.Fatal(err)
	}
}

func (*RealtimeMembersService) Send added in v0.21.0

func (s *RealtimeMembersService) Send(ctx context.Context, realtimeAppId string, memberId string, params RealtimeMemberSendParams, opts ...option.RequestOption) error
Example

Send delivers one event to every connection a single member holds, without putting it on a channel anyone else can subscribe 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")),
		option.WithRealtimeCredentials(os.Getenv("BIRD_REALTIME_KEY"), os.Getenv("BIRD_REALTIME_SECRET")),
	)
	if err != nil {
		log.Fatal(err)
	}
	err = client.Realtime.Members.Send(context.Background(), "rap_01krdgeqcxet5s7t44vh8rt9mg", "user_42", bird.RealtimeMemberSendParams{
		Event: "order-shipped",
		Data:  map[string]any{"order_id": "ord_123"},
	})
	if err != nil {
		log.Fatal(err)
	}
}

type RealtimePublishBatchParams added in v0.15.0

type RealtimePublishBatchParams struct {
	// Up to 10 events per batch.
	Events []RealtimeBatchEventParams
}

RealtimePublishBatchParams is the request body for publish_batch.

type RealtimePublishParams added in v0.15.0

type RealtimePublishParams struct {
	// The event name clients bind to. Application event names are free-form; the `bird:` and `bird_internal:` prefixes are reserved for the protocol and rejected.
	Event string
	// The channels to deliver the event to (up to 100 per call). Prefix with `private-` or `presence-` for authenticated channels. A `private-encrypted-` channel must be the only channel in its publish: each encrypted channel has its own key, so a fan-out would hand the other channels unreadable ciphertext.
	Channels []string
	// Arbitrary JSON payload delivered as the event data — an object, array, or scalar. Cap: 10 KB serialized.
	Data any
	// Exclude this connection from delivery, to avoid echoing a change back to the client that triggered it. The value is the client's connection id, assigned when its connection is established.
	ExcludeConnectionID string
	// Per-channel attributes to return alongside the publish, reflecting each channel's state at publish time (same semantics and validation errors as on the channel endpoints: `member_count` is presence-channels only, `connection_count` requires the app's connection-counting flag). Requesting attributes counts as one additional message toward usage.
	Include []RealtimeChannelInclude
}

RealtimePublishParams is the request body for publish.

type RealtimePublishResult added in v0.15.0

type RealtimePublishResult = oapi.RealtimePublishResult

Realtime read and publish results. RealtimePublishResult and RealtimeBatchPublishResult carry per-channel counts only when the call asked for them via Include. RealtimeChannelsList is the app's occupied channels (unpaginated); RealtimeChannelInfo is one channel's state; RealtimeChannelMembers is the members present on a presence channel.

type RealtimeService added in v0.15.0

type RealtimeService struct {

	// Channels reads the app's occupied channels and their members.
	Channels *RealtimeChannelsService
	// Members acts on an app-defined member across all of its connections.
	Members *RealtimeMembersService
	// contains filtered or unexported fields
}

RealtimeService publishes events to a Realtime app and inspects its live state. Reach it via Client.Realtime.

Every call needs the app's own credentials on top of the workspace API key: configure them with option.WithRealtimeCredentials, at construction for a single app or per call when one client serves several apps. Without them a method fails before any request is sent.

The app id is a positional argument rather than client config, so one client can address any app the workspace owns.

func (*RealtimeService) AuthorizeChannel added in v0.33.0

AuthorizeChannel signs a channel subscription for a browser client and returns the body your auth endpoint responds with. It is pure crypto — no request is sent — so authorize as many subscriptions as you like: the signature is HMAC-SHA256(secret, "<connection_id>:<channel_name>[:<member_data>]") keyed by the app secret and prefixed with the app key. A private-encrypted- channel's response also carries the channel's shared_secret, derived from the configured encryption master key; hand it only to a client you have just authorized to read that channel, since it decrypts every event on it.

Authorize only after your own check that this user may join this channel — the signature is the edge's only evidence that they may.

auth, err := client.Realtime.AuthorizeChannel(bird.RealtimeChannelAuthorizationParams{
	ConnectionID: req.ConnectionID,
	ChannelName:  req.ChannelName,
})

See ExampleRealtimeService_AuthorizeChannel for the whole auth endpoint.

Example

AuthorizeChannel signs a subscription for a browser client locally. Authorize only after checking that the user may join the channel. The signature is the edge's only evidence that they may. On a private-encrypted channel, the response also carries that channel's shared_secret, so the client can decrypt.

package main

import (
	"encoding/json"
	"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.WithRealtimeCredentials(os.Getenv("BIRD_REALTIME_KEY"), os.Getenv("BIRD_REALTIME_SECRET")),
		option.WithRealtimeEncryptionMasterKey(os.Getenv("BIRD_REALTIME_ENCRYPTION_MASTER_KEY")),
	)
	if err != nil {
		log.Fatal(err)
	}
	http.HandleFunc("/bird/auth", func(w http.ResponseWriter, r *http.Request) {
		var req struct {
			ConnectionID string `json:"connection_id"`
			ChannelName  string `json:"channel_name"`
		}
		if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
			http.Error(w, "bad request", http.StatusBadRequest)
			return
		}
		auth, err := client.Realtime.AuthorizeChannel(bird.RealtimeChannelAuthorizationParams{
			ConnectionID: req.ConnectionID,
			ChannelName:  req.ChannelName,
		})
		if err != nil {
			http.Error(w, "server error", http.StatusInternalServerError)
			return
		}
		w.Header().Set("Content-Type", "application/json")
		_ = json.NewEncoder(w).Encode(auth)
	})
}

func (*RealtimeService) Publish added in v0.15.0

func (s *RealtimeService) Publish(ctx context.Context, realtimeAppId string, params RealtimePublishParams, opts ...option.RequestOption) (*RealtimePublishResult, error)

Publish delivers one event to the named channels and reports how it fanned out.

A private-encrypted- channel's payload is sealed here, before the request leaves the process: Bird sees only {"nonce", "ciphertext"}, and the master key configured with option.WithRealtimeEncryptionMasterKey never travels. Such a publish names exactly one channel — each channel derives its own key, so a fan-out would deliver ciphertext the other channels' subscribers cannot open.

The payload is sealed once and reused across retries, so a retried publish delivers the same envelope rather than re-encrypting under a fresh nonce.

Example

Publish delivers one event to one or more channels. The Realtime app's own key and secret authenticate the call, alongside the workspace API key.

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")),
		option.WithRealtimeCredentials(os.Getenv("BIRD_REALTIME_KEY"), os.Getenv("BIRD_REALTIME_SECRET")),
	)
	if err != nil {
		log.Fatal(err)
	}
	result, err := client.Realtime.Publish(context.Background(), "rap_123", bird.RealtimePublishParams{
		Event:    "order.created",
		Channels: []string{"orders", "presence-lobby"},
		Data:     map[string]any{"order_id": "ord_1", "total": 4200},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(result.Data)
}

func (*RealtimeService) PublishBatch added in v0.15.0

func (s *RealtimeService) PublishBatch(ctx context.Context, realtimeAppId string, params RealtimePublishBatchParams, opts ...option.RequestOption) (*RealtimeBatchPublishResult, error)

PublishBatch delivers several events in one request, each to a single channel. Every event addressed to a private-encrypted- channel is sealed here under that channel's own key, so encrypted and plain events can share a batch.

Example

PublishBatch sends several events, each to a single channel, 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")),
		option.WithRealtimeCredentials(os.Getenv("BIRD_REALTIME_KEY"), os.Getenv("BIRD_REALTIME_SECRET")),
	)
	if err != nil {
		log.Fatal(err)
	}
	result, err := client.Realtime.PublishBatch(context.Background(), "rap_123", bird.RealtimePublishBatchParams{
		Events: []bird.RealtimeBatchEventParams{
			{Event: "order.created", Channel: "orders", Data: map[string]any{"id": 1}},
			{Event: "order.updated", Channel: "orders", Data: map[string]any{"id": 2}},
		},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(result.Data)
}

type ReceiveRule added in v0.12.0

type ReceiveRule = oapi.ReceiveRule

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

type ReceiveRuleCreateAction added in v0.16.0

type ReceiveRuleCreateAction = oapi.ReceiveRuleCreateAction

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 SMSErrorCode added in v0.28.0

type SMSErrorCode = oapi.SMSErrorCode

SMSErrorCode is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the SMSErrorCode* constants with a default branch rather than treating the set as closed.

type SMSEventList added in v0.33.0

type SMSEventList = oapi.SMSEventList

SMSEventList is the lifecycle timeline of one SMS, oldest first. Returned by Sms.ListEvents.

type SMSInboundStatsByCountryResponse added in v0.33.0

type SMSInboundStatsByCountryResponse = oapi.SMSInboundStatsByCountryResponse

SMS statistics responses, returned by the Client.Sms.Stats methods. Each is the read-side body for one breakdown; the Inbound set counts messages the workspace's own numbers received rather than what it sent.

type SMSInboundStatsByNumberResponse added in v0.33.0

type SMSInboundStatsByNumberResponse = oapi.SMSInboundStatsByNumberResponse

SMS statistics responses, returned by the Client.Sms.Stats methods. Each is the read-side body for one breakdown; the Inbound set counts messages the workspace's own numbers received rather than what it sent.

type SMSInboundStatsByOperatorResponse added in v0.33.0

type SMSInboundStatsByOperatorResponse = oapi.SMSInboundStatsByOperatorResponse

SMS statistics responses, returned by the Client.Sms.Stats methods. Each is the read-side body for one breakdown; the Inbound set counts messages the workspace's own numbers received rather than what it sent.

type SMSInboundStatsResponse added in v0.33.0

type SMSInboundStatsResponse = oapi.SMSInboundStatsResponse

SMS statistics responses, returned by the Client.Sms.Stats methods. Each is the read-side body for one breakdown; the Inbound set counts messages the workspace's own numbers received rather than what it sent.

type SMSInboundStatsSummaryResponse added in v0.33.0

type SMSInboundStatsSummaryResponse = oapi.SMSInboundStatsSummaryResponse

SMS statistics responses, returned by the Client.Sms.Stats methods. Each is the read-side body for one breakdown; the Inbound set counts messages the workspace's own numbers received rather than what it sent.

type SMSKeywordOperation added in v0.33.0

type SMSKeywordOperation = oapi.SMSKeywordOperation

SMSKeywordOperation is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the SMSKeywordOperation* constants with a default branch rather than treating the set as closed.

type SMSKeywordRule added in v0.33.0

type SMSKeywordRule = oapi.SMSKeywordRule

SMSKeywordRule is what one keyword does when a subscriber texts it, Bird's or the workspace's own; SMSKeywordRuleList is the (unpaginated) set of them.

type SMSKeywordRuleList added in v0.33.0

type SMSKeywordRuleList = oapi.SMSKeywordRuleList

SMSKeywordRule is what one keyword does when a subscriber texts it, Bird's or the workspace's own; SMSKeywordRuleList is the (unpaginated) set of them.

type SMSKeywordRuleScope added in v0.33.0

type SMSKeywordRuleScope = oapi.SMSKeywordRuleScope

SMSKeywordRuleScope distinguishes Bird's default keyword rules from a workspace's own.

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 SMSMessageCategory added in v0.16.0

type SMSMessageCategory = oapi.SMSMessageCategory

SMSMessageCategory is an SMS's content classification.

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 SMSStatsByCarrierResponse added in v0.33.0

type SMSStatsByCarrierResponse = oapi.SMSStatsByCarrierResponse

SMS statistics responses, returned by the Client.Sms.Stats methods. Each is the read-side body for one breakdown; the Inbound set counts messages the workspace's own numbers received rather than what it sent.

type SMSStatsByCategoryResponse added in v0.33.0

type SMSStatsByCategoryResponse = oapi.SMSStatsByCategoryResponse

SMS statistics responses, returned by the Client.Sms.Stats methods. Each is the read-side body for one breakdown; the Inbound set counts messages the workspace's own numbers received rather than what it sent.

type SMSStatsByCountryResponse added in v0.33.0

type SMSStatsByCountryResponse = oapi.SMSStatsByCountryResponse

SMS statistics responses, returned by the Client.Sms.Stats methods. Each is the read-side body for one breakdown; the Inbound set counts messages the workspace's own numbers received rather than what it sent.

type SMSStatsByErrorCodeResponse added in v0.33.0

type SMSStatsByErrorCodeResponse = oapi.SMSStatsByErrorCodeResponse

SMS statistics responses, returned by the Client.Sms.Stats methods. Each is the read-side body for one breakdown; the Inbound set counts messages the workspace's own numbers received rather than what it sent.

type SMSStatsByOriginatorResponse added in v0.33.0

type SMSStatsByOriginatorResponse = oapi.SMSStatsByOriginatorResponse

SMS statistics responses, returned by the Client.Sms.Stats methods. Each is the read-side body for one breakdown; the Inbound set counts messages the workspace's own numbers received rather than what it sent.

type SMSStatsByStatusResponse added in v0.33.0

type SMSStatsByStatusResponse = oapi.SMSStatsByStatusResponse

SMS statistics responses, returned by the Client.Sms.Stats methods. Each is the read-side body for one breakdown; the Inbound set counts messages the workspace's own numbers received rather than what it sent.

type SMSStatsByTagResponse added in v0.33.0

type SMSStatsByTagResponse = oapi.SMSStatsByTagResponse

SMS statistics responses, returned by the Client.Sms.Stats methods. Each is the read-side body for one breakdown; the Inbound set counts messages the workspace's own numbers received rather than what it sent.

type SMSStatsLifecycleSortMetric added in v0.33.0

type SMSStatsLifecycleSortMetric = oapi.SMSStatsLifecycleSortMetric

SMSStatsLifecycleSortMetric is the reduced sort vocabulary of a breakdown whose rows carry lifecycle counts only.

type SMSStatsResponse added in v0.33.0

type SMSStatsResponse = oapi.SMSStatsResponse

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

type SMSStatsSortMetric added in v0.33.0

type SMSStatsSortMetric = oapi.SMSStatsSortMetric

SMSStatsSortMetric is the metric an SMS-stats breakdown sorts by, for the breakdowns whose rows carry rates as well as counts.

type SMSStatsSummary added in v0.33.0

type SMSStatsSummary = oapi.SMSStatsSummary

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

type SMSStatus added in v0.3.0

type SMSStatus = oapi.SMSMessageStatus

SMSStatus is a message's delivery status.

type SMSSuppression added in v0.33.0

type SMSSuppression = oapi.SMSSuppression

SMSSuppression is one sender-and-subscriber pair Bird will not deliver to; SMSSuppressionList is a page of them.

type SMSSuppressionCoverage added in v0.33.0

type SMSSuppressionCoverage = oapi.SMSSuppressionCoverage

SMSSuppressionCoverage is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the SMSSuppressionCoverage* constants with a default branch rather than treating the set as closed.

type SMSSuppressionEndReason added in v0.33.0

type SMSSuppressionEndReason = oapi.SMSSuppressionEndReason

SMSSuppressionEndReason is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the SMSSuppressionEndReason* constants with a default branch rather than treating the set as closed.

type SMSSuppressionList added in v0.33.0

type SMSSuppressionList = oapi.SMSSuppressionList

SMSSuppression is one sender-and-subscriber pair Bird will not deliver to; SMSSuppressionList is a page of them.

type SMSSuppressionOrigin added in v0.33.0

type SMSSuppressionOrigin = oapi.SMSSuppressionOrigin

SMSSuppressionOrigin is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the SMSSuppressionOrigin* constants with a default branch rather than treating the set as closed.

type SMSSuppressionReason added in v0.33.0

type SMSSuppressionReason = oapi.SMSSuppressionReason

SMSSuppressionReason is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the SMSSuppressionReason* constants with a default branch rather than treating the set as closed.

type SMSSuppressionReasonFilter added in v0.33.0

type SMSSuppressionReasonFilter = oapi.SMSSuppressionReasonFilter

SMSSuppressionReasonFilter is why a suppression exists, used by the read filters.

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

type SMSTemplateList added in v0.3.0

type SMSTemplateList = oapi.SMSTemplateList

type SMSTemplateListParams added in v0.3.0

type SMSTemplateListParams struct {
	// Keep only templates of this scope. Every SMS template is `system`, so `workspace` matches none. Omit for all.
	Scope TemplateScope
	// Keep only templates whose `category` matches. Omit for all categories.
	Category SMSMessageCategory
	// Keep only templates available in this language, as a BCP-47 tag. Matches the template's `available_languages` entries exactly, with no fallback.
	Language string
}

SMSTemplateListParams filters the list read.

type SmsKeywordRulesCreateParams added in v0.33.0

type SmsKeywordRulesCreateParams struct {
	// What Bird does when an inbound message matches the rule. - `stop` unsubscribes the sender from further messages. - `start` resubscribes them. - `help` replies with your support information. - `info` replies with your program information. It behaves exactly as `help` does and is separate so a country whose INFO answer must differ from its HELP answer can carry both. Where Bird ships no `info` rule for a country, INFO is one of that country's `help` keywords and answers with the `help` reply. - `confirm` marks a double opt-in reply. It sends nothing today, so answer it from your own handler. - `custom` replies with the text you configured and has no other effect. Bird's built-in rules fix the operation for `stop`, `start` and `help`; you can change their reply but not what they do. The same holds for `info` in any country where Bird ships an `info` rule. This is an open enum. Accept unrecognized values.
	Operation SMSKeywordOperation
	// The country this rule applies in, as an ISO 3166-1 alpha-2 code. It matches a message two ways: one received on any of your numbers in this country, and one sent by a subscriber whose own number is in it, wherever they text you. Rules for the country a message arrives in always outrank rules for the country its sender is in; within each, your rule wins over Bird's keywords for that country. To confine a rule to one of your numbers, set `number` instead. Required for `stop`, `start` and `help`, because those replace what Bird ships for one country and a worldwide rule would replace every country's. Omit it only for `custom`, which then applies everywhere you send. Derived from `number` when you supply an E.164 number and leave this out; a short code carries no country, so a rule for one must name it.
	Country Nullable[string]
	// Which language this rule replaces, in countries where Bird ships keywords in more than one. Required there and rejected elsewhere. Listing the country's rules shows whether it applies and which languages are available.
	Language Nullable[string]
	// Narrows the rule to one number you hold, in E.164 format or as a short code. Omit to cover every number you hold in the country. The number must be one of yours and able to receive messages.
	Number Nullable[string]
	// Extra keywords to match, on top of the ones Bird already ships for this operation and country. Omit to keep Bird's keywords and change only the reply, including keywords Bird adds later. You cannot remove one of Bird's keywords, and a keyword Bird has bound to another operation cannot be reused here. Required for `custom`, which inherits none.
	Keywords []string
	// The message to send back when a keyword matches, except on a `confirm` rule, which never sends one whatever this is set to. Set it to null together with `confirmed_self_managed` to send nothing at all.
	Reply Nullable[string]
	// Set this with `reply: null` to confirm you send this reply from your own system, which switches Bird's auto-reply off for the rule. Required to send no reply, and rejected when a reply is given, so the two can never disagree.
	ConfirmedSelfManaged *bool
}

SmsKeywordRulesCreateParams is the request body for create.

type SmsKeywordRulesListParams added in v0.33.0

type SmsKeywordRulesListParams struct {
	// Keep only rules that apply in this country, as an ISO 3166-1 alpha-2 code. Omit for every country the default catalog covers, plus your own rules.
	Country string
	// Keep only the rules that apply to this number of yours, in E.164 format or as a short code, ordered the way they are applied to an inbound message.
	Number string
	// The country a sender is messaging from, as an ISO 3166-1 alpha-2 code. Use it with `number` to see what someone in that country gets, which can differ from what a local sender gets. Ignored without `number`.
	FromCountry string
	// Keep only rules for this operation. Omit for all of them.
	Operation SMSKeywordOperation
	// Keep only default rules (`system`) or only the rules you created (`workspace`). Omit for both.
	Scope SMSKeywordRuleScope
}

SmsKeywordRulesListParams filters the list read.

type SmsKeywordRulesService added in v0.33.0

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

SmsKeywordRulesService reads Bird's keyword rules and manages the workspace's own overrides of them. Reach it via Client.SmsKeywordRules.

func (*SmsKeywordRulesService) Create added in v0.33.0

Create Replace the default opt-out, opt-in, or help reply for one country, or add a `custom` keyword. A workspace rule takes precedence over the default for that country. Opt-out and opt-in keywords cannot be assigned to another operation.

Example

Create overrides Bird's default reply for one country.

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.SmsKeywordRules.Create(context.Background(), bird.SmsKeywordRulesCreateParams{
		Operation: bird.SMSKeywordOperationStop,
		Country:   bird.Value("NL"),
		Reply:     bird.Value("You are unsubscribed from MyBrand. Reply START to resume."),
	})
	if err != nil {
		log.Fatal(err)
	}
	// EffectiveKeywords is Bird's set plus any of your own.
	fmt.Println(rule.Id, *rule.EffectiveKeywords)
}

func (*SmsKeywordRulesService) Delete added in v0.33.0

Delete Delete one of your own keyword rules, which restores Bird's default for that country and operation. Bird's own rules cannot be deleted.

Example

Delete restores Bird's default for that country and operation.

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.SmsKeywordRules.Delete(context.Background(), "skr_01j9x2k3m4n5p6q7r8s9t0v1w2"); err != nil {
		log.Fatal(err)
	}
}

func (*SmsKeywordRulesService) Get added in v0.33.0

Get Read one default or workspace keyword rule. Its ID prefix identifies which kind: a workspace rule can be changed with `sms_keyword_rules.update`, a Bird default cannot.

Example

Get reads one rule, Bird's or the workspace's own.

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.SmsKeywordRules.Get(context.Background(), "skr_01j9x2k3m4n5p6q7r8s9t0v1w2")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(rule.Operation, *rule.Reply)
}

func (*SmsKeywordRulesService) List added in v0.33.0

List List the default and workspace keyword rules that apply to inbound messages, most specific first. Filter by `country`, `number`, `operation`, or `scope`. Pass `number` to see one number's rules in evaluation order. Default coverage varies by country.

Example

List shows what a reply to the workspace's numbers does.

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)
	}
	rules, err := client.SmsKeywordRules.List(context.Background(), bird.SmsKeywordRulesListParams{
		Country: "NL", // omit for every country Bird's catalogue covers, plus your own rules
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, rule := range rules.Data {
		fmt.Println(rule.Operation, rule.Keywords)
	}
}

func (*SmsKeywordRulesService) Update added in v0.33.0

Update Change one of your own keyword rules: its reply, its extra keywords, or its self-managed attestation. Bird's default rules cannot be updated; create your own for that country instead with `sms_keyword_rules.create`. Omitting `keywords` leaves the set alone, while sending an empty list clears your additions back to Bird's.

Example

Update changes a rule the workspace created.

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)
	}
	// Omitting Keywords leaves the set alone; an empty slice clears your
	// additions back to Bird's.
	rule, err := client.SmsKeywordRules.Update(context.Background(), "skr_01j9x2k3m4n5p6q7r8s9t0v1w2", bird.SmsKeywordRulesUpdateParams{
		Reply: bird.Value("You are unsubscribed. Reply START to resume."),
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(*rule.Reply)
}

type SmsKeywordRulesUpdateParams added in v0.33.0

type SmsKeywordRulesUpdateParams struct {
	// Replaces the extra keywords this rule matches, on top of the ones Bird ships. Send an empty array to keep Bird's keywords only. Omit to leave the current ones unchanged.
	Keywords []string
	// Replaces the message sent back when a keyword matches, except on a `confirm` rule, which never sends one whatever this is set to. Set it to null together with `confirmed_self_managed` to switch the auto-reply off. Omit to leave it unchanged.
	Reply Nullable[string]
	// Set this with `reply: null` to confirm you send this reply from your own system. Required to switch the auto-reply off, and rejected when a reply is given.
	ConfirmedSelfManaged *bool
}

SmsKeywordRulesUpdateParams is the request body for update.

type SmsListEventsParams added in v0.33.0

type SmsListEventsParams struct {
	// Filter by event type, such as `sms.delivered` or `sms.failed`.
	Type string
}

SmsListEventsParams filters the list_events read.

type SmsListParams added in v0.3.0

type SmsListParams struct {
	// Maximum number of items to return per page.
	Limit int
	// Limits the response to resources created at or after this timestamp. Combine it with `created_before` to select a time window. Use an RFC 3339 timestamp with a timezone offset.
	CreatedAfter time.Time
	// Limits the response to resources created before this timestamp. Combine it with `created_after` to select a time window. Use an RFC 3339 timestamp with a timezone offset.
	CreatedBefore time.Time
	// Filter by direction. Omit for both.
	Direction MessageDirection
	// Keep only messages whose current `status` matches; repeat the parameter to match any of several. One of `scheduled`, `accepted`, `sent`, `delivered`, `undelivered`, `failed`, `rejected`, `canceled`, `expired`, or `received`.
	Status []string
	// Keep only messages whose failure reason (`last_error.code`) matches; repeat the parameter to match any of several. One of `invalid_destination`, `unreachable`, `blocked_by_carrier`, `blocked_by_recipient`, `landline_unreachable`, `content_rejected`, `sender_unregistered`, `recipient_opted_out`, `provider_unavailable`, `insufficient_balance`, or `unknown`.
	ErrorCode []string
	// Filter by category.
	Category SMSMessageCategory
	// Filter by recipient phone number (E.164 exact match).
	To string
	// Filter by sender (E.164, alphanumeric, or short code; exact match).
	From string
	// Filter by tag. Accepts `name` to match any record carrying that tag name, or `name:value` to match a specific tag pair (for example `category:welcome`). Repeat the parameter to add more tags. A record must match every tag listed to be returned.
	Tag []string
}

SmsListParams filters the 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         // required with Text; omit on a template send
	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 slug (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
	// SmartEncoding replaces characters outside the GSM-7 alphabet with their closest
	// equivalent, which often lowers the segment count and the cost. A pointer because
	// false is a real value the send carries: nil omits the option and takes Bird's
	// default (off), &false records the choice explicitly.
	SmartEncoding *bool
}

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

type SmsService added in v0.16.0

type SmsService struct {

	// Stats reads aggregate statistics over the workspace's SMS traffic.
	Stats *SmsStatsService
	// contains filtered or unexported fields
}

SmsService sends free-text or stored-template SMS messages and reads them back. Reach it through Client.Sms.

func (*SmsService) Get added in v0.16.0

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

Get Get one SMS message by ID: its current delivery status, segment breakdown, cost, and failure detail if it failed.

func (*SmsService) List added in v0.16.0

List List SMS messages, newest first, as a cursor page (`data`, `next_cursor`). Pass `next_cursor` back as `starting_after` to fetch the next page. Filter by direction, status, category, recipient, sender, or tag. Range over it; the second value is non-nil only on the iteration where a fetch failed.

func (*SmsService) ListEvents added in v0.33.0

func (s *SmsService) ListEvents(ctx context.Context, messageId string, params SmsListEventsParams, opts ...option.RequestOption) (*SMSEventList, error)

ListEvents The lifecycle event timeline for one SMS, oldest first: what happened to it and when. Filter with `type` (for example `sms.delivered`) to keep one kind of event. Use `sms.get` for the message's current state and `sms.list` to find its ID.

Example

ListEvents returns the lifecycle timeline for one message.

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.Sms.ListEvents(context.Background(), "sms_01j9x2k3m4n5p6q7r8s9t0v1w2", bird.SmsListEventsParams{})
	if err != nil {
		log.Fatal(err)
	}
	for _, e := range events.Data {
		fmt.Println(*e.Type, *e.OccurredAt)
	}
}

func (*SmsService) ListPage added in v0.16.0

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

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

func (*SmsService) Send added in v0.16.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{
		From:     "+15557654321",
		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.16.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.

Example

Send up to 100 independent messages in one call. Acceptance is all-or-nothing: every message is validated before any of them queue.

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.Sms.SendBatch(context.Background(), bird.SmsSendBatchParams{
		Messages: []bird.SmsSendParams{
			{
				From: "+15557654321", To: "+15551111111",
				Text: "Hi Alice!", Category: bird.SMSCategoryMarketing,
			},
			{
				From: "+15557654321", To: "+15552222222",
				Text: "Hi Bob!", Category: bird.SMSCategoryMarketing,
			},
		},
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, msg := range batch.Data {
		fmt.Println(msg.Id, *msg.Status)
	}
}

type SmsStatsByCarrierParams added in v0.33.0

type SmsStatsByCarrierParams 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 keep the 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Metric to rank rows by, applied descending. Any lifecycle count or derived rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `accepted`.
	Sort SMSStatsSortMetric
	// Maximum number of carrier rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also carries a `trend` array: a short per-bucket lifecycle-count series for that row 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.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain StatsTrendGrain
}

SmsStatsByCarrierParams filters the by_carrier read.

type SmsStatsByCategoryParams added in v0.33.0

type SmsStatsByCategoryParams 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 keep the 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Metric to rank rows by, applied descending. Any lifecycle count or derived rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `accepted`.
	Sort SMSStatsSortMetric
	// 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 lifecycle-count series for that row 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.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain StatsTrendGrain
}

SmsStatsByCategoryParams filters the by_category read.

type SmsStatsByCountryParams added in v0.33.0

type SmsStatsByCountryParams 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 keep the 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Metric to rank rows by, applied descending. Any lifecycle count or derived rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `accepted`.
	Sort SMSStatsSortMetric
	// Maximum number of country rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also carries a `trend` array: a short per-bucket lifecycle-count series for that row 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.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain StatsTrendGrain
}

SmsStatsByCountryParams filters the by_country read.

type SmsStatsByErrorCodeParams added in v0.33.0

type SmsStatsByErrorCodeParams 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 keep the 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Metric to rank rows by, applied descending. Defaults to `failed`. Only lifecycle counts are sortable; this breakdown has no rates.
	Sort SMSStatsLifecycleSortMetric
	// Maximum number of error-code rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also carries a `trend` array: a short per-bucket lifecycle-count series for that row 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.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain StatsTrendGrain
}

SmsStatsByErrorCodeParams filters the by_error_code read.

type SmsStatsByOriginatorParams added in v0.33.0

type SmsStatsByOriginatorParams 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 keep the 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Metric to rank rows by, applied descending. Any lifecycle count or derived rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `accepted`.
	Sort SMSStatsSortMetric
	// Maximum number of originator rows to return, ranked by the `sort` field descending.
	Limit int
	// When true, each row also carries a `trend` array: a short per-bucket lifecycle-count series for that row 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.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain StatsTrendGrain
}

SmsStatsByOriginatorParams filters the by_originator read.

type SmsStatsByStatusParams added in v0.33.0

type SmsStatsByStatusParams 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
}

SmsStatsByStatusParams filters the by_status read.

type SmsStatsByTagParams added in v0.33.0

type SmsStatsByTagParams 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 keep the 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Metric to rank rows by, applied descending. Any lifecycle count or derived rate in the response may be used; rows whose rate is undefined (zero denominator) sort last. Defaults to `accepted`.
	Sort SMSStatsSortMetric
	// 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 lifecycle-count series for that row 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.
	IncludeTrend bool
	// Bucket grain for the `trend` series. Has no effect unless `include_trend=true`.
	TrendGrain StatsTrendGrain
}

SmsStatsByTagParams filters the by_tag read.

type SmsStatsDailyParams added in v0.33.0

type SmsStatsDailyParams 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Restrict the statistics to a single originator (the sender address messages were sent from). Mutually exclusive with the other dimension filters (`country`, `category`, `carrier`); only one may be set per request. Matches the message `from`.
	Originator string
	// Restrict the statistics to a single destination country, as an ISO 3166-1 alpha-2 code. Mutually exclusive with the other dimension filters (`originator`, `category`, `carrier`); only one may be set per request.
	Country string
	// Restrict the statistics to a single category. Mutually exclusive with the other dimension filters (`originator`, `country`, `carrier`); only one may be set per request.
	Category string
	// Restrict the statistics to a single delivery carrier. Mutually exclusive with the other dimension filters (`originator`, `country`, `category`); only one may be set per request.
	Carrier string
}

SmsStatsDailyParams filters the daily read.

type SmsStatsHourlyParams added in v0.33.0

type SmsStatsHourlyParams struct {
	// Start of the window (ISO 8601 instant), rounded down to the start of its hour and included. The boundary uses the local hour when `timezone` is set and the UTC hour otherwise. When `timezone` is set, a numeric UTC offset such as `+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 and included. The boundary uses the local hour when `timezone` is set and the UTC hour otherwise, so both bounds are inclusive. When `timezone` is set, a numeric UTC offset is rejected; use a `Z` (UTC) instant. Defaults to the current hour when omitted. The window may not exceed 30 days (720 hours).
	To time.Time
	// IANA timezone identifier used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Restrict the statistics to a single originator (the sender address messages were sent from). Mutually exclusive with the other dimension filters (`country`, `category`, `carrier`); only one may be set per request. Matches the message `from`.
	Originator string
	// Restrict the statistics to a single destination country, as an ISO 3166-1 alpha-2 code. Mutually exclusive with the other dimension filters (`originator`, `category`, `carrier`); only one may be set per request.
	Country string
	// Restrict the statistics to a single category. Mutually exclusive with the other dimension filters (`originator`, `country`, `carrier`); only one may be set per request.
	Category string
	// Restrict the statistics to a single delivery carrier. Mutually exclusive with the other dimension filters (`originator`, `country`, `category`); only one may be set per request.
	Carrier string
}

SmsStatsHourlyParams filters the hourly read.

type SmsStatsInboundByCountryParams added in v0.33.0

type SmsStatsInboundByCountryParams 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Maximum rows to return, ranked by volume. Defaults to 50; the maximum is 200, and asking for more returns 422 rather than silently returning fewer.
	Limit int
}

SmsStatsInboundByCountryParams filters the by_country read.

type SmsStatsInboundByNumberParams added in v0.33.0

type SmsStatsInboundByNumberParams 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Maximum rows to return, ranked by volume. Defaults to 50; the maximum is 200, and asking for more returns 422 rather than silently returning fewer.
	Limit int
}

SmsStatsInboundByNumberParams filters the by_number read.

type SmsStatsInboundByOperatorParams added in v0.33.0

type SmsStatsInboundByOperatorParams 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Maximum rows to return, ranked by volume. Defaults to 50; the maximum is 200, and asking for more returns 422 rather than silently returning fewer.
	Limit int
}

SmsStatsInboundByOperatorParams filters the by_operator read.

type SmsStatsInboundDailyParams added in v0.33.0

type SmsStatsInboundDailyParams 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 used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
}

SmsStatsInboundDailyParams filters the daily read.

type SmsStatsInboundHourlyParams added in v0.33.0

type SmsStatsInboundHourlyParams struct {
	// Start of the window (inclusive), an RFC 3339 instant truncated to the hour. Defaults to 7 days (168 hours) before `to` when omitted.
	From time.Time
	// End of the window (inclusive), an RFC 3339 instant truncated to the hour. Defaults to the current hour when omitted. Window may not exceed 720 hours. A numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; pass a calendar day or a `Z` instant instead.
	To time.Time
	// IANA timezone identifier used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
}

SmsStatsInboundHourlyParams filters the hourly read.

type SmsStatsInboundService added in v0.33.0

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

SmsStatsInboundService reads how many messages the workspace's own numbers received. Reach it via Client.Sms.Stats.Inbound.

func (*SmsStatsInboundService) ByCountry added in v0.33.0

ByCountry Messages your numbers received, grouped by the country of the receiving number.

Example

ByCountry groups received messages by where the sender messaged from.

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)
	}
	stats, err := client.Sms.Stats.Inbound.ByCountry(context.Background(), bird.SmsStatsInboundByCountryParams{
		From: time.Now().AddDate(0, -1, 0),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, row := range *stats.Data {
		fmt.Println(*row.Country, *row.Received)
	}
}

func (*SmsStatsInboundService) ByNumber added in v0.33.0

ByNumber How many messages each of your numbers received, which is the view that shows whether a campaign's reply traffic is landing on the number you expect.

Example

ByNumber shows which of the workspace's numbers took the traffic.

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)
	}
	stats, err := client.Sms.Stats.Inbound.ByNumber(context.Background(), bird.SmsStatsInboundByNumberParams{
		From: time.Now().AddDate(0, -1, 0),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, row := range *stats.Data {
		fmt.Println(*row.Number, *row.Received)
	}
}

func (*SmsStatsInboundService) ByOperator added in v0.33.0

ByOperator Messages your numbers received, grouped by the sender's mobile operator. Messages whose operator the carrier did not report are excluded, so these rows can sum to less than `sms.stats.inbound.summary` for the same period.

Example

ByOperator groups received messages by the sender's mobile operator.

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)
	}
	stats, err := client.Sms.Stats.Inbound.ByOperator(context.Background(), bird.SmsStatsInboundByOperatorParams{
		From: time.Now().AddDate(0, -1, 0),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, row := range *stats.Data {
		// Messages whose operator the carrier did not report are excluded, so
		// these rows can sum to less than the inbound summary for the same period.
		fmt.Println(*row.MccMnc, *row.Received)
	}
}

func (*SmsStatsInboundService) Daily added in v0.33.0

Daily Messages your numbers received, one row per calendar day. Set `timezone` to get local calendar days instead of UTC.

Example

Daily returns received-message counts, one row per calendar day.

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.Sms.Stats.Inbound.Daily(context.Background(), bird.SmsStatsInboundDailyParams{
		From: time.Now().AddDate(0, 0, -7),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, point := range *series.Data {
		fmt.Println(*point.Bucket, *point.Received)
	}
}

func (*SmsStatsInboundService) Hourly added in v0.33.0

Hourly Messages your numbers received, one row per hour, for inspecting inbound volume inside a single day.

Example

Hourly returns received-message counts, one row per hour.

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.Sms.Stats.Inbound.Hourly(context.Background(), bird.SmsStatsInboundHourlyParams{
		From: time.Now().Add(-24 * time.Hour),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, point := range *series.Data {
		fmt.Println(*point.Bucket, *point.Received)
	}
}

func (*SmsStatsInboundService) Summary added in v0.33.0

Summary Total messages your numbers received over a period. For a breakdown use `sms.stats.inbound.by_country`, `sms.stats.inbound.by_operator`, or `sms.stats.inbound.by_number`.

Example

Summary returns how many messages the workspace's numbers received.

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.Sms.Stats.Inbound.Summary(context.Background(), bird.SmsStatsInboundSummaryParams{
		From: "2026-05-01",
		To:   "2026-05-31",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(*summary.Received)
}

type SmsStatsInboundSummaryParams added in v0.33.0

type SmsStatsInboundSummaryParams struct {
	// Inclusive start of the window, either a calendar day (YYYY-MM-DD) or an RFC 3339 instant rounded down to the hour. The form you use selects the grain the total is resolved at. Interpreted in `timezone`, or in UTC when `timezone` is omitted. Must use the same form as `to`. A numeric UTC offset (for example `+05:45`) is rejected when `timezone` is set; pass a calendar day or a `Z` instant instead. Defaults to 30 days before `to` for day windows, or 168 hours before `to` for hour windows.
	From string
	// Inclusive end of the window, in the same form as `from`. Defaults to today, or the current hour for an hour window. A day window may not exceed 365 days and an hour window 720 hours.
	To string
	// IANA timezone identifier used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Set to `previous_period` to include the received-message count for the immediately preceding window of equal length. The response also includes the change between the two, so you can show "+X% vs last period" without a second request.
	Compare StatsComparePeriod
}

SmsStatsInboundSummaryParams filters the summary read.

type SmsStatsService added in v0.33.0

type SmsStatsService struct {

	// Inbound reads the same shapes for messages the workspace's numbers received.
	Inbound *SmsStatsInboundService
	// contains filtered or unexported fields
}

SmsStatsService reads aggregated statistics over the workspace's own SMS traffic. Reach it via Client.Sms.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 (*SmsStatsService) ByCarrier added in v0.33.0

ByCarrier SMS delivery and latency stats grouped by the carrier that handled the message, ranked by the `sort` metric (default `accepted`) and capped by `limit` (default 50, maximum 200). Use it to compare delivery performance across carriers.

Example

ByCarrier compares delivery across the carriers that handled the traffic.

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)
	}
	stats, err := client.Sms.Stats.ByCarrier(context.Background(), bird.SmsStatsByCarrierParams{
		From: time.Now().AddDate(0, -1, 0),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, row := range *stats.Data {
		fmt.Println(*row.Carrier, *row.Delivery.Delivered)
	}
}

func (*SmsStatsService) ByCategory added in v0.33.0

ByCategory SMS delivery and latency stats grouped by the category you sent under, ranked by the `sort` metric (default `accepted`) and capped by `limit` (default 50, maximum 200).

Example

ByCategory splits the window by the category messages were sent under.

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)
	}
	stats, err := client.Sms.Stats.ByCategory(context.Background(), bird.SmsStatsByCategoryParams{
		From: time.Now().AddDate(0, -1, 0),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, row := range *stats.Data {
		fmt.Println(*row.Category, *row.Delivery.Accepted)
	}
}

func (*SmsStatsService) ByCountry added in v0.33.0

ByCountry SMS delivery and latency stats grouped by destination country, ranked by the `sort` metric (default `accepted`) and capped by `limit` (default 50, maximum 200). Use it to find where delivery is worst before drilling into `sms.stats.by_error_code`.

Example

ByCountry ranks destination countries by the sort metric.

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)
	}
	stats, err := client.Sms.Stats.ByCountry(context.Background(), bird.SmsStatsByCountryParams{
		From: time.Now().AddDate(0, -1, 0),
		To:   time.Now(),
		Sort: "delivery_rate", // worst delivery first is Sort plus a read of the tail
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, row := range *stats.Data {
		fmt.Println(*row.Country, *row.Delivery.Accepted, *row.Delivery.DeliveryRate)
	}
}

func (*SmsStatsService) ByErrorCode added in v0.33.0

ByErrorCode SMS stats grouped by our normalized failure reason, which answers which reasons are driving your failures. The grouping key is the same value as the `error_code` filter on `sms.list`, so a row joins straight to the messages behind it. Ranked by the `sort` metric (default `failed`) and capped by `limit`.

Example

ByErrorCode ranks the failure reasons behind undelivered traffic.

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)
	}
	stats, err := client.Sms.Stats.ByErrorCode(context.Background(), bird.SmsStatsByErrorCodeParams{
		From: time.Now().AddDate(0, -1, 0),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, row := range *stats.Data {
		// The same value as the error_code filter on Sms.List, so a row joins to its messages.
		fmt.Println(*row.ErrorCode, *row.Delivery.Failed)
	}
}

func (*SmsStatsService) ByOriginator added in v0.33.0

ByOriginator SMS delivery and latency stats grouped by originator, the sender address messages went out from, ranked by the `sort` metric (default `accepted`) and capped by `limit` (default 50, maximum 200). Use it to compare how your senders perform.

Example

ByOriginator compares how each sender address performs.

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)
	}
	stats, err := client.Sms.Stats.ByOriginator(context.Background(), bird.SmsStatsByOriginatorParams{
		From: time.Now().AddDate(0, -1, 0),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, row := range *stats.Data {
		fmt.Println(*row.Originator, *row.Delivery.DeliveryRate)
	}
}

func (*SmsStatsService) ByStatus added in v0.33.0

ByStatus How many messages ended the period in each lifecycle status: accepted, sent, delivered, undelivered, failed, rejected, expired, ordered by count. The "where did my messages end up" view, suitable for a status-distribution chart.

Example

ByStatus shows where the window's messages ended up.

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)
	}
	stats, err := client.Sms.Stats.ByStatus(context.Background(), bird.SmsStatsByStatusParams{
		From: time.Now().AddDate(0, -1, 0),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, row := range *stats.Data {
		fmt.Println(*row.Status, *row.Count)
	}
}

func (*SmsStatsService) ByTag added in v0.33.0

ByTag SMS delivery and latency stats grouped by tag (`name:value`), ranked by the `sort` metric (default `accepted`) and capped by `limit` (default 50, maximum 200). Only tagged messages appear, and one carrying several tags counts once under each, so rows do not sum to the period total.

Example

ByTag ranks the campaigns and segments sends are tagged with.

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)
	}
	stats, err := client.Sms.Stats.ByTag(context.Background(), bird.SmsStatsByTagParams{
		From: time.Now().AddDate(0, -1, 0),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, row := range *stats.Data {
		// A message carrying several tags counts once under each, so rows do not
		// sum to the period total.
		fmt.Println(*row.Tag, *row.Delivery.Accepted)
	}
}

func (*SmsStatsService) Daily added in v0.33.0

Daily One row of SMS lifecycle counts per calendar day, for charts and trend lines. The window is at most 365 days; set `timezone` to get local calendar days instead of UTC. Rates and latency percentiles are whole-window figures, so read those from `sms.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.Sms.Stats.Daily(context.Background(), bird.SmsStatsDailyParams{
		From: time.Now().AddDate(0, 0, -7),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, point := range *series.Data {
		fmt.Println(*point.Bucket, *point.Delivery.Accepted)
	}
}

func (*SmsStatsService) Hourly added in v0.33.0

Hourly One row of SMS lifecycle counts per hour, for inspecting send rate and deliverability inside a single day. The window is at most 30 days (720 rows) and both bounds round down to the hour. For longer ranges use `sms.stats.daily`.

Example

Hourly returns one row per hour, for a window of at most 30 days.

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.Sms.Stats.Hourly(context.Background(), bird.SmsStatsHourlyParams{
		From: time.Now().Add(-24 * time.Hour),
		To:   time.Now(),
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, point := range *series.Data {
		fmt.Println(*point.Bucket, *point.Delivery.Accepted)
	}
}

func (*SmsStatsService) Summary added in v0.33.0

Summary Aggregate SMS KPIs for one period: accepted, sent, delivered, undelivered, failed, rejected and expired counts, the derived delivery and failure rates, and latency percentiles. The `from` and `to` values are both YYYY-MM-DD days or both RFC 3339 instants (hour grain). Add `compare=previous_period` for deltas against the preceding window. For a per-day or per-hour series use `sms.stats.daily` or `sms.stats.hourly`.

Example

Summary returns the delivery 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.Sms.Stats.Summary(context.Background(), bird.SmsStatsSummaryParams{
		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.Delivery.Accepted, *summary.Delivery.DeliveryRate)
}

type SmsStatsSummaryParams added in v0.33.0

type SmsStatsSummaryParams struct {
	// Inclusive start of the window: a calendar day (YYYY-MM-DD) or an RFC 3339 instant rounded down to the hour. The `timezone` parameter makes a calendar day local and rounds an instant down to the local hour. Omit `timezone` to use UTC. When `timezone` is set, a numeric UTC offset such as `+05:45` is rejected; use a calendar day or a `Z` (UTC) instant. This value must use the same form as `to`. When omitted, it defaults to 30 days before `to` for day windows or 168 hours (7 days) before `to` for hour windows.
	From string
	// Inclusive end of the window: a calendar day (YYYY-MM-DD) or an RFC 3339 instant rounded down to the hour. The `timezone` parameter makes a calendar day local and rounds an instant down to the local hour. Omit `timezone` to use UTC. When `timezone` is set, a numeric UTC offset is rejected; use a calendar day or a `Z` (UTC) instant. This value must use the same form as `from`. When omitted, it defaults to today for day windows or the current hour for hour windows in that timezone. Day windows may not exceed 365 days; hour windows may not exceed 720 hours (30 days).
	To string
	// IANA timezone identifier used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.
	Timezone string
	// Restrict the statistics to a single originator (the sender address messages were sent from). Mutually exclusive with the other dimension filters (`country`, `category`, `carrier`); only one may be set per request. Matches the message `from`.
	Originator string
	// Restrict the statistics to a single destination country, as an ISO 3166-1 alpha-2 code. Mutually exclusive with the other dimension filters (`originator`, `category`, `carrier`); only one may be set per request.
	Country string
	// Restrict the statistics to a single category. Mutually exclusive with the other dimension filters (`originator`, `country`, `carrier`); only one may be set per request.
	Category string
	// Restrict the statistics to a single delivery carrier. Mutually exclusive with the other dimension filters (`originator`, `country`, `category`); only one may be set per request.
	Carrier 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 StatsComparePeriod
}

SmsStatsSummaryParams filters the summary read.

type SmsSuppressionsAddParams added in v0.33.0

type SmsSuppressionsAddParams struct {
	// The subscriber to stop messaging, in E.164 format.
	Destination string
	// The sender to stop. Your other senders keep reaching this subscriber, so stopping every one of them means one call per sender.
	Originator string
}

SmsSuppressionsAddParams is the request body for add.

type SmsSuppressionsListParams added in v0.33.0

type SmsSuppressionsListParams struct {
	// Return only suppressions for this exact subscriber number in E.164 form. Prefix matching is unsupported.
	Destination string
	// Return only suppressions covering this sender.
	Originator string
	// Return only suppressions with this reason: - `keyword_stop`: The subscriber texted a stop keyword to the sender. - `carrier_opted_out`: Their carrier reported the opt-out. - `manual`: Added through the API or dashboard.
	Reason SMSSuppressionReasonFilter
	// Maximum number of items to return per page.
	Limit int
}

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

type SmsSuppressionsService added in v0.33.0

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

SmsSuppressionsService reads and edits who an SMS sender may not message. Reach it via Client.SmsSuppressions. A suppression covers one sender and one subscriber, so the same number can appear under several of them.

func (*SmsSuppressionsService) Add added in v0.33.0

Add Stop one of your senders from messaging one subscriber. Covers that sender only; your other senders keep reaching them.

Example

Add stops one sender from messaging one subscriber.

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)
	}
	// A suppression covers one sender and one subscriber, so stopping every
	// sender means one call per sender.
	suppression, err := client.SmsSuppressions.Add(context.Background(), bird.SmsSuppressionsAddParams{
		Destination: "+15550001234",
		Originator:  "+15557654321",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(suppression.Id)
}

func (*SmsSuppressionsService) Get added in v0.33.0

func (s *SmsSuppressionsService) Get(ctx context.Context, suppressionId string, opts ...option.RequestOption) (*SMSSuppression, error)

Get Read one SMS suppression: the sender and subscriber it covers, why messages are stopped, what it blocks, and whether it is still in force. To check whether you may message someone, filter `sms_suppressions.list` by their number instead.

Example

Get reads one suppression 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)
	}
	suppression, err := client.SmsSuppressions.Get(context.Background(), "sup_01j9x2k3m4n5p6q7r8s9t0v1w2")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(suppression.Originator, suppression.Destination, *suppression.Blocking)
}

func (*SmsSuppressionsService) List added in v0.33.0

List List the workspace's SMS suppressions (sender-and-subscriber pairs blocked from delivery) as a cursor page. Range over it; the second value is non-nil only on the iteration where a fetch failed.

Example

List iterates every suppression currently stopping the workspace's messages.

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 suppression, err := range client.SmsSuppressions.List(context.Background(), bird.SmsSuppressionsListParams{}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(suppression.Originator, suppression.Destination, *suppression.Reason)
	}
}

func (*SmsSuppressionsService) ListPage added in v0.33.0

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

func (*SmsSuppressionsService) Remove added in v0.33.0

func (s *SmsSuppressionsService) Remove(ctx context.Context, suppressionId string, opts ...option.RequestOption) error

Remove End a manual SMS suppression, letting that sender message that subscriber again. Only reason `manual` can be ended this way: a subscriber's own stop keyword and a carrier's opt-out are refused.

Example

Remove ends a manual suppression.

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)
	}
	// Only a `manual` suppression can be ended: a subscriber's own stop keyword
	// and a carrier's opt-out are refused.
	if err := client.SmsSuppressions.Remove(context.Background(), "sup_01j9x2k3m4n5p6q7r8s9t0v1w2"); err != nil {
		log.Fatal(err)
	}
}

type SmsTemplatesService added in v0.16.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.16.0

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

Get Get one SMS template by its slug or ID, including its body and the variables it expects. Fetch it before `sms.send` to see which parameter keys a template send requires.

Example

Read one SMS template by its slug (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.16.0

List List the SMS templates available to your workspace, including our built-in templates. Filter by scope, category, or language. The catalog is small and returned in full; this list is not paginated. Use `sms_templates.get` to read one template's variables before sending with it.

Example

List the SMS templates available to the workspace. The catalogue is small, returned in full, and 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: "system",
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, tpl := range list.Data {
		fmt.Println(tpl.Id, *tpl.Slug)
	}
}

type StatsComparePeriod added in v0.33.0

type StatsComparePeriod = oapi.StatsComparePeriod

StatsComparePeriod asks a stats summary for the preceding window too. Not SMS-specific: every channel's summary read takes the same one value, so the four still declaring it inline can $ref this instead.

type StatsTrendGrain added in v0.16.0

type StatsTrendGrain = oapi.StatsTrendGrain

StatsTrendGrain is the bucket grain of a stats trend series.

type Tag added in v0.16.0

type Tag = oapi.Tag

type TemplateLanguageStatus added in v0.32.0

type TemplateLanguageStatus = oapi.TemplateLanguageStatus

TemplateLanguageStatus is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the TemplateLanguageStatus* constants with a default branch rather than treating the set as closed.

type TemplateScope added in v0.16.0

type TemplateScope = oapi.TemplateScope

TemplateScope distinguishes Bird's built-in templates from a workspace's own.

type TemplateStatus added in v0.32.0

type TemplateStatus = oapi.TemplateStatus

TemplateStatus is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the TemplateStatus* constants with a default branch rather than treating the set as closed.

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 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 VerificationAttemptFailureReason added in v0.19.0

type VerificationAttemptFailureReason = oapi.VerificationAttemptFailureReason

VerificationAttemptFailureReason is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the VerificationAttemptFailureReason* constants with a default branch rather than treating the set as closed.

type VerificationChannel added in v0.19.0

type VerificationChannel = oapi.VerificationChannel

VerificationChannel is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the VerificationChannel* constants with a default branch rather than treating the set as closed.

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 VerificationOptions added in v0.16.0

type VerificationOptions = oapi.VerificationOptions

type VerificationTerminalReason added in v0.19.0

type VerificationTerminalReason = oapi.VerificationTerminalReason

VerificationTerminalReason is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the VerificationTerminalReason* constants with a default branch rather than treating the set as closed.

type VerificationTo added in v0.16.0

type VerificationTo = oapi.VerificationTo

type VerifyService added in v0.7.0

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

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

type VerifyVerificationsCheckParams added in v0.16.0

type VerifyVerificationsCheckParams struct {
	// The recipient to verify. Provide an `email`, a `phone_number`, or both; at least one is required. The addresses also identify the verification: a check must supply exactly the set used on the create call, so a verification created with both addresses is not found by either one alone.
	To VerificationTo
	// The passcode the recipient received. Passcodes are numeric; submit the digits exactly as delivered. An incorrect value is a normal `200` outcome with `success: false`. It does not return an error.
	Code string
}

VerifyVerificationsCheckParams is the request body for check.

type VerifyVerificationsCreateParams added in v0.16.0

type VerifyVerificationsCreateParams struct {
	// The recipient to verify. Provide an `email`, a `phone_number`, or both; at least one is required. The addresses also identify the verification: a check must supply exactly the set used on the create call, so a verification created with both addresses is not found by either one alone.
	To VerificationTo
	// Per-request overrides applied to this verification only.
	Options *VerificationOptions
	// Optional key/value pairs to attach to the verification, for example a correlation id. Returned on the verification.
	Metadata map[string]any
}

VerifyVerificationsCreateParams is the request body for create.

type VerifyVerificationsNextChannelParams added in v0.27.0

type VerifyVerificationsNextChannelParams struct {
	// The recipient to verify. Provide an `email`, a `phone_number`, or both; at least one is required. The addresses also identify the verification: a check must supply exactly the set used on the create call, so a verification created with both addresses is not found by either one alone.
	To VerificationTo
}

VerifyVerificationsNextChannelParams is the request body for next_channel.

type VerifyVerificationsService added in v0.16.0

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

VerifyVerificationsService starts a verification, sending a one-time passcode, and checks the passcode a recipient submits.

func (*VerifyVerificationsService) Check added in v0.16.0

Check Check a passcode a recipient submitted. Identify the verification by the same `to` recipient used to start it; no verification ID is needed. A wrong or expired code returns HTTP 200 with `success: false` and a `reason` (for example `incorrect_code` or `expired`). A verification that has already reached a final state is no longer checkable and returns 404, as does a missing verification; malformed input or rate limiting is also an error status.

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.VerifyVerificationsCheckParams{
		To:   bird.VerificationTo{PhoneNumber: bird.String("+15551234567")},
		Code: "123456",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(*result.Success)
}

func (*VerifyVerificationsService) Create added in v0.16.0

Create Start a verification and send a one-time passcode to the email address, phone number, or both in `to`. Delivery uses one planned channel at a time and fails over when necessary. Calling again for the same recipient reuses the verification in progress and sends after the resend cooldown. The passcode is never returned; submit the recipient's code with `verify.verifications.check`. SMS, WhatsApp, and Telegram delivery draw on the workspace's balance.

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.VerifyVerificationsCreateParams{
		To: bird.VerificationTo{PhoneNumber: bird.String("+15551234567")},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(verification.Id, *verification.Status)
}

func (*VerifyVerificationsService) NextChannel added in v0.27.0

NextChannel Advance an in-progress verification to its next channel and send a fresh passcode. Identify it with the same `to` recipient used to create it; no verification ID is required. This bypasses the resend cooldown, and earlier passcodes remain valid. `last_channel` identifies the most recent completed send. `422 NoNextChannel` means the plan is exhausted; create the verification again to resend on the current channel.

Example

Send a fresh passcode on the next channel when the recipient never got the first.

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.NextChannel(context.Background(), bird.VerifyVerificationsNextChannelParams{
		To: bird.VerificationTo{PhoneNumber: bird.String("+15551234567")},
	})
	if err != nil {
		log.Fatal(err)
	}
	if verification.LastChannel != nil {
		fmt.Println(*verification.LastChannel)
	}
}

type VoiceCall added in v0.27.0

type VoiceCall = oapi.VoiceCall

VoiceCall is one call-detail record, in flight or settled; VoiceCallList is a page of them.

type VoiceCallDirection added in v0.27.0

type VoiceCallDirection = oapi.VoiceCallDirection

VoiceCallStatus is how a call ended, or that it is still ringing or connected. VoiceCallDirection is which way the call was placed.

type VoiceCallList added in v0.27.0

type VoiceCallList = oapi.VoiceCallList

VoiceCall is one call-detail record, in flight or settled; VoiceCallList is a page of them.

type VoiceCallStatus added in v0.27.0

type VoiceCallStatus = oapi.VoiceCallStatus

VoiceCallStatus is how a call ended, or that it is still ringing or connected. VoiceCallDirection is which way the call was placed.

type VoiceListParams added in v0.27.0

type VoiceListParams struct {
	// Return only calls in this direction.
	Direction VoiceCallDirection
	// Return only calls with one of these statuses, comma-separated. In-flight and final statuses may be combined freely.
	Status []VoiceCallStatus
	// Return only calls belonging to this session, which is how the legs of one multi-party or transferred call are correlated.
	SessionID string
	// Return only calls carried by this SIP trunk.
	SipTrunkID string
	// Return only calls placed from this calling party number, matched as a whole number rather than as a fragment. Give it in international form: `+14155551234`, `14155551234`, and `0014155551234` all select the same calls. A number given without a country code is read as an international one, so give the country code to be sure of what you are matching. Use `number` instead to match part of a number, or either side of the call.
	From string
	// Return only calls placed to this called party number, matched as a whole number rather than as a fragment. Give it in international form: `+16505559876`, `16505559876`, and `0016505559876` all select the same calls. A number given without a country code is read as an international one, so give the country code to be sure of what you are matching. Use `number` instead to match part of a number, or either side of the call.
	To string
	// Return only calls where the calling or called number contains this value. Matches a partial number, so a country or area-code prefix returns every call to or from it. Combines with `from`/`to`, which match one side exactly.
	Number string
	// Filter by tag. Accepts `name` to match any record carrying that tag name, or `name:value` to match a specific tag pair (for example `category:welcome`). Repeat the parameter to add more tags. A record must match every tag listed to be returned.
	Tag []string
	// Return only calls that started at or after this instant, inclusive. RFC 3339 timestamp.
	StartedAfter time.Time
	// Return only calls that started at or before this instant, inclusive. RFC 3339 timestamp.
	StartedBefore time.Time
	// Maximum number of items to return per page.
	Limit int
}

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

type VoiceService added in v0.27.0

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

VoiceService reads a workspace's call log — the record Bird writes for every call, in flight or settled. Reach it via Client.Voice. Calls are placed by the customer's own SIP equipment rather than through the API, so this is a read surface with no send verb.

func (*VoiceService) Get added in v0.27.0

func (s *VoiceService) Get(ctx context.Context, callId string, opts ...option.RequestOption) (*VoiceCall, error)

Get Fetch one call by ID, at any point in its lifecycle. A call still ringing or connected carries no economics yet: `duration_ms`, `billable_ms`, `ended_at`, and `cost` are null until it ends, and the same ID then returns the settled record. Poll here to watch one known call; use `voice.list` to find calls in the first place. When a call was refused, `rejection_reason` names the gate that turned it away.

Example

Get returns one call at any point in its lifecycle, settled or still up.

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)
	}
	call, err := client.Voice.Get(context.Background(), "vcl_01k0p3v9wera3v6q6xw3e9y2mh")
	if err != nil {
		log.Fatal(err)
	}
	// A call still ringing or connected carries no economics yet.
	fmt.Println(call.Status, call.DurationMs)
}

func (*VoiceService) List added in v0.27.0

List List the workspace's calls, newest first. Filter to `ringing`/`in_progress` for the calls in progress right now, to final statuses for completed records, or to any mix of the two. Use `from`/`to` for one known party number in international form, and `number` to search either side by fragment. These are per-call records and do not include aggregate rates or totals. Use `voice.get` to follow one call to settlement. Range over it; the second value is non-nil only on the iteration where a fetch failed.

Example

List the workspace's calls. Filtering to the in-flight statuses gives the calls happening right now; omit the filter for completed 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)
	}
	for call, err := range client.Voice.List(context.Background(), bird.VoiceListParams{
		Status: []bird.VoiceCallStatus{"ringing", "in_progress"},
	}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(call.Id, call.Status)
	}
}

func (*VoiceService) ListPage added in v0.27.0

func (s *VoiceService) ListPage(ctx context.Context, params VoiceListParams, startingAfter string, opts ...option.RequestOption) (*VoiceCallList, error)

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

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.

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 WhatsAppAudioSend added in v0.33.0

type WhatsAppAudioSend = oapi.WhatsAppAudioSend

The free-form content arms a send carries in place of a template. Each is the wire object verbatim: the SDK sugars only the template handle, because the server decides which single arm a send may carry and reports the verdict.

type WhatsAppDocumentSend added in v0.33.0

type WhatsAppDocumentSend = oapi.WhatsAppDocumentSend

The free-form content arms a send carries in place of a template. Each is the wire object verbatim: the SDK sugars only the template handle, because the server decides which single arm a send may carry and reports the verdict.

type WhatsAppErrorCode added in v0.19.0

type WhatsAppErrorCode = oapi.WhatsAppErrorCode

WhatsAppErrorCode is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the WhatsAppErrorCode* constants with a default branch rather than treating the set as closed.

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 WhatsAppEventType added in v0.32.0

type WhatsAppEventType = oapi.WhatsAppEventType

WhatsAppEventType is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the WhatsAppEventType* constants with a default branch rather than treating the set as closed.

type WhatsAppImageSend added in v0.33.0

type WhatsAppImageSend = oapi.WhatsAppImageSend

The free-form content arms a send carries in place of a template. Each is the wire object verbatim: the SDK sugars only the template handle, because the server decides which single arm a send may carry and reports the verdict.

type WhatsAppLocationSend added in v0.33.0

type WhatsAppLocationSend = oapi.WhatsAppLocationSend

The free-form content arms a send carries in place of a template. Each is the wire object verbatim: the SDK sugars only the template handle, because the server decides which single arm a send may carry and reports the verdict.

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 WhatsAppStickerSend added in v0.33.0

type WhatsAppStickerSend = oapi.WhatsAppStickerSend

The free-form content arms a send carries in place of a template. Each is the wire object verbatim: the SDK sugars only the template handle, because the server decides which single arm a send may carry and reports the verdict.

type WhatsAppTag added in v0.33.0

type WhatsAppTag = oapi.Tag

WhatsAppTag is a structured {name, value} label on a WhatsApp send.

type WhatsAppTemplateCategory added in v0.19.0

type WhatsAppTemplateCategory = oapi.WhatsAppTemplateCategory

WhatsAppTemplateCategory is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the WhatsAppTemplateCategory* constants with a default branch rather than treating the set as closed.

type WhatsAppTemplateParameterType added in v0.19.0

type WhatsAppTemplateParameterType = oapi.WhatsAppTemplateParameterType

WhatsAppTemplateParameterType is an open string on the wire: a value added by a newer server deserializes unchanged, so compare against the WhatsAppTemplateParameterType* constants with a default branch rather than treating the set as closed.

type WhatsAppTextSend added in v0.33.0

type WhatsAppTextSend = oapi.WhatsAppTextSend

The free-form content arms a send carries in place of a template. Each is the wire object verbatim: the SDK sugars only the template handle, because the server decides which single arm a send may carry and reports the verdict.

type WhatsAppVideoSend added in v0.33.0

type WhatsAppVideoSend = oapi.WhatsAppVideoSend

The free-form content arms a send carries in place of a template. Each is the wire object verbatim: the SDK sugars only the template handle, because the server decides which single arm a send may carry and reports the verdict.

type WhatsappListEventsParams added in v0.6.0

type WhatsappListEventsParams struct {
	// Keep only events of this exact type (for example `whatsapp.delivered` or `whatsapp.failed`). Omit for the full timeline.
	Type WhatsAppEventType
}

WhatsappListEventsParams filters the list_events read.

type WhatsappListParams added in v0.6.0

type WhatsappListParams struct {
	// Maximum number of items to return per page.
	Limit int
	// Limits the response to resources created at or after this timestamp. Combine it with `created_before` to select a time window. Use an RFC 3339 timestamp with a timezone offset.
	CreatedAfter time.Time
	// Limits the response to resources created before this timestamp. Combine it with `created_after` to select a time window. Use an RFC 3339 timestamp with a timezone offset.
	CreatedBefore time.Time
	// Filter by status. Repeat the parameter to match any of several statuses.
	Status []WhatsAppMessageStatus
	// Filter by whether the business sent the message (`outbound`) or received it from the contact (`inbound`).
	Direction MessageDirection
	// Filter by recipient, exact match. The recipient is the contact on an outbound message and your business number on an inbound one, matching the `to` each message returns. Accepts an E.164 phone number, or a business-scoped user ID to name the contact. Only a contact is ever identified by a business-scoped user ID, so `to=<business-scoped user ID>` matches outbound messages only.
	To string
	// Filter by sender, exact match. The sender is your business number on an outbound message and the contact on an inbound one, matching the `from` each message returns. Accepts an E.164 phone number, or a business-scoped user ID to name the contact. Only a contact is ever identified by a business-scoped user ID, so `from=<business-scoped user ID>` matches inbound messages only.
	From string
	// Deprecated: use `to` or `from` instead, which also match a business-scoped user ID. Filters by contact phone number (E.164 exact match), in either direction.
	PhoneNumber string
	// Filter by business-scoped user ID (Meta identifier), matching the contact in either direction. `to` and `from` also accept one, but each matches a single end of the message.
	Bsuid string
	// Filter by category.
	Category WhatsAppTemplateCategory
	// Filter by tag. Accepts `name` to match any record carrying that tag name, or `name:value` to match a specific tag pair (for example `category:welcome`). Repeat the parameter to add more tags. A record must match every tag listed to be returned.
	Tag []string
}

WhatsappListParams filters the 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, or a business-scoped user ID
	From string // the business number to send from; omit only for a Bird-managed template

	Template   string                             // the template's id (wat_…) or its slug (e.g. bird_otp)
	Language   string                             // template language as a BCP-47 tag; omit when the template has a single language
	Components []WhatsAppMessageTemplateComponent // values that fill the template's placeholders

	Text     *WhatsAppTextSend
	Image    *WhatsAppImageSend
	Video    *WhatsAppVideoSend
	Audio    *WhatsAppAudioSend
	Sticker  *WhatsAppStickerSend
	Document *WhatsAppDocumentSend
	Location *WhatsAppLocationSend

	Tags     []WhatsAppTag  // structured {name, value} labels for filtering and analytics
	Metadata map[string]any // arbitrary JSON stored on the message and echoed in webhooks
}

WhatsappSendParams is a single WhatsApp message send. Carry exactly one kind of content — a template, or one free-form arm. Which arms a send may use, and whether From is required for it, are the server's to decide, so this type enforces neither. Zero-value fields are omitted from the request.

type WhatsappService added in v0.16.0

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

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

func (*WhatsappService) Get added in v0.16.0

func (s *WhatsappService) Get(ctx context.Context, messageId string, opts ...option.RequestOption) (*WhatsAppMessage, error)

Get Get one WhatsApp message by id: current delivery status, sent/delivered/read timestamps, the one content it was built from (a template, or free-form text, image, video, audio, sticker, document or location), and failure detail if it failed. For the per-event timeline use whatsapp_list_events.

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.16.0

List List WhatsApp messages, newest first, as a cursor page ({data, next_cursor, …}). Each message carries the one content it was built from: a template, or free-form text, image, video, audio, sticker, document or location. Pass next_cursor back as starting_after to fetch the next page. Filter by direction, status, recipient (to), sender (from), business-scoped user ID (bsuid), template category, or tag. to and from each accept a phone number or a business-scoped user ID; pair either with direction to search a single side of the message. Use whatsapp_get for one message's current state. 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.16.0

func (s *WhatsappService) ListEvents(ctx context.Context, messageId string, params WhatsappListEventsParams, opts ...option.RequestOption) (*WhatsAppEventList, error)

ListEvents Get one WhatsApp message's delivery timeline, oldest first: whatsapp.accepted, whatsapp.sent, whatsapp.delivered, whatsapp.read, and whatsapp.failed events, with failure detail on failed events. Not paginated; an unknown message ID returns `404`. Use `whatsapp.get` for the condensed current status.

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.16.0

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

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

func (*WhatsappService) Send added in v0.16.0

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

Example

Send a WhatsApp template message.

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)
	}
	code := "123456"
	msg, err := client.Whatsapp.Send(context.Background(), bird.WhatsappSendParams{
		To:       "+15551234567",
		Template: "bird_otp",
		Language: "en",
		Components: []bird.WhatsAppMessageTemplateComponent{{
			Type:       "body",
			Parameters: &[]bird.WhatsAppMessageTemplateComponentParameter{{Type: "text", Text: &code}},
		}},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(msg.Id, *msg.Status)
}
Example (FreeForm)

Send free-form WhatsApp text, inside an open 24-hour customer service 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)
	}
	msg, err := client.Whatsapp.Send(context.Background(), bird.WhatsappSendParams{
		To:   "+15551234567",
		From: "+15557654321",
		Text: &bird.WhatsAppTextSend{Body: "Your order has shipped!"},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(msg.Id, *msg.Status)
}

Directories

Path Synopsis
examples
onboarding-sms command
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.
realtimecrypto
Package realtimecrypto implements the wire crypto for Realtime end-to-end encrypted channels (private-encrypted-…): the per-channel key derivation, the event envelope, and the channel-auth signature.
Package realtimecrypto implements the wire crypto for Realtime end-to-end encrypted channels (private-encrypted-…): the per-channel key derivation, the event envelope, and the channel-auth signature.
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