GET /v1/sms/stream
curl --request GET \
--url https://api.revdesk.com/v1/sms/streamimport requests
url = "https://api.revdesk.com/v1/sms/stream"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.revdesk.com/v1/sms/stream', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.revdesk.com/v1/sms/stream",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.revdesk.com/v1/sms/stream"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.revdesk.com/v1/sms/stream")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.revdesk.com/v1/sms/stream")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodySMS
GET /v1/sms/stream
Subscribe to real-time inbound SMS events via Server-Sent Events (SSE).
GET
/
v1
/
sms
/
stream
GET /v1/sms/stream
curl --request GET \
--url https://api.revdesk.com/v1/sms/streamimport requests
url = "https://api.revdesk.com/v1/sms/stream"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.revdesk.com/v1/sms/stream', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.revdesk.com/v1/sms/stream",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.revdesk.com/v1/sms/stream"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.revdesk.com/v1/sms/stream")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.revdesk.com/v1/sms/stream")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyOpens a long-lived Server-Sent Events (SSE) connection that pushes inbound SMS messages to your client in real time. Messages are scoped to the phone numbers owned by the authenticated API key.
Sent immediately after the connection is established.
Sent when an inbound SMS arrives on one of your active phone numbers.
Authentication
Requires a Bearer API key with thesms:read scope.
curl -N "https://api.revdesk.com/v1/sms/stream" \
-H "Authorization: Bearer YOUR_API_KEY"
Events
connected
Sent immediately after the connection is established.
event: connected
data: {"clientId":"sms-42-1716000000000-abc1234","timestamp":1716000000000}
sms_received
Sent when an inbound SMS arrives on one of your active phone numbers.
event: sms_received
data: {"message_id":"msg_abc123","from":"+14155551234","to":"+14155559999","body":"Hello!","received_at":"2026-05-22T18:30:00.000Z"}
| Field | Type | Description |
|---|---|---|
message_id | string | Unique identifier for the message |
from | string | Sender phone number (E.164) |
to | string | Your phone number that received the message (E.164) |
body | string | Message text content |
received_at | string | ISO 8601 timestamp of when the message was received |
Heartbeat
A comment-only heartbeat is sent every 30 seconds to keep the connection alive:: heartbeat
Connection behavior
- Max duration: 300 seconds (5 minutes). Reconnect after the connection closes.
- Reconnect: Re-open the stream (with a short backoff) after it closes. Do not use native
EventSource— it cannot send anAuthorizationheader, and you must never put your API key in the URL (it leaks into logs and history). Usefetchwith a streamed body reader instead. - Scope filtering: Events are filtered to the user or team associated with the API key.
Consume this stream from your server, never from browser JavaScript. It needs a full API key,
which is long-lived and carries every scope the key was issued with. Anything you ship to a browser
is readable by an extension, a devtools pane, a bundled source map, or any XSS on the page, and a
leaked key is usable until you notice and revoke it. The stream also carries full phone numbers and
message bodies, so the exposure is your customers’ data, not just your credential.Connect from a backend process and relay what the browser actually needs over your own
authenticated channel (a WebSocket or your own SSE endpoint), filtered to what that user may see.
Client tokens are not an alternative here: they only ever carry
voice:webrtc, never sms:read.Example
// Runs on your server. Native EventSource can't set headers, so use fetch + a stream reader.
const res = await fetch("https://api.revdesk.com/v1/sms/stream", {
headers: { Authorization: "Bearer YOUR_API_KEY" },
});
const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
for (;;) {
const { value, done } = await reader.read();
if (done) break; // connection closed — reconnect with a short backoff
buffer += decoder.decode(value, { stream: true });
// SSE frames are separated by a blank line.
const frames = buffer.split("\n\n");
buffer = frames.pop() ?? "";
for (const frame of frames) {
const event = frame.match(/^event: (.+)$/m)?.[1];
const dataLine = frame.match(/^data: (.+)$/m)?.[1];
if (!dataLine) continue; // e.g. `: heartbeat`
const data = JSON.parse(dataLine);
if (event === "sms_received") console.log(`New SMS from ${data.from}: ${data.body}`);
}
}
import requests
import json
url = "https://api.revdesk.com/v1/sms/stream"
headers = {"Authorization": "Bearer YOUR_API_KEY"}
with requests.get(url, headers=headers, stream=True) as r:
for line in r.iter_lines(decode_unicode=True):
if line.startswith("data: "):
data = json.loads(line[6:])
print(f"Received: {data}")