By area
Faxes
Written beside the API’s code, and read from it every hour.
| Method | Path | What it does |
|---|---|---|
| POST | /v1/faxes | Send a fax |
| GET | /v1/faxes | Fax history, sent and received |
| Field | Meaning |
|---|---|
from | One of your active fax lines |
to | A 10-digit US or Canadian number. Premium numbers (900, 976) and other countries' area codes are refused. |
file | The document, a base64 PDF of at most 25 pages. Up to 20 MB. |
filename | Optional. document.pdf by default. |
recipient_name, subject | Optional |
test | true for a dry run |
# Remove "test": true to send it for real.
# base64 -w0 is GNU coreutils; on a Mac use: base64 -i intake-form.pdf
curl -X POST https://api.vocatech.com/v1/faxes \
-H "Authorization: Bearer $VOCATECH_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<EOF
{
"from": "7185550101",
"to": "7185550143",
"filename": "intake-form.pdf",
"subject": "Signed intake form",
"test": true,
"file": "$(base64 -w0 intake-form.pdf)"
}
EOFimport { readFile } from 'node:fs/promises';
import { vt } from './vocatech.mjs';
const res = await vt('POST', '/v1/faxes', {
from: '7185550101', // one of your fax lines
to: '7185550143',
file: (await readFile('intake-form.pdf')).toString('base64'),
filename: 'intake-form.pdf',
subject: 'Signed intake form',
test: true, // remove to send it for real
});
console.log(res.status, res.fax);import base64
from vocatech import vt
with open("intake-form.pdf", "rb") as f:
document = base64.b64encode(f.read()).decode()
res = vt("POST", "/v1/faxes", {
"from": "7185550101", # one of your fax lines
"to": "7185550143",
"file": document,
"filename": "intake-form.pdf",
"subject": "Signed intake form",
"test": True, # remove to send it for real
})
print(res["status"], res["fax"])<?php
require __DIR__ . '/vocatech.php';
$res = vt('POST', '/v1/faxes', [
'from' => '7185550101', // one of your fax lines
'to' => '7185550143',
'file' => base64_encode(file_get_contents('intake-form.pdf')),
'filename' => 'intake-form.pdf',
'subject' => 'Signed intake form',
'test' => true, // remove to send it for real
]);
echo $res['status'], PHP_EOL;Dry run response200 OK
{
"status": "test",
"fax": {
"from": "7185550101",
"to": "7185550143",
"filename": "intake-form.pdf",
"fax_line": "Front office fax",
"valid": true
}
}Send response201 Created
{
"status": "queued",
"fax": {
"fax_id": "fax_90412",
"from": "7185550101",
"to": "7185550143",
"filename": "intake-form.pdf",
"subject": "Signed intake form",
"created_at": "2026-09-24T09:20:41-04:00"
}
}- Limits: a PDF of at most 25 pages and 20 MB (
400for another file type or more pages,413above 20 MB), 3 faxes a minute and 50 faxes sent a day per account (the day runs midnight to midnight Eastern), and the account's monthly allowance of outbound pages, 1,000 a month for each fax line on the account unless Vocatech set another figure, pooled across the lines, the same count the portal and email to fax keep. The day and monthly limits answer429when reached. The fax API is for sending your own documents, not for marketing or bulk faxing. - Faxing must be on for the account. Otherwise both fax routes answer
403, as does afromthat is not one of your active fax lines. - If the fax service refuses the job, the send answers
500with its reason in the message. created_atin the send answer carries New York time with its offset. The other times in the API are UTC.
History takes start_date, end_date, timezone, page and limit as for calls, sort (day_desc or day_asc), direction (incoming or outgoing), status (in_progress, completed, failed or restricted) and search (part of the other number or the subject). Each fax has fax_id, direction, status, from, to, pages, subject, has_document and sent_at. When has_document is true, fetch the PDF with GET /v1/media/{fax_id}.
