saperly

Core concepts

The Saperly model — numbers, connections, your prepaid balance, workspaces, and the compliance layer that wraps them.

A short mental model. Saperly has five moving parts: numbers, connections, your balance, workspaces, and the compliance layer that wraps them. Everything else is built on these.

Numbers

A number is a real phone number provisioned under your workspace. Provision one with a country, type, and optional area code:

{ "country": "US", "numberType": "local", "areaCode": "415" }

Each number carries its price (monthlyPriceCents) and the connectionId of the handler bound to it. Monthly rent is swept automatically against your prepaid balance, idempotent per billing period. Releasing a number soft-deletes it (releasedAt is set) and stops the rent.

See the Numbers guide.

Connections

A connection is the handler bound to a number — the thing that answers. A connection has a mode:

  • Hosted — an in-network voice assistant (speech-to-text → LLM → text-to-speech). Bring your own OpenAI-compatible LLM, pick a TTS voice, and optionally declare MCP servers the assistant can call.
  • Manual — bring your own LLM as the brain. Saperly forwards each text turn to your agent (over an HTTP endpoint or an outbound websocket) and executes the directives it returns (speak, wait_for_user, hangup, transfer, send_dtmf).

One number → one connection. The same connection can answer many numbers. See Connections and Manual mode.

Your balance (prepaid)

Saperly is prepaid. You top up a balance; usage is metered against it through a reserve → settle → release cycle:

  1. Reserve — before an action (a call, a number), funds are held. You can never over-spend a balance or a scoped key's spend cap — the reservation simply fails first.
  2. Settle — after the action, the actual cost is applied.
  3. Release — if the action never happens, the held funds return.

Top up manually or enable auto-recharge. See Billing.

Workspaces & tenancy

A workspace is your tenant. Members are humans (with roles); agents authenticate with scoped sk_ API keys. The workspace an action belongs to is always read from the credential — never from client input — so a key can only ever touch its own workspace's data.

See Authentication.

Compliance

Consent, disclosures, and 10DLC registration are first-class and enforced independently of any LLM — so a model you swap out can never route around them:

  • Consent — record implied_inbound / explicit_outbound consent per (number, peer), check it before outbound contact, and revoke on STOP.
  • Disclosures — the AI/TCPA notice lives on a connection (complianceEnabled + disclosure); when on, it is spoken as the line's first, uninterruptible utterance.
  • 10DLC — register a campaign (brand + use case) so your US SMS is carrier-certified and delivers reliably.

See Compliance.

Audio stays in-network

Saperly runs the phone network for you, and call audio never reaches your servers. Saperly handles signaling, identity, compliance, the record, and billing; your code only ever sees text and tool calls.

Even in manual mode, where your LLM is the brain, speech-to-text and text-to-speech happen in-network — you receive transcribed turns and return directives, and no audio socket is ever opened to your server. That's what keeps Saperly simple to run at scale: no media pipeline to operate, no audio egress, and nothing of yours that has to be online for a call to happen.

Two ways to call the API

Saperly exposes the same capabilities through two REST surfaces:

SurfaceStyleBest for
v2 (current)camelCase, scoped sk_ keysnew integrations, fleets, MCP
v1 (SDK-compatible)snake_case, wrapped envelopesthe published @saperly/sdk / saperly SDKs

Both run over the same backend. The SDKs target v1; the API reference documents every endpoint of both.

On this page