WHATSAPP FOR DEVELOPERS

WhatsApp API 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

Getting started

Authentication

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.

Which number is used?

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.

Integration header

Every request sends Integration: <add-on>, the plan add-on to check (default custom; e.g. zapier, hubspot, n8n).

Rate limits

Send routes: 60 requests/min. All other routes: 120 requests/min. Every response carries an X-Request-Id header; quote it when contacting support.

Responses and errors

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

Endpoints

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.

Connection

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." }
}

Messages

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 } }
}

Presence & Status

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
  } }
}

Chats

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 } }
}

Contacts & Profile

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 } }
}

Groups

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

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 } }
}

Start building on WhatsApp

Connect a number, create a token and send your first message in minutes. 7-day free trial.