TypeScript SDK
The official TypeScript SDK for Sent provides type-safe access to the entire Sent API. Built for modern Node.js applications with native ESM and CommonJS support, automatic retries, and comprehensive error handling.
Installation
npm install @sentdm/sentdmyarn add @sentdm/sentdmpnpm add @sentdm/sentdmbun add @sentdm/sentdmQuick Start
Initialize the client
import SentDm from '@sentdm/sentdm';
const client = new SentDm(); // Uses SENT_DM_API_KEY env var by defaultSend your first message
const response = await client.messages.send({
to: ['+1234567890'],
template: {
id: '7ba7b820-9dad-11d1-80b4-00c04fd430c8',
name: 'welcome',
parameters: {
name: 'John Doe'
}
}
});
console.log('Message sent:', response.data.messages[0].id);
console.log('Status:', response.data.messages[0].status);Authentication
The client can be configured using environment variables or explicitly:
import SentDm from '@sentdm/sentdm';
// Using environment variables (recommended)
// SENT_DM_API_KEY=your_api_key
const client = new SentDm();
// Or explicit configuration
const client = new SentDm({
apiKey: 'your_api_key',
});Send Messages
Send a message
const response = await client.messages.send({
to: ['+1234567890'],
template: {
id: '7ba7b820-9dad-11d1-80b4-00c04fd430c8',
name: 'welcome',
parameters: {
name: 'John Doe',
order_id: '12345'
}
},
channels: ['whatsapp', 'sms'] // Optional: defaults to template channels
});
console.log('Message ID:', response.data.messages[0].id);
console.log('Status:', response.data.messages[0].status);Test mode
Use testMode to validate requests without sending real messages:
const response = await client.messages.send({
to: ['+1234567890'],
template: {
id: '7ba7b820-9dad-11d1-80b4-00c04fd430c8',
name: 'welcome'
},
testMode: true // Validates but doesn't send
});
// Response will have test data
console.log('Validation passed:', response.data.messages[0].id);Handle errors
When the library is unable to connect to the API, or if the API returns a non-success status code (i.e., 4xx or 5xx response), a subclass of APIError will be thrown:
try {
const response = await client.messages.send({
to: ['+1234567890'],
template: {
id: '7ba7b820-9dad-11d1-80b4-00c04fd430c8',
name: 'welcome'
}
});
} catch (err) {
if (err instanceof SentDm.APIError) {
console.log(err.status); // 400
console.log(err.name); // BadRequestError
console.log(err.headers); // {server: 'nginx', ...}
} else {
throw err;
}
}Error codes are as follows:
| Status Code | Error Type |
|---|---|
| 400 | BadRequestError |
| 401 | AuthenticationError |
| 403 | PermissionDeniedError |
| 404 | NotFoundError |
| 422 | UnprocessableEntityError |
| 429 | RateLimitError |
| >=500 | InternalServerError |
| N/A | APIConnectionError |
Retries
Certain errors will be automatically retried 2 times by default, with a short exponential backoff. Connection errors, 408 Request Timeout, 409 Conflict, 429 Rate Limit, and >=500 Internal errors will all be retried by default.
// Configure the default for all requests:
const client = new SentDm({
maxRetries: 0, // default is 2
});
// Or, configure per-request:
await client.messages.send({
to: ['+1234567890'],
template: { id: 'welcome-template', name: 'welcome' }
}, {
maxRetries: 5,
});Timeouts
Requests time out after 1 minute by default. You can configure this with a timeout option:
// Configure the default for all requests:
const client = new SentDm({
timeout: 20 * 1000, // 20 seconds (default is 1 minute)
});
// Override per-request:
await client.messages.send({
to: ['+1234567890'],
template: { id: 'welcome-template', name: 'welcome' }
}, {
timeout: 5 * 1000,
});Contacts
Create and manage contacts:
// Create a contact
const contact = await client.contacts.create({
phoneNumber: '+1234567890',
});
console.log('Contact ID:', contact.data.id);
// List contacts
const contacts = await client.contacts.list({
limit: 100,
});
console.log('Total:', contacts.data.length);
// Get a contact
const contact = await client.contacts.get('contact-uuid');
// Update a contact
const updated = await client.contacts.update('contact-uuid', {
phoneNumber: '+1987654321',
});
// Delete a contact
await client.contacts.delete('contact-uuid');Templates
List and retrieve templates:
// List all templates
const templates = await client.templates.list();
for (const template of templates.data) {
console.log(`${template.name} (${template.status}): ${template.id}`);
}
// Get a specific template
const template = await client.templates.get('template-uuid');
console.log('Template name:', template.data.name);
console.log('Status:', template.data.status);Framework Integration
NestJS
See the NestJS Integration guide for complete dependency injection, module setup, and testing examples.
// messages/messages.service.ts
import { Injectable, Inject } from '@nestjs/common';
import SentDm from '@sentdm/sentdm';
import { SENT_CLIENT } from '../sent/sent.module';
@Injectable()
export class MessagesService {
constructor(
@Inject(SENT_CLIENT) private readonly sentClient: SentDm,
) {}
async sendWelcomeMessage(phoneNumber: string, name: string) {
const response = await this.sentClient.messages.send({
to: [phoneNumber],
template: {
id: 'welcome-template',
name: 'welcome',
parameters: { name }
}
});
return response.data.messages[0];
}
}Next.js (App Router)
See the Next.js Integration guide for complete Server Actions, Route Handlers, and Edge Runtime examples.
// app/api/send-message/route.ts
import SentDm from '@sentdm/sentdm';
import { NextResponse } from 'next/server';
const client = new SentDm();
export async function POST(request: Request) {
const { phoneNumber, templateId, variables } = await request.json();
try {
const response = await client.messages.send({
to: [phoneNumber],
template: {
id: templateId,
name: 'welcome',
parameters: variables
}
});
return NextResponse.json({
messageId: response.data.messages[0].id,
status: response.data.messages[0].status,
});
} catch (error) {
if (error instanceof SentDm.APIError) {
return NextResponse.json(
{ error: error.message },
{ status: error.status }
);
}
throw error;
}
}Express.js
See the Express.js Integration guide for complete dependency injection, validation, and structured logging examples.
import express from 'express';
import SentDm from '@sentdm/sentdm';
const app = express();
const client = new SentDm();
app.use(express.json());
app.post('/send-message', async (req, res) => {
const { phoneNumber, templateId, variables } = req.body;
try {
const response = await client.messages.send({
to: [phoneNumber],
template: {
id: templateId,
name: 'welcome',
parameters: variables
}
});
res.json({
success: true,
message: response.data,
});
} catch (error) {
if (error instanceof SentDm.APIError) {
res.status(error.status).json({ error: error.message });
} else {
res.status(500).json({ error: 'Internal server error' });
}
}
});
app.listen(3000);Logging
The log level can be configured via the SENT_DM_LOG environment variable or using the logLevel client option:
import SentDm from '@sentdm/sentdm';
const client = new SentDm({
logLevel: 'debug', // Show all log messages
});Available log levels: 'debug', 'info', 'warn' (default), 'error', 'off'
Source & Issues
- Version: 0.8.0
- GitHub: sentdm/sent-dm-typescript
- NPM: @sentdm/sentdm
- Issues: Report a bug
Getting Help
- Documentation: API Reference
- Troubleshooting: Common Issues
- Support: Email support@sent.dm with your request ID