Send SMS Message
Send a single SMS message to one recipient
Endpoint
POST /api/sms/messagesRequest body
| Field | Type | Required | Description |
|---|---|---|---|
message | string | Yes | Non-empty SMS message content. The API does not currently enforce a fixed character limit |
sender | string | Yes | Sender ID (max 11 alphanumeric chars) |
payment_type | string | Yes | wallet or subscription |
receiver | string | Yes | Phone number matching a provider pattern configured in the platform (e.g., 00218912345678) |
expires_after | integer | No | Seconds this message stays worth delivering, 60–604800. Defaults to 24 hours. Undelivered recipients are then marked expired and refunded — see Message validity |
Headers
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer YOUR_API_TOKEN |
Content-Type | Yes | application/json |
Accept | Yes | application/json — without it, validation errors are not returned as JSON |
Idempotency-Key | No | Replaying the same key with the same body returns the original result instead of sending again |
Example
curl -X POST https://sms.lamah.com/api/sms/messages \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"message": "Your appointment is confirmed for Tuesday at 4:30 PM.",
"sender": "MyBusiness",
"payment_type": "wallet",
"receiver": "00218912345678"
}'Response
{
"message_id": "b9e8a1f2-4c60-4b0b-9f51-0c4f2f6c9e7a",
"cost": 1
}| Field | Description |
|---|---|
message_id | UUID for this send — use it with Get Message |
cost | Number of SMS parts charged for this send |
A 200 means the message was accepted and your balance reserved, not that it has been handed to the network. Delivery happens asynchronously — poll Get Message for status.
Error responses
422 Unprocessable Entity — Validation failed
Returned when a field is missing or invalid, including an unrecognised phone number format.
{
"message": "The receiver must be valid in system providers.",
"errors": {
"receiver": ["The receiver must be valid in system providers."]
}
}404 Not Found — Sender not found
The sender ID is unknown, inactive, or not linked to your company.
{ "message": "Sender not found" }400 Bad Request — Provider mismatch
The receiver's network is not one the sender ID is registered on. This is a permanent mismatch — retrying will not help.
{ "message": "The receiver is not from the same provider" }400 Bad Request — Insufficient balance
{ "message": "Insufficient balance" }401 Unauthorized
{ "message": "Invalid or missing token." }409 Conflict — Idempotency key reused
{ "message": "Idempotency key is already in use" }503 Service Unavailable — Provider temporarily unavailable
The receiver's network operator is one your sender ID is registered on, but it is temporarily unreachable. Nothing is sent and nothing is charged.
{ "message": "The provider for this receiver is temporarily unavailable" }Distinguish this from the 400 above by status code: 400 means the pairing will never work, 503 means the same request will work once the operator is restored. Sends to other operators are unaffected.
503 Service Unavailable — Ingest unavailable
Transient — retry with backoff and the same Idempotency-Key.
{ "message": "SMS ingest unavailable" }If your company is not yet verified, receiver is overridden with your company's registered phone number. The request still returns 200 and still consumes balance.
GSM-7 messages use up to 160 characters in one SMS part. Unicode messages, including Arabic, use up to 70 characters in one part. For providers with multipart splitting enabled, longer messages use up to 153 GSM-7 characters or 67 Unicode characters per part; otherwise the calculation remains 160 or 70 characters per part. Billing is based on the calculated number of parts.