> ## 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.

# Privacy

> Privacy settings management - fetch, update, and configure account privacy

The privacy API allows you to fetch and update account-level privacy settings, such as who can see your last seen, profile photo, about text, and online status. All methods use type-safe enums for categories and values.

## Access

Privacy operations are available directly on the `Client`:

```rust theme={null}
use whatsapp_rust::privacy_settings::{PrivacyCategory, PrivacyValue};

let settings = client.fetch_privacy_settings().await?;
client.set_privacy_setting(PrivacyCategory::Last, PrivacyValue::Contacts).await?;
```

## Methods

### fetch\_privacy\_settings

Fetch all current privacy settings.

```rust theme={null}
pub async fn fetch_privacy_settings(&self) -> Result<PrivacySettingsResponse, IqError>
```

**Returns:**

* `PrivacySettingsResponse` - Contains a list of all privacy settings

**Example:**

```rust theme={null}
use whatsapp_rust::privacy_settings::{PrivacyCategory, PrivacyValue};

let response = client.fetch_privacy_settings().await?;

for setting in &response.settings {
    println!("{:?} = {:?}", setting.category, setting.value);
}

// Look up a specific category
if let Some(value) = response.get_value(&PrivacyCategory::Last) {
    println!("Last seen: {:?}", value);
}
```

<Note>
  The client also fetches privacy settings automatically in the background right after connecting, purely to keep an internal cache current. Today the only setting cached this way is `ReadReceipts`, which gates the wire type of outgoing DM read/played receipts (see [Read receipt privacy gating](/api/receipt#read-receipt-privacy-gating)). That cache is written **only** by the automatic background fetch on connect — calling `fetch_privacy_settings` yourself is a bare passthrough that returns the current server-side values without touching device state, so it does not also refresh the cache. Call it directly when you need the full, current set of values, e.g. to render a settings screen; a reconnect (not a manual call) is what updates the cached read-receipts gate.
</Note>

### set\_privacy\_setting

Update a specific privacy setting.

```rust theme={null}
pub async fn set_privacy_setting(
    &self,
    category: PrivacyCategory,
    value: PrivacyValue,
) -> Result<SetPrivacySettingResponse, IqError>
```

**Parameters:**

* `category` - A `PrivacyCategory` enum variant
* `value` - A `PrivacyValue` enum variant (must be valid for the category)

**Returns:**

* `SetPrivacySettingResponse` - Contains an optional `dhash` field (present only for `ContactBlacklist` operations)

**Example:**

```rust theme={null}
use whatsapp_rust::privacy_settings::{PrivacyCategory, PrivacyValue};

// Hide last seen from everyone
client.set_privacy_setting(PrivacyCategory::Last, PrivacyValue::None).await?;

// Show profile photo only to contacts
client.set_privacy_setting(PrivacyCategory::Profile, PrivacyValue::Contacts).await?;

// Allow everyone to add you to groups
client.set_privacy_setting(PrivacyCategory::GroupAdd, PrivacyValue::All).await?;

// Disable read receipts
client.set_privacy_setting(PrivacyCategory::ReadReceipts, PrivacyValue::None).await?;

// Restrict calls to known contacts only
client.set_privacy_setting(PrivacyCategory::CallAdd, PrivacyValue::Known).await?;
```

<Note>
  Each `PrivacyCategory` only accepts specific `PrivacyValue` variants. See the [valid combinations table](#valid-category-value-combinations) below.
</Note>

<Note>
  Setting `ReadReceipts` to `None` takes effect on the **next connect** (the client re-fetches and re-caches the setting on each connect, matching WhatsApp Web, which reads it from local prefs) — calling `fetch_privacy_settings` yourself in the same session does not refresh that cache either (see the note above); a reconnect is currently the only way. From then on, `mark_as_read`/`mark_as_played` on a direct message send `read-self`/`played-self` instead of `read`/`played`, so the other party is no longer notified. This only applies to DMs — group, broadcast list, status-broadcast, and newsletter receipts are unaffected. See [Read receipt privacy gating](/api/receipt#read-receipt-privacy-gating).
</Note>

### set\_privacy\_disallowed\_list

Update a privacy category's disallowed list (contacts-except-specific-users mode). Only available for categories that support `ContactBlacklist`: `Last`, `Profile`, `Status`, and `GroupAdd`.

```rust theme={null}
pub async fn set_privacy_disallowed_list(
    &self,
    category: PrivacyCategory,
    update: DisallowedListUpdate,
) -> Result<SetPrivacySettingResponse, IqError>
```

**Parameters:**

* `category` - Must be `Last`, `Profile`, `Status`, or `GroupAdd`
* `update` - A `DisallowedListUpdate` containing the `dhash` and user entries to add/remove

**Returns:**

* `SetPrivacySettingResponse` - Contains the updated `dhash` for conflict detection

**Example:**

```rust theme={null}
use whatsapp_rust::privacy_settings::{
    PrivacyCategory, DisallowedListUpdate, DisallowedListUserEntry, DisallowedListAction,
};

// First, set the category to contact_blacklist mode
client.set_privacy_setting(
    PrivacyCategory::Last,
    PrivacyValue::ContactBlacklist,
).await?;

// Then update the disallowed list
let update = DisallowedListUpdate {
    dhash: "current_hash".to_string(), // from previous response
    users: vec![
        DisallowedListUserEntry {
            action: DisallowedListAction::Add,
            jid: blocked_user_lid,
            pn_jid: Some(blocked_user_pn),
        },
    ],
};

let response = client.set_privacy_disallowed_list(
    PrivacyCategory::Last,
    update,
).await?;

// Save the new dhash for future updates
let new_dhash = response.dhash;
```

### set\_default\_disappearing\_mode

Set the default disappearing messages duration for all new chats.

```rust theme={null}
pub async fn set_default_disappearing_mode(
    &self,
    duration: u32,
) -> Result<(), IqError>
```

**Parameters:**

* `duration` - Timer in seconds. Common values: `86400` (24 hours), `604800` (7 days), `7776000` (90 days). Pass `0` to disable.

**Example:**

```rust theme={null}
// Enable 7-day default disappearing messages
client.set_default_disappearing_mode(604800).await?;

// Disable default disappearing messages
client.set_default_disappearing_mode(0).await?;
```

<Note>
  This sets the default for **new** chats only. Existing chats keep their current setting. To change disappearing messages for a specific group, use [`set_ephemeral`](/api/groups#set_ephemeral).
</Note>

## Types

### PrivacyCategory

Controls which privacy setting is being read or written. Each category maps to a wire-protocol string value.

```rust theme={null}
pub enum PrivacyCategory {
    Last,           // "last" — Last seen visibility
    Online,         // "online" — Online status visibility
    Profile,        // "profile" — Profile photo visibility
    Status,         // "status" — Status/story visibility
    GroupAdd,       // "groupadd" — Who can add you to groups
    ReadReceipts,   // "readreceipts" — Read receipt visibility
    CallAdd,        // "calladd" — Who can call you
    Messages,       // "messages" — Who can message you
    DefenseMode,    // "defense" — Defense mode configuration
    Other(String),  // Unknown/future category
}
```

### PrivacyValue

The value assigned to a privacy category.

```rust theme={null}
pub enum PrivacyValue {
    All,              // "all" — Visible to everyone
    Contacts,         // "contacts" — Visible only to contacts
    None,             // "none" — Not visible to anyone
    ContactBlacklist, // "contact_blacklist" — Contacts except specific list
    MatchLastSeen,    // "match_last_seen" — Match the other person's setting
    Known,            // "known" — Known contacts (for calls)
    Off,              // "off" — Feature disabled (defense mode)
    OnStandard,       // "on_standard" — Standard mode (defense mode)
    Other(String),    // Unknown/future value
}
```

### Valid category-value combinations

Not all values are valid for every category. Use `PrivacyCategory::is_valid_value()` to check at runtime.

| Category       | Valid values                                  |
| -------------- | --------------------------------------------- |
| `Last`         | `All`, `Contacts`, `ContactBlacklist`, `None` |
| `Online`       | `All`, `MatchLastSeen`                        |
| `Profile`      | `All`, `Contacts`, `ContactBlacklist`, `None` |
| `Status`       | `All`, `Contacts`, `ContactBlacklist`, `None` |
| `GroupAdd`     | `All`, `Contacts`, `ContactBlacklist`, `None` |
| `ReadReceipts` | `All`, `None`                                 |
| `CallAdd`      | `All`, `Known`, `Contacts`                    |
| `Messages`     | `All`, `Contacts`                             |
| `DefenseMode`  | `Off`, `OnStandard`                           |

### PrivacySetting

```rust theme={null}
pub struct PrivacySetting {
    pub category: PrivacyCategory,
    pub value: PrivacyValue,
}
```

### PrivacySettingsResponse

```rust theme={null}
pub struct PrivacySettingsResponse {
    pub settings: Vec<PrivacySetting>,
}
```

**Methods:**

* `get(&self, category: &PrivacyCategory) -> Option<&PrivacySetting>` - Look up a setting by category
* `get_value(&self, category: &PrivacyCategory) -> Option<&PrivacyValue>` - Look up a value directly

### SetPrivacySettingResponse

```rust theme={null}
pub struct SetPrivacySettingResponse {
    pub dhash: Option<String>,
}
```

The `dhash` field is populated when setting a `ContactBlacklist` value or updating a disallowed list. Use it for conflict detection on subsequent updates.

### DisallowedListUpdate

Used with `set_privacy_disallowed_list` to add or remove users from a category's disallowed list.

```rust theme={null}
pub struct DisallowedListUpdate {
    pub dhash: String,
    pub users: Vec<DisallowedListUserEntry>,
}
```

### DisallowedListUserEntry

```rust theme={null}
pub struct DisallowedListUserEntry {
    pub action: DisallowedListAction,
    pub jid: Jid,
    pub pn_jid: Option<Jid>,
}
```

### DisallowedListAction

```rust theme={null}
pub enum DisallowedListAction {
    Add,    // "add" — Add user to disallowed list (default)
    Remove, // "remove" — Remove user from disallowed list
}
```

## Common patterns

### Fetch and display all settings

```rust theme={null}
use whatsapp_rust::privacy_settings::{PrivacyCategory, PrivacyValue};

let response = client.fetch_privacy_settings().await?;

let categories = [
    PrivacyCategory::Last,
    PrivacyCategory::Online,
    PrivacyCategory::Profile,
    PrivacyCategory::Status,
    PrivacyCategory::GroupAdd,
    PrivacyCategory::ReadReceipts,
    PrivacyCategory::CallAdd,
    PrivacyCategory::Messages,
    PrivacyCategory::DefenseMode,
];

for category in &categories {
    let value = response
        .get_value(category)
        .unwrap_or(&PrivacyValue::All);
    println!("{:?}: {:?}", category, value);
}
```

### Maximum privacy configuration

```rust theme={null}
use whatsapp_rust::privacy_settings::{PrivacyCategory, PrivacyValue};

client.set_privacy_setting(PrivacyCategory::Last, PrivacyValue::None).await?;
client.set_privacy_setting(PrivacyCategory::Online, PrivacyValue::MatchLastSeen).await?;
client.set_privacy_setting(PrivacyCategory::Profile, PrivacyValue::Contacts).await?;
client.set_privacy_setting(PrivacyCategory::Status, PrivacyValue::Contacts).await?;
client.set_privacy_setting(PrivacyCategory::GroupAdd, PrivacyValue::Contacts).await?;
client.set_privacy_setting(PrivacyCategory::ReadReceipts, PrivacyValue::None).await?;
client.set_privacy_setting(PrivacyCategory::CallAdd, PrivacyValue::Contacts).await?;
client.set_privacy_setting(PrivacyCategory::Messages, PrivacyValue::Contacts).await?;
```

### Validate before setting

```rust theme={null}
use whatsapp_rust::privacy_settings::{PrivacyCategory, PrivacyValue};

let category = PrivacyCategory::Online;
let value = PrivacyValue::None;

if category.is_valid_value(&value) {
    client.set_privacy_setting(category, value).await?;
} else {
    eprintln!("Invalid value for category");
}
```

## See also

* [Client API](/api/client#fetch_privacy_settings) - Client-level privacy methods
* [Receipt API](/api/receipt#read-receipt-privacy-gating) - How `ReadReceipts` gates DM read/played receipts
* [TC Token API](/api/tctoken) - Trusted contact tokens used for privacy-gated operations
* [Blocking API](/api/blocking) - Block and unblock contacts
