---
title: SMS vs voice — Concepts
description: Two channels, one number. Different transports, different operations.
url: https://agentnumber.really.com/docs/concepts/sms-vs-voice
doc_version: "1.0.0"
last_updated: "2026-05-15"
---

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

# SMS vs voice

> Two channels, one number. Different latency, different transports, different operations. Use both or use one — same auth either way.

## At a glance

|  | SMS | Voice |
| --- | --- | --- |
| Transport | HTTP request/response | WebSocket (binary frames) |
| Direction | Inbound + outbound | Inbound + outbound |
| Send | [`POST /sms/send`](/docs/reference/send) | [`POST /voice/dial`](/docs/reference/voice-dial) |
| Receive | [`GET /sms/receive`](/docs/reference/receive) (atomic claim; MCP `receive_sms` for long-poll) | [`/voice/presence/<phone>`](/docs/reference/voice-presence) WS |
| Stream | — | [`/voice/stream/<call_id>`](/docs/reference/voice-stream) WS |
| Latency profile | Near-instant OTP end-to-end | Low-latency PCM audio |
| Auth | Bearer token | Bearer token |

## SMS

Drop in for OTPs, notifications, two-way text agents. [`/sms/receive`](/docs/reference/receive) is an atomic claim — two parallel calls won't double-deliver the same message — that returns immediately. For long-poll behavior (the typical OTP use case), use the MCP `receive_sms` tool. For history (no mutation), use [`/sms/messages`](/docs/reference/messages).

## Voice

Two WebSocket channels with different jobs:

- **Presence WS** — long-lived listener. Open it once with your bearer, leave it open as long as you accept calls. Server pushes three event types over the call lifecycle: `{event: "ringing", call_id, caller, stream_url}`, `{event: "answered", call_id}`, and `{event: "ended", call_id, missed}`.
- **Stream WS** — per-call audio channel. Open it on the `stream_url` from the presence event (or from a `/voice/dial` response). Send + receive 16 kHz PCM as binary frames. Close to hang up.

## Same number, both channels

No separate provisioning. The phone number returned by [`/subscribe`](/docs/reference/subscribe) is the SMS number AND the voice number. Carrier-verified caller ID, so downstream voice services treat the call as a legitimate consumer call.

## Where to go next

- [Quickstart](/docs/quickstart) — full SMS round-trip in four `curl` calls
- [Voice overview](/docs/voice) — full voice flow with both channels
- [MCP](/docs/mcp) — call both channels through Model Context Protocol

---

## Sitemap

- [Overview](/docs/)
- [Quickstart](/docs/quickstart)
- [Authentication](/docs/auth)
- [SMS](/docs/sms)
- [Voice](/docs/voice)
- [MCP](/docs/mcp)
- [Payment](/docs/payment)

See the full [sitemap.md](/sitemap.md) for the complete index of docs pages.
