Update sender
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Body
Turn the voice channel on or off. The sender must already have a phone number provisioned for calls; enabling it otherwise returns 400 instead of storing a flag that changes nothing. Confirm with the channels array on the response.
Turn the one-way SMS channel on or off. Enabling needs nothing else and takes effect immediately; disabling removes the channel from the sender. Confirm with the channels array on the response.
HTTPS URL for webhook events. Set to null to remove webhook.
Events to subscribe to.
Type of event that triggers the webhook.
Message lifecycle events:
message.queued: Message created and queued for sending.data.status=queuedmessage.sent: Message accepted by the provider.data.status=sentmessage.delivered: Message delivered to recipient.data.status=deliveredmessage.read: Message was read by the recipient (WhatsApp only).data.status=readmessage.failed: Message failed to send.data.status=failed
Inbound events:
message.inbound: New message received from a contact.data.conversationIdis the inbox thread id (deep-link withhttps://dashboard.zavu.dev/{locale}/inbox?conv={conversationId}); it isnullwhile the conversation row is still being created (the first message of a brand-new thread, or several near-simultaneous first messages), whereconversation.newcarries the id instead —GET /v1/messages/{messageId}always has it. Reactions are delivered asmessage.inboundwithmessageType='reaction'. When the contact replied to (quoted) an earlier message,data.contentcarries the reply context:replyToMessageId,replyToProviderMessageId,replyToFrom,replyToText, andreplyToMessageType.data.providerTimestampis the provider's original receive time in Unix milliseconds (the moment the channel received the message from the contact — WhatsApp, Telegram, Instagram, Messenger;nullfor SMS and email). Compare it against the top-leveltimestamp(when Zavu dispatched the webhook) to detect and ignore delayed deliveries. When the conversation was opened from a Click-to-WhatsApp ad or post,data.referralcarries the ad attribution — includingctwaClid, the identifier Meta's Conversions API needs to credit a conversion back to that ad. WhatsApp only, and only on the first message of the thread: it is absent from every later message, so persist it when it arrives.message.unsupported: Received a message type that is not supported
Broadcast events:
broadcast.status_changed: Broadcast status changed (pending_review, approved, rejected, sending, completed, cancelled)
Other events:
conversation.new: New conversation started with a contact.datacarriesconversationId(the inbox thread id — deep-link withhttps://dashboard.zavu.dev/{locale}/inbox?conv={conversationId}), thephoneNumberoremailkey,channel,firstMessageId,firstMessageText, andprofileName.template.status_changed: WhatsApp template approval status changed.datacarriestemplateId,name,previousStatus,currentStatus,rejectionReason, andcategory— the category Meta currently bills the template under. Meta can recategorize a template (typicallyUTILITYtoMARKETING) at approval or long afterwards, which changes what each message costs;categoryis how that reaches you. A recategorization with no status change is delivered as this same event, so comparecategoryagainst what you hold rather than only reacting tocurrentStatus.
Partner events:
invitation.status_changed: A partner invitation's stored status changed: toin_progress,completed,failed,cancelled, or back topendingwhen it is resent from the dashboard. A change to the same status sends nothing, and expiry is not a stored change, so no event is sent when an invitation expires. Delivered to the project webhook (POST /v1/invitations/webhook) of the project that created the invitation; a parent project does not receive its sub-accounts' events.datacarriesinvitationId,clientName,clientEmail,connectionType(whatsapp_wabaormessenger),previousStatus, andcurrentStatus. Oncompletedit also carriessenderId,connectedAccount(channel,id,name) — the WhatsApp number or Facebook Page that was linked — and, for WhatsApp,wabaAccountId. Onfailedit carriesfailureReason; the invitation link stays usable, so a client can retry it.
Voice Agent events:
For every voice event, data carries callId, direction, from, to, status, durationSeconds, endReason, and transcriptAvailable. The terminal events (call.completed, call.failed) additionally carry cost — what the call was billed, in USD, combining telephony and the managed voice pipeline — and currency. They are dispatched after the call is charged, so cost is populated rather than zero; telephony can still be settling on an outbound call, in which case GET /v1/calls/{callId} holds the reconciled figure.
call.initiated: An outbound call was created and is dialing, or an inbound call was received.data.status=ringingcall.answered: The call was answered and the voice agent is connected.data.status=in_progresscall.completed: The call ended after a conversation.data.status=completed;durationSecondsandendReasondescribe how it ended, andtranscriptAvailableindicates whether a transcript can be fetched.call.failed: The call could not be completed (busy, no answer, canceled, or an error).data.statusis the terminal status andendReasonexplains the cause.
Custom domain events:
domain.verified: A custom email domain passed verification (DKIM, and SPF/DMARC/MAIL FROM if enhanced records are enabled)domain.failed: A custom email domain failed verification or is partially verified
message.queued, message.sent, message.delivered, message.read, message.status, message.failed, message.inbound, message.unsupported, broadcast.status_changed, conversation.new, template.status_changed, invitation.status_changed, call.initiated, call.answered, call.completed, call.failed, domain.verified, domain.failed Whether the webhook is active.
Enable or disable inbound email receiving for this sender. Enabling requires a verified inbound MX record on the domain; the request is ignored otherwise, and emailReceivingEnabled comes back false on the response. Disabling always applies.
Enable or disable domain catch-all. When enabled (with emailReceivingEnabled true), this sender receives email for any address at its domain. Ignored (treated as false) if receiving is not enabled.
Attach or change the sender's email from-address (e.g. noreply@yourdomain.com). The domain must be a verified email domain in your project.
"noreply@yourdomain.com"
ID of the verified email domain to attach. Optional — resolved from emailAddress's domain when omitted.
Display name shown in the recipient's inbox for the email channel.
100Move this webhook between signature schemes. v1 -> v2 directly returns 400; go through v1+v2 first. See https://docs.zavu.dev/guides/receiving-messages/signature-migration
v1, v1+v2, v2 "v2"
Response
Sender updated.
"sender_12345"
"Primary sender"
Phone number in E.164 format.
"+13125551212"
Channels this sender can actually send on right now: configured AND activated. Empty means the sender cannot send or receive anything yet: a phoneNumber alone does not enable SMS or voice, and a connected account that is not activated is left out, because every send on it is refused. Check this rather than inferring capability from phoneNumber or emailAddress, and turn a connected channel on with POST /v1/senders/{senderId}/channels/{channel}/activate.
Whether this sender is the project's default.
Webhook configuration for the sender.
WhatsApp Business Account information. Only present if a WABA is connected.
From-address for the email channel, if configured.
"noreply@yourdomain.com"
Whether inbound email receiving is enabled for this sender.
Whether catch-all receiving is enabled. When true (and emailReceivingEnabled is true), this sender receives email addressed to any local part at its domain, not just its own address. The original recipient is delivered in the message.inbound webhook's data.to.
