Use cases · Replace Twilio

You built a phone company inside your product. Retire it.

Teams that built messaging on raw CPaaS own subaccount plumbing, opt-out bookkeeping, 10DLC orchestration, and webhook glue nobody wants to maintain. Handset is the application layer you were forced to write (multi-tenant, compliant, and billed on usage) with your send calls staying almost identical.

before-after.ts
// Before: raw CPaaS + your own platform code
client.messages.create({ from, to, body })
// …plus ~2,000 lines you maintain

// After: the platform layer is the product
await sendMessage({ body: { from, to, body } });
→ threads, opt-outs, 10DLC, receipts: handled

The maintenance surface

The code you get to delete

None of this code is your product. All of it pages someone when it breaks. Here's where each piece goes.

Subaccount scaffolding

todaySubaccount-per-customer creation, credential storage, and the mapping tables that tie them to your users.

afterTenants are first-class API objects: numbers, threads, hours, and opt-out lists hang off them natively.

Opt-out bookkeeping

todayA stop-words table, a send-time check you hope every code path calls, and the audit trail for when it didn't.

afterSTOP/HELP keywords answer themselves; opt-outs are enforced at send time, per tenant, on our side of the API.

10DLC state machine

todayBrand and campaign registration flows, vetting-status polling, and the spreadsheet that tracks which customer is stuck where.

afterBrands and campaigns are objects with approval webhooks. Test mode approves instantly so onboarding is code.

Message threading

todayThe conversations table you hand-rolled: matching inbound numbers to customers, ordering, unread counts.

afterEvery message carries a conversation_id. The inbox view becomes a GET.

Voice glue

todayTwiML endpoints, ring-timeout handling, voicemail recording storage, and a transcription vendor.

afterHours-based routing, voicemail, and transcripts are configuration per tenant: voicemail.created arrives transcribed.

Concept mapping

Your mental model survives the migration

SubaccountTenant

First-class, with its own numbers, threads, hours, and opt-out list

Messaging ServiceTenant + number

No pooling abstraction to configure: sends come from the tenant's number

client.messages.createPOST /v1/messages

Same shape: from, to, body, plus threading and compliance underneath

Status callbacksSigned webhooks

HMAC-signed, retried until acknowledged, one catalog of event types

A2P registration consolePOST /v1/brands, /v1/campaigns

Registration is an API object with approval webhooks, per tenant

Port-in ticketsPOST /v1/port_ins

Porting is an API: submit, then status webhooks until numbers go live

The migration

Five steps, rehearsed before anything moves

The whole path runs in test mode first, including porting. Your production traffic switches when you've already watched it work.

Rehearse in test mode

Point your staging environment at test keys. Magic numbers simulate delivery, replies, opt-outs, and port-ins, and the whole migration runs green before a real number moves.

Map subaccounts to tenants

One import loop: create a tenant per subaccount, carry over your customer IDs as metadata.

Re-register campaigns by API

Brands and campaigns per tenant, with approval webhooks. Design partners get white-glove 10DLC re-registration, we've done the TCR dance so you don't.

Port your numbers

POST /v1/port_ins per batch, then watch status webhooks until they flip live. Your customers keep the numbers their customers know.

Point your triggers at one endpoint

Your existing send calls become POST /v1/messages, same shape, less code around it. Then start deleting the plumbing above.

And the "someday" features come with the switch. Voice routing, transcribed voicemail, click-to-call with live transcripts, DTMF gather, raw media streaming for voice agents, the roadmap items you kept deferring because they meant more CPaaS plumbing are already on the same API and the same numbers.

Migrating? Bring a founder.

Design partners get white-glove 10DLC re-registration, a rehearsed port plan, and a founder on the call until traffic is switched.