WhatsApp Real-Time Message API - Webhook & Telegram avatar
WhatsApp Real-Time Message API - Webhook & Telegram

Pricing

$29.00/month + usage

Go to Apify Store
WhatsApp Real-Time Message API - Webhook & Telegram

WhatsApp Real-Time Message API - Webhook & Telegram

Real-time WhatsApp message receiver with instant webhook and Telegram forwarding. One-time QR authentication with persistent sessions. Download media (images, audio notes, videos, docs). Filter messages by chat type. Built-in REST API for monitoring and message retrieval.

Pricing

$29.00/month + usage

Rating

0.0

(0)

Developer

ClearPath

ClearPath

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

WhatsApp Real-Time Message API

Receive WhatsApp messages in real-time and forward them instantly to your webhook or Telegram. All messages are also stored in an Apify Dataset for later access.

Demo

Quick Start - QR Code Authentication

First time only - your session is saved automatically for future runs.

  1. Start the Actor (it runs in Standby mode automatically)
  2. Access the API at: https://clearpath--whatsapp-real-time-message-api.apify.actor
  3. Call /qr to get the QR code, or watch the logs
  4. Open WhatsApp on your phone > Settings > Linked Devices > Link a Device
  5. Scan the QR code
  6. Messages start flowing to your webhook/Telegram immediately

Your session persists in a Key-Value Store. Future runs reconnect automatically without QR scanning.

Pricing

$29/month - Unlimited messages, all features included.

  • 1-day free trial
  • Webhook forwarding with HMAC signing
  • Telegram integration
  • Media download (images, videos, documents, audio, stickers)
  • Message filtering and API endpoints
  • Session persistence across runs

You also pay standard Apify platform costs for compute and storage.

Actor Input Screenshot

WhatsApp Real-Time Message API

How It Works

The Actor runs continuously in Standby mode, capturing every WhatsApp message in real-time.

Your WhatsApp ──> Actor (always running) ──> Webhook / Telegram
└──> Apify Dataset (access via /messages)

All messages are automatically:

  1. Stored in Apify Dataset (access anytime via /messages endpoint)
  2. Pushed to your webhook and/or Telegram (if configured)

Keep It Running (Important!)

Apify pauses idle Actors after ~5 minutes of no HTTP requests. Messages are lost while paused.

To capture messages 24/7, ping /health every 4 minutes:

  • Use UptimeRobot (free), cron job, or any monitoring tool
  • Your WhatsApp session is saved - no QR rescan needed after restart
  • Actor wakes instantly when any endpoint is called

Session Persistence

Your WhatsApp session is automatically saved to a Key-Value Store, so you only need to scan the QR code once.

How it works:

  • On first run, scan the QR code to link your WhatsApp
  • Session credentials are stored in a named KV store (whatsapp-auth-realtime by default)
  • Subsequent runs automatically reconnect using the saved session
  • No QR code needed unless the session becomes invalid

When you need to re-scan:

  • You manually unlink the device from WhatsApp settings
  • The session expires (rare, typically months of inactivity)
  • You delete the auth KV store
  • You change the authStoreName input to a different value

Multiple WhatsApp accounts: Use different authStoreName values to maintain separate sessions:

{
"authStoreName": "whatsapp-auth-account-2"
}

Input Options

Notification Settings

FieldTypeDefaultDescription
enableWebhookbooleanfalseForward incoming messages to a webhook URL
webhookUrlstring-Your webhook endpoint (required if webhook enabled)
webhookSecretstring-Secret for HMAC-SHA256 signature verification
enableTelegrambooleanfalseForward messages to Telegram
telegramChatIdstring-Your Telegram chat/user ID (required if Telegram enabled)

Validation: On startup, the Actor verifies webhook connectivity (POST test) and Telegram access (bot token + chat reachability). Invalid or unreachable channels are disabled with a warning—the Actor continues running.

Message Filtering

FieldTypeDefaultDescription
chatFilterstringallFilter by chat type: all, groups, or private
includeStatusesbooleanfalseInclude WhatsApp Status (story) updates
includeFromMebooleantrueInclude messages you send from the linked device
downloadMediaarrayall typesMedia types to download: images, videos, documents, audio, stickers

Storage Settings

FieldTypeDefaultDescription
messageDatasetNamestringdefaultDataset name for storing messages
authStoreNamestringwhatsapp-auth-realtimeKV store name for session persistence

Input Examples

Webhook Integration

Forward all messages to your server with signature verification:

{
"enableWebhook": true,
"webhookUrl": "https://your-server.com/whatsapp-webhook",
"webhookSecret": "your-secret-key-here"
}

Telegram Notifications

Get messages delivered to your Telegram (requires TELEGRAM_BOT_TOKEN environment variable):

{
"enableTelegram": true,
"telegramChatId": "123456789"
}

Groups Only, Text Only

Monitor group chats without downloading media:

{
"enableWebhook": true,
"webhookUrl": "https://your-server.com/hook",
"chatFilter": "groups",
"downloadMedia": [],
"includeFromMe": false
}

Full Setup with Both Channels

{
"enableWebhook": true,
"webhookUrl": "https://your-server.com/whatsapp",
"webhookSecret": "hmac-secret",
"enableTelegram": true,
"telegramChatId": "123456789",
"chatFilter": "all",
"includeStatuses": false,
"downloadMedia": ["images", "documents"]
}

HTTP API Endpoints

Base URL: https://clearpath--whatsapp-real-time-message-api.apify.actor

Authentication: Pass your Apify API token as a query parameter: ?token=YOUR_API_TOKEN

The Actor exposes these endpoints while running in Standby mode:

GET /health

Returns connection status and metrics.

{
"status": "ok",
"uptimeSec": 3600,
"whatsapp": {
"connected": true,
"connectionState": "open",
"qrRequired": false
},
"metrics": {
"messagesReceived": 142,
"messagesStored": 140,
"messagesFiltered": 2,
"webhookSent": 135,
"webhookFailed": 5,
"telegramSent": 130,
"telegramFailed": 0
}
}

GET /qr

Get the QR code for WhatsApp linking (if not yet connected).

{
"status": "qr_available",
"qr": "2@ABC123...",
"generatedAt": "2024-12-04T10:30:00.000Z",
"ageSec": 15
}

If already connected:

{
"status": "connected",
"message": "Already connected to WhatsApp"
}

GET /messages

Fetch stored messages with pagination.

Query parameters:

  • limit (default: 100) - Number of messages to return
  • offset (default: 0) - Starting position
  • desc (default: false) - Set to true for newest messages first
{
"items": [...],
"total": 1042,
"offset": 0,
"limit": 100,
"desc": false
}

GET /status

Simple connection check.

{
"connected": true,
"connectionState": "open"
}

Webhook Payload Format

Each message is POSTed to your webhook with this structure:

Text Message

{
"event": "whatsapp_message",
"receivedAt": "2024-12-04T10:30:45.123Z",
"data": {
"messageId": "3EB0A1B2C3D4E5F6G7H8",
"from": "14155551234@s.whatsapp.net",
"fromMe": false,
"timestamp": "2024-12-04T10:30:45.000Z",
"messageType": "conversation",
"text": "Hey, are you free for lunch today?",
"chatId": "14155551234@s.whatsapp.net",
"chatType": "private",
"chatName": "Sarah Miller",
"fromName": "Sarah Miller"
}
}

Image Message

{
"event": "whatsapp_message",
"receivedAt": "2024-12-04T10:35:00.000Z",
"data": {
"messageId": "3EB0B2C3D4E5F6G7H8I9",
"from": "14155551234@s.whatsapp.net",
"fromMe": false,
"timestamp": "2024-12-04T10:35:00.000Z",
"messageType": "image",
"text": "Check out this view!",
"chatId": "14155551234@s.whatsapp.net",
"chatType": "private",
"chatName": "Sarah Miller",
"fromName": "Sarah Miller",
"media": {
"messageType": "image",
"mimetype": "image/jpeg",
"fileSize": 245678,
"width": 1920,
"height": 1080,
"caption": "Check out this view!",
"url": "https://api.apify.com/v2/key-value-stores/abc123/records/media-3EB0B2C3.jpg",
"downloadStatus": "downloaded"
}
}
}

Group Message

{
"event": "whatsapp_message",
"receivedAt": "2024-12-04T11:00:00.000Z",
"data": {
"messageId": "3EB0C3D4E5F6G7H8I9J0",
"from": "14155559876@s.whatsapp.net",
"fromMe": false,
"timestamp": "2024-12-04T11:00:00.000Z",
"messageType": "conversation",
"text": "Meeting moved to 3 PM",
"chatId": "120363000000000001@g.us",
"chatType": "group",
"chatName": "Weekend Tennis Group",
"fromName": "John Doe"
}
}

Location Message

{
"event": "whatsapp_message",
"data": {
"messageId": "3EB0D4E5F6G7H8I9J0K1",
"messageType": "location",
"chatId": "14155551234@s.whatsapp.net",
"chatType": "private",
"location": {
"latitude": 37.7749,
"longitude": -122.4194,
"name": "Ferry Building",
"address": "San Francisco, CA",
"isLive": false
}
}
}

Reaction

{
"event": "whatsapp_message",
"data": {
"messageId": "3EB0E5F6G7H8I9J0K1L2",
"messageType": "reaction",
"chatId": "14155551234@s.whatsapp.net",
"reaction": {
"text": "❤️",
"targetMessageId": "3EB0A1B2C3D4E5F6G7H8"
}
}
}

Webhook HMAC Verification

If you configure webhookSecret, each request includes an X-Signature header with an HMAC-SHA256 signature of the request body.

Node.js verification example:

const crypto = require('crypto');
function verifyWebhook(req, secret) {
const signature = req.headers['x-signature'];
const body = req.rawBody; // Raw JSON string, not parsed
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return signature === expectedSignature;
}
// Express middleware example
app.post('/whatsapp-webhook', express.raw({ type: 'application/json' }), (req, res) => {
if (!verifyWebhook(req, 'your-secret-key')) {
return res.status(401).json({ error: 'Invalid signature' });
}
const message = JSON.parse(req.body);
console.log('Received:', message.data.text);
res.sendStatus(200);
});

Telegram Integration

To receive messages on Telegram:

  1. Get your chat ID (message @userinfobot)
  2. Set enableTelegram: true and telegramChatId in your input

Important: Bot Permission Setup

Before notifications will work, you must message the bot first:

  1. Find the bot - Search for @whatsapp_realtime_api_bot on Telegram
  2. Send any message - Type /start or any text to initiate contact
  3. Done! - The bot can now send you notifications

Message format in Telegram:

📱 Private: Sarah Miller
👤 From: Sarah Miller
🕐 2024-12-04, 10:30 AM
Hey, are you free for lunch today?

For media messages, the Telegram bot sends the file directly with a caption containing the message details.

Message Output Format

Messages stored in the Dataset have this structure:

{
"id": "3EB0A1B2C3D4E5F6G7H8",
"from": "14155551234@s.whatsapp.net",
"fromMe": false,
"timestamp": "2024-12-04T10:30:45.000Z",
"messageType": "conversation",
"text": "Hello!",
"chatId": "14155551234@s.whatsapp.net",
"chatType": "private",
"chatName": "Sarah Miller",
"fromName": "Sarah Miller",
"quotedMessageId": null,
"media": null,
"location": null,
"contact": null,
"reaction": null,
"poll": null
}

Message Types

TypeDescription
conversationPlain text message
extendedTextText with link preview or quoted reply
imageImage message
videoVideo message
audioAudio/voice message
documentFile attachment
stickerSticker
locationStatic location
liveLocationLive location sharing
contactShared contact
contactsMultiple shared contacts
reactionEmoji reaction
pollPoll
pollUpdatePoll vote

Media Object

When media is downloaded, the media field contains:

{
"type": "image",
"mimetype": "image/jpeg",
"fileSize": 245678,
"width": 1920,
"height": 1080,
"seconds": null,
"caption": "Check this out!",
"fileName": null,
"url": "https://api.apify.com/v2/key-value-stores/xxx/records/media-abc123.jpg",
"downloadStatus": "downloaded",
"downloadedAt": "2024-12-04T10:30:50.000Z"
}

Download status values:

  • downloaded - Successfully downloaded and stored
  • failed - Download failed after retries
  • expired - Media no longer available on WhatsApp servers (common for older messages)

Chat ID Formats

  • Private chats: {phone}@s.whatsapp.net (e.g., 14155551234@s.whatsapp.net)
  • Group chats: {id}@g.us (e.g., 120363000000000001@g.us)
  • Status updates: status@broadcast

Data Privacy

All data is stored exclusively in your private Apify storage:

  • Messages: Stored in your private Dataset
  • Media: Stored in your private Key-Value Store
  • Session: Stored in a named KV store (whatsapp-auth-realtime)

The Actor developer has no access to your data. All storage is private to your Apify account.

Troubleshooting

QR code not appearing

  • Wait for the Actor to fully start (check /health endpoint)
  • Try the /qr endpoint directly to get the QR code data
  • Ensure no other device is already linked with the same session

Webhook not receiving messages

  • Verify your webhook URL is publicly accessible
  • Check the Actor logs for webhook errors
  • Confirm the webhook returns HTTP 200 within 10 seconds
  • Review /health metrics for webhookFailed count

"Already connected" but not receiving messages

  • The WhatsApp session may be stale. Delete the auth store and re-link
  • Check if messages are filtered by your chatFilter settings
  • Verify includeFromMe setting if testing with your own messages

Actor keeps stopping

  • Normal idle timeout behavior - see Keep It Running section
  • Set up UptimeRobot or cron to ping /health every 4 minutes

Media download failing

  • Media on WhatsApp servers expires after ~30 days
  • Large files may timeout - check downloadMedia settings
  • Verify you're downloading the correct media types

Session not reconnecting (unexpected QR code)

  • Check if the auth KV store exists (whatsapp-auth-realtime)
  • Verify you're using the same authStoreName as previous runs
  • The device may have been unlinked from WhatsApp settings on your phone

Support

Questions or issues? Contact: max@mapa.slmail.me