# Faxes

| 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 |

**curl**

```bash
# 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)"
}
EOF
```

**Node**

```javascript
import { 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);
```

**Python**

```python
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**

```php
<?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 OKCopy**

```json
{
  "status": "test",
  "fax": {
    "from": "7185550101",
    "to": "7185550143",
    "filename": "intake-form.pdf",
    "fax_line": "Front office fax",
    "valid": true
  }
}
```

**Send response201 CreatedCopy**

```json
{
  "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 (`400` for another file type or more pages, `413` above 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 answer `429` when 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 a `from` that is not one of your active fax lines.
- If the fax service refuses the job, the send answers `500` with its reason in the message.
- `created_at` in 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}`.

[Faxes in the API reference](https://vocatech.com/developers/reference/faxes)
