Omni SDK
Official client libraries for the Azmarq API. Install once, send SMS, WhatsApp, RCS, and OTP from your server. The SDK posts to https://api.azmarq.com with the apikey header. It does not change the HTTP contract on this hub.
There are two packages. Use azmarqomni in application code. Use azmarqomni-mcp only to expose Azmarq tools to Claude, Cursor, or an HTTP MCP host. Do not send a Bearer token to the Azmarq API.
Install
All seven languages are published. Server-side only — never put the API key in browser JavaScript.
| Language | Install | Import / use |
|---|---|---|
| TypeScript / Node.js 18+ | npm install azmarqomni | import { Azmarq } from "azmarqomni" |
| Python 3.9+ | pip install azmarqomni | from azmarq import Azmarq |
| Go | go get github.com/azmarq/azmarqomni | azmarqomni.New(...) |
| PHP | composer require azmarq/azmarqomni | new Azmarq\Azmarq(...) |
| Java | com.azmarq:azmarqomni:0.2.0 | new com.azmarq.omni.Azmarq(...) |
| C# | dotnet add package Azmarqomni | new Azmarqomni.Azmarq(...) |
| Ruby | gem install azmarqomni | Azmarqomni::Client.new(...) |
Python installs as azmarqomni and imports as azmarq. Node ships TypeScript types (.d.ts) with the package.
Install Node
npm install azmarqomni
Install Python
pip install azmarqomni
Current Node and Python package version is 0.2.0.
Authenticate
- Sign in to the Azmarq console.
- Open Developer → API Key.
- Copy the key. Do not commit it.
Auth uses the apikey header, not a Bearer token. The SDK sets that header for you. Your account must already have the channel enabled (sender ID, WhatsApp template, RCS bot, or OTP config). The SDK does not unlock a product you have not subscribed to.
Environment
export AZMARQ_API_KEY="your-api-key"
Node client
const { Azmarq } = require("azmarqomni");
const client = new Azmarq(); // reads AZMARQ_API_KEY
const clientWithKey = new Azmarq({ apiKey: "your-api-key" });
Python client
import os
from azmarq import Azmarq
client = Azmarq() # reads AZMARQ_API_KEY
client = Azmarq(api_key=os.environ["AZMARQ_API_KEY"])
See Authentication for the same key on raw HTTP.
Unified send
One send for the happy path. Channel helpers when you need templates, OTP, or RCS bots. Success returns messageId. The original API body stays on raw.
Send
import { Azmarq } from "azmarqomni";
import { pageMetadata } from '@/lib/seo'
export const metadata = pageMetadata('/sdk')
const client = new Azmarq();
const result = await client.send({
channel: "sms",
from: "SENDER",
to: "9800000001",
text: "Hello from Azmarq",
});
console.log(result.messageId);
to accepts a 10-digit local number, 91…, or +91. The SDK normalizes before the HTTP call. Default country code is 91. Override with defaultCountryCode / default_country_code.
| Input | SMS / OTP sent as | WhatsApp / RCS sent as |
|---|---|---|
9800000001 | 919800000001 | +919800000001 |
09800000001 | 919800000001 | +919800000001 |
+91 98000 00001 | 919800000001 | +919800000001 |
The same send({ channel }) works for WhatsApp and RCS. India SMS / DLT rules still apply: approved sender IDs and template registration stay upstream of the SDK.
Channel helpers
type is TRANS, PROMO, or OTP. Set unicode: 1 / unicode=1 for non-GSM text and flash: 1 / flash=1 for a flash SMS. A list of numbers is sent as a comma-separated MSISDN string.
SMS
Node SMS
await client.sms.send({
sender: "SENDER",
to: ["9800000001", "9800000002"],
text: "Hello from Azmarq",
type: "TRANS",
});
await client.sms.sendTemplate({
sender: "AOCAPI",
to: "9800000001",
templateId: "1507165650000000000",
custom: ["Ada", "ORD-1001"],
});
Python SMS
client.sms.send_template(
sender="AOCAPI",
to="919800000001",
template_id="1507165650000000000",
custom=["Ada", "ORD-1001"],
)
Payload fields for every SMS variant are on SMS.
OTP
Node OTP
const started = await client.verify.generate({
configId: "your-config-id",
to: "919800000001",
});
await client.verify.validate({ verifyId: started.data, otp: "123456" });
Python OTP
started = client.verify.generate(config_id="your-config-id", to="919800000001")
client.verify.validate(verify_id=started["data"], otp="123456")
HTTP generate/validate is on OTP.
Node WhatsApp
await client.whatsapp.sendTemplate({
from: "+919800000000",
to: "+919800000001",
templateName: "order_update",
components: { body: { params: ["Ada", "ORD-1001"] } },
});
Python WhatsApp
client.whatsapp.send_template(
from_="+919800000000",
to="+919800000001",
template_name="order_update",
components={"body": {"params": ["Ada", "ORD-1001"]}},
)
For a payload the helpers do not model (carousel, catalog, flow), post the documented JSON:
Documented JSON
await client.whatsapp.send({
from: "+919800000000",
to: "+919800000001",
type: "template",
templateName: "carousel_template",
components: {},
});
Template approval, the 24-hour window, and send routes are on WhatsApp.
RCS
Node RCS
await client.rcs.send({
number: "+919800000001",
templateName: "plane_text",
botId: "YOUR_BOT_ID",
type: "TRANS",
});
Python RCS
client.rcs.send(
number="+919800000001",
template_name="plane_text",
bot_id="YOUR_BOT_ID",
type="TRANS",
)
See RCS for bots, templates, and send.
Escape hatch
Anything the helpers do not model — pass the documented body through client.request:
Raw request
await client.request("POST", "/v1/whatsapp", { /* documented JSON */ });
Errors
Required fields, route type, WhatsApp template names, and phone length are checked before the HTTP call. error.field names the bad argument when the check is local. Catch AuthenticationError, InvalidRequestError, APIError, or ConnectionError. They all extend AzmarqError.
| Error | When |
|---|---|
AuthenticationError | Missing or unknown API key |
InvalidRequestError | Local validation failed, or the API returned 4xx / { error: true } |
APIError | 5xx from Azmarq |
ConnectionError | Network failure |
Retries stay off by default. Do not turn on maxRetries for send traffic — a retry can deliver the same message twice.
HTTP status bodies are on Errors.
Delivery webhooks
Parse SMS delivery JSON with parseSmsDelivery / parse_sms_delivery. Treat the webhook URL as a secret — the API does not define webhook signatures. Event shapes are on Webhooks.
MCP vs SDK
| Package | Use it for |
|---|---|
azmarqomni (this page) | Application code in Node, Python, Go, PHP, Java, C#, Ruby |
azmarqomni-mcp | Claude Desktop, Cursor, or a hosted MCP connector |
MCP wraps this SDK. It does not replace it. Setup is on Omni MCP.