Step-by-Step Guide

How to Send OTP Without DLT Registration

A step-by-step guide to sending OTPs in India without any DLT setup. From account creation to your first API call in 5 minutes.

✦ No credit card required · Free plan available · Setup in 5 minutes

Integration Steps

Step-by-Step Guide

01

Create Your Account

Sign up at app.startmessaging.com with your email. No company documents or KYC required to get started.

02

Generate an API Key

Go to the API Keys page in your dashboard and click 'Create API Key'. Copy the key — it is shown only once. The key starts with the sm_live_ prefix.

03

Top Up Your Wallet

Add funds to your wallet via Razorpay (UPI, cards, netbanking). Each OTP costs Rs 0.25.

04

Send Your First OTP

Make a POST request to /otp/send with the phone number. We generate and deliver the OTP via SMS in under 2 seconds. See the code examples below.

05

Verify the OTP

When your user enters the OTP, call POST /v1/otp/verify with the OTP request ID and the code. We handle validation, expiry, and attempt limits.

Send an OTP in One API Call

Works with every language. Just a single POST request.

curl -X POST https://api.startmessaging.com/otp/send \
  -H "Content-Type: application/json" \
  -H "X-API-Key: sm_live_your_api_key_here" \
  -d '{
    "phoneNumber": "+919876543210",
    "templateId": "YOUR_TEMPLATE_ID",
    "variables": {
      "otp": "123456",
      "appName": "YourApp"
    }
  }'
const response = await fetch("https://api.startmessaging.com/otp/send", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "sm_live_your_api_key_here",
  },
  body: JSON.stringify({
    phoneNumber: "+919876543210",
    templateId: "YOUR_TEMPLATE_ID",
    variables: {
      otp: "123456",
      appName: "YourApp",
    },
  }),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.startmessaging.com/otp/send",
    headers={
        "Content-Type": "application/json",
        "X-API-Key": "sm_live_your_api_key_here",
    },
    json={
        "phoneNumber": "+919876543210",
        "templateId": "YOUR_TEMPLATE_ID",
        "variables": {
            "otp": "123456",
            "appName": "YourApp"
        },
    },
)

data = response.json()
print(data)
$ch = curl_init("https://api.startmessaging.com/otp/send");

curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        "Content-Type: application/json",
        "X-API-Key: sm_live_your_api_key_here",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "phoneNumber" => "+919876543210",
        "templateId" => "YOUR_TEMPLATE_ID",
        "variables" => [
            "otp" => "123456",
            "appName" => "YourApp"
        ]
    ]),
]);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
import java.net.http.*;
import java.net.URI;

HttpClient client = HttpClient.newHttpClient();

String body = """
    {
      "phoneNumber": "+919876543210",
      "templateId": "YOUR_TEMPLATE_ID",
      "variables": {
        "otp": "123456",
        "appName": "YourApp"
      }
    }
    """;

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.startmessaging.com/otp/send"))
    .header("Content-Type", "application/json")
    .header("X-API-Key", "sm_live_your_api_key_here")
    .POST(HttpRequest.BodyPublishers.ofString(body))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
package main

import (
  "bytes"
  "encoding/json"
  "fmt"
  "net/http"
  "io"
)

func main() {
  payload, _ := json.Marshal(map[string]interface{}{
    "phoneNumber": "+919876543210",
    "templateId":  "YOUR_TEMPLATE_ID",
    "variables": map[string]string{
      "otp":     "123456",
      "appName": "YourApp",
    },
  })

  req, _ := http.NewRequest("POST", "https://api.startmessaging.com/otp/send", bytes.NewBuffer(payload))
  req.Header.Set("Content-Type", "application/json")
  req.Header.Set("X-API-Key", "sm_live_your_api_key_here")

  resp, _ := http.DefaultClient.Do(req)
  defer resp.Body.Close()

  body, _ := io.ReadAll(resp.Body)
  fmt.Println(string(body))
}
FAQ

Send OTP Without DLT FAQ

Do I need any documents to sign up?

No. You can sign up with just an email address. No company registration, PAN card, GST certificate, or any other documents are required.

What phone number format should I use?

Use E.164 format: country code + number. For India, that is +91 followed by the 10-digit mobile number. Example: +919876543210.

How many OTPs can I send per second?

We support up to 20 OTPs per second globally per account. This ensures high throughput for production applications during peak times.

How long does an OTP remain valid?

OTPs expire after a configurable time window. The default expiry ensures security while giving users enough time to receive and enter the code.

What happens if SMS delivery fails?

StartMessaging automatically retries with a backup SMS provider. We only retry on service errors (5xx or timeout), not on validation errors like invalid phone numbers.

SMS & Auth API

Ready to Send Your First OTP?

Follow the steps above and go live in under 5 minutes. No DLT registration needed.