Batch Messaging
Send the same message to multiple recipients in a single API call.
Overview
The MsGine SDK supports sending to multiple recipients by passing an array to the to parameter of client.sms.send(). A single API call handles all recipients — no looping required.
Basic Usage
typescript
import { MsGineClient } from '@msgine/sdk';
const client = new MsGineClient({
apiKey: process.env.MSGINE_API_KEY!,
});
const result = await client.sms.send({
to: ['+256701521269', '+256701521270', '+256701521271'],
message: 'Hello from MsGine!',
});
console.log('Message ID:', result.id);
console.log('Recipients:', result.to.length);
console.log('Status:', result.status);
console.log('Cost:', result.cost, result.currency);Response
typescript
{
id: "msg_1234567890",
channel: "sms",
to: ["+256701521269", "+256701521270", "+256701521271"],
from: "MsGine",
content: "Hello from MsGine!",
status: "pending",
cost: 90, // 30 UGX × 3 recipients
currency: "UGX",
createdAt: "2024-01-15T10:30:00Z"
}Examples
Broadcast Notification
typescript
async function notify(phones: string[], message: string) {
const result = await client.sms.send({ to: phones, message });
console.log(`Sent to ${result.to.length} recipients. Cost: ${result.cost} ${result.currency}`);
return result;
}
await notify(
['+256701521269', '+256701521270', '+256701521271'],
'System maintenance tonight at 10 PM'
);With Error Handling
typescript
import { MsGineClient, MsGineError, MsGineValidationError } from '@msgine/sdk';
async function broadcastSafely(phones: string[], message: string) {
try {
const result = await client.sms.send({ to: phones, message });
return { success: true, messageId: result.id, cost: result.cost };
} catch (error) {
if (error instanceof MsGineValidationError) {
console.error('Validation failed:', error.message);
if (error.field) console.error('Field:', error.field);
return { success: false, error: 'Invalid input' };
}
if (error instanceof MsGineError) {
console.error('API error:', error.message);
return { success: false, error: error.message };
}
return { success: false, error: 'Unknown error' };
}
}Personalized Messages
To send a different message to each recipient, make separate calls:
typescript
interface User {
phone: string;
name: string;
code: string;
}
async function sendVerificationCodes(users: User[]) {
const results = await Promise.all(
users.map(user =>
client.sms.send({
to: user.phone,
message: `Hi ${user.name}, your code is ${user.code}. Expires in 10 minutes.`,
})
)
);
return results.map((result, i) => ({
user: users[i],
messageId: result.id,
status: result.status,
}));
}
const users = [
{ phone: '+256701521269', name: 'Alice', code: '123456' },
{ phone: '+256701521270', name: 'Bob', code: '789012' },
];
await sendVerificationCodes(users);Large Recipient Lists
For very large lists, send in chunks to stay within rate limits:
typescript
async function sendInChunks(phones: string[], message: string, chunkSize = 100) {
const results = [];
for (let i = 0; i < phones.length; i += chunkSize) {
const chunk = phones.slice(i, i + chunkSize);
const result = await client.sms.send({ to: chunk, message });
results.push(result);
console.log(`Sent chunk ${Math.floor(i / chunkSize) + 1}/${Math.ceil(phones.length / chunkSize)}`);
// Pace requests to avoid rate limits
if (i + chunkSize < phones.length) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
return results;
}Best Practices
Validate Phone Numbers First
typescript
function isValidE164(phone: string): boolean {
return /^\+[1-9]\d{1,14}$/.test(phone);
}
const validPhones = phones.filter(p => {
if (!isValidE164(p)) {
console.warn(`Skipping invalid number: ${p}`);
return false;
}
return true;
});
if (validPhones.length > 0) {
await client.sms.send({ to: validPhones, message });
}Track Costs
typescript
const result = await client.sms.send({ to: phones, message });
console.log(`Total cost: ${result.cost} ${result.currency}`);Rate Limits
The API allows 100 requests per minute per API key. For high-volume campaigns, pace your requests or contact support for increased limits.
Next Steps
- Error Handling - Handle errors gracefully
- Best Practices - Optimization tips
- REST API Reference - Direct API integration