API Documentation

Complete guide to integrating MarzSMS into your applications. Build powerful SMS capabilities with our simple, reliable API.

Getting Started

Welcome to the MarzSMS API! This documentation will help you integrate SMS functionality into your application quickly and easily.

Base URL

https://sms.wearemarz.com/api/v1

All API endpoints are prefixed with this base URL. Make sure to use HTTPS in production.

API Credentials

To get started, you'll need API credentials. Sign up for an account and navigate to the API Keys section to generate your credentials.

Sign Up Now →

Authentication

Step-by-Step: Getting Your API Credentials

  1. 1. Sign up or log in to your MarzSMS account at sms.wearemarz.com
  2. 2. Navigate to Dashboard → Settings & Tools → API Keys
  3. 3. Click "Create New API Key" and give it a descriptive name (e.g., "Production API" or "Test Environment")
  4. 4. Important: Copy your API Key and API Secret immediately. The secret is only shown once and cannot be retrieved later.
  5. 5. Store your credentials securely. Never commit them to version control or expose them publicly.

How HTTP Basic Authentication Works

All API requests require authentication using HTTP Basic Authentication. This means:

  • API Key = Username (used as the first part of credentials)
  • API Secret = Password (used as the second part of credentials)
  • Format: API_KEY:API_SECRET
  • This combination is base64-encoded and sent in the Authorization header

Security Note: Always use HTTPS in production. Never expose your API credentials in client-side code.

cURL Example

Using the -u flag automatically handles Basic Auth:

curl -X POST "https://sms.wearemarz.com/api/v1/sms/send" \ -u "YOUR_API_KEY:YOUR_API_SECRET" \ -H "Content-Type: application/json" \ -d '{ "recipient": "+256700000000", "message": "Hello, this is a test message!" }'

Replace YOUR_API_KEY and YOUR_API_SECRET with your actual credentials.

PHP Example

Using CURLOPT_USERPWD for Basic Auth:

// Your API credentials $apiKey = 'sk_your_actual_api_key_here'; $apiSecret = 'your_actual_api_secret_here'; // Initialize cURL $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => 'https://sms.wearemarz.com/api/v1/sms/send', CURLOPT_RETURNTRANSFER => true, CURLOPT_USERPWD => $apiKey . ':' . $apiSecret, // Basic Auth CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode([ 'recipient' => '+256700000000', 'message' => 'Hello, this is a test message!', ]), ]); $response = curl_exec($curl); $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); $error = curl_error($curl); curl_close($curl); if ($error) { echo "cURL Error: " . $error; } else { $result = json_decode($response, true); if ($result['success']) { echo "Success! " . $result['message']; } else { echo "Error: " . $result['message']; } }

JavaScript (Fetch) Example

Using base64 encoding for Basic Auth header:

// Your API credentials const apiKey = 'sk_your_actual_api_key_here'; const apiSecret = 'your_actual_api_secret_here'; // Encode credentials for Basic Auth const credentials = btoa(apiKey + ':' + apiSecret); fetch('https://sms.wearemarz.com/api/v1/sms/send', { method: 'POST', headers: { 'Authorization': 'Basic ' + credentials, 'Content-Type': 'application/json', }, body: JSON.stringify({ recipient: '+256700000000', message: 'Hello from JavaScript!' }) }) .then(response => response.json()) .then(data => { if (data.success) { console.log('Success!', data.message); console.log('Remaining balance:', data.data.remaining_balance); } else { console.error('Error:', data.message); } }) .catch(error => { console.error('Request failed:', error); });

Python (requests) Example

import requests import json # Your API credentials api_key = 'sk_your_actual_api_key_here' api_secret = 'your_actual_api_secret_here' url = 'https://sms.wearemarz.com/api/v1/sms/send' headers = { 'Content-Type': 'application/json' } data = { 'recipient': '+256700000000', 'message': 'Hello from Python!' } # Basic Auth with requests library response = requests.post( url, headers=headers, auth=(api_key, api_secret), json=data ) result = response.json() if result['success']: print('Success!', result['message']) print('Remaining balance:', result['data']['remaining_balance']) else: print('Error:', result['message'])
POST /api/v1/sms/send

Send SMS

Send SMS messages to one or multiple recipients. Supports up to 320 characters per message (2 SMS units).

Request Parameters

Parameter Type Required Description
recipient string Yes Phone number(s). See recipient formatting below.
message string Yes Message text. Max 320 characters (2 SMS units).

Recipient Formatting (IMPORTANT)

Single Recipient:

{ "recipient": "+256700000000", "message": "Hello!" }

Accepted formats: +256700000000 or 256700000000

Multiple Recipients (Comma-Separated):

{ "recipient": "+256700000000, +256700000001, +256700000002", "message": "Hello everyone!" }

You can send to multiple recipients at once:

  • Separate phone numbers with commas: +256700000000, +256700000001
  • Spaces around commas are optional: +256700000000,+256700000001
  • Mix international and local formats: +256700000000, 0700000001
  • All numbers are automatically normalized to international format

Phone Number Requirements:

  • Must be valid Uganda phone numbers (starting with +256 or 256)
  • Must have exactly 9 digits after country code (e.g., +256700000000 = +256 + 700000000)
  • Invalid numbers will be rejected with a 422 error
  • Example valid: +256700000000, 256700000000
  • Example invalid: +25670000000 (too short), +1234567890 (wrong country)

Request Body Examples

Single recipient:

{ "recipient": "+256700000000", "message": "Hello, this is a test message!" }

Multiple recipients:

{ "recipient": "+256700000000, +256700000001, +256700000002", "message": "Hello everyone! This message will be sent to all three recipients." }

Long message (320 characters = 2 SMS units):

{ "recipient": "+256700000000", "message": "This is a longer message that exceeds 160 characters and will be sent as 2 SMS units. Each 160 characters equals 1 SMS unit, so this message will cost 2x the normal rate. Make sure you have sufficient balance!" }

Cost: 2 SMS units × cost_per_sms = Total cost

Success Response (200 OK)

When the SMS is successfully sent:

{ "success": true, "message": "SMS sent to 2/2 recipient(s)", "data": { "total_recipients": 2, "successful": 2, "failed": 0, "total_cost": 100, "currency": "UGX", "remaining_balance": 9900, "results": [ { "recipient": "+256700000000", "status": "sent", "transaction_id": "550e8400-e29b-41d4-a716-446655440000", "message_id": "ATXid_abc123xyz", "cost": 50 }, { "recipient": "+256700000001", "status": "sent", "transaction_id": "550e8400-e29b-41d4-a716-446655440001", "message_id": "ATXid_def456uvw", "cost": 50 } ] } }

Response Fields:

  • success - Boolean indicating if request succeeded
  • message - Human-readable status message
  • total_recipients - Total number of recipients
  • successful - Number of successful sends
  • failed - Number of failed sends
  • total_cost - Total cost deducted (UGX)
  • remaining_balance - Balance after deduction
  • results - Array of individual send results

Error Responses

401 - Unauthorized (Invalid Credentials)

{ "success": false, "message": "Invalid API credentials.", "error": "invalid_credentials" }

Check that your API key and secret are correct.

402 - Insufficient Balance

{ "success": false, "message": "Insufficient balance. Required: 100 UGX. Current balance: 50 UGX", "error": "insufficient_balance", "required": 100, "current_balance": 50, "currency": "UGX" }

Top up your account to continue sending messages.

422 - Validation Error (Invalid Recipients)

{ "success": false, "message": "Invalid phone number format(s): +25670000000, +1234567890", "error": "invalid_phone_numbers", "invalid_numbers": [ "+25670000000", "+1234567890" ] }

One or more phone numbers are invalid. Check the format and try again.

422 - Validation Error (Missing Fields)

{ "message": "The recipient field is required.", "errors": { "recipient": ["The recipient field is required."] } }

Ensure all required fields are provided.

500 - Server Error

{ "success": false, "message": "Failed to send SMS: Internal server error", "error": "send_failed" }

An unexpected error occurred. Try again or contact support.

Pro Tips:

  • Always check the remaining_balance in the response before sending more messages
  • Use the /api/v1/account/balance endpoint to check balance before bulk sends
  • Store the transaction_id for tracking and support purposes
  • Handle partial failures: Check successful vs failed counts
  • Long messages (160+ chars) cost more: 160 chars = 1 SMS, 161-320 chars = 2 SMS

Bulk SMS Upload via Excel

For sending SMS to multiple recipients at once, you can use the bulk upload feature through the web interface. This allows you to upload an Excel file with phone numbers and messages, making it easy to send personalized or bulk messages.

How to Use Bulk Upload:

  1. Navigate to Send SMS page in your dashboard
  2. Scroll down to the Bulk SMS Upload section
  3. Click Download Excel Template to get the template file
  4. Open the template in Excel or Google Sheets
  5. Fill in the phone numbers in column A (Phone Number)
  6. Fill in the messages in column B (Message), or leave messages column empty and use the optional override message field
  7. Save the file
  8. Upload the file using the upload form
  9. Optionally provide a message to override all messages in the file
  10. Click Upload and Send Bulk SMS

Excel File Format

The Excel file must follow this format:

Column A Column B
Phone Number Message
+256700000000 Hello! This is a test message.
+256700000001 Hello! This is another test message.

File Requirements

  • File formats: .xlsx, .xls, or .csv
  • Maximum file size: 10MB
  • First row: Must contain headers (Phone Number, Message)
  • Phone numbers: Must be valid Uganda phone numbers (e.g., +256700000000)
  • Messages: Maximum 320 characters per message
  • Empty rows: Will be automatically skipped
  • Invalid data: Rows with invalid phone numbers or messages will be skipped with a warning

Optional Message Override

If you want to send the same message to all recipients in your Excel file, you can:

  • Leave the Message column empty in your Excel file
  • Enter your message in the "Optional: Override Message" field
  • This message will be sent to all recipients listed in the file

Note: If you provide both messages in the Excel file and an override message, the override message will take precedence.

Best Practices:

  • Test with a small file first (5-10 recipients) before uploading large batches
  • Ensure your account has sufficient balance before uploading large files
  • Keep phone numbers in international format (+256) for best results
  • Review the success/warning messages after upload to see which rows were processed
  • Invalid rows are skipped automatically, so check your file format if many rows are skipped
  • For very large batches (1000+ recipients), consider splitting into multiple smaller files
GET /api/v1/account/balance

Check Account Balance

Get your current account balance and cost per SMS information. This endpoint requires authentication but no additional parameters.

Example Request

curl -X GET "https://sms.wearemarz.com/api/v1/account/balance" \ -u "YOUR_API_KEY:YOUR_API_SECRET"

Success Response (200 OK)

{ "success": true, "data": { "balance": 100000.00, "currency": "UGX", "cost_per_sms": 30.00 } }

Response Fields:

  • balance - Current account balance in UGX (decimal number)
  • currency - Always "UGX" for Uganda Shillings
  • cost_per_sms - Cost per SMS unit (may vary based on your package: Starter=30, Pro=29, Premium=28 UGX)

Error Response (401 - Unauthorized)

{ "success": false, "message": "Invalid API credentials.", "error": "invalid_credentials" }
GET /api/v1/sms/history

Get SMS History

Retrieve your SMS transaction history with pagination support. Results are sorted by most recent first.

Query Parameters

Parameter Type Required Default Description
page integer No 1 Page number to retrieve
per_page integer No 50 Items per page (max: 100)

Example Requests

Get first page (default):

curl -X GET "https://sms.wearemarz.com/api/v1/sms/history" \ -u "YOUR_API_KEY:YOUR_API_SECRET"

Get page 2 with 25 items per page:

curl -X GET "https://sms.wearemarz.com/api/v1/sms/history?page=2&per_page=25" \ -u "YOUR_API_KEY:YOUR_API_SECRET"

Success Response (200 OK)

{ "success": true, "data": { "transactions": [ { "uuid": "550e8400-e29b-41d4-a716-446655440000", "recipient": "+256700000000", "message": "Hello! This is a test message.", "status": "sent", "cost": 30.00, "currency": "UGX", "provider": "africastalking", "sent_at": "2025-11-02 14:30:00", "created_at": "2025-11-02 14:30:00" }, { "uuid": "550e8400-e29b-41d4-a716-446655440001", "recipient": "+256700000001", "message": "Another message", "status": "failed", "cost": 30.00, "currency": "UGX", "provider": "africastalking", "sent_at": null, "created_at": "2025-11-02 14:25:00" } ], "pagination": { "current_page": 1, "per_page": 50, "total": 150, "last_page": 3, "from": 1, "to": 50 } } }

Transaction Fields:

  • uuid - Unique transaction identifier
  • recipient - Phone number (international format)
  • message - The message content sent
  • status - Status: "sent", "delivered", "pending", or "failed"
  • cost - Cost in UGX (decimal)
  • provider - SMS provider used (usually "africastalking")
  • sent_at - Timestamp when SMS was sent (null if failed)
  • created_at - Timestamp when transaction was created

Error Response (401 - Unauthorized)

{ "success": false, "message": "Invalid API credentials.", "error": "invalid_credentials" }

Pricing

  • Cost per SMS: 50 UGX (or as configured per business)
  • Characters per SMS: 160 characters = 1 SMS unit
  • Long messages: Multiple SMS charges apply (e.g., 320 chars = 2 SMS = 100 UGX)

Error Codes

401 - Unauthorized

Invalid or missing API credentials. Check that your API key and secret are correct.

402 - Insufficient Balance

Account balance is too low to send SMS. Top up your account to continue sending messages.

422 - Validation Error

Invalid request parameters. Check that all required fields are provided and formatted correctly.

500 - Server Error

An internal server error occurred. Please try again later or contact support if the issue persists.

Need Help?

Our team is here to help you integrate MarzSMS into your application. Get in touch for technical support, custom integrations, or any questions.