Integration checklist

OTP integration and testing checklist

Keep API credentials server-side, validate phone numbers, throttle retries, expire OTPs, protect user data, check delivery statuses and match approved sender headers and templates. Test invalid requests and failed deliveries before production.

</> Indian Developer Integration Hub

OTP SMS API Documentation for Developers

Integrate an OTP SMS API for developers into PHP, Node.js, Python or Laravel. Follow the examples for SMS API authentication, OTP requests and delivery statuses. Keep keys server-side and test approved templates, errors and retry behavior before production.

Monitor API response time
Live Webhook Delivery Receipts
Review Active Wallet & Prepaid Plans
POST https://nizorasms.com/api/v1/otp/send
Sample JSON Response (HTTP 200)
{
  "status": "success",
  "job_id": "job_94a8e2b19f03",
  "phone": "919876543210",
  "units_deducted": 1,
  "balance_remaining": "₹482.40",
  "operator_route": "AIRTEL_PRIORITY",
  "dispatched_at": "2026-10-13T10:14:02.418Z"
}

OTP SMS REST API integration examples for popular backend stacks

Pick your language below and start verifying users in production within minutes.

PHP Native Implementation otp_sender.php
<?php
declare(strict_types=1);

$apiKey = 'YOUR_NIZORA_API_KEY';
$payload = json_encode([
    'phone' => '919876543210',
    'otp' => '482910',
    'template_id' => 'TPL_LOGIN_VERIFY'
]);

$ch = curl_init('https://nizorasms.com/api/v1/otp/send');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json'
    ],
    CURLOPT_TIMEOUT => 5
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$result = json_decode((string)$response, true);
if ($httpCode === 200 && ($result['status'] ?? '') === 'success') {
    echo "OTP Sent Successfully! Job ID: " . $result['job_id'];
} else {
    echo "Failed to send OTP: " . ($result['message'] ?? 'Unknown error');
}
Laravel HTTP Client app/Services/OtpService.php
<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;

class OtpService
{
    public function sendOtp(string $phone, string $otp): bool
    {
        $response = Http::withToken(config('services.nizorasms.api_key'))
            ->post('https://nizorasms.com/api/v1/otp/send', [
                'phone' => $phone,
                'otp' => $otp,
                'template_id' => 'TPL_LOGIN_VERIFY',
            ]);

        return $response->successful() && $response->json('status') === 'success';
    }
}
Node.js / Express services/nizoraSms.js
const axios = require('axios');

async function dispatchOtp(phone, otpCode) {
  try {
    const response = await axios.post(
      'https://nizorasms.com/api/v1/otp/send',
      {
        phone: phone,
        otp: otpCode,
        template_id: 'TPL_LOGIN_VERIFY'
      },
      {
        headers: {
          'Authorization': `Bearer ${process.env.NIZORA_API_KEY}`,
          'Content-Type': 'application/json'
        },
        timeout: 5000
      }
    );

    return response.data;
  } catch (error) {
    console.error('NizoraSMS Error:', error.response?.data || error.message);
    throw error;
  }
}

module.exports = { dispatchOtp };
Python (requests) otp_client.py
import requests

def send_otp(phone: str, otp_code: str) -> dict:
    url = "https://nizorasms.com/api/v1/otp/send"
    headers = {
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json"
    }
    payload = {
        "phone": phone,
        "otp": otp_code,
        "template_id": "TPL_LOGIN_VERIFY"
    }
    
    response = requests.post(url, json=payload, headers=headers, timeout=5)
    response.raise_for_status()
    return response.json()

# Example usage
# res = send_otp("919876543210", "591024")
# print("Job:", res.get("job_id"))
Flutter (Dart) lib/services/sms_service.dart
import 'dart:convert';
import 'package:http/http.dart' as http;

// Your own authenticated backend proxies SMS requests and stores the secret API key.
class NizoraSmsService {
  static const String _backend = 'https://YOUR_APP_DOMAIN/api/send-otp';

  static Future<bool> requestOtp(String phone) async {
    final response = await http.post(
      Uri.parse(_backend),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'phone': phone}),
    );
    return response.statusCode == 200;
  }
}

// Protect this endpoint with authentication, rate limiting and anti-abuse checks.
// Do not put NizoraSMS API credentials or raw OTP verification logic in client code.
Java (OkHttp 3) NizoraClient.java
import okhttp3.*;
import java.io.IOException;

public class NizoraClient {
    private static final OkHttpClient client = new OkHttpClient();

    public static void sendOtp(String phone, String otp) throws IOException {
        MediaType JSON = MediaType.get("application/json; charset=utf-8");
        String json = "{\"phone\":\"" + phone + "\",\"otp\":\"" + otp + "\",\"template_id\":\"TPL_LOGIN_VERIFY\"}";

        RequestBody body = RequestBody.create(json, JSON);
        Request request = new Request.Builder()
                .url("https://nizorasms.com/api/v1/otp/send")
                .header("Authorization", "Bearer YOUR_API_KEY")
                .post(body)
                .build();

        try (Response response = client.newCall(request).execute()) {
            System.out.println("Response: " + response.body().string());
        }
    }
}
cURL Terminal Command CLI Terminal
curl -X POST https://nizorasms.com/api/v1/otp/send \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "919876543210",
    "otp": "839120",
    "template_id": "TPL_LOGIN_VERIFY"
  }'

Standard API Response & Error Codes

Predictable JSON status codes for effortless error handling in your backend.

HTTP Code Status Code Description Recommended Action
200 OK success OTP accepted & pushed to carrier pipe Store job_id for delivery receipt reconciliation
400 Bad Request ERR_INVALID_PHONE Mobile number format invalid or missing country code Validate 10-digit Indian number before request
401 Unauthorized ERR_INVALID_KEY Bearer token missing, expired, or invalid Verify your API key in the NizoraSMS panel
402 Payment Required ERR_LOW_BALANCE Purchased plan entitlement or available sending quota is insufficient Check your active plan and usage in the dashboard
429 Rate Limited ERR_RATE_LIMIT Too many requests within sliding window Respect throttle headers or request quota increase

Frequently Asked Questions — Developer API Integration

Everything Indian developers need to know about API quotas, libraries, and carrier delivery.

How long does it take to integrate NizoraSMS OTP API?

Integration time varies by your backend, credentials, approved message templates and testing. Review the request, authentication and error-handling documentation before launching.

Which programming languages and frameworks are supported?

A server-side REST client can typically be built in PHP, Node.js, Python, Laravel, Java or other languages. Verify endpoint parameters and credentials in the current documentation.

How do I handle OTP delivery webhooks (DLR callbacks)?

Configure a callback URL if delivery webhooks are enabled for your account. Confirm the callback format, authentication and delivery-event behavior during integration testing; delivery timing varies by provider and network.

What is the API response time and delivery latency?

API response time and handset delivery time depend on network conditions, template approval, traffic and carrier routing. Measure both separately using test traffic and delivery reports; no fixed delivery-time guarantee is implied.

How do I integrate an OTP SMS API with PHP, Laravel or Node.js?

Make an authenticated HTTPS request from your backend, supply the mobile number and the account-approved OTP template, store the request ID for delivery status and validate the OTP on your own server. The API examples below illustrate these steps; confirm exact fields in your account.

Should I put OTP SMS API credentials in a Flutter or Android app?

No. A mobile app or browser should call your own backend. Keep the messaging API key on the server and set rate limits, authentication and OTP expiration in the application.

Start Integrating in Production Today

Sign up, review the API guide and approved OTP template requirements, then test your integration with your assigned credentials.

Create Developer Account →