REST API v1 Ethiopia Telecom & Safaricom High-Throughput Gateway

Developer API Documentation & Sandbox

Integrate programmatic SMS, OTP delivery, delivery reports, and airtime disbursement into your apps with sub-second latency.

Your API Base URL
https://bulk.uplink.et
Client Identifier (Email)
client.demo@uplink.et
Balance: ETB 1,000.00 Manage Keys →

Quick Start: Send Your First SMS

Generate a JWT session token and dispatch an SMS in less than 60 seconds.

Two-Step Flow: Step 1: Authenticate with your ClientId and ClientSecret to obtain a JWT Bearer token. Step 2: Pass that Bearer token in the Authorization header for subsequent requests.
# 1. Authenticate to get Bearer Token
curl -X POST "https://bulk.uplink.et/api/vas/security/authenticatetoken" \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "client.demo@uplink.et",
    "clientSecret": "uplink_sec_live_demo8892"
  }'

# 2. Send SMS using the Token
curl -X POST "https://bulk.uplink.et/sms/send" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "senderId": "Uplink",
    "recipients": ["251911234567"],
    "message": "Hello from Uplink Ethiopia! Your verification OTP is 849201."
  }'
import requests

BASE_URL = "https://bulk.uplink.et"

# Step 1: Authenticate
auth_resp = requests.post(f"{BASE_URL}/api/vas/security/authenticatetoken", json={
    "clientId": "client.demo@uplink.et",
    "clientSecret": "uplink_sec_live_demo8892"
})
token = auth_resp.json().get("token")

# Step 2: Send SMS
headers = {
    "Authorization": f"Bearer {token}",
    "Content-Type": "application/json"
}
payload = {
    "senderId": "Uplink",
    "recipients": ["251911234567"],
    "message": "Hello from Uplink Ethiopia! Your OTP is 849201."
}

send_resp = requests.post(f"{BASE_URL}/sms/send", json=payload, headers=headers)
print(send_resp.json())
const axios = require('axios');

const BASE_URL = 'https://bulk.uplink.et';

async function sendSms() {
  // Step 1: Authenticate
  const authRes = await axios.post(`${BASE_URL}/api/vas/security/authenticatetoken`, {
    clientId: 'client.demo@uplink.et',
    clientSecret: 'uplink_sec_live_demo8892'
  });
  const token = authRes.data.token;

  // Step 2: Send SMS
  const sendRes = await axios.post(`${BASE_URL}/sms/send`, {
    senderId: 'Uplink',
    recipients: ['251911234567'],
    message: 'Hello from Uplink Ethiopia! Your OTP is 849201.'
  }, {
    headers: { Authorization: `Bearer ${token}` }
  });

  console.log(sendRes.data);
}

sendSms();
<?php
$baseUrl = 'https://bulk.uplink.et';

// 1. Authenticate
$authPayload = json_encode([
    'clientId' => 'client.demo@uplink.et',
    'clientSecret' => 'uplink_sec_live_demo8892'
]);

$ch = curl_init("$baseUrl/api/vas/security/authenticatetoken");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $authPayload,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true
]);
$authRes = json_decode(curl_exec($ch), true);
$token = $authRes['token'];
curl_close($ch);

// 2. Send SMS
$smsPayload = json_encode([
    'senderId' => 'Uplink',
    'recipients' => ['251911234567'],
    'message' => 'Hello from Uplink Ethiopia! Your OTP is 849201.'
]);

$ch = curl_init("$baseUrl/sms/send");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $smsPayload,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $token",
        'Content-Type: application/json'
    ],
    CURLOPT_RETURNTRANSFER => true
]);
$response = curl_exec($ch);
echo $response;
curl_close($ch);
?>
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

using var client = new HttpClient();
var baseUrl = "https://bulk.uplink.et";

// 1. Authenticate
var authPayload = new StringContent(
    JsonSerializer.Serialize(new { clientId = "client.demo@uplink.et", clientSecret = "uplink_sec_live_demo8892" }),
    Encoding.UTF8, "application/json");

var authRes = await client.PostAsync($"{baseUrl}/api/vas/security/authenticatetoken", authPayload);
var authJson = await authRes.Content.ReadAsStringAsync();
var tokenDoc = JsonDocument.Parse(authJson);
var token = tokenDoc.RootElement.GetProperty("token").GetString();

// 2. Send SMS
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var sendPayload = new StringContent(
    JsonSerializer.Serialize(new {
        senderId = "Uplink",
        recipients = new[] { "251911234567" },
        message = "Hello from Uplink Ethiopia! Your OTP is 849201."
    }),
    Encoding.UTF8, "application/json");

var sendRes = await client.PostAsync($"{baseUrl}/sms/send", sendPayload);
Console.WriteLine(await sendRes.Content.ReadAsStringAsync());
POST /api/vas/security/authenticatetoken

Generate a JWT Bearer access token valid for 60 minutes.

Request Body (JSON)
FieldTypeRequiredDescription
clientIdstringYesYour account email or username (e.g. client.demo@uplink.et)
clientSecretstringYesYour secure API secret generated in Profile > API Keys
Sample Response (200 OK)
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expiration": "2026-08-14T13:28:00Z"
}
POST /sms/send

Dispatch transactional or bulk SMS to Ethiopian mobile subscribers (Ethio Telecom).

Request Headers
Authorization: Bearer <YOUR_TOKEN>
Content-Type: application/json
Request Body (JSON)
FieldTypeRequiredDescription
senderIdstringYesApproved Alphanumeric Sender ID registered on your account
recipientsarray<string>YesArray of phone numbers in international format (e.g. ["251911234567"])
messagestringYesMessage body (supports Latin GSM-7 and Ethiopian Ge'ez / Amharic UCS-2)
scheduledAtdatetimeOptionalUTC ISO-8601 Timestamp for scheduled delivery (e.g. 2026-08-15T09:00:00Z)
Sample Response (200 OK)
{
  "batchId": "10492",
  "status": "Accepted",
  "numberOfRecipients": 1
}
GET /sms/status/{id}

Check the real-time delivery status of an individual SMS message.

Sample Response (200 OK)
{
  "messageId": "85921",
  "recipient": "251911234567",
  "status": "Delivered",
  "deliveredAt": "2026-08-14T12:28:12Z"
}
POST /airtime/send

Programmatically disburse instant airtime in Ethiopian Birr (ETB) to Ethio Telecom.

Request Body (JSON)
{
  "recipientPhone": "251911234567",
  "network": "EthioTelecom",
  "amountEtb": 100.00
}
Sample Response (200 OK)
{
  "transactionId": 4829,
  "status": "Success",
  "recipient": "251911234567",
  "amountEtb": 100.00,
  "reference": "AT_ET_98492048",
  "message": "Airtime successfully dispatched."
}
Ethiopian Amharic (Ge'ez) & Character Limits

SMS protocols handle English (GSM-7) and Amharic (UCS-2 Unicode) with different segment limits:

GSM-7 (English / Numbers)
  • • Single Part Limit: 160 characters
  • • Multi-part Segmentation: 153 characters/part
  • • Standard Latin charset (A-Z, 0-9, standard symbols)
UCS-2 (Amharic / Ge'ez)
  • • Single Part Limit: 70 characters
  • • Multi-part Segmentation: 67 characters/part
  • • Fully supported: Ethiopic syllabary (ሀ, ለ, ሐ, መ, etc.)

Interactive In-Browser Sandbox

Live Request Runner

Test API requests directly from this console against your live account.

// Response will appear here after execution...
Status: Ready