API documentation

One REST API for every service. JSON in, JSON out, a bearer key, and the same response for everything.

Overview

Base URL: https://nexcoddigital.in/api/v1/

Every service — SMS, OTP, WhatsApp, email, voice, KYC, payments, recharge, utility — is called the same way: POST /services/{CODE} with its parameters as JSON. The price comes from your wallet; if the request fails you are refunded at once.

Authentication

Create keys in your account under API keys. Send the key in the Authorization header (or X-API-Key). Keys are shown once; keep them on your server, never in an app or web page.

Authorization: Bearer nxd_live_9f2c…

Keys can be locked to your server IPs. Calls from any other IP get ip_not_allowed.

Sandbox

Keys that start with nxd_test_ run in the sandbox: parameters are checked exactly as in live, a success response is returned, no provider is called and nothing is charged. KYC is not needed for test keys. You can also try every service from the API console.

POST/services/{CODE}

Runs a service. Put its parameters at the top level of the JSON body (or inside "params"). Add an optional client_ref — your own id for the request, up to 64 characters.

curl -X POST https://nexcoddigital.in/api/v1//services/SMS_TXN \
  -H "Authorization: Bearer nxd_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "mobile": "9876543210",
    "message": "Your order 1024 is confirmed.",
    "template_id": "1707160000000000000",
    "client_ref": "order-1024"
  }'

Services with amount + fee charging (recharge, bill payment, payout) take an amount in rupees; your wallet is debited the amount plus the service fee.

GET/transactions/{REF}

Returns one request by our reference — use it to check a pending request. GET/transactions?client_ref=order-1024 finds it by your id; without a filter it lists your latest requests (limit up to 100).

GET/balance

{ "ok": true, "balance": 4821.64, "currency": "INR", "account": "NXD10024", "mode": "live" }

GET/services

Every service available to you with your price, its unit, charging type, status and parameter list.

Response

Every request answers HTTP 200 with this shape when it was processed, whether the provider succeeded or not. Check ok and status.

{
  "ok": true,
  "ref": "NXD7K2M9QH4TPX",        // our reference
  "client_ref": "order-1024",
  "service": "SMS_TXN",
  "status": "success",           // success | pending | refunded
  "mode": "live",
  "charged": 0.18,
  "balance": 4821.64,
  "provider_ref": "a1b2c3",
  "data": { },                     // service-specific fields
  "created_at": "2026-10-21T10:15:00+05:30"
}
statusMeaning
successDone. Charged.
pendingAccepted by the provider, final result not yet known (common for recharge and payouts). Charged now; if it finally fails it is refunded to your wallet. You get a webhook either way.
refundedFailed. ok is false, error says why, nothing was charged.

Errors

Requests that are refused before processing return {"ok": false, "error": {"code", "message"}} with the HTTP status below.

codeHTTPMeaning
unauthorized401Missing, malformed or revoked API key.
account_inactive403The account is suspended or waiting for approval.
ip_not_allowed403The calling IP is not on the key's whitelist.
kyc_required403Live keys need verified KYC. Test keys work without it.
service_not_found404No service with that code. List them with GET /services.
missing_params422A required parameter is missing.
invalid_param422A parameter is not in the expected format.
invalid_json400The request body is not valid JSON.
insufficient_balance402The wallet cannot cover the request. Nothing was charged.
daily_limit_reached429The account's daily spend cap is reached.
rate_limited429More than the per-minute limit (default 120) for this key. Retry after 60 seconds.
service_maintenance503The service is paused for maintenance.
request_failed200The provider could not complete it. ok is false, status is refunded, and you were not charged.

Idempotency

Send the same client_ref again — after a timeout, say — and you get the first request's result back with "duplicate": true. It is never run or charged twice.

Webhooks

Add HTTPS endpoints under Webhooks. We POST JSON for these events:

EventWhen
transaction.successRequest succeeded
transaction.failedRequest failed
transaction.pendingRequest pending
transaction.refundedRequest refunded
wallet.creditedWallet credited
wallet.low_balanceWallet balance low

Headers: X-Nexcod-Event, X-Nexcod-Timestamp and X-Nexcod-Signature: sha256=…, the HMAC-SHA256 of timestamp + "." + raw body with the endpoint's secret. Answer 2xx within 10 seconds; otherwise we retry after 1, 5, 30, 120 and 360 minutes.

// Node.js (Express, raw body)
const crypto = require('crypto');
const sig = crypto.createHmac('sha256', process.env.NEXCOD_WEBHOOK_SECRET)
  .update(req.get('X-Nexcod-Timestamp') + '.' + req.rawBody).digest('hex');
if ('sha256=' + sig !== req.get('X-Nexcod-Signature')) return res.sendStatus(401);

Limits

120 requests a minute per key by default (ask support to raise it). Accounts can also carry a daily spend cap. Over the limit you get HTTP 429 with Retry-After: 60.

Code samples

Python

import os, requests
r = requests.post("https://nexcoddigital.in/api/v1//services/KYC_PAN",
    headers={"Authorization": "Bearer " + os.environ["NEXCOD_KEY"]},
    json={"pan": "ABCDE1234F", "client_ref": "kyc-77"}, timeout=40)
res = r.json()
if res["ok"]: print(res["data"])

Node.js

const res = await fetch('https://nexcoddigital.in/api/v1//services/RC_MOBILE', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.NEXCOD_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ mobile: '9876543210', operator: 'JIO', amount: '299', client_ref: 'rc-501' }),
}).then(r => r.json());

Service catalogue

Codes and parameters. * = required. Your prices are in your account and in GET /services.

Email

EMAIL_SEND · Transactional email (coming soon)fixed price, per email
to *To email — e.g. customer@example.com
subject *Subject — e.g. Your invoice
html *HTML body — e.g. <p>Hello</p>
from_nameFrom name — e.g. Your Brand

KYC & Verification

KYC_PAN · PAN verification (coming soon)fixed price, per check
pan *PAN — e.g. ABCDE1234F
nameName to match — e.g. Ravi Kumar
KYC_GSTIN · GSTIN verification (coming soon)fixed price, per check
gstin *GSTIN — e.g. 27ABCDE1234F1Z5
KYC_BANK · Bank account verification (coming soon)fixed price, per check
account *Account number — e.g. 50100012345678
ifsc *IFSC — e.g. HDFC0001234
KYC_UPI · UPI ID verification (coming soon)fixed price, per check
vpa *UPI ID — e.g. name@bank

Other APIs

LOOKUP_IFSC · IFSC lookup (coming soon)fixed price, per lookup
ifsc *IFSC — e.g. HDFC0001234
LOOKUP_PINCODE · Pincode lookup (coming soon)fixed price, per lookup
pincode *Pincode — e.g. 110001

OTP

OTP_SMS · OTP over SMS (coming soon)fixed price, per OTP
mobile *Mobile number — e.g. 9876543210
otpOTP (leave empty to let us generate it) — e.g. 482913
template_idDLT template ID — e.g. 1707160000000000000
OTP_VOICE · OTP over voice call (coming soon)fixed price, per call
mobile *Mobile number — e.g. 9876543210
otp *OTP — e.g. 482913

Payments

PAY_LINK · Payment link (coming soon)fixed price, per link
amount *Amount (₹) — e.g. 499.00
purpose *Purpose — e.g. Invoice 1024
mobileCustomer mobile — e.g. 9876543210
emailCustomer email — e.g. customer@example.com
PAYOUT_IMPS · Payout (IMPS) (coming soon)amount + fee, per payout
amount *Amount (₹) — e.g. 1000.00
account *Account number — e.g. 50100012345678
ifsc *IFSC — e.g. HDFC0001234
name *Beneficiary name — e.g. Ravi Kumar

Recharge

RC_MOBILE · Mobile recharge (coming soon)amount + fee, per recharge
mobile *Mobile number — e.g. 9876543210
operator *Operator — e.g. JIO
amount *Amount (₹) — e.g. 299
circleCircle — e.g. DL
RC_DTH · DTH recharge (coming soon)amount + fee, per recharge
subscriber_id *Subscriber ID — e.g. 1234567890
operator *Operator — e.g. TATAPLAY
amount *Amount (₹) — e.g. 350

SMS

SMS_TXN · Transactional SMS (coming soon)fixed price, per SMS
mobile *Mobile number — e.g. 9876543210
message *Message text — e.g. Your order 1024 is confirmed.
template_idDLT template ID — e.g. 1707160000000000000
senderSender ID — e.g. NEXCOD
SMS_PROMO · Promotional SMS (coming soon)fixed price, per SMS
mobile *Mobile number — e.g. 9876543210
message *Message text — e.g. Flat 20% off this weekend.
template_idDLT template ID — e.g. 1707160000000000000

Utility & BBPS

BILL_FETCH · Bill fetch (BBPS) (coming soon)fixed price, per fetch
biller_id *Biller ID — e.g. MSEDCL000MAH01
consumer_no *Consumer number — e.g. 170012345678
BILL_PAY · Bill payment (BBPS) (coming soon)amount + fee, per payment
biller_id *Biller ID — e.g. MSEDCL000MAH01
consumer_no *Consumer number — e.g. 170012345678
amount *Amount (₹) — e.g. 1240.00
FASTAG · FASTag recharge (coming soon)amount + fee, per recharge
vehicle_no *Vehicle number — e.g. MH12AB1234
operator *FASTag bank — e.g. ICICI
amount *Amount (₹) — e.g. 500

Voice

VOICE_CALL · Voice broadcast call (coming soon)fixed price, per call
mobile *Mobile number — e.g. 9876543210
audio_urlAudio URL — e.g. https://example.com/msg.mp3
textText to speak — e.g. Your appointment is tomorrow at 10 AM.

WhatsApp

WA_TEMPLATE · WhatsApp template message (coming soon)fixed price, per message
mobile *Mobile number — e.g. 9876543210
template *Template name — e.g. order_update
variablesVariables (comma separated) — e.g. Ravi,1024
media_urlMedia URL — e.g. https://example.com/invoice.pdf
WA_TEXT · WhatsApp session message (coming soon)fixed price, per message
mobile *Mobile number — e.g. 9876543210
message *Message text — e.g. Thanks, your ticket is resolved.