4ce4204b6c
CI / Lint (push) Failing after 2s
CI / Build (push) Has been skipped
SDK CI / PHP SDK (push) Failing after 1s
Split PHP SDK / PHP SDK tests (push) Failing after 1s
CI / Test (push) Failing after 1s
CI / Dashboard (push) Failing after 0s
SDK CI / JavaScript SDK (push) Failing after 0s
SDK CI / Python SDK (push) Failing after 2s
SDK CI / Java SDK (push) Failing after 1s
Split PHP SDK / Mirror sdk/php -> rmyndharis/openwa-php (push) Has been skipped
CI / Test (PostgreSQL migrations) (push) Failing after 7m47s
CI / Docker Build (push) Has been skipped
1425 lines
38 KiB
Markdown
1425 lines
38 KiB
Markdown
# 07 - API Collection
|
||
|
||
## 07.1 Overview
|
||
|
||
This collection gives a runnable cURL for every OpenWA REST endpoint. The examples assume two environment variables — set them once and reuse them:
|
||
|
||
```bash
|
||
export BASE=http://localhost:2785
|
||
export API_KEY=owa_k1_your-api-key-here
|
||
```
|
||
|
||
(For the metrics endpoint also `export METRICS_TOKEN=...`.)
|
||
|
||
### Authentication
|
||
|
||
Every request carries the key in the `X-API-Key` header — REST auth is **header-only**, an `?apiKey=` query value is not accepted. Routes that mutate state need an `operator` key; API-key and settings management need an `admin` key; read-only routes accept any valid key. The metrics endpoint uses `Authorization: Bearer $METRICS_TOKEN` instead.
|
||
|
||
```bash
|
||
# the auth header that prefixes nearly every call below
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
### Responses
|
||
|
||
Responses are the **raw payload** — no `{ success, data }` envelope. A resource route returns the object directly; a list route returns a bare JSON array. Errors return the NestJS default shape `{ "statusCode", "message", "error" }`. Add `Content-Type: application/json` only when sending a body.
|
||
|
||
### Sections
|
||
|
||
Sessions · Messages · Webhooks · Groups · Contacts · Chats · Labels · Channels · Catalog · Templates · Plugins · Settings · Auth (API Keys) · Health · Infrastructure · Stats · Metrics · Events (WebSocket).
|
||
|
||
## 07.2 Endpoints
|
||
|
||
All examples assume `BASE` and `API_KEY` are exported (see 07.1). Paths are prefixed with `/api`.
|
||
|
||
### 07.3 Sessions
|
||
|
||
All routes are under `$BASE/api/sessions` and require `X-API-Key: $API_KEY` (some require an OPERATOR-role key). Reads come first, then writes.
|
||
|
||
#### GET /api/sessions
|
||
|
||
List all sessions visible to the key. Add `limit`/`offset` to page large installations.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions?limit=100&offset=0" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:id
|
||
|
||
Get a single session by ID.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:id/qr
|
||
|
||
Get the QR code (PNG data URL) for authentication.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a/qr" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:id/groups
|
||
|
||
List groups the session belongs to (paginated).
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a/groups?limit=100&offset=0" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:id/chats
|
||
|
||
List active chats, most-recent first (paginated).
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a/chats?limit=100&offset=0" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/stats/overview
|
||
|
||
Aggregate session statistics for monitoring.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/stats/overview" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/sessions
|
||
|
||
Create a new session (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "name": "my-bot", "config": { "autoReconnect": true }, "proxyUrl": "http://proxy.example.com:8080", "proxyType": "http" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:id/start
|
||
|
||
Start a session and initialize the connection (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a/start" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/sessions/:id/stop
|
||
|
||
Stop a session and disconnect (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a/stop" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/sessions/:id/force-kill
|
||
|
||
Force-kill a stuck session (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a/force-kill" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/sessions/:id/pairing-code
|
||
|
||
Request an 8-char pairing code via phone number (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a/pairing-code" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "phoneNumber": "628123456789" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:id/chats/read
|
||
|
||
Mark a chat as read/seen (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a/chats/read" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "1234567890@c.us" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:id/chats/unread
|
||
|
||
Mark a chat as unread (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a/chats/unread" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "1234567890@c.us" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:id/chats/delete
|
||
|
||
Delete a chat from the chat list (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a/chats/delete" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "1234567890-123@g.us" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:id/chats/typing
|
||
|
||
Send a typing/recording presence indicator (or clear it with `paused`) (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a/chats/typing" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "1234567890@c.us", "state": "typing" }'
|
||
```
|
||
|
||
#### DELETE /api/sessions/:id
|
||
|
||
Delete a session (OPERATOR). Returns `204` with no body.
|
||
|
||
```bash
|
||
curl -X DELETE "$BASE/api/sessions/8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
### 07.4 Messages
|
||
|
||
All routes are under `/api/sessions/:sessionId/messages`. Reads accept any API key; send/write routes need an OPERATOR (or higher) key.
|
||
|
||
#### GET /api/sessions/:sessionId/messages
|
||
|
||
Get persisted message history from the local DB (paginated, filterable).
|
||
|
||
```bash
|
||
curl "$BASE/api/sessions/my-session/messages?chatId=628123456789@c.us&limit=20&offset=0" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/messages/:chatId/history
|
||
|
||
Fetch chat history live from WhatsApp, bypassing the DB.
|
||
|
||
```bash
|
||
curl "$BASE/api/sessions/my-session/628123456789@c.us/history?limit=100&deep=true" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/messages/:chatId/:messageId/reactions
|
||
|
||
Get reactions for a message, grouped by emoji.
|
||
|
||
```bash
|
||
curl "$BASE/api/sessions/my-session/628123456789@c.us/true_628123456789@c.us_3EB0ABCD/reactions" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/messages/batch/:batchId
|
||
|
||
Get the status and progress of a bulk batch.
|
||
|
||
```bash
|
||
curl "$BASE/api/sessions/my-session/messages/batch/batch_a1b2c3d4" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/send-text
|
||
|
||
Send a plain text message.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/send-text" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "628123456789@c.us", "text": "Hello from OpenWA!" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/send-template
|
||
|
||
Render a stored template (`{{vars}}` substituted) and send it as text.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/send-template" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "628123456789@c.us", "templateName": "order-confirmation", "vars": { "customer": "Alice", "orderId": "1234" } }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/send-image
|
||
|
||
Send an image by URL or base64 with an optional caption.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/send-image" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "628123456789@c.us", "url": "https://example.com/image.jpg", "caption": "Check out this image!" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/send-video
|
||
|
||
Send a video by URL or base64 with an optional caption.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/send-video" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "628123456789@c.us", "url": "https://example.com/clip.mp4", "caption": "video" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/send-audio
|
||
|
||
Send an audio message by URL or base64. Add `"ptt": true` to send a real WhatsApp voice note (mic bubble + waveform); the server defaults the mimetype to `audio/ogg; codecs=opus` when `ptt` is set without one.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/send-audio" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "628123456789@c.us", "url": "https://example.com/voice.ogg", "mimetype": "audio/ogg", "ptt": true }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/send-document
|
||
|
||
Send a document/file by URL or base64.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/send-document" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "628123456789@c.us", "url": "https://example.com/report.pdf", "filename": "report.pdf", "mimetype": "application/pdf" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/send-location
|
||
|
||
Send a location pin.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/send-location" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "628123456789@c.us", "latitude": -6.2088, "longitude": 106.8456, "description": "Jakarta", "address": "Central Jakarta" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/send-contact
|
||
|
||
Send a contact card (vCard).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/send-contact" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "628123456789@c.us", "contactName": "John Doe", "contactNumber": "628987654321" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/send-sticker
|
||
|
||
Send a sticker by URL or base64 (typically webp).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/send-sticker" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "628123456789@c.us", "url": "https://example.com/sticker.webp", "mimetype": "image/webp" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/send-poll
|
||
|
||
Send a native WhatsApp poll (2–12 options; single choice unless `allowMultipleAnswers` is true).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/send-poll" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "1203630000@g.us", "name": "Where should we meet?", "options": ["Park", "Beach", "Downtown"] }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/reply
|
||
|
||
Reply to a message, quoting a prior one.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/reply" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "628123456789@c.us", "quotedMessageId": "true_628123456789@c.us_3EB0ABCD", "text": "Replying to you" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/forward
|
||
|
||
Forward a message from one chat to another.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/forward" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "fromChatId": "628111111111@c.us", "toChatId": "628222222222@c.us", "messageId": "true_628111111111@c.us_3EB0XYZ" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/react
|
||
|
||
Add a reaction (send an empty `emoji` to remove it).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/react" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "628123456789@c.us", "messageId": "true_628123456789@c.us_3EB0ABCD", "emoji": "👍" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/delete
|
||
|
||
Delete a message (for everyone by default).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/delete" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "628123456789@c.us", "messageId": "true_628123456789@c.us_3EB0ABCD", "forEveryone": true }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/send-bulk
|
||
|
||
Send to multiple recipients as an async batch (max 100 messages).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/send-bulk" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"messages": [
|
||
{ "chatId": "628111111111@c.us", "type": "text", "content": { "text": "Hi {{name}}" }, "variables": { "name": "Alice" } },
|
||
{ "chatId": "628222222222@c.us", "type": "image", "content": { "image": { "url": "https://example.com/promo.jpg" }, "caption": "Promo" } }
|
||
],
|
||
"options": { "delayBetweenMessages": 3000, "randomizeDelay": true, "stopOnError": false }
|
||
}'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/batch/:batchId/cancel
|
||
|
||
Cancel a running bulk batch (no body).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/batch/batch_a1b2c3d4/cancel" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
### 07.5 Contacts
|
||
|
||
#### GET /api/sessions/:sessionId/contacts
|
||
|
||
List contacts for a session (paginated window).
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/main/contacts?limit=100&offset=0" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/contacts/check/:number
|
||
|
||
Check whether a phone number is on WhatsApp.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/main/contacts/check/628123456789" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/contacts/:contactId
|
||
|
||
Get a single contact by its WhatsApp id.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/main/contacts/6281234567890@c.us" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/contacts/:contactId/profile-picture
|
||
|
||
Get a contact's profile picture URL.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/main/contacts/6281234567890@c.us/profile-picture" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/contacts/:contactId/phone
|
||
|
||
Resolve a contact id (e.g. an @lid) to a phone number.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/main/contacts/12345678901234@lid/phone" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/contacts/:contactId/block
|
||
|
||
Block a contact (requires an OPERATOR key). Send an empty body.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/main/contacts/6281234567890@c.us/block" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{}'
|
||
```
|
||
|
||
#### DELETE /api/sessions/:sessionId/contacts/:contactId/block
|
||
|
||
Unblock a contact (requires an OPERATOR key).
|
||
|
||
```bash
|
||
curl -X DELETE "$BASE/api/sessions/main/contacts/6281234567890@c.us/block" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
### 07.6 Groups
|
||
|
||
#### GET /api/sessions/:sessionId/groups
|
||
|
||
List all groups for a session (paginated).
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/my-session/groups?limit=1000&offset=0" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/groups/:groupId
|
||
|
||
Get detailed group info including participants.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/my-session/groups/120363021234567890@g.us" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/groups/:groupId/invite-code
|
||
|
||
Get the group invite code and full invite link.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/my-session/groups/120363021234567890@g.us/invite-code" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/groups
|
||
|
||
Create a new group with an initial set of participants (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/groups" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "name": "Project Team", "participants": ["628123456789@c.us", "628987654321@c.us"] }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/groups/:groupId/participants
|
||
|
||
Add participants to a group (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/groups/120363021234567890@g.us/participants" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "participants": ["628123456789@c.us"] }'
|
||
```
|
||
|
||
#### DELETE /api/sessions/:sessionId/groups/:groupId/participants
|
||
|
||
Remove participants from a group (OPERATOR). This DELETE takes a JSON body.
|
||
|
||
```bash
|
||
curl -X DELETE "$BASE/api/sessions/my-session/groups/120363021234567890@g.us/participants" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "participants": ["628123456789@c.us"] }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/groups/:groupId/participants/promote
|
||
|
||
Promote participants to group admin (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/groups/120363021234567890@g.us/participants/promote" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "participants": ["628123456789@c.us"] }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/groups/:groupId/participants/demote
|
||
|
||
Demote participants from group admin (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/groups/120363021234567890@g.us/participants/demote" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "participants": ["628123456789@c.us"] }'
|
||
```
|
||
|
||
#### PUT /api/sessions/:sessionId/groups/:groupId/subject
|
||
|
||
Change the group name/subject (OPERATOR).
|
||
|
||
```bash
|
||
curl -X PUT "$BASE/api/sessions/my-session/groups/120363021234567890@g.us/subject" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "subject": "New Team Name" }'
|
||
```
|
||
|
||
#### PUT /api/sessions/:sessionId/groups/:groupId/description
|
||
|
||
Change the group description; an empty string clears it (OPERATOR).
|
||
|
||
```bash
|
||
curl -X PUT "$BASE/api/sessions/my-session/groups/120363021234567890@g.us/description" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "description": "Internal coordination group." }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/groups/:groupId/leave
|
||
|
||
Leave a group (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/groups/120363021234567890@g.us/leave" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/groups/:groupId/invite-code/revoke
|
||
|
||
Revoke the current invite code and generate a new one (OPERATOR).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/groups/120363021234567890@g.us/invite-code/revoke" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
### 07.7 Message Templates
|
||
|
||
All template routes are nested under a session and require an OPERATOR-level key.
|
||
|
||
#### GET /api/sessions/:sessionId/templates
|
||
|
||
List all templates for a session, newest first.
|
||
|
||
```bash
|
||
curl "$BASE/api/sessions/$SESSION_ID/templates" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/templates/:id
|
||
|
||
Get a single template by ID.
|
||
|
||
```bash
|
||
curl "$BASE/api/sessions/$SESSION_ID/templates/$TEMPLATE_ID" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/templates
|
||
|
||
Create a message template with `{{variable}}` placeholders.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/$SESSION_ID/templates" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"name": "order-confirmation",
|
||
"body": "Hi {{customer}}, your order {{orderId}} has shipped.",
|
||
"header": "OpenWA Store",
|
||
"footer": "Reply STOP to unsubscribe."
|
||
}'
|
||
```
|
||
|
||
#### PUT /api/sessions/:sessionId/templates/:id
|
||
|
||
Update a template (partial; only provided fields change).
|
||
|
||
```bash
|
||
curl -X PUT "$BASE/api/sessions/$SESSION_ID/templates/$TEMPLATE_ID" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"body": "Hi {{customer}}, your order {{orderId}} is out for delivery.",
|
||
"footer": "Thanks for shopping with us."
|
||
}'
|
||
```
|
||
|
||
#### DELETE /api/sessions/:sessionId/templates/:id
|
||
|
||
Delete a template by ID (returns `204` empty body).
|
||
|
||
```bash
|
||
curl -X DELETE "$BASE/api/sessions/$SESSION_ID/templates/$TEMPLATE_ID" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
### 07.8 Catalog & Channels
|
||
|
||
#### GET /api/sessions/:sessionId/catalog
|
||
|
||
Get business catalog info for the session.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/my-session/catalog" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/catalog/products
|
||
|
||
List catalog products with pagination.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/my-session/catalog/products?page=1&limit=20" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/catalog/products/:productId
|
||
|
||
Get a specific catalog product by id (unknown id returns 200 with `null`).
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/my-session/catalog/products/PROD_12345" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/send-product
|
||
|
||
Send a product card to a chat (OPERATOR key required).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/send-product" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "6281234567890@c.us", "productId": "PROD_12345", "body": "Check out this item!" }'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/messages/send-catalog
|
||
|
||
Send the business catalog link to a chat (OPERATOR key required).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/messages/send-catalog" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "chatId": "6281234567890@c.us", "body": "Browse our full catalog here" }'
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/channels
|
||
|
||
List subscribed channels/newsletters.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/my-session/channels" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/channels/:channelId
|
||
|
||
Get a single channel by id.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/my-session/channels/120363000000000000@newsletter" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/channels/:channelId/messages
|
||
|
||
Get recent messages from a channel.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/my-session/channels/120363000000000000@newsletter/messages?limit=50" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/channels/subscribe
|
||
|
||
Subscribe to a channel by invite code (OPERATOR key required).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/channels/subscribe" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "inviteCode": "ABC123xyz" }'
|
||
```
|
||
|
||
#### DELETE /api/sessions/:sessionId/channels/:channelId
|
||
|
||
Unsubscribe from a channel (OPERATOR key required).
|
||
|
||
```bash
|
||
curl -X DELETE "$BASE/api/sessions/my-session/channels/120363000000000000@newsletter" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
### 07.9 Labels & Status
|
||
|
||
```bash
|
||
# List all labels for a session (WhatsApp Business only)
|
||
curl -X GET "$BASE/api/sessions/$SESSION_ID/labels" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
```bash
|
||
# Get a single label by ID
|
||
curl -X GET "$BASE/api/sessions/$SESSION_ID/labels/5" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
```bash
|
||
# List labels assigned to a chat
|
||
curl -X GET "$BASE/api/sessions/$SESSION_ID/labels/chat/6281234567890@c.us" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
```bash
|
||
# Add a label to a chat (OPERATOR)
|
||
curl -X POST "$BASE/api/sessions/$SESSION_ID/labels/chat/6281234567890@c.us" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "labelId": "5" }'
|
||
```
|
||
|
||
```bash
|
||
# Remove a label from a chat (OPERATOR)
|
||
curl -X DELETE "$BASE/api/sessions/$SESSION_ID/labels/chat/6281234567890@c.us/5" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
```bash
|
||
# Get all status updates (stories) visible to the session
|
||
curl -X GET "$BASE/api/sessions/$SESSION_ID/status" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
```bash
|
||
# Get status updates posted by a specific contact
|
||
curl -X GET "$BASE/api/sessions/$SESSION_ID/status/6281234567890@c.us" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
```bash
|
||
# Post a text status (OPERATOR)
|
||
curl -X POST "$BASE/api/sessions/$SESSION_ID/status/send-text" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "text": "Hello from OpenWA!", "backgroundColor": "#25D366", "font": 2 }'
|
||
```
|
||
|
||
```bash
|
||
# Post an image status from a URL (OPERATOR)
|
||
curl -X POST "$BASE/api/sessions/$SESSION_ID/status/send-image" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "image": { "url": "https://example.com/photo.jpg" }, "caption": "My status" }'
|
||
```
|
||
|
||
```bash
|
||
# Post a video status from a URL (OPERATOR)
|
||
curl -X POST "$BASE/api/sessions/$SESSION_ID/status/send-video" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "video": { "url": "https://example.com/clip.mp4" }, "caption": "Watch this" }'
|
||
```
|
||
|
||
```bash
|
||
# Delete one of the session's own posted statuses (OPERATOR)
|
||
curl -X DELETE "$BASE/api/sessions/$SESSION_ID/status/false_status@broadcast_3A1F" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
### 07.10 Webhooks (management)
|
||
|
||
All routes require an API key with OPERATOR role or higher. `secret` and `headers` are write-only (never returned). The per-session routes live under `/api/sessions/:sessionId/webhooks`; the cross-session list is `/api/webhooks`.
|
||
|
||
#### GET /api/sessions/:sessionId/webhooks
|
||
|
||
List all webhooks for a session (newest first).
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/my-session/webhooks" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/sessions/:sessionId/webhooks/:id
|
||
|
||
Get a single webhook by ID, scoped to the session.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/sessions/my-session/webhooks/f1e2d3c4-b5a6-7890-1234-567890abcdef" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/webhooks
|
||
|
||
List webhooks visible to the calling key (scoped to its allowed sessions). Add `limit`/`offset` to page large lists.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/webhooks?limit=100&offset=0" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/webhooks
|
||
|
||
Create a webhook for the session.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/webhooks" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"url": "https://your-server.com/webhook",
|
||
"events": ["message.received", "session.status"],
|
||
"secret": "your-secret-key",
|
||
"headers": { "X-Custom-Header": "value" },
|
||
"filters": {
|
||
"conditions": [
|
||
{ "field": "sender", "operator": "is", "value": ["1234567890@c.us"] },
|
||
{ "field": "body", "operator": "contains", "value": "invoice" }
|
||
]
|
||
},
|
||
"retryCount": 3
|
||
}'
|
||
```
|
||
|
||
#### PUT /api/sessions/:sessionId/webhooks/:id
|
||
|
||
Update a webhook (partial; only provided fields change).
|
||
|
||
```bash
|
||
curl -X PUT "$BASE/api/sessions/my-session/webhooks/f1e2d3c4-b5a6-7890-1234-567890abcdef" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"events": ["*"],
|
||
"active": false,
|
||
"retryCount": 5,
|
||
"filters": null
|
||
}'
|
||
```
|
||
|
||
#### POST /api/sessions/:sessionId/webhooks/:id/test
|
||
|
||
Send a synthetic test payload to the webhook URL and report the result (no request body).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/sessions/my-session/webhooks/f1e2d3c4-b5a6-7890-1234-567890abcdef/test" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### DELETE /api/sessions/:sessionId/webhooks/:id
|
||
|
||
Delete a webhook (returns `204` no content).
|
||
|
||
```bash
|
||
curl -X DELETE "$BASE/api/sessions/my-session/webhooks/f1e2d3c4-b5a6-7890-1234-567890abcdef" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
### 07.11 API Keys
|
||
|
||
All `/api/auth/api-keys` routes require an **ADMIN** key. `POST /api/auth/validate` accepts any valid key. The plaintext key is returned only by the create call.
|
||
|
||
#### GET /api/auth/api-keys
|
||
|
||
List all API keys (newest first).
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/auth/api-keys" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/auth/api-keys/:id
|
||
|
||
Get one API key by id.
|
||
|
||
```bash
|
||
curl -X GET "$BASE/api/auth/api-keys/3f2a1c9e-1b2d-4a5f-9c8e-aa11bb22cc33" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/auth/api-keys
|
||
|
||
Create a key; the response includes the full plaintext key once.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/auth/api-keys" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"name": "Production Bot",
|
||
"role": "operator",
|
||
"allowedIps": ["192.168.1.1", "10.0.0.0/8"],
|
||
"allowedSessions": ["session-uuid-1"],
|
||
"expiresAt": "2027-12-31T23:59:59Z"
|
||
}'
|
||
```
|
||
|
||
#### PUT /api/auth/api-keys/:id
|
||
|
||
Update name/role/allowedIps/allowedSessions/expiresAt.
|
||
|
||
```bash
|
||
curl -X PUT "$BASE/api/auth/api-keys/3f2a1c9e-1b2d-4a5f-9c8e-aa11bb22cc33" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"name": "Renamed Bot",
|
||
"role": "viewer",
|
||
"allowedIps": ["203.0.113.5"],
|
||
"expiresAt": "2028-01-01T00:00:00Z"
|
||
}'
|
||
```
|
||
|
||
#### POST /api/auth/api-keys/:id/revoke
|
||
|
||
Deactivate a key without deleting it (no body).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/auth/api-keys/3f2a1c9e-1b2d-4a5f-9c8e-aa11bb22cc33/revoke" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### DELETE /api/auth/api-keys/:id
|
||
|
||
Permanently delete a key (returns `204`, no body).
|
||
|
||
```bash
|
||
curl -X DELETE "$BASE/api/auth/api-keys/3f2a1c9e-1b2d-4a5f-9c8e-aa11bb22cc33" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/auth/validate
|
||
|
||
Validate the supplied key and report its role (empty body; key read from the header).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/auth/validate" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
### 07.12 System (Health, Metrics, Stats, Settings)
|
||
|
||
#### GET /api/health
|
||
|
||
Basic health check (status, timestamp, version). Public.
|
||
|
||
```bash
|
||
curl "$BASE/api/health"
|
||
```
|
||
|
||
#### GET /api/health/live
|
||
|
||
Liveness probe — always `{ "status": "ok" }`. Public.
|
||
|
||
```bash
|
||
curl "$BASE/api/health/live"
|
||
```
|
||
|
||
#### GET /api/health/ready
|
||
|
||
Readiness probe — checks both datasources; `503` while draining or on DB failure. Public.
|
||
|
||
```bash
|
||
curl "$BASE/api/health/ready"
|
||
```
|
||
|
||
#### GET /api/metrics
|
||
|
||
Prometheus scrape. Gated by the metrics bearer token (not the API key); `404` when `METRICS_TOKEN` is unset.
|
||
|
||
```bash
|
||
curl "$BASE/api/metrics" \
|
||
-H "Authorization: Bearer $METRICS_TOKEN"
|
||
```
|
||
|
||
#### GET /api/stats/overview
|
||
|
||
Cross-session aggregate stats. ADMIN key required.
|
||
|
||
```bash
|
||
curl "$BASE/api/stats/overview" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/stats/messages
|
||
|
||
Message stats over a period (`24h` | `7d` | `30d`, default `24h`). ADMIN key required.
|
||
|
||
```bash
|
||
curl "$BASE/api/stats/messages?period=7d" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/stats/sessions/:sessionId
|
||
|
||
Per-session stats. Any valid API key (not session-scoped).
|
||
|
||
```bash
|
||
curl "$BASE/api/stats/sessions/9f1c2d3e-…" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/settings
|
||
|
||
Read runtime settings (env-derived). ADMIN key required (`403` otherwise).
|
||
|
||
```bash
|
||
curl "$BASE/api/settings" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### PUT /api/settings
|
||
|
||
Always returns `501` — settings are read-only at runtime. ADMIN key required (still `501`).
|
||
|
||
```bash
|
||
curl -X PUT "$BASE/api/settings" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "general": { "sessionTimeout": 10 } }'
|
||
```
|
||
|
||
### 07.13 Administration (Infrastructure, Plugins, MCP)
|
||
|
||
ADMIN-only operations (except the public health check and the MCP transport). Assumes `BASE`, `API_KEY`, and — for MCP — that `MCP_ENABLED=true`.
|
||
|
||
#### GET /api/infra/health
|
||
|
||
Public liveness probe.
|
||
|
||
```bash
|
||
curl "$BASE/api/infra/health"
|
||
```
|
||
|
||
#### GET /api/infra/status
|
||
|
||
Aggregate infra status (DB, Redis, queue, storage, engine).
|
||
|
||
```bash
|
||
curl "$BASE/api/infra/status" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/infra/engines
|
||
|
||
List available WhatsApp engine plugins.
|
||
|
||
```bash
|
||
curl "$BASE/api/infra/engines" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/infra/engines/current
|
||
|
||
Get the currently active engine type.
|
||
|
||
```bash
|
||
curl "$BASE/api/infra/engines/current" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/infra/config
|
||
|
||
Read saved infrastructure config (secrets omitted).
|
||
|
||
```bash
|
||
curl "$BASE/api/infra/config" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### PUT /api/infra/config
|
||
|
||
Merge-save infrastructure config to `data/.env.generated`.
|
||
|
||
```bash
|
||
curl -X PUT "$BASE/api/infra/config" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"database": { "type": "postgres", "host": "db.example.com", "port": "5432", "username": "openwa", "password": "s3cret", "database": "openwa", "poolSize": 10, "sslEnabled": true, "sslRejectUnauthorized": false },
|
||
"redis": { "enabled": true, "builtIn": true },
|
||
"queue": { "enabled": true },
|
||
"storage": { "type": "s3", "s3Bucket": "my-bucket", "s3Region": "ap-southeast-1", "s3AccessKey": "AKIA...", "s3SecretKey": "...", "s3Endpoint": "https://s3.example.com" },
|
||
"engine": { "type": "whatsapp-web.js", "headless": true }
|
||
}'
|
||
```
|
||
|
||
#### POST /api/infra/restart
|
||
|
||
Request a graceful restart, optionally orchestrating Docker profiles.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/infra/restart" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "profiles": ["postgres", "redis"], "profilesToRemove": ["minio"] }'
|
||
```
|
||
|
||
#### GET /api/infra/export-data
|
||
|
||
Export all Data DB rows as JSON for migration.
|
||
|
||
```bash
|
||
curl "$BASE/api/infra/export-data" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/infra/import-data
|
||
|
||
Replace all Data DB rows with a prior export (destructive, all-or-nothing).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/infra/import-data" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"tables": {
|
||
"sessions": [ { "id": "s1", "name": "main", "status": "READY", "phone": "15551234567", "pushName": "Me", "config": {}, "proxyUrl": null, "proxyType": null, "connectedAt": "2026-06-25T00:00:00.000Z", "lastActiveAt": "2026-06-25T00:00:00.000Z", "createdAt": "2026-06-25T00:00:00.000Z", "updatedAt": "2026-06-25T00:00:00.000Z" } ],
|
||
"webhooks": [], "messages": [], "messageBatches": [], "templates": [], "baileysStoredMessages": []
|
||
}
|
||
}'
|
||
```
|
||
|
||
#### GET /api/infra/storage/files/count
|
||
|
||
File count and total size in the active storage backend.
|
||
|
||
```bash
|
||
curl "$BASE/api/infra/storage/files/count" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/infra/storage/export
|
||
|
||
Export all storage files to a tar.gz; returns its server-side path.
|
||
|
||
```bash
|
||
curl "$BASE/api/infra/storage/export" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/infra/storage/import
|
||
|
||
Import storage files from a tar.gz located inside `data/`.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/infra/storage/import" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "filePath": "./data/exports/storage-export-1750000000000-abc.tar.gz" }'
|
||
```
|
||
|
||
#### GET /api/plugins
|
||
|
||
List all loaded plugins (secrets redacted).
|
||
|
||
```bash
|
||
curl "$BASE/api/plugins" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/plugins/catalog
|
||
|
||
List the remote plugin catalog with install state.
|
||
|
||
```bash
|
||
curl "$BASE/api/plugins/catalog" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/plugins/:id
|
||
|
||
Get a single plugin by id.
|
||
|
||
```bash
|
||
curl "$BASE/api/plugins/chat-flow" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/plugins/:id/config-ui
|
||
|
||
Fetch a plugin's sandboxed config-UI HTML (for an iframe srcdoc).
|
||
|
||
```bash
|
||
curl "$BASE/api/plugins/chat-flow/config-ui" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### GET /api/plugins/:id/health
|
||
|
||
Check a plugin's health.
|
||
|
||
```bash
|
||
curl "$BASE/api/plugins/chat-flow/health" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/plugins/install
|
||
|
||
Install a plugin from an uploaded .zip (multipart, field `file`, max 5 MB).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/plugins/install" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-F "file=@my-plugin.zip"
|
||
```
|
||
|
||
#### POST /api/plugins/install-url
|
||
|
||
Install a plugin by downloading its .zip from a URL (SSRF-guarded).
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/plugins/install-url" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "url": "https://github.com/openwa-plugins/chat-flow/releases/download/v1.0.0/chat-flow.zip" }'
|
||
```
|
||
|
||
#### POST /api/plugins/:id/enable
|
||
|
||
Enable a plugin.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/plugins/chat-flow/enable" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /api/plugins/:id/disable
|
||
|
||
Disable a plugin.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/plugins/chat-flow/disable" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### PUT /api/plugins/:id/config
|
||
|
||
Update a plugin's base configuration.
|
||
|
||
```bash
|
||
curl -X PUT "$BASE/api/plugins/chat-flow/config" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "config": { "apiKey": "sk-...", "replyDelayMs": 1500 } }'
|
||
```
|
||
|
||
#### PUT /api/plugins/:id/config/:sessionId
|
||
|
||
Set (or clear with `{}`) a per-session plugin config override.
|
||
|
||
```bash
|
||
curl -X PUT "$BASE/api/plugins/chat-flow/config/session-1" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "config": { "replyDelayMs": 3000 } }'
|
||
```
|
||
|
||
#### PUT /api/plugins/:id/sessions
|
||
|
||
Set which sessions a session-scoped plugin is activated for (`["*"]` = all).
|
||
|
||
```bash
|
||
curl -X PUT "$BASE/api/plugins/chat-flow/sessions" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "sessions": ["*"] }'
|
||
```
|
||
|
||
#### POST /api/plugins/:id/update
|
||
|
||
Update an installed plugin in place from a URL.
|
||
|
||
```bash
|
||
curl -X POST "$BASE/api/plugins/chat-flow/update" \
|
||
-H "X-API-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "url": "https://example.com/plugins/chat-flow-1.1.0.zip" }'
|
||
```
|
||
|
||
#### DELETE /api/plugins/:id
|
||
|
||
Uninstall a plugin (built-ins protected).
|
||
|
||
```bash
|
||
curl -X DELETE "$BASE/api/plugins/chat-flow" \
|
||
-H "X-API-Key: $API_KEY"
|
||
```
|
||
|
||
#### POST /mcp
|
||
|
||
MCP JSON-RPC 2.0 transport (no `/api` prefix; gated by `MCP_ENABLED=true`). The API key goes via `X-Api-Key` or `Authorization: Bearer`; auth is enforced per tool call. See doc 24 for the tool catalog.
|
||
|
||
```bash
|
||
# Initialize handshake
|
||
curl -X POST "$BASE/mcp" \
|
||
-H "X-Api-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-06-18", "capabilities": {}, "clientInfo": { "name": "openwa-collection", "version": "1.0.0" } } }'
|
||
|
||
# List available tools
|
||
curl -X POST "$BASE/mcp" \
|
||
-H "X-Api-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {} }'
|
||
|
||
# Call a tool (arguments must match the tool's zod inputSchema)
|
||
curl -X POST "$BASE/mcp" \
|
||
-H "X-Api-Key: $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "session_send_text", "arguments": { "sessionId": "default", "to": "6281234567890", "text": "Hello from MCP" } } }'
|
||
```
|
||
|
||
### 07.14 Real-time (WebSocket)
|
||
|
||
Events are delivered over **Socket.IO** on the `/events` namespace (not a raw WebSocket). Use the `socket.io-client` package. Set `BASE_WS` (e.g. `ws://localhost:2785`) and `API_KEY`.
|
||
|
||
```bash
|
||
npm install socket.io-client
|
||
```
|
||
|
||
```js
|
||
// realtime.mjs — run: BASE_WS=ws://localhost:2785 API_KEY=... SESSION_ID=main node realtime.mjs
|
||
import { io } from 'socket.io-client';
|
||
|
||
const BASE_WS = process.env.BASE_WS || 'ws://localhost:2785';
|
||
const API_KEY = process.env.API_KEY;
|
||
const SESSION_ID = process.env.SESSION_ID || 'main';
|
||
|
||
const socket = io(`${BASE_WS}/events`, {
|
||
auth: { apiKey: API_KEY }, // or transport.headers / ?apiKey=
|
||
});
|
||
|
||
socket.on('connect', () => {
|
||
console.log('connected:', socket.id);
|
||
socket.emit('message', {
|
||
type: 'subscribe',
|
||
sessionId: SESSION_ID,
|
||
events: ['*'], // or e.g. ['message.received', 'session.status']
|
||
requestId: 'sub-1',
|
||
});
|
||
});
|
||
|
||
socket.on('message', (msg) => {
|
||
if (msg.type === 'event') {
|
||
console.log(`[${msg.payload.event}] ${msg.payload.sessionId}`, msg.payload.data);
|
||
} else {
|
||
console.log(`[${msg.type}]`, msg); // subscribed | unsubscribed | pong | error
|
||
}
|
||
});
|
||
|
||
socket.on('connect_error', (err) => console.error('connect_error:', err.message));
|
||
socket.on('disconnect', (reason) => console.log('disconnected:', reason));
|
||
```
|