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

# Multi-Device & Device Selection

> Run several WhatsApp accounts on one GOWA server and choose which one each request uses with X-Device-Id.

![GOWA Multi Device Whats App Architecture](https://mintcdn.com/gowa-docs/ccA2Yz4DVI9xOiS8/images/GOWA-Multi-Device-WhatsApp-Architecture.png?fit=max\&auto=format\&n=ccA2Yz4DVI9xOiS8\&q=85\&s=116b948218cb46aa9eca0b959634eaaf)

"Multi-device" means two things in GOWA:

* **WhatsApp's multi-device protocol.** GOWA links to an account as a companion device, like WhatsApp Web. The phone does not need to stay online, and each account allows up to four linked companions.
* **Multiple accounts per server.** One GOWA process can hold many **device slots**. Each slot pairs with a different WhatsApp account, or with the same number as a separate companion.

## Device slots

A slot has an ID you choose (or a generated UUID), a state, and once paired the account's JID.

| State | Meaning |
| - | - |
| `disconnected` | Not connected to WhatsApp. A new or logged-out slot starts here. |
| `connecting` | Connection in progress. |
| `connected` | Socket open, not yet logged in (for example while waiting for a QR scan). |
| `logged_in` | Paired and ready to send and receive. |

### Manage slots

```bash theme={null}
# Create (device_id is optional)
curl -u admin:changeme -X POST http://localhost:3000/devices \
  -H "Content-Type: application/json" \
  -d '{"device_id": "sales"}'

# List
curl -u admin:changeme http://localhost:3000/devices

# Inspect / live status
curl -u admin:changeme http://localhost:3000/devices/sales
curl -u admin:changeme http://localhost:3000/devices/sales/status

# Pair, log out, reconnect
curl -u admin:changeme http://localhost:3000/devices/sales/login
curl -u admin:changeme -X POST "http://localhost:3000/devices/sales/login/code?phone=628123456789"
curl -u admin:changeme -X POST http://localhost:3000/devices/sales/logout
curl -u admin:changeme -X POST http://localhost:3000/devices/sales/reconnect

# Remove the slot and its session and chat data
curl -u admin:changeme -X DELETE http://localhost:3000/devices/sales
```

`/devices/...` routes take the device from the path, so they never need `X-Device-Id`. Slots and sessions persist across restarts.

## Selecting a device

Every other device-scoped route (`/send/*`, `/message/*`, `/chat*`, `/group*`, `/user/*`, `/newsletter/*`, `/call/*` and `/app/*` except `/app/info`) needs to know which account to act as. GOWA resolves it in this order:

1. The `X-Device-Id` header (URL-decoded).
2. The `device_id` query parameter.
3. If neither is given and **exactly one** slot exists, that slot.

The value can be the slot ID or the account JID (for example `628123456789@s.whatsapp.net`).

```bash theme={null}
curl -u admin:changeme -X POST http://localhost:3000/send/message \
  -H "Content-Type: application/json" \
  -H "X-Device-Id: sales" \
  -d '{"phone": "628123456789", "message": "Hi from the sales number"}'

# Equivalent, using the query parameter
curl -u admin:changeme -X POST "http://localhost:3000/send/message?device_id=sales" \
  -H "Content-Type: application/json" \
  -d '{"phone": "628123456789", "message": "Hi from the sales number"}'
```

> [!TIP]
>
> Always send `X-Device-Id`, even with one slot. Adding a second slot later would otherwise make every unscoped call fail with `DEVICE_ID_REQUIRED`.

### Selection errors

| HTTP | `code` | Cause |
| - | - | - |
| 400 | `DEVICE_ID_REQUIRED` | No device given and zero or several slots exist. |
| 404 | `DEVICE_NOT_FOUND` | No slot matches the given ID or JID. |
| 503 | `DEVICE_MANAGER_UNAVAILABLE` | The server has not finished initializing. |

A slot that exists but is not logged in passes selection; the request then fails with a WhatsApp error such as "you are not logged in".

## Per-device features

| Feature | How it is scoped |
| - | - |
| Webhooks | Every payload carries `device_id` (account JID) and `session_id` (slot ID). A slot can have its own webhook: `PATCH /devices/{device_id}/webhook`. See [Webhooks](https://gowa-docs.mintlify.site/concepts/webhooks.md#per-device-webhooks). |
| WebSocket | Connect to `/ws?device_id=<id>` to receive one slot's events. |
| Scheduled sends | Belong to the slot that created them; list them with that slot's `X-Device-Id`. |
| MCP | `X-Device-Id` on the MCP connection, or a `device_id` argument per tool call. See [MCP server](https://gowa-docs.mintlify.site/integrations/mcp.md). |
| Chatwoot | `CHATWOOT_DEVICE_ID` for a single inbox, or per-device configs for one inbox per slot. See [Chatwoot](https://gowa-docs.mintlify.site/integrations/chatwoot.md). |

## Limits and caveats

* WhatsApp allows up to four linked companions per account. Each GOWA slot paired to that account uses one.
* WhatsApp unlinks a companion if the phone stays offline for about 14 days.
* History sync after pairing is partial and controlled by WhatsApp; GOWA stores what it receives in its chat storage.
* Each slot is a full WhatsApp connection. Memory and CPU grow with the number of slots and the volume of traffic.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.