Sending SMS
Learn how to send SMS messages using the MsGine SDK.
Basic Usage
Send a simple SMS message:
typescript
import { MsGineClient } from '@msgine/sdk';
const client = new MsGineClient({
apiKey: process.env.MSGINE_API_KEY!,
})
const result = await client.sms.send({
to: '+256701521269',
message: 'Hello from MsGine!'
})
console.log('Message sent:', result.id)Parameters
to (required)
Type: string | string[]
The recipient's phone number(s) in E.164 format.
typescript
// Single recipient
await client.sms.send({
to: '+256701521269', // ✅ Correct
message: 'Hello!'
})
// Multiple recipients
await client.sms.send({
to: ['+256701521269', '+256701234567'],
message: 'Hello!'
})
// ❌ Incorrect formats:
// to: '0701521269' // Missing country code
// to: '256701521269' // Missing + prefixmessage (required)
Type: string (max 1000 characters)
The message content to send.
typescript
await client.sms.send({
to: '+256701521269',
message: 'Your verification code is 123456'
})Message Length
- Standard SMS: Up to 160 characters per part
- Unicode/Emoji: Up to 70 characters per part
- Maximum: 1000 characters total
from (optional)
Type: string (max 11 characters)
Custom sender ID displayed to recipients.
typescript
await client.sms.send({
to: '+256701521269',
from: 'MyApp',
message: 'Hello from MyApp!'
})callbackUrl (optional)
Type: string
Webhook URL to receive delivery status updates.
typescript
await client.sms.send({
to: '+256701521269',
message: 'Hello!',
callbackUrl: 'https://your-app.com/webhooks/msgine'
})Response
The sms.send() method returns a promise that resolves to a SendSmsResponse:
typescript
{
id: "msg_1234567890", // Unique message identifier
sid: "SM1234567890", // Provider-specific ID
channel: "sms", // Message channel
to: ["+256701521269"], // Recipients
from: "MsGine", // Sender ID
content: "Hello from MsGine!", // Message content
status: "pending", // Message status
cost: 30, // Cost in UGX
currency: "UGX", // Currency
createdAt: "2024-01-15T10:30:00Z",
updatedAt: "2024-01-15T10:30:01Z"
}Message Statuses
| Status | Description |
|---|---|
pending | Message is queued for delivery |
sent | Message has been sent to the carrier |
delivered | Message was successfully delivered |
failed | Message delivery failed |
Examples
Send a Verification Code
typescript
async function sendVerificationCode(phoneNumber: string, code: string) {
const result = await client.sms.send({
to: phoneNumber,
message: `Your verification code is ${code}. Valid for 10 minutes.`
})
return result.id
}
const messageId = await sendVerificationCode('+256701521269', '123456')Send a Notification
typescript
async function sendNotification(phoneNumber: string, message: string) {
try {
const result = await client.sms.send({
to: phoneNumber,
message
})
if (result.status === 'pending' || result.status === 'sent') {
console.log('✅ Notification sent successfully')
return true
}
return false
} catch (error) {
console.error('❌ Failed to send notification:', error)
return false
}
}Send with Error Handling
typescript
import { MsGineClient, MsGineError, MsGineValidationError } from '@msgine/sdk'
async function sendSmsWithErrorHandling(to: string, message: string) {
try {
const result = await client.sms.send({ to, message })
return { success: true, data: result }
} catch (error) {
if (error instanceof MsGineValidationError) {
// Input failed validation before reaching the API
console.error('Validation failed:', error.message)
if (error.field) console.error('Field:', error.field)
return { success: false, error: 'Invalid input' }
}
if (error instanceof MsGineError) {
// API returned an error
console.error('API error:', error.message)
console.error('Status:', error.statusCode)
return { success: false, error: error.message }
}
// Handle unexpected errors
console.error('Unexpected error:', error)
return { success: false, error: 'Unknown error' }
}
}Phone Number Formatting
E.164 Format
All phone numbers must be in E.164 format:
+[country code][subscriber number]Examples:
typescript
'+256701521269' // Uganda
'+1555123456' // United States
'+447911123456' // United Kingdom
'+33123456789' // FranceCommon Mistakes
typescript
// ❌ Missing country code
to: '0701521269'
// ❌ Missing + prefix
to: '256701521269'
// ❌ Contains spaces or hyphens
to: '+256 70 152 1269'
to: '+256-70-152-1269'
// ✅ Correct format
to: '+256701521269'Message Content
Character Limits
- Standard SMS: 160 characters per part
- Unicode/Emoji: 70 characters per part
- Maximum: 1000 characters
Long Messages
Messages longer than 160 characters are automatically split into parts:
typescript
await client.sms.send({
to: '+256701521269',
message: 'This is a longer message that will be split...'
})
// Charged per part — check the `cost` field in the responseBest Practices
1. Validate Phone Numbers
Always validate phone numbers before sending:
typescript
function isValidE164(phoneNumber: string): boolean {
const e164Regex = /^\+[1-9]\d{1,14}$/
return e164Regex.test(phoneNumber)
}
if (isValidE164(phoneNumber)) {
await client.sms.send({ to: phoneNumber, message })
}2. Handle Errors Gracefully
Always wrap API calls in try-catch:
typescript
try {
const result = await client.sms.send({ to, message })
// Handle success
} catch (error) {
// Handle error
}3. Keep Messages Concise
Shorter messages are:
- Cheaper (one part vs multiple)
- Faster to read
- More likely to be read completely
typescript
// ✅ Good: Concise and clear
"Your code: 123456. Valid for 10 min."
// ❌ Too verbose
"Hello! Thank you for using our service. Your verification code is 123456. Please note that this code will expire in 10 minutes from now."4. Use Environment Variables
Never hardcode sensitive data:
typescript
// ✅ Good
const client = new MsGineClient({
apiKey: process.env.MSGINE_API_KEY!,
})
// ❌ Bad
const client = new MsGineClient({
apiKey: 'sk_live_1234567890'
})Next Steps
- Batch Messaging - Send to multiple recipients
- Error Handling - Handle errors properly
- REST API Reference - Direct API integration