Quickstart
Send your first SMS in three steps.
1. Get an API token
Create a scoped key from your dashboard.
From your dashboard go to Settings, then API Keys & Webhooks and create a token. Copy it immediately, it is shown only once. Tokens carry scopes (abilities) that limit what they can do, see Authentication.
2. Send a message
One POST puts a campaign in the queue.
POST /sms/sendsms:send
Send to one or more recipients from an approved sender ID. Pass an Idempotency-Key so a retry never double-sends.
curl -X POST https://api.helliomessaging.com/v1/sms/send \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"recipients": ["+233241234567"],
"sender": "HELLIO",
"message": "Hello from Hellio!"
}'
const res = await fetch("https://api.helliomessaging.com/v1/sms/send", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.HELLIO_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
recipients: ["+233241234567"],
sender: "HELLIO",
message: "Hello from Hellio!",
}),
});
const { data } = await res.json();
import os, uuid, requests
res = requests.post(
"https://api.helliomessaging.com/v1/sms/send",
headers={
"Authorization": f"Bearer {os.environ['HELLIO_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"recipients": ["+233241234567"],
"sender": "HELLIO",
"message": "Hello from Hellio!",
},
)
data = res.json()["data"]
use Illuminate\Support\Facades\Http;
$data = Http::withToken($apiKey)
->withHeaders(['Idempotency-Key' => (string) Str::uuid()])
->post("https://api.helliomessaging.com/v1/sms/send", [
'recipients' => ['+233241234567'],
'sender' => 'HELLIO',
'message' => 'Hello from Hellio!',
])
->json('data');
A 202 Accepted means the campaign is queued:
{
"data": {
"reference": "8f3a...",
"campaign_id": 1042,
"status": "queued",
"accepted_recipients": 1,
"invalid_recipients": 0,
"segments": 1,
"estimated_cost": "0.0300",
"currency": "GHS",
"message": "Hello from Hellio!",
"short_links": []
}
}
Shortening links
Replace long URLs with tracked short links.
Pass shorten_links to have every URL in your message swapped for a short, tracked link. Shorter messages often mean fewer segments, so this can also lower the cost of the send.
curl -X POST https://api.helliomessaging.com/v1/sms/send \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"recipients": ["+233241234567"],
"sender": "HELLIO",
"message": "Your receipt: https://example.com/orders/12345/receipt?token=abc",
"shorten_links": true
}'
The response returns the message as it will actually be sent, plus each link that was created, so you can match clicks back to the URL you supplied:
{
"data": {
"segments": 1,
"message": "Your receipt: https://hmbyt.sbs/k3f9qa",
"short_links": [
{
"short_url": "https://hmbyt.sbs/k3f9qa",
"target_url": "https://example.com/orders/12345/receipt?token=abc"
}
]
}
}
Omit shorten_links to follow your account's default. Set it to false to keep your URLs exactly as written on a send where the default is on. Links that are already short links of ours are left alone, so re-sending a message never double-shortens it.
Clicks are reported under Reports → Short URLs, broken down by country, device and browser.
3. Check delivery
Confirm what happened to your message.
Fetch the campaign summary, or a single message by its reference:
curl https://api.helliomessaging.com/v1/campaigns/8f3a... \
-H "Authorization: Bearer YOUR_API_TOKEN"
Response:
{
"data": {
"reference": "8f3a...",
"campaign_id": 1042,
"status": "completed",
"recipients": 1,
"estimated_cost": "0.0300",
"charged": "0.0300",
"breakdown": { "delivered": 1 }
}
}
For real-time updates instead of polling, set up a webhook.
Recipients format
How to pass one number or many.
recipients accepts an array, or a single comma / newline separated string. Numbers may be written in local (0241234567) or international (+233241234567) form, spaces are ignored.
Other channels
The same credentials power OTP, voice, lookup and email.
The same token + base URL power OTP (/otp/send, /otp/verify), voice (/voice/send), number lookup (/lookup) and email verification (/email/verify). See the API Reference for every endpoint.
