One messaging API for every customer channel
Send WhatsApp, SMS, voice and email messages, run verifications and receive events through a single REST API, with RCS coming soon. Predictable JSON and webhooks, with signed webhooks and a developer sandbox coming soon — so you integrate once and add channels without starting a new integration.
curl -X POST https://api.commleap.com/v1/messages \ -H "Authorization: Bearer $COMMLEAP_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 3b9d7a10-booking-8812" \ -d '{ "to": "+14165550142", "channel": "sms", "text": "Your table for 4 is confirmed for 7:30 pm. Reply C to cancel." }'
HTTP/1.1 202 Accepted { "id": "msg_4Rt8Lw2", "status": "queued", "channel": "sms", "to": "+14165550142", "segments": 1, "created_at": "2026-10-12T18:04:37Z" }
A CPaaS API with conventions you can predict
Every CommLeap endpoint follows the same rules for authentication, request format, errors and pagination. Learn them once and they apply across every channel.
- Base URL:
https://api.commleap.com/v1, JSON over HTTPS - Authentication: Bearer API keys, scoped by permission, with optional IP allow-listing
- Idempotency: an
Idempotency-Keyheader makes POST requests safe to retry - Pagination: cursor-based, with
limit,has_moreandnext_cursor - Errors: one consistent error object with a type, code, message and request ID
- Rate limits: reported in response headers, with HTTP 429 when a limit is reached
Base URL, endpoint paths, headers and field names on this page are illustrative. The full API reference is shared on request.
HTTP/1.1 422 Unprocessable Entity { "error": { "type": "invalid_request", "code": "template_not_approved", "message": "Template 'order_shipped' is not approved for language 'fr'.", "param": "template.language", "request_id": "req_9Fz3Kd1" } }
GET /v1/contacts?limit=50&cursor=c_eyJpZCI6IjgxMiJ9 { "data": [ { "id": "con_2Hs81", "phone": "+14165550117", "opt_in": ["whatsapp", "sms"] }, { "id": "con_2Hs82", "phone": "+14165550118", "opt_in": ["email"] } ], "has_more": true, "next_cursor": "c_eyJpZCI6IjgxNCJ9" }
From API keys to production traffic
The path to your first message is short. The path to production adds the checks that keep it reliable.
Get sandbox keys Coming soon
Request early sandbox access. When the sandbox launches, you will create a scoped API key for your test environment. Keep keys in a secret manager, not in source code.
Send your first message
Call POST /v1/messages with a recipient, a channel and your content or template. You get back a message ID and a queued status.
Handle webhooks
Register an HTTPS endpoint with POST /v1/webhooks and process delivery and inbound events asynchronously. Signature verification is coming soon.
Go live
Complete channel onboarding such as WhatsApp business verification or sender registration where required, switch to production keys and monitor your first traffic.
Send a WhatsApp template with SMS fallback Coming soon
The same request shape works for every channel. Set channel to whatsapp, sms or email (rcs coming soon) and pass a template or free-form content. An ordered fallback list for messages that must arrive is coming soon.
- Works with any HTTP client — no proprietary library required
- Template variables, media and interactive buttons in one model
- Every attempt reported through webhooks, including fallback attempts once fallback Coming soon launches
curl -X POST https://api.commleap.com/v1/messages \ -H "Authorization: Bearer $COMMLEAP_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: order-CL-48213-shipped" \ -d '{ "to": "+14165550123", "channel": "whatsapp", "template": { "name": "order_shipped", "language": "en", "variables": ["Aisha", "CL-48213"] }, "fallback": ["sms"] }'
const res = await fetch("https://api.commleap.com/v1/messages", { method: "POST", headers: { Authorization: `Bearer ${process.env.COMMLEAP_API_KEY}`, "Content-Type": "application/json", "Idempotency-Key": "order-CL-48213-shipped", }, body: JSON.stringify({ to: "+14165550123", channel: "whatsapp", template: { name: "order_shipped", language: "en", variables: ["Aisha", "CL-48213"], }, fallback: ["sms"], }), }); if (!res.ok) throw new Error((await res.json()).error.message); const { id, status } = await res.json(); // status: "queued"
import os import requests resp = requests.post( "https://api.commleap.com/v1/messages", headers={ "Authorization": f"Bearer {os.environ['COMMLEAP_API_KEY']}", "Idempotency-Key": "order-CL-48213-shipped", }, json={ "to": "+14165550123", "channel": "whatsapp", "template": { "name": "order_shipped", "language": "en", "variables": ["Aisha", "CL-48213"], }, "fallback": ["sms"], }, timeout=10, ) resp.raise_for_status() print(resp.json()["id"]) # msg_7Hq2xN4
<?php $payload = [ "to" => "+14165550123", "channel" => "whatsapp", "template" => [ "name" => "order_shipped", "language" => "en", "variables" => ["Aisha", "CL-48213"], ], "fallback" => ["sms"], ]; $ch = curl_init("https://api.commleap.com/v1/messages"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer " . getenv("COMMLEAP_API_KEY"), "Content-Type: application/json", "Idempotency-Key: order-CL-48213-shipped", ], CURLOPT_POSTFIELDS => json_encode($payload), ]); $message = json_decode(curl_exec($ch), true); echo $message["status"]; // queued
Core endpoints
A compact surface covers messaging, verification, voice, templates, contacts and webhook management. Paths are relative to https://api.commleap.com.
| Endpoint | What it does | Related events |
|---|---|---|
POST /v1/messages | Send a message on WhatsApp, SMS or email; RCS and optional ordered fallback Coming soon | message.sent, message.delivered, message.read, message.failed |
GET /v1/messages/{id} | Retrieve a message, its channel attempts and current status | — |
POST /v1/verify | Start a verification and send a one-time code by WhatsApp, SMS, voice or email | — |
POST /v1/verify/check | Check the code a user entered against an active verification | verification.approved, verification.failed |
POST /v1/calls | Place an outbound call for notifications, voice OTP or connecting parties | call.completed |
GET /v1/templatesPOST /v1/templates | List message templates and their approval status; create and submit new templates | — |
GET /v1/contactsPOST /v1/contacts | List contacts with cursor pagination; create or update contacts and their channel consent | — |
GET /v1/webhooksPOST /v1/webhooks | List and register webhook endpoints and choose the events each one receives | — |
Endpoint names and fields shown here are illustrative. The full API reference is shared on request.
Webhooks for every event that matters
CommLeap pushes status changes, inbound messages and verification results to your HTTPS endpoint as they happen. Signed webhooks Coming soon will add an HMAC signature header to each request, so you can prove it came from CommLeap before acting on it.
- HMAC-SHA256 signature over a timestamp and the raw request body Coming soon
- Automatic retries with exponential backoff when your endpoint fails
- A unique event ID on every delivery for safe de-duplication
- Per-endpoint event subscriptions; per-endpoint signing secrets Coming soon
POST /webhooks/commleap CommLeap-Signature: t=1760292131,v1=5f2b9c0e7a41d8... { "id": "evt_2Lk9pQ7", "event": "message.delivered", "created_at": "2026-10-12T18:02:11Z", "data": { "message_id": "msg_7Hq2xN4", "channel": "whatsapp", "to": "+14165550123", "status": "delivered", "delivered_at": "2026-10-12T18:02:10Z" } }
import crypto from "node:crypto"; import express from "express"; const app = express(); const secret = process.env.COMMLEAP_WEBHOOK_SECRET; app.post("/webhooks/commleap", express.raw({ type: "application/json" }), (req, res) => { const parts = Object.fromEntries( (req.get("CommLeap-Signature") ?? "").split(",").map((p) => p.split("=")) ); const expected = crypto .createHmac("sha256", secret) .update(`${parts.t}.${req.body}`) .digest("hex"); const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300; const valid = typeof parts.v1 === "string" && parts.v1.length === expected.length && crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected)); if (!fresh || !valid) return res.sendStatus(400); const event = JSON.parse(req.body); enqueue(event); // process async; de-duplicate on event.id res.sendStatus(200); });
import hashlib, hmac, os, time from flask import Flask, abort, request app = Flask(__name__) SECRET = os.environ["COMMLEAP_WEBHOOK_SECRET"].encode() @app.post("/webhooks/commleap") def commleap_webhook(): header = request.headers.get("CommLeap-Signature", "") parts = dict(p.split("=", 1) for p in header.split(",") if "=" in p) ts, sig = parts.get("t", "0"), parts.get("v1", "") signed = f"{ts}.".encode() + request.get_data() expected = hmac.new(SECRET, signed, hashlib.sha256).hexdigest() if abs(time.time() - int(ts)) > 300 or not hmac.compare_digest(expected, sig): abort(400) enqueue(request.get_json()) # process async; de-duplicate on event id return "", 200
| Event | Sent when |
|---|---|
message.sent | A message has been handed to the channel or carrier |
message.delivered | The channel or carrier reports the message as delivered |
message.read | The recipient has read the message, on channels that report read receipts and where the recipient has them enabled |
message.failed | Delivery failed on a channel, with an error code (and whether fallback was attempted, once fallback Coming soon launches) |
message.inbound | A customer sends a message, button reply or form response |
verification.approved | A user entered a correct code for an active verification |
verification.failed | A verification expired or ran out of permitted attempts |
call.completed | An inbound or outbound call has ended, with duration and outcome |
conversation.assigned | A conversation in the Omnichannel Inbox is assigned to an agent or team |
The details that keep integrations reliable at scale
Sending one message is easy. Sending the right message once, observing what happened and recovering from failure is where a messaging API earns its place.
Idempotent requests
Retry a POST with the same Idempotency-Key after a timeout or network error and receive the original result instead of creating a duplicate message.
Retries and backoff
Webhook deliveries are retried with exponential backoff. HTTP 429 responses and rate-limit headers tell your client when to slow down and when to try again.
Observability
Every response carries a request ID. Message logs, channel attempts and webhook delivery history in the dashboard help keep support tickets short.
Separate environments Coming soon
A developer sandbox with keys and data separate from production will let you test templates, fallback rules and webhook handling without touching live customers.
Scoped credentials
Issue API keys limited to the permissions a service needs, and restrict them to known IP ranges with allow-listing.
Built-in security controls
HTTPS-only endpoints and scoped keys support your security reviews, with signed webhooks and audit trails for key and configuration changes coming soon. Read about security.
Connect CommLeap without writing a full integration
Not every workflow needs custom code. Webhooks and standard HTTP make CommLeap easy to connect to the systems your teams already use.
Webhooks to any endpoint
Point events at your CRM, helpdesk, data pipeline or serverless function. Anything that can receive an HTTPS request can react to a delivery, reply or verification.
iPaaS and automation tools
Connect through tools such as Zapier or Make using their HTTP and webhook steps — for example, to send a WhatsApp update when a deal closes or log inbound messages to a spreadsheet. Step availability depends on your plan with each provider.
Applications for business teams
The Omnichannel Inbox, Conversational AI Coming soon and Campaigns run on the same API, so teams can work without code and developers can extend them later.
Full API reference on request, sandbox access Coming soon
The complete API reference, including every field, error code and event schema, is shared on request, and sandbox credentials will follow when the developer sandbox launches. Tell us which channels and use cases you are building for and an engineer will get you set up. Request early sandbox access.
Developer questions, answered
Do you provide official SDKs?
You don't need one to get started. The CommLeap API is a standard REST API that accepts and returns JSON over HTTPS, so it works with any HTTP client in any language. The examples on this page use cURL, Node.js with fetch, Python with requests and PHP with cURL.
How do I get sandbox access?
The developer sandbox is coming soon. Request early access through our contact form and tell us which channels you want to test. When it launches, sandbox keys will be separate from production keys, and sandbox traffic will be isolated from your live traffic. Request early sandbox access.
How are webhooks secured?
Webhooks are delivered to the HTTPS endpoints you register. Signed (HMAC) webhooks are coming soon: each request will carry an HMAC signature header computed with a secret unique to your endpoint, and your server should recompute the signature over the timestamp and raw request body, compare it in constant time and reject requests that don't match or are too old.
What happens if our webhook endpoint is unavailable?
Failed deliveries are retried with exponential backoff. Each event carries a unique ID, so your handler can safely ignore duplicates. You can also retrieve the current status of any message with GET /v1/messages/{id} to reconcile after an outage.
How do rate limits work?
Rate limits are communicated through response headers. If you exceed a limit, the API returns HTTP 429 and indicates when to retry. Limits depend on your account and environment, and channel-level limits — such as WhatsApp messaging limits set by Meta — also apply.
How do we avoid sending the same message twice?
Send an Idempotency-Key header with each POST request. If a request is retried with the same key — after a timeout, for example — the API returns the original result instead of creating a second message.
Can we use one integration for every channel?
Yes. The same authentication, error format and webhook events cover WhatsApp, SMS, Voice and Email, with RCS coming soon, and one message endpoint handles WhatsApp, SMS and email. You choose a channel per request, and ordered fallback lists are coming soon. Adding a channel does not mean starting a new integration, although channel onboarding such as WhatsApp business verification or sender registration may still apply.
Is the API versioned?
Yes. The version is part of the base URL, for example https://api.commleap.com/v1. Breaking changes are introduced under a new version rather than changed in place, and additive changes such as new fields or event types can appear within a version.
Explore the channels behind the API
WhatsApp Business API
Two-way WhatsApp messaging at enterprise scale — templates, Flows, catalogs and automation.
Learn moreVerify API
One-time passwords over WhatsApp, SMS, voice and email; automatic fallback and fraud controls coming soon.
Learn moreSecurity & trust
Encryption, access controls and compliance support; SSO and audit logs coming soon.
Learn moreStart building on CommLeap
Plan your integration and your move to production with an engineer who knows the channels. The developer sandbox is coming soon, so request early access now.
- Solution design with a named specialist
- WhatsApp onboarding and verification support
- Transparent, volume-based pricing