VICIfast
All guides

Testing a VICIfast integration in the sandbox

Test keys, the pretend wallet and catalogue, and the simulations that make a call ring, a month pass or a back-order fill - so you can test your code against events without waiting for them.

VICIfastLast updated

The VICIfast sandbox is a copy of the API that touches nothing real. Keys that start vf_test_ work against it: the same endpoints, the same answers, the same errors - but no number is bought, no wallet is charged and no server is changed. This guide covers what the sandbox has, what it does not do, and how to make things happen in it on demand.

What is in the sandbox?

  • A pretend wallet with $100.00, charged at your real prices.
  • A made-up catalogue: 555-0100 to 555-0199 in every area code. Numbers ending 00 or 11 are premium at $25.00 a month.
  • One server, srv_sandbox, that numbers can be pointed at.
  • Back-orders that deliver half of each line at once and leave the rest open, so you can track and cancel them.
  • Calls for the numbers you hold, with recordings you can transcribe.

Every answer to a test key carries the header X-VICIfast-Mode: test. Webhook endpoints made with a test key receive the sandbox's events, and only those.

What does the sandbox not do?

Anything that reaches the outside world. Sending a message, enrolling a lead in a journey, and changing a CID group on a real server all answer test_mode_unsupported to a test key. Use a live key for those.

How do I make things happen?

With the sandbox:simulate scope, a test key can trigger the events your integration would otherwise wait days for. Each one sends its webhook to your test endpoints, so you can test the code that receives them.

A caller rings one of your numbers - the call appears in GET /api/v1/calls, and call.inbound.completed is sent:

curl -X POST https://vicifast.com/api/v1/sandbox/inbound-calls \
  -H "Authorization: Bearer $VICIFAST_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "number": "+13055550100", "from": "+12125559999", "duration_s": 95 }'

Time passes - up to 400 days. Renewals that fall due are charged to the pretend wallet, oldest first; a number with auto-renew off is released at the end of its three-month minimum term; a renewal the wallet cannot pay fails. Each sends its event:

curl -X POST https://vicifast.com/api/v1/sandbox/time-travel \
  -H "Authorization: Bearer $VICIFAST_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "days": 31 }'

A back-order fills - numbers arrive (numbers.arrived), and backorder.filled is sent once everything ordered is in:

curl -X POST https://vicifast.com/api/v1/sandbox/backorders/BACKORDER_ID/deliver \
  -H "Authorization: Bearer $VICIFAST_KEY"

The wallet runs low - set the pretend balance. Dropping below a test endpoint's threshold sends wallet.low; raising it sends wallet.topped_up. Set it low and then move time on to see a renewal fail:

curl -X POST https://vicifast.com/api/v1/sandbox/wallet \
  -H "Authorization: Bearer $VICIFAST_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "balance_cents": 150 }'

How do I start over?

POST /api/v1/sandbox/reset empties the sandbox: no numbers, no orders, and a fresh $100.00. The dashboard's API → Keys page has the same button.

When is my integration ready for live?

When it handles the answers and events above - including the failures - with a test key, swap in a live key. The requests do not change. Two differences to plan for: real purchases need an approved termination account, and real money moves, so send an Idempotency-Key and a spending limit (max_total_cents or max_charge_cents) on every request that charges. The quickstart shows both.