code examples

Sent logo
Sent TeamMay 3, 2025 / code examples / Article

How to Send SMS with Node.js and Vonage API: Complete Tutorial

Learn how to build a Node.js REST API to send SMS messages using the Vonage SMS API. Complete guide with Express setup, code examples, error handling, and deployment.

How to Send SMS with Node.js and Vonage API: Complete Tutorial

This guide provides a complete walkthrough for building a Node.js and Express application that sends SMS messages using the Vonage SMS API. You'll learn everything from project setup to deployment and troubleshooting.

By the end, you'll have a functional REST API endpoint that accepts a phone number and message text, then uses the Vonage API to programmatically send SMS messages. This serves as a foundation for applications requiring SMS notifications, two-factor authentication, user verification, or other communication features.

Project Overview and Goals

What You're Building:

A minimal REST API built with Node.js and Express. This API exposes a single endpoint (POST /send-sms) that takes a recipient phone number and message body, and uses the Vonage Node.js SDK to send the SMS via the Vonage SMS API. This guide focuses on core functionality; production deployments require additional security, error handling, and scalability enhancements (discussed later).

Problem Solved:

Provides a straightforward, server-side mechanism to programmatically send SMS messages, abstracting direct Vonage API interaction into a simple API call.

Technologies Used:

  • Node.js: JavaScript runtime for server-side code
  • Express: Minimal Node.js web application framework for creating API endpoints
  • Vonage Node.js SDK (@vonage/server-sdk): Simplifies Vonage API interaction, handling authentication and request formatting (GitHub repo)
  • Vonage SMS API: Underlying service that dispatches SMS messages globally (General Availability status)
  • dotenv: Module to load environment variables from a .env file into process.env, keeping credentials secure

System Architecture:

An HTTP client (like curl or a web application) sends a POST request to the /send-sms endpoint of your Node.js/Express server. The server uses the Vonage SDK, configured with API credentials, to request the Vonage SMS API. Vonage then sends the SMS to the recipient's phone.

Prerequisites:

  1. Node.js and npm: Install from nodejs.org. Requires Node.js v18.11.0+ for built-in watch mode.
  2. Vonage API Account: Sign up for free at Vonage API Dashboard. You'll receive free credit for testing.
    • Trial Account Limitation: New Vonage accounts start on trial. You must whitelist recipient phone numbers in the Vonage Dashboard before sending SMS during trial. See the Troubleshooting section for details.
  3. Vonage API Key and Secret: Found on your Vonage API Dashboard main page after signup
  4. Vonage Virtual Number: Rent a Vonage phone number capable of sending SMS from the Dashboard under "Numbers" > "Buy numbers". Trial accounts may have destination limitations.
  5. (Optional) HTTP Client: Tools like curl or Postman for testing

Expected Outcome:

A running Node.js server with a /send-sms endpoint. Sending a POST request with valid to and text parameters results in an SMS sent via Vonage.


1. Setting Up Your Node.js SMS Project

Initialize your Node.js project and install dependencies.

  1. Create Project Directory:

    bash
    mkdir vonage-sms-guide
    cd vonage-sms-guide
  2. Initialize npm:

    bash
    npm init -y

    This creates package.json to manage dependencies and scripts.

  3. Install Dependencies:

    bash
    npm install express @vonage/server-sdk dotenv
  4. Create Project Files:

    bash
    touch index.js .env .gitignore
  5. Configure .gitignore: Add these lines to prevent committing dependencies and sensitive credentials:

    text
    # .gitignore
    
    node_modules/
    .env
  6. Configure Environment Variables (.env): Replace placeholder values with your actual credentials from the Vonage Dashboard:

    dotenv
    # .env
    
    # Found on your Vonage API Dashboard
    VONAGE_API_KEY=YOUR_API_KEY
    VONAGE_API_SECRET=YOUR_API_SECRET
    
    # Your Vonage virtual number capable of sending SMS
    VONAGE_VIRTUAL_NUMBER=YOUR_VONAGE_NUMBER
    
    # Port for the Express server
    PORT=3000
    • VONAGE_API_KEY / VONAGE_API_SECRET: SDK uses these to authenticate requests
    • VONAGE_VIRTUAL_NUMBER: The "From" number appearing on recipient's phone (must be associated with your account)
    • PORT: Local port for your Express server

Project Structure:

vonage-sms-guide/ ├── node_modules/ ├── .env # API keys and secrets (DO NOT COMMIT) ├── .gitignore # Untracked files ├── index.js # Main application code ├── package-lock.json # Exact dependency versions └── package.json # Project metadata and dependencies

2. Implementing Core SMS Functionality

Write the code in index.js to set up the Express server, initialize the Vonage SDK, and create the SMS sending function.

javascript
// index.js
'use strict';

// 1. Import necessary modules
require('dotenv').config(); // Load environment variables from .env
const express = require('express');
const { Vonage } = require('@vonage/server-sdk');

// 2. Initialize Vonage SDK
// API Key and Secret are loaded from environment variables
const vonage = new Vonage({
  apiKey: process.env.VONAGE_API_KEY,
  apiSecret: process.env.VONAGE_API_SECRET
});

// 3. Initialize Express app
const app = express();
app.use(express.json()); // Parse JSON request bodies
app.use(express.urlencoded({ extended: true })); // Parse URL-encoded data

// 4. Define the SMS sending function
async function sendSms(recipient, message) {
  const from = process.env.VONAGE_VIRTUAL_NUMBER;
  const to = recipient;
  const text = message;

  try {
    // Uses Vonage's SMS API (General Availability)
    // Reference: https://developer.vonage.com/en/messaging/sms/overview
    const responseData = await vonage.sms.send({ to, from, text });
    console.log(`Message sent successfully to ${to}. Message ID: ${responseData.messages[0]['message-id']}`);
    
    // Status '0' indicates success per Vonage API spec
    if (responseData.messages[0]['status'] === '0') {
      return { success: true, data: responseData };
    } else {
      const errorText = responseData.messages[0]['error-text'];
      console.error(`Message failed with error: ${errorText}`);
      return { success: false, message: `Message failed: ${errorText}` };
    }
  } catch (err) {
    // Handle network issues or SDK errors
    console.error("Error sending SMS:", err);
    return { success: false, message: 'Failed to send SMS due to an internal error.' };
  }
}

// 5. Define the API endpoint (Covered in next section)
// ... Endpoint code will go here ...

// 6. Start the server
const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`Server listening at http://localhost:${port} on ${new Date().toLocaleString()}`);
  console.log(`Using Vonage Number: ${process.env.VONAGE_VIRTUAL_NUMBER}`);
  
  // Check for API credentials
  if (!process.env.VONAGE_API_KEY || !process.env.VONAGE_API_SECRET || !process.env.VONAGE_VIRTUAL_NUMBER) {
      console.warn("***********************************************************************");
      console.warn("WARNING: Vonage API credentials or virtual number missing in .env file!");
      console.warn("SMS sending will likely fail. Check your .env configuration.");
      console.warn("***********************************************************************");
  }
});

Explanation:

  1. Imports: Load dotenv for credentials, express for the server, and the Vonage class from the SDK
  2. Vonage Initialization: Create a Vonage instance with API key and secret from process.env. The SDK handles authentication using these credentials (SDK documentation)
  3. Express Initialization: Create Express app and apply middleware to parse request bodies
  4. sendSms Function:
    • async function encapsulating SMS logic
    • Retrieves from number from environment variables
    • Uses vonage.sms.send() with to, from, and text parameters
    • Checks the status property in responseData.messages[0]['status']. Status '0' indicates success according to Vonage API documentation
    • Handles both successful sends and API-level errors (invalid numbers, insufficient funds, etc.)
    • Includes try...catch for network errors or SDK exceptions
    • Returns object with success: true/false and relevant data or error message
  5. Server Start: Retrieves PORT from .env (defaults to 3000), starts Express server, logs confirmation and warnings if credentials are missing

3. Building the REST API Endpoint

Add the API endpoint to index.js before the app.listen call (where the "// 5. Define the API endpoint" comment is).

javascript
// index.js (Add before app.listen)

// 5. Define the API endpoint
app.post('/send-sms', async (req, res) => {
  // Basic Input Validation
  const { to, text } = req.body;

  if (!to || !text) {
    console.warn('Received invalid request: Missing "to" or "text" field.');
    return res.status(400).json({
      success: false,
      message: 'Missing required fields: "to" (recipient phone number) and "text" (message body).'
    });
  }

  // E.164 format check (international phone number standard)
  const phoneRegex = /^\+[1-9]\d{1,14}$/;
  if (!phoneRegex.test(to)) {
      console.warn(`Received invalid phone number format: ${to}`);
      return res.status(400).json({
          success: false,
          message: 'Invalid phone number format. Use E.164 format (e.g., +14155552671).'
      });
      // Note: Production validation should use libraries like google-libphonenumber
      // for comprehensive country-specific rules
  }

  console.log(`Received request to send SMS to: ${to}`);

  // Call the SMS sending function
  const result = await sendSms(to, text);

  // Send response based on result
  if (result.success) {
    res.status(200).json({
      success: true,
      message: 'SMS sent successfully.', // Final delivery is asynchronous
      details: result.data // Include Vonage response details
    });
  } else {
    // 500 for internal errors; could map specific Vonage errors to 400/502
    res.status(500).json({
      success: false,
      message: result.message
    });
  }
});

Explanation:

  1. Route Definition: app.post('/send-sms', ...) listens for HTTP POST requests on /send-sms
  2. Input Validation:
    • Extracts to (recipient) and text (message) from req.body
    • Checks both fields are present; returns 400 Bad Request if missing
    • Regex validates E.164 phone number format (international standard). Production apps should use robust libraries like google-libphonenumber
  3. Call sendSms: Invokes the function with validated parameters
  4. Response Handling:
    • On success (200 OK): Returns success message and Vonage response data
    • On failure (500 Internal Server Error): Returns error message. More refined implementations might map specific Vonage errors to different HTTP status codes

4. Vonage API Integration Setup

Integration occurs during setup and initialization:

  1. Credentials: Stored securely in .env (VONAGE_API_KEY, VONAGE_API_SECRET, VONAGE_VIRTUAL_NUMBER)
  2. SDK Initialization: Vonage SDK instance created with these credentials in index.js
  3. API Call: vonage.sms.send() handles communication with Vonage API, including authentication headers
  4. Dashboard Configuration (Critical for Trial Accounts):
    • Log in to Vonage API Dashboard
    • Navigate to "Numbers" > "Your numbers" to confirm you have a virtual number capable of sending SMS
    • Trial accounts: You must add and verify recipient phone numbers. Look for profile/settings or "Test Numbers" section. Sending to unverified numbers fails. Upgrade by adding payment details to remove restrictions (common beginner issue)
    • API Settings: Check "API settings" in dashboard. The "Default SMS Setting" should be appropriate. This guide uses the SMS API (vonage.sms.send). For receiving messages, this setting changes webhook formats

5. Error Handling, Logging, and Retry Logic

  • Error Handling:
    • sendSms function uses try...catch for network or SDK-level errors
    • Inspects Vonage API response (responseData.messages[0].status and error-text) to detect API-specific errors (invalid number, insufficient balance)
    • API endpoint returns appropriate HTTP status codes (400 for bad input, 500 for server/API errors, 200 for success)
  • Logging:
    • Basic console.log, console.warn, and console.error provide visibility
    • Production recommendation: Use robust logging libraries (Winston or Pino) for structured JSON logs to files or logging services. Log: request receipt, validation failures, Vonage API calls, success/error responses, caught exceptions
  • Retry Mechanisms:
    • This guide doesn't implement automatic retries
    • Production recommendation: For transient network errors or rate-limiting (status code 1), implement retry strategy with exponential backoff using libraries like async-retry. Wrap vonage.sms.send() in a retry loop with progressive waits. Don't retry permanent errors (invalid API key, invalid recipient)

6. Database Schema

Not applicable for this simple SMS API. For tracking sent messages, storing templates, or managing users, add a database (PostgreSQL, MongoDB) and data layer (ORM like Prisma or Sequelize).


7. Security Best Practices for SMS APIs

  • Secrets Management: Use .env and .gitignore. In production, use environment variables from deployment platform or dedicated secrets manager
  • Input Validation: Basic validation for to and text presence and format included. Use libraries like joi or express-validator for complex validation in production
  • Rate Limiting: Not implemented. Use middleware like express-rate-limit to prevent API abuse (limit requests per IP)
  • Authentication/Authorization: Endpoint is currently open. In production, protect with API keys, JWT tokens, or session authentication

8. Handling International SMS and Special Cases

  • International Numbers: E.164 format (+ followed by country code and number) is standard. Vonage routes based on this. Ensure your account/number is enabled for destination countries
  • Character Limits & Encoding:
    • Standard SMS: 160 GSM-7 characters or 70 UCS-2 (Unicode) characters per message (Vonage encoding guide)
    • Longer messages split into concatenated SMS (charged per segment)
    • Characters from GSM extended table require 2 bytes each
    • Special characters (Chinese, Japanese, Korean, Arabic, Cyrillic) force UCS-2 encoding, reducing limit to 70 characters
    • Vonage accepts up to 3,200 characters, but best practice is max 6 SMS parts
  • Delivery Reports (DLRs): Not covered in this guide. Configure webhook URL in Vonage settings to receive delivery status updates (delivered, failed, rejected). Requires adding another endpoint to your Express app for callbacks

9. Performance Optimization for High-Volume SMS

Not critical for single SMS messages. For high volumes, consider:

  • Asynchronous Processing: Push SMS tasks to background job queue (e.g., BullMQ with Redis) and return immediate 202 Accepted response. Separate worker process handles sending
  • SDK Client Reuse: The vonage client is initialized once and reused (already efficient)

10. Monitoring and Analytics for SMS Delivery

  • Logging: Use structured logging (see Section 5)
  • Health Checks: Add a /health endpoint returning 200 OK for load balancers or monitoring systems
  • Metrics: Track request counts, error rates, and latency for /send-sms using monitoring tools (Prometheus/Grafana, Datadog). Track Vonage API call latency and success/error rates
  • Error Tracking: Use services like Sentry or Bugsnag to capture and aggregate runtime errors

11. Common Issues and Troubleshooting

  • Error: 401 Unauthorized (Authentication failed)

    • Cause: Incorrect VONAGE_API_KEY or VONAGE_API_SECRET in .env
    • Solution: Verify credentials in .env against Vonage Dashboard. Ensure require('dotenv').config(); is called early. Check for extra spaces or characters
  • Error: Invalid 'From' number

    • Cause: VONAGE_VIRTUAL_NUMBER is incorrect, not owned by your account, or not SMS-capable
    • Solution: Verify number in Dashboard under "Numbers" > "Your numbers". Ensure correct E.164 format
  • Error: Non-Whitelisted Destination (Status code 15)

    • Cause: Trial account sending to non-whitelisted phone number
    • Solution: Add recipient to "Test Numbers" list in Dashboard, or upgrade account by adding billing details
  • Error: Missing Mandatory Field (Status code 4 or 5)

    • Cause: Missing or invalid to, from, or text parameter
    • Solution: Check sendSms function and /send-sms endpoint logic. Review logs for validation errors
  • SMS Not Received, but API shows Success (status: '0')

    • Causes: Carrier filtering, incorrect recipient number (valid format but wrong number), network issues, destination country restrictions
    • Solutions:
      • Verify recipient number is correct and active
      • Check Dashboard logs ("Logs" > "SMS") for detailed delivery status
      • Test with different number or carrier
      • Verify account allows sending to specific country
      • Set up DLR webhooks for detailed delivery status
  • Caveat: Environment Variables Not Loading

    • Cause: require('dotenv').config(); not called, called too late, or .env file in wrong location
    • Solution: Ensure require('dotenv').config(); is first line in index.js. Verify .env location (project root where node runs)
  • Caveat: Port Conflict (EADDRINUSE)

    • Cause: Another application using the port
    • Solution: Stop other application or change PORT in .env

12. Production Deployment and CI/CD

  • Deployment Platforms: Deploy to Heroku, Render, AWS Elastic Beanstalk, Google Cloud Run, or VPS

  • Environment Variables: Never include .env in deployment or Git commits. Configure variables (VONAGE_API_KEY, VONAGE_API_SECRET, VONAGE_VIRTUAL_NUMBER, PORT, NODE_ENV=production) in deployment platform's settings

  • package.json Scripts:

    json
    {
      "scripts": {
        "start": "node index.js",
        "dev": "node --watch index.js"
      }
    }

    Note: dev script requires Node.js v18.11.0+. For broader compatibility, use nodemon index.js (requires npm install --save-dev nodemon). Most platforms automatically run npm start

  • CI/CD Pipeline (GitHub Actions example):

    1. Push code to Git repository (GitHub, GitLab)
    2. Set repository secrets for Vonage credentials and deployment keys
    3. Create workflow file (.github/workflows/deploy.yml) that:
      • Checks out code
      • Sets up Node.js
      • Installs dependencies (npm ci – preferred in CI for using package-lock.json)
      • (Optional) Runs tests (npm test)
      • Deploys to platform using CLI or GitHub Actions (e.g., actions/heroku-deploy, google-github-actions/deploy-cloudrun)
      • Passes environment variables securely during deployment
  • Rollback: Most platforms offer mechanisms to redeploy previous versions (e.g., Heroku's heroku rollback, AWS CodeDeploy strategies)


13. Testing Your SMS API

  1. Start the Server Locally: Ensure .env is correctly populated:

    bash
    node index.js

    You should see "Server listening..." in the console.

  2. Manual Testing (using curl): Open a new terminal. Replace +14155550100 with valid test number (whitelisted for trial accounts):

    bash
    curl -X POST http://localhost:3000/send-sms \
         -H "Content-Type: application/json" \
         -d '{
               "to": "+14155550100",
               "text": "Hello from your Node.js Vonage App!"
             }'
  3. Check Expected Output:

    • Terminal running curl:
      • Success:
        json
        {
          "success": true,
          "message": "SMS sent successfully.",
          "details": {
            "message-count": "1",
            "messages": [
              {
                "to": "14155550100",
                "message-id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                "status": "0",
                "remaining-balance": "x.xxxx",
                "message-price": "x.xxxx",
                "network": "xxxxx"
              }
            ]
          }
        }
      • Failure (validation):
        json
        {
          "success": false,
          "message": "Missing required fields: \"to\" (recipient phone number) and \"text\" (message body)."
        }
      • Failure (API error):
        json
        {
          "success": false,
          "message": "Message failed: Invalid Sender Address - rejected"
        }
    • Terminal running Node.js server: Check console logs for "Received request...", "Message sent successfully...", or error details
    • Recipient Phone: Should receive the SMS
    • Vonage Dashboard: Check "Logs" > "SMS" for message record and status
  4. Automated Testing:

    • Unit Tests: Use Jest or Mocha/Chai to test sendSms in isolation. Mock @vonage/server-sdk to avoid actual API calls. Test different inputs and scenarios based on mocked responses
    • Integration Tests: Use supertest to make HTTP requests to Express app. Test /send-sms endpoint, validating inputs, responses, and status codes

Frequently Asked Questions

How do I send SMS messages from Node.js?

To send SMS from Node.js, install the Vonage SDK (npm install @vonage/server-sdk), initialize it with your API credentials, and call vonage.sms.send() with the recipient number, sender number, and message text. This guide provides a complete implementation with Express.

What is the best SMS API for Node.js?

Vonage SMS API (formerly Nexmo) is one of the most popular choices for Node.js due to its comprehensive SDK, reliable delivery, and competitive pricing. Other options include Twilio, AWS SNS, and MessageBird. The choice depends on your requirements for features, pricing, and geographic coverage.

How much does it cost to send SMS with Vonage?

Vonage SMS pricing varies by destination country. Most messages cost between $0.0045-0.02 USD per SMS segment. New accounts receive free credit for testing. Check the Vonage Pricing page for specific rates.

What is E.164 phone number format?

E.164 is the international phone number format required by most SMS APIs. It consists of a plus sign (+) followed by the country code and phone number, with no spaces or special characters (e.g., +14155552671 for a US number).

How many characters can I send in an SMS?

Standard SMS supports 160 GSM-7 characters or 70 Unicode characters per message. Longer messages are automatically split into concatenated SMS segments, with each part counting as a separate billable message. Characters from the GSM extended table use 2 bytes each.

Can I send SMS to international numbers?

Yes, Vonage supports SMS delivery to over 200 countries. Ensure your phone numbers use E.164 format with the correct country code. Note that trial accounts may have restrictions on international destinations until you add billing details.

How do I handle SMS delivery failures?

Implement comprehensive error handling by checking the status code in Vonage's response. Status '0' indicates success, while other codes indicate specific errors (invalid number, insufficient balance, etc.). Set up delivery receipt webhooks for real-time delivery confirmation.

What's the difference between Vonage SMS API and Messages API?

The SMS API (used in this guide) is optimized for simple text messaging and is in General Availability. The Messages API is a newer, more feature-rich platform supporting SMS, MMS, WhatsApp, Facebook Messenger, and Viber through a unified interface.


Next Steps

After completing this tutorial, consider these enhancements:

  • Add delivery receipts by configuring webhook endpoints to track message delivery status
  • Implement message templates for common use cases like verification codes or notifications
  • Add rate limiting to prevent abuse and manage API costs
  • Integrate with a database to log sent messages and track delivery metrics
  • Explore the Messages API for multi-channel communication (SMS, WhatsApp, etc.)
  • Set up monitoring with tools like Datadog or New Relic for production reliability

References

This guide provides a solid foundation for sending SMS messages with Node.js, Express, and Vonage. Adapt error handling, security, logging, and deployment strategies to fit your production requirements.

Frequently Asked Questions

How to send SMS with Node.js and Express?

Use the Vonage SMS API with the Node.js SDK and Express. Create an API endpoint that accepts recipient number and message text, then uses the SDK to send the SMS via Vonage.

What is the Vonage Node.js SDK used for?

The Vonage Node.js SDK (`@vonage/server-sdk`) simplifies interaction with the Vonage APIs. It handles authentication and request formatting, making it easier to send SMS messages from your Node.js application.

Why does Vonage require whitelisting numbers?

For trial accounts, Vonage requires whitelisting recipient numbers in the dashboard for security and to prevent abuse. This restriction is lifted once the account is upgraded with billing details.

When should I use the Vonage Messages API?

While this guide uses the simpler `vonage.sms.send()` method, Vonage's Messages API offers more advanced features. Consider it for richer messaging needs beyond basic SMS.

Can I send SMS to international numbers with Vonage?

Yes, use the E.164 format (+[country code][number]). Ensure your Vonage account and number are enabled for the destination countries and that you comply with any applicable regulations.

How to set up a Node.js project for sending SMS?

Initialize a Node project with `npm init`, install `express`, `@vonage/server-sdk`, and `dotenv`. Create `index.js`, `.env`, and `.gitignore`. Add API keys and virtual number to `.env` and implement the SMS sending logic.

What is the purpose of .env file in Vonage SMS project?

The `.env` file stores sensitive information like your Vonage API key, secret, and virtual number. It's crucial for security and should never be committed to version control.

How to handle errors when sending SMS with Vonage?

Use `try...catch` blocks for network/SDK errors. Check the Vonage API response status for success ('0') or specific error codes. Implement robust logging for easier debugging and monitoring in production.

How to test my Vonage SMS API endpoint?

Start your server locally with `node index.js`. Use a tool like `curl` or Postman to send POST requests to your `/send-sms` endpoint with test data, ensuring whitelisted recipient numbers in trial accounts. Check responses and logs to verify successful SMS delivery.

When to implement retry mechanisms for sending SMS messages?

In production, use retry mechanisms with exponential backoff for handling transient errors like network issues or rate limiting. Avoid retrying permanent errors like invalid API keys.

How to secure my Vonage SMS application?

Use a secrets manager for API keys, implement robust input validation, rate limiting, and appropriate authentication/authorization for the `/send-sms` endpoint.

What are SMS character limits with Vonage?

Standard SMS messages are limited to 160 characters (GSM-7 encoding). Longer messages may be split, incurring costs for multiple segments. Special characters might force UCS-2, further reducing per-segment limits.

How can I get delivery reports for my Vonage SMS?

Configure a webhook URL in your Vonage Dashboard settings to receive delivery reports. This will notify your application when a message is delivered, failed, or rejected.

How to troubleshoot 'Authentication failed' error with Vonage?

Double-check your `VONAGE_API_KEY` and `VONAGE_API_SECRET` in the `.env` file and your Vonage Dashboard. Ensure the `.env` file is loaded correctly early in your application.

Why is my Vonage SMS not received despite success status?

Several reasons include carrier issues, incorrect recipient number, temporary network problems, or country-specific restrictions. Verify the recipient number, consult Vonage Dashboard logs, and consider setting up delivery receipts.