A simplified inbound payload when a user taps a suggested reply (postbackData lets you map the tap to intent):
{
"senderPhoneNumber": "+14155550123",
"messageId": "abc-123",
"suggestionResponse": {
"postbackData": "confirm_appt_1043",
"text": "Confirm"
},
"sendTime": "2026-06-08T17:40:00Z"
}
Always verify the request is genuinely from your provider before acting on it, and respond quickly with a 200 so events aren’t retried unnecessarily.
The endpoint itself has a short list of hard requirements. It must be reachable over HTTPS on a public hostname with a valid certificate, it must answer within a few seconds, and it must return 200 as soon as it has safely accepted the payload rather than after it has finished processing it. The reliable shape is to validate, write the event to a queue, return 200, and do the real work asynchronously. Endpoints that call a slow internal API before responding are the most common cause of duplicate events in production.
Verification comes before anything else. Your provider signs each request, and your handler should recompute that signature over the raw request body, before any JSON parsing or middleware reformatting, and reject anything that does not match. An unverified webhook is a way for anyone who learns the URL to inject fake opt-outs and fake inbound messages into your system, so treat the check as mandatory rather than a hardening step for later.
Three delivery properties are worth designing around from the start:
- At-least-once, not exactly-once. A timeout or a non-200 triggers a retry, and a slow 200 can arrive after the retry was already sent. Deduplicate on
messageIdand make handlers idempotent. - Order is not guaranteed. A read receipt can arrive before the delivery receipt it logically follows. Sequence on the event timestamp rather than on arrival order.
- Retries back off and then stop. Providers give up after a bounded window, so a long outage means lost events. Reconcile against the message log afterwards rather than assuming the stream was complete.
A short pre-launch checklist: signature verification on the raw body, 200 returned in under a second, deduplication by messageId, opt-out events written straight to the suppression list before anything else, and a dead-letter queue for payloads that fail to parse so a single malformed event cannot stall the pipeline.
The exact SimplyRCS payload for each event, the signature header and the retry schedule are in the public API reference at SimplyRCS for developers, which is readable without an account.