REST + JSON • HTTPS • Webhooks

MessageFlow Developer API

One server-side integration for OTPs, account events, order updates, delivery notifications, payment alerts and custom transactional messages.

Security: Keep project API keys on your backend/server. Do not embed a private MessageFlow API key directly in Android, iOS, Flutter, React Native or browser JavaScript.

Getting Started

  1. Create a project.
  2. Add WhatsApp 1–5 sender profile(s).
  3. Connect each sender with Official Meta Cloud API or Scan QR — Linked Device.
  4. Generate a project API key.
  5. Run Launch Readiness and send a connection test.
  6. Integrate the REST endpoints from your backend.
  7. Optionally configure signed customer webhooks.

Production base URL: https://sms.adarshrupa.in/api/v1

Authentication

Use X-API-Key or a Bearer token containing the project API key.

POST /api/v1/messages/send
X-API-Key: mf_live_your_secret_key
Content-Type: application/json

The full API-key secret is shown only when created/rotated. Store it in a server-side secret manager or environment variable.

WhatsApp Connections

MethodBest useSetup
Official Meta Cloud APIProduction-critical business messagingWhatsApp 1–5 → Connect → Official Meta Cloud API → Save & Verify
Scan QR — Linked Device
Experimental
Optional WhatsApp / WhatsApp Business linked-device connectionWhatsApp 1–5 → Connect → Scan QR; phone → Linked devices → Link a device

Official Meta Cloud API

Provider credentials are stored encrypted. The sender is marked connected only after verification. Configure the callback URL shown in the dashboard for Meta delivery/read events.

Scan QR — Linked Device

Scan the QR using the phone's Linked devices screen. Session credentials remain on your server and are reused after normal service/server restarts. A WhatsApp logout/revocation can require a new QR scan.

Linked Device: this mode is not the official Meta server API. The local bridge listens only on 127.0.0.1:8091. Session files are credentials. Do not expose the bridge publicly, and do not use failover to bypass platform restrictions/rate limits or for spam/bulk messaging.

WhatsApp 1–5

Slots are availability backups. Auto-routing uses eligible healthy senders. Failover is for continuity; MessageFlow does not blindly rotate after ambiguous delivery failures.

API integration is sender-agnostic: your website/app calls the same MessageFlow endpoints whether the selected sender uses Meta Cloud or Linked Device.

Launch Readiness

The dashboard checks the project, active API key, connected healthy sender, background worker and optional customer webhook. If a project uses Linked Device, R13 also requires the local Linked Device bridge to report healthy before the project is shown as ready.

Use Send Test on a connected WhatsApp slot before integrating production traffic.

Send a Message

POST/api/v1/messages/send

{
  "to": "919876543210",
  "message": "Your order ORD1024 has been confirmed.",
  "idempotency_key": "ORDER-ORD1024-CONFIRMED"
}

Use a unique idempotency_key for each business event to protect against accidental duplicate requests.

OTP API

POST/api/v1/otp/send

POST/api/v1/otp/verify

OTP expiry, resend cooldown, verification-attempt limits and hashed storage are enforced server-side.

Message Status

GET/api/v1/messages/{message_id}

Typical states: queued, processing, retrying, sent, delivered, read, failed, awaiting_sender, awaiting_connection. Downstream delivery/read states depend on the active provider.

Conversation Inbox & Manual Messaging

Numbers that already have MessageFlow transactional history appear in Conversation Inbox. Automated and manual messages share one timeline. Authorized dashboard users can send a manual follow-up using Auto Sender or a selected sender slot.

Manual sends are logged with status and audit information.

Customer Webhooks

Supported events include message.sent, message.delivered, message.read, message.failed and otp.verified.

Deliveries are HMAC-SHA256 signed. Verify signatures before trusting payloads. Failed deliveries retry and eventually enter the dead-letter queue, where they can be redriven.

Security & Limits

  • Per-key requests/minute limits.
  • Optional exact-IP/CIDR allowlists.
  • Plan project/sender/monthly-message limits when enabled.
  • Login brute-force throttling and security-event logging.
  • HttpOnly/SameSite dashboard sessions.
  • Password changes/resets invalidate older sessions.
  • Linked Device bridge is loopback-only and internally authenticated.

Rate-limited requests return HTTP 429 and Retry-After where applicable.

Error Reference

CodeMeaning
INVALID_API_KEYUse a valid active project key.
API_KEY_IP_NOT_ALLOWEDSource IP is outside the key allowlist.
RATE_LIMITEDAPI-key request rate exceeded.
MESSAGE_LIMIT_REACHEDPlan message quota exhausted.
OTP_RESEND_COOLDOWNWait before requesting another OTP.
OTP_EXPIREDThe active OTP has expired.
LINKED_DEVICE_SEND_FAILEDLinked Device bridge/session could not send; inspect connection state and logs.

Troubleshooting

Linked Device QR does not appear

Confirm the linked-device service is active and the dashboard can reach the local bridge. The bridge must never be exposed through Nginx.

Linked Device says logged out

Open Connect → Scan QR again and relink from the phone.

Project is not Ready

Open Launch Readiness. Fix required blockers: active API key, sender connection, worker health, and Linked Device bridge health when applicable.

Message failed

Open Message Records for the provider error. Meta may require provider-approved templates/conversation rules; Linked Device failures can require reconnect/re-scan.

Code Samples

cURL

curl -X POST https://sms.adarshrupa.in/api/v1/messages/send \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $MESSAGEFLOW_API_KEY" \
  -d '{"to":"919876543210","message":"Order confirmed","idempotency_key":"ORDER-1024"}'

PHP / Laravel

$response = Http::withHeaders([
  'X-API-Key' => env('MESSAGEFLOW_API_KEY')
])->post('https://sms.adarshrupa.in/api/v1/messages/send', [
  'to' => '919876543210',
  'message' => 'Order confirmed',
  'idempotency_key' => 'ORDER-1024'
]);

Node.js

await fetch('https://sms.adarshrupa.in/api/v1/messages/send', {
  method: 'POST',
  headers: {'Content-Type':'application/json','X-API-Key':process.env.MESSAGEFLOW_API_KEY},
  body: JSON.stringify({to:'919876543210',message:'Order confirmed',idempotency_key:'ORDER-1024'})
});

Python

requests.post(
  'https://sms.adarshrupa.in/api/v1/messages/send',
  headers={'X-API-Key': os.environ['MESSAGEFLOW_API_KEY']},
  json={'to':'919876543210','message':'Order confirmed','idempotency_key':'ORDER-1024'}
)

Java / .NET

Send HTTPS JSON from your server and attach the project key as X-API-Key. See Interactive API for the complete schema.

Flutter / Kotlin / Swift

Call your own authenticated application backend. Keep the MessageFlow private API key on that backend, not in the mobile binary.