Skip to main content
Node.js
import { PeriskopeApi } from '@periskope/periskope-client';

const client = new PeriskopeApi({
  authToken: 'YOUR_API_KEY',
  phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});

async function sendMessage() {
  const response = await client.message.send({
    chat_id: '919537851844',
    message: 'Hi from Periskope'
  });

  console.log(response);
}

sendMessage();
{
"queue_id": "ba3273cb-12be-48d4-90e0-0cbc0b427ef1",
"queue_position": 0,
"unique_id": "3EB05FC204C28E456D8596",
"hint": "You can track message status using the fetch jobs api - /queue/jobs?queue_id=ba3273cb-12be-48d4-90e0-0cbc0b427ef1"
}

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Headers

x-phone
string

Please provide the number of the phone you want to call with this API in the header. The number must be in country code + number format without any characters or spaces, e.g. 919876543210; Alternatively, provide the phone_id (phone-xxxxxxxxxxxx) in the header

Example:

"{{orgPhone}}"

Body

application/json
chat_id
string
required
  • For groups, enter the chat_id of the group. This will be a string that ends with @g.us
  • For 1-1 chats, enter the country_code + number of the recipient e.g. 919537851844@c.us (The @c.us is optional)
Example:

"919537851844@c.us"

message
string

The text body or caption. You can use basic markdown formatting supported by WhatsApp e.g. * for bold, and _ for italic, etc.

media
object

Media object containing file information and content

Note: You must specify either filedata or url

poll
object
  • pollName - The question or title of the poll
    • pollOptions - Raw bytes of the file, represented in base64
    • options - Additional options to be sent with the poll
      • allowMultipleAnswers - Boolean. When set to true, respondents can select multiple options
      • pollId - Optional unique identifier of the poll. Useful when sending it across multiple chats
reply_to
string

To reply to a message, add the message_id in this field

options
object
  • hide_url_preview - Set it to true to disable automatic link previews in the messages containing URLs

Response

200 - application/json

Text Message / Media Message / Reply Message / Poll Message

The response object confirms that your message request has been accepted and added to the processing queue for asynchronous delivery.

What you receive:

  • queue_id — A unique identifier for your enqueued message task. Save this value to track your message's progress, correlate it with webhook events, or reference it in support requests.
  • queue_position — Your message's position in the processing queue at the moment it was enqueued. This is zero-based (0 = first in queue, 1 = second, etc.). Note that this position reflects the queue state at enqueue time and may change as other messages are processed.
  • unique_id — A provisional identifier (when available) that helps correlate the queued request with downstream message objects or WhatsApp provider references.
  • hint — A helper message that tells you the next recommended step, such as which queue endpoint to call for status updates.

Understanding the queue system:

  • Messages are NOT sent immediately upon receiving this response. Instead, they are queued and processed asynchronously in the background.
  • Processing typically begins within seconds, but actual timing depends on:
    • Current queue depth and system throughput
    • Message type and size (text messages are faster than media)
    • Media file size and processing requirements
    • Rate limits applied to your phone number or organization
    • WhatsApp provider connectivity and response times
  • The system automatically retries failed messages for transient errors (network issues, temporary provider unavailability, etc.). Messages will be retried up to 3 times with exponential backoff delays between attempts. After 3 failed attempts, the message will be marked as failed and no further retries will occur.

How the queue_id maps to your message:

  • When you receive the queue_id, your message is in a "queued" state
  • Once processing begins, the queue_id becomes associated with a provisional sent_message_id in the message object
  • After successful delivery to WhatsApp, the queue_id maps to the final provider message ID
  • You can use the queue_id to track the message through its entire lifecycle: queued → processing → sent → delivered → read (or failed)

Tracking your message status: You have two primary methods to monitor your message:

  1. Fetch Queue Jobs API — Use the Fetch Queue Jobs API (/queue/jobs?queue_id=<queue_id>) to check your message's current state. The API returns job information including the status field, which can be one of:

    • waiting — Waiting to be processed
    • active — Currently being processed/sent to WhatsApp
    • completed — Successfully sent to WhatsApp servers
    • failed — Delivery failed after all retry attempts (check error details for reason)

    Note: The job status reflects the queue processing state. For delivery and read status, use webhooks or check the message's ack field via the message API.

  2. Webhook notifications — If you have webhooks configured, you'll automatically receive real-time events as your message progresses:

    • message.sent — Fired when the message is successfully sent to WhatsApp
    • message.delivered — Fired when the message is delivered to the recipient
    • message.read — Fired when the message is read (requires read receipts to be enabled)
    • message.failed — Fired if the message fails to send or deliver after all retry attempts
    • Each webhook event includes the queue_id so you can correlate it with your original request

Error handling and retries:

  • If a message fails due to transient errors (network issues, temporary provider unavailability, timeouts), the system will automatically retry the message
  • Messages are retried up to 3 times with exponential backoff delays (the delay increases with each retry attempt)
  • Permanent failures (invalid chat_id, blocked numbers, etc.) will not be retried
  • After 3 failed retry attempts, the message status will be set to failed and you'll receive a message.failed webhook event if configured

Best practices:

  • Always save the queue_id immediately after receiving the response
  • Don't poll the queue status too frequently (recommended: every 1-2 seconds for active monitoring, or use webhooks for real-time updates)
  • Implement proper error handling for failed messages
  • Use webhooks when possible for more efficient, event-driven tracking
  • Monitor your message status and handle failed messages appropriately in your application

Related documentation: