Skip to main content

SMS

Send SMS messages via the SMPP channel. Two sending patterns are available:

  • Transactional — Create a long-lived campaign, then add messages one at a time (OTP, notifications, alerts)
  • Promotional — Send to many recipients in a single request (marketing, offers, newsletters)
SMS Sender ID Required

Your company must have an approved SMS Sender ID before sending SMS messages. This is the alphanumeric name (max 11 characters, e.g., "MyBrand") that appears as the sender on recipients' phones. Register SMS senders in Dashboard → Channels → SMS — they require administrator approval before use. You can also list your approved senders via GET /api/v1/sms-senders.

When using the External API, set smsSenderId on your SMS template at creation time. The sender ID flows from the template to campaigns automatically.


Create Transactional Campaign

Create a long-lived SMS campaign for transactional messages. The campaign stays in InProgress status and accepts messages indefinitely.

POST /api/v1/sms/campaigns

Request Body

{
"name": "Order Notifications",
"description": "Real-time order status updates",
"templateId": "550e8400-e29b-41d4-a716-446655440000"
}

Parameters

FieldTypeRequiredDescription
namestringYesCampaign name (max 200 chars)
descriptionstringNoCampaign description (max 1000 chars)
templateIdUUIDYesID of an SMS template
note

The template must be an SMS (SMPP) template. Viber templates will be rejected with a 400 error.

Response

{
"campaignId": "660e8400-e29b-41d4-a716-446655440001",
"name": "Order Notifications",
"status": "InProgress",
"createdAt": "2024-01-15T10:30:00Z"
}

Example

curl -X POST https://api.transformify.mk/api/v1/sms/campaigns \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"name": "Order Notifications",
"description": "Real-time order status updates",
"templateId": "550e8400-e29b-41d4-a716-446655440000"
}'

Add Message to Campaign

Add a single message to a transactional SMS campaign. The message is queued for immediate processing.

POST /api/v1/sms/campaigns/{id}/messages

Path Parameters

ParameterTypeDescription
idUUIDCampaign ID

Request Body

{
"phoneNumber": "38970123456",
"externalUserId": "order_12345",
"placeholders": {
"orderId": "ORD-12345",
"status": "Shipped"
}
}

Parameters

FieldTypeRequiredDescription
phoneNumberstringYesRecipient phone number (optional + prefix, 10-15 digits; regex: ^\+?\d{10,15}$)
externalUserIdstringNoYour identifier for tracking
placeholdersobjectNoTemplate substitution values

Response

{
"messageId": "770e8400-e29b-41d4-a716-446655440002",
"campaignId": "660e8400-e29b-41d4-a716-446655440001",
"phoneNumber": "38970123456",
"status": "Pending",
"queuedAt": "2024-01-15T10:31:00Z"
}
Message Statuses

Messages progress through these statuses: Pending -> Sending -> Sent -> Delivered or Failed.

Example

curl -X POST https://api.transformify.mk/api/v1/sms/campaigns/660e8400-e29b-41d4-a716-446655440001/messages \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "38970123456",
"externalUserId": "order_12345",
"placeholders": {
"orderId": "ORD-12345",
"status": "Shipped"
}
}'

Send Promotional SMS

Send bulk promotional SMS messages to a list of recipients in a single request. Returns immediately while messages are prepared asynchronously. Once the campaign reaches Ready status, call POST /api/v1/campaigns/{id}/start to begin delivery.

POST /api/v1/sms/promotional

Request Body

{
"templateId": "550e8400-e29b-41d4-a716-446655440000",
"recipients": [
{
"phoneNumber": "38970111111",
"externalUserId": "customer_001",
"placeholders": { "name": "John", "promoCode": "JOHN20" }
},
{
"phoneNumber": "38970222222",
"placeholders": { "name": "Jane", "promoCode": "JANE20" }
}
],
"placeholders": {
"companyName": "Acme Corp"
}
}

Parameters

FieldTypeRequiredDescription
templateIdUUIDYesID of an SMS template
recipientsarrayYesList of recipients
recipients[].phoneNumberstringYesPhone number (optional + prefix, 10-15 digits; regex: ^\+?\d{10,15}$)
recipients[].externalUserIdstringNoYour identifier for tracking
recipients[].placeholdersobjectNoPer-recipient template placeholders
placeholdersobjectNoDefault placeholders (fallback for recipients without their own)
note

The template must be an SMS (SMPP) template. Viber templates will be rejected with a 400 error.

Response

{
"campaignId": "660e8400-e29b-41d4-a716-446655440001",
"messageCount": 50000,
"status": "Queuing",
"queuedAt": "2024-01-15T10:30:00Z",
"message": "Campaign accepted. 50000 recipients are being queued for insertion. Poll GET /api/v1/campaigns/{id} for status, then call POST /api/v1/campaigns/{id}/start when Ready."
}

Async Flow

For large sends, the API returns 202 Accepted immediately while messages are prepared in the background. Follow this three-step flow:

Step 1 — Send (POST /api/v1/sms/promotional)
Returns 202 with status: "Queuing" and a campaignId.

Step 2 — Poll until Ready (GET /api/v1/campaigns/{id})
Poll the campaign until status changes from QueuingReady.

Step 3 — Start delivery (POST /api/v1/campaigns/{id}/start)
When the campaign is Ready, call this endpoint to begin message delivery. The status moves to InProgress.

POST /api/v1/sms/promotional      → 202, campaignId, status: "Queuing"
GET /api/v1/campaigns/{id} → poll until status: "Ready"
POST /api/v1/campaigns/{id}/start → status: "InProgress", delivery begins

Example

curl -X POST https://api.transformify.mk/api/v1/sms/promotional \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"templateId": "550e8400-e29b-41d4-a716-446655440000",
"recipients": [
{
"phoneNumber": "38970111111",
"placeholders": { "name": "John", "promoCode": "JOHN20" }
},
{
"phoneNumber": "38970222222",
"placeholders": { "name": "Jane", "promoCode": "JANE20" }
}
],
"placeholders": { "companyName": "Acme Corp" }
}'

Send SMS

Send SMS messages without creating a template. Provide raw message content, an approved SMS Sender ID, and a list of recipients.

POST /api/v1/sms/send

Request Body

{
"messageContent": "Your order #12345 has been shipped!",
"smsSenderId": 1,
"recipients": [
{
"phoneNumber": "38970123456",
"externalUserId": "customer_001"
},
{
"phoneNumber": "38970123457"
}
]
}

Parameters

FieldTypeRequiredDescription
messageContentstringYesSMS message text (1-1,600 characters, no placeholders)
smsSenderIdintegerYesID of an approved SMS Sender (see GET /api/v1/sms-senders)
recipientsarrayYesList of recipients
recipients[].phoneNumberstringYesPhone number (optional + prefix, 10-15 digits)
recipients[].externalUserIdstringNoYour identifier for tracking (max 100 chars)
note

The SMS Sender must belong to your company and have Approved status. Use GET /api/v1/sms-senders to list your available senders.

Response

{
"campaignId": "660e8400-e29b-41d4-a716-446655440001",
"messageCount": 2,
"skippedCount": 0,
"invalidPhoneNumbers": [],
"status": "Pending",
"queuedAt": "2024-01-15T10:30:00Z",
"message": "2 messages queued for delivery."
}

Response Fields

FieldTypeDescription
campaignIdUUIDCampaign identifier for tracking
messageCountintegerNumber of valid recipients accepted
skippedCountintegerNumber of invalid phone numbers skipped
invalidPhoneNumbersarrayList of skipped invalid phone numbers
statusstringAlways Pending — messages are queued for immediate processing
queuedAtdatetimeWhen the request was accepted
messagestringSummary including count of any skipped numbers

Example

curl -X POST https://api.transformify.mk/api/v1/sms/send \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"messageContent": "Your order #12345 has been shipped!",
"smsSenderId": 1,
"recipients": [
{ "phoneNumber": "38970123456", "externalUserId": "customer_001" },
{ "phoneNumber": "38970123457" }
]
}'

Errors

StatusErrorDescription
400Invalid template channel typeTemplate is not an SMS (SMPP) template
400No valid phone numbersAll recipient phone numbers are invalid
400Too many recipientsExceeds maximum recipients per request
400Campaign is not activeCampaign status is not InProgress
400Cannot add messages to bulk campaignCampaign is not transactional
400Campaign is not an SMS campaignCampaign channel type is not SMPP
400Invalid SMS SenderSender ID not found, not approved, or wrong company (direct send)
401UnauthorizedInvalid API key
404Not FoundTemplate or campaign not found
429Too many pending messagesPending message capacity exceeded