The business phone API for vertical SaaS

Phone infrastructure to grow your platform

Give your vertical SaaS compliant two‑way texting, inbound calling, voicemail, and real phone numbers, through one API, from your customers' first text to your millionth.

npm install @handset/sdk
import { sendMessage } from "@handset/sdk";

await sendMessage({
  body: {
    from: "num_01kzv…", // your customer's number
    to: "+14154136287",
    body: "Your technician is 15 minutes out.",
  },
});

// → queued: threading, opt-outs & 10DLC handled. Webhook incoming.

message.delivered

+1 415 413 6287 · just now

10DLC

Registered messaging

E911

Address provisioning

STOP/HELP

CTIA keywords built in

HMAC

Signed webhooks

AES-256

Encrypted EINs at rest

A complete phone system for every business on your platform. Your customers already run their businesses inside your product, then step outside it to text and call their customers. Handset is the phone company behind your API: carrier contracts, 10DLC, CTIA keywords, E911, and multi‑tenant numbers, designed to work as one.

Messaging

/v1/messages

Two-way SMS that threads into conversations per tenant. STOP, HELP, and START handled automatically, opt-outs enforced at send time.

Bayview Dental+1 415 259 5084

Hi Maria, reminder: cleaning tomorrow at 9:30 AM. Reply C to confirm.

C, see you then!

conversation cnv_01kzv9… · delivered

Voice & voicemail

/v1/calls

Inbound calls routed by each tenant's business hours, to real phones or a softphone right in your web app. Outbound click-to-call with live mid-call transcripts; voicemail with recordings.

Voicemailafter hours

0:16

+1 415 413 6287

“Hi, calling about a leaky faucet in the…”

Numbers

/v1/phone_numbers

Search, buy, or port in real numbers: E911 included, live on arrival.

+1 415 555 0184Buy · $1/mo

+1 415 555 0271sms · voice

+1 415 555 0339sms · voice

Compliance

/v1/brands

10DLC brands and campaigns as API objects, not support tickets.

Brand · Ridge Plumbingvetted

Campaign · appointmentsapproved

EIN **-***6789 · encrypted

Webhooks

/v1/webhook_endpoints

Nine event types, HMAC-signed, retried until you acknowledge.

message.received200 OK

call.completed200 OK

voicemail.created200 OK

Embed a phone system in your platform. One account, many tenants: each of your customers gets their own numbers, conversations, opt‑out lists, and business hours, isolated by design and billed as one platform.

Start with tenants

Carrier infrastructure, without the carrier.

Ed25519‑verified carrier webhooks in, HMAC‑signed platform events out, a transactional queue in between. You never touch a SIP trunk, but the dial tone is real. Press it.

350 Hz + 440 Hz

The dial tone behind vertical SaaS

0API

for messaging, voice, numbers, and compliance

0event types

HMAC-signed webhooks, retried until acknowledged

0endpoints

spec-first REST, typed SDKs on the way

0modes

live and test on every account, from day one

Developer experience

Test mode is not an afterthought. Every account ships with parallel live and test keys. Test mode runs a simulated carrier: numbers are free, compliance approves instantly, and magic numbers let you rehearse failure before it happens in production.

hs_test: simulated carrier
# Magic number: simulate a failed delivery
curl https://api.handset.dev/v1/messages \
  -H "Authorization: Bearer hs_test_…" \
  -d to="+15005550001" -d body="…"

→ webhook: message.failed
  "failure_reason": "carrier_rejected"
hs_live: real carrier network
# Same code. Real number, real delivery.
curl https://api.handset.dev/v1/messages \
  -H "Authorization: Bearer hs_live_…" \
  -d to="+14154136287" -d body="…"

→ webhook: message.delivered
  status: "delivered"

Handset UI · open source

The UI is already built too. Handset UI is an open-source component registry for the shadcn CLI: inboxes, threads, a browser softphone, 10DLC compliance forms, number porting, and call routing, copied into your repo as source, styled with your tokens, wired to the API through your own backend.

# One command. Your product has a phone system.
npx shadcn@latest add @handset/phone-system

✔ inbox · thread · composer · call-log
✔ voicemail-player · call-transcript
9 components installed → components/handset/

No iframes, no widget skins. The source lands in your project: rename it, restyle it, rip pieces out. Your API key stays on your server; the components talk to a proxy route you own.

  • @handset/messagingTwo-pane texting: inbox, threads, delivery states
  • @handset/softphoneDial, answer, mute: a phone inside your app
  • @handset/contact-timelineEvery text, call, and voicemail in one scroll
  • @handset/opt-in-formConsent UI shaped by a real carrier review
  • 35+ components, live demos, MIT licensed → ui.handset.dev

AI agents

Your agent can already use us. Handset ships an MCP server, listed on the official registry: one config line and an AI agent is texting, calling, and reading transcripts against the simulated carrier, no signup meeting required. When it's time to speak, the same API streams raw call audio both ways.

# One line. Your agent has a phone system.
claude mcp add handset -e HANDSET_API_KEY=hs_test_… -- npx -y @handset/mcp

› send_message · make_call · get_transcript
› start_transcription · buy_number · create_tenant · 9 more
connected: test mode, simulated carrier

# Live keys refused unless you explicitly allow them:
HANDSET_ALLOW_LIVE=1, because agents shouldn't dial real people by accident

Coding agents get first-class treatment too: a companion skill (npx @handset/mcp --skill) teaches them the integration patterns, and the docs ship llms.txt for the rest.

  • MCP server

    15 tools on the official MCP Registry (send, call, transcribe, provision), safe by default on test-mode keys.

  • Media streaming

    Fork or bidirectional raw call audio over WebSockets: the substrate your speech loop runs on.

  • Live transcripts + AI summaries

    Every utterance as a webhook mid-call; a written recap seconds after hangup.

  • Realtime events

    The whole event catalog pushed the moment it commits, browser-safe tokens included.

  • The AI & MCP guide → docs.handset.dev/ai

Pricing

Build for free. Pay for what you send.

Develop against the simulated carrier at no cost. When you go live, top up a prepaid balance and pay only for usage. No monthly fee, no minimums, no contract.

See full pricing details →

Test mode

Free

No card required

  • The full API and every feature
  • Simulated carrier + magic numbers
  • Instant compliance, free numbers
  • MCP server and SDKs
Start building

Pay as you go

Self-serve

Usage-based

Prepaid credits, top up from $5

  • Outbound SMS$0.012 / segment
  • Inbound SMS$0.006 / segment
  • Outbound MMS$0.04 / message
  • Inbound MMS$0.015 / message
  • Voice$0.02 / minute
  • Live transcription$0.05 / minute
  • Phone numbers$2.50 / month
  • 10DLC registrationat cost
Go live

Scale

Custom

For embedding at volume

  • Volume usage rates
  • White-glove 10DLC onboarding
  • Number porting
  • Invoicing and net terms
  • Founder-direct support
Talk to us

Building something ambitious? Early design partners lock in lower founding rates for life, plus white-glove onboarding and founder-direct support.

hello@handset.dev →

A segment is one 160-character SMS (70 characters for messages with emoji or other Unicode); longer texts are split into multiple segments and billed per segment, the way carriers meter them. Prices are in USD. Carrier surcharges (e.g. per-message 10DLC fees) are passed through at cost and itemized. Credits never expire.

Put a handset in your product.

We're onboarding a small group of vertical SaaS platforms. Tell us what your customers need to say, and to whom.