VICIfast
All guides

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.

VICIfastLast updated

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 starts vf_test_ and works against a sandbox: a pretend $100 wallet, a made-up catalogue and one server called srv_sandbox. Start with a test key.
  • Scopes. Grant only what the integration needs. For this guide: numbers:read, numbers:buy and numbers: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-Key header - 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.