Vocatech API
API reference
Read from the API’s own reference file every hour.
Every route of the Vocatech API with its parameters, its fields, its answers and its errors, read from the API’s own file every hour. To learn a job step by step, start with the developer guide.
The Vocatech API connects your own systems to your phone system. Read your calls, texts and faxes. Send texts and faxes. Look up who is calling. Keep your contacts in sync. Have your AI agent place a call. Open a support ticket. Get every event pushed to your server by webhook.
Base URL: https://api.vocatech.com. Paths start with /v1. Requests and responses are JSON.
Server to server only. The API sends no CORS headers. Keep your key on your server. Never put it in a web page or a mobile app.
Keys. Send your key on every request as Authorization: Bearer YOUR_API_KEY. A key is an opaque 32-character secret. It is not a JWT. Make the main key in the Vocatech portal on your company's Integrations page (Generate or Regenerate). Make metered texting keys under Textdock > API Messaging, one per integrator, up to 10. The API cannot create or change keys.
Every route
Getting started
Calls
Messages
- POST
/v1/Send a textmessages - GET
/v1/List messagesmessages - GET
/v1/See the send queuemessages/ queue - DELETE
/v1/Cancel every queued messagemessages/ queue - DELETE
/v1/Cancel one queued messagemessages/ queue/ {id}
Faxes
Media
Callers
Contacts
- GET
/v1/List contact fieldscontacts/ fields - GET
/v1/List contactscontacts - POST
/v1/Create or update contactscontacts - DELETE
/v1/Delete contactscontacts - GET
/v1/Find contacts by phone numbercontacts/ lookup
AI agents
Support
Knowledge
Old paths
Webhook endpoints
- GET
/v1/List webhook endpointswebhooks - POST
/v1/Create a webhook endpointwebhooks - GET
/v1/List failed deliverieswebhooks/ failures - GET
/v1/Get a webhook endpointwebhooks/ {id} - PATCH
/v1/Update a webhook endpointwebhooks/ {id} - DELETE
/v1/Delete a webhook endpointwebhooks/ {id} - POST
/v1/Send a test deliverywebhooks/ {id}/ test
Every webhook event
- POST
call.startedAn extension started ringing or dialing - POST
call.answeredAn extension answered - POST
call.endedA call ended - POST
call.transcriptionA recorded call has its transcript - POST
message.sentA text went out through the API or an automation - POST
message.receivedA text or WhatsApp message arrived - POST
message.status_updatedThe carrier reported on a text - POST
fax.sentAn outgoing fax is in progress - POST
fax.receivedAn incoming fax is arriving - POST
fax.deliveredA fax completed - POST
fax.failedA fax failed
Scopes
The main key reaches every route. A key can be narrowed to one or more scopes. A scoped key that calls a route outside its scopes gets 403 with scopes and path in the body. Every key may call GET /v1/whoami.
| Scope | Reaches |
|---|---|
messaging | /v1/messages (send, history, queue), /v1/reports/messages, /v1/media (message attachments only), /v1/webhooks (message events only) |
agents | /v1/agents, /v1/callers, /v1/contacts/lookup |
support | /v1/support, /v1/knowledge |
knowledge | /v1/knowledge |
A scoped key sees and changes only the webhooks it created, and only their failures.
IP allow-list
A key can be locked to exact IPv4 or IPv6 addresses in the portal. Ranges are not supported. An empty list allows any address. A request from any other address gets 403 with client_ip in the body. Call GET /v1/whoami first and enter the address exactly as it shows client_ip.
Rate limits
Every key has a separate counter for each kind of request. Windows are fixed and run on UTC: a minute, an hour and a day each reset on the clock. Refused requests count too.
| Counter | Requests | Per minute | Per hour | Per day |
|---|---|---|---|---|
default | everything not listed below | 600 | 3,600 | 100,000 |
reports | GET /v1/calls, GET /v1/messages, /v1/reports/* | 300 | 3,000 | 100,000 |
messages | POST /v1/messages on a main key | 20 | 200 | |
faxes | POST /v1/faxes, per account | 3 | 50 faxes sent | |
dial | POST /v1/agents/{id}/calls | 10 | 500 | |
tickets | POST /v1/support/tickets | 10 | 200 | |
knowledge | GET or POST /v1/knowledge/answer | 30 | 2,000 |
- A metered API Messaging key (scope
messaging) is not held to 20 a minute and 200 a day. Its sends are accepted and paced by its own queue: message parts per minute (60 by default) and messages per day (5,000 by default), set per key by Vocatech. The backstop of 100,000 requests a day still applies. A company-wide cap of 960 T-Mobile-bound messages a day, shared with the company's broadcasts, also paces the queue (limits.tmobile_day_allowanceinGET /v1/messages/queue); T-Mobile's day resets at midnight Pacific, and every number is looked up for its carrier before the send. - A metered API Messaging key's sends are paid per message and are outside the account's included texting limit (50 texts an hour and 150 a day as standard): that limit never holds them back and they never use it up. Texts sent with a main key count toward it, together with the texts the account's people send, and past it the send is answered
429. - A request without a live key (missing, wrong or turned off) is counted by source address: 60 a minute and 600 an hour.
- Faxes are counted per account, not per key: 3 requests a minute, and 50 faxes actually sent a day, counted by the Eastern calendar day (a dry run or a refused request does not count toward the 50). A fax is a PDF of at most 25 pages. The fax API is for sending your own documents; it is not for marketing or bulk faxing.
- Each account also has a monthly allowance of outbound fax pages, 1,000 a month for each fax line on the account (unless Vocatech set another figure), pooled across the lines, so an account with three lines may send 3,000 pages a month from any one of them. It is the same count the portal and email to fax keep. Past it,
POST /v1/faxesanswers429. - Every
429from a counter carries aRetry-Afterheader: the seconds until that window resets.
{"error":"Rate limit exceeded","period":"minute","limit":20,"counter":"messages","retry_after":37}Errors
| Status | Meaning |
|---|---|
400 | Bad input: a date, a number, a window over 366 days, an end before a start. |
401 | No key, or a key that is wrong or turned off. |
403 | Outside the key's scopes, an address not on the allow-list, or the request was refused (for example, from is not your number, or the recipient opted out). |
404 | Not found, or not yours. |
409 | A conflict: a queued message already sending or finished, or a support ticket being worked (retry after Retry-After). |
410 | The media file is no longer available. |
413 | A fax document over 20 MB. |
422 | A field failed validation. The message says which. |
429 | A rate limit. See above. |
502 | A service we rely on answered and refused. |
503 | Retry. The key could not be checked just now (Retry-After: 5), or a service could not be reached. |
504 | A text send was not confirmed. It may have gone out. Check GET /v1/messages before you retry. |
Errors come in a few shapes:
- Key errors (
401, the key-check503):{"error":"Unauthorized","message":"Missing or invalid Authorization header."} - Access errors (
403scope or address):{"error":"Forbidden","message":"...","scopes":"messaging","path":"/v1/calls"}or{"error":"Forbidden","message":"...","client_ip":"198.51.100.7"} - Rate limits (
429): see above. - Action errors, from a route that ran:
{"error":{"code":404,"type":"NOT_FOUND","message":"Attachment not found."}}.typeisBAD_REQUEST,UNAUTHORIZED,FORBIDDEN,NOT_FOUND,CONFLICT,UNPROCESSABLE_ENTITY,RATE_LIMIT_EXCEEDED,SERVER_ERROR, orERRORfor any other status. - Route errors, for an unknown path, a wrong method, a webhook that is not found, or an unexpected fault:
{"statusCode":404,"error":{"type":"RESOURCE_NOT_FOUND","description":"Webhook not found."}}
Conventions
- Times in responses are UTC, ISO 8601, like
2026-09-24T14:05:09.000Z, unless a field says otherwise. - Report windows (
start_date,end_date) are local days intimezone, which defaults toAmerica/New_York. - Phone numbers in reports are digits without the leading 1, like
7185550142. Message and fax webhooks use E.164, like+17185550142. - Lists page with
page(from 1) andlimit.metacarries the totals. - Durations are in seconds.
info.versionis the date this reference was last checked against the code. New fields can appear in responses. Build clients that ignore fields they do not know.
The file behind this reference
The whole reference is one OpenAPI 3.1 file, the API’s own, kept with its code. Hand the file to a coding tool or import it into an API client. Each page here is also plain text for an AI, and the whole reference is one file.
