API Reference
Complete reference for all SMSGist REST API endpoints. All requests go to https://api.smsgist.com.
Authentication
All API client routes require two authentication headers:
| Header | Description |
|---|---|
X-Client-Id | Your credential's client ID |
Authorization | Bearer <encrypted_token> |
The Bearer token is your client_secret encrypted with your app_secret_key using AES-256. The official SDKs handle this automatically — you only need your raw credentials.
# Headers required on every request
X-Client-Id: your_client_id
Authorization: Bearer <aes256_encrypted_token>
Content-Type: application/json
Idempotency
Append X-Idempotency-Key to any send request to prevent duplicate messages. If a request with the same key was already processed within 24 hours, the original response is returned without re-sending.
X-Idempotency-Key: your-unique-request-id
Common Response Format
All API responses share a consistent envelope:
{
"status": "success",
"message": "Human readable description",
"data": { ... }
}
On error, status is "error" and data is null:
{
"status": "error",
"message": "Insufficient credits",
"data": null
}
SMS
Send SMS
POST /api/sms/send
{
"recipients": ["+233245972246", "+233201234567"],
"message": "Your OTP is 482916",
"route": "regular"
}
| Field | Type | Required | Description |
|---|---|---|---|
recipients | string | string | Yes | Phone number(s) in E.164 format |
message | string | Yes | Message body |
route | string | No | regular (default) or otp for priority routing |
Response — HTTP 201
{
"status": "success",
"message": "SMS queued for sending successfully",
"data": {
"message_id": "7f3a2b9d-1e4c-4b2a-9d1e-4c7f3a2b9d1e",
"status": "queued",
"recipients_count": 2,
"segments": 1,
"total_cost": 0.06,
"cost_per_unit": 0.03,
"recipients": [
{ "recipient_id": "uuid-...", "recipient": "+233245972246" },
{ "recipient_id": "uuid-...", "recipient": "+233201234567" }
]
}
}
Send Email
POST /api/email/send
{
"recipients": ["user@example.com", "other@example.com"],
"subject": "Welcome to MyApp",
"body": "<h1>Hello!</h1><p>Thanks for signing up.</p>",
"from_name": "MyApp Team",
"reply_to": "support@myapp.com",
"no_tracking": false
}
| Field | Type | Required | Description |
|---|---|---|---|
recipients | string | string | Yes | Email address(es) |
subject | string | Yes | Email subject line |
body | string | Yes | Email body (HTML supported) |
from_name | string | No | Display name for the sender |
reply_to | string | No | Reply-to email address |
no_tracking | boolean | No | Disable open/click tracking (default: false) |
route | string | No | regular (default) or otp |
Response — HTTP 201
{
"status": "success",
"message": "Email queued for sending successfully",
"data": {
"message_id": "9c4d3e2f-8a7b-6c5d-4e3f-2a1b0c9d8e7f",
"status": "queued",
"recipients_count": 2,
"segments": 0,
"total_cost": 0.002,
"cost_per_unit": 0.001,
"recipients": [
{ "recipient_id": "uuid-...", "recipient": "user@example.com" },
{ "recipient_id": "uuid-...", "recipient": "other@example.com" }
]
}
}
Message Status
Get Message Status
GET /api/message/{id}/status
Returns the overall status and per-recipient delivery details for any message sent through this credential.
Response — HTTP 200
{
"status": "success",
"message": "Action performed successfully",
"data": {
"message_id": "7f3a2b9d-1e4c-4b2a-9d1e-4c7f3a2b9d1e",
"service": "sms",
"status": "sent",
"total_recipients": 2,
"delivered": 1,
"pending": 0,
"failed": 1,
"sent_at": "2026-03-21T10:28:00Z",
"recipients": [
{
"recipient_id": "uuid-...",
"recipient": "+233245972246",
"send_status": "sent",
"delivery_status": "DELIVERED",
"delivered_at": "2026-03-21T10:30:15Z",
"error_message": null
},
{
"recipient_id": "uuid-...",
"recipient": "+233201234567",
"send_status": "failed",
"delivery_status": "FAILED",
"delivered_at": null,
"error_message": "Number not reachable"
}
]
}
}
Retry Failed Message
POST /api/message/{id}/retry
Retries delivery to failed recipients only. Only messages with status: "failed" can be retried.
Response — HTTP 201
{
"status": "success",
"message": "Message re-queued successfully",
"data": {
"message_id": "new-uuid-for-retry",
"original_message_id": "7f3a2b9d-1e4c-4b2a-9d1e-4c7f3a2b9d1e",
"status": "queued",
"recipients_count": 1,
"total_cost": 0.03
}
}
Credits
Get Credit Balance
GET /api/credits/balance
Returns the credit balance for the credential or its parent app/organization.
Response — HTTP 200
{
"status": "success",
"message": "Action performed successfully",
"data": {
"balance": 125.50,
"reserved": 0.06,
"available": 125.44,
"currency": "GHS"
}
}
| Field | Description |
|---|---|
balance | Total balance |
reserved | Credits reserved for in-flight messages |
available | Spendable balance (balance - reserved) |
currency | Always GHS |
Error Codes
| HTTP Status | Meaning |
|---|---|
400 | Bad request — missing or invalid parameters |
401 | Authentication failed — check your X-Client-Id and token |
402 | Insufficient credits |
404 | Resource not found |
422 | Validation error — see message field |
429 | Rate limit exceeded |
500 | Server error — please retry |
Credential Modes
Your credential can be in one of three modes. Set it in the dashboard under your credential settings.
| Mode | Behaviour |
|---|---|
live | Messages are sent to real recipients and credits are deducted |
test | Messages are redirected to your configured test phone/email |
dryrun | Messages go through the full pipeline but are never submitted to a carrier — no credits deducted |
