Rashbery WhatsApp Gateway API

REST API for sending WhatsApp messages

Base URL
https://ws.rashbery.com/wsr
Authentication
Bearer Token
Max Devices/User
Depends on plan

Overview

The Rashbery WhatsApp Gateway provides a REST API for sending text messages, media, and group messages through your connected WhatsApp devices. It acts as a secure proxy between your application and the underlying WhatsApp bot service.

How It Works

  1. Add a device: Go to Devices, create a device and scan the QR code with WhatsApp.
  2. Get a token: Open the device detail page or call POST /wsr/api-tokens with device_id to create a device-scoped Bearer token.
  3. Send messages: Call endpoints with only Authorization: Bearer <token>. No device_id is required in the body when the token is device-scoped.
  4. Check status: Each send returns a request_id. Use the Requests endpoint to look up delivery status.

Key Features

  • Token-based auth: Secure Bearer token authentication via Laravel Sanctum (hashed at rest)
  • Device-scoped tokens: Tokens bind to one device so body device_id is not needed
  • Request tracking: Every message recorded with pending → sent/delivered/read/failed status
  • Subscription gated: Access requires active subscription or free-tier quota
  • Auto-cleanup: Request history auto-deleted after 3 days
  • Rate limited: 30 requests/min per API token

Authentication

All API endpoints require a Bearer token in the Authorization header. Prefer device-scoped tokens (created with device_id) so send endpoints only need the token — no device_id in the body.

Security notes:

  • Tokens are stored as SHA-256 hashes; only the plain token is shown once at creation.
  • Device-scoped tokens can only operate on the bound device (ownership is verified).
  • Revoke compromised tokens immediately via DELETE /wsr/api-tokens/{id}.
  • Always send over HTTPS in production; never commit tokens to source control.
MethodToken TypeWhere to Get It
Authorization: Bearer <token>Laravel Sanctum TokenDevice detail page or POST /wsr/api-tokens with device_id

Headers

Authorization: Bearer 8Xk2m9...Vd3j
Content-Type: application/json

Subscription & Quota

  • Sending messages requires an active subscription or free-tier quota.
  • When your subscription expires, API access is blocked with a 403 response.
  • Free-tier users get a limited message quota; once exhausted, subscribe to a paid plan.
  • The /user endpoint can be called without subscription check to query your quota.

Messaging

Send text messages, check if a number is on WhatsApp, and broadcast to multiple recipients.

Send a text message to a WhatsApp number

Auth: Bearer token

Request Body

{
  "number": "628123456789",
  "message": "Hello from Rashbery WhatsApp Gateway!"
}

Response

{
  "status": true,
  "message": "Message sent successfully",
  "data": {
    "request_id": 42,
    "status": "sent",
    "wa_message_id": "3EB0F7D8A1B2C3D4E5F6"
  }
}

Send the same text message to multiple numbers

Auth: Bearer token

Request Body

{
  "numbers": [
    "628123456789",
    "628987654321"
  ],
  "message": "Broadcast message",
  "delay_ms": 1000
}

Response

{
  "status": true,
  "message": "Bulk messages sent",
  "data": {
    "request_ids": [
      42,
      43
    ],
    "status": "sent"
  }
}

Check whether a phone number is registered on WhatsApp

Auth: Bearer token

Request Body

{
  "number": "628123456789"
}

Response

{
  "status": true,
  "message": "Number check complete",
  "data": {
    "isRegistered": true
  }
}

Send media (image, video, document) from a public URL

Auth: Bearer token

Request Body

{
  "number": "628123456789",
  "file_url": "https://example.com/invoice.pdf",
  "caption": "Your invoice is ready"
}

Response

{
  "status": true,
  "message": "Media sent successfully",
  "data": {
    "request_id": 44,
    "status": "sent",
    "wa_message_id": "3EB0F7D8A1B2C3D4E5F6"
  }
}

Send media from a base64-encoded string

Auth: Bearer token

Request Body

{
  "number": "628123456789",
  "base64": "/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAA...",
  "mimetype": "image/jpeg",
  "filename": "photo.jpg",
  "caption": "Photo from API"
}

Response

{
  "status": true,
  "message": "Media sent successfully",
  "data": {
    "request_id": 45,
    "status": "sent",
    "wa_message_id": "3EB0F7D8A1B2C3D4E5F6"
  }
}

Media

Send images, videos, documents, and audio files via URL or base64 encoding.

Groups

Send text messages and media to WhatsApp groups. Provide group ID or group name.

Send a text message to a WhatsApp group using group ID

Auth: Bearer token

Request Body

{
  "group_id": "120363024567890@g.us",
  "message": "Hello everyone!"
}

Response

{
  "status": true,
  "message": "Group message sent",
  "data": {
    "request_id": 46,
    "status": "sent",
    "wa_message_id": "3EB0F7D8A1B2C3D4E5F6"
  }
}

Send media to a WhatsApp group

Auth: Bearer token

Request Body

{
  "group_id": "120363024567890@g.us",
  "file_url": "https://example.com/promo.jpg",
  "caption": "Check out this offer!",
  "mention": "628123456789"
}

Response

{
  "status": true,
  "message": "Group media sent",
  "data": {
    "request_id": 47,
    "status": "sent",
    "wa_message_id": "3EB0F7D8A1B2C3D4E5F6"
  }
}

Request Status

Track every message you send. Each API call creates a request record with status updates (pending → sent / delivered / read / failed). Records are auto-purged after 3 days.

List your recent message requests (last 3 days) with delivery status

Auth: Bearer token

Query Parameters

NameTypeRequiredDescription
device_idintegerNoFilter by device
statusstringNoFilter: pending / sent / delivered / read / failed
channelstringNoFilter: message / media / group / group-media
per_pageintegerNoItems per page (max 100, default 20)

Response

{
  "status": true,
  "data": {
    "data": [
      {
        "id": 42,
        "channel": "message",
        "to": "628123456789",
        "body": "Hello!",
        "status": "sent",
        "wa_message_id": "3EB0...7F",
        "sent_at": "2026-07-21T15:30:00.000Z",
        "created_at": "2026-07-21T15:30:00.000Z"
      }
    ],
    "current_page": 1,
    "last_page": 3,
    "per_page": 20,
    "total": 48
  }
}

Get detailed status of a single message request

Auth: Bearer token

Query Parameters

NameTypeRequiredDescription
idintegerYesRequest ID from the list

Response

{
  "status": true,
  "data": {
    "id": 42,
    "user_id": 5,
    "channel": "message",
    "direction": "out",
    "to": "628123456789",
    "body": "Hello!",
    "status": "sent",
    "wa_message_id": "3EB0F7D8A1B2C3D4E5F6",
    "error_message": null,
    "sent_at": "2026-07-21T15:30:00.000Z",
    "created_at": "2026-07-21T15:30:00.000Z"
  }
}

Error Codes

CodeStatusDescription
200OKRequest successful
400Bad RequestInvalid request body or parameters
401UnauthorizedMissing or invalid Bearer token
403ForbiddenSubscription expired, quota exhausted, or insufficient permissions
404Not FoundDevice or resource not found
422Validation ErrorRequest body validation failed
429Too Many RequestsRate limit exceeded (30 req/min for API)
503Service UnavailableDevice not connected or wa-bot service unreachable

Error Response Format

{
  "status": false,
  "message": "Device is not connected. Please scan the QR code first.",
  "data": {
    "request_id": 42,
    "status": "failed"
  }
}

Rate Limits

ScopeLimitDescription
External API30 requests per minute per userAll /wsr/* endpoints share this limit
Auth endpoints5 attempts per minute per email+IPLogin, register, password reset
Coupon validation10 requests per minute per userCoupon apply endpoint

429 Response

{
  "status": false,
  "message": "Too many requests. Please slow down."
}

When receiving 429, wait at least 2 seconds before retrying.

SDKs & Code Examples

Curl

curl -X POST https://ws.rashbery.com/wsr/api-tokens \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "My App", "abilities": ["*"], "device_id": 1}'

Javascript

const axios = require('axios');

const api = axios.create({
  baseURL: 'https://ws.rashbery.com/wsr',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json'
  }
});

async function createToken(name) {
  const response = await api.post('/api-tokens', { name, abilities: ['*'], device_id: 1 });
  console.log('Save this token — it will not be shown again:', response.data.data.token);
  return response.data.data;
}

Php

<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;

$client = new Client([
  'base_uri' => 'https://ws.rashbery.com/wsr/',
  'headers' => [
    'Authorization' => 'Bearer YOUR_API_TOKEN',
    'Content-Type' => 'application/json'
  ]
]);

$response = $client->post('message/send', [
  'json' => [
    'number' => '628123456789',
    'message' => 'Hello from PHP!'
  ]
]);

$data = json_decode($response->getBody(), true);
echo "Request ID: " . $data['data']['request_id'] . PHP_EOL;

Python

import requests

API_URL = 'https://ws.rashbery.com/wsr'
API_TOKEN = 'YOUR_API_TOKEN'

headers = {
    'Authorization': f'Bearer {API_TOKEN}',
    'Content-Type': 'application/json'
}

def send_message(number, message):
    response = requests.post(
        f'{API_URL}/message/send',
        headers=headers,
        json={
            'number': number,
            'message': message
        }
    )
    return response.json()

# Usage
result = send_message('628123456789', 'Hello from Python!')
print(f"Request ID: {result['data']['request_id']}, Status: {result['data']['status']}")