Documentation
¶
Overview ¶
Package bird is the Go SDK for the Bird email platform (ADR-0044).
The wire types and a low-level client are generated from the OpenAPI spec into internal/oapi and never hand-edited. This package is the hand-written, idiomatic layer on top: 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. The request lifecycle lives in internal/requestconfig and the error model in internal/apierror; both are re-exported here.
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>",
})
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)
}
Output:
Index ¶
- Constants
- func Bool(v bool) *bool
- func Int(v int) *int
- func Ptr[T any](v T) *T
- func String(v string) *string
- type APIError
- type Audience
- type AudienceAddContactsParams
- type AudienceCreateParams
- type AudienceList
- type AudienceListContactsParams
- type AudienceListParams
- type AudienceMember
- type AudienceMemberList
- type AudienceRemoveContactsParams
- type AudienceUpdateParams
- type AudiencesService
- func (s *AudiencesService) AddContacts(ctx context.Context, audienceID string, params AudienceAddContactsParams, ...) error
- func (s *AudiencesService) Create(ctx context.Context, params AudienceCreateParams, opts ...option.RequestOption) (*Audience, error)
- func (s *AudiencesService) Delete(ctx context.Context, id string, opts ...option.RequestOption) error
- func (s *AudiencesService) Get(ctx context.Context, id string, opts ...option.RequestOption) (*Audience, error)
- func (s *AudiencesService) List(ctx context.Context, params AudienceListParams, opts ...option.RequestOption) iter.Seq2[*Audience, error]
- func (s *AudiencesService) ListContacts(ctx context.Context, audienceID string, params AudienceListContactsParams, ...) iter.Seq2[*AudienceMember, error]
- func (s *AudiencesService) ListContactsPage(ctx context.Context, audienceID string, params AudienceListContactsParams, ...) (*AudienceMemberList, error)
- func (s *AudiencesService) ListPage(ctx context.Context, params AudienceListParams, startingAfter string, ...) (*AudienceList, error)
- func (s *AudiencesService) RemoveContact(ctx context.Context, audienceID, contactID string, ...) error
- func (s *AudiencesService) RemoveContacts(ctx context.Context, audienceID string, params AudienceRemoveContactsParams, ...) error
- func (s *AudiencesService) Update(ctx context.Context, id string, params AudienceUpdateParams, ...) (*Audience, error)
- type Category
- type Client
- func (c *Client) Delete(ctx context.Context, path string, out any, opts ...option.RequestOption) error
- func (c *Client) Do(ctx context.Context, method, path string, body, out any, ...) error
- func (c *Client) Get(ctx context.Context, path string, out any, opts ...option.RequestOption) error
- func (c *Client) Patch(ctx context.Context, path string, body, out any, opts ...option.RequestOption) error
- func (c *Client) Post(ctx context.Context, path string, body, out any, opts ...option.RequestOption) error
- func (c *Client) Put(ctx context.Context, path string, body, out any, opts ...option.RequestOption) error
- type ConnectionError
- type Contact
- type ContactBatchParams
- type ContactCreateParams
- type ContactList
- type ContactListParams
- type ContactPropertiesService
- func (s *ContactPropertiesService) Archive(ctx context.Context, id string, opts ...option.RequestOption) (*ContactProperty, error)
- func (s *ContactPropertiesService) Create(ctx context.Context, params ContactPropertyCreateParams, ...) (*ContactProperty, error)
- func (s *ContactPropertiesService) Get(ctx context.Context, id string, opts ...option.RequestOption) (*ContactProperty, error)
- func (s *ContactPropertiesService) List(ctx context.Context, params ContactPropertyListParams, ...) iter.Seq2[*ContactProperty, error]
- func (s *ContactPropertiesService) ListPage(ctx context.Context, params ContactPropertyListParams, startingAfter string, ...) (*ContactPropertyList, error)
- func (s *ContactPropertiesService) Unarchive(ctx context.Context, id string, opts ...option.RequestOption) (*ContactProperty, error)
- func (s *ContactPropertiesService) Update(ctx context.Context, id string, params ContactPropertyUpdateParams, ...) (*ContactProperty, error)
- type ContactProperty
- type ContactPropertyCreateParams
- type ContactPropertyList
- type ContactPropertyListParams
- type ContactPropertyUpdateParams
- type ContactUpdateParams
- type ContactUpsertResult
- type ContactUpsertResultItem
- type ContactsService
- func (s *ContactsService) Batch(ctx context.Context, params ContactBatchParams, opts ...option.RequestOption) (*ContactUpsertResult, error)
- func (s *ContactsService) Create(ctx context.Context, params ContactCreateParams, opts ...option.RequestOption) (*Contact, error)
- func (s *ContactsService) Delete(ctx context.Context, id string, opts ...option.RequestOption) error
- func (s *ContactsService) Get(ctx context.Context, id string, opts ...option.RequestOption) (*Contact, error)
- func (s *ContactsService) List(ctx context.Context, params ContactListParams, opts ...option.RequestOption) iter.Seq2[*Contact, error]
- func (s *ContactsService) ListPage(ctx context.Context, params ContactListParams, startingAfter string, ...) (*ContactList, error)
- func (s *ContactsService) Update(ctx context.Context, id string, params ContactUpdateParams, ...) (*Contact, error)
- type DomainFailedEvent
- type DomainVerifiedEvent
- type EmailAcceptedEvent
- type EmailAttachment
- type EmailBatch
- type EmailBatchItem
- type EmailBouncedEvent
- type EmailClickedEvent
- type EmailComplainedEvent
- type EmailDefaults
- type EmailDeferredEvent
- type EmailDeliveredEvent
- type EmailListParams
- type EmailListUnsubscribedEvent
- type EmailMessage
- type EmailMessageList
- type EmailOpenedEvent
- type EmailOutOfBandBounceEvent
- type EmailProcessedEvent
- type EmailReceivedEvent
- type EmailRejectedEvent
- type EmailSendBatchParams
- type EmailSendParams
- type EmailService
- func (s *EmailService) Cancel(ctx context.Context, id string, opts ...option.RequestOption) error
- func (s *EmailService) Get(ctx context.Context, id string, opts ...option.RequestOption) (*EmailMessage, error)
- func (s *EmailService) List(ctx context.Context, params EmailListParams, opts ...option.RequestOption) iter.Seq2[*EmailMessage, error]
- func (s *EmailService) ListPage(ctx context.Context, params EmailListParams, startingAfter string, ...) (*EmailMessageList, error)
- func (s *EmailService) Send(ctx context.Context, params EmailSendParams, opts ...option.RequestOption) (*EmailMessage, error)
- func (s *EmailService) SendBatch(ctx context.Context, params EmailSendBatchParams, opts ...option.RequestOption) (*EmailBatch, error)
- type EmailStatus
- type EmailSuppressionCreatedEvent
- type EmailTag
- type EmailUnsubscribedEvent
- type ErrorDetail
- type ErrorNextAction
- type ErrorType
- type Event
- type RateLimitError
- type Response
- type SMSBatch
- type SMSCategory
- type SMSMessage
- type SMSMessageList
- type SMSService
- func (s *SMSService) Get(ctx context.Context, id string, opts ...option.RequestOption) (*SMSMessage, error)
- func (s *SMSService) List(ctx context.Context, params SmsListParams, opts ...option.RequestOption) iter.Seq2[*SMSMessage, error]
- func (s *SMSService) ListPage(ctx context.Context, params SmsListParams, startingAfter string, ...) (*SMSMessageList, error)
- func (s *SMSService) Send(ctx context.Context, params SmsSendParams, opts ...option.RequestOption) (*SMSMessage, error)
- func (s *SMSService) SendBatch(ctx context.Context, params SmsSendBatchParams, opts ...option.RequestOption) (*SMSBatch, error)
- type SMSStatus
- type SMSTag
- type SMSTemplate
- type SMSTemplateCategory
- type SMSTemplateList
- type SMSTemplateListParams
- type SMSTemplateScope
- type SMSTemplatesService
- type SmsListParams
- type SmsSendBatchParams
- type SmsSendParams
- type TimeoutError
- type UnmetGate
- type ValidationError
- type WebhookEventType
- type WebhookService
- type WebhookVerificationError
- type WhatsAppEvent
- type WhatsAppEventList
- type WhatsAppMessage
- type WhatsAppMessageList
- type WhatsAppMessageStatus
- type WhatsAppMessageTemplateComponent
- type WhatsAppMessageTemplateComponentParameter
- type WhatsAppService
- func (s *WhatsAppService) Get(ctx context.Context, id string, opts ...option.RequestOption) (*WhatsAppMessage, error)
- func (s *WhatsAppService) List(ctx context.Context, params WhatsappListParams, opts ...option.RequestOption) iter.Seq2[*WhatsAppMessage, error]
- func (s *WhatsAppService) ListEvents(ctx context.Context, id string, params WhatsappListEventsParams, ...) (*WhatsAppEventList, error)
- func (s *WhatsAppService) ListPage(ctx context.Context, params WhatsappListParams, startingAfter string, ...) (*WhatsAppMessageList, error)
- func (s *WhatsAppService) Send(ctx context.Context, params WhatsappSendParams, opts ...option.RequestOption) (*WhatsAppMessage, error)
- type WhatsAppTemplate
- type WhatsAppTemplateList
- type WhatsAppTemplatesService
- type WhatsappListEventsParams
- type WhatsappListParams
- type WhatsappSendParams
Examples ¶
- Package
- AudiencesService.AddContacts
- AudiencesService.Create
- AudiencesService.Delete
- AudiencesService.Get
- AudiencesService.List
- AudiencesService.ListContacts
- AudiencesService.RemoveContact
- AudiencesService.RemoveContacts
- AudiencesService.Update
- Client.Get
- ContactPropertiesService.Archive
- ContactPropertiesService.Create
- ContactPropertiesService.Get
- ContactPropertiesService.List
- ContactPropertiesService.Unarchive
- ContactPropertiesService.Update
- ContactsService.Batch
- ContactsService.Create
- ContactsService.Delete
- ContactsService.Get
- ContactsService.List
- ContactsService.Update
- EmailDefaults
- EmailService.Get
- EmailService.List
- EmailService.Send
- EmailService.Send (DisplayNames)
- EmailService.Send (Errors)
- EmailService.Send (Rich)
- EmailService.SendBatch
- SMSService.Send
- SMSService.Send (Template)
- SMSTemplatesService.Get
- SMSTemplatesService.List
- WebhookService.Unwrap
- WhatsAppService.Get
- WhatsAppService.List
- WhatsAppService.ListEvents
- WhatsAppService.Send
- WhatsAppTemplatesService.List
Constants ¶
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 )
ErrorType values — the coarse categories clients branch on (ADR-0016).
Variables ¶
This section is empty.
Functions ¶
Types ¶
type 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
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 {
ContactIDs []string
}
AudienceAddContactsParams adds up to 1,000 existing contacts to a static audience. Adding a contact that is already a member has no effect; if any ID does not exist, the whole request fails and no contacts are added.
type AudienceCreateParams ¶ added in v0.4.0
type AudienceCreateParams struct {
Name string // required
Description string // optional
Type string // optional; "" defaults to "static" server-side
}
AudienceCreateParams creates an audience. Name is required. Type is the audience's recipient model; leave it "" to default to "static" (the only currently usable value — "dynamic" and "external" are preview values the server rejects).
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 {
Limit int
}
AudienceListContactsParams bounds a page of an audience's contacts. Zero-value fields are omitted.
type AudienceListParams ¶ added in v0.4.0
type AudienceListParams struct {
Limit int
}
AudienceListParams filters the audience 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 {
ContactIDs []string
}
AudienceRemoveContactsParams removes up to 1,000 contacts from a static audience. Removing a contact that is not a member has no effect; if any ID does not exist, the whole request fails and no contacts are removed.
type AudienceUpdateParams ¶ added in v0.4.0
AudienceUpdateParams is a partial update of an audience. Every field is a pointer: nil leaves it unchanged; point Description at "" to clear it.
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 adds up to 1,000 existing contacts to a static audience. Retried safely with a reused idempotency key.
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)
}
}
Output:
func (*AudiencesService) Create ¶ added in v0.4.0
func (s *AudiencesService) Create(ctx context.Context, params AudienceCreateParams, opts ...option.RequestOption) (*Audience, error)
Create creates a static audience. Retried safely: a single idempotency key is reused across attempts. 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)
}
audience, err := client.Audiences.Create(context.Background(), bird.AudienceCreateParams{
Name: "Newsletter subscribers",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(audience.Id)
}
Output:
func (*AudiencesService) Delete ¶ added in v0.4.0
func (s *AudiencesService) Delete(ctx context.Context, id string, opts ...option.RequestOption) error
Delete removes an audience. The contacts themselves are not deleted.
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)
}
}
Output:
func (*AudiencesService) Get ¶ added in v0.4.0
func (s *AudiencesService) Get(ctx context.Context, id string, opts ...option.RequestOption) (*Audience, error)
Get returns a single audience by id.
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)
}
Output:
func (*AudiencesService) List ¶ added in v0.4.0
func (s *AudiencesService) List(ctx context.Context, params AudienceListParams, opts ...option.RequestOption) iter.Seq2[*Audience, error]
List walks every audience matching params, fetching pages lazily. Range over it; the second value is non-nil only on the iteration where a fetch failed.
Example ¶
List auto-paginates: it lazily fetches each page and yields every 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)
}
}
Output:
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 walks every contact in an audience, fetching pages lazily. 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)
}
}
Output:
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 an audience's contacts, ordered by join time, most recent first. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the most recent.
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 audiences. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the most recent.
func (*AudiencesService) RemoveContact ¶ added in v0.4.0
func (s *AudiencesService) RemoveContact(ctx context.Context, audienceID, contactID string, opts ...option.RequestOption) error
RemoveContact removes one contact's membership in an audience. The contact itself is not deleted and remains a member of any other audiences. Retried safely with a reused idempotency key.
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)
}
}
Output:
func (*AudiencesService) RemoveContacts ¶ added in v0.4.0
func (s *AudiencesService) RemoveContacts(ctx context.Context, audienceID string, params AudienceRemoveContactsParams, opts ...option.RequestOption) error
RemoveContacts removes up to 1,000 contacts from a static audience. The contacts themselves are not deleted. Retried safely with a reused idempotency key.
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)
}
}
Output:
func (*AudiencesService) Update ¶ added in v0.4.0
func (s *AudiencesService) Update(ctx context.Context, id string, params AudienceUpdateParams, opts ...option.RequestOption) (*Audience, error)
Update edits an audience. Only the fields set in params change. Retried safely with a reused idempotency key.
Example ¶
Update changes only the fields set in params; every other field is left unchanged.
package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
audience, err := client.Audiences.Update(context.Background(), "adn_123", bird.AudienceUpdateParams{
Name: bird.String("Renamed"),
})
if err != nil {
log.Fatal(err)
}
fmt.Println(audience.Id)
}
Output:
type Category ¶
type Category = oapi.EmailMessageCategory
Category classifies a send's suppression policy.
type Client ¶
type Client struct {
Email *EmailService
Sms *SMSService
SmsTemplates *SMSTemplatesService
Whatsapp *WhatsAppService
WhatsappTemplates *WhatsAppTemplatesService
Webhooks *WebhookService
Contacts *ContactsService
Audiences *AudiencesService
ContactProperties *ContactPropertiesService
// 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) 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 ¶
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))
}
Output:
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
Contact is a workspace contact; ContactList is a page of contacts; ContactUpsertResult is the result of a bulk upsert, with one ContactUpsertResultItem per submitted contact in submission order.
type ContactBatchParams ¶ added in v0.4.0
type ContactBatchParams struct {
Contacts []ContactCreateParams
AudienceIDs []string // audiences every contact in the request is added to
DataMode string // "merge" (default) or "replace"; how each contact's Data is applied to its existing stored values
}
ContactBatchParams bulk-upserts contacts matched by email address: existing contacts are updated with the supplied fields, new ones are created. AudienceIDs and DataMode are omitted from the request when left at their zero value.
type ContactCreateParams ¶ added in v0.4.0
type ContactCreateParams struct {
Email string // required; unique within the workspace
ExternalID string // optional caller-supplied identifier, unique within the workspace when set
FirstName string // optional
LastName string // optional
Data map[string]any // optional custom property values, keyed by contact property name
}
ContactCreateParams creates a contact. Email is required; the rest are optional and omitted from the request when left at their zero value.
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 {
Email string // exact match; matches at most one contact
ExternalID string // exact match; matches at most one contact
Search string // case-insensitive substring match against email
Limit int
}
ContactListParams filters the contact list. Zero-value fields are omitted.
type ContactPropertiesService ¶ added in v0.4.0
type ContactPropertiesService struct {
// contains filtered or unexported fields
}
ContactPropertiesService manages workspace contact properties: create, read, update, list, archive, and unarchive. Reach it via Client.ContactProperties.
func (*ContactPropertiesService) Archive ¶ added in v0.4.0
func (s *ContactPropertiesService) Archive(ctx context.Context, id string, opts ...option.RequestOption) (*ContactProperty, error)
Archive archives a contact property: the key stops being accepted in new contact writes and stops rendering in templates, but every value already stored on contacts is preserved. Reverse it with Unarchive. Retried safely with a reused idempotency key.
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)
}
Output:
func (*ContactPropertiesService) Create ¶ added in v0.4.0
func (s *ContactPropertiesService) Create(ctx context.Context, params ContactPropertyCreateParams, opts ...option.RequestOption) (*ContactProperty, error)
Create registers a contact property. Retried safely: a single idempotency key is reused across attempts. 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)
}
property, err := client.ContactProperties.Create(context.Background(), bird.ContactPropertyCreateParams{
Key: "plan",
Type: "string",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(property.Id)
}
Output:
func (*ContactPropertiesService) Get ¶ added in v0.4.0
func (s *ContactPropertiesService) Get(ctx context.Context, id string, opts ...option.RequestOption) (*ContactProperty, error)
Get returns a single contact property by id.
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)
}
Output:
func (*ContactPropertiesService) List ¶ added in v0.4.0
func (s *ContactPropertiesService) List(ctx context.Context, params ContactPropertyListParams, opts ...option.RequestOption) iter.Seq2[*ContactProperty, error]
List walks every contact property matching params, fetching pages lazily. Range over it; the second value is non-nil only on the iteration where a fetch failed.
Example ¶
List auto-paginates: it lazily fetches each page and yields every 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)
}
}
Output:
func (*ContactPropertiesService) ListPage ¶ added in v0.4.0
func (s *ContactPropertiesService) ListPage(ctx context.Context, params ContactPropertyListParams, startingAfter string, opts ...option.RequestOption) (*ContactPropertyList, error)
ListPage fetches one page of contact properties. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the most recent.
func (*ContactPropertiesService) Unarchive ¶ added in v0.4.0
func (s *ContactPropertiesService) Unarchive(ctx context.Context, id string, opts ...option.RequestOption) (*ContactProperty, error)
Unarchive reactivates an archived contact property: the key is accepted in contact writes and renders in templates again. Retried safely with a reused idempotency key.
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)
}
Output:
func (*ContactPropertiesService) Update ¶ added in v0.4.0
func (s *ContactPropertiesService) Update(ctx context.Context, id string, params ContactPropertyUpdateParams, opts ...option.RequestOption) (*ContactProperty, error)
Update changes a contact property's fallback value. Retried safely with a reused idempotency key.
Example ¶
Update changes a contact property's fallback value.
package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
property, err := client.ContactProperties.Update(context.Background(), "prp_123", bird.ContactPropertyUpdateParams{
FallbackValue: "free",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(property.Id)
}
Output:
type ContactProperty ¶ added in v0.4.0
type ContactProperty = oapi.ContactProperty
ContactProperty is a custom contact property definition; ContactPropertyList is a page of properties.
type ContactPropertyCreateParams ¶ added in v0.4.0
type ContactPropertyCreateParams struct {
Key string // required; lowercase letters, digits, underscores, starting with a letter
Type string // required; "string", "number", or "boolean"
FallbackValue any // optional; matches the declared Type
}
ContactPropertyCreateParams registers a contact property. Key and Type are required; Type cannot be changed after creation.
type ContactPropertyList ¶ added in v0.4.0
type ContactPropertyList = oapi.ContactPropertyList
ContactProperty is a custom contact property definition; ContactPropertyList is a page of properties.
type ContactPropertyListParams ¶ added in v0.4.0
type ContactPropertyListParams struct {
Limit int
}
ContactPropertyListParams filters the contact property list. Zero-value fields are omitted.
type ContactPropertyUpdateParams ¶ added in v0.4.0
type ContactPropertyUpdateParams struct {
FallbackValue any // optional; nil leaves the fallback unchanged
}
ContactPropertyUpdateParams changes a contact property's fallback value.
type ContactUpdateParams ¶ added in v0.4.0
type ContactUpdateParams struct {
Email *string
ExternalID *string
FirstName *string
LastName *string
Data map[string]any
}
ContactUpdateParams is a partial update of a contact. Every field is a pointer: nil leaves it unchanged; point at "" to clear a name or the external id. A key in Data set to nil removes that key from the contact's stored custom values; keys omitted from Data are left unchanged.
type ContactUpsertResult ¶ added in v0.4.0
type ContactUpsertResult = oapi.ContactUpsertResult
Contact is a workspace contact; ContactList is a page of contacts; ContactUpsertResult is the result of a bulk upsert, with one ContactUpsertResultItem per submitted contact in submission order.
type ContactUpsertResultItem ¶ added in v0.4.0
type ContactUpsertResultItem = oapi.ContactUpsertResultItem
Contact is a workspace contact; ContactList is a page of contacts; ContactUpsertResult is the result of a bulk upsert, with one ContactUpsertResultItem per submitted contact in submission order.
type ContactsService ¶ added in v0.4.0
type ContactsService struct {
// contains filtered or unexported fields
}
ContactsService manages workspace contacts: create, read, update, delete, bulk upsert, and list. Reach it via Client.Contact.
func (*ContactsService) Batch ¶ added in v0.4.0
func (s *ContactsService) Batch(ctx context.Context, params ContactBatchParams, opts ...option.RequestOption) (*ContactUpsertResult, error)
Batch creates or updates up to a batch's worth of contacts in one request, matched by email address. Retried safely with a reused idempotency key.
Example ¶
Batch creates or updates several contacts, matched by email address, in one request.
package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
result, err := client.Contacts.Batch(context.Background(), bird.ContactBatchParams{
Contacts: []bird.ContactCreateParams{
{Email: "a@x.com"},
},
})
if err != nil {
log.Fatal(err)
}
for _, item := range result.Data {
fmt.Println(item.Email, item.Status)
}
}
Output:
func (*ContactsService) Create ¶ added in v0.4.0
func (s *ContactsService) Create(ctx context.Context, params ContactCreateParams, opts ...option.RequestOption) (*Contact, error)
Create creates a contact. Retried safely: a single idempotency key is reused across attempts. Provide your own key with option.WithIdempotencyKey.
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)
}
Output:
func (*ContactsService) Delete ¶ added in v0.4.0
func (s *ContactsService) Delete(ctx context.Context, id string, opts ...option.RequestOption) error
Delete removes a contact.
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)
}
}
Output:
func (*ContactsService) Get ¶ added in v0.4.0
func (s *ContactsService) Get(ctx context.Context, id string, opts ...option.RequestOption) (*Contact, error)
Get returns a single contact by id.
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)
}
Output:
func (*ContactsService) List ¶ added in v0.4.0
func (s *ContactsService) List(ctx context.Context, params ContactListParams, opts ...option.RequestOption) iter.Seq2[*Contact, error]
List walks every contact matching params, fetching pages lazily. Range over it; the second value is non-nil only on the iteration where a fetch failed.
Example ¶
List auto-paginates: it lazily fetches each page and yields every 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)
}
}
Output:
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 contacts. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the most recent.
func (*ContactsService) Update ¶ added in v0.4.0
func (s *ContactsService) Update(ctx context.Context, id string, params ContactUpdateParams, opts ...option.RequestOption) (*Contact, error)
Update edits a contact. Only the fields set in params change. Retried safely with a reused idempotency key.
Example ¶
Update changes only the fields set in params; every other field is left unchanged.
package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
contact, err := client.Contacts.Update(context.Background(), "con_123", bird.ContactUpdateParams{
FirstName: bird.String("Jane"),
})
if err != nil {
log.Fatal(err)
}
fmt.Println(contact.Id)
}
Output:
type DomainFailedEvent ¶
type DomainFailedEvent = oapi.EventDomainFailed
Webhook event payloads, returned by Event.AsAny. Type-switch on these.
type DomainVerifiedEvent ¶
type DomainVerifiedEvent = oapi.EventDomainVerified
Webhook event payloads, returned by Event.AsAny. Type-switch on these.
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)
}
}
Output:
type EmailDeferredEvent ¶
type EmailDeferredEvent = oapi.EventEmailDeferred
Webhook event payloads, returned by Event.AsAny. Type-switch on these.
type EmailDeliveredEvent ¶
type EmailDeliveredEvent = oapi.EventEmailDelivered
Webhook event payloads, returned by Event.AsAny. Type-switch on these.
type EmailListParams ¶
type EmailListParams struct {
Limit int
Status EmailStatus
Category Category
Tag string
To string
From string
CreatedAfter time.Time
CreatedBefore time.Time
}
EmailListParams filters the message list. Zero-value fields are omitted.
type EmailListUnsubscribedEvent ¶
type EmailListUnsubscribedEvent = oapi.EventEmailListUnsubscribed
Webhook event payloads, returned by Event.AsAny. Type-switch on these.
type EmailMessage ¶
type EmailMessage = oapi.EmailMessage
EmailMessage is a sent message with aggregate delivery status.
type EmailMessageList ¶
type EmailMessageList = oapi.EmailMessageList
EmailMessageList is one page of messages plus its pagination cursors.
type EmailOpenedEvent ¶
type EmailOpenedEvent = oapi.EventEmailOpened
Webhook event payloads, returned by Event.AsAny. Type-switch on these.
type EmailOutOfBandBounceEvent ¶
type EmailOutOfBandBounceEvent = oapi.EventEmailOutOfBandBounce
Webhook event payloads, returned by Event.AsAny. Type-switch on these.
type EmailProcessedEvent ¶
type EmailProcessedEvent = oapi.EventEmailProcessed
Webhook event payloads, returned by Event.AsAny. Type-switch on these.
type EmailReceivedEvent ¶
type EmailReceivedEvent = oapi.EventEmailReceived
Webhook event payloads, returned by Event.AsAny. Type-switch on these.
type EmailRejectedEvent ¶
type EmailRejectedEvent = oapi.EventEmailRejected
Webhook event payloads, returned by Event.AsAny. Type-switch on these.
type EmailSendBatchParams ¶ added in v0.2.0
type EmailSendBatchParams struct {
Messages []EmailSendParams
}
EmailSendBatchParams is a batch of email sends submitted in one request. Each Message is an individual send; the whole batch is validated before any item is queued. The result preserves submission order.
type EmailSendParams ¶
type EmailSendParams struct {
From string // sender; bare address or "Name <addr>" form; must be on a verified domain
To []string // primary recipients; each may be bare or "Name <addr>" form
Cc []string // optional; same syntax as To
Bcc []string // optional; same syntax as To
ReplyTo []string // optional Reply-To; same syntax as To
Subject string // subject line
HTML string // HTML body; at least one of HTML or Text is required
Text string // plain-text body
Tags []EmailTag // structured {name,value} labels for filtering and analytics
Metadata map[string]any // arbitrary JSON, echoed on reads and in webhook payloads
Headers map[string]string // custom email headers
Attachments []EmailAttachment // file attachments
Category Category // transactional (default) or marketing
IpPoolId string // IP pool ID (ipp_…); workspace default when empty
// TrackOpens and TrackClicks are pointers because the server default is
// true — a nil leaves the default, false explicitly disables tracking.
TrackOpens *bool
TrackClicks *bool
// Template, when set, sends a published template in place of inline content:
// leave Subject/HTML/Text empty (the template supplies them) and personalize
// with Parameters. The value is the template's ID (`emt_…`) or its name handle.
Template string
// Parameters holds template variables rendered into the subject and
// body at send time; works with both inline content and a Template.
Parameters map[string]any
}
EmailSendParams is an email send. Optional fields are omitted from the request when left at their zero value.
Address fields (From, To, Cc, Bcc, ReplyTo) accept either a bare email address or RFC 5322 mailbox syntax with a display name: "Support Team <support@example.com>".
type EmailService ¶
type EmailService struct {
// contains filtered or unexported fields
}
EmailService sends and reads email messages. Reach it via Client.Email.
func (*EmailService) Cancel ¶ added in v0.4.1
func (s *EmailService) Cancel(ctx context.Context, id string, opts ...option.RequestOption) error
Cancel cancels a message scheduled with ScheduledAt before it sends. Only a message that is still scheduled can be canceled; one that already started sending — or was previously canceled — returns a conflict error. It returns no content on success. Retries reuse one idempotency key; provide your own with option.WithIdempotencyKey.
func (*EmailService) Get ¶
func (s *EmailService) Get(ctx context.Context, id string, opts ...option.RequestOption) (*EmailMessage, error)
Get returns a single message by ID, with aggregate delivery status rolled up across recipients.
Example ¶
package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
msg, err := client.Email.Get(context.Background(), "em_abc123")
if err != nil {
log.Fatal(err)
}
fmt.Println(*msg.Status, *msg.DeliveredCount)
}
Output:
func (*EmailService) List ¶
func (s *EmailService) List(ctx context.Context, params EmailListParams, opts ...option.RequestOption) iter.Seq2[*EmailMessage, error]
List walks every message matching params, fetching pages lazily. Range over it; the second value is non-nil only on the iteration where a fetch failed, after which the sequence ends.
for msg, err := range client.Email.List(ctx, bird.EmailListParams{Status: bird.EmailStatusBounced}) {
if err != nil { return err }
log.Println(msg.Id)
}
Example ¶
List auto-paginates: it lazily fetches each page and yields every matching message across all of them.
package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
for msg, err := range client.Email.List(context.Background(), bird.EmailListParams{Status: bird.EmailStatusBounced}) {
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id)
}
page, err := client.Email.ListPage(context.Background(), bird.EmailListParams{}, "")
if err != nil {
log.Fatal(err)
}
fmt.Println(len(page.Data)) // page.NextCursor carries the next starting_after
}
Output:
func (*EmailService) ListPage ¶
func (s *EmailService) ListPage(ctx context.Context, params EmailListParams, startingAfter string, opts ...option.RequestOption) (*EmailMessageList, error)
ListPage fetches one page of messages. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the most recent.
func (*EmailService) Send ¶
func (s *EmailService) Send(ctx context.Context, params EmailSendParams, opts ...option.RequestOption) (*EmailMessage, error)
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)
}
Output:
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)
}
}
Output:
Example (Errors) ¶
Branch on the typed error hierarchy. The SDK already retries transient failures (timeouts, 429, 5xx), so a returned error is terminal — most callers just propagate it; branch only to act on a category.
package main
import (
"context"
"errors"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
_, err = client.Email.Send(context.Background(), bird.EmailSendParams{
From: "onboarding@messagebird.dev", To: []string{"delivered@messagebird.dev"}, Subject: "Hello from Bird", HTML: "<p>My first Bird email.</p>",
})
if err != nil {
var rle *bird.RateLimitError
var ve *bird.ValidationError
var ae *bird.APIError
switch {
case errors.As(err, &rle):
fmt.Println("rate limited; retry after", rle.RetryAfter)
case errors.As(err, &ve):
for _, d := range ve.Details {
fmt.Printf("%s: %s\n", d.Param, d.Message)
}
case errors.As(err, &ae):
fmt.Printf("API error %s (status %d, request %s)\n", ae.Code, ae.StatusCode, ae.RequestID)
default:
log.Print(err) // transport: *bird.ConnectionError or *bird.TimeoutError
}
}
}
Output:
Example (Rich) ¶
A richer send: cc/bcc, reply-to, tags, metadata, opt-out of click tracking, and an idempotency key (safe to retry — the server dedupes).
package main
import (
"context"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
_, err = client.Email.Send(context.Background(), bird.EmailSendParams{
From: "hello@acme.com",
To: []string{"a@example.com", "b@example.com"},
Cc: []string{"manager@example.com"},
ReplyTo: []string{"support@acme.com"},
Subject: "Your March invoice",
HTML: "<p>Attached.</p>",
Tags: []bird.EmailTag{{Name: "category", Value: "billing"}},
Metadata: map[string]any{"invoice_id": "inv_123"},
TrackClicks: bird.Bool(false),
}, option.WithIdempotencyKey("invoice-march/cust_1"))
if err != nil {
log.Fatal(err)
}
}
Output:
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)
}
}
Output:
type EmailStatus ¶
type EmailStatus = oapi.EmailMessageStatus
EmailStatus is a message's aggregate delivery status.
const ( EmailStatusAccepted EmailStatus = "accepted" EmailStatusProcessed EmailStatus = "processed" EmailStatusDelivered EmailStatus = "delivered" EmailStatusDeferred EmailStatus = "deferred" EmailStatusBounced EmailStatus = "bounced" EmailStatusComplained EmailStatus = "complained" EmailStatusRejected EmailStatus = "rejected" EmailStatusPartialFailure EmailStatus = "partial_failure" )
type EmailSuppressionCreatedEvent ¶
type EmailSuppressionCreatedEvent = oapi.EventEmailSuppressionCreated
Webhook event payloads, returned by Event.AsAny. Type-switch on these.
type EmailUnsubscribedEvent ¶
type EmailUnsubscribedEvent = oapi.EventEmailUnsubscribed
Webhook event payloads, returned by Event.AsAny. Type-switch on these.
type ErrorDetail ¶
type ErrorDetail = apierror.ErrorDetail
The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.
type ErrorNextAction ¶ added in v0.2.2
type ErrorNextAction = apierror.ErrorNextAction
The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.
type ErrorType ¶
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 ¶
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 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 Response ¶
type Response = requestconfig.Response
Response is the transport metadata for one call, captured via option.WithResponseInto.
type SMSBatch ¶ added in v0.3.0
type SMSBatch = oapi.SMSMessageBatchResponse
SMSMessage is a sent or received SMS with its status, segment breakdown, and cost; SMSMessageList is a page of messages; SMSBatch is a batch-send result.
type SMSCategory ¶ added in v0.3.0
type SMSCategory = oapi.SMSMessageCategory
SMSCategory classifies a send for opt-out (STOP) policy, quiet hours, and per-country compliance.
const ( SMSCategoryTransactional SMSCategory = "transactional" SMSCategoryMarketing SMSCategory = "marketing" SMSCategoryAuthentication SMSCategory = "authentication" SMSCategoryService SMSCategory = "service" )
type SMSMessage ¶ added in v0.3.0
type SMSMessage = oapi.SMSMessage
SMSMessage is a sent or received SMS with its status, segment breakdown, and cost; SMSMessageList is a page of messages; SMSBatch is a batch-send result.
type SMSMessageList ¶ added in v0.3.0
type SMSMessageList = oapi.SMSMessageList
SMSMessage is a sent or received SMS with its status, segment breakdown, and cost; SMSMessageList is a page of messages; SMSBatch is a batch-send result.
type SMSService ¶ added in v0.3.0
type SMSService struct {
// contains filtered or unexported fields
}
SMSService sends SMS messages — free text or by stored template — and reads them back. Reach it via Client.Sms.
func (*SMSService) Get ¶ added in v0.3.0
func (s *SMSService) Get(ctx context.Context, id string, opts ...option.RequestOption) (*SMSMessage, error)
Get returns a single SMS message with its current delivery status, segment breakdown, cost, and failure detail if it failed.
func (*SMSService) List ¶ added in v0.3.0
func (s *SMSService) List(ctx context.Context, params SmsListParams, opts ...option.RequestOption) iter.Seq2[*SMSMessage, error]
List walks every message matching params, fetching pages lazily. Range over it; the second value is non-nil only on the iteration where a fetch failed.
func (*SMSService) ListPage ¶ added in v0.3.0
func (s *SMSService) ListPage(ctx context.Context, params SmsListParams, startingAfter string, opts ...option.RequestOption) (*SMSMessageList, error)
ListPage fetches one page of messages. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the most recent.
func (*SMSService) Send ¶ added in v0.3.0
func (s *SMSService) Send(ctx context.Context, params SmsSendParams, opts ...option.RequestOption) (*SMSMessage, error)
Send sends one SMS message. Retried safely: a single idempotency key is reused across attempts. Provide your own key with option.WithIdempotencyKey.
Example ¶
Send a free-text SMS.
package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
msg, err := client.Sms.Send(context.Background(), bird.SmsSendParams{
To: "+15551234567",
Text: "Your verification code is 123456.",
Category: bird.SMSCategoryAuthentication,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)
}
Output:
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)
}
Output:
func (*SMSService) SendBatch ¶ added in v0.3.0
func (s *SMSService) SendBatch(ctx context.Context, params SmsSendBatchParams, opts ...option.RequestOption) (*SMSBatch, error)
SendBatch sends up to 100 independent SMS messages in one call. Each item is a full send with its own id, status, and cost; all items are validated before any are queued. Retried safely with a reused idempotency key.
type SMSStatus ¶ added in v0.3.0
type SMSStatus = oapi.SMSMessageStatus
SMSStatus is a message's delivery status.
type SMSTemplate ¶ added in v0.3.0
type SMSTemplate = oapi.SMSTemplate
SMSTemplate is an SMS template with its body, variables, and available languages; SMSTemplateList is the (unpaginated) set of templates available to the workspace.
type SMSTemplateCategory ¶ added in v0.3.0
type SMSTemplateCategory string
SMSTemplateCategory filters templates by content classification.
const ( SMSTemplateCategoryTransactional SMSTemplateCategory = "transactional" SMSTemplateCategoryMarketing SMSTemplateCategory = "marketing" SMSTemplateCategoryAuthentication SMSTemplateCategory = "authentication" SMSTemplateCategoryService SMSTemplateCategory = "service" )
type SMSTemplateList ¶ added in v0.3.0
type SMSTemplateList = oapi.SMSTemplateList
SMSTemplate is an SMS template with its body, variables, and available languages; SMSTemplateList is the (unpaginated) set of templates available to the workspace.
type SMSTemplateListParams ¶ added in v0.3.0
type SMSTemplateListParams struct {
Scope SMSTemplateScope // filter by origin (system or workspace)
Category SMSTemplateCategory // filter by content classification
Language string // keep only templates available in this BCP-47 language tag
}
SMSTemplateListParams filters the template list. Zero-value fields are omitted.
type SMSTemplateScope ¶ added in v0.3.0
type SMSTemplateScope string
SMSTemplateScope filters templates by origin: Bird's built-in templates (system) or the workspace's own (workspace).
const ( SMSTemplateScopeSystem SMSTemplateScope = "system" SMSTemplateScopeWorkspace SMSTemplateScope = "workspace" )
type SMSTemplatesService ¶ added in v0.3.0
type SMSTemplatesService struct {
// contains filtered or unexported fields
}
SMSTemplatesService reads the SMS templates available to a workspace — Bird's built-in templates and any the workspace authored. Reach it via Client.SMSTemplates. The catalogue is read-only through this SDK.
func (*SMSTemplatesService) Get ¶ added in v0.3.0
func (s *SMSTemplatesService) Get(ctx context.Context, templateRef string, opts ...option.RequestOption) (*SMSTemplate, error)
Get returns a single SMS template by its name or id, including its body and the variables it expects.
Example ¶
Read one SMS template by its name (or id).
package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
tpl, err := client.SmsTemplates.Get(context.Background(), "bird_otp_verification")
if err != nil {
log.Fatal(err)
}
fmt.Println(tpl.Id, *tpl.Body)
}
Output:
func (*SMSTemplatesService) List ¶ added in v0.3.0
func (s *SMSTemplatesService) List(ctx context.Context, params SMSTemplateListParams, opts ...option.RequestOption) (*SMSTemplateList, error)
List returns the SMS templates available to the workspace, filtered by params. The catalogue is small and returned in full — this list is not paginated.
Example ¶
List the SMS templates available to the workspace. The catalogue is small and returned in full — this list is not paginated.
package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
list, err := client.SmsTemplates.List(context.Background(), bird.SMSTemplateListParams{
Scope: bird.SMSTemplateScopeSystem,
})
if err != nil {
log.Fatal(err)
}
for _, tpl := range list.Data {
fmt.Println(tpl.Id, *tpl.Name)
}
}
Output:
type SmsListParams ¶ added in v0.3.0
type SmsListParams struct {
Direction string // "outbound" or "inbound"; empty for both
Statuses []string // filter by any of several delivery statuses
ErrorCodes []string // filter by any of several failure reasons
Category SMSCategory // filter by content classification
To string // filter by recipient (E.164 exact match)
From string // filter by sender (exact match)
Tags []string // filter by tag name or name:value; AND-combined
CreatedAfter time.Time
CreatedBefore time.Time
Limit int
}
SmsListParams filters the message list. Zero-value fields are omitted.
type SmsSendBatchParams ¶ added in v0.3.0
type SmsSendBatchParams struct {
Messages []SmsSendParams
}
SmsSendBatchParams is a batch of up to 100 independent SMS sends.
type SmsSendParams ¶ added in v0.3.0
type SmsSendParams struct {
To string // required; recipient phone number in E.164 format
From string // optional sender; Bird selects one when empty
Text string // free-text body (mutually exclusive with Template)
Category SMSCategory // required with Text; omit on a template send
Template string // stored template id (smt_…) or name (mutually exclusive with Text)
Language string // template language as a BCP-47 tag; template sends only
Parameters map[string]any // template variable values; template sends only
Tags []SMSTag // structured {name, value} labels for filtering and analytics
Metadata map[string]any // arbitrary JSON stored on the message and echoed in webhooks
}
SmsSendParams is a single SMS send. Provide either Text (with Category) or a Template (by id or name, with Parameters) — the two are mutually exclusive. Zero-value fields are omitted from the request.
type TimeoutError ¶
type TimeoutError = apierror.TimeoutError
The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.
type UnmetGate ¶ added in v0.4.1
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 WebhookEventType ¶
type WebhookEventType = oapi.WebhookEventType
WebhookEventType is a webhook event's discriminant. It is an open string: the known values are the EventType* constants in eventtypes.gen.go, and an event type added by a newer server flows through Unwrap as a plain string.
const ( EventTypeDomainFailed WebhookEventType = "domain.failed" EventTypeDomainVerified WebhookEventType = "domain.verified" EventTypeEmailAccepted WebhookEventType = "email.accepted" EventTypeEmailBounced WebhookEventType = "email.bounced" EventTypeEmailCanceled WebhookEventType = "email.canceled" EventTypeEmailClicked WebhookEventType = "email.clicked" EventTypeEmailComplained WebhookEventType = "email.complained" EventTypeEmailDeferred WebhookEventType = "email.deferred" EventTypeEmailDelivered WebhookEventType = "email.delivered" EventTypeEmailListUnsubscribed WebhookEventType = "email.list_unsubscribed" EventTypeEmailMailboxMessageDelivered WebhookEventType = "email_mailbox.message_delivered" EventTypeEmailMailboxMessageFailed WebhookEventType = "email_mailbox.message_failed" EventTypeEmailMailboxMessageReceived WebhookEventType = "email_mailbox.message_received" EventTypeEmailMailboxMessageReceivedBlocked WebhookEventType = "email_mailbox.message_received_blocked" EventTypeEmailMailboxMessageReceivedUnauthenticated WebhookEventType = "email_mailbox.message_received_unauthenticated" EventTypeEmailMailboxMessageSent WebhookEventType = "email_mailbox.message_sent" EventTypeEmailMailboxSuspended WebhookEventType = "email_mailbox.suspended" EventTypeEmailMailboxThreadCreated WebhookEventType = "email_mailbox.thread_created" EventTypeEmailOpened WebhookEventType = "email.opened" EventTypeEmailOutOfBandBounce WebhookEventType = "email.out_of_band_bounce" EventTypeEmailProcessed WebhookEventType = "email.processed" EventTypeEmailReceived WebhookEventType = "email.received" EventTypeEmailRejected WebhookEventType = "email.rejected" EventTypeEmailScheduled WebhookEventType = "email.scheduled" EventTypeEmailSuppressionCreated WebhookEventType = "email_suppression.created" EventTypeEmailUnsubscribed WebhookEventType = "email.unsubscribed" EventTypeSmsAccepted WebhookEventType = "sms.accepted" EventTypeSmsDelivered WebhookEventType = "sms.delivered" EventTypeSmsExpired WebhookEventType = "sms.expired" EventTypeSmsFailed WebhookEventType = "sms.failed" EventTypeSmsRejected WebhookEventType = "sms.rejected" EventTypeSmsSent WebhookEventType = "sms.sent" EventTypeSmsUndelivered WebhookEventType = "sms.undelivered" )
Webhook event types known at this SDK version. WebhookEventType is an open string on the wire: a value added by a newer server flows through Unwrap unchanged, so switch on these constants with a default branch.
type WebhookService ¶
type WebhookService struct {
// contains filtered or unexported fields
}
WebhookService verifies inbound webhook deliveries. Reach it via Client.Webhooks. Configure the signing secret with option.WithWebhookSecret on the client (or per call on Unwrap). It is pure crypto — no transport.
func (*WebhookService) Unwrap ¶
func (s *WebhookService) Unwrap(payload []byte, headers http.Header, opts ...option.RequestOption) (Event, error)
Unwrap verifies the Standard Webhooks signature over the raw request body and returns the decoded event. Hand it the exact bytes received — parsing and re-serializing before verifying breaks the signature.
Example ¶
Unwrap verifies the Standard Webhooks signature over the raw request body and returns a typed event to dispatch on.
package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(
option.WithAPIKey(os.Getenv("BIRD_API_KEY")),
option.WithWebhookSecret(os.Getenv("BIRD_WEBHOOK_SECRET")),
)
if err != nil {
log.Fatal(err)
}
http.HandleFunc("/webhooks/bird", func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
event, err := client.Webhooks.Unwrap(body, r.Header)
if err != nil {
http.Error(w, "invalid signature", http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusNoContent) // ack fast, then process
payload, _ := event.AsAny()
switch p := payload.(type) {
case bird.EmailDeliveredEvent:
fmt.Println("delivered:", p.Data.EmailId, p.Data.Recipient)
case bird.EmailBouncedEvent:
fmt.Println("bounced:", p.Type)
}
})
}
Output:
type WebhookVerificationError ¶
type WebhookVerificationError = apierror.WebhookVerificationError
The SDK error model, re-exported from internal/apierror so these names are the semver-locked public surface. Catch *APIError (via errors.As) to handle any server error; the variants carry extra data. Transport failures with no HTTP response are *ConnectionError / *TimeoutError; a bad webhook signature is *WebhookVerificationError.
type WhatsAppEvent ¶ added in v0.6.0
type WhatsAppEvent = oapi.WhatsAppEvent
WhatsAppEvent is a single lifecycle event on a message's timeline; WhatsAppEventList is the (unpaginated) timeline for one message.
type WhatsAppEventList ¶ added in v0.6.0
type WhatsAppEventList = oapi.WhatsAppEventList
WhatsAppEvent is a single lifecycle event on a message's timeline; WhatsAppEventList is the (unpaginated) timeline for one message.
type WhatsAppMessage ¶ added in v0.6.0
type WhatsAppMessage = oapi.WhatsAppMessage
WhatsAppMessage is a sent or received WhatsApp message; WhatsAppMessageList is a page of messages.
type WhatsAppMessageList ¶ added in v0.6.0
type WhatsAppMessageList = oapi.WhatsAppMessageList
WhatsAppMessage is a sent or received WhatsApp message; WhatsAppMessageList is a page of messages.
type WhatsAppMessageStatus ¶ added in v0.6.0
type WhatsAppMessageStatus = oapi.WhatsAppMessageStatus
WhatsAppMessageStatus is a message's delivery status.
type WhatsAppMessageTemplateComponent ¶ added in v0.6.0
type WhatsAppMessageTemplateComponent = oapi.WhatsAppMessageTemplateComponent
WhatsAppMessageTemplateComponent is a filled-in template component — supplied on a template send and echoed back on the sent message. WhatsAppMessageTemplateComponentParameter is one of its placeholder values.
type WhatsAppMessageTemplateComponentParameter ¶ added in v0.6.0
type WhatsAppMessageTemplateComponentParameter = oapi.WhatsAppMessageTemplateComponentParameter
WhatsAppMessageTemplateComponent is a filled-in template component — supplied on a template send and echoed back on the sent message. WhatsAppMessageTemplateComponentParameter is one of its placeholder values.
type WhatsAppService ¶ added in v0.6.0
type WhatsAppService struct {
// contains filtered or unexported fields
}
WhatsAppService sends WhatsApp template messages and reads them back. Reach it via Client.Whatsapp.
func (*WhatsAppService) Get ¶ added in v0.6.0
func (s *WhatsAppService) Get(ctx context.Context, id string, opts ...option.RequestOption) (*WhatsAppMessage, error)
Get returns a single WhatsApp message with its current delivery status and failure detail if it failed.
Example ¶
Read a single WhatsApp message by id.
package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
msg, err := client.Whatsapp.Get(context.Background(), "wam_01krdgeqcxet5s7t44vh8rt9mg")
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)
}
Output:
func (*WhatsAppService) List ¶ added in v0.6.0
func (s *WhatsAppService) List(ctx context.Context, params WhatsappListParams, opts ...option.RequestOption) iter.Seq2[*WhatsAppMessage, error]
List walks every message matching params, fetching pages lazily. Range over it; the second value is non-nil only on the iteration where a fetch failed.
Example ¶
List WhatsApp messages to a given contact, paginating lazily.
package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
for msg, err := range client.Whatsapp.List(context.Background(), bird.WhatsappListParams{PhoneNumber: "+15551234567"}) {
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id)
}
}
Output:
func (*WhatsAppService) ListEvents ¶ added in v0.6.0
func (s *WhatsAppService) ListEvents(ctx context.Context, id string, params WhatsappListEventsParams, opts ...option.RequestOption) (*WhatsAppEventList, error)
ListEvents returns the lifecycle event timeline for a WhatsApp message, in chronological order. The timeline is bounded and returned in full — this list is not paginated.
Example ¶
List the lifecycle events for a WhatsApp message, in chronological order.
package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
events, err := client.Whatsapp.ListEvents(context.Background(), "wam_01krdgeqcxet5s7t44vh8rt9mg", bird.WhatsappListEventsParams{})
if err != nil {
log.Fatal(err)
}
for _, e := range events.Data {
fmt.Println(e.Id, *e.Type)
}
}
Output:
func (*WhatsAppService) ListPage ¶ added in v0.6.0
func (s *WhatsAppService) ListPage(ctx context.Context, params WhatsappListParams, startingAfter string, opts ...option.RequestOption) (*WhatsAppMessageList, error)
ListPage fetches one page of messages. Pass the previous page's NextCursor as startingAfter to advance; "" starts from the most recent.
func (*WhatsAppService) Send ¶ added in v0.6.0
func (s *WhatsAppService) Send(ctx context.Context, params WhatsappSendParams, opts ...option.RequestOption) (*WhatsAppMessage, error)
Send sends one WhatsApp template message. Retried safely: a single idempotency key is reused across attempts. Provide your own key with option.WithIdempotencyKey.
Example ¶
Send a WhatsApp template message. Templates are currently the only supported content type.
package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
msg, err := client.Whatsapp.Send(context.Background(), bird.WhatsappSendParams{
To: "+15551234567",
Template: "bird_otp",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)
}
Output:
type WhatsAppTemplate ¶ added in v0.6.0
type WhatsAppTemplate = oapi.WhatsAppTemplate
WhatsAppTemplate is a template available to the workspace; WhatsAppTemplateList is the (unpaginated) set of templates.
type WhatsAppTemplateList ¶ added in v0.6.0
type WhatsAppTemplateList = oapi.WhatsAppTemplateList
WhatsAppTemplate is a template available to the workspace; WhatsAppTemplateList is the (unpaginated) set of templates.
type WhatsAppTemplatesService ¶ added in v0.6.0
type WhatsAppTemplatesService struct {
// contains filtered or unexported fields
}
WhatsAppTemplatesService reads the WhatsApp templates available to a workspace — Bird's built-in templates and any the workspace authored. Reach it via Client.WhatsappTemplates. The catalogue is read-only through this SDK.
func (*WhatsAppTemplatesService) List ¶ added in v0.6.0
func (s *WhatsAppTemplatesService) List(ctx context.Context, opts ...option.RequestOption) (*WhatsAppTemplateList, error)
List returns the WhatsApp templates available to the workspace. The catalogue is small and returned in full — this list is not paginated.
Example ¶
List the WhatsApp templates available to the workspace. The catalogue is small and returned in full — this list is not paginated.
package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
list, err := client.WhatsappTemplates.List(context.Background())
if err != nil {
log.Fatal(err)
}
for _, tpl := range list.Data {
fmt.Println(*tpl.Name)
}
}
Output:
type WhatsappListEventsParams ¶ added in v0.6.0
type WhatsappListEventsParams struct {
Type string // filter by event type (e.g. "whatsapp.delivered"); empty returns every event
}
WhatsappListEventsParams filters a message's event timeline. Zero-value fields are omitted.
type WhatsappListParams ¶ added in v0.6.0
type WhatsappListParams struct {
Statuses []WhatsAppMessageStatus // filter by any of several delivery statuses
PhoneNumber string // filter by contact phone number (E.164 exact match)
Bsuid string // filter by business-scoped user ID (Meta identifier)
CreatedAfter time.Time
CreatedBefore time.Time
Limit int
}
WhatsappListParams filters the message list. Zero-value fields are omitted.
type WhatsappSendParams ¶ added in v0.6.0
type WhatsappSendParams struct {
To string // required; recipient phone number in E.164 format
Template string // required; the template's stable handle (e.g. bird_otp)
Language string // template language variant; omit when the template has a single language
Components []WhatsAppMessageTemplateComponent // values that fill the template's placeholders
}
WhatsappSendParams is a single WhatsApp message send. Templates are currently the only supported content type, so Template is required; free-form content will be added in a future release. Zero-value fields are omitted from the request.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
quickstart-email
command
|
|
|
quickstart-whatsapp
command
|
|
|
standard-library
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. |
|
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. |