Mex feature wraps WhatsApp’s Meta Exchange (MEX) GraphQL API. Operations are persisted: you reference each query or mutation by a (name, id) pair pulled from a generated operation module, and pass its typed Variables. WhatsApp Web bundle updates rotate the numeric id, so the human-readable name keeps diagnostics stable across releases.
Access
Building a request
mex_operation! binds operation name, persisted document ID, declared keys, and generated variables type from the same module. An unrelated variables type fails to compile. Generated Variables, nested input/response shapes and response mirrors are non-exhaustive and implement Default. Construct with Default and assign the fields you need. External struct literals, including ..Default::default(), no longer compile. None omits a key where the serializer allows it; it supplies no protocol default or validation of server-required variables.
execute
Mex::execute(MexRequest<V>) is the shared path for queries and mutations, with V: Serialize. It serializes directly to wire bytes and returns MexResponse. Generated response mirrors are heuristic; use a domain parser before treating the payload as a feature contract.
Use operation.raw_request(serializable_value) when a generated variables mirror cannot represent the intended input. The descriptor’s metadata stays bound to that operation. For custom persisted operations, MexOperation::from_raw_parts or MexRequest::new_raw is the explicit unchecked path; the host owns metadata consistency.
MexRequest
Metadata is private. Read it withdoc() and declared_variables(); variables remains public. missing_variables() is an optional diagnostic that compares serialized top-level keys, including keys omitted by skip_serializing_if. It allocates a JSON value and is not automatically enforced on execution. A declared key is not proof of a required server variable.
Convenience operations
Usefetch_reachout_timelock, fetch_new_chat_message_capping_info, and get_username for the library’s parsed contracts. ReachoutTimelockUpdate delivers parsed push updates separately from these reads. See events.
Types
OwnUsername
This account’s own Meta username, asget_username reports it. Every field is optional because the server omits the ones that don’t apply.
NewChatMessageCapping
How many new one-on-one conversations you can still start in the current cycle, and why. Every field is optional — the server omits any that don’t apply to your account’s tier.total_quota/used_quota— new chats allowed / already started this cyclecycle_start_timestamp/cycle_end_timestamp/server_sent_timestamp— Unix seconds. The cap lifts oncecycle_end_timestamppasses.
remaining_quota() -> Option<u64>— saturating subtraction ofused_quotafromtotal_quota, when both are present; returnsSome(0)whenused_quotaexceedstotal_quota
CappingStatus
Where you stand against the cap.CappingOteStatus
Whether you’re eligible for the one-time extension that lifts the cap for a cycle.CappingMvStatus
Your Meta Verified subscription state, which lifts the cap permanently.NewChatMessageCapping, CappingStatus, CappingOteStatus, and CappingMvStatus are re-exported from the crate root, alongside the other Mex types.Error handling
execute converts a fatal GraphQL response into MexError::ExtensionError while preserving its numeric code. Fatal selection checks a summary error, then an error with error_code, then the first error with fallback code 500. The typed MexFatalError remains reachable through an IQ parse-error source chain at lower levels.
get_username treats a fatal 404 as “no username set” rather than a failure. It arrives as either MexError::ExtensionError { code: 404, .. } or MexError::Request(IqError::ServerError { code: 404, .. }) — the two shapes WhatsApp Web’s own MEX client raises a 404 from. Either shape returns Ok(None) instead of an error.
MexFatalError
whatsapp_rust::wacore::iq::mex::MexFatalError retains the operation’s query: &'static str, numeric code: i32, and message: String. Use typed matching or source-chain inspection rather than parse its display text. Read the pinned MEX response parser for fatal selection and parsing.
Response handling
Check for data
Handle non-fatal errors
Errors without anerror_code are non-fatal and surface in response.errors alongside any partial data.
Decode the typed response
Generated operation modules also expose aResponse struct that mirrors the GraphQL schema. Decode it from response.data with serde_json:
The persisted
DOC_ID for each operation is regenerated from the latest WhatsApp Web bundle. Pin to a specific crate version if you need a stable wire format.