Skip to main content
The Newsletter feature provides methods for managing WhatsApp newsletter channels, including creation, subscription management, admin operations, reactions, and live updates. Newsletter operations use MEX (GraphQL) for metadata/management and IQ stanzas for message operations. Newsletter message sending is handled by the unified client.send_message() method — see the Send API. Reactions remain on the Newsletter struct because they use a different stanza format.
Newsletter messages are plaintext — they are not encrypted with the Signal protocol.

Access

Access newsletter operations through the client:

Methods

list_subscribed

List all newsletters the user is subscribed to.
Returns:
  • Vec<NewsletterMetadata> — List of subscribed newsletters
Example:

get_metadata

Fetch metadata for a newsletter by its JID.
Parameters:
  • jid — Newsletter JID (server must be newsletter)
Returns:
  • NewsletterMetadata — Full newsletter metadata
Example:

get_metadata_by_invite

Fetch metadata for a newsletter by its invite code.
Parameters:
  • invite_code — Newsletter invite code string
Returns:
  • NewsletterMetadata — Full newsletter metadata
Example:

create

Create a new newsletter.
Parameters:
  • name — Newsletter name
  • description — Optional description
Returns:
  • NewsletterMetadata — Metadata of the newly created newsletter
Example:

join

Join (subscribe to) a newsletter.
Parameters:
  • jid — Newsletter JID to join
Returns:
  • NewsletterMetadata — Metadata with the viewer’s role set to Subscriber
Example:

leave

Leave (unsubscribe from) a newsletter.
Parameters:
  • jid — Newsletter JID to leave
Example:

update

Update a newsletter’s name and/or description.
Parameters:
  • jid — Newsletter JID
  • name — New name, or None to keep the current name
  • description — New description, or None to keep the current description
Returns:
  • NewsletterMetadata — Updated metadata
Example:

set_picture

Replace a newsletter’s picture. Carried by the same mutation as update — WhatsApp Web edits the picture as base64-encoded JPEG bytes — so the response is the newsletter’s refreshed metadata.
Parameters:
  • jid — Newsletter JID
  • jpeg — JPEG-encoded image bytes
Returns:
  • NewsletterMetadata — Updated metadata
Example:

remove_picture

Remove a newsletter’s picture.
Parameters:
  • jid — Newsletter JID
Returns:
  • NewsletterMetadata — Updated metadata
Example:

delete

Delete a newsletter. Owner-only.
Parameters:
  • jid — Newsletter JID
Example:

change_owner

Transfer a newsletter’s ownership to another user. Owner-only.
Parameters:
  • jid — Newsletter JID
  • user — The new owner. May be a LID or a phone-number JID — a phone-number JID is resolved to its LID before the request. If no LID is known for the target, the call fails with NewsletterError::InvalidRequest rather than sending an address the server can’t route.
Example:

demote_admin

Demote an admin of a newsletter back to subscriber. Owner-only.
Parameters:
  • jid — Newsletter JID
  • user — The admin to demote. Same LID resolution as change_owner.
Example:

get_admin_info

Fetch a newsletter’s admin-side information, including its admin count.
Parameters:
  • jid — Newsletter JID
Returns:
  • NewsletterAdminInfo — Admin count, the viewer’s own admin profile, and the admin-profiles setting
The admin count has no query of its own — it rides along with the admin profile and the admin-profiles setting in this one response. The server only answers it for admins and owners, so admin_count is None for everyone else.
Example:

get_followers

List up to count of a newsletter’s followers (subscribers).
Parameters:
  • jid — Newsletter JID
  • count — Maximum number of followers to return
This operation takes no cursor — WhatsApp Web asks for a single page clamped to its subscriber-list limit, so count is the whole request. There is no built-in pagination.
Returns:
  • Vec<NewsletterFollower> — One page of followers
Example:

set_follower_mute

Mute or unmute a newsletter’s follower-activity notifications (WhatsApp Web’s MUTE_FOLLOWER_ACTIVITY). Sent via MEX as a user-setting update.
Parameters:
  • jid — Newsletter JID
  • mutedtrue silences notifications, false re-enables them
Example:

set_admin_mute

Mute or unmute a newsletter’s admin-activity notifications (WhatsApp Web’s MUTE_ADMIN_ACTIVITY). Only meaningful for owners/admins.
Parameters:
  • jid — Newsletter JID
  • mutedtrue silences admin-activity notifications, false re-enables them
Example:
The mute state is sent as ON/OFF; the mute expiration is local database state and is never put on the wire, matching WhatsApp Web’s WAWebNewsletterUpdateUserSettingJob.

Sending messages

Newsletter message sending is handled by the unified client.send_message() method. See the Send API reference for full details.
The library detects newsletter recipients automatically and sends messages as plaintext (no Signal encryption), with the correct type and mediatype stanza attributes inferred from the message content. Stanza-level <meta> nodes (for polls, events, etc.) are also included automatically, matching WhatsApp Web behavior.
Newsletter::send_message() was removed. Use client.send_message() instead — it accepts newsletter, group, and direct message JIDs.

send_reaction

Send a reaction to a newsletter message.
Parameters:
  • jid — Newsletter JID
  • server_id — Server-assigned ID of the message to react to
  • reaction — Emoji code (e.g., "👍", "❤️"), or empty string to remove
Example:

edit_message

Edit a previously-sent newsletter message. Channel messages are plaintext, so the edit is sent as a <message edit="1"> stanza with the new protobuf body — not through the E2E send path.
Parameters:
  • jid — Newsletter JID. Non-newsletter JIDs are rejected with an error; use Client::edit_message for DMs and groups.
  • message_id — The target message’s message_id (the wire stanza id, as returned by send_message or carried on NewsletterMessage). This is not the server_id used by reactions. Empty IDs are rejected.
  • new_content — Replacement message body. Typically a wa::Message { conversation: Some(..), .. } for text edits.
Example:

revoke_message

Revoke (delete) a previously-sent newsletter message. Like edit_message, this goes through the plaintext channel path, not the E2E send path.
Parameters:
  • jid — Newsletter JID. Non-newsletter JIDs are rejected; use Client::revoke_message for DMs and groups.
  • message_id — The target message’s message_id (wire stanza id, not server_id). Empty IDs are rejected.
Example:
Newsletter JIDs are now also rejected at the root of the E2E send path. If your code accidentally routes a channel JID through send_message_impl, pin_message, or the standard edit_message / revoke_message on Client, you get an error that names the mis-route instead of a malformed encrypted fan-out.

get_messages

Fetch message history from a newsletter.
Parameters:
  • jid — Newsletter JID
  • count — Maximum number of messages to return
  • before — If set, return messages before this server_id (for pagination)
Returns:
  • Vec<NewsletterMessage> — List of newsletter messages
Example:

subscribe_live_updates

Subscribe to live updates for a newsletter (reaction counts, message changes).
Parameters:
  • jid — Newsletter JID
Returns:
  • u64 — Subscription duration in seconds (typically 300)
The server sends Event::NewsletterLiveUpdate events with updated reaction counts. You need to re-subscribe periodically when the duration expires. Example:

Types

NewsletterMetadata

Metadata for a newsletter channel. Implements PartialEq and Eq for direct comparison.

NewsletterVerification

NewsletterState

NewsletterRole

The viewer’s role in a newsletter.
All newsletter enums are #[non_exhaustive], so match statements should include a wildcard arm to handle future variants.

NewsletterAdminProfile

An admin’s public profile within a newsletter, carried on NewsletterAdminInfo and on a NewsletterFollower who is an admin.
id is the profile’s own identifier, not a JID — the server hands it back as an opaque string and WhatsApp Web never parses it.

NewsletterAdminInfo

Admin-side information about a newsletter, returned by get_admin_info.
  • admin_count — How many admins the newsletter has. The server only answers this for admins and owners, so it’s None for everyone else — never a 0 that would misleadingly read as “no admins”.
  • admin_profile — The viewer’s own admin profile, present once they’ve set one up.
  • admin_profiles_enabled — Whether admin profiles are enabled for this newsletter.

NewsletterFollower

A follower (subscriber) of a newsletter, returned by get_followers.
  • jid — The follower’s identity JID — a LID on accounts that have migrated.
  • phone_jid — The follower’s phone-number JID, withheld by the server when the follower’s privacy settings hide it.
  • role — The follower’s role in the newsletter.
  • follow_time — When the follower subscribed (Unix seconds).
  • admin_profile — Set when the follower is an admin who has published a profile.

NewsletterMessage

A message from a newsletter’s history. #[non_exhaustive] — construct it from parsed responses rather than by struct literal, so newly-added counters land as fields, not breaks.
  • message_id — Wire stanza id. Pass this to edit_message and revoke_message; it is not the same as server_id, which reactions use. Empty when the server omitted it.
  • server_id — Server-assigned monotonic id. Use it as the pagination cursor in get_messages and as the target for send_reaction.
  • timestamp — Message timestamp (Unix seconds). Moves with an edit.
  • message_typeText, Media, or Poll on the wire. An edit or revocation is not a message type; see edit. Reactions are counts on the reacted-to message, not a type.
  • editAdminEdit (3) for an edited message, AdminRevoke (8) for a revoked one, Empty otherwise. A revoked message keeps its envelope, drops its body, its forward counter, and message becomes None.
  • message — Decoded protobuf message from the <plaintext> bytes. None when the server sent no body (for example, after a revocation, or when the payload was empty).
  • media_type — Hint about the payload readable without decoding it. Unknown values are kept as NewsletterMediaType::Other.
  • reactions — Aggregated per-emoji counts.
  • votes — Per-option tallies when this is a poll message; empty otherwise. See NewsletterPollVote.
  • forwards_count — How many times the message was forwarded. None means the server omitted the counter; treat it as distinct from Some(0).
  • views_count, responses_count — View count and channel-question response count. Contract-derived; a follower-side capture never carried them, so expect None unless the viewer’s role in the channel entitles them to those figures.
  • original_timestamp<meta original_msg_t> in Unix seconds: when the message was first posted, as opposed to timestamp, which moves with an edit.
  • last_edit_timestamp_ms<meta msg_edit_t> in Unix milliseconds (unlike every other timestamp on this struct): when the message was last edited.
  • poll_type — The poll’s lifecycle stage (creation, quiz creation, result snapshot). Populated only when message_type is Poll, matching WhatsApp Web’s scoping.
  • content_type, question_type, message_association_type<meta> classifiers. question_type is question for a channel question or reply for an admin reply. message_association_type records how this media relates to another message (media_poll, motion_photo, poll_add_option, …).
  • is_wamo_sub<meta is_wamo_sub="true">.
  • admin_profile — Publishing admin’s public profile, on channels that enabled admin profiles.
  • rcat<rcat> payload bytes. Opaque receiver-side token WhatsApp Web associates with type="media" + mediatype="url" link previews; carried verbatim and not interpreted.

NewsletterMessageType

The type attribute of a newsletter history <message>. Uses a wire enum with an Other(String) fallback so a future value on the wire deserializes rather than fails.
Only Text, Media, and Poll are produced by the wire; the other named variants are kept for source compatibility with earlier releases and will never match a parsed response. Read edits and revocations from NewsletterMessage::edit, poll stage from NewsletterMessage::poll_type, poll totals from NewsletterMessage::votes, and reaction totals from NewsletterMessage::reactions. Methods:
  • as_str() — Wire-protocol string representation.
  • From<&str> — Parse from a wire string; unknown values become Other(String).

NewsletterMediaType

The mediatype attribute of newsletter <plaintext>. Known values match the whatspec IR; anything else is kept as Other(String) for forward compatibility.

NewsletterQuestionType

The questiontype attribute in newsletter <meta>.

NewsletterMessageAssociationType

The message_association_type attribute in newsletter <meta>. Describes how a media message relates to another message.

NewsletterReactionCount

A reaction count on a newsletter message.

NewsletterPollVote

A poll option’s vote tally on a newsletter message. Channel polls are counted server-side, so unlike a DM or group vote the totals arrive in plaintext — nothing to decrypt.
Votes with malformed hashes or a missing or malformed required count are dropped during parsing; a valid count="0" is preserved and remains distinct from absence.

Error handling

All newsletter methods return Result<T, NewsletterError>: