import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: '919876543210', // the phone to act with (x-phone)
});
async function main() {
const response = await client.messages.broadcastMessage({
chat_ids: [
'911111111111@c.us',
'120363000000000000@g.us',
],
});
console.log(response);
}
main();curl -X POST 'https://api.periskope.app/v1/message/broadcast' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'x-phone: 919876543210' \
-H 'Content-Type: application/json' \
-d '{
"chat_ids": [
"911111111111@c.us",
"120363000000000000@g.us"
]
}'{
"broadcast_id": "00000000-0000-0000-0000-000000000000",
"hint": "You can track broadcast status by making a POST request to /messages/queues with { \"broadcast_id\": \"00000000-0000-0000-0000-000000000000\" } as body"
}{
"code": "UNAUTHORIZED_ERROR",
"message": "Invalid bearer auth token",
"status": 401
}{
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"status": 422,
"fields": {
"body.chat_id": {
"message": "chat_id is required"
}
}
}{
"code": "RATE_LIMIT_ERROR",
"message": "You can only make 100 requests per second",
"status": 429
}{
"code": "UNKNOWN_ERROR",
"message": "Internal server error",
"status": 500
}Broadcast Message
Sends the same message (text, media or poll) to many chats — from chat_ids, or every chat carrying the given label. One credit per recipient; rejected up front when credits are insufficient.
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: '919876543210', // the phone to act with (x-phone)
});
async function main() {
const response = await client.messages.broadcastMessage({
chat_ids: [
'911111111111@c.us',
'120363000000000000@g.us',
],
});
console.log(response);
}
main();curl -X POST 'https://api.periskope.app/v1/message/broadcast' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'x-phone: 919876543210' \
-H 'Content-Type: application/json' \
-d '{
"chat_ids": [
"911111111111@c.us",
"120363000000000000@g.us"
]
}'{
"broadcast_id": "00000000-0000-0000-0000-000000000000",
"hint": "You can track broadcast status by making a POST request to /messages/queues with { \"broadcast_id\": \"00000000-0000-0000-0000-000000000000\" } as body"
}{
"code": "UNAUTHORIZED_ERROR",
"message": "Invalid bearer auth token",
"status": 401
}{
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"status": 422,
"fields": {
"body.chat_id": {
"message": "chat_id is required"
}
}
}{
"code": "RATE_LIMIT_ERROR",
"message": "You can only make 100 requests per second",
"status": 429
}{
"code": "UNKNOWN_ERROR",
"message": "Internal server error",
"status": 500
}Authorizations
Your Periskope API token, sent as Authorization: Bearer <token>. Generate one from the Periskope dashboard under Settings → API & Webhooks. API access requires an active Pro or Enterprise plan.
Headers
Optional. Scope results to a single phone: country code + number without symbols or spaces (e.g. 911111111111), or a phone_id (phone-xxxxxxxxxxxx). Omit to return data across all phones the API token can access.
"919876543210"
Body
Recipients of the broadcast, as an array of chat ids (or a single comma-separated string). For group chats, the chat_id ending with @g.us; for 1-1 chats, country code + number of the contact, optionally suffixed with @c.us (e.g. 911111111111 or 911111111111@c.us). Duplicates are removed. Either chat_ids or label is required.
[
"911111111111@c.us",
"120363000000000000@g.us"
]
Name of a chat label — when chat_ids is empty, the broadcast is sent to every chat carrying this label. Ignored when chat_ids is provided.
"newsletter"
The text body of the message, or the caption when media is provided. Supports the basic WhatsApp markdown formatting (bold, italic, strikethrough, monospace).
"Hello World"
Media to send — a document, image, video, audio file or voice note. Provide either a public url or base64 filedata. The message text, when given, becomes the caption.
Show child attributes
Show child attributes
Poll to send instead of a plain message. The resulting message has message_type poll_creation.
Show child attributes
Show child attributes
message_id of an existing message in the chat to reply to. The sent message quotes it.
"true_911111111111@c.us_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
Additional sending options
Show child attributes
Show child attributes
Per-chat values for the {{placeholders}} used in the message. Required when the message contains placeholders: every recipient chat must have an entry covering exactly the placeholder names — missing or extra keys are rejected.
Show child attributes
Show child attributes
[
{
"chat_id": "911111111111@c.us",
"values": { "name": "Jane", "order_id": "ORD-1042" }
}
]
UTC date and time to start the broadcast at, in ISO 8601 format. Must be in the future. Omit to start immediately.
"2026-02-06T11:21:00Z"
Time interval between consecutive messages, in seconds (0-60). Defaults to about 1 second when omitted.
0 <= x <= 6010
Org phones to send the broadcast from — recipients are distributed across them. Takes precedence over the x-phone header. When neither is given, every available phone of the org is used.
["911111111111@c.us"]
Response
The created broadcast
Id of the created broadcast. Use it to track progress via POST /message/queues or to cancel/stop via DELETE /message/broadcast/{broadcast_id}. Messages produced by the broadcast carry it as broadcast_id.
"00000000-0000-0000-0000-000000000000"
Human-readable pointer on how to track the broadcast
"You can track broadcast status by making a POST request to /messages/queues with { \"broadcast_id\": \"00000000-0000-0000-0000-000000000000\" } as body"
Was this page helpful?