Provision fax numbers for your users, send and receive faxes programmatically, extract structured data with AI, and react to delivery events via webhooks — without managing phone infrastructure.
The FaxSeal Partner API gives you full inbound and outbound fax capability under a single key.
X-Partner-Key on all requestsexternalUserId — a stable ID from your system (e.g. user_42)fax.received, fax.extracted) and outbound (fax.sending, fax.delivered, fax.failed)Base URL: https://faxseal.com/api/partner
All requests require your partner key in the X-Partner-Key header.
curl https://faxseal.com/api/partner/inbox \ -H "X-Partner-Key: sk_partner_YOUR_KEY_HERE"
Keep your key secret — it has full access to all users in your partner account.Get a key →
Provision a dedicated fax number for a user. Numbers persist until you release them and are billed monthly ($2.50/mo personal, $7.50/mo business).
curl -X POST https://faxseal.com/api/partner/numbers \
-H "X-Partner-Key: sk_partner_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"externalUserId":"user_42","areaCode":"415","tier":"personal"}'
Response 200:
{
"faxNumber": "+14155550123",
"city": "San Francisco",
"state": "CA",
"tier": "personal",
"webhookConfigured": true
}tier: personal (default) or business. Returns 409 if the user already has a number.
Response 200:
{ "active": true, "faxNumber": "+14155550123", "tier": "personal" }Response 200: { "ok": true }Send an outbound fax from a user's provisioned number. Deducts credits from your partner balance. The user must have a provisioned fax number — it becomes the caller ID automatically.
Accepts multipart/form-data (file upload) or application/json (remote URL). PDF only. Max 20 MB. Pages are counted before billing.
curl -X POST https://faxseal.com/api/partner/fax \ -H "X-Partner-Key: sk_partner_YOUR_KEY_HERE" \ -F "toNumber=+12125550001" \ -F "externalUserId=user_42" \ -F "callbackUrl=https://yourapp.com/api/fax-status" \ -F "[email protected]" Response 202: { "jobId": "clxyzabc", "status": "queued", "pages": 3, "creditsUsed": 3, "creditsRemaining": 97 }
curl -X POST https://faxseal.com/api/partner/fax \
-H "X-Partner-Key: sk_partner_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"toNumber": "+12125550001",
"externalUserId": "user_42",
"fileUrl": "https://yourapp.com/documents/form.pdf",
"callbackUrl": "https://yourapp.com/api/fax-status",
"callbackSecret": "whsec_..."
}'| Field | Required | Description |
|---|---|---|
toNumber | Yes | Destination fax number in E.164 format |
externalUserId | Yes | Identifies the sender — must have a provisioned number |
file | One of | PDF file (multipart upload) |
fileUrl | One of | HTTPS URL to a PDF (fetched server-side) |
callbackUrl | No | Overrides your default webhook for this fax only |
callbackSecret | No | HMAC secret for signing this fax's callbacks |
Credit cost = dialing zone rate × page multiplier (same formula as regular credit sends). Returns 402 if balance is insufficient — top up via Credits API. Returns 422 if the user has no provisioned number.
Returns received faxes for a user. Supports page, q (OCR search), and from (sender filter).
GET /api/partner/inbox?externalUserId=user_42
Response 200:
{
"faxes": [
{
"id": "clxyzabc",
"externalUserId": "user_42",
"fromNumber": "+15125551234",
"toNumber": "+14155550123",
"pages": 2,
"ocrText": "Patient name: Jane Smith...",
"ocrStatus": "done",
"extractedData": { "patient_name": "Jane Smith", ... },
"extractStatus": "done",
"fileUrl": "https://faxseal.com/api/partner/inbox/clxyzabc/file?token=...",
"receivedAt": "2026-04-18T14:22:00Z"
}
],
"total": 1,
"page": 1,
"pages": 1
}Set your default webhook URL via the Settings API. You can also override per fax using callbackUrl on the send request. FaxSeal delivers with up to 3 retry attempts (1 min → 5 min → 25 min) and a 10-second timeout.
| Event | Direction | When fired |
|---|---|---|
fax.received | Inbound | OCR complete (~30s after receipt) |
fax.extracted | Inbound | AI extraction complete (~60s after receipt) |
fax.sending | Outbound | Job accepted by carrier |
fax.delivered | Outbound | Carrier confirmed delivery |
fax.failed | Outbound | Delivery failed after all retries |
{
"event": "fax.delivered",
"jobId": "clxyzabc",
"status": "delivered",
"toNumber": "+12125550001",
"externalUserId": "user_42",
"pages": 3,
"creditsUsed": 3,
"timestamp": "2026-04-18T14:25:00Z"
}
// fax.failed also includes:
{
"failureReason": "no-answer" // busy | no-answer | failed | canceled
}FaxSeal signs every delivery with HMAC-SHA256 in the x-faxseal-signature header. Format: t=<unix_ts>,v1=<hex>. Verify by recomputing the HMAC over <timestamp>.<rawBody>.
// Node.js webhook verification
import { createHmac } from 'crypto';
const rawBody = await req.text();
const sig = req.headers.get('x-faxseal-signature'); // "t=1234567890,v1=abc123..."
const [tPart, v1Part] = sig.split(',');
const ts = tPart?.slice(2);
const expected = createHmac('sha256', process.env.FAXSEAL_WEBHOOK_SECRET)
.update(`${ts}.${rawBody}`)
.digest('hex');
if (!ts || !v1Part || expected !== v1Part.slice(3)) {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
}
// Respond 2xx quickly — process asynchronouslyOutbound faxes are charged in credits. 1 credit covers 1 fax page to a domestic number. International and multi-page faxes use more credits. Credits never expire.
curl https://faxseal.com/api/partner/credits \
-H "X-Partner-Key: sk_partner_YOUR_KEY_HERE"
Response 200:
{
"credits": 97,
"bundles": [
{ "id": "partner_100", "label": "100 credits", "amountCents": 3900, "credits": 100 },
{ "id": "partner_500", "label": "500 credits", "amountCents": 14900, "credits": 500, "popular": true },
{ "id": "partner_2000", "label": "2,000 credits", "amountCents": 49900, "credits": 2000 }
]
}Returns a Stripe Checkout URL. Redirect the operator (or your billing page) to complete payment. Credits are added immediately after payment confirmation.
curl -X POST https://faxseal.com/api/partner/credits \
-H "X-Partner-Key: sk_partner_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"bundle":"partner_500","successUrl":"https://yourapp.com/billing/success"}'
Response 200:
{
"url": "https://checkout.stripe.com/c/pay/...",
"sessionId": "cs_live_..."
}A low-balance warning email is sent to your billing address when credits drop below 10.
When an extractionSchema is set on your account, FaxSeal runs GPT-4o-mini over OCR text and fires a fax.extracted webhook with structured JSON.
{
"type": "patient_referral",
"fields": [
{ "name": "patient_name", "type": "string" },
{ "name": "dob", "type": "string" },
{ "name": "diagnosis", "type": "string" },
{ "name": "medications", "type": "array" },
{ "name": "referring_npi", "type": "string" }
]
}{
"event": "fax.extracted",
"faxId": "clxyzabc",
"externalUserId": "user_42",
"fromNumber": "+15125551234",
"fileUrl": "https://faxseal.com/api/partner/inbox/clxyzabc/file?token=...",
"ocrText": "PATIENT: Jane Smith DOB: 1980-03-15...",
"extracted": {
"patient_name": "Jane Smith",
"dob": "1980-03-15",
"diagnosis": "Type 2 Diabetes",
"medications": ["Metformin 500mg", "Lisinopril 10mg"],
"referring_npi": "1234567890"
}
}Query inbound and outbound activity for your partner account or for a specific user. Defaults to the current calendar month.
curl "https://faxseal.com/api/partner/usage?externalUserId=user_42&from=2026-04-01" \
-H "X-Partner-Key: sk_partner_YOUR_KEY_HERE"
Response 200:
{
"from": "2026-04-01T00:00:00.000Z",
"to": "2026-04-30T23:59:59.999Z",
"externalUserId": "user_42",
"credits": { "remaining": 97 },
"outbound": {
"total": 12,
"delivered": 10,
"failed": 1,
"queued": 1,
"sending": 0,
"creditsUsed": 34
},
"inbound": {
"total": 8,
"pages": 22
}
}Response 200:
{
"name": "AcmeHealth",
"webhookUrl": "https://acmehealth.com/api/faxseal/webhook",
"webhookSecret": "***",
"billingEmail": "[email protected]",
"extractionSchema": { ... },
"createdAt": "2026-01-01T00:00:00Z"
}Update webhookUrl, webhookSecret, billingEmail, and/or extractionSchema. All fields optional.
curl -X PATCH https://faxseal.com/api/partner/settings \
-H "X-Partner-Key: sk_partner_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"billingEmail":"[email protected]","webhookUrl":"https://acmehealth.com/api/faxseal/webhook"}'
Response 200: { "ok": true }billingEmail is required before purchasing credits via the Credits API.
Every partner account includes a self-serve web dashboard at /partner. Portal access is separate from the API — it is granted by an admin to specific FaxSeal user accounts.
Your FaxSeal account manager assigns you a role on your partner account. Once assigned, a Partner Portal link appears in your FaxSeal dashboard. You can also navigate directly to /partner.
| Page | What you can see | Min. role |
|---|---|---|
| Overview | Active numbers, credit balance, this-month sent/received counts | All |
| Usage | Job history, delivery rates, inbound totals, top users | All |
| Credits | Credit balance, full transaction log | All |
| Billing | Billing status, grace period, past-due notices | billing |
| Settings | API key reveal/copy, webhook URL configuration | developer |
| Team | Member list, add/remove members, change roles | owner |
| Role | Permissions |
|---|---|
owner | Full access + team membership management + ownership transfer |
admin | Overview, usage, credits, billing, settings, team roster (read-only) |
billing | Overview, usage, credits, billing status, team roster (read-only) |
developer | Overview, usage, credits, settings (webhook), team roster (read-only) |
Ownership transfer demotes all current owners to admin atomically. An account can only have one owner at a time.
fax.received fires first; fax.extracted fires after.Verify your email and your key is issued instantly — no waiting, no back-and-forth.
Get a partner key →