The Webhook SMS integration allows you to receive inbound SMS/MMS messages via HTTP webhooks and send outbound SMS through a simple REST API. This supports two-way messaging with AI platforms, automation tools, and custom applications.
How it works:
All API endpoints are served from:
https://api.cloudspirevoice.com/
When a customer sends an SMS or MMS to your DID, your webhook endpoint receives an HTTP POST with a JSON payload.
| Property | Value |
|---|---|
| Method | POST |
| Content-Type | application/json |
| Authorization | Value of your configured Auth Header (if set), otherwise omitted |
| Timeout | 30 seconds |
{
"event": "sms.inbound",
"from": "+17705551234",
"to": "+14045559999",
"text": "Hello, I need help with my account",
"media": [
"https://api.cloudspirevoice.com/uploads/wh_67ae1b2f3c4d5.jpg"
],
"timestamp": "2026-02-13T14:30:00-05:00"
}
| Field | Type | Always Present | Description |
|---|---|---|---|
event | string | Yes | Always "sms.inbound" |
from | string | Yes | The sender's phone number in E.164 format (+1XXXXXXXXXX) |
to | string | Yes | Your DID that received the message, in E.164 format |
text | string | Yes | The message body. May be an empty string for MMS-only messages. |
media | array | No | Array of publicly accessible URLs for MMS attachments. Only present when the message includes media. Files are hosted on our server and retained for 30 days. |
timestamp | string | Yes | ISO 8601 timestamp with timezone offset |
Your endpoint must return an HTTP status in the 2xx range to confirm receipt. Any non-2xx response is treated as a delivery failure.
Return HTTP 200 with an empty body or any body without a reply field. The message is delivered to your system and no reply is sent to the customer.
To send an immediate SMS reply back to the customer, return a JSON response with a reply field:
{
"reply": "Thanks for reaching out! Your account number is 12345.",
"media": ["https://example.com/receipt.pdf"]
}
| Field | Type | Required | Description |
|---|---|---|---|
reply | string | Yes | The SMS text to send back to the customer. Must be non-empty. |
media | array | No | Array of publicly accessible media URLs to include as MMS attachments. |
If the reply field is missing or empty, no reply is sent.
Use this endpoint when your service needs to send an SMS outside of the synchronous reply window — for example, sending a follow-up message minutes or hours later, or initiating a new conversation.
POST https://api.cloudspirevoice.com/webhook-to-sms.php
| Header | Value |
|---|---|
Content-Type | application/json |
{
"from": "14045559999",
"to": "17705551234",
"text": "Your appointment is confirmed for Friday at 3pm.",
"secret": "your-webhook-secret",
"media_url": "https://example.com/confirmation.jpg"
}
| Field | Type | Required | Description |
|---|---|---|---|
from | string | Yes | The DID to send from (your provisioned number). Digits only, no + prefix. Must be a DID configured with WEBHOOK destination. |
to | string | Yes | The recipient phone number. Digits only, no + prefix. 10–15 digits. |
text | string | Conditional | The message body. Required unless media_url is provided. |
secret | string | Yes | The webhook secret configured for this DID. Must match exactly. |
media_url | string | No | A publicly accessible URL for an MMS attachment (image, PDF, etc.). When provided, the message is sent as MMS. If media_url is provided, text may be empty. |
HTTP 200
{
"status": "success",
"message": "SMS Queued | FROM: 14045559999 | TO: 17705551234 | ID: bw-msg-abc123"
}
The ID value is the carrier message ID and can be used for delivery tracking.
HTTP 400
{
"status": "error",
"message": "Authentication failed: invalid secret. Error: [WH-AUTH]"
}
| Code | Meaning | Resolution |
|---|---|---|
[WH-AUTH] | Secret is missing or does not match | Verify the secret value matches the Webhook Secret provided to you by your onCloud administrator |
[WH-1] | Missing required fields or invalid JSON | Ensure from, to, and either text or media_url are present in a valid JSON body |
[WH-2] | Phone number format invalid | Use 10–15 digit format, digits only (e.g., 14045559999, not +1-404-555-9999) |
[WH-3] | DID not configured for webhook | The from number must be provisioned for webhook SMS by your onCloud administrator |
[WH-23-2] | No active SMS plan for this DID | Contact your onCloud administrator to verify the DID has an active SMS plan |
[WH-23-3] | Monthly SMS limit exceeded | The plan's monthly message limit has been reached. Contact your administrator to increase the limit or wait for the next billing cycle. |
[WH-23-4] | Plan does not include outbound | The SMS plan for this DID does not include outbound messages. Contact your administrator. |
This example demonstrates a typical two-way SMS flow using n8n as middleware between your DID and an AI service.
When a customer texts your DID, your webhook endpoint receives:
{
"event": "sms.inbound",
"from": "+17705551234",
"to": "+14045559999",
"text": "What are your business hours?",
"timestamp": "2026-02-13T14:30:00-05:00"
}
If your service can generate a reply within 30 seconds (e.g., a quick AI lookup), respond directly in the HTTP response body:
{
"reply": "Our business hours are Monday-Friday 9am-5pm EST. Can I help with anything else?"
}
The system automatically sends this as an SMS from your DID to the customer.
If your service needs to send a message later (a follow-up, a scheduled reminder, or any message outside the 30-second window), POST to the outbound endpoint:
curl -X POST https://api.cloudspirevoice.com/webhook-to-sms.php \
-H "Content-Type: application/json" \
-d '{
"from": "14045559999",
"to": "17705551234",
"text": "Just following up - did you need anything else?",
"secret": "your-webhook-secret"
}'
| Context | Format | Example |
|---|---|---|
Inbound payload (from, to) | E.164 with + | +14045559999 |
Outbound request (from, to) | Digits only, no + | 14045559999 |
All phone numbers must include the country code (e.g., 1 for US/Canada).
[WH-23-3]. Inbound messages are still delivered to your webhook, but automatic replies will fail.https://api.cloudspirevoice.com/uploads/media_url must be a publicly accessible HTTP or HTTPS URLmedia_url is provided on outbound, the message is sent as SMS only (the media is silently dropped)