Reliable messaging for real operations

SMS that fits the systems you already run.

Send transactional messages, reminders, alerts, and bulk campaigns through one signed REST endpoint. Build with JSON or upload prepared message files.

Signed requests

JSON and files

Delivery tracking

POST /api/v1/send-smsReady
1

Prepare

Create JSON or a CSV message file.

2

Hash

SHA-256 the exact bytes being sent.

3

Sign

Create an HMAC signature with your secret.

4

Send

POST once and track the returned message ID.

One endpoint, two delivery modes

Send a signed POST request using either an exact JSON body or a multipart file upload. Use the API hostname issued for your environment.

HTTP
POST https://sms.vomule.net/api/v1/send-sms

Use OpenAPI or Postman

Download the OpenAPI spec for Swagger-compatible tools, or import the Postman collection for quick tests. The Postman JSON request signs itself after you set your collection variables.

For CSV uploads, Postman cannot hash the selected local file in a pre-request script. Use the PHP, JavaScript, or Python file-upload example to calculate the file body hash and signature, then paste those values into the collection variables.

Sign every request on your server

Authentication combines your client ID, a current Unix timestamp, a SHA-256 body hash, and an HMAC-SHA256 signature.

HeaderValue
X-Client-IDYour issued client ID
X-TimestampCurrent Unix timestamp in seconds; accepted for five minutes
X-Body-HashSHA-256 of the exact JSON bytes or original uploaded file bytes
X-SignatureLowercase HMAC-SHA256 signature
SIGNATURE BASE
{timestamp}POST/api/v1/send-sms{bodyHash}
SIGNATURE
HMAC_SHA256(signatureBase, clientSecret)

Keep the client secret in server environment variables. Never place it in browser JavaScript, mobile applications, repositories, logs, or support messages.

Send one message

Hash the exact JSON bytes you send. These examples read credentials from environment variables and preserve the same encoded body for hashing and transmission.

PHP
<?php
$clientId = getenv('VOMULE_SMS_CLIENT_ID');
$clientSecret = getenv('VOMULE_SMS_CLIENT_SECRET');
$baseUrl = rtrim(getenv('VOMULE_SMS_BASE_URL'), '/');
$path = '/api/v1/send-sms';
$timestamp = time();
$payload = ['msisdn' => '+26650123456', 'message' => 'Hello from PHP', 'request_id' => 'order-1001'];
$rawBody = json_encode($payload, JSON_UNESCAPED_SLASHES);
$bodyHash = hash('sha256', $rawBody);
$signature = hash_hmac('sha256', $timestamp . 'POST' . $path . $bodyHash, $clientSecret);

$ch = curl_init($baseUrl . $path);
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        "X-Client-ID: {$clientId}", "X-Timestamp: {$timestamp}",
        "X-Body-Hash: {$bodyHash}", "X-Signature: {$signature}",
    ],
    CURLOPT_POSTFIELDS => $rawBody,
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

Request body

JSON
{
  "msisdn": "+26650123456",
  "message": "Your verification code is 482913.",
  "request_id": "order-20260622-0001"
}

Success response

JSON
{
  "message": "Message successfully queued",
  "status": "queued",
  "message_id": "019..."
}

Upload a prepared message file

CSV rows use msisdn,message,request_id. For multipart mode, hash only the original file bytes, not the multipart envelope.

PHP
<?php
$clientId = getenv('VOMULE_SMS_CLIENT_ID');
$clientSecret = getenv('VOMULE_SMS_CLIENT_SECRET');
$baseUrl = rtrim(getenv('VOMULE_SMS_BASE_URL'), '/');
$path = '/api/v1/send-sms';
$filePath = '/path/to/messages.csv';
$timestamp = time();
$bodyHash = hash_file('sha256', $filePath);
$signature = hash_hmac('sha256', $timestamp . 'POST' . $path . $bodyHash, $clientSecret);

$ch = curl_init($baseUrl . $path);
curl_setopt_array($ch, [
    CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["X-Client-ID: {$clientId}", "X-Timestamp: {$timestamp}", "X-Body-Hash: {$bodyHash}", "X-Signature: {$signature}"],
    CURLOPT_POSTFIELDS => ['file' => new CURLFile($filePath)],
]);
$response = curl_exec($ch);
curl_close($ch);

Example CSV

CSV
+26650123456,"Your order is ready",order-1001
+26658123456,"Your appointment is tomorrow",appointment-2048

Success response

JSON
{ "message": "File successfully uploaded" }

Errors and safe retries

StatusMeaning
400The supplied body hash does not match the received bytes.
401Credentials, timestamp, hash, or signature are invalid.
422Message fields or the uploaded file failed validation.
429The client exceeded its rate limit and should retry with backoff.
500An unexpected service error occurred.

Use a unique request_id for tracing. Check the response and delivery logs before retrying; repeated request IDs are not currently guaranteed to be idempotent.

Ready to put SMS into your workflow?

Create a workspace, obtain API credentials, and start with a signed test request.

Create your account