Skip to content

Test mode

A test key (mv_test_sk_…) runs the same API on simulated calls. Calls go to a virtual carrier instead of the phone network; speech recognition, the language model and the voice are simulated; and nothing is billed. Use test mode to build your integration and to test it, in CI too, without a phone line and without AI spend. When it works, a live key (mv_live_sk_…) runs the same code on real calls.

Create a test key in DevelopersAPI keys with Mode set to Test (see authentication).

Live mode Test mode
Calls Real calls over your SIP connections A virtual carrier with test numbers; no phone network is ever reached
Speech recognition, AI model, voice The real providers Simulated; the post-call summary and quality score are fixed stand-ins
Billing Rated and billed Never billed
Calls, campaigns, contacts, events, webhook endpoints Live objects ("livemode": true) Separate test objects ("livemode": false): each mode sees only its own
Assistants, flows, inbound routes, queues, knowledge base Shared by both modes Shared by both modes
SIP connections, the do-not-call list, consents Available Live only. Test keys can read the do-not-call list and consents; anything else answers 403 with the code live_only
Webhooks Sent to live endpoints Sent to test endpoints only
Limits Your plan’s Fewer calls at once and per day, and half the request rate

Every object of the API has a livemode field, so you can always tell which mode it belongs to. A test key can’t touch a live object, nor a live key a test one: that answers 403 with the code livemode_mismatch.

In test mode every call goes to the virtual carrier. These numbers make it behave like the real world, so you can test every path of your code:

Number What happens
+972500000001 Answers. A simulated caller talks for a few turns, then hangs up.
+972500000002 Busy. The call ends without being answered.
+972500000003 An answering machine answers (answered_by: "machine").
+972500000004 On the do-not-call list: the request is refused before anything is dialled, with a compliance_error.
+972500000005 Rings with no answer for 30 seconds.
+972500000006 The carrier fails.
Any other number Answers, like +972500000001.

The same behaviours answer on +15005550001 to +15005550006 if you prefer North American numbers. On +972500000003, answering-machine detection runs even when your call or assistant has it off, so answered_by is always set; with amd.on_machine: "leave_message" the assistant leaves its message after the beep.

To test inbound calls, create a sandbox number (POST /v1/phone_numbers with a test key, pointing at your assistant) and have a simulated caller dial it with POST /v1/test_helpers/inbound_calls. POST /v1/test_helpers/events sends a sample event to your test-mode webhook endpoints.

The caller’s lines come from a script and the assistant’s from a simulated model, so a test call reads like a test, not like a real conversation. The quickstart places one.

Test-mode events (a test call ended, a test campaign finished) go only to webhook endpoints created with a test key, so your tests never reach production systems. Create a separate endpoint for your test environment, and check livemode on every event you receive.

Test mode has its own, smaller limits: fewer calls in progress at once, a cap on test calls per 24 hours, and half the request rate of your plan. The numbers per plan are in errors, rate limits and concurrency.

  1. Create a live key (mv_live_sk_…) the same way, with Mode on Live, and keep it on your server only.
  2. Connect a phone line: phone numbers and SIP.
  3. Read compliance before you call customers: §30A consent for marketing, the do-not-call lists, and calling hours around Shabbat and holidays.
  4. Recreate the live objects your code expects (webhook endpoints, campaigns): test objects never become live ones.