Integrate faxing into your product, back office, or workflow. Simple REST API, signed status webhooks, pay-as-you-go pricing — no subscription.
curl https://sendfax.me/api/v1/faxes \
-H "Authorization: Bearer sfx_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+15551234567",
"file": "'$(base64 -i contract.pdf)'",
"filename": "contract.pdf"
}'
# → 201 Created
# { "id": "fax_ab12…", "status": "queued",
# "pages": 3, "cost": 30, … }One credit balance, shared with your web account. Faxes are charged per page at the standard destination rate (10¢/page to the US) — API credit packs include bonus credit that brings your effective price down to 4¢/page. Credit never expires, and failed faxes are refunded automatically.
Create a key in Dashboard → API and pass it as a Bearer token. Keys are shown once and stored hashed — treat them like passwords. Requests are limited to 60 per minute per key.
Authorization: Bearer sfx_live_YOUR_KEYSend a fax. The PDF is base64-encoded in the request body (max 15 MB). Cost is computed server-side from the page count and destination rate, and charged to your balance. Returns 201 with the fax object.
{
"to": "+15551234567", // E.164 fax number, required
"file": "<base64 PDF>", // required
"filename": "contract.pdf" // optional
}// 201 Created
{
"id": "fax_ab12cd34ef56",
"direction": "sent",
"to": "+15551234567",
"pages": 3,
"cost": 30, // cents charged
"status": "queued",
"created_at": "2026-07-24T10:30:00.000Z"
}Fetch one fax and its current status: queued → sending → delivered or failed (failed faxes are refunded and retried once automatically). Poll this, or use webhooks below.
List faxes, newest first. Query params: limit (1–100, default 25), before (ISO timestamp cursor), direction (sent or received — inbound faxes to your fax number appear here too).
{ "data": [ { "id": "fax_…", … } ], "has_more": false }Your account email and current credit balance in cents.
{ "email": "you@company.com", "credit_balance": 4550 }Register an https endpoint in the dashboard and we'll POST every fax lifecycle event to it: fax.queued, fax.sending, fax.delivered, fax.failed and fax.received (inbound). Deliveries are retried up to 3 times and logged in your dashboard.
// Event payload
{
"id": "evt_9f8e7d6c5b4a",
"type": "fax.delivered",
"created_at": "2026-07-24T10:31:40.000Z",
"data": {
"fax_id": "fax_ab12cd34ef56",
"direction": "sent",
"to": "+15551234567",
"pages": 3,
"cost": 30,
"status": "delivered"
}
}// Verify the signature (Standard Webhooks spec —
// works with any svix-compatible library)
import { Webhook } from "svix";
const wh = new Webhook(process.env.SENDFAX_WEBHOOK_SECRET);
const event = wh.verify(rawBody, {
"webhook-id": req.headers["webhook-id"],
"webhook-timestamp": req.headers["webhook-timestamp"],
"webhook-signature": req.headers["webhook-signature"],
});Errors return a JSON body: { "error": { "code", "message" } }
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | Missing, invalid, or revoked API key |
| 402 | insufficient_credit | Balance too low for this fax — top up |
| 400 | invalid_number | `to` is not a valid E.164 number |
| 400 | invalid_file | File is not a readable PDF (max 15 MB) |
| 429 | rate_limited | More than 60 requests in a minute |
| 502 | carrier_rejected | Carrier refused the fax — you were not charged |
Create a key, grab a credit pack, and send your first API fax in minutes.
Get your API key →