Miauzap is an implementation of the whatsmeowlibrary as a simple RESTful API service with support for multiple devices and concurrent sessions.
The whatsmeow library does not use Puppeteer in headless Chrome, nor an Android emulator. It communicates directly with WhatsApp's websocket servers, being quite fast and using less memory and CPU than other solutions. The disadvantage is that a change in WhatsApp's protocol could break connections and would require a library update.
Authentication
Miauzap offers two authentication methods:
- For regular users:Use the
tokenheader which will be matched with the 'users' table in the database. - For administrators:Use the
Authorizationheader with the administrative token to access protected administration routes.
Example request with user token:
curl -X POST https: //seu-dominio.com/webhook \
-H "token: seu_token_aqui" \
-H "Content-Type: application/json" \
-d '{
"webhook": "https://seu-webhook.com/callback",
"events": ["Message",
"ReadReceipt"]
}
'
Getting Started
To start using the Miauzap API, follow these steps:
- Create a user:
You need to create a user in the database. The administrator can create a new user through the
/admin/usersroute. - Connect to WhatsApp:
Use the
/session/connectendpoint to start a connection with WhatsApp servers. - Scan the QR code:
Get the QR code through the
/session/qrendpoint and scan it with your WhatsApp app. - Configure your Webhook:
Use the
/webhookendpoint to configure your webhook URL and the types of events you want to receive. - Send messages:
Now you're ready to send messages using the various endpoints available at
/chat/send /*.
Session
Endpoints to manage the connection with WhatsApp servers.
POST /session/connect
Connects to WhatsApp servers. If there is no previous session, you will need to scan a QR code.
Body Parameters:
| Parameter | Type | Description |
|---|---|---|
| Subscribe | Array[string] | List of event types to subscribe to. Possible values: "Message", "ReadReceipt", "Presence", "HistorySync", "ChatPresence", "All" |
| Immediate | boolean | If true, returns immediately without waiting for connection confirmation |
Request Example:
{
"Subscribe": ["Message", "ReadReceipt"],
"Immediate": true
}
Response:
{
"code": 200,
"data": {
"details": "Connected!",
"events": "Message,ReadReceipt",
"jid": "5491155555555.0:53@s.whatsapp.net",
"webhook": "https://some.site/webhook?request=parameter"
},
"success": true
}
Request Example (cURL):
curl -X POST "http://localhost:8080/session/connect" \
-H "token: YOUR_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{
"Subscribe": ["Message", "ReadReceipt"],
"Immediate": true
}'
POST /session/disconnect
Disconnects from WhatsApp servers without ending the session.
Response:
{
"code": 200,
"data": {
"Details": "Disconnected"
},
"success": true
}
POST /session/logout
Ends the connection and terminates the session, requiring QR scanning again on next connection.
Response:
{
"code": 200,
"data": {
"Details": "Logged out"
},
"success": true
}
GET /session/status
Gets the current connection and session status.
Response:
{
"code": 200,
"data": {
"Connected": true,
"LoggedIn": true
},
"success": true
}
GET /session/qr
Gets the QR code for scanning in the WhatsApp app.
Response:
{
"code": 200,
"data": {
"QRCode": "data:image/png;base64,iVBORw0KGgoA..."
},
"success": true
}
Webhook
Endpoints to configure webhooks that will receive event notifications.
GET /webhook
Gets the configured webhook and subscribed events.
Response:
{
"code": 200,
"data": {
"subscribe": ["Message", "ReadReceipt"],
"webhook": "https://example.net/webhook"
},
"success": true
}
POST /webhook
Configures a webhook to receive events.
Body Parameters:
| Parameter | Type | Description |
|---|---|---|
| webhook | string | Webhook URL that will receive the calls |
| events | Array[string] | List of event types to subscribe to. See the "Available Event Types" section below for the complete list. |
| active | boolean | Defines whether the webhook is active or not. Default: true |
Request Example:
{
"webhook": "https://example.net/webhook",
"events": ["Message", "ReadReceipt"]
}
Response:
{
"code": 200,
"data": {
"webhook": "https://example.net/webhook",
"events": ["Message", "ReadReceipt"]
},
"success": true
}
PUT /webhook
Updates the webhook configuration. Can update only the URL, only the events, or both.
Body Parameters:
| Parameter | Type | Description |
|---|---|---|
| webhook | string | New webhook URL (optional if only updating events) |
| events | Array[string] | New event list (optional if only updating URL) |
| active | boolean | Activate or deactivate the webhook |
Request Examples:
// Atualizar apenas eventos
{
"events": ["Message", "Receipt", "GroupInfo"],
"active": true
}
// Atualizar apenas URL
{
"webhook": "https://novo-endpoint.com/webhook",
"active": true
}
// Desativar webhook
{
"active": false
}
DELETE /webhook
Removes the webhook and clears the event configuration.
Response:
{
"code": 200,
"data": {
"message": "Webhook removed successfully"
},
"success": true
}
Available Event Types
Below is the complete list of events you can subscribe to:
Messages and Communication
Message- Message received or sentUndecryptableMessage- Message that could not be decryptedReceipt- Delivery/read confirmationMediaRetry- Media resend attempt
Groups and Contacts
GroupInfo- Group information updatedJoinedGroup- Joined a groupPicture- Profile picture updatedBlocklistChange- Blocklist changeBlocklist- Blocklist
Connection and Session
Connected- Connected to WhatsAppDisconnected- Disconnected from WhatsAppConnectFailure- Connection failureKeepAliveRestored- Connection restoredKeepAliveTimeout- Connection timeoutLoggedOut- Session endedClientOutdated- Client outdatedTemporaryBan- Temporary banStreamError- Stream errorStreamReplaced- Stream replacedPairSuccess- Pairing successfulPairError- Pairing errorQR- QR code generatedQRTimeout- QR code timeoutQRScannedWithoutMultidevice- QR scanned without multi-device
Privacy and Settings
PrivacySettings- Privacy settingsPushNameSetting- Display name changedUserAbout- Status/About updated
Synchronization and State
AppState- Application stateAppStateSyncComplete- Synchronization completeHistorySync- History synchronizationOfflineSyncCompleted- Offline synchronization completedOfflineSyncPreview- Offline synchronization preview
Calls
CallOffer- Call offerCallAccept- Call acceptedCallTerminate- Call terminatedCallOfferNotice- Call offer notificationCallRelayLatency- Call relay latency
Presence and Activity
Presence- Presence statusChatPresence- Chat presence (typing)
Others
IdentityChange- Identity changeCATRefreshError- CAT refresh errorNewsletterJoin- Joined newsletterNewsletterLeave- Left newsletterNewsletterMuteChange- Newsletter mute changeNewsletterLiveUpdate- Newsletter live updateFBMessage- Facebook Bridge messageAll- Receive all events
Webhook Structure
When an event occurs, Miauzap sends a POST request to the configured webhook with the event data. Below are the formats of the main event types:
Received Message
{
"event": "Message",
"instance": "5491155553934.0:53@s.whatsapp.net",
"data": {
"id": "3EB0ABCD123456789",
"pushName": "Nome do Contato",
"fromMe": false,
"timestamp": 1647878528,
"chat": "5491199999999@s.whatsapp.net",
"sender": "5491199999999@s.whatsapp.net",
"message": {
"conversation": "Olá, como vai?"
}
}
}
Read Receipt
{
"event": "ReadReceipt",
"instance": "5491155553934.0:53@s.whatsapp.net",
"data": {
"sender": "5491199999999@s.whatsapp.net",
"chat": "5491199999999@s.whatsapp.net",
"ids": ["3EB0ABCD123456789"],
"timestamp": 1647878650
}
}
Presence
{
"event": "Presence",
"instance": "5491155553934.0:53@s.whatsapp.net",
"data": {
"sender": "5491199999999@s.whatsapp.net",
"status": "available",
"timestamp": 1647878750
}
}
Chat
Endpoints to send messages and manage chat interactions.
POST /chat/send/text
Sends a text message to a contact or group.
Body Parameters:
| Parameter | Type | Description |
|---|---|---|
| Phone | string | Recipient's phone number (with country code, without "+" or other special characters) |
| Body | string | Text message content |
| Id | string | Custom ID for the message. If not provided, a random ID will be generated |
| ContextInfo | object | Context information to reply to a specific message |
Request Example:
{
"Phone": "5491155553935",
"Body": "Olá, como você está?",
"Id": "ABCDABCD1234",
"ContextInfo": {
"StanzaId": "3EB06F9067F80BAB89FF",
"Participant": "5491155553935@s.whatsapp.net"
}
}
Response:
{
"code": 200,
"data": {
"Details": "Sent",
"Id": "ABCDABCD1234",
"Timestamp": "2023-03-24T15:49:08-03:00"
},
"success": true
}
Request Example (cURL):
curl -X POST "http://localhost:8080/chat/send/text" \
-H "token: YOUR_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{
"Phone": "5491155553935",
"Body": "Hello, how are you?"
}'
POST /chat/send/image
Sends an image to a contact or group.
Body Parameters:
| Parameter | Type | Description |
|---|---|---|
| Phone | string | Recipient's phone number |
| Image | string | Image in base64 format (must start with "data:image/jpeg;base64," or "data:image/png;base64,") |
| Caption | string | Optional caption for the image |
| Id | string | Custom ID for the message |
Request Example:
{
"Phone": "5491155553935",
"Image": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
"Caption": "Check this out!",
"Id": "IMG123456"
}
Response:
{
"code": 200,
"data": {
"Details": "Sent",
"Id": "IMG123456",
"Timestamp": "2023-03-24T15:50:00-03:00"
},
"success": true
}
Request Example (cURL):
curl -X POST "http://localhost:8080/chat/send/image" \
-H "token: YOUR_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{
"Phone": "5491155553935",
"Image": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
"Caption": "Check this out!"
}'
GET /chat/history
Recover the message history of a specific chat. Returns the messages in reverse chronological order (most recent first).
Parâmetros de Query:
| Parameter | Type | Description |
|---|---|---|
| chat_jid | string | JID (WhatsApp ID) of the chat to retrieve the history |
| limit | integer | Maximum number of messages to retrieve (default: 50, maximum: 1000) |
Request Example:
GET /chat/history?chat_jid=5491155553935@s.whatsapp.net&limit=10
Resposta de Sucesso:
{
"code": 200,
"success": true,
"data": [
{
"id": 1,
"user_id": "abc123def456",
"chat_jid": "5491155553935@s.whatsapp.net",
"sender_jid": "5491155554444@s.whatsapp.net",
"message_id": "3EB0C767D26A1B5F7C83",
"timestamp": "2023-12-01T15:30:00Z",
"message_type": "text",
"text_content": "Olá, como você está?",
"media_link": ""
},
{
"id": 2,
"user_id": "abc123def456",
"chat_jid": "5491155553935@s.whatsapp.net",
"sender_jid": "5491155553935@s.whatsapp.net",
"message_id": "4FB1D878E37B2C6G8D94",
"timestamp": "2023-12-01T15:25:00Z",
"message_type": "image",
"text_content": "Veja esta foto!",
"media_link": "https://example.com/media/image123.jpg"
}
]
}
Possible Errors:
| Code | Description |
|---|---|
| 400 | Invalid request - chat_jid parameter required |
| 501 | Not implemented - message history is disabled |
| 500 | Internal server error |
POST /media/upload
Uploads media to WhatsApp servers. Input must be multipart/form-data with a 'file' field.
Response:
{ "code": 200, "data": { "url": "...", "direct_path": "...", "media_key": "...", "mimetype": "image/jpeg", "file_enc_sha256": "...", "file_sha256": "...", "file_length": 12345 }, "success": true }
POST /chat/send/carousel
Sends an interactive carousel message with multiple cards. Cards can contain images, videos, or documents.
Body Parameters:
| Parameter | Type | Description |
|---|---|---|
| number | string | Recipient's phone number (alias: Phone) |
| text | string | Main message body text (alias: Body) |
| carousel | Array[object] | List of carousel cards (alias: Cards) |
Card Object:
| Parameter | Type | Description |
|---|---|---|
| image | string | Image URL or Base64 (optional) |
| video | string | Video URL or Base64 (optional) |
| document | string | Document URL or Base64 (optional) |
| header | string | Card header (text, ignored if media present) |
| body | string | Card body text (alias: text) |
| footer | string | Card footer text |
| buttons | Array | List of buttons (reply, url, copy) |
Request Example:
{
"number": "5491155553935",
"text": "Check out our latest products",
"carousel": [
{
"image": "https://example.com/product1.jpg",
"body": "Product 1 Description",
"buttons": [{"id": "buy1", "display_text": "Buy Now"}]
},
{
"video": "https://example.com/demo.mp4",
"body": "Product Demo",
"buttons": [
{"type": "url", "display_text": "Visit Website", "url": "https://example.com"}
]
}
]
}
Response:
{
"code": 200,
"data": {
"Details": "Sent",
"Id": "CAR123456",
"Timestamp": "2023-03-24T16:00:00-03:00"
},
"success": true
}
Request Example (cURL):
curl -X POST "http://localhost:8080/chat/send/carousel" \
-H "token: YOUR_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{
"number": "5491155553935",
"text": "Check out our latest products",
"carousel": [
{
"image": "https://example.com/product1.jpg",
"body": "Product 1 Description",
"buttons": [{"id": "buy1", "display_text": "Buy Now"}]
}
]
}'
POST /chat/send/poll
Sends a poll message to a group.
Request Example:
{
"group": "120363313346913103@g.us",
"header": "Qual o seu pet favorito?",
"options": ["Gato 🐱", "Cachorro 🐶", "Passarinho 🐦", "Peixe 🐟"]
}
POST /chat/send/edit
Edits an existing text message that you previously sent.
Request Example:
{
"phone": "5491155554444",
"body": "Texto corrigido após enviar 🐱",
"id": "MESSAGE_ID_TO_EDIT"
}
POST /chat/delete
Deletes (revokes) a message for everyone.
Request Example:
{
"phone": "5491155554444",
"id": "MESSAGE_ID_TO_DELETE"
}
POST /chat/react
Reacts to a specific message using emojis. Omit participant if it is a 1-on-1 chat.
Request Example:
{
"phone": "5491155554444",
"body": "❤️",
"id": "MESSAGE_ID_TO_REACT_TO",
"participant": ""
}
POST /chat/archive
Archives or unarchives a specific chat.
Request Example:
{
"jid": "5491155554444@s.whatsapp.net",
"archive": true
}
POST /chat/presence
Informs the chat that you are composing (typing) or paused. state can be 'composing' or 'paused'.
Request Example:
{
"phone": "5491155554444",
"state": "composing"
}
POST /chat/markread
Force a receipt "mark as read" on an array of message IDs.
Request Example:
{
"Id": ["MESSAGE_ID_1","MESSAGE_ID_2"],
"ChatPhone": "5491155554444",
"SenderPhone": "5491155554444"
}
GET /chat/history
Returns the messages history for a specific chat.
Request Example (cURL):
curl -X GET -H 'Token: 1234ABCD' "http://localhost:8080/chat/history?chat_jid=5491155554444@s.whatsapp.net&limit=50"
User
Endpoints to get information about users and manage presence.
POST /user/check
Checks if phone numbers have WhatsApp.
Body Parameters:
| Parameter | Type | Description |
|---|---|---|
| Phone | Array[string] | List of phone numbers to check |
Request Example:
{
"Phone": ["5491155553934", "5491155553935"]
}
Response:
{
"code": 200,
"data": {
"Users": [
{
"IsInWhatsapp": true,
"JID": "5491155553934@s.whatsapp.net",
"Query": "5491155553934",
"VerifiedName": "Company Name"
},
{
"IsInWhatsapp": false,
"JID": "5491155553935@s.whatsapp.net",
"Query": "5491155553935",
"VerifiedName": ""
}
]
},
"success": true
}
POST /user/devices
Returns list of devices for the given users.
Body Parameters:
| Parameter | Type | Description |
|---|---|---|
| phones | Array[string] | List of phone numbers |
Response:
{ "code": 200, "data": { "5491155553934@s.whatsapp.net": { "devices": [] } }, "success": true }
Group
Endpoints to manage groups and their properties.
GET /group/list
Lists all groups to which the account is linked.
Response:
{
"code": 200,
"data": {
"Groups": [
{
"AnnounceVersionID": "1650572126123738",
"DisappearingTimer": 0,
"GroupCreated": "2022-04-21T17:15:26-03:00",
"IsAnnounce": false,
"IsEphemeral": false,
"IsLocked": false,
"JID": "120362023605733675@g.us",
"Name": "Super Group",
"NameSetAt": "2022-04-21T17:15:26-03:00",
"NameSetBy": "5491155554444@s.whatsapp.net",
"OwnerJID": "5491155554444@s.whatsapp.net",
"ParticipantVersionID": "1650234126145738",
"Participants": [
{
"IsAdmin": true,
"IsSuperAdmin": true,
"JID": "5491155554444@s.whatsapp.net"
},
{
"IsAdmin": false,
"IsSuperAdmin": false,
"JID": "5491155553333@s.whatsapp.net"
}
],
"Topic": "",
"TopicID": "",
"TopicSetAt": "0001-01-01T00:00:00Z",
"TopicSetBy": ""
}
]
},
"success": true
}
POST /group/description
Updates the description of the group.
POST /group/requests
Returns list of participants requesting to join the group.
POST /group/requests/update
Approves or rejects a participant's request to join.
POST /group/link
Links a group to a community.
POST /group/subgroups
Get subgroups of a community.
Privacy
Endpoints to manage privacy settings and blocklist.
GET /privacy/settings
Gets current privacy settings (Last Seen, Profile Photo, Status, Read Receipts, etc).
POST /privacy/settings
Updates a specific privacy setting.
GET /blocklist
Gets the list of blocked users.
POST /blocklist/update
Blocks or unblocks a user.
Admin
Administrative endpoints to manage users and instances.
GET /admin/users
Lists all users registered in the system.
Headers:
| Header | Value | Description |
|---|---|---|
| Authorization | string | Administrative token for authentication |
Response:
{
"code": 200,
"data": [
{
"id": 1,
"name": "John",
"token": "1234ABCD",
"webhook": "https://example.com/webhook",
"jid": "5491155553934@s.whatsapp.net",
"qrcode": "",
"connected": true,
"expiration": 0,
"events": "Message,ReadReceipt"
}
],
"success": true
}
S3 Storage
Configure S3-compatible storage to store WhatsApp media files. Supports AWS S3, MinIO, DigitalOcean Spaces and other compatible providers.
GET /s3/config
Gets the current S3 configuration.
Response:
{
"code": 200,
"data": {
"endpoint": "https://s3.amazonaws.com",
"bucket": "meu-bucket",
"region": "us-east-1",
"path_prefix": "uploads/whatsapp/",
"force_path_style": false
},
"success": true
}
PUT /s3/config
Configures S3 storage for this instance.
Body Parameters:
| Parameter | Type | Description |
|---|---|---|
| endpoint | string | S3 endpoint URL (default: https://s3.amazonaws.com) |
| access_key | string | S3 access key |
| secret_key | string | S3 secret key |
| bucket | string | S3 bucket name |
| region | string | S3 region (required for AWS S3) |
| path_prefix | string | Path prefix to organize files |
| force_path_style | boolean | Use forced path style (required for MinIO) |
Request Example:
{
"endpoint": "https://s3.amazonaws.com",
"access_key": "AKIAIOSFODNN7EXAMPLE",
"secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"bucket": "meu-bucket-whatsapp",
"region": "us-east-1",
"path_prefix": "uploads/",
"force_path_style": false
}
Response:
{
"code": 200,
"data": {
"message": "S3 configuration saved successfully"
},
"success": true
}
POST /s3/test
Tests the connection to S3 using the provided configuration.
Body Parameters:
Same parameters as PUT /s3/config endpoint
Response:
{
"code": 200,
"data": {
"message": "S3 connection test successful"
},
"success": true
}
- AWS S3: Use the default endpoint and specify the region
- MinIO: Use your custom endpoint (ex: http://localhost:9000) and enable force_path_style
- DigitalOcean Spaces: Use https://nyc3.digitaloceanspaces.com as endpoint
Proxy
Configure an HTTP/HTTPS or SOCKS5 proxy for WhatsApp connections. Useful for network restrictions or enhanced privacy.
GET /proxy/config
Gets the current proxy configuration.
Response:
{
"code": 200,
"data": {
"proxy_url": "socks5://proxy.example.com:1080",
"username": "user",
"bypass_list": ["localhost", "127.0.0.1", "*.local"]
},
"success": true
}
PUT /proxy/config
Configures the proxy for this instance.
Body Parameters:
| Parameter | Type | Description |
|---|---|---|
| proxy_url | string | Full proxy URL including protocol and port |
| username | string | Username for proxy authentication |
| password | string | Password for proxy authentication |
| bypass_list | Array[string] | List of domains/IPs that should bypass the proxy |
Request Example:
{
"proxy_url": "socks5://proxy.example.com:1080",
"username": "usuario",
"password": "senha123",
"bypass_list": ["localhost", "127.0.0.1", "*.local", "192.168.*"]
}
Response:
{
"code": 200,
"data": {
"message": "Proxy configuration saved successfully"
},
"success": true
}
POST /proxy/test
Tests the connection through the configured proxy.
Body Parameters:
Same parameters as PUT /proxy/config endpoint (except bypass_list)
Response:
{
"code": 200,
"data": {
"message": "Proxy connection test successful",
"response_time": "245ms"
},
"success": true
}
- HTTP/HTTPS:
http://proxy.example.com:8080 - SOCKS5:
socks5://proxy.example.com:1080 - With authentication:
socks5://user:pass@proxy.example.com:1080
Best Practices
To use the Miauzap API efficiently and avoid problems, consider these best practices:
Security
- Keep your authentication tokens secure and do not expose them publicly.
- Use HTTPS for all communications with the API and with your webhooks.
- Implement proper validation for received webhooks to avoid processing malicious data.
Usage Limits
- Avoid sending many messages in a short period to avoid blocks from WhatsApp.
- Implement retry mechanisms with exponential backoff to handle temporary failures.
- Monitor connection status regularly and reconnect when necessary.
Webhooks
- Make sure your webhook endpoint can process requests quickly (less than 5 seconds).
- Implement a queue to process events asynchronously if processing is time-consuming.
- Configure your server to handle traffic spikes, especially if you manage multiple numbers.
FAQ
/session/connect endpoint and scan the QR again. Miauzap does not
automatically
reconnect in case of forced logout.
To reduce the risk of being blocked:
- Do not send mass messages to people who don't know you
- Do not send the same message to many contacts in sequence
- Respect sending limits (approximately 50-100 messages per day for new numbers)
- Use a number that already has usage history on WhatsApp
- Do not use the API to send spam or inappropriate content