> ## Documentation Index
> Fetch the complete documentation index at: https://whatsapp-rust.jlucaso.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Status

> Post, react to, and manage WhatsApp status/story updates

The `Status` feature provides APIs for posting text, image, and video status updates, reacting to statuses (e.g. the "like" heart), and revoking previously sent statuses.

## Access

Access status operations through the client:

```rust theme={null}
let status = client.status();
```

## Methods

### send\_text

Send a text status update with background color and font style.

```rust theme={null}
pub async fn send_text(
    &self,
    text: &str,
    background_argb: u32,
    font: wa::message::extended_text_message::FontType,
    recipients: &[Jid],
    options: StatusSendOptions,
) -> Result<SendResult, SendError>
```

**Parameters:**

* `text` - Status text content
* `background_argb` - Background color as ARGB (e.g., `0xFF1E6E4F`)
* `font` - Pass one of the `FontType` variants (e.g. `FontType::SYSTEM`). This is a typed protocol enum, so you can't pass a value it doesn't define — an older `i32` form silently dropped out-of-range values at encode time
* `recipients` - Slice of recipient JIDs
* `options` - Privacy and delivery options

**Returns:**

* `SendResult` containing the `message_id` and `to` JID. Use `result.message_key()` to get a `wa::MessageKey` for revocation or other follow-up operations.

**Example:**

```rust theme={null}
use waproto::whatsapp as wa;
use whatsapp_rust::{Jid, StatusSendOptions};

let recipients = [
    Jid::pn("15551234567"),
    Jid::pn("15559876543"),
];

let result = client.status()
    .send_text(
        "Hello from Rust!",
        0xFF1E6E4F, // Green background
        wa::message::extended_text_message::FontType::SYSTEM,
        &recipients,
        StatusSendOptions::default(),
    )
    .await?;

println!("Status sent: {}", result.message_id);
```

### send\_image

Send an image status update.

```rust theme={null}
pub async fn send_image(
    &self,
    upload: UploadResponse,
    thumbnail: Vec<u8>,
    caption: Option<&str>,
    recipients: &[Jid],
    options: StatusSendOptions,
) -> Result<SendResult, SendError>
```

**Parameters:**

* `upload` - Upload response from `client.upload()` (takes ownership)
* `thumbnail` - JPEG thumbnail bytes
* `caption` - Optional caption text
* `recipients` - Slice of recipient JIDs
* `options` - Privacy options

**Example:**

```rust theme={null}
use wacore::download::MediaType;

// Upload the image first
let image_data = std::fs::read("photo.jpg")?;
let upload = client.upload(image_data, MediaType::Image, Default::default()).await?;

// Create thumbnail (simplified - use proper JPEG encoding)
let thumbnail = create_thumbnail(&image_data)?;

let result = client.status()
    .send_image(
        upload,
        thumbnail,
        Some("Check this out!"),
        &[Jid::pn("15551234567")],
        StatusSendOptions::default(),
    )
    .await?;
```

### send\_video

Send a video status update.

```rust theme={null}
pub async fn send_video(
    &self,
    upload: UploadResponse,
    thumbnail: Vec<u8>,
    duration_seconds: u32,
    caption: Option<&str>,
    recipients: &[Jid],
    options: StatusSendOptions,
) -> Result<SendResult, SendError>
```

**Parameters:**

* `upload` - Upload response from `client.upload()` (takes ownership)
* `thumbnail` - JPEG thumbnail bytes
* `duration_seconds` - Video duration
* `caption` - Optional caption text
* `recipients` - Slice of recipient JIDs
* `options` - Privacy options

**Example:**

```rust theme={null}
use wacore::download::MediaType;

let video_data = std::fs::read("video.mp4")?;
let upload = client.upload(video_data, MediaType::Video, Default::default()).await?;
let thumbnail = extract_video_thumbnail(&video_data)?;

let result = client.status()
    .send_video(
        upload,
        thumbnail,
        30, // 30 seconds
        None,
        &[Jid::pn("15551234567")],
        StatusSendOptions::default(),
    )
    .await?;
```

### send\_raw

Send a custom message type as a status update.

```rust theme={null}
pub async fn send_raw(
    &self,
    message: wa::Message,
    recipients: &[Jid],
    options: StatusSendOptions,
) -> Result<SendResult, SendError>
```

**Example:**

```rust theme={null}
use waproto::whatsapp as wa;

let message = wa::Message {
    extended_text_message: buffa::MessageField::some(wa::message::ExtendedTextMessage {
        text: Some("Custom message".to_string()),
        ..Default::default()
    }),
    ..Default::default()
};

let result = client.status()
    .send_raw(message, recipients, StatusSendOptions::default())
    .await?;
```

### revoke

Delete a previously sent status update.

```rust theme={null}
pub async fn revoke(
    &self,
    message_id: impl Into<String>,
    recipients: &[Jid],
    options: StatusSendOptions,
) -> Result<SendResult, SendError>
```

**Parameters:**

* `message_id` - ID of the status to revoke
* `recipients` - Same recipients the status was sent to
* `options` - Privacy options

**Example:**

```rust theme={null}
use waproto::whatsapp::message::extended_text_message::FontType;

// Send a status
let result = client.status()
    .send_text("Temporary status", 0xFF000000, FontType::SYSTEM, &recipients, Default::default())
    .await?;

// Later, revoke it
client.status()
    .revoke(&result.message_id, &recipients, Default::default())
    .await?;
```

### send\_reaction

React to a status update with an emoji. You send status reactions via `Client::send_reaction` (not `client.status()`) using `status@broadcast` as the chat JID and a `wa::MessageKey` whose `participant` field identifies the status owner.

```rust theme={null}
pub async fn send_reaction(
    &self,
    chat: impl Into<Jid>,
    target_key: wa::MessageKey,
    emoji: &str,
) -> Result<SendResult, SendError>
```

**Parameters:**

* `chat` - `Jid::status_broadcast()` (the broadcast JID)
* `target_key` - Identifies the status to react to; set `participant` to the status owner's JID and `id` to the status message ID
* `emoji` - Emoji to send (e.g. `"💚"`). Pass `""` to remove a previous reaction

**Example:**

```rust theme={null}
use waproto::whatsapp as wa;

let status_jid = Jid::status_broadcast();

let target_key = wa::MessageKey {
    remote_jid: Some(status_jid.to_string()),
    from_me: Some(false),
    id: Some(status_message_id.clone()),
    participant: Some(Jid::pn("15551234567").to_string()),
};

// React to a status
client.send_reaction(&status_jid, target_key.clone(), "💚").await?;

// Remove a previous reaction
client.send_reaction(&status_jid, target_key, "").await?;
```

<Note>
  See [Send API — send\_reaction](/api/send#send_reaction) for the full parameter reference and additional examples.
</Note>

## Types

### StatusPrivacySetting

Privacy setting for status delivery.

```rust theme={null}
#[non_exhaustive]
pub enum StatusPrivacySetting {
    /// Send to all contacts in address book (default)
    Contacts,
    /// Send only to contacts in an allow list
    AllowList,
    /// Send to all contacts except those in a deny list
    DenyList,
}
```

`StatusPrivacySetting` is `#[non_exhaustive]`, so match statements should include a wildcard arm to handle future variants.

### StatusSendOptions

Options for sending status updates.

```rust theme={null}
pub struct StatusSendOptions {
    /// Privacy setting for this status. Sent in the `<meta>` stanza node.
    pub privacy: StatusPrivacySetting,
    /// Override the generated message ID.
    pub message_id: Option<String>,
    /// Extra child nodes appended to the status stanza.
    pub extra_stanza_nodes: Vec<Node>,
    /// Freshness policy for the recipient device lists used by this send.
    pub device_freshness: Freshness,
}
```

* `message_id` - Set this to resend a failed status with its original ID, or to otherwise ensure idempotency. Leave it `None` to auto-generate an ID. Same override use case as `SendOptions::message_id` on 1:1/group sends — see [Send API — SendOptions](/api/send#sendoptions).
* `extra_stanza_nodes` - Add neutral child nodes here to include them on the outgoing `<message>` stanza. Don't use this for structural children the send path owns (e.g. `<enc>`, `<participants>`) — those are rejected before any cryptographic state changes.
* `device_freshness` - Leave this at `Freshness::CachePreferred` (default) to reuse the cached recipient device list, or set `Freshness::Refresh` to force a fresh device-list fetch before sending. See [`Freshness`](/api/groups#freshness).

**Example:**

```rust theme={null}
use whatsapp_rust::{Freshness, StatusSendOptions, StatusPrivacySetting};

// Send to all contacts
let options = StatusSendOptions::default();

// Send to allow list only, forcing a fresh device-list fetch
let options = StatusSendOptions {
    privacy: StatusPrivacySetting::AllowList,
    device_freshness: Freshness::Refresh,
    ..Default::default()
};
```

## Font styles

WhatsApp Web supports 5 font styles (0-4):

| Index | Style                  |
| ----- | ---------------------- |
| 0     | Default (sans-serif)   |
| 1     | Serif                  |
| 2     | Typewriter (monospace) |
| 3     | Bold script            |
| 4     | Condensed              |

## Background colors

Background colors use ARGB format (`0xAARRGGBB`):

```rust theme={null}
// Solid green
let green = 0xFF1E6E4F_u32;

// Solid blue
let blue = 0xFF1A73E8_u32;

// Solid red
let red = 0xFFD93025_u32;

// Semi-transparent black
let overlay = 0x80000000_u32;
```

## Recipient management

Recipients should be JIDs of users who can see the status. You can pass any `&[Jid]` — an array literal, a slice of a `Vec`, or a fixed-size array:

```rust theme={null}
// Single recipient (array literal)
let recipients = &[Jid::pn("15551234567")];

// Multiple recipients
let recipients = &[
    Jid::pn("15551234567"),
    Jid::pn("15559876543"),
    "15557654321@s.whatsapp.net".parse()?,
];

// From an existing Vec
let jids = vec![Jid::pn("15551234567")];
let recipients = &jids;
```

<Note>
  The `recipients` list should match your privacy settings. When revoking a status, use the same recipients list that was used when posting.
</Note>

## Phash validation

After sending a status update, the library validates the participant hash (`phash`) from the server's acknowledgment against the locally computed value. On mismatch, the sender key device cache is invalidated so the next status send re-fetches current device lists. This runs in the background and does not affect the send result. See [Signal Protocol — Phash validation](/advanced/signal-protocol#phash-validation-for-stale-device-list-detection) for details.
