Quick Start
Send your first WhatsApp message in 3 steps:
Create a session & scan the QR code
curl -X POST https://api.vespergateway.com/api/v1/sessions \
-H "x-api-key: vsp_your_key" \
-H "Content-Type: application/json" \
-d '{"name": "my-whatsapp"}'Get the QR code & scan it with your phone (WhatsApp > Settings > Linked Devices)
curl https://api.vespergateway.com/api/v1/sessions/SESSION_ID/qr \
-H "x-api-key: vsp_your_key"Send a message
curl -X POST https://api.vespergateway.com/api/v1/messages/send/text \
-H "x-api-key: vsp_your_key" \
-H "Content-Type: application/json" \
-d '{
"session": "SESSION_ID",
"to": "905551234567",
"text": "Hello from Vesper! 🚀"
}'Base URL: https://api.vespergateway.com/api/v1 — every endpoint is prefixed with /api/v1 and uses JSON for requests and responses.
Tools & resources
Authentication
Every API request requires an API key. Pass it in the x-api-key header:
curl -H "x-api-key: vsp_abc123def456" \
https://api.vespergateway.com/api/v1/sessionsx-api-keyheaderREQUIREDYour API key (starts with vsp_)API keys are generated in your app settings and shown only once — copy and store yours securely. You can revoke and regenerate keys at any time.
Sessions
A session is a WhatsApp connection linked to a phone number. Create one, scan the QR code, and it stays connected with automatic reconnect.
Endpoints
/sessionsCreate a new WhatsApp session
/sessionsList all your sessions
/sessions/:idGet session details (status, phone, name)
/sessions/:id/qrGet the QR code as a base64 image for pairing
/sessions/:id/statusCheck connection status (connected / connecting / disconnected)
/sessions/:id/restartRestart the session (re-connect WhatsApp)
/sessions/:idPermanently delete the session and all its data
Create a session
curl -X POST https://api.vespergateway.com/api/v1/sessions \
-H "x-api-key: vsp_your_key" \
-H "Content-Type: application/json" \
-d '{"name": "store-whatsapp"}'Request body:
namestringREQUIREDUnique session name (1-64 characters)Session lifecycle
Poll GET /sessions/:id/qr every 3-5 seconds. When the status becomes connected, the QR was scanned successfully. Sessions auto-reconnect if the connection drops.
Messages
Send text, images, videos, documents, audio, and location messages. All send endpoints follow the same pattern.
Send endpoints
/messages/send/textSend a text message
/messages/send/imageSend an image (URL or base64)
/messages/send/videoSend a video (URL)
/messages/send/documentSend a file (PDF, DOCX, etc.)
/messages/send/audioSend audio or a voice note
/messages/send/locationSend a location pin
History endpoints
/messages/:sessionIdGet message history (paginated, optional ?jid= filter)
/messages/:sessionId/:msgIdGet a single message by ID
/messages/:sessionId/:msgIdDelete a message from the database
Send a text message
curl -X POST https://api.vespergateway.com/api/v1/messages/send/text \
-H "x-api-key: vsp_your_key" \
-H "Content-Type: application/json" \
-d '{
"session": "SESSION_ID",
"to": "905551234567",
"text": "Hello from Vesper! 🚀"
}'sessionstringREQUIREDSession IDtostringREQUIREDRecipient phone (international format, no + or spaces)textstringREQUIREDMessage text (supports emojis)Send an image
curl -X POST https://api.vespergateway.com/api/v1/messages/send/image \
-H "x-api-key: vsp_your_key" \
-H "Content-Type: application/json" \
-d '{
"session": "SESSION_ID",
"to": "905551234567",
"url": "https://example.com/photo.jpg",
"caption": "Check this out!"
}'urlstringREQUIREDPublic image URL (JPEG, PNG, WebP)captionstringOptional caption textSend a document
curl -X POST https://api.vespergateway.com/api/v1/messages/send/document \
-H "x-api-key: vsp_your_key" \
-H "Content-Type: application/json" \
-d '{
"session": "SESSION_ID",
"to": "905551234567",
"url": "https://example.com/report.pdf",
"filename": "Q1-Report.pdf"
}'urlstringREQUIREDPublic file URLfilenamestringREQUIREDDisplay filename (e.g. report.pdf)captionstringOptional caption textSend a location
curl -X POST https://api.vespergateway.com/api/v1/messages/send/location \
-H "x-api-key: vsp_your_key" \
-H "Content-Type: application/json" \
-d '{
"session": "SESSION_ID",
"to": "905551234567",
"latitude": 41.0082,
"longitude": 28.9784,
"name": "Istanbul"
}'Message response
{
"success": true,
"data": {
"key": { "remoteJid": "905551234567@s.whatsapp.net", "fromMe": true, "id": "3EB0A8C2F5B7..." },
"status": "PENDING"
}
}Phone format: international format without + or spaces. Examples: 905551234567 (Turkey), 491621234567 (Germany), 447911123456 (UK).
Message status tracking
Status updates are tracked automatically. Subscribe to the message.sent, message.delivered, and message.read webhook events to follow each message.
Webhooks
Webhooks notify your server in real time when events happen — messages received, delivered, read, sessions connecting or disconnecting, and more. Register a URL, pick the events you want, and Vesper sends a POST request to it.
Management endpoints
/webhooksCreate a new webhook
/webhooksList all webhooks
/webhooks/:idGet webhook details
/webhooks/:idUpdate webhook URL, events, or secret
/webhooks/:idDelete a webhook
/webhooks/:id/testSend a test payload to verify your endpoint
/webhooks/:id/logsView recent delivery logs (success / fail)
Create a webhook
curl -X POST https://api.vespergateway.com/api/v1/webhooks \
-H "x-api-key: vsp_your_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/vesper/webhook",
"events": ["message.received", "message.delivered", "message.read"],
"secret": "your_webhook_secret_min16chars"
}'urlstringREQUIREDYour HTTPS endpoint that will receive POST requestseventsstring[]REQUIREDEvents to subscribe to. Use ["*"] for all eventssecretstringMin 16 characters. Used to sign payloads with HMAC-SHA256Payload format
Every webhook delivery is a POST request with this structure:
{
"event": "message.received",
"timestamp": "2026-06-24T10:30:00.000Z",
"session": "YoNofiM9vtHy",
"data": {
"id": "3EB0A8C2F5B7E6A1",
"from": "905551234567@s.whatsapp.net",
"type": "text",
"content": { "text": "Hey, is my order ready?" },
"pushName": "Ahmet"
}
}Headers sent with each delivery
Content-Typeheaderapplication/jsonUser-AgentheaderVesper-Webhook/1.0X-Vesper-Eventheadermessage.receivedX-Vesper-DeliveryheadernanoidX-Vesper-Signatureheadersha256=…Verify the signature
const crypto = require("crypto");
function verify(rawBody, signature, secret) {
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return signature === expected;
}Important: respond with a 2xx status within 10 seconds or the delivery will be retried. Failed deliveries retry up to 5 times with exponential backoff (1s, 2s, 4s, 8s, 16s).
Webhook Events
Detailed payload examples for each event type, so you know exactly what your server will receive.
message.receivedA new message was received from someone{
"event": "message.received",
"timestamp": "2026-06-24T10:30:00.000Z",
"session": "YoNofiM9vtHy",
"data": {
"id": "3EB0A8C2F5B7E6A1",
"from": "905551234567@s.whatsapp.net",
"type": "text",
"timestamp": 1750761000,
"content": { "text": "Hey, is my order ready?", "caption": "", "mimetype": "", "filename": "", "base64": "" },
"pushName": "Ahmet"
}
}type can be text, image, video, audio, document, location, sticker, contact, or reaction. For media messages, base64 contains the file data and mimetype tells you the format.
message.from_phoneYou sent a message from your phone (not via the API){
"event": "message.from_phone",
"timestamp": "2026-06-24T10:31:00.000Z",
"session": "YoNofiM9vtHy",
"data": {
"id": "3EB0B9D3E6C8F7B2",
"to": "905551234567@s.whatsapp.net",
"type": "text",
"content": { "text": "Yes, it will be ready in 10 minutes!" },
"pushName": "My Business"
}
}Use this event to sync messages sent from your phone into your CRM, helpdesk, or any external system. The message is also stored in Vesper's database.
message.sentmessage.deliveredmessage.readTrack your message's journey — the same payload structure is used for all three events:
{
"event": "message.delivered",
"timestamp": "2026-06-24T10:30:05.000Z",
"session": "YoNofiM9vtHy",
"data": { "id": "3EB0A8C2F5B7E6A1", "session": "YoNofiM9vtHy", "remoteJid": "905551234567@s.whatsapp.net" }
}message.updatedA message was edited{
"event": "message.updated",
"timestamp": "2026-06-24T10:35:00.000Z",
"session": "YoNofiM9vtHy",
"data": { "id": "3EB0A8C2F5B7E6A1", "remoteJid": "905551234567@s.whatsapp.net", "message": { "conversation": "Edited message text" } }
}session.connectedsession.disconnected// session.connected
{
"event": "session.connected",
"session": "YoNofiM9vtHy",
"data": { "session": "YoNofiM9vtHy", "phone": "905559876543", "pushName": "My Business" }
}
// session.disconnected
{
"event": "session.disconnected",
"session": "YoNofiM9vtHy",
"data": { "session": "YoNofiM9vtHy", "reason": "connection_lost" }
}reason can be connection_lost (temporary, auto-reconnects) or logged_out (the user unlinked the device — the session needs re-pairing).
All available events
message.receivedNew incoming messagemessage.from_phoneMessage sent from your phonemessage.sentMessage reached WhatsApp serversmessage.deliveredMessage delivered to recipientmessage.readRecipient read the messagemessage.updatedMessage was editedsession.connectedWhatsApp session connectedsession.disconnectedSession disconnectedsession.qrNew QR code generated for pairinggroup.joinParticipant added to groupgroup.leaveParticipant removed from groupgroup.updateGroup settings changedGroups
Create and manage WhatsApp groups programmatically.
/groups/:sessionIdList all groups for a session
/groups/createCreate a new group
/groups/:groupIdUpdate group subject or description
/groups/:groupId/participants/addAdd participants to a group
/groups/:groupId/participants/removeRemove participants from a group
Broadcast
Send bulk messages to recipient lists. Messages are queued and sent with smart delays to help avoid bans.
/broadcast/listsCreate a recipient list
/broadcast/listsGet all recipient lists
/broadcast/campaignsCreate and send a broadcast campaign
/broadcast/campaignsList all campaigns
/broadcast/campaigns/:idGet campaign details and delivery status
/broadcast/campaigns/:id/cancelCancel an in-progress broadcast
Broadcast messages support personalization with name and surname placeholders in your text. Plan limits apply: Starter 100/mo, Pro 1,000/mo, Enterprise 5,000/mo.
Chatbot
Build automated conversation flows that respond to incoming WhatsApp messages. Create flows with steps (send text, buttons, conditions, webhooks), assign them to a session, and publish.
Flow lifecycle
A flow needs an assigned WhatsApp session and at least one step before it can be published. Each session can have only one active published flow at a time.
Flow endpoints
/chatbot/flows?appId=List all chatbot flows for an app
/chatbot/flowsCreate a new flow
/chatbot/flows/:flowIdGet flow details with steps
/chatbot/flows/:flowIdUpdate a flow (name, trigger, session, enabled)
/chatbot/flows/:flowIdDelete a flow (cascades steps & sessions)
/chatbot/flows/:flowId/publishPublish a draft flow
/chatbot/flows/:flowId/unpublishUnpublish back to draft
/chatbot/flows/:flowId/duplicateDuplicate a flow with all its steps
Step endpoints
/chatbot/flows/:flowId/stepsAdd a step to a flow
/chatbot/flows/:flowId/steps/:stepIdUpdate a step
/chatbot/flows/:flowId/steps/:stepIdDelete a step
/chatbot/flows/:flowId/steps/batchBatch update positions & connections
Test & statistics
/chatbot/flows/:flowId/simulateSimulate flow execution with test messages
/chatbot/flows/:flowId/sessionsGet flow conversation history
/chatbot/stats?appId=Get chatbot statistics for an app
Create a flow
curl -X POST https://api.vespergateway.com/api/v1/chatbot/flows \
-H "x-api-key: vsp_your_key" \
-H "Content-Type: application/json" \
-d '{
"appId": "APP_ID",
"name": "Welcome Bot",
"triggerType": "keyword",
"triggerValue": { "keywords": ["hello", "hi", "merhaba"], "matchType": "contains" },
"sessionId": "SESSION_ID"
}'appIdstringREQUIREDApp IDnamestringREQUIREDFlow name (1-100 characters)triggerTypestringREQUIREDkeyword | first_contact | scheduletriggerValueobjectTrigger config (keywords, matchType, schedule times)sessionIdstringWhatsApp session ID (required to publish)Node types reference
| Type | Description | Config fields |
|---|---|---|
send_text | Send a text message | message |
send_image | Send an image | url, caption |
send_buttons | Send options (WhatsApp List) | message, buttons[{id, label}] |
wait_reply | Wait for a user reply | timeout, timeoutAction |
condition | Branch by condition | rules[{variable, operator, value}], logic |
delay | Wait N seconds | seconds |
webhook | Call an external API | url, method, headers, body |
set_variable | Assign a variable | name, source, value |
Use the simulate endpoint to test your flow without sending real WhatsApp messages. Variables such as last_reply and your custom variables are resolved during execution.
Errors & Rate Limits
Error format
{
"success": false,
"error": {
"code": "LIMIT_EXCEEDED",
"message": "Monthly message limit (5000) exceeded"
}
}Common error codes
401UnauthorizedMissing or invalid API key403ForbiddenPlan limit exceeded or feature not available404Not FoundSession or resource doesn't exist409ConflictResource already exists (duplicate session name)429Too Many RequestsRate limit exceeded (100 requests/minute)Plan limits
| Plan | Apps | Sessions | Messages/mo | Broadcast/mo |
|---|---|---|---|---|
| Starter €29 | 1 | 2 | 5,000 | 100 |
| Pro €69 | 3 | 10 | 25,000 | 1,000 |
| Enterprise €149 | 10 | 50 | 100,000 | 5,000 |
Check the X-RateLimit-Remaining and X-RateLimit-Reset response headers. When you hit a limit, back off and retry after the reset time.