Quick start
Send your first WhatsApp message through the YASend API in about five minutes.
Base URL https://api.yasend.dev · Auth Authorization: Bearer <your API key> · Format JSON
1. Get an API key
Sign up at yasend.dev. Every account starts with a 24-hour free trial. Then, in
the portal, open API keys and create a key. It starts with ysk_live_ and is shown only once:
store it like a password, on your server only.
2. Create a session
A session is one WhatsApp number connected to YASend.
curl -X POST https://api.yasend.dev/v1/sessions \
-H "Authorization: Bearer $YASEND_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "OTP sender"}'
const res = await fetch("https://api.yasend.dev/v1/sessions", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.YASEND_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ name: "OTP sender" }),
});
const session = await res.json();
console.log(session.id);
import os, requests
r = requests.post("https://api.yasend.dev/v1/sessions",
headers={"Authorization": f"Bearer {os.environ['YASEND_KEY']}"},
json={"name": "OTP sender"})
session = r.json()
print(session["id"])
use Illuminate\Support\Facades\Http;
$session = Http::withToken(env('YASEND_KEY'))
->post('https://api.yasend.dev/v1/sessions', ['name' => 'OTP sender'])
->json();
echo $session['id'];
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new("Bearer", Environment.GetEnvironmentVariable("YASEND_KEY"));
var res = await http.PostAsJsonAsync("https://api.yasend.dev/v1/sessions", new { name = "OTP sender" });
var session = await res.Content.ReadFromJsonAsync<JsonElement>();
Console.WriteLine(session.GetProperty("id"));
The response includes the session's own key in apiKey. That key only works for this one session,
and it is also shown only once.
3. Link your phone
Start the session, then scan its QR code with the phone that owns the number: WhatsApp → Settings → Linked devices → Link a device.
curl -X POST https://api.yasend.dev/v1/sessions/$SESSION_ID/connect -H "Authorization: Bearer $YASEND_KEY"
curl "https://api.yasend.dev/v1/sessions/$SESSION_ID/qr?format=png" -H "Authorization: Bearer $YASEND_KEY" -o qr.png
The QR code refreshes about every 20 seconds, so fetch it again if it expires. Prefer typing a code? Use a pairing code instead.
When the phone is linked, GET /v1/sessions/{id} shows "status": "connected".
New numbers start slowly. To protect your number from being banned, a freshly linked number can send only a few messages a day at first, and needs a profile name, a profile photo and at least one manual conversation. See Safety & warm-up.
4. Send a message
curl -X POST https://api.yasend.dev/v1/messages \
-H "Authorization: Bearer $YASEND_KEY" \
-H "Content-Type: application/json" \
-d '{"sessionId": "'$SESSION_ID'", "to": "963912345678", "text": "Hello from YASend 👋"}'
const res = await fetch("https://api.yasend.dev/v1/messages", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.YASEND_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ sessionId, to: "963912345678", text: "Hello from YASend 👋" }),
});
const message = await res.json();
if (!res.ok) throw new Error(`${message.error.code}: ${message.error.message}`);
console.log(message.status, message.waMessageId);
r = requests.post("https://api.yasend.dev/v1/messages",
headers={"Authorization": f"Bearer {os.environ['YASEND_KEY']}"},
json={"sessionId": session_id, "to": "963912345678", "text": "Hello from YASend 👋"})
r.raise_for_status()
print(r.json()["status"])
$message = Http::withToken(env('YASEND_KEY'))
->post('https://api.yasend.dev/v1/messages', [
'sessionId' => $sessionId,
'to' => '963912345678',
'text' => 'Hello from YASend 👋',
])->throw()->json();
var res = await http.PostAsJsonAsync("https://api.yasend.dev/v1/messages",
new { sessionId, to = "963912345678", text = "Hello from YASend 👋" });
res.EnsureSuccessStatusCode();
to is the phone number in international format, as digits only (no +, spaces or leading 00).
A plain send waits until WhatsApp has accepted the message, usually 3–10 seconds, because YASend
paces messages like a human. To get an instant answer instead, add ?async=true and receive the
result by webhook. See Sending messages.