Webhook SMS API
Docs Home / API Reference / Webhook SMS API

Webhook SMS API

Receive text messages at your own web address and send replies through a simple API.

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:

  1. A customer sends an SMS/MMS to your provisioned DID
  2. Our system forwards the message as a JSON POST to your configured webhook URL
  3. Your service can reply immediately in the HTTP response (synchronous reply)
  4. Your service can also send outbound SMS at any time via the outbound API endpoint (asynchronous)

Base URL

All API endpoints are served from:

https://api.cloudspirevoice.com/

Receiving Inbound SMS

When a customer sends an SMS or MMS to your DID, your webhook endpoint receives an HTTP POST with a JSON payload.

Request Details

PropertyValue
MethodPOST
Content-Typeapplication/json
AuthorizationValue of your configured Auth Header (if set), otherwise omitted
Timeout30 seconds

Inbound Payload

{
  "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"
}

Payload Fields

FieldTypeAlways PresentDescription
eventstringYesAlways "sms.inbound"
fromstringYesThe sender's phone number in E.164 format (+1XXXXXXXXXX)
tostringYesYour DID that received the message, in E.164 format
textstringYesThe message body. May be an empty string for MMS-only messages.
mediaarrayNoArray 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.
timestampstringYesISO 8601 timestamp with timezone offset

Expected Response

Your endpoint must return an HTTP status in the 2xx range to confirm receipt. Any non-2xx response is treated as a delivery failure.

Fire-and-Forget (No Reply)

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.

Synchronous Reply

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"]
}
FieldTypeRequiredDescription
replystringYesThe SMS text to send back to the customer. Must be non-empty.
mediaarrayNoArray of publicly accessible media URLs to include as MMS attachments.

If the reply field is missing or empty, no reply is sent.

Sending Outbound SMS (Asynchronous)

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.

Endpoint

POST https://api.cloudspirevoice.com/webhook-to-sms.php

Headers

HeaderValue
Content-Typeapplication/json

Request Payload

{
  "from": "14045559999",
  "to": "17705551234",
  "text": "Your appointment is confirmed for Friday at 3pm.",
  "secret": "your-webhook-secret",
  "media_url": "https://example.com/confirmation.jpg"
}

Request Fields

FieldTypeRequiredDescription
fromstringYesThe DID to send from (your provisioned number). Must be a DID configured with WEBHOOK destination. Any of the formats below is accepted.
tostringYesThe recipient phone number. A number written with a leading + is sent exactly as written. Without the +, a 10-digit number is read as a US or Canada number; include the country code for any other country.
textstringConditionalThe message body. Required unless media_url is provided.
secretstringYesThe webhook secret configured for this DID. Must match exactly.
media_urlstringNoA 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.

Success Response

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.

Error Response

HTTP 400

{
  "status": "error",
  "message": "Authentication failed: invalid secret. Error: [WH-AUTH]"
}

Error Codes

CodeMeaningResolution
[WH-AUTH]Secret is missing or does not matchVerify the secret value matches the Webhook Secret provided to you by your Cloudspire administrator
[WH-1]Missing required fields or invalid JSONEnsure from, to, and either text or media_url are present in a valid JSON body
[WH-2]Phone number format invalidSend a 10-digit US or Canada number, or a number with its country code (10 to 15 digits in all). Spaces, dashes, parentheses and a leading + are fine.
[WH-3]DID not configured for webhookThe from number must be provisioned for webhook SMS by your Cloudspire administrator
[WH-23-2]The number cannot send texts yetThe number is inactive or not set up for texting, or the account does not yet have the SMS Message Package and an approved business texting registration. Contact your Cloudspire administrator.
[WH-23-CAP]Trial texting limit reachedA trial account has used its included texts. Upgrade to a plan to keep sending.
[WH-23-TF]Toll-free numberToll-free numbers need toll-free verification to send texts, which a business texting registration does not provide. Send from a local number.
[WH-23-OPTOUT]Recipient opted outThe recipient replied STOP to this number. Nothing is sent until they reply START.
[WH-23-9]Temporary failure (HTTP 503)The message was not sent. Retry the request.
[WH-BW-APP]Texting is not available right nowThe message was not sent. Contact your Cloudspire administrator.

Complete Two-Way Example

This example demonstrates a typical two-way SMS flow using n8n as middleware between your DID and an AI service.

Step 1: Your Endpoint Receives Inbound SMS

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"
}

Step 2: Send a Synchronous Reply

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.

Step 3: Send an Async Follow-Up

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"
  }'

Phone Number Format Reference

ContextFormatExample
Inbound payload (from, to)E.164 with ++14045559999
Outbound request (from, to)Digits, with or without +; punctuation is ignored14045559999, +14045559999, (404) 555-9999

A number written with a leading + is sent exactly as written. Without the +, a 10-digit number is read as a US or Canada number and sent with its 1 country code, and any other number must include its country code.

Billing and Limits

Media / MMS Notes