Skip to main content

Overview

This walks through the shortest path from a fresh API key to a finished call result: generate a key, create a contact, schedule an outbound call, poll it until it finishes, then fetch the transcript and summary. Every request below is a real endpoint you can run as-is once you swap in your own key, script, and number. For the full endpoint list see REST Endpoints (OpenAPI); for what each field on a call means see Call Statuses, End Reasons & Outcomes Reference.

1. Generate an API key

In the app, go to Settings → API Keys and click Generate Key. Give it an optional Key Name (optional) (for example Quickstart test) so you can tell keys apart later, then click Generate. The full key is shown exactly once — “Copy your API key now. It won’t be shown again.” Copy it somewhere safe. Afterwards the key list only shows its prefix (keys start with vxw_) alongside its name, creation date, and last-used date, so if you lose the plaintext value you’ll need to revoke it and generate a new one. Every request below authenticates with this key as a bearer token:
An API key is scoped to the team it was generated under — every contact, call, and record it touches belongs to that team. See API Keys & Authentication for revocation and error details, and Rate Limits & Request Limits for how many requests per minute a key can make.

2. Create a contact

phone_number and first_name are required; last_name, email, address, location, gender, age, and title are optional. Send the number in whatever common local format you have on hand — the API normalises it to E.164 for you (0429069971 becomes +61429069971). If a contact with that normalised number already exists on your team, the request fails with 409 Conflict rather than creating a duplicate. A successful call returns 201 Created:
Keep contact_id — you’ll want it if you look the contact up again later, though scheduling a call in the next step only needs the phone number.

3. Find your script_id and from_number

Two values are required to schedule a call and both live in the app rather than being generated by this API:
  • script_id — open Call Scripts, select the script you want the call to run, go to its Settings tab, and read the Script UUID field on the Call Settings card.
  • from_number — go to Numbers & Routing → Numbers, select the number you want to call from, and use the Copy number button that appears when you hover over the number in its detail panel. It must be a number that belongs to your team.

4. Schedule the call

from_number, script_id, and contact.phone_number are required. scheduled_time is an ISO 8601 timestamp and defaults to now if you leave it out. The contact block upserts by phone number — since 0429069971 normalises to the same contact you created in step 2, this call is linked to that existing contact rather than creating a second one; any first_name/last_name you send here updates the existing record. A successful call returns 201 Created:
Save call_id — every remaining step uses it.
from_number and contact.phone_number must both be sent in a format the API can parse to E.164 — either already E.164 (+61291234567) or a common local format (02 9123 4567). Both are normalised before the call is created.

5. Poll the call status

Poll on an interval (a few seconds is reasonable) until status reaches one of the terminal values — completed, voicemail, dropout, hang-up, rang-out, failed, cancelled, User rejected, or User unavailable. The full meaning of each status is documented on Call Statuses, End Reasons & Outcomes Reference — note that status reaching a terminal value means the call itself has finished, but the transcript and summary may still be generated a few seconds later.

6. Fetch the result

Once status is terminal, fetch the full result:
If you poll get-call-result too soon after status turns terminal, call_summary, structured_data, transcript, transcript_json, and objectives may still be empty — give processing a few more seconds and fetch again.

The %2B encoding gotcha

Whenever a phone number appears in a URL path — for example GET /api/v1/get-contact/{phone_number} — its leading + must be percent-encoded as %2B, because a literal + in a URL path is ambiguous with a space:
Phone numbers sent inside a JSON request body (like phone_number in create-contact or create-phone-call) don’t need this encoding — only ones placed directly in the URL path.

Handling errors

Every endpoint returns the same JSON error shape:
400 means the request itself was malformed (missing field, bad phone number, invalid timestamp); 401 means the API key is missing, malformed, or invalid; 403 means the API key has been revoked; 404 means the script_id, from_number, or call_id doesn’t exist or doesn’t belong to your team; 409 means a contact with that phone number already exists; 429 means you’ve hit a rate-limit bucket — see Rate Limits & Request Limits for the exact numbers and the Retry-After header to respect.

Next Steps

API Keys & Authentication

Generate, name, and revoke API keys, and the exact 401/403 responses to expect.

REST Endpoints (OpenAPI)

The full endpoint reference, including contacts, lists, custom variables, and webhooks.

Call Statuses, End Reasons & Outcomes Reference

Every status and end reason a call can report, plus cancel/reschedule/retry rules.

Rate Limits & Request Limits

Every rate-limit bucket, the 429 response headers, and the request body size cap.