WHATSAPP FOR DEVELOPERS
Send messages, manage chats, groups, profile and privacy for your connected WhatsApp number with one REST API. One base URL, one bearer token, JSON in and out.
Base URL: https://app.assistro.co/api/v1/whatsapp
Send Authorization: Bearer <token> on every request. Any Assistro token works on the same routes: a pat_ personal access token, an Assistro JWT or a Passport (OAuth) token.
The number never goes in the URL. A Passport token uses its own connection; an Assistro or pat_ token uses the connection it was issued for, otherwise your selected connection.
Every request sends Integration: <add-on>, the plan add-on to check (default custom; e.g. zapier, hubspot, n8n).
Send routes: 60 requests/min. All other routes: 120 requests/min. Every response carries an X-Request-Id header; quote it when contacting support.
Success: {"success": true, "status": 1, "data": …}. For message, chat, group and profile routes the result is at data.data. Errors: {"success": false, "status": 0, "message", "reason"}.
401 missing or invalid token
402 expired_plan, unknown_integration: no active plan for the Integration
403 connection_not_allowed: token issued for another number
404 connection_not_found: number is not on this account
422 connection_inactive: number switched off in Assistro
429 daily_limit_exceeded, monthly_limit_exceeded or throttled
400/404 client_rejected: WhatsApp refused it; message says why, data.code gives the code (VALIDATION, WA_404…)
502 client_error / client_unavailable: e.g. number not connected
API REFERENCE
All paths are relative to https://app.assistro.co/api/v1/whatsapp. Send Authorization: Bearer <token> and Integration: custom on every request. Click any endpoint to see its request body and an example response.
Link a number and check that it is online.
GET
/qr
QR code (or 8-digit pairing code) to link the number.
Details ▾
Query parameters (optional)
pair_with_code=1 // pairing code instead of QR
whatsapp_number=919876543210 // first connection only
Header (optional)
x-wa-version: 2.3000.1023223821
200 Response
{
"success": true, "status": 1,
"data": {
"qr": "data:image/png;base64,iVBORw0KG…",
"statusCode": 1
}
}
GET
/connection
Is the number connected right now?
Details ▾
Request
No body.
A disconnected number returns 404 with
reason: client_rejected and data.isConnected: 0.
200 Response
{
"success": true, "status": 1,
"data": { "isConnected": 1, "statusCode": 1 }
}
GET
/connection/test
Is the session fully ready after a scan or restart?
Details ▾
Request
No body. Poll every few seconds after
scanning the QR until isConnected is 1.
200 Response
{
"success": true, "status": 1,
"data": { "isConnected": 1, "statusCode": 1 }
}
POST
/disconnect
Log the number out. A new scan is needed afterwards.
Details ▾
Request
No body.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "message": "Client disconnected." }
}
Send any message type and act on messages you sent. Send routes: 60 requests/min.
POST
/messages/text
Text message, with optional mentions and quoted reply.
Details ▾
Request body
{
"to": "919876543210",
"text": "Hi! Your order #1042 has shipped 🚚",
"mentions": ["919876543210"], // optional
"quoted": { // optional, reply to a message
"key": { "id": "3EB0C4F1A2B3C4D5E6F7", "fromMe": false },
"text": "Where is my order?"
}
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"key": {
"remoteJid": "[email protected]",
"fromMe": true,
"id": "3EB0C4F1A2B3C4D5E6F7"
},
"messageTimestamp": 1761800000
} }
}
POST
/messages/media
Image, video, audio, document, sticker or GIF.
Details ▾
Request body
{
"to": "919876543210",
"kind": "image", // image | video | audio | document | sticker | gif
"media": {
"url": "https://example.com/product.jpg",
"mime_type": "image/jpeg",
"file_name": "product.jpg"
},
"caption": "Here is the product", // optional
"ptt": false, // audio as voice note
"viewOnce": false
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"key": {
"remoteJid": "[email protected]",
"fromMe": true,
"id": "3EB0C4F1A2B3C4D5E6F7"
},
"messageTimestamp": 1761800000
} }
}
POST
/messages/location
Map pin with optional name and address.
Details ▾
Request body
{
"to": "919876543210",
"latitude": 23.0225,
"longitude": 72.5714,
"name": "Assistro Office", // optional
"address": "Ahmedabad, Gujarat, India" // optional
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"key": { "remoteJid": "[email protected]",
"fromMe": true, "id": "3EB0C4F1A2B3C4D5E6F7" },
"messageTimestamp": 1761800000
} }
}
POST
/messages/contact
Share one or more contact cards.
Details ▾
Request body
{
"to": "919876543210",
"contacts": [
{
"fullName": "Assistro Support",
"phone": "919812345678",
"org": "Assistro" // optional
}
]
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"key": { "remoteJid": "[email protected]",
"fromMe": true, "id": "3EB0C4F1A2B3C4D5E6F7" },
"messageTimestamp": 1761800000
} }
}
POST
/messages/poll
Poll with options and how many each person can pick.
Details ▾
Request body
{
"to": "919876543210",
"name": "Which delivery slot suits you?",
"options": ["Morning (9–12)", "Afternoon (12–4)", "Evening (4–8)"],
"selectableCount": 1
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"key": { "remoteJid": "[email protected]",
"fromMe": true, "id": "3EB0C4F1A2B3C4D5E6F7" },
"messageTimestamp": 1761800000
} }
}
POST
/messages/forward
Forward a received message to a chat or group.
Details ▾
Request body
{
"to": "[email protected]",
"message": { // full message as received
"key": {
"remoteJid": "[email protected]",
"id": "3EB0XXXXXXXXXXXX",
"fromMe": false
},
"message": { "conversation": "My order has not arrived yet" }
}
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"key": { "remoteJid": "[email protected]",
"fromMe": true, "id": "3EB0C4F1A2B3C4D5E6F7" },
"messageTimestamp": 1761800000
} }
}
POST
/messages/reaction
React with an emoji. An empty emoji removes it.
Details ▾
Request body
{
"to": "919876543210",
"emoji": "👍", // "" removes your reaction
"key": { "id": "3EB0C4F1A2B3C4D5E6F7", "fromMe": true }
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"key": { "remoteJid": "[email protected]",
"fromMe": true, "id": "3EB0C4F1A2B3C4D5E6F7" },
"messageTimestamp": 1761800000
} }
}
POST
/messages/pin
Pin or unpin a message for 24 h, 7 d or 30 d.
Details ▾
Request body
{
"to": "919876543210",
"key": { "id": "3EB0C4F1A2B3C4D5E6F7", "fromMe": true },
"pin": true,
"durationSeconds": 86400 // 86400 | 604800 | 2592000
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"key": { "remoteJid": "[email protected]",
"fromMe": true, "id": "3EB0C4F1A2B3C4D5E6F7" },
"messageTimestamp": 1761800000
} }
}
POST
/messages/edit
Edit a message you sent (within ~15 minutes).
Details ▾
Request body
{
"to": "919876543210",
"key": { "id": "3EB0C4F1A2B3C4D5E6F7", "fromMe": true },
"text": "Your order #1042 arrives tomorrow 🚚"
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"key": { "remoteJid": "[email protected]",
"fromMe": true, "id": "3EB0C4F1A2B3C4D5E6F7" },
"messageTimestamp": 1761800000
} }
}
POST
/messages/delete
Delete a message you sent, for everyone.
Details ▾
Request body
{
"to": "919876543210",
"key": { "id": "3EB0C4F1A2B3C4D5E6F7", "fromMe": true }
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"key": { "remoteJid": "[email protected]",
"fromMe": true, "id": "3EB0C4F1A2B3C4D5E6F7" },
"messageTimestamp": 1761800000
} }
}
POST
/messages/star
Star or unstar a message.
Details ▾
Request body
{
"to": "919876543210",
"key": { "id": "3EB0C4F1A2B3C4D5E6F7", "fromMe": true },
"star": true
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
POST
/messages/download
Download received media as base64.
Details ▾
Request body
{
"message": { // full message as received
"key": {
"remoteJid": "[email protected]",
"id": "3EB0XXXXXXXXXXXX", "fromMe": false
},
"message": { "imageMessage": {
"url": "https://mmg.whatsapp.net/v/t62…",
"mimetype": "image/jpeg",
"mediaKey": "…", "fileEncSha256": "…"
} }
}
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"mimetype": "image/jpeg",
"fileName": null,
"base64": "/9j/4AAQSkZJRgABAQAAAQ…"
} }
}
POST
/messages/read
Mark received messages as read (blue ticks).
Details ▾
Request body
{
"keys": [
{
"remoteJid": "[email protected]",
"id": "3EB0XXXXXXXXXXXX",
"fromMe": false
}
]
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
Typing indicators, online state and Status posts.
POST
/presence
Show typing, recording, online or paused.
Details ▾
Request body
{
"state": "composing", // available | unavailable | composing | recording | paused
"to": "919876543210" // optional; omit for global state
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
POST
/presence/subscribe
Start tracking a contact's online state.
Details ▾
Request body
{
"jid": "[email protected]"
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
GET
/presence/{jid}
Last known presence of a subscribed contact.
Details ▾
Request
No body. Call POST /presence/subscribe first;
presence is null until the contact comes online.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"jid": "[email protected]",
"presence": {
"lastKnownPresence": "available",
"lastSeen": null
}
} }
}
POST
/status
Post a text or media WhatsApp Status.
Details ▾
Request body
{
"statusJidList": ["[email protected]"], // who can see it
"content": {
"text": "Diwali sale — 20% off this week!",
"backgroundColor": "#25D366",
"font": 1
}
}
// media status: "content": { "kind": "image",
// "media": { "url", "mime_type", "file_name" }, "caption" }
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"key": { "remoteJid": "status@broadcast",
"fromMe": true, "id": "3EB0C4F1A2B3C4D5E6F7" },
"messageTimestamp": 1761800000
} }
}
Manage conversations on this number. {jid} is e.g. [email protected].
POST
/chats/{jid}/mute
Mute a chat for a period, or unmute it.
Details ▾
Request body
{
"muteSeconds": 28800 // 8 h; null unmutes
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
POST
/chats/{jid}/read
Mark the whole chat read or unread.
Details ▾
Request body
{
"read": true, // false = unread
"lastMessage": { // the chat's latest message
"key": { "id": "3EB0C4F1A2B3C4D5E6F7", "fromMe": true },
"timestamp": 1761800000
}
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
POST
/chats/{jid}/delete
Delete the chat for you only.
Details ▾
Request body
{
"lastMessage": {
"key": { "id": "3EB0C4F1A2B3C4D5E6F7", "fromMe": true },
"timestamp": 1761800000
}
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
POST
/chats/{jid}/delete-message
Delete one message for you only.
Details ▾
Request body
{
"key": { "id": "3EB0C4F1A2B3C4D5E6F7", "fromMe": true },
"timestamp": 1761800000,
"deleteMedia": false // also delete the downloaded file
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
POST
/chats/{jid}/disappearing
Turn disappearing messages on or off.
Details ▾
Request body
{
"seconds": 604800 // 0 off | 86400 | 604800 | 7776000
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
Look up contacts and manage this number's own profile.
GET
/contacts/{jid}/picture
Contact's profile photo URL.
Details ▾
Query parameters
type=image // image (full size) | preview (thumbnail)
The URL expires; fetch it again rather than storing it.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"url": "https://pps.whatsapp.net/v/t61.24694-24/…_n.jpg"
} }
}
GET
/contacts/{jid}/status
Contact's About text.
Details ▾
Request
No body.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": [
{
"id": "[email protected]",
"status": { "status": "Available",
"setAt": "2026-06-30T06:38:20.000Z" }
}
] }
}
GET
/contacts/{jid}/business
Business profile: category, address, website, hours.
Details ▾
Request
No body. Empty for personal (non-business) accounts.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"wid": "[email protected]",
"category": "Information Technology Company",
"address": "Ahmedabad, Gujarat, India",
"website": ["https://example.com"],
"email": "[email protected]",
"business_hours": { "timezone": "Asia/Kolkata", … }
} }
}
PUT
/profile/name
Set the display name customers see.
Details ▾
Request body
{
"name": "Assistro Support"
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
PUT
/profile/status
Set your About text, e.g. support hours.
Details ▾
Request body
{
"status": "Support: Mon–Sat, 9 AM – 7 PM IST"
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
PUT
/profile/picture
Set your profile picture from a URL.
Details ▾
Request body
{
"media": {
"url": "https://example.com/logo.jpg",
"mime_type": "image/jpeg",
"file_name": "logo.jpg"
}
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
DELETE
/profile/picture
Remove your profile picture.
Details ▾
Request
No body.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
Create groups, manage members and settings, handle invites. {groupId} is e.g. [email protected].
GET
/groups
List every group this number is in.
Details ▾
Request
No body.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": [
{
"id": "[email protected]",
"subject": "Assistro Support",
"size": 2,
"announce": false,
"participants": [
{ "phoneNumber": "[email protected]", "admin": "superadmin" },
{ "phoneNumber": "[email protected]", "admin": null }
]
}
] }
}
POST
/groups
Create a group with a subject and first members.
Details ▾
Request body
{
"subject": "Order #1042 — Support",
"participants": ["919876543210"]
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"id": "[email protected]",
"subject": "Order #1042 — Support",
"size": 2,
"creation": 1761800000,
"participants": [ … ]
} }
}
GET
/groups/{groupId}
One group's members, admins and settings.
Details ▾
Request
No body.
A group this number is not in returns
404 WA_404 item-not-found.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"id": "[email protected]",
"subject": "Assistro Support",
"desc": "Support group for Assistro customers",
"announce": false, "restrict": false,
"size": 2,
"participants": [ … ]
} }
}
POST
/groups/{groupId}/participants
Add, remove, promote or demote members.
Details ▾
Request body
{
"action": "add", // add | remove | promote | demote
"participants": ["919876543210"]
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": [
{ "status": "200", "jid": "[email protected]" }
] }
}
// per member: 200 done, 403 not allowed, 409 already in group
PUT
/groups/{groupId}/subject
Rename the group.
Details ▾
Request body
{
"subject": "Order #1042 — Resolved"
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
PUT
/groups/{groupId}/description
Set the group description.
Details ▾
Request body
{
"description": "Replies within 2 hours, Mon–Sat."
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
PUT
/groups/{groupId}/settings
Admins-only messages, or lock group info.
Details ▾
Request body
{
"setting": "announcement"
}
// announcement | not_announcement | locked | unlocked
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
PUT
/groups/{groupId}/ephemeral
Disappearing messages for the whole group.
Details ▾
Request body
{
"seconds": 604800 // 0 off | 86400 | 604800 | 7776000
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
PUT
/groups/{groupId}/add-mode
Who can add members: admins or everyone.
Details ▾
Request body
{
"mode": "admin_add" // admin_add | all_member_add
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
PUT
/groups/{groupId}/join-approval
Require admin approval to join via link.
Details ▾
Request body
{
"mode": "on" // on | off
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
PUT
/groups/{groupId}/picture
Set the group icon from a URL.
Details ▾
Request body
{
"media": {
"url": "https://example.com/group.jpg",
"mime_type": "image/jpeg",
"file_name": "group.jpg"
}
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
DELETE
/groups/{groupId}/picture
Remove the group icon.
Details ▾
Request
No body.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
POST
/groups/{groupId}/leave
Leave the group.
Details ▾
Request
No body.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
GET
/groups/{groupId}/invite-code
Invite link code (admins only).
Details ▾
Request
No body. Share the link as
https://chat.whatsapp.com/<code>
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": "AbCdEf123456GhIjKl" }
}
POST
/groups/{groupId}/invite-code/revoke
Revoke the invite link and get a new code.
Details ▾
Request
No body.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": "ZyXwVu987654TsRqPo" }
}
GET
/groups/invite/{code}
Preview a group from an invite code.
Details ▾
Request
No body. {code} is the part after chat.whatsapp.com/.
An invalid code returns 400 WA_400 bad-request.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"id": "[email protected]",
"subject": "Assistro Support",
"size": 2,
"creation": 1761800000
} }
}
POST
/groups/invite/{code}/join
Join a group from an invite code.
Details ▾
Request
No body.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": "[email protected]" }
}
GET
/groups/{groupId}/requests
People waiting for approval to join.
Details ▾
Request
No body.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": [
{
"jid": "[email protected]",
"request_method": "invite_link",
"request_time": "1761800000"
}
] }
}
POST
/groups/{groupId}/requests
Approve or reject join requests.
Details ▾
Request body
{
"action": "approve", // approve | reject
"participants": ["919876543210"]
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": [
{ "status": "200", "jid": "[email protected]" }
] }
}
Privacy settings and the blocklist.
GET
/privacy
Current privacy settings.
Details ▾
Request
No body.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": {
"last": "contacts", "online": "match_last_seen",
"profile": "all", "status": "contacts",
"readreceipts": "all", "groupadd": "contacts",
"calladd": "all", "messages": "all"
} }
}
PUT
/privacy/{setting}
Change one privacy setting.
Details ▾
Request body (PUT /privacy/groupsAdd)
{
"value": "contacts"
}
// {setting}: lastSeen | online | profilePicture | status
// | readReceipts | groupsAdd | defaultDisappearing
// value: all | contacts | contact_blacklist | none
// online: all | match_last_seen; readReceipts: all | none
// defaultDisappearing: 0 | 86400 | 604800 | 7776000
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
GET
/blocklist
Blocked numbers.
Details ▾
Request
No body.
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": [
"[email protected]"
] }
}
POST
/blocklist
Block or unblock a number.
Details ▾
Request body
{
"jid": "[email protected]",
"action": "block" // block | unblock
}
200 Response
{
"success": true, "status": 1,
"data": { "success": true, "data": { "success": true } }
}
Connect a number, create a token and send your first message in minutes. 7-day free trial.