Skip to content

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 + prefix

message (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!'
})

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 ​

StatusDescription
pendingMessage is queued for delivery
sentMessage has been sent to the carrier
deliveredMessage was successfully delivered
failedMessage 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'   // France

Common 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 response

Best 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 ​

Released under the MIT License.