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({
  apiToken: process.env.MSGINE_API_TOKEN!
})

const result = await client.sendSms({
  to: '+256701521269',
  message: 'Hello from MsGine!'
})

console.log('Message sent:', result.id)

Parameters

to (required)

Type: string

The recipient's phone number in E.164 format.

typescript
await client.sendSms({
  to: '+256701521269',  // ✅ Correct
  message: 'Hello!'
})

// ❌ Incorrect formats:
// to: '0701521269'     // Missing country code
// to: '256701521269'   // Missing + prefix

message (required)

Type: string (max 1600 characters)

The message content to send.

typescript
await client.sendSms({
  to: '+256701521269',
  message: 'Your verification code is 123456'
})

Message Length

  • Standard SMS: Up to 160 characters
  • Long SMS: Up to 1600 characters (sent as multiple parts)
  • Unicode/Emoji: Up to 70 characters per part

Response

The sendSms 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: 0.05,                     // Cost in currency
  currency: "USD",                // Currency code
  createdAt: "2024-01-15T10:30:00Z",  // ISO 8601 timestamp
  updatedAt: "2024-01-15T10:30:01Z"   // ISO 8601 timestamp
}

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.sendSms({
    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.sendSms({
      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.sendSms({ to, message })
    return { success: true, data: result }
  } catch (error) {
    if (error instanceof MsGineValidationError) {
      // Handle validation errors
      console.error('Validation failed:', error.message)
      console.error('Details:', error.errors.issues)
      return { success: false, error: 'Invalid input' }
    }

    if (error instanceof MsGineError) {
      // Handle API errors
      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
  • Unicode/Emoji: 70 characters per part
  • Maximum: 1600 characters (10 parts)

Special Characters

Unicode characters and emojis count as multiple characters:

typescript
// Standard: 1 character each
"Hello" // 5 characters

// Unicode: 2 characters each
"Hello 👋" // 7 characters (6 + 2 for emoji)

Long Messages

Messages longer than 160 characters are automatically split:

typescript
await client.sendSms({
  to: '+256701521269',
  message: 'This is a very long message that exceeds 160 characters and will be automatically split into multiple parts by the carrier. The recipient will receive it as a single message.'
})
// This will be sent as 2 SMS parts

TIP

You're charged for each part of a long message. 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.sendSms({ to: phoneNumber, message })
}

2. Handle Errors Gracefully

Always wrap API calls in try-catch:

typescript
try {
  const result = await client.sendSms({ 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({
  apiToken: process.env.MSGINE_API_TOKEN!
})

// ❌ Bad
const client = new MsGineClient({
  apiToken: 'sk_live_1234567890'
})

Next Steps

Released under the MIT License.