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

# List contacts

> Lists every synced contact or queries a specific number

**Auth:** `TokenAccount` or `TokenInstance` • **Rate-limit:** `Global` (100/min) • **Idempotent:** yes

## Description

Returns the list of contacts synced in the WhatsMeow `ContactStore`, these are the contacts coming from the main phone's address book: name, push name, business name, and redacted phone number.

If `?number=` is provided, returns a single contact. If the number is not in the address book, the response is still `200 OK` with `contact.found = false`.

<Info>
  **Read-only** operation against the local store, does not generate any WhatsApp traffic.
</Info>

## Examples

### List all

Without query params, returns every contact synced in the instance's local `ContactStore`, with `total` indicating the size of the list.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://ryzeapi.cloud/api/chat/contacts/$Instance_Name" \
    -H "token: $Token_Instance"
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/chat/contacts/${process.env.Instance_Name}`, {
    method: "GET",
    headers: {
      "token": process.env.Token_Instance
    }
  });
  ```

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

  requests.get(
      f"https://ryzeapi.cloud/api/chat/contacts/{os.environ['Instance_Name']}",
      headers={"token": os.environ["Token_Instance"]}
  )
  ```

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

  import (
      "net/http"
      "os"
  )

  func main() {
      req, _ := http.NewRequest("GET", "https://ryzeapi.cloud/api/chat/contacts/"+os.Getenv("Instance_Name"), nil)
      req.Header.Set("token", os.Getenv("Token_Instance"))
      http.DefaultClient.Do(req)
  }
  ```
</CodeGroup>

### Specific number

Filters by `?number=5511999999999` (international phone). Returns the single `contact` object, with `found=false` when the number is not in the synced address book.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://ryzeapi.cloud/api/chat/contacts/$Instance_Name?number=5511999999999" \
    -H "token: $Token_Instance"
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/chat/contacts/${process.env.Instance_Name}?number=5511999999999`, {
    method: "GET",
    headers: {
      "token": process.env.Token_Instance
    }
  });
  ```

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

  requests.get(
      f"https://ryzeapi.cloud/api/chat/contacts/{os.environ['Instance_Name']}?number=5511999999999",
      headers={"token": os.environ["Token_Instance"]}
  )
  ```

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

  import (
      "net/http"
      "os"
  )

  func main() {
      req, _ := http.NewRequest("GET", "https://ryzeapi.cloud/api/chat/contacts/"+os.Getenv("Instance_Name")+"?number=5511999999999", nil)
      req.Header.Set("token", os.Getenv("Token_Instance"))
      http.DefaultClient.Do(req)
  }
  ```
</CodeGroup>

### Full JID

Accepts the entire JID in `?number=5511999999999@s.whatsapp.net` when you already have the full identifier (from a webhook or another API response), avoiding manually building the suffix.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://ryzeapi.cloud/api/chat/contacts/$Instance_Name?number=5511999999999@s.whatsapp.net" \
    -H "token: $Token_Instance"
  ```

  ```javascript JavaScript theme={null}
  await fetch(`https://ryzeapi.cloud/api/chat/contacts/${process.env.Instance_Name}?number=5511999999999@s.whatsapp.net`, {
    method: "GET",
    headers: {
      "token": process.env.Token_Instance
    }
  });
  ```

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

  requests.get(
      f"https://ryzeapi.cloud/api/chat/contacts/{os.environ['Instance_Name']}?number=5511999999999@s.whatsapp.net",
      headers={"token": os.environ["Token_Instance"]}
  )
  ```

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

  import (
      "net/http"
      "os"
  )

  func main() {
      req, _ := http.NewRequest("GET", "https://ryzeapi.cloud/api/chat/contacts/"+os.Getenv("Instance_Name")+"?number=5511999999999@s.whatsapp.net", nil)
      req.Header.Set("token", os.Getenv("Token_Instance"))
      http.DefaultClient.Do(req)
  }
  ```
</CodeGroup>

## Success response

Without `?number`, returns `contacts` (array) with every contact synced from the address book + `total`. With `?number=...`, returns only `contact` (a single object). Each item carries `jid`, `lid` (when applicable), the available names (`first_name`, `full_name`, `push_name`, `business_name`), and `redacted_phone` for cases where we only know the LID. The `found` field indicates whether the entry came from the store.

```json 200 OK theme={null}
{
  "success": true,
  "message": "Contacts retrieved successfully",
  "contacts": [
    {
      "jid": "5511999999999@s.whatsapp.net",
      "lid": "",
      "first_name": "John",
      "full_name": "John Smith",
      "push_name": "John",
      "business_name": "",
      "redacted_phone": "+55 11 ..... 9999",
      "found": true
    },
    {
      "jid": "5511888888888@s.whatsapp.net",
      "full_name": "Mary",
      "push_name": "Mary S.",
      "found": true
    }
  ],
  "total": 42
}
```

## Path parameters

<ParamField path="instance" type="string" required>
  Instance name (e.g., `$Instance_Name`).
</ParamField>

## Headers

| Name    | Required                 | Example        | Description                    |
| ------- | ------------------------ | -------------- | ------------------------------ |
| `token` | yes (or `Authorization`) | `a1b2c3d4-...` | TokenAccount or TokenInstance. |

## Query params

<ParamField query="number" type="string">
  International phone (`5511999999999`) or JID (`5511999999999@s.whatsapp.net`, `...@lid`). If provided, returns only this contact.
</ParamField>

## Notes and gotchas

<Note>
  * `found=false` with empty `push_name` and empty `redacted_phone` usually means the number does not have WhatsApp or never exchanged messages with you.
  * `business_name` is only filled for verified WhatsApp Business accounts.
  * Operations involving more than a thousand contacts may take a few seconds because of the `context.WithTimeout(30s)` applied to `GetAllContacts`.
</Note>

## Error responses

| HTTP | `error.message`                                                                         | When it happens                                 |
| ---- | --------------------------------------------------------------------------------------- | ----------------------------------------------- |
| 400  | `Instance name is required`                                                             | Empty `:instance`.                              |
| 401  | `Invalid token`                                                                         | See [Authentication](/en/guide/authentication). |
| 404  | `Instance not found`                                                                    | The instance does not exist on the account.     |
| 500  | `WhatsApp client not found for instance`                                                | Client deallocated.                             |
| 500  | `WhatsApp client is not connected`                                                      | Disconnected instance.                          |
| 500  | `contact store not available (use a store that implements ContactStore, e.g. sqlstore)` | Store not supported.                            |
| 500  | `invalid number: <...>`                                                                 | Malformed `?number=`.                           |
| 500  | `failed to get contacts: <...>` / `failed to get contact: <...>`                        | Internal WhatsMeow error.                       |

```json Error 400 theme={null}
{
  "success": false,
  "error": { "message": "Instance name is required" }
}
```
