Mursilat API v2 · 2026-10
Build on WhatsApp from your own number
One REST API for numbers, every message type, safe campaigns, auto-replies, OTP and signed webhooks — with the Number Shield protecting every send, and no message content stored.
- Scoped keys
- Idempotent writes
- Arabic & English errors
- Zero message retention
- Base URL
https://mursilat.com/api/v2- API version
2026-10
curl -X POST "https://mursilat.com/api/v2/messages" \
-H "Authorization: Bearer $WASLA_API_KEY" \
-H "Idempotency-Key: order-1042-confirm" \
-H "Content-Type: application/json" \
-d '{
"numberId": "cm1abcd2345efgh6789ijkl",
"to": "201001234567",
"type": "text",
"text": "طلبك اتشحن 🚚 *شكرًا*",
"reference": "order-1042"
}'const res = await fetch('https://mursilat.com/api/v2/messages', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.WASLA_API_KEY}`,
'Idempotency-Key': 'order-1042-confirm',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"numberId": "cm1abcd2345efgh6789ijkl",
"to": "201001234567",
"type": "text",
"text": "طلبك اتشحن 🚚 *شكرًا*",
"reference": "order-1042"
}),
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
console.log(data);import os
import requests
headers = {"Authorization": f"Bearer {os.environ['WASLA_API_KEY']}", "Idempotency-Key": "order-1042-confirm"}
res = requests.post(
"https://mursilat.com/api/v2/messages",
headers=headers,
json={
"numberId": "cm1abcd2345efgh6789ijkl",
"to": "201001234567",
"type": "text",
"text": "طلبك اتشحن 🚚 *شكرًا*",
"reference": "order-1042"
},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
print(data)<?php
$ch = curl_init('https://mursilat.com/api/v2/messages');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WASLA_API_KEY'),
'Idempotency-Key: order-1042-confirm',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'numberId' => 'cm1abcd2345efgh6789ijkl',
'to' => '201001234567',
'type' => 'text',
'text' => 'طلبك اتشحن 🚚 *شكرًا*',
'reference' => 'order-1042'
], JSON_UNESCAPED_UNICODE),
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($status >= 400) { throw new Exception($data['error']['code'] . ': ' . $data['error']['message']); }
print_r($data);Start here
From zero to a delivered message and a verified webhook.
API reference
Every endpoint with parameters, examples in four languages and a live console. · 80 endpoints
- Account & keys1Create account API keys in Settings → API keys: choose scopes, numbers and optionally allowed IPs. The key is shown once.
- Numbers16Add numbers, pair them with a QR or a pairing code, follow their connection and manage their webhooks. Tip: a WhatsApp Business number with a real profile (name, photo, description) is trusted more by customers and by WhatsApp.
- Messages9One endpoint for every message type, now or scheduled. Every send goes through the Number Shield (warm-up caps, pacing, opt-outs, content rules) and your plan quota. Status endpoints return metadata only: the API never returns message content.
- Campaigns (bulk)9Send one message to many people safely: the Number Shield paces it, respects quiet hours, skips opted-out and invalid numbers and pauses on bad signals. Content and recipients are deleted automatically after the campaign ends (keep window up to 24 h); only totals remain.
- Auto-replies11Keyword (exact, contains, starts with, or a regular expression), welcome (first message) and away (outside business hours) rules per number. Opt-out keywords always win; replies go out as replies (short pacing).
- OTP (verification codes)3Mursilat generates the code, sends it from your number and keeps only a hash — the code is never returned, stored or logged. Verify with a constant-time check and limited attempts. Deliverability: send OTPs only to people who asked for them, the text is fixed and localized — only your app name is added.
- Number Shield & stats8See how healthy a number is, pause it, make it slower than the Number Shield (never faster) and read daily statistics. No tool can promise a number is never restricted; these lower the risk.
- Groups2Read the groups of a number. Sending to groups is blocked by the Number Shield on purpose: spam reports from groups get numbers banned fastest. This is a safety decision, not a missing feature.
- Webhooks9Real-time events signed with HMAC-SHA256 (X-Wasla-Signature: t=…,v1=…), retried for about an hour. One account-level URL for all numbers, and/or one per number. The delivery log keeps metadata only (7 days).
- Website button & WhatsApp links12A chat button for your website (one script tag) and tracked wa.me links / QR codes for ads, bios and print. Every click gets a short ref code in the prefilled text; when the visitor writes, Mursilat links the chat to the page / ad / campaign (webhook conversation.attributed). Inbound-first chats are the safest for your number. No visitor IP, cookie or full URL is stored.
Webhooks
WebhooksReal-time signed events: the event catalog with full examples, signature verification, retries, redelivery, ordering and idempotency.Webhook payload inspectorPaste a webhook body, its X-Wasla-Signature header and your secret: the signature and the envelope are checked locally in your browser.Guides
Practical, safe ways to use the API in production.
- Sending your first campaign safelySend one message to many people without hurting your number: test, vary the text, choose the speed, watch progress by webhook.
- Interactive buttons and their numbered fallbackReply buttons, list menus and link buttons from a linked number — and why every customer can still answer when buttons don’t render.
- OTP done rightSend one-time codes from your own number: Mursilat generates and hashes the code, uses a fixed safe text, and limits attempts and recipients.
- Protecting your number (Number Shield)How the Number Shield governs every send — warm-up caps, pacing, quiet hours, opt-outs, content rules — and what the API answers when it queues, paces or refuses.
- Privacy: what Mursilat stores and doesn’tInbox messages stored encrypted per account for the customer’s retention period; what the API keeps (metadata, for how long) and what it never returns.
- Migrating from v1 to v2Move from per-number v1 keys and endpoints to v2 account keys, one REST surface and signed v2 webhooks — step by step.
- Using a dedicated business numberWhy your API traffic should come from a dedicated WhatsApp Business number, and how to set it up so customers trust it.
Downloads
Import the API into your tools.
- OpenAPI 3.1 (v2)For code generators, Swagger UI, Insomnia.
/developers/openapi-v2.json - Postman collection (v2)Set the apiKey variable and send.
/developers/postman-v2.json - OpenAPI (v1, legacy)
/developers/openapi.json - Postman (v1, legacy)
/developers/postman.json