handset docs

Docs › Get started

Test mode

Every account ships with parallel hs_live_… and hs_test_… keys. Test keys run a simulated carrier: numbers are free and instant, compliance approves immediately, and the whole event pipeline — webhooks included — behaves exactly like production.

What the simulator does

  • Numbers — search and purchase return instantly and cost nothing; the inventory is synthetic but shaped like the real thing.
  • Messages — sends are accepted and delivery receipts arrive moments later as real webhook events.
  • Voice — inbound calls, answers, hangups, and voicemails can be simulated so your call-handling UI is testable without dialing a phone.
  • Compliance — brands vet and campaigns approve immediately, with the same status_changed events production emits over days.

Magic numbers

Rehearse the failures you hope never happen:

ValueBehavior
+15005550001Send accepted, then delivery fails — message.failed webhook with carrier_rejected
+15005550009The carrier rejects the send itself; after retries the message ends failed with send_failed
E911 ZIP 00000Emergency-address registration is rejected
Any other numberDelivers instantly with a receipt

A failure drill

curl
# Same code as production — only the key differs.
curl https://api.handset.dev/v1/messages \
  -H "Authorization: Bearer $HANDSET_TEST_KEY" \
  -d '{"from": "num_…", "to": "+15005550001", "body": "This one is doomed."}'

# moments later, at your webhook endpoint:
 message.failed  "failure_reason": "carrier_rejected"
Mode isolation is strict: a test key can never see live traffic, and vice versa — separate ledgers end to end.