On-demand premium SMS
On-demand premium SMS lets you charge subscribers per-message for content they request — quizzes, sports scores, news clips, jokes, horoscopes. The customer texts a keyword to your shortcode, you reply with the paid content, and the carrier collects the fee on your behalf.
- How the flow works
- Request parameters
- Response parameters
- Sample request
- Incoming keyword webhook
- Delivery status webhook
- Error responses
How the flow works
- The subscriber texts your keyword (e.g.
GOAL) to your shortcode. - Sozuri pushes an incoming webhook to your application with a
linkIdidentifying this request. - You reply via the API, passing the same
linkIdback — this is what triggers the premium charge. - Sozuri sends a delivery webhook when the premium SMS reaches the subscriber and the carrier confirms the charge.
Required headers
POST /api/v1/premium HTTP/1.1
Host: sozuri.net
Authorization: Bearer Your_Project_API_KEY
Content-Type: application/json
Accept: application/json
Request parameters
| Field | Required | Type | Description |
|---|---|---|---|
| project | Yes | String | The Sozuri project that owns the API key. |
| from | Yes | String | Your premium shortcode (e.g. 23546). |
| to | Yes | String | The subscriber’s phone number in E.164. 0722-503-129 is normalised to 254722503129. |
| channel | Yes | String | Always premium. |
| type | Yes | String | Always ondemand on this endpoint. |
| message | Yes | String | The premium content you’re sending the subscriber. |
| keyword | Yes | String | The keyword the subscriber sent in to request this content (e.g. OMOKA). |
| linkId | Yes | String | The ID Sozuri delivered in the incoming-keyword webhook. Mandatory for billing this message as on-demand. |
| campaign | No | String | Optional label for grouping reports. |
| apiKey | — | String | Your project API key. Recommended: pass as a Bearer token instead. |
Response parameters
Synchronous JSON response confirming the premium message was accepted for delivery:
| Field | Type | Description |
|---|---|---|
| messageData.messages | Number | Total messages accepted. |
| recipients[].messageId | String | Unique Sozuri ID for this message. |
| recipients[].to | String | The recipient’s phone number. |
| recipients[].status | String | Acceptance status — accepted, unknown_number etc. Not the final delivery status. |
| recipients[].statusCode | String | Numeric status — see status codes. |
| recipients[].messagePart | Number | SMS parts used. One GSM-7 part is 160 characters. |
| recipients[].keyword | String | Echoes back the keyword. |
| recipients[].type | String | Always ondemand here. |
Sample request
POST /api/v1/premium HTTP/1.1
Host: sozuri.net
Authorization: Bearer LOx5JPdqf0lvf.......R9X9XDJ4PFxRqVrt9dx83cWiwfTQMF
Content-Type: application/json
Accept: application/json
{
"project": "my project",
"from": "23546",
"to": "2547251642xx",
"campaign": "Promo Nai",
"channel": "premium",
"message": "Test SMS.",
"type": "ondemand",
"linkId": "54785454",
"keyword": "Omoka"
}
POST /api/v1/premium HTTP/1.1
Host: sozuri.net
Authorization: Bearer LOx5JPdqf0lvf45EZAQMJ.......SUzyxR9X9XDJ4PFxRqVrt9dx83cWiwfTQMF
Content-Type: application/json
Accept: application/xml
<request>
<project>my project</project>
<from>23546</from>
<to>2547251642xx</to>
<campaign>Promo Nai</campaign>
<channel>premium</channel>
<message>Test SMS.</message>
<type>ondemand</type>
<linkId>54785454</linkId>
<keyword>Omoka</keyword>
</request>
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sozuri.net/api/v1/premium",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
"project" => "my project",
"from" => "23546",
"to" => "2547251642xx",
"campaign" => "Promo Nai",
"channel" => "premium",
"message" => "Test SMS.",
"type" => "ondemand",
"linkId" => "54785454",
"keyword" => "Omoka",
]),
CURLOPT_HTTPHEADER => [
"Accept: application/json",
"Authorization: Bearer LOx5JPdqf0lvf45EZAQMJm85OSUzyxR9X9XDJ4PFxRqVrt9dx83cWiwfTQMF",
"Content-Type: application/json",
],
]);
echo curl_exec($curl);
curl_close($curl);
const response = await fetch("https://sozuri.net/api/v1/premium", {
method: "POST",
headers: {
"Authorization": "Bearer LOx5JPdqf0lvf45EZAQMJm85OSUzyxR9X9XDJ4PFxRqVrt9dx83cWiwfTQMF",
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify({
project: "my project",
from: "23546",
to: "2547251642xx",
campaign: "Promo Nai",
channel: "premium",
message: "Test SMS.",
type: "ondemand",
linkId: "54785454",
keyword: "Omoka"
})
});
console.log(await response.json());
require 'uri'
require 'net/http'
require 'json'
uri = URI("https://sozuri.net/api/v1/premium")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer LOx5JPdqf0lvf45EZAQMJm85OSUzyxR9X9XDJ4PFxRqVrt9dx83cWiwfTQMF"
request["Content-Type"] = "application/json"
request["Accept"] = "application/json"
request.body = {
project: "my project", from: "23546", to: "2547251642xx",
campaign: "Promo Nai", channel: "premium", message: "Test SMS.",
type: "ondemand", linkId: "54785454", keyword: "Omoka"
}.to_json
puts http.request(request).body
import requests
response = requests.post(
"https://sozuri.net/api/v1/premium",
headers={
"Authorization": "Bearer LOx5JPdqf0lvf45EZAQMJm85OSUzyxR9X9XDJ4PFxRqVrt9dx83cWiwfTQMF",
"Content-Type": "application/json",
"Accept": "application/json",
},
json={
"project": "my project", "from": "23546", "to": "2547251642xx",
"campaign": "Promo Nai", "channel": "premium", "message": "Test SMS.",
"type": "ondemand", "linkId": "54785454", "keyword": "Omoka",
},
)
print(response.json())
HttpResponse<String> response = Unirest.post("https://sozuri.net/api/v1/premium")
.header("Authorization", "Bearer LOx5JPdqf0lvf45EZAQMJm85OSUzyxR9X9XDJ4PFxRqVrt9dx83cWiwfTQMF")
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.body("{\"project\":\"my project\",\"from\":\"23546\",\"to\":\"2547251642xx\","
+ "\"campaign\":\"Promo Nai\",\"channel\":\"premium\",\"message\":\"Test SMS.\","
+ "\"type\":\"ondemand\",\"linkId\":\"54785454\",\"keyword\":\"Omoka\"}")
.asString();
var client = new RestClient("https://sozuri.net/api/v1/premium");
var request = new RestRequest(Method.POST);
request.AddHeader("Accept", "application/json");
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Bearer LOx5JPdqf0lvf45EZAQMJm85OSUzyxR9X9XDJ4PFxRqVrt9dx83cWiwfTQMF");
request.AddParameter("application/json",
"{\"project\":\"my project\",\"from\":\"23546\",\"to\":\"2547251642xx\","
+ "\"campaign\":\"Promo Nai\",\"channel\":\"premium\",\"message\":\"Test SMS.\","
+ "\"type\":\"ondemand\",\"linkId\":\"54785454\",\"keyword\":\"Omoka\"}",
ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
curl -X POST https://sozuri.net/api/v1/premium \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer LOx5JPdqf0lvf45EZAQMJm85OSUzyxR9X9XDJ4PFxRqVrt9dx83cWiwfTQMF' \
-d '{
"project": "my project",
"from": "23546",
"to": "2547251642xx",
"campaign": "Promo Nai",
"channel": "premium",
"message": "Test SMS.",
"type": "ondemand",
"linkId": "54785454",
"keyword": "Omoka"
}'
Sample JSON response
{
"messageData": { "messages": 1 },
"recipients": [
{
"messageId": "MSGBLK6012A7E8B90A21611835368",
"to": "2547251642xx",
"status": "accepted",
"statusCode": "11",
"keyword": "Omoka",
"messagePart": 1,
"type": "ondemand"
}
]
}
Incoming keyword webhook
When a subscriber texts your keyword to your premium shortcode, Sozuri pushes this webhook to your application. Capture the linkId — you must include it on your reply so the carrier knows to charge the subscriber.
{
"project": "yourproject_name",
"shortcode": "25145",
"keyword": "JOIN",
"number": "2547251xxxxx",
"network": "safaricom",
"type": "linkNotification",
"linkId": "256e487h2",
"status": "success",
"timestamp": "1603713484"
}
Delivery status webhook
Sozuri sends a delivery callback when the carrier confirms (or rejects) your premium message:
{
"project": "yourproject_name",
"shortcode": "25145",
"keyword": "JOIN",
"number": "2547251xxxxx",
"network": "safaricom",
"type": "premiumDelivery",
"status": "success",
"timestamp": "1603713484"
}
Error responses
On-demand premium SMS uses the SDP error envelope: { "status": "error", "description": "…" }. Auth errors (Unknown project.) follow the SMS envelope and are documented on the Authentication page.
| Condition | HTTP | Response body |
|---|---|---|
| Keyword/shortcode pair doesn’t match an active premium service on this project. | 400 | |
The linkId on a paid reply doesn’t match an incoming-keyword event we issued. |
400 | |
Offer reference not found (e.g. you sent an offer_code that’s not configured). |
400 | |
| Destination phone number is malformed or not in supported E.164 format. | 400 | |
Use cases
Where on-demand premium SMS earns its keep.
Sports scores & alerts
Subscriber texts GOAL to get the latest score on demand — charge per request, no app required.
News & horoscopes
Daily snippets of paid content on demand — the foundation of the original mobile content businesses.
Quizzes & trivia
Pay-per-question trivia campaigns on radio or TV — the keyword becomes the call-to-action.
A - Nigeria
B - Cote d’Ivoire
C - South Africa 08:42
Monetise your content via SMS.
Apply for a premium shortcode and we’ll handle billing, settlement and carrier paperwork end-to-end.