Introduction
The Email SaaS Cloud platform exposes a REST API for transactional email, SMS, WhatsApp Cloud, WebChat, billing catalog, and marketing analytics. External integrations authenticate with organization API keys (Bearer token). Workspace control-plane routes use browser session cookies or JWT after sign-in.
GEThttps://api.commtunnel.cloud/v1/public/openapi.json
OpenAPI specification
Machine-readable contract for public send and read endpoints. Download for client generation and CI contract tests.
Authentication: None
Response
Status: 200
{ "openapi": "3.0.3", "info": { "title": "Email SaaS Public API" }, ... }
POSThttps://api.commtunnel.cloud/v1/public/emails/send
Authentication (API key)
Send `Authorization: Bearer <api_key>` on public routes. Keys are scoped (for example `send:email`, `read:email`, `send:sms`, `read:sms`, `send:whatsapp`, `read:whatsapp`). Organization IP allowlists apply when configured.
Authentication: Bearer API key
Create and rotate keys in the workspace under Integration and APIs after sign-in.
Optional header `x-idempotency-key` deduplicates send requests within the retention window.
GEThttps://api.commtunnel.cloud—
Error envelope
Failed requests return JSON with `error`, `code`, and `requestId`. Validation failures include a `details` object.
Response
Status: 4xx / 5xx
{
"error": "Origin not allowed",
"code": "MARKETING_ORIGIN_DENIED",
"requestId": "abc123"
}
Email (public API)
Queue, preview, and inspect transactional email using scoped API keys.
POSThttps://api.commtunnel.cloud/v1/public/emails/send
Send email
Queue an email for delivery. Returns 202 with external id when accepted.
Authentication: Bearer API key
Scopes: send:email
Request body
| Name | Type | Description |
|---|
fromRequired | string (email) | Verified sender address for your organization. |
toRequired | string (email) | Recipient address. |
subjectRequired | string | Message subject line. |
html | string | HTML body (provide html and/or text). |
text | string | Plain-text body. |
templateId | string (uuid) | Use a workspace template instead of inline body. |
variables | object | Template merge variables. |
tracking | boolean | Enable open/click tracking pixels and link wrapping. |
sandboxMode | boolean | Persist and audit without delivery. |
idempotencyKey | string | Client-supplied deduplication key. |
Response
Status: 202
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "QUEUED",
"createdAt": "2026-06-03T12:00:00.000Z",
"duplicate": false
}
POSThttps://api.commtunnel.cloud/v1/public/emails/preview
Preview email
Render subject and bodies without queuing delivery. Useful for template QA.
Authentication: Bearer API key
Scopes: send:email
Request body
| Name | Type | Description |
|---|
subject | string | Subject to render. |
html | string | HTML source. |
text | string | Plain-text source. |
templateId | string (uuid) | Template to render. |
variables | object | Merge fields. |
Response
Status: 200
{
"subject": "Welcome",
"html": "<p>Hello</p>",
"text": "Hello",
"trackingEnabled": true,
"estimatedSizeBytes": 842,
"moderation": { "blocked": false, "token": null }
}
GEThttps://api.commtunnel.cloud/v1/public/emails/{externalId}
Get email status
Fetch delivery state and metadata for a queued message.
Authentication: Bearer API key
Scopes: read:email
Path parameters
| Name | Type | Description |
|---|
externalIdRequired | string | Id returned from send. |
GEThttps://api.commtunnel.cloud/v1/public/emails/{externalId}/timeline
Email event timeline
List lifecycle events (queued, sent, delivered, opened, clicked, bounced, etc.).
Authentication: Bearer API key
Scopes: read:email
Path parameters
| Name | Type | Description |
|---|
externalIdRequired | string | Email external id. |
Query parameters
| Name | Type | Description |
|---|
limit | integer | Max events (default 100). |
GEThttps://api.commtunnel.cloud/v1/public/emails/stats
Delivery stats
Aggregate status counts for a time window.
Authentication: Bearer API key
Scopes: read:email
Query parameters
| Name | Type | Description |
|---|
startRequired | string (date-time) | Window start (ISO 8601). |
endRequired | string (date-time) | Window end (ISO 8601). |
SMS (public API)
Send standard and OTP SMS through approved sender IDs. Recipients on your opt-out list receive HTTP 403 with `SMS_RECIPIENT_OPTED_OUT`.
POSThttps://api.commtunnel.cloud/v1/public/sms/send
Send SMS
Queue an outbound SMS. `senderId` must match an organization-approved sender or the platform default.
Authentication: Bearer API key
Scopes: send:sms
Request body
| Name | Type | Description |
|---|
toRequired | string | E.164 recipient, e.g. +23451234567. |
senderIdRequired | string | Alphanumeric ≤11 or numeric ≤16 characters. |
bodyRequired | string | Message text (up to 1600 characters). |
sendType | integer | 0=Normal, 1=Flash, 2=Unicode. |
idempotencyKey | string | Optional deduplication key. |
Response
Status: 202
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"senderId": "ACME",
"status": "QUEUED",
"createdAt": "2026-06-03T12:00:00.000Z",
"duplicate": false,
"segments": 1,
"encoding": "GSM7"
}
403 `SMS_SENDER_ID_NOT_APPROVED` when sender is not approved for the tenant.
POSThttps://api.commtunnel.cloud/v1/public/sms/otp/send
Send OTP SMS
Queue a one-time passcode SMS using an OTP-approved brand name.
Authentication: Bearer API key
Scopes: send:sms
Request body
| Name | Type | Description |
|---|
toRequired | string | E.164 mobile number. |
brandNameRequired | string | OTP brand (3–20 chars); must be approved for the org. |
otpCodeRequired | string | Numeric OTP, 4–8 digits. |
purpose | string | LOGIN | PHONE_VERIFICATION | PASSWORD_RESET (default PHONE_VERIFICATION). |
Response
Status: 202
{
"id": "770e8400-e29b-41d4-a716-446655440002",
"status": "QUEUED",
"cooldownSeconds": 60
}
GEThttps://api.commtunnel.cloud/v1/public/sms/{externalId}
Get SMS status
Get SMS status
Authentication: Bearer API key
Scopes: read:sms
Path parameters
| Name | Type | Description |
|---|
externalIdRequired | string | SMS external id. |
GEThttps://api.commtunnel.cloud/v1/public/sms/{externalId}/timeline
SMS event timeline
SMS event timeline
Authentication: Bearer API key
Scopes: read:sms
Path parameters
| Name | Type | Description |
|---|
externalIdRequired | string | SMS external id. |
Query parameters
| Name | Type | Description |
|---|
limit | integer | Max events (default 100). |
POSThttps://api.commtunnel.cloud/v1/public/sms/{externalId}/retry
Retry failed SMS
Re-queue a failed message when eligible.
Authentication: Bearer API key
Scopes: send:sms
Path parameters
| Name | Type | Description |
|---|
externalIdRequired | string | Failed SMS external id. |
SMS inbound (MO receive)
When you operate two-way SMS with an inbound shortcode or longcode, carriers POST mobile-originated (MO) messages to your configured URL. The platform normalizes opt-out keywords and can route conversational replies into inbound tickets. Payload shape follows common aggregator conventions (see Hollatags MO receive).
POSThttps://your-inbound-url.example/mo
Receive inbound SMS (MO)
Configure your inbound URL with the SMS aggregator. Incoming MO messages are POSTed as form fields or JSON depending on provider. Respond with JSON containing `sms_message` to reply in-session to the originating handset.
Authentication: Provider-configured (URL + optional token)
Request body
| Name | Type | Description |
|---|
sms_fromRequired | integer / string | Originating mobile number. |
sms_toRequired | string | Your shortcode or longcode number. |
sms_messageRequired | string | Inbound SMS text content. |
Response
Status: 200
{ "sms_message": "Thank you for your reply." }
Only `sms_message` is required in the JSON response; it is delivered back to the originating mobile (session `sms_from`).
Platform webhook `POST /v1/webhooks/sms/inbound-opt-out` records STOP/UNSUBSCRIBE keywords when MO traffic is forwarded with organization context.
WhatsApp Cloud (public API)
Send and inspect WhatsApp Cloud API messages. Requires platform `WHATSAPP_*` configuration and organization line setup.
POSThttps://api.commtunnel.cloud/v1/public/whatsapp/send
Send WhatsApp message
Hand off a text message to Meta Graph synchronously.
Authentication: Bearer API key
Scopes: send:whatsapp
Request body
| Name | Type | Description |
|---|
toRequired | string | International number (digits with country code). |
bodyRequired | string | Message text (max 4096). |
idempotencyKey | string | Duplicate key returns 200 with existing id. |
Response
Status: 201
{
"id": "880e8400-e29b-41d4-a716-446655440003",
"status": "SENT",
"duplicate": false,
"providerMessageId": "wamid.xxx"
}
GEThttps://api.commtunnel.cloud/v1/public/whatsapp/{externalId}
Get WhatsApp status
Get WhatsApp status
Authentication: Bearer API key
Scopes: read:whatsapp
Path parameters
| Name | Type | Description |
|---|
externalIdRequired | string | Message external id. |
GEThttps://api.commtunnel.cloud/v1/public/whatsapp/{externalId}/timeline
WhatsApp timeline
WhatsApp timeline
Authentication: Bearer API key
Scopes: read:whatsapp
Path parameters
| Name | Type | Description |
|---|
externalIdRequired | string | Message external id. |
Query parameters
| Name | Type | Description |
|---|
limit | integer | Max events (default 100). |
POSThttps://api.commtunnel.cloud/v1/public/whatsapp/{externalId}/retry
Retry WhatsApp message
Retry WhatsApp message
Authentication: Bearer API key
Scopes: send:whatsapp
Path parameters
| Name | Type | Description |
|---|
externalIdRequired | string | Failed message id. |
WebChat (public widget API)
Visitor-facing routes mounted under `/v1/public/chat/*`. Used by the embedded widget; not API-key authenticated.
GEThttps://api.commtunnel.cloud/v1/public/chat-widget.js
Widget script
JavaScript bundle for embedding WebChat on your site.
Authentication: None
GEThttps://api.commtunnel.cloud/v1/public/chat/widget-config
Widget configuration
Widget configuration
Authentication: None
Query parameters
| Name | Type | Description |
|---|
publicKeyRequired | string | Inbox public key from Chat Settings. |
POSThttps://api.commtunnel.cloud/v1/public/chat/session
Create visitor session
Starts a conversation after optional captcha verification. Origin must match inbox allowlist.
Authentication: None
Request body
| Name | Type | Description |
|---|
publicKeyRequired | string | Widget public key. |
captchaToken | string | Captcha token when required. |
honeypot | string | Must be empty; bots are rejected. |
Response
Status: 201
{
"sessionToken": "eyJ...",
"conversationId": "uuid",
"expiresAt": "2026-06-03T13:00:00.000Z"
}
POSThttps://api.commtunnel.cloud/v1/public/chat/verify
Verify visitor identity
Verify visitor identity
Authentication: Bearer session token
Request body
| Name | Type | Description |
|---|
nameRequired | string | Visitor display name. |
emailRequired | string (email) | Visitor email for CRM profile. |
GEThttps://api.commtunnel.cloud/v1/public/chat/messages
List messages
List messages
Authentication: Bearer session token
Query parameters
| Name | Type | Description |
|---|
since | string (ISO date-time) | Incremental sync cursor. |
POSThttps://api.commtunnel.cloud/v1/public/chat/messages
Send visitor message
Send visitor message
Authentication: Bearer session token
Request body
| Name | Type | Description |
|---|
bodyRequired | string | Message text (1–4096 chars). |
GEThttps://api.commtunnel.cloud/v1/public/chat/stream
Server-sent events stream
Long-lived SSE connection for real-time agent replies. Pass `token` query param or Bearer header.
Authentication: Bearer session token
Response
Status: 200 (text/event-stream)
POSThttps://api.commtunnel.cloud/v1/public/chat/actions/{actionId}/confirm
Confirm AI action
Confirm AI action
Authentication: Bearer session token
Path parameters
| Name | Type | Description |
|---|
actionIdRequired | string (uuid) | Pending action id. |
Request body
| Name | Type | Description |
|---|
verifyToken | string | Step-up verification when required. |
idempotencyKey | string | Replay-safe confirm key. |
POSThttps://api.commtunnel.cloud/v1/public/chat/csat
Submit CSAT
Submit CSAT
Authentication: Bearer session token
Request body
| Name | Type | Description |
|---|
scoreRequired | integer | 1–5 rating. |
comment | string | Optional feedback (max 2000 chars). |
Billing catalog & marketing
Unauthenticated catalog for pricing pages and first-party marketing event ingestion.
GEThttps://api.commtunnel.cloud/v1/public/billing-catalog
Billing catalog
Plans and add-on groups for public pricing UI.
Authentication: None
Query parameters
| Name | Type | Description |
|---|
currency | string | ISO 4217 code (default USD). |
POSThttps://api.commtunnel.cloud/v1/public/marketing/events
Marketing event
Accept homepage and funnel analytics from allowed origins only.
Authentication: None (origin allowlist)
Request body
| Name | Type | Description |
|---|
eventRequired | string | Event name enum (e.g. homepage_view, homepage_cta_click). |
sourceRequired | string | Page source identifier. |
pathRequired | string | URL path. |
ts | integer | Client timestamp (ms); must be within 7 days. |
cta | string | CTA identifier for click events. |
destination | string | Navigation target. |
botTrap | string | Must be empty (honeypot). |
Response
Status: 202
{ "accepted": true, "id": "uuid" }
403 `MARKETING_ORIGIN_DENIED` when `Origin` header is not on the allowlist.
Email tracking
Pixel and redirect endpoints injected into tracked emails. Not authenticated.
GEThttps://api.commtunnel.cloud/v1/track/open
Open pixel
1×1 tracking pixel; records open events when tracking is enabled on the message.
Authentication: None
Query parameters
| Name | Type | Description |
|---|
tRequired | string | Signed tracking token. |
Response
Status: 200 (image/gif)
GEThttps://api.commtunnel.cloud/v1/track/click
Click redirect
Records click then redirects to the original URL.
Authentication: None
Query parameters
| Name | Type | Description |
|---|
tRequired | string | Signed tracking token. |
Webhooks
Customer-configured webhooks receive normalized lifecycle events. Provider webhooks (Stripe, Meta, SMS DLR) use separate signed ingress routes.
POSThttps://your-app.example/webhooks/email-saas
Customer webhook delivery
Configure endpoints in the workspace. Payloads include `email_*`, `sms_*`, `whatsapp_*`, and `sms_opt_out` event types with HMAC signature headers for verification.
Authentication: HMAC signature (workspace secret)
Response
Status: 2xx from your server
Verify signatures using the webhook signing secret from Integration and APIs.
POSThttps://api.commtunnel.cloud/v1/webhooks/whatsapp
Meta WhatsApp webhook
Meta Cloud API callback URL. GET verifies `hub.verify_token`; POST validates `X-Hub-Signature-256`.
Authentication: Meta app secret
POSThttps://api.commtunnel.cloud/v1/webhooks/sms/dlr
SMS delivery receipt (DLR)
Carrier delivery status callbacks (query token + JSON body with message_id and status).
Authentication: Query token
Workspace session API (overview)
Authenticated control-plane routes under `/v1/*` use session cookies (browser) or bearer tokens after login. CSRF token required on mutating requests. This is a summary; full workspace contracts are available after sign-in.
POSThttps://api.commtunnel.cloud/v1/emails/send
Workspace email send
Same delivery pipeline as public API with session auth and moderation UI integration.
Authentication: Session JWT / cookie
POSThttps://api.commtunnel.cloud/v1/sms/send
Workspace SMS send
Composer send with sender ID validation and quota enforcement.
Authentication: Session JWT / cookie
POSThttps://api.commtunnel.cloud/v1/whatsapp/send
Workspace WhatsApp send
Workspace WhatsApp send
Authentication: Session JWT / cookie
POSThttps://api.commtunnel.cloud/v1/api-keys
Create API key
Issue scoped keys for public API integration. Requires current password step-up.
Authentication: Session + CSRF
GEThttps://api.commtunnel.cloud/v1/chat/conversations
Chat desk API
Agent inbox, assignments, AI modes, OAuth CRM/calendar connections, and analytics.
Authentication: Session + org permissions (chat:read, chat:inbox:manage, etc.)
GEThttps://api.commtunnel.cloud/v1/deliverability/platform-health
Deliverability health
Deliverability health
Authentication: Session