Core Concepts

Most integration confusion comes from not having the right mental model.

This is the model.

Line

A line is the main resource in Saperly.

It owns:

  • a phone number
  • a mode
  • optional webhook destinations
  • optional hosted AI settings
  • compliance behavior

Most workflows start by creating a line.

Modes

Every line runs in one of three modes.

hosted

Saperly runs the conversation loop.

You configure:

  • system_prompt
  • begin_message
  • voice
  • context_limit

text — Webhook mode

Saperly handles telephony and speech. Your webhook decides what to say.

You configure:

  • webhook_url
  • optional status_callback_url

audio

Saperly streams raw audio to your infrastructure over WebSocket.

You configure:

  • audio_handler_url
  • optional status_callback_url

Mode comparison

FeatureHostedWebhook (text)Audio
Who controls conversationSaperly AIYour serverYour server
What you configurePrompt, voice, greetingWebhook URLWebSocket URL
Audio formatN/A (handled)N/A (handled)mulaw_8k, pcm16_8k/16k/24k
Latency controlNoneModerateFull
Cost (Zone A)$0.26/min$0.13/min$0.13/min
SDK supportFullFullPartial
Best forSimple botsCustom logicRealtime voice AI

International destinations vary by zone — see Voice zones.

Calls

A call belongs to a line.

Calls can be:

  • inbound
  • outbound

Call records hold status, timing, transcript data, and optional recording metadata.

Call lifecycle

Inbound call

Phone rings → Saperly answers → Mode handler activates
→ hosted: AI conversation loop starts
→ webhook: webhook receives call_started, then message events
→ audio: WebSocket relay opens, audio frames flow
Call ends → transcript saved → call record finalized → status callback fired

Outbound call

POST /api/v1/calls → pre-call check (balance + consent + disclosure)
→ Pass: carrier initiates call → ring → connect → mode handler activates
→ Fail: 402 (balance) or 403 (consent) or 422 (validation)

Conversations

For SMS, Saperly groups messages by line and contact number.

Conversations are automatically created when SMS messages arrive. Use the conversations endpoint to inspect message history.

Inbound SMS is mode-independent — every line receives messages and logs a sms_received compliance event regardless of voice mode. To auto-reply with your own LLM, set webhook_url on the line so your code can receive the event and call POST /api/v1/messages.

Use conversations when you want:

  • a list of active SMS threads
  • message history with one contact
  • context for support or workflow automation

Outbound calling is blocked until you record consent for that destination number.

That is not a docs footnote. That is part of the product contract.

The basic flow is:

  1. record consent
  2. place outbound call
  3. keep the audit trail

Compliance events

Saperly records compliance events like:

  • disclosure played
  • consent collected
  • consent revoked
  • call started
  • call ended
  • pre-call check passed or blocked

This matters if you are calling real customers and need evidence later.

Voices

Hosted mode can use a selected voice for speech output.

List available voices with:

$GET /api/v1/voices

Settings

Settings are account-level defaults. For example, setting a default webhook_url means new lines inherit it automatically. Per-line config always overrides account defaults.

Resource map

A single line can have many calls and many SMS conversations. Consent is scoped to a line + phone number pair. Compliance events are scoped to a line and optionally a call.

If you want the shortest possible resource map:

  • Auth: create account, log in, manage keys
  • Lines: provision and configure phone numbers
  • Calls: start, inspect, hang up, or run one-off conversation calls
  • Messages / Conversations: send SMS and inspect SMS history
  • Consent / Compliance / Disclosures: keep calling legal and auditable
  • Billing / Usage: track balance, spend, and operational activity

For the endpoint-by-endpoint map, read API Overview.