VICIfast API quickstart - buy and route a number from code
Five requests from an API key to a number ringing on your VICIdial server - search, quote, buy, point and watch - first in the free sandbox, then live.
The VICIfast API lets your own code do what the dashboard's number pages do: search the catalogue, buy numbers, point them at a VICIdial in-group, and read the calls they take. This guide goes from an API key to a ringing number in five requests. Do it with a test key first - the sandbox behaves the same way and charges nothing.
Everything below is plain HTTPS and JSON. The full reference, with every field, is at /api-docs.
How do I get an API key?
In the dashboard, open API → Keys and create one. Two choices matter:
- Live or test. A live key starts
vf_live_and acts on your real account. A test key startsvf_test_and works against a sandbox: a pretend $100 wallet, a made-up catalogue and one server calledsrv_sandbox. Start with a test key. - Scopes. Grant only what the integration needs. For this guide:
numbers:read,numbers:buyandnumbers:write.
Send the key on every request:
export VICIFAST_KEY=vf_test_...
curl https://vicifast.com/api/v1/numbers \
-H "Authorization: Bearer $VICIFAST_KEY"
Keys can only be created by the account owner, and each can be limited to the IP addresses your servers use.
1. Search the catalogue
GET /api/v1/numbers/available lists numbers on sale at your price. Filter by area_code, state, npa_nxx (area code and exchange together), rate_center, or vanity digits: contains and ends_with accept letters read off a phone keypad, so ends_with=SALES finds numbers ending 72537.
curl "https://vicifast.com/api/v1/numbers/available?area_code=305&limit=5" \
-H "Authorization: Bearer $VICIFAST_KEY"
Each result carries monthly_price_cents and setup_price_cents - your own price, the same one the purchase charges.
2. Ask what it would cost
Add "dry_run": true to a purchase and nothing is bought: the answer says exactly what the real call would charge, and refuses for the same reasons it would (not enough in the wallet, a number already gone).
curl -X POST https://vicifast.com/api/v1/numbers/purchase \
-H "Authorization: Bearer $VICIFAST_KEY" \
-H "Content-Type: application/json" \
-d '{ "quantity": 1, "area_code": "305", "dry_run": true }'
3. Buy it
The same request without dry_run, plus two things every request that spends money should carry:
- an
Idempotency-Keyheader - any unique string. If the connection drops and you send the request again with the same key, you get the original answer back instead of buying twice; max_total_cents- the most this request may charge. If the price is higher, nothing is bought.
curl -X POST https://vicifast.com/api/v1/numbers/purchase \
-H "Authorization: Bearer $VICIFAST_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "quantity": 1, "area_code": "305", "max_total_cents": 500 }'
A 201 means the numbers are yours. Name exact numbers instead of a quantity with "numbers": ["+13055550101"]. On a live account, buying needs an approved termination account.
4. Point it at your server
GET /api/v1/servers lists your VICIdial servers. Then tell a number where to ring:
curl -X PATCH https://vicifast.com/api/v1/numbers/%2B13055550101 \
-H "Authorization: Bearer $VICIFAST_KEY" \
-H "Content-Type: application/json" \
-d '{ "routing": { "server_id": "srv_sandbox", "in_group": "SALES" } }'
The answer's routing.state is pending until your server has taken the change, then applied. To change many numbers at once, PATCH /api/v1/numbers takes the same change with a list of up to 500 numbers. Add "cid_groups": ["FL_LOCAL"] to the routing and the numbers also join those caller-ID groups on the server.
5. Watch the calls
GET /api/v1/calls lists calls from the last 90 days, newest first. Filter with direction, number, from, to and window; GET /api/v1/calls/export returns the same calls as CSV.
curl "https://vicifast.com/api/v1/calls?number=%2B13055550101&window=7d" \
-H "Authorization: Bearer $VICIFAST_KEY"
Rather than polling, subscribe a webhook endpoint to call.inbound.completed and each finished call is sent to you as it happens - see Receiving VICIfast webhooks.
Moving to live
Swap the test key for a live one. Nothing else changes: the same requests, the same answers. In the sandbox you can also make a call ring or a month pass on demand - Testing in the sandbox shows how.
Is there an SDK?
Yes, for TypeScript and Python. Each one has a method for every endpoint, sends the Idempotency-Key for you, retries only what is safe to retry, and walks the pages of a list. Step 1 in each:
// npm install @vicifast/api
import { Vicifast } from '@vicifast/api';
const vf = new Vicifast({ apiKey: process.env.VICIFAST_KEY! });
const found = await vf.searchNumbers({ query: { area_code: '305', limit: 5 } });
# pip install vicifast
import os
from vicifast import Vicifast
vf = Vicifast(api_key=os.environ["VICIFAST_KEY"])
found = vf.search_numbers(area_code="305", limit=5)
What if something goes wrong?
Every error has the same shape - { "error": { "code": "...", "message": "..." } } - and every response carries an X-Request-Id to quote to support. Branch on code, never on the message. The limit is 600 requests a minute per key; over it, the answer is 429 with a Retry-After header. The full list of codes is in the reference.