Documentation
¶
Overview ¶
Package anypost is the official Go client for the Anypost email API.
Create a client with an API key (or set ANYPOST_API_KEY and pass an empty string), then call resource methods. Every method takes a context.Context for cancellation and timeout.
client, err := anypost.New("ap_your_api_key")
if err != nil {
log.Fatal(err)
}
sent, err := client.Email.Send(ctx, &anypost.SendEmailRequest{
From: "Acme <you@yourdomain.com>",
To: []string{"someone@example.com"},
Subject: "Hello",
HTML: "<p>It worked.</p>",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(sent.ID)
A failed call returns an *anypost.Error; recover it with errors.As and branch on its Type. Keep the API key server-side; it is a bearer credential.
Index ¶
- Constants
- func Bool(v bool) *bool
- func String(v string) *string
- func VerifyWebhookSignature(payload []byte, signatureHeader, secret string, opts ...VerifyOption) error
- type APIKey
- type APIKeyCreateParams
- type APIKeyUpdateParams
- type APIKeyWithSecret
- type APIKeysService
- func (s *APIKeysService) Create(ctx context.Context, params *APIKeyCreateParams, opts ...RequestOption) (*APIKeyWithSecret, error)
- func (s *APIKeysService) Delete(ctx context.Context, id string, opts ...RequestOption) error
- func (s *APIKeysService) Get(ctx context.Context, id string, opts ...RequestOption) (*APIKey, error)
- func (s *APIKeysService) List(ctx context.Context, params ListParams, opts ...RequestOption) (*Page[APIKey], error)
- func (s *APIKeysService) Update(ctx context.Context, id string, params *APIKeyUpdateParams, ...) (*APIKey, error)
- type Attachment
- type BatchItemError
- type BatchItemResult
- type BatchResponse
- type BatchSummary
- type Client
- type DNSRecord
- type Domain
- type DomainCreateParams
- type DomainTracking
- type DomainTrackingParams
- type DomainUpdateParams
- type DomainsService
- func (s *DomainsService) Create(ctx context.Context, params *DomainCreateParams, opts ...RequestOption) (*Domain, error)
- func (s *DomainsService) Delete(ctx context.Context, id string, opts ...RequestOption) error
- func (s *DomainsService) Get(ctx context.Context, id string, opts ...RequestOption) (*Domain, error)
- func (s *DomainsService) List(ctx context.Context, params ListParams, opts ...RequestOption) (*Page[Domain], error)
- func (s *DomainsService) Update(ctx context.Context, id string, params *DomainUpdateParams, ...) (*Domain, error)
- func (s *DomainsService) Verify(ctx context.Context, id string, opts ...RequestOption) (*Domain, error)
- type EmailBatchRequest
- type EmailService
- type Error
- type ErrorType
- type Event
- type EventBot
- type EventListParams
- type EventTracking
- type EventType
- type EventsService
- type IdentityService
- type ListParams
- type Option
- type Page
- type Permissions
- type RequestOption
- type SendEmailRequest
- type SendResponse
- type Suppression
- type SuppressionCreateParams
- type SuppressionListParams
- type SuppressionOrigin
- type SuppressionReason
- type SuppressionsService
- func (s *SuppressionsService) Create(ctx context.Context, params *SuppressionCreateParams, opts ...RequestOption) (*Suppression, error)
- func (s *SuppressionsService) Delete(ctx context.Context, email, topic string, opts ...RequestOption) error
- func (s *SuppressionsService) DeleteForEmail(ctx context.Context, email string, opts ...RequestOption) error
- func (s *SuppressionsService) Get(ctx context.Context, email, topic string, opts ...RequestOption) (*Suppression, error)
- func (s *SuppressionsService) List(ctx context.Context, params SuppressionListParams, opts ...RequestOption) (*Page[Suppression], error)
- func (s *SuppressionsService) ListForEmail(ctx context.Context, email string, opts ...RequestOption) ([]Suppression, error)
- type Template
- type TemplateCreateParams
- type TemplateDraft
- type TemplateDraftParams
- type TemplateDuplicateParams
- type TemplateKind
- type TemplateUpdateParams
- type TemplatesService
- func (s *TemplatesService) Create(ctx context.Context, params *TemplateCreateParams, opts ...RequestOption) (*Template, error)
- func (s *TemplatesService) Delete(ctx context.Context, id string, opts ...RequestOption) error
- func (s *TemplatesService) DeleteDraft(ctx context.Context, id string, opts ...RequestOption) error
- func (s *TemplatesService) Duplicate(ctx context.Context, id string, params *TemplateDuplicateParams, ...) (*Template, error)
- func (s *TemplatesService) Get(ctx context.Context, id string, opts ...RequestOption) (*Template, error)
- func (s *TemplatesService) GetDraft(ctx context.Context, id string, opts ...RequestOption) (*TemplateDraft, error)
- func (s *TemplatesService) List(ctx context.Context, params ListParams, opts ...RequestOption) (*Page[Template], error)
- func (s *TemplatesService) Publish(ctx context.Context, id string, opts ...RequestOption) (*Template, error)
- func (s *TemplatesService) Update(ctx context.Context, id string, params *TemplateUpdateParams, ...) (*Template, error)
- func (s *TemplatesService) UpdateDraft(ctx context.Context, id string, params *TemplateDraftParams, ...) (*TemplateDraft, error)
- type Tracking
- type Unsubscribe
- type UnsubscribeMode
- type VerificationFailure
- type VerifyOption
- type Webhook
- type WebhookCreateParams
- type WebhookDelivery
- type WebhookDeliveryEvent
- type WebhookEventType
- type WebhookStatus
- type WebhookTestResult
- type WebhookUpdateParams
- type WebhookVerificationError
- type WebhookVerificationReason
- type WebhookWithSecret
- type WebhooksService
- func (s *WebhooksService) Create(ctx context.Context, params *WebhookCreateParams, opts ...RequestOption) (*WebhookWithSecret, error)
- func (s *WebhooksService) Delete(ctx context.Context, id string, opts ...RequestOption) error
- func (s *WebhooksService) Get(ctx context.Context, id string, opts ...RequestOption) (*Webhook, error)
- func (s *WebhooksService) List(ctx context.Context, params ListParams, opts ...RequestOption) (*Page[Webhook], error)
- func (s *WebhooksService) RotateSecret(ctx context.Context, id string, opts ...RequestOption) (*WebhookWithSecret, error)
- func (s *WebhooksService) Test(ctx context.Context, id string, opts ...RequestOption) (*WebhookTestResult, error)
- func (s *WebhooksService) Update(ctx context.Context, id string, params *WebhookUpdateParams, ...) (*Webhook, error)
- type WhoamiAPIKey
- type WhoamiLimits
- type WhoamiResponse
- type WhoamiTeam
Constants ¶
const DefaultWebhookTolerance = 300 * time.Second
DefaultWebhookTolerance is the default maximum age of a webhook delivery, measured from its signed timestamp. Deliveries older than this are rejected to bound replay of a captured request.
const Version = "1.4.0"
Version is the SDK version, reported in the User-Agent header. It is the single source of truth: bump it, tag the commit `vX.Y.Z`, and push — the release workflow publishes the module proxy entry for the tag.
Variables ¶
This section is empty.
Functions ¶
func Bool ¶
Bool is a helper for setting an optional *bool field, e.g. Tracking{Opens: anypost.Bool(true)}.
func String ¶ added in v1.2.0
String is a helper for setting an optional *string field, e.g. TemplateCreateParams{HTML: anypost.String("<h1>Hi</h1>")}.
func VerifyWebhookSignature ¶
func VerifyWebhookSignature(payload []byte, signatureHeader, secret string, opts ...VerifyOption) error
VerifyWebhookSignature verifies the signature on an Anypost webhook delivery.
Pass the raw request body (the exact bytes received, before JSON parsing), the Anypost-Signature header value, and the webhook's signing secret. It returns nil on success and a *WebhookVerificationError otherwise.
The header may carry more than one v1= component during a secret rotation; a match on any one passes, so deliveries keep verifying across a rotation.
Types ¶
type APIKey ¶
type APIKey struct {
// ID is the key_-prefixed id.
ID string `json:"id"`
Name string `json:"name"`
// KeyPrefix is the first 12 characters of the key, shown for identification.
KeyPrefix string `json:"key_prefix"`
Permissions Permissions `json:"permissions"`
// AllowedDomains lists the domains this key may send from. nil means all
// verified domains.
AllowedDomains []string `json:"allowed_domains"`
// AllowedIPs lists the IPs/CIDRs allowed to use this key. nil means all IPs.
AllowedIPs []string `json:"allowed_ips"`
// LastUsedAt is when the key was last used, or nil if never.
LastUsedAt *string `json:"last_used_at"`
CreatedAt string `json:"created_at"`
}
APIKey is an API key's metadata. The plaintext secret is never returned here.
type APIKeyCreateParams ¶
type APIKeyCreateParams struct {
Name string `json:"name"`
Permissions Permissions `json:"permissions"`
// AllowedDomains restricts sending to these domains. Omit for all verified.
AllowedDomains []string `json:"allowed_domains,omitempty"`
// AllowedIPs restricts use to these IPs/CIDRs. Omit for all IPs.
AllowedIPs []string `json:"allowed_ips,omitempty"`
}
APIKeyCreateParams is the body for APIKeysService.Create.
type APIKeyUpdateParams ¶
type APIKeyUpdateParams struct {
Name string `json:"name"`
Permissions Permissions `json:"permissions"`
// AllowedDomains restricts sending to these domains. Pass an empty slice to
// lift the restriction.
AllowedDomains []string `json:"allowed_domains,omitempty"`
// AllowedIPs restricts use to these IPs/CIDRs. Pass an empty slice to lift it.
AllowedIPs []string `json:"allowed_ips,omitempty"`
}
APIKeyUpdateParams is the body for APIKeysService.Update. The plaintext secret is not rotated here.
type APIKeyWithSecret ¶
type APIKeyWithSecret struct {
APIKey
// Key is the full API key. Store it securely; it cannot be retrieved later.
Key string `json:"key"`
}
APIKeyWithSecret is a newly created key, including its plaintext secret. The secret is returned only once, at creation.
type APIKeysService ¶
type APIKeysService struct {
// contains filtered or unexported fields
}
APIKeysService holds the /api-keys operations. Access it via Client.APIKeys.
func (*APIKeysService) Create ¶
func (s *APIKeysService) Create(ctx context.Context, params *APIKeyCreateParams, opts ...RequestOption) (*APIKeyWithSecret, error)
Create issues a new API key. The plaintext secret is returned only in this response, as Key — store it securely; it cannot be retrieved later.
func (*APIKeysService) Delete ¶
func (s *APIKeysService) Delete(ctx context.Context, id string, opts ...RequestOption) error
Delete removes a key. It may keep authenticating for up to 5 minutes due to gateway caching.
func (*APIKeysService) Get ¶
func (s *APIKeysService) Get(ctx context.Context, id string, opts ...RequestOption) (*APIKey, error)
Get retrieves a single API key's metadata. The secret is never returned.
func (*APIKeysService) List ¶
func (s *APIKeysService) List(ctx context.Context, params ListParams, opts ...RequestOption) (*Page[APIKey], error)
List returns one page of the team's API keys, newest-first.
func (*APIKeysService) Update ¶
func (s *APIKeysService) Update(ctx context.Context, id string, params *APIKeyUpdateParams, opts ...RequestOption) (*APIKey, error)
Update changes a key's name, permissions, and restrictions. The secret is not rotated here. Changes may take up to 5 minutes to propagate.
type Attachment ¶
type Attachment struct {
// Filename is the file name shown to the recipient.
Filename string `json:"filename"`
// Content is the raw file bytes; encoded to base64 on the wire.
Content []byte `json:"content"`
// ContentType is the MIME type. Defaults to application/octet-stream
// server-side when empty.
ContentType string `json:"content_type,omitempty"`
// ContentID marks the attachment inline, referenced from the HTML via cid:.
ContentID string `json:"content_id,omitempty"`
}
Attachment is one inline attachment on a message.
Content is the raw file bytes (for example, the result of os.ReadFile). The SDK base64-encodes it on the wire via Go's standard JSON encoding of a byte slice — do not pre-encode it.
type BatchItemError ¶
BatchItemError is the inner error on a failed batch entry.
type BatchItemResult ¶
type BatchItemResult struct {
Status string `json:"status"`
// Index is the zero-based position in the request Emails slice.
Index int `json:"index"`
ID string `json:"id,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
Error *BatchItemError `json:"error,omitempty"`
}
BatchItemResult is one entry's outcome in a batch send. Discriminate on Status: "queued" entries carry ID and CreatedAt; "failed" entries carry Error.
type BatchResponse ¶
type BatchResponse struct {
Summary BatchSummary `json:"summary"`
Data []BatchItemResult `json:"data"`
}
BatchResponse is returned from a batch send. A mixed-outcome batch (HTTP 207) is a success, not an error: inspect each entry's Status. Data[i].Index == i.
type BatchSummary ¶
type BatchSummary struct {
Total int `json:"total"`
Queued int `json:"queued"`
Failed int `json:"failed"`
}
BatchSummary tallies a batch's per-entry outcomes.
type Client ¶
type Client struct {
// Email holds send operations (/email, /email/batch).
Email *EmailService
// Domains holds sending-domain operations (/domains).
Domains *DomainsService
// APIKeys holds API-key operations (/api-keys).
APIKeys *APIKeysService
// Templates holds template operations (/templates), including draft/publish.
Templates *TemplatesService
// Suppressions holds suppression-list operations (/suppressions).
Suppressions *SuppressionsService
// Webhooks holds webhook operations (/webhooks), including test and rotation.
Webhooks *WebhooksService
// Events holds read access to the event stream (/events).
Events *EventsService
// contains filtered or unexported fields
}
Client is the entry point to the Anypost API. Construct it with New. It is safe for concurrent use by multiple goroutines.
func New ¶
New creates a Client. If apiKey is empty, it falls back to the ANYPOST_API_KEY environment variable; if neither is set, it returns an error.
func (*Client) Whoami ¶
func (c *Client) Whoami(ctx context.Context, opts ...RequestOption) (*WhoamiResponse, error)
Whoami identifies the team and permission level behind the current API key.
type DNSRecord ¶
type DNSRecord struct {
// Type is the record type. "CNAME" is the only value today.
Type string `json:"type"`
// Name is the record name to publish, relative to the registered apex.
Name string `json:"name"`
// Value is the CNAME target (absolute FQDN).
Value string `json:"value"`
// Purpose is one of "verification", "dkim", or "tracking".
Purpose string `json:"purpose"`
}
DNSRecord is a DNS record the customer must publish to verify a domain or its branded tracking.
type Domain ¶
type Domain struct {
// ID is the domain_-prefixed id.
ID string `json:"id"`
// Name is the domain name, e.g. example.com.
Name string `json:"name"`
// Status is "pending" until the mail-flow CNAMEs resolve, then "verified".
Status string `json:"status"`
// DNSRecords holds the mail-flow records to publish.
DNSRecords []DNSRecord `json:"dns_records"`
// VerificationFailure is the most recent mail-flow failure, or nil.
VerificationFailure *VerificationFailure `json:"verification_failure"`
// Tracking is the branded tracking configuration and its status.
Tracking DomainTracking `json:"tracking"`
CreatedAt string `json:"created_at"`
// VerifiedAt is when the domain last transitioned to verified, or nil.
VerifiedAt *string `json:"verified_at"`
}
Domain is a sending domain and its mail-flow verification state.
type DomainCreateParams ¶
type DomainCreateParams struct {
// Name is the domain to add, e.g. example.com.
Name string `json:"name"`
}
DomainCreateParams is the body for DomainsService.Create.
type DomainTracking ¶
type DomainTracking struct {
OpensEnabled bool `json:"opens_enabled"`
ClicksEnabled bool `json:"clicks_enabled"`
// Subdomain is the tracking subdomain prefix, or nil when tracking is off.
Subdomain *string `json:"subdomain"`
// DNSRecords holds the branded-tracking records to publish. Empty when off.
DNSRecords []DNSRecord `json:"dns_records"`
// Status is "disabled", "pending", or "verified".
Status string `json:"status"`
// VerificationFailure is the most recent tracking-CNAME failure, or nil.
VerificationFailure *VerificationFailure `json:"verification_failure"`
// VerifiedAt is when the tracking CNAME was last observed resolving, or nil.
VerifiedAt *string `json:"verified_at"`
}
DomainTracking is a domain's branded open/click tracking configuration. It is independent of mail-flow verification.
type DomainTrackingParams ¶
type DomainTrackingParams struct {
OpensEnabled *bool `json:"opens_enabled,omitempty"`
ClicksEnabled *bool `json:"clicks_enabled,omitempty"`
// Subdomain is the tracking subdomain prefix. Required when either tracking
// flag is turned on; leave nil to keep the current value unchanged.
Subdomain *string `json:"subdomain,omitempty"`
}
DomainTrackingParams is the mutable tracking configuration on an update. Leave a pointer nil to leave that field unchanged.
type DomainUpdateParams ¶
type DomainUpdateParams struct {
Tracking DomainTrackingParams `json:"tracking"`
}
DomainUpdateParams is the body for DomainsService.Update. Only tracking configuration is mutable; the domain name is immutable.
type DomainsService ¶
type DomainsService struct {
// contains filtered or unexported fields
}
DomainsService holds the /domains operations. Access it via Client.Domains.
func (*DomainsService) Create ¶
func (s *DomainsService) Create(ctx context.Context, params *DomainCreateParams, opts ...RequestOption) (*Domain, error)
Create adds a sending domain. The returned domain is pending until verified.
func (*DomainsService) Delete ¶
func (s *DomainsService) Delete(ctx context.Context, id string, opts ...RequestOption) error
Delete permanently removes a domain and its DKIM keys.
func (*DomainsService) Get ¶
func (s *DomainsService) Get(ctx context.Context, id string, opts ...RequestOption) (*Domain, error)
Get retrieves a single domain by id.
func (*DomainsService) List ¶
func (s *DomainsService) List(ctx context.Context, params ListParams, opts ...RequestOption) (*Page[Domain], error)
List returns one page of the team's domains, newest-first. Range over the returned page's All method to walk every page, or follow NextCursor yourself.
func (*DomainsService) Update ¶
func (s *DomainsService) Update(ctx context.Context, id string, params *DomainUpdateParams, opts ...RequestOption) (*Domain, error)
Update changes a domain's tracking configuration. The domain name is immutable.
func (*DomainsService) Verify ¶
func (s *DomainsService) Verify(ctx context.Context, id string, opts ...RequestOption) (*Domain, error)
Verify triggers a verification check. It always returns the current domain — read Status and VerificationFailure to learn the outcome; a still-pending domain is not an error. Safe to poll while DNS propagates.
type EmailBatchRequest ¶
type EmailBatchRequest struct {
// Defaults fills any field an entry omits. To is excluded — recipients are
// always per-entry. Reuse SendEmailRequest, leaving To zero.
Defaults *SendEmailRequest `json:"defaults,omitempty"`
// Emails holds the 1-100 messages in the batch.
Emails []SendEmailRequest `json:"emails"`
}
EmailBatchRequest is the body for a batch send: 1-100 messages, with optional batch-wide defaults.
type EmailService ¶
type EmailService struct {
// contains filtered or unexported fields
}
EmailService holds the /email operations. Access it via Client.Email.
func (*EmailService) Send ¶
func (s *EmailService) Send(ctx context.Context, email *SendEmailRequest, opts ...RequestOption) (*SendResponse, error)
Send sends a single message. All addresses in To/CC/BCC share one envelope. It returns the queued message id; a failure returns an *Error.
When retries are enabled and no WithIdempotencyKey is supplied, the client generates one so a retried send cannot deliver twice. Pass WithIdempotencyKey to dedupe across process restarts.
func (*EmailService) SendBatch ¶
func (s *EmailService) SendBatch(ctx context.Context, batch *EmailBatchRequest, opts ...RequestOption) (*BatchResponse, error)
SendBatch sends 1-100 independent messages in one request. A mixed-outcome batch (HTTP 207) returns normally — inspect each entry's Status in Data; it does not return an error.
type Error ¶
type Error struct {
// Type is the stable, machine-readable error type. Branch on this.
Type ErrorType
// Message is the human-readable description from the API.
Message string
// Status is the HTTP status code, or 0 when no response was received.
Status int
// RequestID is the server-assigned request id, when the response carried
// one. Quote it in support requests.
RequestID string
// ValidationErrors maps a field path to its list of problems. Populated
// only for ErrorTypeValidation.
ValidationErrors map[string][]string
// RetryAfter is the server-advised wait before retrying. Populated only for
// ErrorTypeRateLimit when the response carried a Retry-After header.
RetryAfter time.Duration
// Body is the raw response body, for inspection beyond the parsed fields.
Body []byte
// contains filtered or unexported fields
}
Error is the single error type returned by every SDK call that fails. A request that reached the API and came back non-2xx carries Type, Status, and (when sent) RequestID; a request that never got a response carries ErrorTypeConnection, a zero Status, and a wrapped cause.
Use errors.As to recover it, then switch on Type:
var apiErr *anypost.Error
if errors.As(err, &apiErr) {
switch apiErr.Type {
case anypost.ErrorTypeValidation:
// apiErr.ValidationErrors: field -> messages
case anypost.ErrorTypeRateLimit:
// apiErr.RetryAfter
}
}
type ErrorType ¶
type ErrorType string
ErrorType is the stable, machine-readable classification of an API error. Branch on this rather than on the HTTP status: the type is part of the API contract, the status is not.
const ( ErrorTypeValidation ErrorType = "validation_error" ErrorTypeAuthentication ErrorType = "authentication_error" ErrorTypePermission ErrorType = "permission_error" ErrorTypeNotFound ErrorType = "not_found" ErrorTypeConflict ErrorType = "conflict" ErrorTypeIdempotencyConflict ErrorType = "idempotency_concurrent" ErrorTypeIdempotencyMismatch ErrorType = "idempotency_mismatch" ErrorTypeWebhookRotation ErrorType = "webhook_rotation_in_progress" ErrorTypeRateLimit ErrorType = "rate_limit_exceeded" ErrorTypePayloadTooLarge ErrorType = "payload_too_large" ErrorTypeProvisioning ErrorType = "provisioning_error" ErrorTypeInternal ErrorType = "internal_error" // ErrorTypeConnection is set when no HTTP response was received (a network // failure, timeout, or context cancellation). Status is then 0 and the // underlying cause is available via errors.Unwrap. ErrorTypeConnection ErrorType = "connection_error" )
type Event ¶
type Event struct {
// ID is the stable id for log correlation. Not addressable — there is no
// GET /events/{id}.
ID string `json:"id"`
Type EventType `json:"type"`
// OccurredAt is the ISO 8601 UTC timestamp when the event was observed.
OccurredAt string `json:"occurred_at"`
// EmailID is the email_<uuidv7> id minted when the message was accepted.
EmailID *string `json:"email_id"`
// MessageID is the RFC 5322 Message-ID: header, when one was stamped.
MessageID *string `json:"message_id"`
// From is the envelope From: address.
From *string `json:"from"`
// FromDomain is the From: domain, lowercased.
FromDomain *string `json:"from_domain"`
// Recipient is the single recipient this event refers to.
Recipient *string `json:"recipient"`
// Subject is the captured Subject: header, truncated at the capture limit.
Subject *string `json:"subject"`
// Campaign is the originating send's campaign value.
Campaign *string `json:"campaign"`
// TemplateID is the public id of the template the originating send used.
TemplateID *string `json:"template_id"`
// Topic is the send-time topic the message was tagged with.
Topic *string `json:"topic"`
// Tags are the customer-supplied tags from the originating send.
Tags []string `json:"tags"`
// IPPool is which dedicated IP pool the message egressed from. Nil on
// sends that named no pool and on accounts without dedicated IPs. Set on
// every event for the message, not just email.sent, so bounce and
// complaint rates can be read per pool.
IPPool *string `json:"ip_pool"`
// SMTPCode is the SMTP reply code observed, or nil without an SMTP exchange.
SMTPCode *int `json:"smtp_code"`
// BounceType is why the message failed. Only on email.bounced, and one of:
// "permanent" — the receiver refused the address outright (5xx). The
// address is suppressed; this is what counts against list
// quality.
// "transient" — a temporary failure still unresolved when the message
// was reported, e.g. an out-of-band 4xx DSN.
// "expired" — aged out of the retry queue after 72 hours without ever
// reaching the receiver. Not a hard bounce, and the
// address is not suppressed.
BounceType *string `json:"bounce_type"`
// BounceClassification is the bounce classification. Only on email.bounced.
BounceClassification *string `json:"bounce_classification"`
// Attempt is the delivery attempt number, or nil for non-delivery events.
Attempt *int `json:"attempt"`
// Tracking is the tracking metadata, mirroring the webhook payload's
// data.tracking. Nil on every event except opens/clicks, and on human
// opens/clicks. Its Bot is set when the open/click came from a mailbox
// image proxy.
Tracking *EventTracking `json:"tracking"`
}
Event is a single email-pipeline event for the team. Every field is always present; fields that don't apply to a given event type are null on the wire (nil pointers / zero values here) rather than absent.
type EventBot ¶ added in v1.1.0
type EventBot struct {
// Source is the detected mailbox image proxy, e.g. "google", "yahoo", "bing".
Source string `json:"source"`
// Kind is always "proxy" on customer-visible events.
Kind string `json:"kind"`
}
EventBot classifies a proxied open or click. Pure-noise machine traffic (mailbox prefetchers, scanners) never becomes an event, so the only Kind a customer ever sees is "proxy" — a real open whose origin is anonymized by a mailbox image proxy (Gmail, Yahoo, etc.).
type EventListParams ¶
type EventListParams struct {
ListParams
// Start is the ISO 8601 start of the window (inclusive).
Start string
// End is the ISO 8601 end of the window (exclusive).
End string
EventType EventType
// Recipient is an exact recipient address.
Recipient string
// EmailID restricts to one message's email_<uuidv7> id.
EmailID string
// MessageID is an exact Message-ID: header match.
MessageID string
// Domain is a sending-domain hostname (not the domain_<uuid> id).
Domain string
Topic string
// Campaign is a case-sensitive exact match.
Campaign string
// TemplateID is the template the originating send used.
TemplateID string
// IPPool restricts to mail that egressed from this named dedicated IP
// pool. Exact match against the [a-z0-9]([a-z0-9-]*[a-z0-9])? pool-name
// shape; a value outside it returns an empty list rather than being
// ignored, so a typo cannot silently widen the answer to "all pools".
IPPool string
// Tags restricts to events carrying any of these tags (hasAny). Up to 10.
Tags []string
}
EventListParams are the filters for EventsService.List. The window defaults to the last 24 hours and is clamped to the plan's retention. All filters are exact-match except Tags (hasAny).
type EventTracking ¶ added in v1.1.0
type EventTracking struct {
Bot *EventBot `json:"bot,omitempty"`
}
EventTracking is the tracking metadata on email.opened / email.clicked events, mirroring the webhook payload's data.tracking. Bot is set only when the interaction came from a mailbox image proxy; a human open/click has no Bot.
type EventType ¶
type EventType string
EventType is a customer-facing event type in the event stream. The same set is emitted via webhooks; operational events are never returned here.
const ( EventSent EventType = "email.sent" EventDelivered EventType = "email.delivered" EventDelayed EventType = "email.delayed" EventBounced EventType = "email.bounced" EventComplained EventType = "email.complained" EventSuppressed EventType = "email.suppressed" EventUnsubscribed EventType = "email.unsubscribed" EventOpened EventType = "email.opened" EventClicked EventType = "email.clicked" )
type EventsService ¶
type EventsService struct {
// contains filtered or unexported fields
}
EventsService holds read access to the /events stream. List-only — events are not addressable by id. Access it via Client.Events.
func (*EventsService) List ¶
func (s *EventsService) List(ctx context.Context, params EventListParams, opts ...RequestOption) (*Page[Event], error)
List returns one page of the team's events, newest-first.
type IdentityService ¶
type IdentityService struct {
// contains filtered or unexported fields
}
IdentityService holds the /whoami operation.
func (*IdentityService) Whoami ¶
func (s *IdentityService) Whoami(ctx context.Context, opts ...RequestOption) (*WhoamiResponse, error)
Whoami identifies the team and permission level behind the current API key.
type ListParams ¶
type ListParams struct {
// Limit is the page size, 1-100. Zero uses the server default (20).
Limit int
// After is a cursor from a previous page's NextCursor. Opaque — do not parse.
After string
}
ListParams are the cursor-pagination parameters shared by every list endpoint. A zero value requests the first page with the server default size.
type Option ¶
type Option func(*clientConfig)
Option configures a Client in New.
func WithBaseURL ¶
WithBaseURL overrides the API base URL. Defaults to the production endpoint.
func WithDefaultHeader ¶
WithDefaultHeader adds a header sent on every request.
func WithHTTPClient ¶
WithHTTPClient supplies a custom *http.Client. Use this to inject a transport (proxy, custom TLS, or a test RoundTripper). The client's own per-request timeout still applies on top via context.
func WithMaxRetries ¶
WithMaxRetries sets the number of automatic retries for transient failures (429/502/503 and network errors). Defaults to 2. Set 0 to disable.
func WithTimeout ¶
WithTimeout sets the per-request timeout. Defaults to 30s. A zero or negative value disables the client-imposed timeout (the context still applies).
type Page ¶
type Page[T any] struct { // Data holds the items on this page. Data []T // HasMore reports whether another page exists. HasMore bool // NextCursor is the cursor for the next page, or "" when there are none. // Pass it back as ListParams.After to fetch that page yourself. NextCursor string // contains filtered or unexported fields }
Page is one page of a list result. It mirrors the wire envelope (Data, HasMore, NextCursor); call Next to fetch the following page, or range over All to walk every remaining item across pages.
type Permissions ¶
type Permissions string
Permissions is the permission level of an API key.
const ( // PermissionFull grants management and send access. PermissionFull Permissions = "full" // PermissionSendOnly grants send access only. PermissionSendOnly Permissions = "send_only" )
type RequestOption ¶
type RequestOption func(*requestConfig)
RequestOption overrides behavior for a single call.
func WithHeader ¶
func WithHeader(name, value string) RequestOption
WithHeader adds (or overrides) a header on a single request.
func WithIdempotencyKey ¶
func WithIdempotencyKey(key string) RequestOption
WithIdempotencyKey sets the Idempotency-Key for a send. Reusing a key with an identical body replays the stored result; reusing it with a different body fails with ErrorTypeIdempotencyMismatch. Only the send endpoints honor it.
type SendEmailRequest ¶
type SendEmailRequest struct {
// From is the sender address on a verified domain, bare or
// "Display Name <addr@host>". Required for a standalone send; omit on a
// batch entry to inherit Defaults.From.
From string `json:"from,omitempty"`
// To holds 1-50 primary recipients. Combined To+CC+BCC must be <= 50.
To []string `json:"to,omitempty"`
CC []string `json:"cc,omitempty"`
// BCC recipients. Counts against the combined recipient cap.
BCC []string `json:"bcc,omitempty"`
// ReplyTo holds one address or up to 10.
ReplyTo []string `json:"reply_to,omitempty"`
// Subject is required unless a referenced template supplies it.
Subject string `json:"subject,omitempty"`
Text string `json:"text,omitempty"`
HTML string `json:"html,omitempty"`
// TemplateID references a published template (template_<uuid>). Cannot be
// combined with inline Text/HTML.
TemplateID string `json:"template_id,omitempty"`
// Headers are custom message headers. At most 25 survive server-side.
Headers map[string]string `json:"headers,omitempty"`
// Attachments holds up to 20 inline attachments.
Attachments []Attachment `json:"attachments,omitempty"`
// Tags holds up to 10 free-form labels ([A-Za-z0-9_-]{1,64}).
Tags []string `json:"tags,omitempty"`
// Campaign is a stream-segmentation label ([A-Za-z0-9_-]{1,64}).
Campaign string `json:"campaign,omitempty"`
// Topic is the suppression scope / topic bucket ([a-z0-9_.-]{1,64}).
Topic string `json:"topic,omitempty"`
// IPPool names which of your dedicated IP pools this message sends from
// ([a-z0-9]([a-z0-9-]*[a-z0-9])?, at most 32 chars). Accounts with
// dedicated IPs and more than one named pool only. Unlike Tags, Topic and
// Campaign this is not a reporting label — it changes how the message is
// delivered, keeping one stream's reputation and queueing off another's.
// Leave zero to use the account's default pool; an unrecognized name
// returns 422 listing the pools the account does have.
IPPool string `json:"ip_pool,omitempty"`
// Tracking overrides the domain's open/click defaults for this message.
Tracking *Tracking `json:"tracking,omitempty"`
// Variables is the Handlebars substitution map. Encoded JSON must be <= 64 KB.
Variables map[string]any `json:"variables,omitempty"`
// Unsubscribe controls one-click unsubscribe header injection.
Unsubscribe *Unsubscribe `json:"unsubscribe,omitempty"`
}
SendEmailRequest is a single message to send.
For a standalone Send, From and To are required, and at least one of Text, HTML, or TemplateID must be set (the API enforces this). As a batch entry, From (and any other shared field) may be omitted to inherit the batch Defaults — leave it zero and set EmailBatchRequest.Defaults.
type SendResponse ¶
type SendResponse struct {
// ID is the public message identifier (email_<uuidv7>).
ID string `json:"id"`
CreatedAt string `json:"created_at"`
}
SendResponse is returned by a successful single send.
type Suppression ¶
type Suppression struct {
// ID is the sup_-prefixed id, for log correlation. Lookups/deletes key on
// (email, topic).
ID string `json:"id"`
// Email is the suppressed address, normalized to lowercase.
Email string `json:"email"`
// Topic this suppression applies to. "*" means every topic.
Topic string `json:"topic"`
Reason SuppressionReason `json:"reason"`
Origin SuppressionOrigin `json:"origin"`
// Classification is a bounce classification or ARF feedback-type, nil for
// manual entries.
Classification *string `json:"classification"`
// SMTPCode is the SMTP reply code from the bounce, nil for complaints and
// manual entries.
SMTPCode *int `json:"smtp_code"`
// Note is a free-form note attached at creation.
Note *string `json:"note"`
// SuppressedAt is when the suppression was first observed.
SuppressedAt string `json:"suppressed_at"`
// ExpiresAt is when it stops applying, nil means never.
ExpiresAt *string `json:"expires_at"`
CreatedAt string `json:"created_at"`
}
Suppression is a suppressed recipient address, scoped to a topic.
type SuppressionCreateParams ¶
type SuppressionCreateParams struct {
Email string `json:"email"`
// Topic scopes the suppression. Omit or "*" to block every topic.
Topic string `json:"topic,omitempty"`
// Note is an optional internal annotation, preserved across automatic
// re-suppressions.
Note string `json:"note,omitempty"`
}
SuppressionCreateParams is the body for SuppressionsService.Create.
type SuppressionListParams ¶
type SuppressionListParams struct {
ListParams
// EmailContains is a case-insensitive substring match against the address.
EmailContains string
// Topic restricts to a topic. "*" for global entries.
Topic string
Reason SuppressionReason
Origin SuppressionOrigin
}
SuppressionListParams are the filters for SuppressionsService.List.
type SuppressionOrigin ¶
type SuppressionOrigin string
SuppressionOrigin is the provenance of a suppression row.
const ( SuppressionOriginAuto SuppressionOrigin = "auto" SuppressionOriginManual SuppressionOrigin = "manual" )
type SuppressionReason ¶
type SuppressionReason string
SuppressionReason is why an address is suppressed.
const ( SuppressionReasonPermanentBounce SuppressionReason = "permanent_bounce" SuppressionReasonComplaint SuppressionReason = "complaint" SuppressionReasonUnsubscribed SuppressionReason = "unsubscribed" SuppressionReasonManual SuppressionReason = "manual" )
type SuppressionsService ¶
type SuppressionsService struct {
// contains filtered or unexported fields
}
SuppressionsService holds the /suppressions operations. Entries key on (email, topic). Access it via Client.Suppressions.
func (*SuppressionsService) Create ¶
func (s *SuppressionsService) Create(ctx context.Context, params *SuppressionCreateParams, opts ...RequestOption) (*Suppression, error)
Create adds a manual suppression. Defaults to topic "*" (every topic). It returns a validation_error if an active entry for the same (email, topic) exists.
func (*SuppressionsService) Delete ¶
func (s *SuppressionsService) Delete(ctx context.Context, email, topic string, opts ...RequestOption) error
Delete removes the single (email, topic) row. Other topics are untouched.
func (*SuppressionsService) DeleteForEmail ¶
func (s *SuppressionsService) DeleteForEmail(ctx context.Context, email string, opts ...RequestOption) error
DeleteForEmail removes an address from the suppression list across every topic.
func (*SuppressionsService) Get ¶
func (s *SuppressionsService) Get(ctx context.Context, email, topic string, opts ...RequestOption) (*Suppression, error)
Get retrieves the suppression for an (email, topic) pair. Use "*" as the topic for the global row. It returns a not_found error if the pair isn't suppressed.
func (*SuppressionsService) List ¶
func (s *SuppressionsService) List(ctx context.Context, params SuppressionListParams, opts ...RequestOption) (*Page[Suppression], error)
List returns one page of the team's suppressions, newest-first. Expired rows are filtered out.
func (*SuppressionsService) ListForEmail ¶
func (s *SuppressionsService) ListForEmail(ctx context.Context, email string, opts ...RequestOption) ([]Suppression, error)
ListForEmail returns every suppression on file for an address, across all topics. It returns a not_found error if the address has no active suppressions.
type Template ¶
type Template struct {
// ID is the template_-prefixed id.
ID string `json:"id"`
// Name is the identifier, unique within the team.
Name string `json:"name"`
// Subject is the published subject line, nil until first published.
Subject *string `json:"subject"`
Kind TemplateKind `json:"kind"`
// HTML is the published HTML body, nil until first published.
HTML *string `json:"html"`
// Text is the published, machine-derived plain-text body, nil until first
// published.
Text *string `json:"text"`
// Markdown is the published emailmd source, set only for kind=markdown.
Markdown *string `json:"markdown"`
// HasDraft reports whether an unpublished draft is pending.
HasDraft bool `json:"has_draft"`
// PublishedAt is when last published, or nil if never.
PublishedAt *string `json:"published_at"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
Template is a reusable email template. The Subject/HTML/Text/Markdown fields hold the published content and are nil until first published. Edits land in a draft; Publish promotes the draft. Sends always use the published content.
type TemplateCreateParams ¶
type TemplateCreateParams struct {
Name string `json:"name"`
Subject *string `json:"subject,omitempty"`
// Kind defaults to html and is immutable once the template exists.
Kind TemplateKind `json:"kind,omitempty"`
HTML *string `json:"html,omitempty"`
Markdown *string `json:"markdown,omitempty"`
}
TemplateCreateParams is the body for TemplatesService.Create. The new template starts unpublished. For kind=html supply HTML; for kind=markdown supply Markdown. The plain-text body is always derived server-side.
type TemplateDraft ¶
type TemplateDraft struct {
Subject *string `json:"subject"`
HTML *string `json:"html"`
// Text is always machine-derived from the draft's HTML/Markdown.
Text *string `json:"text"`
Markdown *string `json:"markdown"`
UpdatedAt string `json:"updated_at"`
}
TemplateDraft is the unpublished draft content for a template.
type TemplateDraftParams ¶
type TemplateDraftParams struct {
Subject *string `json:"subject,omitempty"`
HTML *string `json:"html,omitempty"`
Markdown *string `json:"markdown,omitempty"`
}
TemplateDraftParams is the body for TemplatesService.UpdateDraft. For kind=html supply HTML; for kind=markdown supply Markdown.
type TemplateDuplicateParams ¶
type TemplateDuplicateParams struct {
// Name for the copy. Defaults to "<source name> (copy)" when omitted.
Name string `json:"name,omitempty"`
}
TemplateDuplicateParams is the body for TemplatesService.Duplicate.
type TemplateKind ¶
type TemplateKind string
TemplateKind is a template's authoring format. Immutable once a template exists.
const ( TemplateKindHTML TemplateKind = "html" TemplateKindMarkdown TemplateKind = "markdown" )
type TemplateUpdateParams ¶
type TemplateUpdateParams struct {
Name string `json:"name"`
}
TemplateUpdateParams is the body for TemplatesService.Update. Only Name is mutable; content is draft-versioned.
type TemplatesService ¶
type TemplatesService struct {
// contains filtered or unexported fields
}
TemplatesService holds the /templates operations, including the draft/publish flow. Access it via Client.Templates.
func (*TemplatesService) Create ¶
func (s *TemplatesService) Create(ctx context.Context, params *TemplateCreateParams, opts ...RequestOption) (*Template, error)
Create makes a template. It starts unpublished — publish it before sending.
func (*TemplatesService) Delete ¶
func (s *TemplatesService) Delete(ctx context.Context, id string, opts ...RequestOption) error
Delete permanently removes a template.
func (*TemplatesService) DeleteDraft ¶
func (s *TemplatesService) DeleteDraft(ctx context.Context, id string, opts ...RequestOption) error
DeleteDraft discards the template's draft without touching published content.
func (*TemplatesService) Duplicate ¶
func (s *TemplatesService) Duplicate(ctx context.Context, id string, params *TemplateDuplicateParams, opts ...RequestOption) (*Template, error)
Duplicate copies a template. The copy starts unpublished with a draft seeded from the source's current editable content. Pass nil params to accept the default name.
func (*TemplatesService) Get ¶
func (s *TemplatesService) Get(ctx context.Context, id string, opts ...RequestOption) (*Template, error)
Get retrieves a template, including its published content.
func (*TemplatesService) GetDraft ¶
func (s *TemplatesService) GetDraft(ctx context.Context, id string, opts ...RequestOption) (*TemplateDraft, error)
GetDraft retrieves the template's unpublished draft. It returns a not_found error if none exists.
func (*TemplatesService) List ¶
func (s *TemplatesService) List(ctx context.Context, params ListParams, opts ...RequestOption) (*Page[Template], error)
List returns one page of the team's templates, newest-first.
func (*TemplatesService) Publish ¶
func (s *TemplatesService) Publish(ctx context.Context, id string, opts ...RequestOption) (*Template, error)
Publish promotes the draft into the published slot, consuming the draft.
func (*TemplatesService) Update ¶
func (s *TemplatesService) Update(ctx context.Context, id string, params *TemplateUpdateParams, opts ...RequestOption) (*Template, error)
Update changes a template's name. Body content lives on the draft.
func (*TemplatesService) UpdateDraft ¶
func (s *TemplatesService) UpdateDraft(ctx context.Context, id string, params *TemplateDraftParams, opts ...RequestOption) (*TemplateDraft, error)
UpdateDraft creates or updates the template's draft. Idempotent upsert; published content is untouched.
type Tracking ¶
type Tracking struct {
// Opens injects the open-tracking pixel into the HTML body when non-nil.
Opens *bool `json:"opens,omitempty"`
// Clicks rewrites links for click tracking when non-nil.
Clicks *bool `json:"clicks,omitempty"`
}
Tracking overrides the sending domain's open/click tracking defaults for one message. A nil field leaves that dimension at the domain default.
type Unsubscribe ¶
type Unsubscribe struct {
Mode UnsubscribeMode `json:"mode"`
// DisplayName is the human-readable label rendered on the hosted
// confirmation page.
DisplayName string `json:"display_name,omitempty"`
}
Unsubscribe configures one-click unsubscribe headers for a send.
type UnsubscribeMode ¶
type UnsubscribeMode string
UnsubscribeMode is the one-click unsubscribe behavior for a send.
const ( // UnsubscribeGenerate mints a per-recipient signed token and injects RFC // 8058 unsubscribe headers. Requires a Topic on the send. UnsubscribeGenerate UnsubscribeMode = "generate" // UnsubscribeNone injects nothing — for transactional sends that must not // carry unsubscribe semantics. UnsubscribeNone UnsubscribeMode = "none" )
type VerificationFailure ¶
type VerificationFailure struct {
// Code is a stable, switchable failure code.
Code string `json:"code"`
// Message is a human-readable description with record names interpolated.
Message string `json:"message"`
}
VerificationFailure is a stable failure category plus a human-readable message.
type VerifyOption ¶
type VerifyOption func(*verifyConfig)
VerifyOption configures webhook signature verification.
func WithNow ¶
func WithNow(unixSeconds int64) VerifyOption
WithNow overrides the current time (Unix seconds) used for the freshness check. For tests.
func WithTolerance ¶
func WithTolerance(d time.Duration) VerifyOption
WithTolerance overrides the maximum delivery age. A zero value disables the freshness check.
type Webhook ¶
type Webhook struct {
ID string `json:"id"`
Name string `json:"name"`
URL string `json:"url"`
Events []WebhookEventType `json:"events"`
Status WebhookStatus `json:"status"`
// SigningSecretPrefix is the first 12 characters of the signing secret.
SigningSecretPrefix string `json:"signing_secret_prefix"`
// SigningSecretPreviousPrefix is the prefix of the previous secret while a
// rotation grace window is open, else nil.
SigningSecretPreviousPrefix *string `json:"signing_secret_previous_prefix"`
// SigningSecretGraceExpiresAt is when the rotation grace window ends, or nil.
SigningSecretGraceExpiresAt *string `json:"signing_secret_grace_expires_at"`
LastDeliveryAt *string `json:"last_delivery_at"`
CreatedAt string `json:"created_at"`
}
Webhook is a webhook subscription. The signing secret is never returned here.
type WebhookCreateParams ¶
type WebhookCreateParams struct {
Name string `json:"name"`
// URL is an https:// endpoint to receive signed deliveries.
URL string `json:"url"`
// Events is at least one event type to subscribe to.
Events []WebhookEventType `json:"events"`
}
WebhookCreateParams is the body for WebhooksService.Create.
type WebhookDelivery ¶
type WebhookDelivery struct {
// BatchID identifies this batch. Stable across retries — de-duplicate on it.
BatchID string `json:"batch_id"`
// Timestamp is the Unix timestamp the batch was signed with.
Timestamp int64 `json:"timestamp"`
Events []WebhookDeliveryEvent `json:"events"`
}
WebhookDelivery is the outer envelope of a webhook delivery: one batch of one or more events.
func UnwrapWebhookEvent ¶
func UnwrapWebhookEvent(payload []byte, signatureHeader, secret string, opts ...VerifyOption) (*WebhookDelivery, error)
UnwrapWebhookEvent verifies a delivery and returns its parsed body. It is a thin wrapper over VerifyWebhookSignature that unmarshals only after the signature checks out.
type WebhookDeliveryEvent ¶
type WebhookDeliveryEvent struct {
// ID is the unique event id. Stable across retries — de-duplicate on it.
ID string `json:"id"`
// Type is a WebhookEventType or "webhook.test".
Type string `json:"type"`
OccurredAt string `json:"occurred_at"`
// Data always carries email_id; the rest depends on the event type.
Data map[string]any `json:"data"`
}
WebhookDeliveryEvent is one event inside a WebhookDelivery.
type WebhookEventType ¶
type WebhookEventType string
WebhookEventType is an event type a webhook can subscribe to.
const ( WebhookEventSent WebhookEventType = "email.sent" WebhookEventDelivered WebhookEventType = "email.delivered" WebhookEventDelayed WebhookEventType = "email.delayed" WebhookEventBounced WebhookEventType = "email.bounced" WebhookEventComplained WebhookEventType = "email.complained" WebhookEventSuppressed WebhookEventType = "email.suppressed" WebhookEventUnsubscribed WebhookEventType = "email.unsubscribed" WebhookEventOpened WebhookEventType = "email.opened" WebhookEventClicked WebhookEventType = "email.clicked" )
type WebhookStatus ¶
type WebhookStatus string
WebhookStatus is a webhook's delivery state. Only "active" and "disabled" can be set through the API; "circuit_disabled" is server-managed.
const ( WebhookStatusActive WebhookStatus = "active" WebhookStatusDisabled WebhookStatus = "disabled" WebhookStatusCircuitDisabled WebhookStatus = "circuit_disabled" )
type WebhookTestResult ¶
type WebhookTestResult struct {
// Delivered is true only when the endpoint returned a 2xx status.
Delivered bool `json:"delivered"`
// StatusCode is the HTTP status the endpoint returned, or nil on a network
// failure.
StatusCode *int `json:"status_code"`
// LatencyMS is wall-clock time from request start to response or error.
LatencyMS int `json:"latency_ms"`
// Error is a human-readable failure reason, or nil on success.
Error *string `json:"error"`
// ResponseBodyPreview is a truncated preview of the endpoint's response body.
ResponseBodyPreview *string `json:"response_body_preview"`
}
WebhookTestResult is the outcome of a synchronous test delivery. A bad endpoint never returns an error — read Delivered and StatusCode.
type WebhookUpdateParams ¶
type WebhookUpdateParams struct {
Name string `json:"name"`
URL string `json:"url"`
Events []WebhookEventType `json:"events"`
// Status sets "disabled" to pause delivery or "active" to resume.
Status WebhookStatus `json:"status"`
}
WebhookUpdateParams is the body for WebhooksService.Update.
type WebhookVerificationError ¶
type WebhookVerificationError struct {
// Reason is the machine-readable cause. Branch on this.
Reason WebhookVerificationReason
Message string
}
WebhookVerificationError is returned when a webhook delivery's signature cannot be verified.
func (*WebhookVerificationError) Error ¶
func (e *WebhookVerificationError) Error() string
type WebhookVerificationReason ¶
type WebhookVerificationReason string
WebhookVerificationReason is the machine-readable cause of a signature verification failure. Branch on it rather than the message.
const ( // ReasonMalformedHeader means the Anypost-Signature header could not be parsed. ReasonMalformedHeader WebhookVerificationReason = "malformed_header" // ReasonNoTimestamp means the header carried no t= component. ReasonNoTimestamp WebhookVerificationReason = "no_timestamp" // ReasonNoSignatures means the header carried no v1= component. ReasonNoSignatures WebhookVerificationReason = "no_signatures" // ReasonTimestampOutOfTolerance means the delivery is older than the tolerance. ReasonTimestampOutOfTolerance WebhookVerificationReason = "timestamp_out_of_tolerance" // ReasonNoMatch means no v1= component matched the computed signature. ReasonNoMatch WebhookVerificationReason = "no_match" )
type WebhookWithSecret ¶
type WebhookWithSecret struct {
Webhook
// SigningSecret is the full signing secret (whsec_...). Returned once; store
// it securely.
SigningSecret string `json:"signing_secret"`
}
WebhookWithSecret is a webhook with its full signing secret. Returned only on create and rotate-secret.
type WebhooksService ¶
type WebhooksService struct {
// contains filtered or unexported fields
}
WebhooksService holds the /webhooks operations. Access it via Client.Webhooks.
func (*WebhooksService) Create ¶
func (s *WebhooksService) Create(ctx context.Context, params *WebhookCreateParams, opts ...RequestOption) (*WebhookWithSecret, error)
Create makes a webhook. The full SigningSecret is on this response only — store it now to verify future deliveries; later reads return only the prefix.
func (*WebhooksService) Delete ¶
func (s *WebhooksService) Delete(ctx context.Context, id string, opts ...RequestOption) error
Delete permanently removes a webhook.
func (*WebhooksService) Get ¶
func (s *WebhooksService) Get(ctx context.Context, id string, opts ...RequestOption) (*Webhook, error)
Get retrieves a webhook. The signing secret is never returned — only its prefix.
func (*WebhooksService) List ¶
func (s *WebhooksService) List(ctx context.Context, params ListParams, opts ...RequestOption) (*Page[Webhook], error)
List returns one page of the team's webhooks, newest-first.
func (*WebhooksService) RotateSecret ¶
func (s *WebhooksService) RotateSecret(ctx context.Context, id string, opts ...RequestOption) (*WebhookWithSecret, error)
RotateSecret rotates the signing secret. The new secret is on this response only. The previous secret stays valid for a 24h grace window. Rotating again before the window ends returns a webhook_rotation_in_progress conflict.
func (*WebhooksService) Test ¶
func (s *WebhooksService) Test(ctx context.Context, id string, opts ...RequestOption) (*WebhookTestResult, error)
Test sends one synthetic webhook.test event and reports the outcome. One-shot, not retried, and absent from delivery history. It returns the result even when the endpoint fails — read Delivered and StatusCode. Works on a disabled webhook too.
func (*WebhooksService) Update ¶
func (s *WebhooksService) Update(ctx context.Context, id string, params *WebhookUpdateParams, opts ...RequestOption) (*Webhook, error)
Update changes a webhook's name, URL, events, and status. It does not rotate the signing secret — use RotateSecret.
type WhoamiAPIKey ¶
type WhoamiAPIKey struct {
ID string `json:"id"`
Permissions Permissions `json:"permissions"`
}
WhoamiAPIKey identifies the API key on the request.
type WhoamiLimits ¶ added in v1.4.0
type WhoamiLimits struct {
// Daily is the messages the team may send per calendar day (UTC).
// Exceeding it returns 429 with scope "daily".
Daily int `json:"daily"`
// Monthly is the messages the team may send per billing month. Exceeding
// it returns 429 with scope "monthly", unless prepaid overage credits
// cover the excess; those are not counted here.
Monthly int `json:"monthly"`
// DeliveryRatePerMinute is how fast accepted mail is released to receiving
// servers. It is not a request limit and never a rejection: mail beyond
// this rate queues and drains at the metered rate.
DeliveryRatePerMinute int `json:"delivery_rate_per_minute"`
}
WhoamiLimits are the sending limits currently enforced against a team. These are effective values and can differ from the plan defaults, so read them at runtime rather than hardcoding them.
type WhoamiResponse ¶
type WhoamiResponse struct {
// Team is the team the key belongs to, or nil if it could not be resolved.
Team *WhoamiTeam `json:"team"`
// APIKey describes the key on the request.
APIKey WhoamiAPIKey `json:"api_key"`
// Limits are the sending limits in force for the team, or nil if the team
// could not be resolved.
Limits *WhoamiLimits `json:"limits"`
}
WhoamiResponse is the identity resolved from the request's API key.
type WhoamiTeam ¶
WhoamiTeam identifies the team behind the API key.