> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ryzeapi.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Update privacy

> Update privacy settings (last seen, online, picture, status, read receipts, calls, groups)

**Auth:** `TokenAccount` or `TokenInstance` • **Rate limit:** `Global` (100/min) • **Idempotent:** yes (setting the same value is a no-op)

## Description

Updates one or more privacy settings. **Partial** update, only the fields you send are changed. At least one of the three subsections (`visibility`, `privacy`, `permissions`) must be sent. The response returns the **complete** settings after the update.

## Examples

### Fully restrictive

Applies a closed-down privacy profile in a single call: hides `lastSeen`, restricts status / picture to contacts, turns off read receipts, and limits calls to known contacts. Each subsection sends one field, totaling several stanzas on WhatsApp.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://ryzeapi.cloud/api/profile/privacy/$Instance_Name" \
    -H "token: $Token_Instance" \
    -H "Content-Type: application/json" \
    -d '{
      "visibility": {
        "lastSeen": "none",
        "status": "contacts",
        "profile": "contacts",
        "online": "match_last_seen"
      },
      "privacy": {
        "readReceipts": "none"
      },
      "permissions": {
        "callAdd": "known",
        "groupAdd": "contacts"
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/profile/privacy/${process.env.Instance_Name}`, {
    method: "POST",
    headers: {
      "token":        process.env.Token_Instance,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      visibility: {
        lastSeen: "none",
        status:   "contacts",
        profile:  "contacts",
        online:   "match_last_seen"
      },
      privacy: {
        readReceipts: "none"
      },
      permissions: {
        callAdd:  "known",
        groupAdd: "contacts"
      }
    })
  });
  ```

  ```python Python theme={null}
  import os, requests

  requests.post(
      f"https://ryzeapi.cloud/api/profile/privacy/{os.environ['Instance_Name']}",
      headers={
          "token":        os.environ["Token_Instance"],
          "Content-Type": "application/json"
      },
      json={
          "visibility": {
              "lastSeen": "none",
              "status":   "contacts",
              "profile":  "contacts",
              "online":   "match_last_seen"
          },
          "privacy": {
              "readReceipts": "none"
          },
          "permissions": {
              "callAdd":  "known",
              "groupAdd": "contacts"
          }
      }
  )
  ```

  ```go Go theme={null}
  package main

  import (
      "net/http"
      "os"
      "strings"
  )

  func main() {
      body := strings.NewReader(`{
          "visibility": {
              "lastSeen": "none",
              "status":   "contacts",
              "profile":  "contacts",
              "online":   "match_last_seen"
          },
          "privacy": {
              "readReceipts": "none"
          },
          "permissions": {
              "callAdd":  "known",
              "groupAdd": "contacts"
          }
      }`)
      req, _ := http.NewRequest("POST", "https://ryzeapi.cloud/api/profile/privacy/"+os.Getenv("Instance_Name"), body)
      req.Header.Set("token", os.Getenv("Token_Instance"))
      req.Header.Set("Content-Type", "application/json")
      http.DefaultClient.Do(req)
  }
  ```
</CodeGroup>

### Only groupAdd

Updates only `permissions.groupAdd` to `contacts`, preventing strangers from adding the account to groups. All other settings remain unchanged.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://ryzeapi.cloud/api/profile/privacy/$Instance_Name" \
    -H "token: $Token_Instance" \
    -H "Content-Type: application/json" \
    -d '{
      "permissions": { "groupAdd": "contacts" }
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/profile/privacy/${process.env.Instance_Name}`, {
    method: "POST",
    headers: {
      "token":        process.env.Token_Instance,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      permissions: { groupAdd: "contacts" }
    })
  });
  ```

  ```python Python theme={null}
  import os, requests

  requests.post(
      f"https://ryzeapi.cloud/api/profile/privacy/{os.environ['Instance_Name']}",
      headers={
          "token":        os.environ["Token_Instance"],
          "Content-Type": "application/json"
      },
      json={
          "permissions": {"groupAdd": "contacts"}
      }
  )
  ```

  ```go Go theme={null}
  package main

  import (
      "net/http"
      "os"
      "strings"
  )

  func main() {
      body := strings.NewReader(`{
          "permissions": { "groupAdd": "contacts" }
      }`)
      req, _ := http.NewRequest("POST", "https://ryzeapi.cloud/api/profile/privacy/"+os.Getenv("Instance_Name"), body)
      req.Header.Set("token", os.Getenv("Token_Instance"))
      req.Header.Set("Content-Type", "application/json")
      http.DefaultClient.Do(req)
  }
  ```
</CodeGroup>

### Disable read receipts

Sets `privacy.readReceipts` to `none` to stop sending the "blue double check". The account stops confirming reads, and also stops seeing other people's confirmations (WhatsApp's reciprocal effect).

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://ryzeapi.cloud/api/profile/privacy/$Instance_Name" \
    -H "token: $Token_Instance" \
    -H "Content-Type: application/json" \
    -d '{
      "privacy": { "readReceipts": "none" }
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/profile/privacy/${process.env.Instance_Name}`, {
    method: "POST",
    headers: {
      "token":        process.env.Token_Instance,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      privacy: { readReceipts: "none" }
    })
  });
  ```

  ```python Python theme={null}
  import os, requests

  requests.post(
      f"https://ryzeapi.cloud/api/profile/privacy/{os.environ['Instance_Name']}",
      headers={
          "token":        os.environ["Token_Instance"],
          "Content-Type": "application/json"
      },
      json={
          "privacy": {"readReceipts": "none"}
      }
  )
  ```

  ```go Go theme={null}
  package main

  import (
      "net/http"
      "os"
      "strings"
  )

  func main() {
      body := strings.NewReader(`{
          "privacy": { "readReceipts": "none" }
      }`)
      req, _ := http.NewRequest("POST", "https://ryzeapi.cloud/api/profile/privacy/"+os.Getenv("Instance_Name"), body)
      req.Header.Set("token", os.Getenv("Token_Instance"))
      req.Header.Set("Content-Type", "application/json")
      http.DefaultClient.Do(req)
  }
  ```
</CodeGroup>

### Only lastSeen and online

Hides `lastSeen` and ties `online` to the same level (`match_last_seen`). Result: nobody sees when the account was last online, nor whether it's active right now.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://ryzeapi.cloud/api/profile/privacy/$Instance_Name" \
    -H "token: $Token_Instance" \
    -H "Content-Type: application/json" \
    -d '{
      "visibility": {
        "lastSeen": "none",
        "online": "match_last_seen"
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/profile/privacy/${process.env.Instance_Name}`, {
    method: "POST",
    headers: {
      "token":        process.env.Token_Instance,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      visibility: {
        lastSeen: "none",
        online:   "match_last_seen"
      }
    })
  });
  ```

  ```python Python theme={null}
  import os, requests

  requests.post(
      f"https://ryzeapi.cloud/api/profile/privacy/{os.environ['Instance_Name']}",
      headers={
          "token":        os.environ["Token_Instance"],
          "Content-Type": "application/json"
      },
      json={
          "visibility": {
              "lastSeen": "none",
              "online":   "match_last_seen"
          }
      }
  )
  ```

  ```go Go theme={null}
  package main

  import (
      "net/http"
      "os"
      "strings"
  )

  func main() {
      body := strings.NewReader(`{
          "visibility": {
              "lastSeen": "none",
              "online":   "match_last_seen"
          }
      }`)
      req, _ := http.NewRequest("POST", "https://ryzeapi.cloud/api/profile/privacy/"+os.Getenv("Instance_Name"), body)
      req.Header.Set("token", os.Getenv("Token_Instance"))
      req.Header.Set("Content-Type", "application/json")
      http.DefaultClient.Do(req)
  }
  ```
</CodeGroup>

## Success response

After applying the updates, the handler re-runs `GetPrivacySettings` and returns the **complete** current snapshot in `settings`, grouped into `visibility` (`lastSeen`, `status`, `profile`, `online`), `privacy` (`readReceipts`), and `permissions` (`callAdd`, `groupAdd`). Use the response as the source of truth for the post-update state, it's what WhatsApp confirmed, not just what you sent.

```json 200 OK theme={null}
{
  "success": true,
  "message": "Privacy settings updated successfully",
  "settings": {
    "visibility": {
      "lastSeen": "none",
      "status": "contacts",
      "profile": "contacts",
      "online": "match_last_seen"
    },
    "privacy": {
      "readReceipts": "none"
    },
    "permissions": {
      "callAdd": "known",
      "groupAdd": "contacts"
    }
  }
}
```

## Path parameters

<ParamField path="instance" type="string" required>
  Instance name.
</ParamField>

## Headers

<ParamField header="token" type="string" required>
  `TokenAccount` or `TokenInstance`.
</ParamField>

<ParamField header="Content-Type" type="string" required>
  `application/json`
</ParamField>

## Request body

Each subsection is optional, but at least one must be present.

<ParamField body="visibility" type="object">
  Subfields: `lastSeen`, `status`, `profile`, `online`.
</ParamField>

<ParamField body="privacy" type="object">
  Subfields: `readReceipts`.
</ParamField>

<ParamField body="permissions" type="object">
  Subfields: `callAdd`, `groupAdd`.
</ParamField>

### Accepted values per field

| Field                             | Values                                            |
| --------------------------------- | ------------------------------------------------- |
| `lastSeen` / `status` / `profile` | `all` / `contacts` / `contact_blacklist` / `none` |
| `online`                          | `all` / `match_last_seen`                         |
| `readReceipts`                    | `all` / `none`                                    |
| `callAdd`                         | `all` / `known`                                   |
| `groupAdd`                        | `all` / `contacts` / `contact_blacklist`          |

## Notes

<Warning>
  **Validation stops at the first error.** If you send `visibility.lastSeen = "X"` (invalid) + `visibility.status = "contacts"` (valid), **nothing** is applied, the handler aborts on the first invalid field. Validate enums on the client before calling.
</Warning>

<Note>
  * Operations are not **transactional**: if the third `SetPrivacySetting` fails, the first two have **already been applied**, the client gets a `500` but the partial state persists. Verify via `GET` after errors.
  * Each field triggers a separate stanza, an update with 7 fields makes 7 calls + 1 final `GetPrivacySettings` = **8 stanzas**. Latency can add up.
  * The response always returns the **complete** current settings (not just the changed fields).
</Note>

## Errors

| HTTP | Message                                                                                 |
| ---- | --------------------------------------------------------------------------------------- |
| 400  | `At least one privacy setting must be provided`                                         |
| 400  | `Invalid lastSeen value: <value>. Valid values: all, contacts, contact_blacklist, none` |
| 400  | `Invalid status value: <value>. Valid values: all, contacts, contact_blacklist, none`   |
| 400  | `Invalid profile value: <value>. Valid values: all, contacts, contact_blacklist, none`  |
| 400  | `Invalid online value: <value>. Valid values: all, match_last_seen`                     |
| 400  | `Invalid readReceipts value: <value>. Valid values: all, none`                          |
| 400  | `Invalid callAdd value: <value>. Valid values: all, known`                              |
| 400  | `Invalid groupAdd value: <value>. Valid values: all, contacts, contact_blacklist`       |
| 400  | `Instance is not connected to WhatsApp`                                                 |
| 500  | `failed to update <field> privacy: <reason>`                                            |

Envelope:

```json theme={null}
{
  "success": false,
  "error": { "message": "Invalid lastSeen value: everyone. Valid values: all, contacts, contact_blacklist, none" }
}
```
