Webhooks vs SSE: Two Ways to Receive an SMS
AltiviaCloud Team · August 29, 2026 · 2 min read
Both deliver the same event. Which one you want depends on whether a browser or a server is waiting for it.
When an SMS arrives for one of your orders, we can tell you in two ways. They are not competing options — they answer different questions.
The short answer
- SSE when a person is looking at a screen and waiting for the code.
- Webhooks when a server needs to react and nobody is watching.
Most integrations end up using both.
SSE: the browser is waiting
Server-Sent Events keep an HTTP connection open and push events down it as they happen. The client side is one browser API, no library:
const stream = new EventSource(`/api/orders/${orderId}/stream`);
stream.onmessage = (event) => {
const payload = JSON.parse(event.data);
if (payload.event === "sms:received") {
showCode(payload.data.code);
stream.close();
}
};
What it gives you is latency measured in the time it takes us to see the message. The code appears while the user is still looking at the page, which is the entire point.
What it does not give you is durability. The connection belongs to that browser tab. Close the tab, lose the laptop's wifi, and the event has nowhere to land. SSE is a live view, not a record.
Webhooks: your server is waiting
A webhook is us making an HTTP request to a URL you own, whenever something happens:
{
"event": "SMS_RECEIVED",
"data": {
"orderId": "clxxx...",
"code": "482913",
"receivedAt": "2026-01-04T12:33:10.000Z"
}
}
This survives everything a browser cannot: your user closed the page, your job runner picked the work up on a different machine, the code needs to end up in a database rather than on a screen.
The cost is that you now run an endpoint, and endpoints have obligations:
- Verify the signature before trusting the body. An unauthenticated webhook URL is a public API for anyone who guesses it.
- Be idempotent. Delivery is at-least-once. The same event can arrive twice, and processing it twice must be harmless — key on the event id, not on the order of arrival.
- Answer fast. Acknowledge with a
2xxand do the real work afterwards. A slow endpoint turns into a retried endpoint.
Using both
The combination that works well in practice:
- The browser opens an SSE stream so the user sees the code the moment it lands.
- Your server takes the webhook and writes it down.
The screen stays instant and the record stays reliable, and neither one is doing the other's job. If you have to pick one to build first, pick the webhook — a lost record is a bug, while a screen that updates a second late is a preference.