Developers
One API for four channels
Send SMS, VoIP MSG, WhatsApp and Viber with one request schema, and pull delivery reports into your own system with webhooks.
Quickstart
Your first message in three steps
Get an access key
Send a request from the form; your key appears in your panel.
Send the request
Use all four channels by changing the channel field.
Connect the report
Define your webhook URL and events start flowing.
Endpoints
Message and report endpoints
/v1/messages
Sends one or many messages (four channels via the channel field).
/v1/messages/{id}
Returns delivery state and error code for one message.
/v1/voice
Starts a voice-message campaign and dials the list.
/v1/reports
Per-channel delivery, read and click summary.
/v1/templates
Creates WhatsApp and Viber templates and tracks approval.
Request samples
The same request, different languages
Copy the samples below and run them with your own key.
curl -X POST https://api.freesendsms.io/v1/messages \
-H "Authorization: Bearer $FSS_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel": "sms",
"to": ["+90 5xx xxx xx xx"],
"sender": "FREESEND",
"text": "Siparisiniz kargoya verildi."
}'
// npm install @freesendsms/sdk
import { Fss } from "@freesendsms/sdk";
const fss = new Fss({ key: process.env.FSS_KEY });
const result = await fss.messages.send({
channel: "whatsapp",
to: ["+90 5xx xxx xx xx"],
template: "appointment_reminder",
variables: { name: "Ayse", time: "14:30" },
});
console.log(result.id, result.status);
<?php
$payload = [
'channel' => 'voip',
'to' => ['+90 5xx xxx xx xx'],
'voice' => 'kargo_hatirlatma.mp3',
'keypad' => ['1' => 'reschedule', '2' => 'replay'],
];
$ch = curl_init('https://api.freesendsms.io/v1/voice');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('FSS_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$response = json_decode(curl_exec($ch), true);
echo $response['status'];
Webhooks
Listen to delivery events
Every state change produces a signed webhook call. Verify the signature and write it to your own database.
-
message.queuedThe message entered the queue. -
message.deliveredThe message reached the recipient. -
message.readThe message was read (WhatsApp, Viber). -
message.failedCarrier rejection or invalid number.
POST /webhooks/fss
X-FSS-Signature: t=1759...,v1=8d1a...
{
"event": "message.delivered",
"message_id": "msg_9f21",
"channel": "sms",
"to": "+905xxxxxxxxx",
"at": "2026-10-20T15:58:04Z"
}
Rules
Sending rules and limits
Consent required
Only send to recipients who opted in.
Opt-out respected
Numbers replying STOP are removed automatically.
Rate limits
50 requests per second; use a queue beyond that.
Data retention
Report records are kept 12 months and deleted on request.
Request an access key
Tell us your scenario and we will open your key and sandbox access together.