WebhookEmail
Webhook signing documentation corrected
Webhook Signature Verification said webhooks are signed with your Account API Key. They are not: since May 2026 a webhook request is signed only when the webhook has its own secret, and a webhook without one is delivered withoutX-SendPost-Signature.- Set a secret with
secreton Create Webhook or Update Webhook, or in the dashboard when you create the webhook. Then verify with that secret wherever you used the API key; the verification code is otherwise unchanged. secretis now listed in the webhook request schema. The API already accepted it.- A per-email
webhookEndpointreceives the email’s events in addition to your account webhooks, not instead of them. Requests to it are signed only when its URL exactly matches an account webhook that has a secret. See Per-Email Webhook Endpoints.
WebhookSub-Account
Webhook create and update fixes
- Create Webhook no longer fails with an empty HTTP 500 when the body has no
eventSubOptions. - Fields you leave out on create now take their documented defaults:
enabledand most events are on. Sendfalsefor anything you don’t want. The SDKs already sent these defaults, so SDK integrations are unaffected. - Update Webhook now changes only the fields you send. Before, every field you left out was switched off and the URL was cleared.
urlmust be an absolutehttp://orhttps://URL. Anything else returns HTTP 422 with{"error": "<reason>"}, and the other webhook errors now carry the same body.- The sub-account
apiKeyis returned only when you create a sub-account or regenerate its key. Listing or getting sub-accounts doesn’t include it.
WebhookEmail
Real-time validation results on webhooks
Sub-accounts with the Real-Time List Cleaning add-on can now receive the result of each email’s address check as a Validation webhook event (type82). See Real-Time Validation Results.event.validationStatusisvalid,invalid,catch allorunknown.invalidemails are not sent.- Turn it on with
validated: trueon an account webhook, or the Validation checkbox in the dashboard. Filter results witheventSubOptions.validated. - Skip the check for one email with
skipValidation: trueon Send Email and Send Email With Template, or the headerX-Sendpost-Validate: false. - The webhook event type list now shows SMTP Dropped as
26, its real value (it was listed as10).
validated receive the same events as before, and validated only appears in webhook responses when it is on.Email
tpspFrom sender for third-party providers
Send Email and Send Email With Template accept an optional tpspFrom sender. Emails delivered through a third-party sending provider (SendGrid, Amazon SES, Mailgun, SparkPost, Postmark or Custom SMTP) go out as tpspFrom; emails delivered on SendPost IPs still go out as from.tpspFrommust be on the same registered domain asfrom, and must be set up as a sender at the provider.- Stats and webhook events stay under
from. - An invalid
tpspFromrejects the request with HTTP 400 anderrorCode11.
tpspFrom, sending works exactly as before.v1 contract
Versioned response contract (legacy → v1)
The public REST API now supports two response contracts, selected per request with theX-SendPost-Public-Contract header.legacy(today’s shape) remains the default — existing integrations are unaffected.v1is available now viaX-SendPost-Public-Contract: v1.- Responses carry
Deprecation,Sunset(31 March 2027, 23:59:59 UTC), andLinkheaders. After the sunset,v1becomes the default.
What v1 changes, field by field
v1 normalizes field casing, removes internal/sensitive fields, and adds a few new fields. The complete diff per resource:Suppression
Suppression
- Added:
reasonText— public reason label (manual/unsubscribe/hardBounce/spamComplaint/unknown). - Removed:
groups,ipId,accountIPPoolId(plus dashboard-onlyipPublicIP,ipPoolName). - Note:
smtpErroris unchanged (already camelCase in legacy — it is not renamed).
IP
IP
- Added:
autoWarmupEnabled(boolean; computed from warmup state). - Renamed:
publicIP→publicIp,reverseDNSHostname→reverseDnsHostname. - Removed:
systemDomain,accountIPPools,autoWarmupPlan(replaced byautoWarmupEnabled),deliverabilityPolicies, and all per-provider settings blobs (gmailSettings…checkpointSettings).
IP Pool
IP Pool
- Sub-account pools: add
shouldOverflow,overflowPoolName. No removals. - Account pools: removed
thirdPartySendingProviders,toAccountIPPools,warmupInterval,warmupIntervalSeconds,warmupQueueMode,resolveTemplateLocally. - Nested
ips[]follow the IP changes above.
Domain
Domain
- Added:
dnsProvider(detected DNS host). - Removed:
gpt,gptVerified,dkimDelegationInfo,dmarcDelegationInfo,returnPathDelegationInfo,trackDelegationInfo. - Unchanged under v1: the
domain/v2endpoints (/subaccount/domain/v2,/account/domain/v2) return the same shape for legacy and v1.
Message
Message
- Renamed:
messageID→messageId,subAccountID→subAccountId,publicIP→publicIp. - Removed:
customFields,resolveTemplateLocally(plus internal-plumbing fields already hidden from legacy).
Event
Event
- Renamed:
eventID→eventId,messageID→messageId,messageSubject→subject. - Removed (top-level):
smtpCode,smtpDescription(still available nested undereventMetadata), plus mock-send flags. eventMetadata: renamedclickedURL→clickedUrl,trackedIP→trackedIp,cityID→cityId; removedsendpostLinkIdand all provider-specific fields (sendgrid*,ses*,sparkpost*,mailgun*,customSmtp*,postmark*).
SubAccount
SubAccount
- Removed:
smtpAuths,blocked_at,hb_exempt,generate_weekly_report,skip_global_suppression_check,handlers(plusblock_reason,created_by,updated_byalready hidden from legacy). apiKey,accountIdare unchanged.
Member
Member
- Renamed:
url→logoUrl. - Removed:
isForbidden,notesColor,twoFactorEnabled,twoFactorVerifiedAt(plusfirebaseUID,isGodModealready hidden from legacy).
Webhook
Webhook
- Removed:
secret(HMAC signing key),eventSubOptions.secretremains available on the legacy contract for same-account callers. - List variant (
successRate):v1always returns a number; legacy returnsnullwhen unmeasured.
Account / Account Setting
Account / Account Setting
- Renamed:
logoURL→logoUrl. - Removed: all billing internals (
stripe*,creditBalance,promoCode,isLegacyBilling,trialPeriod, …), moderation/ops fields (demoLocked*,*SlackEndpoint,slackToken,rbacEnabled,hubspotCompanyId, …) and audit fields. Public callers already receive the curatedv1shape today.
Email (send)
Email (send)
EmailResponse: no field changes (to,submittedAt,messageId,errorCode,message).- Request body: the TPSP routing internals
tpspIppool,tpspTemplate,tpspIpare not part of the v1 shape.
Stats (all stat endpoints)
Stats (all stat endpoints)
Pervasive v1 changes across the stat family:
- Removed everywhere: the bot/human breakdown
botOpened,botClicked,humanOpened,humanClicked; the ops-onlyspamRate,totalQD,warmupVersion,warmupSkipped; and the rawday/month/yeardate columns. - Renamed:
publicIP→publicIp,ipid→ipId; provider statsemail_type→emailType(andemail_type/name→provideron the provider breakdown); sub-account statssid→subAccountId,name→subAccountName; account IP-pool statsaccountIPPoolId→ipPoolId,name→ipPoolName. seedContactStatsnested keys renamed:rStat→rStats,agStat→groupStats,agDomainStat→domainStats,aIPStat→ipStats,aPStat→providerStats.blacklistResourcenormalized fromSnake_Case/PascalCaseto camelCase throughout (Add_Date→addDate,Last_Check→lastCheck,Contact_List_ID→contactListId, etc.).?filter=botreturns a normalized{ enabled, raw, filtered, botOpened, botClicked }view under v1.- Unchanged:
dateStat,validationStat,accountCycleUsage,postmasterDomainStat.
For the authoritative response of any endpoint under
v1, the schema on that endpoint’s API Reference page is the source of truth.