Frequently Asked Questions
Set up a new NestJS project, install the MessageBird Node.js SDK, configure environment variables for your API key and originator, create an SMS service and controller, define a DTO for validation, and implement the API endpoint logic to send SMS messages via the MessageBird API. Don't forget to properly handle errors and secure your API keys, and consider using a service like pm2
upon deployment.
It simplifies interaction with the MessageBird REST API, making it easier to send SMS messages and access other MessageBird services within your Node.js or NestJS applications. It handles API requests and responses, reducing the amount of manual coding required.
Dependency injection in NestJS makes managing dependencies, like the MessageBird service and configuration variables, cleaner and more efficient. It promotes modularity and testability by allowing you to easily swap out real implementations with mocks during testing.
The MessageBird Verify API is recommended over basic SMS sending for OTP-based authentication and verification, as it's specifically designed for that purpose. For basic alerts, notifications, or two-factor authentication, SMS is suitable.
Yes, you can register an alphanumeric sender ID (e.g., 'MyCompany') with MessageBird and use it as the originator for SMS messages. Keep in mind that country-specific regulations apply and must be adhered to.
Create a .env
file in your project's root directory. Add your MessageBird API key (live or test) and originator (phone number or alphanumeric ID) to this file as environment variables (MESSAGEBIRD_API_KEY
and MESSAGEBIRD_ORIGINATOR
). Import and configure ConfigModule
in app.module.ts
to access them in your application via ConfigService
.
The recommended structure includes an SMS module that houses an SMS service and controller. A DTO (Data Transfer Object) is defined to validate incoming requests to the controller's API endpoint (POST /sms/send
). These components interact to handle SMS sending logic, validation, and API requests.
These libraries simplify validation and transformation in NestJS. class-validator
provides decorators for defining validation rules on DTOs. class-transformer
transforms plain JavaScript objects into class instances, applying the validation rules seamlessly.
Use npm run start:dev
to start the server and send test requests using a tool like curl
or Postman to the /sms/send
endpoint. You can also write unit tests for your SMS service using the NestJS testing framework, mocking the MessageBird SDK and ConfigService
to isolate your tests.
Common errors include "Authentication failed" (incorrect API key), "message could not be sent because the originator is invalid" (incorrect sender ID), "Request parameter validation failed" (invalid recipient format), and "No (suitable) routes found" (insufficient balance or coverage issues). Thorough logging and error handling help address them.
Use try...catch
blocks to handle errors from the MessageBird SDK. Log errors using Logger
to track failures and issues. For API errors, throw HttpException
to return meaningful HTTP responses to clients (e.g., 500 Internal Server Error or 400 Bad Request), including specific details from the error response if possible.
Never hardcode API keys in your code. Store them in a .env
file (and add it to .gitignore
), and use environment variables or secure configuration services, especially in production deployments. Do not commit API keys to version control. Rotating keys regularly enhances security.
Implement rate limiting using @nestjs/throttler
to prevent abuse. Use input validation with class-validator
to prevent injection attacks. For public-facing APIs, add authentication mechanisms like JWT to protect the endpoint.
The ValidationPipe
in NestJS automatically validates incoming requests against the defined DTOs, ensuring data integrity and security. It returns 400 Bad Request errors for invalid input and transforms plain objects into DTO instances, applying the validation rules.
Build your application using npm run build
, creating a dist
folder with optimized code. Deploy this folder, along with necessary dependencies and configuration files, to your hosting environment. Manage the process in production using tools like pm2
or platform-specific mechanisms. Ensure environment variables are set securely in the production environment, and do not include the .env
file in the deployment.
Send SMS with MessageBird in NestJS: Complete Integration Guide
This guide provides a step-by-step walkthrough for building a production-ready NestJS application capable of sending SMS messages using the MessageBird API and its Node.js SDK. We will cover project setup, core implementation, configuration, error handling, security, testing, and deployment considerations.
By the end of this guide, you will have a robust API endpoint that accepts a recipient phone number and a message body, validates the input, and uses MessageBird to reliably deliver the SMS. This solves the common need for programmatic SMS notifications, alerts, or basic communication features within a modern web application.
Time to Complete: 30-45 minutes Skill Level Required: Intermediate (familiarity with TypeScript, Node.js, REST APIs, and basic NestJS concepts)
Project Overview and Goals
Goal: Create a simple NestJS API endpoint (
POST /sms/send
) to send outbound SMS messages via MessageBird.Problem Solved: Enables applications to programmatically send SMS messages for various purposes like notifications, verification codes (though MessageBird's Verify API is often better suited for OTP), or simple alerts.
Common Use Cases:
Cost Implications: MessageBird operates on a prepaid model with per-message pricing that varies by destination country. Typical costs range from $0.02-$0.10 per SMS depending on the country. Free trial accounts receive 10 test SMS credits that can only send to your verified phone number (source).
Technologies:
npm install messagebird
.forbidUnknownValues
fromfalse
totrue
, which may affect existing implementations.Architecture:
Prerequisites:
originator
. Important: Some countries (e.g., United States) prohibit alphanumeric sender IDs and require a numeric phone number. See MessageBird's sender ID documentation for country-specific restrictions.1. Setting up the Project
Let's initialize our NestJS project and install the necessary dependencies.
Install NestJS CLI: If you don't have it, install the NestJS command-line interface globally.
Create New NestJS Project: Generate a new project using the CLI.
Choose your preferred package manager (npm or yarn) when prompted.
Navigate to Project Directory:
Install Dependencies: We need the MessageBird SDK, and packages for configuration management and validation.
messagebird
: The official Node.js SDK for the MessageBird API.@nestjs/config
: Handles environment variables gracefully within NestJS.dotenv
: Loads environment variables from a.env
file intoprocess.env
. Used by@nestjs/config
.class-validator
&class-transformer
: Enable easy implementation of validation rules using decorators on DTOs (Data Transfer Objects).Package Version Compatibility:
Common Installation Troubleshooting:
node -v
. MessageBird SDK requires Node.js >= 0.10, but NestJS requires Node.js >= 14.x. Upgrade Node.js if needed using nvm or download from nodejs.org.sudo npm install -g @nestjs/cli
on macOS/Linux or run your terminal as administrator on Windows. Alternatively, configure npm to use a user-level directory for global packages.npm cache clean --force
and deletenode_modules
andpackage-lock.json
, then reinstall.Project Structure: The Nest CLI sets up a standard structure (
src/
containsapp.module.ts
,app.controller.ts
,app.service.ts
,main.ts
). We will create dedicated modules, services, and controllers for SMS functionality.2. Configuring Environment Variables
Sensitive information like API keys should never be hardcoded. We'll use environment variables.
Get MessageBird API Key:
Developers
section in the left-hand menu.API access
.test_
): Simulate SMS sending without actual delivery or charges. Messages appear as "sent" but no real SMS is delivered.live_
): Send actual messages, consume account balance, and deliver to real phone numbers. Requires a topped-up prepaid balance.Get MessageBird Originator:
+12025550134
). Ensure it's SMS-enabled.MyCompany
) registered and approved in your MessageBird account. Note: Alphanumeric sender IDs are subject to country-specific regulations and restrictions. For example, the United States requires numeric phone numbers and does not allow alphanumeric originators. Pre-registration may be required in certain countries.Create
.env
File: In the root directory of your project, create a file named.env
.Add Variables to
.env
: Add your MessageBird API key and originator to the file. Replace placeholders with your actual values.Ignore
.env
File: Add.env
to your.gitignore
file to prevent accidentally committing secrets.Configure NestJS ConfigModule: Import and configure
ConfigModule
in your main application module (src/app.module.ts
) to make environment variables accessible throughout the application via dependency injection.isGlobal: true
makes theConfigService
available in any module without needing to importConfigModule
everywhere.envFilePath: '.env'
tells the module where to find the environment file.3. Implementing Core SMS Functionality (Service)
We'll create a dedicated module and service to handle SMS logic.
Generate SMS Module and Service: Use the Nest CLI.
This creates
src/sms/sms.module.ts
andsrc/sms/sms.service.ts
(along with a test file).Implement SmsService: Open
src/sms/sms.service.ts
and add the logic to interact with the MessageBird SDK.ConfigService
to access environment variables.Logger
provides built-in NestJS logging.constructor
retrieves the API key and originator, then initializes themessagebird
client. Robust error handling is added for missing variables or initialization failure. The comment clarifies the use ofrequire
andany
for CJS interop.sendSms
Method:recipient
andbody
as arguments.params
object required bymessagebird.messages.create
, using the configuredoriginator
.Promise
for compatibility with NestJS's async/await patterns.Logger
.messages.create
includes:id
: Unique message identifier (string)href
: URL to retrieve message detailsdirection
: "mt" (mobile terminated - sent to mobile)originator
: The sender ID usedbody
: Message contentrecipients
: Object with delivery status detailstotalCount
: Total recipient counttotalSentCount
: Count of messages senttotalDeliveredCount
: Count of delivered messagesitems
: Array of per-recipient status objects includingrecipient
,status
,statusReason
,messageLength
,messagePartCount
,price
Update SmsModule: Ensure
SmsService
is listed as a provider insrc/sms/sms.module.ts
. Nest CLI usually does this automatically.4. Building the API Layer (Controller and DTO)
Now, let's create the API endpoint to trigger the
SmsService
.Generate SMS Controller:
This creates
src/sms/sms.controller.ts
.Create Request DTO: Create a Data Transfer Object (DTO) to define the expected shape and validation rules for the request body. Create a file
src/sms/dto/send-sms.dto.ts
.class-validator
(@IsNotEmpty
,@IsString
,@MinLength
, optionally@IsPhoneNumber
) to define validation rules.libphonenumber-js
if@IsPhoneNumber
is used.datacoding
parameter can be set toplain
(GSM-7),unicode
, orauto
(default - automatically detects based on content). See MessageBird SMS API - datacoding.Implement SmsController: Open
src/sms/sms.controller.ts
and define the endpoint.@Controller('sms')
: Sets the base path for all routes in this controller to/sms
.@Post('send')
: Defines a handler forPOST
requests to/sms/send
.@Body() sendSmsDto: SendSmsDto
: Injects the validated request body into thesendSmsDto
parameter.@UsePipes(new ValidationPipe(...))
: Automatically validates the incoming body against theSendSmsDto
.transform: true
: Automatically transforms the incoming plain object to an instance ofSendSmsDto
.whitelist: true
: Strips any properties from the request body that are not defined in the DTO.try...catch
block handles potential errors from theSmsService
and throws anHttpException
with an appropriate status code and message.Update SmsModule: Add the
SmsController
to thecontrollers
array insrc/sms/sms.module.ts
.Enable Validation Globally (Optional but Recommended): Instead of applying
@UsePipes
to every controller method, you can enable theValidationPipe
globally insrc/main.ts
.If you enable it globally, you can remove the
@UsePipes(...)
decorator from theSmsController
.5. Testing the API Endpoint
Let's verify our implementation.
Start the Application:
This starts the NestJS application in watch mode. Look for the log message indicating the port it's running on (usually 3000).
Send a Test Request (Using
curl
): Open a new terminal window and usecurl
(or a tool like Postman or Insomnia) to send a POST request. ReplaceYOUR_RECIPIENT_NUMBER
with a valid phone number (use your own for testing with a live key, or any validly formatted number for a test key).Check Response:
Success: You should receive a JSON response similar to:
Check your application console logs for success messages. If using a live key, check the recipient phone for the SMS. Check the MessageBird Dashboard logs (Logs -> Messages) to see the status.
Validation Error: If you send invalid data (e.g., missing
body
), you'll get a 400 Bad Request response detailing the errors:API Error: If MessageBird rejects the request (e.g., invalid API key, insufficient balance, invalid originator), you'll get a 500 Internal Server Error (or the status code you configured in the controller's
HttpException
):Check your application console logs for detailed error messages from the
SmsService
.6. Error Handling and Logging
We've already incorporated basic logging and error handling:
SmsService
(including MessageBird API errors) and translates them into appropriate HTTP responses (e.g., 500 Internal Server Error, 502 Bad Gateway).err
object often contains anerrors
array with more specific details from the MessageBird API (code, description, parameter). LoggingJSON.stringify(err.errors)
can be very helpful for debugging.Common MessageBird Error Codes:
.env
Full error code reference: MessageBird SMS Errors
Retry Mechanisms (Advanced): For critical SMS, you might implement retries with exponential backoff, especially for transient network errors or temporary MessageBird API issues (e.g., rate limiting). Libraries like
async-retry
or NestJS scheduler features (@nestjs/schedule
) could be used. Example retry logic for 429 errors:7. Security Considerations
API Key Security:
.env
in.gitignore
).Input Validation: Already implemented using
class-validator
DTOs. This prevents malformed requests and basic injection attempts in the body parameters. Always validate and sanitize any user-provided input.Rate Limiting: Protect your API endpoint from abuse. Use
@nestjs/throttler
to limit the number of requests per IP address or user within a specific timeframe.Configure it in
app.module.ts
:MessageBird Rate Limits: MessageBird API enforces the following rate limits (source):
Retry-After
header if provided in 429 responses.Authentication/Authorization: This guide assumes the API endpoint might be internal or protected by other means (e.g., API Gateway, firewall). For public-facing APIs, implement proper authentication (e.g., JWT, API Keys specific to your API consumers) to ensure only authorized clients can trigger SMS sending.
Originator Restrictions: Be aware of country-specific regulations regarding Alphanumeric Sender IDs and ensure your chosen originator is compliant and approved.
GDPR and Data Retention: If operating in the EU or handling EU citizen data, ensure compliance with GDPR:
8. Unit Testing the Service
NestJS encourages testing. Let's write a basic unit test for
SmsService
.Open Test File: Navigate to
src/sms/sms.service.spec.ts
. The CLI generates a basic shell.Write Unit Tests: Mock dependencies (
ConfigService
,messagebird
SDK) and test thesendSms
method logic.jest.fn()
andjest.mock
to create mock implementations ofConfigService
and themessagebird
SDK.Logger
has been removed from the test moduleproviders
for cleanliness, as it wasn't actively used in the tests.Run Tests:
Or for a specific file:
9. Troubleshooting and Caveats
Common Error Messages and Solutions:
Authentication failed
MESSAGEBIRD_API_KEY
in.env
, check for typos/spaces, ensure correct key type (test/live)message could not be sent because the originator is invalid
MESSAGEBIRD_ORIGINATOR
matches a purchased VMN or approved alphanumeric sender ID. Check country restrictions.Request parameter validation failed
(recipients)+
). Example:14155552671
for US number.No (suitable) routes found
429 Too Many Requests
Authentication failed
: Double-check yourMESSAGEBIRD_API_KEY
in.env
. Ensure you're using the correct key (live vs. test) and that it hasn't been revoked. Verify there are no typos or extra spaces.message could not be sent because the originator is invalid
: EnsureMESSAGEBIRD_ORIGINATOR
in.env
matches a purchased number or a registered and approved Alphanumeric Sender ID in your MessageBird account. Check country restrictions for Alphanumeric Sender IDs.Request parameter validation failed
(Parameter:recipients
): Ensure the recipient number is in a valid format. While MessageBird is somewhat flexible, E.164 format (country code and number without '+', e.g.,14155552671
) is strongly recommended. The SDK expectsrecipients
as an array. The MessageBird API expects numbers in international format without the '+' symbol, though the SDK may handle normalization.No (suitable) routes found
: You might have insufficient balance (for live keys) or the recipient country/network might not be supported by your MessageBird account setup or the originator type. Check your balance and MessageBird's coverage documentation.Promise
wrapper is crucial for cleanasync/await
usage in NestJS. Errors in the promise handling logic can mask SDK errors.messagebird
package, as APIs and methods can change. Checkpackage.json
and compare with npm registry.10. Deployment and CI/CD
Build: Create a production build:
This compiles TypeScript to JavaScript in the
dist
folder.Run Production: Start the application using Node.js directly on the compiled output:
Environment Variables: Ensure your production environment (e.g., Docker container, PaaS like Heroku/Vercel/AWS Elastic Beanstalk, VM) has the
MESSAGEBIRD_API_KEY
andMESSAGEBIRD_ORIGINATOR
environment variables set securely. Do not include the.env
file in your production artifact; use the platform's mechanism for environment variables.Docker Containerization Example:
CI/CD Pipeline Example (GitHub Actions):
Process Management: Use a process manager like
pm2
or rely on your platform's built-in service management (e.g., systemd, Docker orchestration) to keep the Node.js application running reliably, handle restarts, and manage logs.Health Check Endpoint: Add a health check endpoint for monitoring:
Frequently Asked Questions
How do I send SMS messages with MessageBird in NestJS?
To send SMS with MessageBird in NestJS, install the MessageBird Node.js SDK (
npm install messagebird
), create a service that wraps the SDK'smessages.create
method with promises, and use NestJS dependency injection to access it from your controller. Configure your API key via@nestjs/config
and validate requests using DTOs with class-validator.What phone number format does MessageBird require?
MessageBird requires phone numbers in E.164 international format without the '+' prefix (e.g.,
14155552671
for a US number). The MessageBird Node.js SDK typically handles format normalization, but providing properly formatted numbers ensures reliable delivery and reduces API errors.Can I use alphanumeric sender IDs with MessageBird in all countries?
No, alphanumeric sender IDs are not supported in all countries. The United States, for example, prohibits alphanumeric sender IDs and requires a registered numeric phone number. Check MessageBird's sender ID documentation for country-specific restrictions before configuring your originator.
How do I handle MessageBird API errors in NestJS?
Wrap MessageBird SDK callbacks in promises and use try-catch blocks in your service methods. Map MessageBird API errors to appropriate HTTP status codes using NestJS
HttpException
classes. Common errors include authentication failures (401), parameter validation errors (400), and insufficient balance or routing issues.What's the difference between MessageBird test and live API keys?
Test API keys allow you to simulate SMS sending without actual delivery or charges. Messages appear as "sent" in your code, but no real SMS is delivered. Live API keys send actual messages, consume your account balance, and deliver to real phone numbers. Always use test keys during development.
How do I validate phone numbers in NestJS before sending SMS?
Use class-validator decorators in your DTO, such as
@IsString()
and@Matches()
with an E.164 regex pattern. For more robust validation, integrate libphonenumber-js to verify phone number validity, format, and country code before passing to the MessageBird API.What dependencies do I need for MessageBird NestJS integration?
You need
@nestjs/core
,@nestjs/common
,messagebird
(the official Node.js SDK),@nestjs/config
for environment variables,class-validator
andclass-transformer
for request validation, and optionallylibphonenumber-js
for advanced phone number validation.How do I deploy a MessageBird NestJS application to production?
Build your NestJS application with
npm run build
, setMESSAGEBIRD_API_KEY
andMESSAGEBIRD_ORIGINATOR
as environment variables in your hosting platform (not in a committed.env
file), and use a process manager like pm2 or platform-native service management. Implement proper error logging, rate limiting, and monitoring for production reliability.Related Resources
For more comprehensive guides on SMS integration and phone number formatting: