> ## Documentation Index
> Fetch the complete documentation index at: https://docs.notvis.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Send SMS

> Send an SMS message to one or more phone numbers.

<Note>
  Also available at `POST /v1/sms/send` for backward compatibility.
</Note>

## Request Headers

<ParamField header="Authorization" type="string" required>
  Bearer token. Format: `Bearer nc_live_your_api_key`
</ParamField>

<ParamField header="Idempotency-Key" type="string">
  Unique key to prevent duplicate sends. Responses are cached for 24 hours. See [Idempotency](/idempotency).
</ParamField>

## Request Body

<ParamField body="to" type="string | string[]" required>
  Recipient phone number(s) in E.164 format (e.g., `+919876543210`, `+14155552671`). Accepts a single string or an array of up to 1,000 numbers for batch sending. Indian numbers without country code are automatically normalized to `+91`.
</ParamField>

<ParamField body="from" type="string">
  Sender ID or header (e.g., `"NOTVIS"`). Must be pre-registered with your SMS provider and DLT portal.
</ParamField>

<ParamField body="template_id" type="string">
  UUID of a pre-configured SMS template in your Notvis account. Either `template_id` or `dlt_template_id` is required.
</ParamField>

<ParamField body="dlt_template_id" type="string">
  DLT registered template ID. Required for regulatory compliance when sending to Indian numbers. Either `template_id` or `dlt_template_id` is required.
</ParamField>

<ParamField body="dlt_entity_id" type="string">
  DLT entity ID. Required alongside `dlt_template_id` for India DLT compliance.
</ParamField>

<ParamField body="variables" type="object">
  Template variable replacements. Keys should be numeric strings (`"1"`, `"2"`, etc.) mapping to replacement values. Maximum 20 variables.
</ParamField>

<ParamField body="callback_url" type="string">
  HTTPS URL to receive delivery status webhooks for this message. Must start with `https://`.
</ParamField>

<ParamField body="schedule_at" type="string">
  ISO 8601 timestamp to schedule the message for future delivery (e.g., `"2026-07-15T10:00:00Z"`). Must be in the future, maximum 7 days ahead.
</ParamField>

<ParamField body="expire_after_seconds" type="integer">
  Message time-to-live in the queue. If the message cannot be delivered within this window, it expires. Range: 5–86400 seconds (24 hours).
</ParamField>

<ParamField body="tags" type="string[]">
  Tags for categorization and filtering. Maximum 10 tags.
</ParamField>

<ParamField body="metadata" type="object">
  Custom key-value pairs. Passed through to delivery webhooks for your tracking purposes.
</ParamField>

<Info>
  **DLT Compliance (India):** All commercial SMS to Indian numbers requires DLT registration. Register your entity, sender ID, and message templates on a DLT portal (Jio, Airtel, Vodafone) before sending.
</Info>

## Response

### Single recipient

<ResponseField name="message_id" type="string">
  Unique identifier for the queued message.
</ResponseField>

<ResponseField name="status" type="string">
  `"queued"` for immediate sends, `"scheduled"` for future sends.
</ResponseField>

<ResponseField name="to" type="string">
  Normalized E.164 phone number.
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 timestamp of when the message was created.
</ResponseField>

### Batch (multiple recipients)

When `to` is an array, the response wraps individual messages:

<ResponseField name="messages" type="array">
  Array of message objects, one per recipient. Each contains `message_id`, `status`, `to`, and `created_at`.
</ResponseField>

<RequestExample>
  ```bash cURL (Single) theme={null}
  curl -X POST https://api.notvis.com/v1/sms/messages \
    -H "Authorization: Bearer nc_live_your_api_key" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: $(uuidgen)" \
    -d '{
      "to": "+919876543210",
      "from": "NOTVIS",
      "dlt_template_id": "1107161234567890",
      "dlt_entity_id": "1101234567890",
      "variables": {
        "1": "123456",
        "2": "10 minutes"
      },
      "callback_url": "https://example.com/webhooks/sms",
      "tags": ["otp"],
      "metadata": { "user_id": "usr_123" }
    }'
  ```

  ```bash cURL (Batch) theme={null}
  curl -X POST https://api.notvis.com/v1/sms/messages \
    -H "Authorization: Bearer nc_live_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "to": ["+919876543210", "+919876543211", "+14155552671"],
      "dlt_template_id": "1107161234567890",
      "variables": { "1": "Summer Sale", "2": "20%" },
      "tags": ["promo"]
    }'
  ```

  ```bash cURL (Scheduled) theme={null}
  curl -X POST https://api.notvis.com/v1/sms/messages \
    -H "Authorization: Bearer nc_live_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "to": "+919876543210",
      "dlt_template_id": "1107161234567890",
      "variables": { "1": "tomorrow" },
      "schedule_at": "2026-07-15T10:00:00Z"
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://api.notvis.com/v1/sms/messages', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer nc_live_your_api_key',
      'Content-Type': 'application/json',
      'Idempotency-Key': crypto.randomUUID(),
    },
    body: JSON.stringify({
      to: '+919876543210',
      from: 'NOTVIS',
      dlt_template_id: '1107161234567890',
      dlt_entity_id: '1101234567890',
      variables: { '1': '123456', '2': '10 minutes' },
      callback_url: 'https://example.com/webhooks/sms',
    }),
  });

  const data = await response.json();
  console.log(data.message_id);
  ```

  ```python Python theme={null}
  import requests
  import uuid

  response = requests.post(
      'https://api.notvis.com/v1/sms/messages',
      headers={
          'Authorization': 'Bearer nc_live_your_api_key',
          'Idempotency-Key': str(uuid.uuid4()),
      },
      json={
          'to': '+919876543210',
          'from': 'NOTVIS',
          'dlt_template_id': '1107161234567890',
          'dlt_entity_id': '1101234567890',
          'variables': {'1': '123456', '2': '10 minutes'},
      },
  )

  print(response.json()['message_id'])
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "net/http"

      "github.com/google/uuid"
  )

  func main() {
      payload := map[string]interface{}{
          "to":              "+919876543210",
          "from":            "NOTVIS",
          "dlt_template_id": "1107161234567890",
          "dlt_entity_id":   "1101234567890",
          "variables":       map[string]string{"1": "123456", "2": "10 minutes"},
      }

      body, _ := json.Marshal(payload)
      req, _ := http.NewRequest("POST", "https://api.notvis.com/v1/sms/messages", bytes.NewBuffer(body))
      req.Header.Set("Authorization", "Bearer nc_live_your_api_key")
      req.Header.Set("Content-Type", "application/json")
      req.Header.Set("Idempotency-Key", uuid.NewString())

      resp, _ := http.DefaultClient.Do(req)
      defer resp.Body.Close()
  }
  ```
</RequestExample>

<ResponseExample>
  ```json 202 Single Recipient theme={null}
  {
    "message_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "status": "queued",
    "to": "+919876543210",
    "created_at": "2026-07-12T10:00:00Z"
  }
  ```

  ```json 202 Batch theme={null}
  {
    "messages": [
      {
        "message_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
        "status": "queued",
        "to": "+919876543210",
        "created_at": "2026-07-12T10:00:00Z"
      },
      {
        "message_id": "8d0f7780-8536-51e5-b827-f18gd2g01bf8",
        "status": "queued",
        "to": "+919876543211",
        "created_at": "2026-07-12T10:00:00Z"
      }
    ]
  }
  ```

  ```json 202 Scheduled theme={null}
  {
    "message_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "status": "scheduled",
    "to": "+919876543210",
    "created_at": "2026-07-12T10:00:00Z"
  }
  ```

  ```json 400 Validation Error theme={null}
  {
    "code": 400,
    "message": "validation failed",
    "details": {
      "to": "invalid phone number: 12345 (expected E.164 format like +919876543210)"
    }
  }
  ```
</ResponseExample>
