# Whatsapp Messaging

> Send WhatsApp messages via ZapHook. Use when user wants to: send text/image/video/audio/document/sticker to WhatsApp numbers, create interactive buttons or lists, send templates, react to messages, mark as read, or show typing indicator. Do not use for reading incoming messages, listing events, or checking delivery status. Requires channel_id (UUID) and phone number in international format (digits only, e.g. 5511999999999).

- Skill: `zaphook/whatsapp-messaging` (Agent Skill, multi-file: 14 files)
- Install (CLI): `npx skillmds@latest add zaphook/whatsapp-messaging`
- Raw SKILL.md: https://api.skillmd.com/api/skills/zaphook/whatsapp-messaging/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- License: MIT
- Author: zaphook (https://skillmd.com/u/zaphook)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/zaphook/whatsapp-messaging

---


# WhatsApp Messaging

Base URL: `https://api.zaphook.cloud`
Auth: `Authorization: Bearer zph_...`

All endpoints require `channel_id` (uuid) and `to` (phone number, international format, digits only, 10-15 chars).

## Commands

### Send Text
```bash
node scripts/send-text.mjs --channel-id <uuid> --to 5511999999999 --body "Hello!"
```
POST /api/public/v1/messages/send-text
Body: `{ "channel_id": "uuid", "to": "phone", "text": { "body": "msg", "preview_url": false } }`

### Send Buttons (1-3 buttons)
```bash
node scripts/send-buttons.mjs --channel-id <uuid> --to <phone> --body "Choose:" --buttons '[{"id":"yes","title":"Yes"},{"id":"no","title":"No"}]'
```
POST /api/public/v1/messages/send-buttons
Body: `{ "channel_id", "to", "body", "buttons": [{"id","title"}], "header?", "footer?" }`

### Send List
```bash
node scripts/send-list.mjs --channel-id <uuid> --to <phone> --body "Select:" --button-text "Menu" --sections '[{"title":"S1","rows":[{"id":"1","title":"Item","description":"desc"}]}]'
```
POST /api/public/v1/messages/send-list
Body: `{ "channel_id", "to", "body", "button_text", "sections": [{"title","rows":[{"id","title","description?"}]}], "header?", "footer?" }`

### Send Image
```bash
node scripts/send-image.mjs --channel-id <uuid> --to <phone> --link "https://..." [--caption "text"]
```
POST /api/public/v1/messages/send-image
Body: `{ "channel_id", "to", "image": {"link":"url"} or {"id":"media_id"}, "caption?" }`

### Send Video
```bash
node scripts/send-video.mjs --channel-id <uuid> --to <phone> --link "https://..." [--caption "text"]
```
POST /api/public/v1/messages/send-video

### Send Audio
```bash
node scripts/send-audio.mjs --channel-id <uuid> --to <phone> --link "https://..."
```
POST /api/public/v1/messages/send-audio

### Send Document
```bash
node scripts/send-document.mjs --channel-id <uuid> --to <phone> --link "https://..." [--filename "doc.pdf"] [--caption "text"]
```
POST /api/public/v1/messages/send-document

### Send Sticker (.webp, 512x512, max 100KB static / 500KB animated)
```bash
node scripts/send-sticker.mjs --channel-id <uuid> --to <phone> --link "https://..."
```
POST /api/public/v1/messages/send-sticker

### Send Location
```bash
node scripts/send-location.mjs --channel-id <uuid> --to <phone> --lat -23.55 --lng -46.63 [--name "Place"] [--address "Street"]
```
POST /api/public/v1/messages/send-location
Body: `{ "channel_id", "to", "location": {"latitude","longitude","name?","address?"} }`

### Request Location
POST /api/public/v1/messages/request-location
Body: `{ "channel_id", "to", "body": "Please share your location" }`

### Send Contact
POST /api/public/v1/messages/send-contact
Body: `{ "channel_id", "to", "contacts": [{"name":{"formatted_name","first_name","last_name?"},"phones":[{"phone","type?"}],"emails?","urls?","addresses?","org?","birthday?"}] }`

### Send Reaction
```bash
node scripts/send-reaction.mjs --channel-id <uuid> --to <phone> --message-id "wamid.x" --emoji "👍"
```
POST /api/public/v1/messages/send-reaction
Body: `{ "channel_id", "to", "message_id", "emoji" }` (empty emoji to remove)

### Mark as Read
```bash
node scripts/mark-as-read.mjs --channel-id <uuid> --message-id "wamid.x"
```
POST /api/public/v1/messages/mark-as-read
Body: `{ "channel_id", "message_id" }`

### Send Template
```bash
node scripts/send-template.mjs --channel-id <uuid> --to <phone> --name "hello_world" --language "pt_BR" [--components '[{"type":"body","parameters":[{"type":"text","text":"João"}]}]']
```
POST /api/public/v1/messages/send-template
Body: `{ "channel_id", "to", "template": {"name","language","components?"} }`

### Typing Indicator
```bash
node scripts/typing.mjs --channel-id <uuid> --message-id "wamid.x"
```
POST /api/public/v1/messages/typing
Body: `{ "channel_id", "message_id" }` (also marks as read, shows typing ~25s)

## Response Format

```json
{ "data": { "message_id": "wamid.xxx", "status": "sent" }, "meta": { "request_id": "uuid", "timestamp": "ISO8601" } }
```

## Troubleshooting

If a message send fails:
1. Check channel health: use `zaphook-api` skill → `node scripts/channel-status.mjs --channel-id <id>`
2. If channel is inactive or not found: verify channel exists with `node scripts/get-channel.mjs --channel-id <id>`
3. Check delivery logs: use `observe-whatsapp` skill → `node scripts/list-events.mjs --has-errors true --channel-id <id>`
4. Inspect specific failure: use `observe-whatsapp` skill → `node scripts/get-event.mjs --event-id <uuid>`
5. If 401: API key invalid or expired → run `npx zaphook-skills configure`
6. If 429: rate limit exceeded → wait and retry (built-in exponential backoff handles this automatically)
7. If 422: check required fields and phone number format (digits only, 10-15 chars, international format)

## Related skills

- `zaphook-api` — Channel and destination management
- `observe-whatsapp` — Monitor events and delivery status

## Agent Rules

- **Never send a message without explicit user permission.** Always confirm before executing any send command.
- **Portuguese (pt-BR):** Always use proper accents and special characters (ã, ç, é, ê, í, ó, ú, à, ü) when composing messages in Portuguese. Never omit diacritics.
- **English:** Use standard English without localization issues.
- Use `--dry-run` to preview payloads before sending when unsure about parameters.

