> ## Documentation Index
> Fetch the complete documentation index at: https://docs.revdesk.com/llms.txt
> Use this file to discover all available pages before exploring further.

# GET /v1/sms/stream

> Subscribe to real-time inbound SMS events via Server-Sent Events (SSE).

Opens 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.

## Authentication

Requires a Bearer API key with the `sms:read` scope.

```bash theme={null}
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 an `Authorization` header, and you must never put your API key in
  the URL (it leaks into logs and history). Use `fetch` with a streamed body reader instead.
* **Scope filtering:** Events are filtered to the user or team associated with the API key.

<Warning>
  **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](/api-reference/client-tokens) are not an alternative here: they only ever carry
  `voice:webrtc`, never `sms:read`.
</Warning>

## Example

<CodeGroup>
  ```javascript Node (fetch stream) theme={null}
  // 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}`);
    }
  }
  ```

  ```python Python theme={null}
  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}")
  ```
</CodeGroup>
