Skip to main content

SMS Events

SMS events track the full lifecycle of messages and bulk campaigns on PBXware in real time. Each SMS message is self-contained. A single event captures everything about one message.


Message Events

Two event types cover the two directions of SMS traffic. Outbound messages fire a second event when the gateway reports a delivery outcome, so a single sent message can produce up to two event_sms_message_sent events.

Inbound:
[Gateway receives message] ──→ event_sms_message_received

Outbound:
[Extension sends message]


event_sms_message_sent (status: SENT)

↓ (gateway reports back)
event_sms_message_sent (status: DELIVERED or FAILED)
EventWhen it fires
event_sms_message_receivedAn inbound message arrives at the gateway
event_sms_message_sentAn outbound message is submitted to the gateway (SENT), and again when the gateway reports a delivery outcome (DELIVERED or FAILED)

Common Payload Fields

All message events include these fields:

FieldTypeDescription
uidStringUnique identifier of the SMS message
gateway_idNumberSMS gateway used to send or receive the message
extensionStringExtension associated with the message event
from_numberStringSender's SMS number
to_numberStringRecipient's SMS number
bodyStringText content of the message
typeStringSMS or MMS

event_sms_message_received · Full spec

Fires when PBXware receives an inbound SMS message.

Additional field:

FieldTypeDescription
associated_extensionsArray of StringsAll extensions configured for the receiving SMS number — useful when one number is shared by multiple agents

event_sms_message_sent · Full spec

Fires when an extension sends an outbound SMS, and again when the gateway reports a delivery update.

Additional field:

FieldTypePossible valuesDescription
statusStringSENT, DELIVERED, FAILEDDelivery state of the outbound message

Two firings: event_sms_message_sent fires once when the message is submitted to the gateway (SENT) and again when the gateway confirms delivery or failure (DELIVERED or FAILED). A FAILED status means the gateway could not deliver the message to the recipient. Both events carry the same uid — use it to correlate the delivery update to the original send.


Campaign Events

Bulk SMS campaigns produce two event types: one when the campaign starts, and one after each batch of messages is dispatched. A campaign with many recipients may produce several batch events.

event_sms_campaign_started

└──(1 or more)─→ event_sms_campaign_messages_batch_sent
EventWhen it fires
event_sms_campaign_startedThe campaign begins — fires once regardless of recipient count
event_sms_campaign_messages_batch_sentAfter each batch of messages is dispatched; a large campaign produces multiple batch events

Common Payload Fields

All campaign events include these fields:

FieldTypeDescription
campaign_idStringUnique identifier of the bulk SMS campaign
sms_numberStringSender SMS number used for the campaign
messageStringCampaign message content

event_sms_campaign_started · Full spec

Fires when a bulk SMS campaign starts. Fires once per campaign regardless of recipient count. The payload contains the common campaign fields only.


event_sms_campaign_messages_batch_sent · Full spec

Fires after each batch of messages is dispatched. Totaling successful + failed across all batch events for a campaign_id gives the overall campaign result.

Additional fields:

FieldTypeDescription
successfulNumberMessages successfully sent in this batch
failedNumberMessages that failed to send in this batch

UID Correlation

Message events: Both event_sms_message_sent firings for the same outbound message carry an identical uid. Store the record on the SENT event and look it up by uid when the DELIVERED or FAILED event arrives.

Campaign events: All events for the same campaign share the same campaign_id. Use it to group event_sms_campaign_started with every subsequent event_sms_campaign_messages_batch_sent.


Example: Inbound SMS

An external number sends an SMS to extension 1001.

#EventuidNotes
1event_sms_message_receiveda1b2c3d4-e5f6-7890-abcd-ef1234567890Message arrives on gateway 390; associated_extensions lists all extensions linked to the receiving SMS number
Raw event payload
{
"event": "event_sms_message_received",
"event_id": "69b32e0c-77e0-42d8-b6d1-3941e1bcea0d",
"spec_version": "1.0",
"tenant_code": "200",
"event_time_info": { "timestamp": 1742306400, "date": "2026-03-18", "time": "14:00:00" },
"payload": {
"uid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"gateway_id": 390,
"extension": "1001",
"from_number": "+15559876543",
"to_number": "+15551234567",
"body": "Hello, your appointment is confirmed for tomorrow.",
"type": "SMS",
"associated_extensions": ["1001", "1002"]
}
}

Example: Outbound SMS — Send and Delivery

Extension 1001 sends a message. Two events are emitted: the first when the message is submitted, the second when the gateway confirms delivery.

+0s +15s

EXT 1001 ●────────────────────────────────●
SENT DELIVERED
#EventuidstatusNotes
1event_sms_message_senta1b2c3d4-e5f6-7890-abcd-ef1234567890SENTMessage submitted to gateway
2event_sms_message_senta1b2c3d4-e5f6-7890-abcd-ef1234567890DELIVEREDGateway confirms delivery
Raw event payloads
{
"event": "event_sms_message_sent",
"event_id": "69b32e0c-77e0-42d8-b6d1-3941e1bcea0d",
"spec_version": "1.0",
"tenant_code": "200",
"event_time_info": { "timestamp": 1742306400, "date": "2026-03-18", "time": "14:00:00" },
"payload": {
"uid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"gateway_id": 387,
"extension": "1001",
"from_number": "+15551234567",
"to_number": "+15559876543",
"body": "Hello, your appointment is confirmed for tomorrow.",
"type": "SMS",
"status": "SENT"
}
}

{
"event": "event_sms_message_sent",
"event_id": "c3d21f4a-88b1-4e92-a01f-6c7d8e9f0a1b",
"spec_version": "1.0",
"tenant_code": "200",
"event_time_info": { "timestamp": 1742306415, "date": "2026-03-18", "time": "14:00:15" },
"payload": {
"uid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"gateway_id": 387,
"extension": "1001",
"from_number": "+15551234567",
"to_number": "+15559876543",
"body": "Hello, your appointment is confirmed for tomorrow.",
"type": "SMS",
"status": "DELIVERED"
}
}

Example: Campaign Batch

A campaign starts and dispatches a batch of 1000 messages.

#Eventcampaign_idNotes
1event_sms_campaign_started42Campaign begins; message content and sender number are set
2event_sms_campaign_messages_batch_sent42First batch dispatched: 950 delivered, 50 failed
Raw event payloads
{
"event": "event_sms_campaign_started",
"event_id": "69b32e0c-77e0-42d8-b6d1-3941e1bcea0d",
"spec_version": "1.0",
"tenant_code": "200",
"event_time_info": { "timestamp": 1742306400, "date": "2026-03-18", "time": "14:00:00" },
"payload": {
"campaign_id": "42",
"sms_number": "+15551234567",
"message": "Hello, your appointment is confirmed for tomorrow."
}
}

{
"event": "event_sms_campaign_messages_batch_sent",
"event_id": "d4e32a5b-99c2-5f03-b12e-7d8e9f0a1b2c",
"spec_version": "1.0",
"tenant_code": "200",
"event_time_info": { "timestamp": 1742306460, "date": "2026-03-18", "time": "14:01:00" },
"payload": {
"campaign_id": "42",
"sms_number": "+15551234567",
"message": "Hello, your appointment is confirmed for tomorrow.",
"successful": 950,
"failed": 50
}
}

Integration Examples

Log Incoming SMS to CRM

app.post('/webhook', (req, res) => {
res.sendStatus(200); // acknowledge immediately

const { event, payload, event_id } = req.body;
if (event !== 'event_sms_message_received') return;

crm.logMessage({
idempotencyKey: event_id, // prevent duplicate logging on retries
messageId: payload.uid,
from: payload.from_number,
to: payload.to_number,
extension: payload.extension,
body: payload.body,
type: payload.type,
});
});

Track Outbound Delivery Status

Use the uid field to correlate the initial send event with the subsequent delivery update.

const pendingMessages = new Map(); // uid → message record

app.post('/webhook', (req, res) => {
res.sendStatus(200);

const { event, payload } = req.body;
if (event !== 'event_sms_message_sent') return;

if (payload.status === 'SENT') {
pendingMessages.set(payload.uid, {
to: payload.to_number,
extension: payload.extension,
body: payload.body,
sentAt: Date.now(),
});
}

if (payload.status === 'DELIVERED' || payload.status === 'FAILED') {
const msg = pendingMessages.get(payload.uid);
if (msg) {
analytics.recordDelivery({
messageId: payload.uid,
status: payload.status,
to: msg.to,
latencyMs: Date.now() - msg.sentAt,
});
pendingMessages.delete(payload.uid);
}
}
});

Campaign Progress Monitoring

Accumulate batch results to track overall campaign delivery and alert on high failure rates.

const campaignTotals = new Map(); // campaign_id → { successful, failed }

app.post('/webhook', (req, res) => {
res.sendStatus(200);

const { event, payload } = req.body;

if (event === 'event_sms_campaign_started') {
campaignTotals.set(payload.campaign_id, { successful: 0, failed: 0 });
}

if (event === 'event_sms_campaign_messages_batch_sent') {
const totals = campaignTotals.get(payload.campaign_id) ?? { successful: 0, failed: 0 };
totals.successful += payload.successful;
totals.failed += payload.failed;
campaignTotals.set(payload.campaign_id, totals);

const failRate = totals.failed / (totals.successful + totals.failed);
if (failRate > 0.1) {
alerts.send({
subject: `High failure rate in campaign ${payload.campaign_id}`,
body: `${(failRate * 100).toFixed(1)}% of messages failed (${totals.failed} failed, ${totals.successful} delivered).`,
});
}
}
});