API Reference

Authentication

Authenticate every request with an API key from the API Keys page, sent as a bearer token:

Authorization: Bearer <publicId>.<secret>

MCP Server

The Fax.live MCP server allows Claude and other AI clients to call this API on your behalf, sending faxes, tracking delivery, and reviewing billing without a direct integration against the endpoints below.

Read the MCP server documentation →

Response Codes

This API communicates errors using standard HTTP status codes. Each error response also includes a message field describing the specific cause.

NameTypeDescription
200OKThe request succeeded.
400Bad RequestThe request was malformed or failed validation - check the error message for specifics.
401UnauthorizedYour API key is missing, malformed, or invalid.
402Payment RequiredYour account is suspended due to a failed payment. Update your payment method to restore access.
403ForbiddenYour credentials could not be authorized for this request.
404Not FoundThe resource you referenced (e.g. a faxId or fileId) doesn't exist or has expired.
409ConflictThe request conflicts with your account's current state, e.g. a fax send already in progress.
500Internal Server ErrorSomething went wrong on our end. Retrying later usually resolves this.
503Service UnavailableFax.live is temporarily unable to process requests - see Check API Status.

Document error codes

A 400 from Upload a document or Send a fax - when a document fails the size/page/format checks described there - also includes a data.errorCode field alongside message, for branching on the failure programmatically instead of matching message text. The same codes appear as validationCode in a successful (non-error) Check document or Check document by URL response:

NameTypeDescription
FILE_TOO_LARGEstringThe file exceeds the 30MB size limit.
TOO_MANY_PAGESstringThe file exceeds the 250 page limit.
INVALID_PDFstringThe file could not be read as a PDF.
ENCRYPTED_PDFstringThe file needs a password to open. PDFs with only editing restrictions (an owner password) are accepted.
DOWNLOAD_FAILEDstringfileUrl could not be downloaded - unreachable, a non-2xx response, or a network error.
DOWNLOAD_TIMEOUTstringDownloading fileUrl took too long and was aborted.

Check API status

GET /api/v1/status

Confirms your API key is valid and that Fax.live's services are currently up. Useful as a quick check before troubleshooting a failing integration.

curl https://api.fax.live/api/v1/status \
  -H "Authorization: Bearer <publicId>.<secret>"

Response

NameTypeDescription
status"ok"Always ok - a non-200 response means something is wrong.
checkedAtstring (ISO 8601)When this check was run.
{
  "status": "ok",
  "checkedAt": "2026-08-14T16:08:53.671Z"
}

Returns 503 with a generic error message if Fax.live is currently unavailable.

Upload a document

POST /api/v1/uploadDocument

Uploads a PDF and returns a fileId you can pass to sendFax below in place of fileUrl - use this instead of hosting the PDF publicly yourself. Uploaded files are automatically deleted after 24 hours.

Request Body

multipart/form-data with a single field:

NameTypeRequiredDescription
filebinary (PDF)RequiredThe PDF to upload. Max 30MB, max 250 pages.
curl -X POST https://api.fax.live/api/v1/uploadDocument \
  -H "Authorization: Bearer <publicId>.<secret>" \
  -F "file=@document.pdf;type=application/pdf"

Response

NameTypeDescription
fileIdstring (uuid)Pass this as fileId to sendFax in place of fileUrl.
pageCountintegerNumber of pages detected in the uploaded PDF.
expiresAtstring (ISO 8601)Approximately when the file will no longer be available. Upload again if you haven't sent by then.
{
  "fileId": "b3f1c9e2-4a6d-4b7a-9e21-7c9a6a4d21fe",
  "pageCount": 2,
  "expiresAt": "2026-08-19T16:08:53.671Z"
}

A 400 for a file that fails the size/page/format checks includes a data.errorCode - one of the document error codes:

{
  "statusCode": 400,
  "message": "File exceeds the 250 page limit (312 pages)",
  "data": { "errorCode": "TOO_MANY_PAGES" }
}

Check document

GET /api/v1/checkDocument

Checks a single uploaded file by fileId, or, if omitted, lists all of your currently uploaded files.

Query Parameters

NameTypeRequiredDescription
fileIdstring (uuid)OptionalA fileId returned by uploadDocument above. Omit to list all of your currently uploaded files instead.
curl "https://api.fax.live/api/v1/checkDocument?fileId=b3f1c9e2-4a6d-4b7a-9e21-7c9a6a4d21fe" \
  -H "Authorization: Bearer <publicId>.<secret>"

Response - checking a single file

NameTypeDescription
fileIdstring (uuid)Identifier for the uploaded file.
validbooleanWhether the file is still within its guaranteed availability window.
createdAtstring (ISO 8601)When the file was uploaded.
expiresAtstring (ISO 8601)Approximately when the file will no longer be available.
pageCountinteger | nullNumber of pages detected in the PDF at upload time. null for files uploaded before this field existed.
validToFaxboolean | nullWhether the file is within today's size/page limits. null when pageCount is unknown (see above).
validationCodestring | nullOne of the document error codes when validToFax is false. null otherwise.
estimatedCostobject | nullEstimated cost to send this document, based on the current per-page price. null when pageCount is unknown.
urlstringDownload URL for the file.

estimatedCost fields

NameTypeDescription
pricePerPageCentsintegerCurrent price per page, in cents.
currencystringThree-letter ISO currency code, e.g. usd.
totalCentsintegerpricePerPageCents multiplied by the document's pageCount.
{
  "fileId": "b3f1c9e2-4a6d-4b7a-9e21-7c9a6a4d21fe",
  "valid": true,
  "createdAt": "2026-08-19T16:08:53.671Z",
  "expiresAt": "2026-08-20T16:08:53.671Z",
  "pageCount": 3,
  "validToFax": true,
  "validationCode": null,
  "estimatedCost": {
    "pricePerPageCents": 5,
    "currency": "usd",
    "totalCents": 15
  },
  "url": "https://firebasestorage.googleapis.com/..."
}

Returns 404 if no file exists for that fileId.

Response - listing all files

{
  "files": [
    {
      "fileId": "b3f1c9e2-4a6d-4b7a-9e21-7c9a6a4d21fe",
      "valid": true,
      "createdAt": "2026-08-19T16:08:53.671Z",
      "expiresAt": "2026-08-20T16:08:53.671Z",
      "pageCount": 3,
      "validToFax": true,
      "validationCode": null,
      "estimatedCost": {
        "pricePerPageCents": 5,
        "currency": "usd",
        "totalCents": 15
      },
      "url": "https://firebasestorage.googleapis.com/..."
    }
  ]
}

Check document by URL

GET /api/v1/checkDocumentByUrl

Like Check document above, but for a file you haven't uploaded - downloads a publicly reachable PDF from fileUrl and reports the same information, so you can pre-flight-check a fileUrl before passing it to sendFax below.

This endpoint downloads the entire file before it can respond, so it can take up to a couple of minutes for a large file or a slow host - set a generous timeout on your side for this call rather than the fast response times of the other endpoints on this page.

Query Parameters

NameTypeRequiredDescription
fileUrlstringRequiredPublicly reachable URL to a PDF to check.
curl "https://api.fax.live/api/v1/checkDocumentByUrl?fileUrl=https%3A%2F%2Fexample.com%2Fdocument.pdf" \
  -H "Authorization: Bearer <publicId>.<secret>"

Response

NameTypeDescription
fileUrlstringThe fileUrl that was checked.
pageCountinteger | nullNumber of pages detected in the PDF. null if the file couldn't be read as a PDF.
sizeBytesintegerSize of the downloaded file, in bytes.
validToFaxbooleanWhether the file is within today's size/page limits and could be sent as-is.
validationErrorstring | nullReason validToFax is false. null when the file is valid.
validationCodestring | nullOne of the document error codes pairing with validationError. null when the file is valid.
estimatedCostobject | nullEstimated cost to send this document, based on the current per-page price. null when validToFax is false.

estimatedCost fields

NameTypeDescription
pricePerPageCentsintegerCurrent price per page, in cents.
currencystringThree-letter ISO currency code, e.g. usd.
totalCentsintegerpricePerPageCents multiplied by the document's pageCount.
{
  "fileUrl": "https://example.com/document.pdf",
  "pageCount": 3,
  "sizeBytes": 482910,
  "validToFax": true,
  "validationError": null,
  "validationCode": null,
  "estimatedCost": {
    "pricePerPageCents": 5,
    "currency": "usd",
    "totalCents": 15
  }
}

Returns 400 if the file couldn't be downloaded at all (e.g. the URL is unreachable or timed out) - that's different from a successful check that reports validToFax: false for a file that downloaded fine but is too large, has too many pages, or isn't a valid PDF:

{
  "fileUrl": "https://example.com/too-many-pages.pdf",
  "pageCount": 312,
  "sizeBytes": 9481022,
  "validToFax": false,
  "validationError": "File exceeds the 250 page limit (312 pages)",
  "validationCode": "TOO_MANY_PAGES",
  "estimatedCost": null
}

Send a fax

POST /api/v1/sendFax

Sends a fax using either a fileId from uploadDocument above or your own publicly hosted PDF via fileUrl. Rejects if a send is already in progress for your account.

This version of the API currently accepts US and Canada destination numbers only, in E.164 format. Numbers from other countries are rejected with a 400 error.

Request Body

Exactly one of fileUrl or fileId is required, along with toNumber:

NameTypeRequiredDescription
toNumberstringRequiredDestination fax number. Must be a US or Canada number in E.164 format, e.g. +14155551234.
fileUrlstringOptionalPublicly reachable URL to a PDF document to send. Required unless fileId is provided. Downloaded and validated (size/page limits) before sending - rejected with 400 if it fails, and can take up to a couple of minutes for a large file or slow host. Consider Check document by URL above to run that check up front.
fileIdstring (uuid)OptionalA fileId returned by uploadDocument above. Required unless fileUrl is provided.
curl -X POST https://api.fax.live/api/v1/sendFax \
  -H "Authorization: Bearer <publicId>.<secret>" \
  -H "Content-Type: application/json" \
  -d '{
    "toNumber": "+14155551234",
    "fileUrl": "https://example.com/document.pdf"
  }'

Or, sending a previously uploaded document by its fileId instead:

{
  "toNumber": "+14155551234",
  "fileId": "b3f1c9e2-4a6d-4b7a-9e21-7c9a6a4d21fe"
}

Response

NameTypeDescription
faxIdstringUnique identifier for this fax. Use it with the status endpoint below.
status"QUEUED"Always QUEUED immediately after a successful send request.
{
  "faxId": "fax_abc123",
  "status": "QUEUED"
}

If fileUrl is provided, it's downloaded and validated before sending - a 400 here means nothing was sent, with data.errorCode set to one of the document error codes:

{
  "statusCode": 400,
  "message": "File exceeds the 250 page limit (312 pages)",
  "data": { "errorCode": "TOO_MANY_PAGES" }
}

Check fax status

GET /api/v1/fax/:faxId/status

Returns the full fax entry, including its current status.

Path Parameters

NameTypeRequiredDescription
faxIdstringRequiredThe faxId returned by sendFax.
curl https://api.fax.live/api/v1/fax/{faxId}/status \
  -H "Authorization: Bearer <publicId>.<secret>"

Response - Fax Entry

NameTypeDescription
faxIdstringUnique identifier for this fax.
destinationstringDestination number, in E.164 format.
originstringYour reserved fax number, in E.164 format.
status"QUEUED" | "SENDING" | "SENT" | "FAILED"Current delivery status.
pageCountinteger | nullNumber of pages faxed. null until known.
createdAtstring (ISO 8601)When the send was requested.
completedAtstring (ISO 8601) | nullWhen the fax reached a terminal status (SENT or FAILED). null until then.
failReasonstring | nullReason for failure, set only when status is FAILED.
fileUrlstringThe source PDF url that was faxed.
{
  "faxId": "fax_abc123",
  "destination": "+14155551234",
  "origin": "+14155559876",
  "status": "SENT",
  "pageCount": 2,
  "createdAt": "2026-08-14T16:08:53.671Z",
  "completedAt": "2026-08-14T16:09:12.114Z",
  "failReason": null,
  "fileUrl": "https://example.com/document.pdf"
}

Fax history

GET /api/v1/faxHistory

Returns a list of your faxes, newest first. All query parameters are optional.

Query Parameters

NameTypeRequiredDescription
limitintegerOptionalPage size. Default 20, max 100.
cursorstringOptionalPass the previous response's nextCursor to fetch the next page.
destinationstringOptionalFilter to faxes sent to this number. Must be a US or Canada number in E.164 format, e.g. +14155551234.
startDatestring (date)OptionalOnly faxes created on or after this date. Accepts YYYY-MM-DD or a full ISO timestamp.
endDatestring (date)OptionalOnly faxes created on or before this date. Accepts YYYY-MM-DD or a full ISO timestamp - a bare date includes that whole day.
curl "https://api.fax.live/api/v1/faxHistory?limit=20&destination=%2B14155551234&startDate=2026-08-01&endDate=2026-08-31" \
  -H "Authorization: Bearer <publicId>.<secret>"

Response

NameTypeDescription
entriesFaxEntry[]Page of fax entries, newest first. See fields below.
nextCursorstring | nullPass as cursor to fetch the next page. null once there are no more results.

Fax Entry fields

NameTypeDescription
faxIdstringUnique identifier for this fax.
destinationstringDestination number, in E.164 format.
originstringYour reserved fax number, in E.164 format.
status"QUEUED" | "SENDING" | "SENT" | "FAILED"Current delivery status.
pageCountinteger | nullNumber of pages faxed. null until known.
createdAtstring (ISO 8601)When the send was requested.
completedAtstring (ISO 8601) | nullWhen the fax reached a terminal status (SENT or FAILED). null until then.
failReasonstring | nullReason for failure, set only when status is FAILED.
fileUrlstringThe source PDF url that was faxed.
{
  "entries": [
    {
      "faxId": "fax_abc123",
      "destination": "+14155551234",
      "origin": "+14155559876",
      "status": "SENT",
      "pageCount": 2,
      "createdAt": "2026-08-14T16:08:53.671Z",
      "completedAt": "2026-08-14T16:09:12.114Z",
      "failReason": null,
      "fileUrl": "https://example.com/document.pdf"
    }
  ],
  "nextCursor": "fax_xyz789"
}

Billing history

GET /api/v1/billingHistory

Returns your invoices, newest first. All query parameters are optional.

Query Parameters

NameTypeRequiredDescription
limitintegerOptionalPage size. Default 20, max 100.
cursorstringOptionalPass the previous response's nextCursor to fetch the next page.
startDatestring (date)OptionalOnly invoices created on or after this date. Accepts YYYY-MM-DD or a full ISO timestamp.
endDatestring (date)OptionalOnly invoices created on or before this date. Accepts YYYY-MM-DD or a full ISO timestamp - a bare date includes that whole day.
curl "https://api.fax.live/api/v1/billingHistory?limit=20&startDate=2026-08-01&endDate=2026-08-31" \
  -H "Authorization: Bearer <publicId>.<secret>"

Response

NameTypeDescription
entriesBillingEntry[]Page of invoices, newest first. See fields below.
nextCursorstring | nullPass as cursor to fetch the next page. null once there are no more results.

Billing Entry fields

NameTypeDescription
idstringUnique invoice identifier.
statusstringInvoice status, e.g. paid, open, void, uncollectible.
totalintegerInvoice total, in cents.
currencystringThree-letter ISO currency code, e.g. usd.
createdstring (ISO 8601)Invoice creation timestamp.
descriptionstring | nullLine-item descriptions, joined together.
hostedInvoiceUrlstring | nullLink to the hosted invoice page. A fax.live url that redirects (302) to the actual page.
invoicePdfstring | nullDirect link to a downloadable PDF of the invoice.
{
  "entries": [
    {
      "id": "in_1AbCdEfGhIjKlMnO",
      "status": "paid",
      "total": 1999,
      "currency": "USD",
      "created": "2026-08-14T16:08:53.671Z",
      "description": "Fax API Access",
      "hostedInvoiceUrl": "https://api.fax.live/api/v1/billingHistory/in_1AbCdEfGhIjKlMnO/hosted",
      "invoicePdf": "https://pay.fax.live/invoice/.../pdf"
    }
  ],
  "nextCursor": "in_0ZyXwVuTsRqPoNm"
}

Balance

GET /api/v1/balance

Returns your current account balance information.

curl https://api.fax.live/api/v1/balance \
  -H "Authorization: Bearer <publicId>.<secret>"

Response

NameTypeDescription
faxCreditUsage.balanceCentsintegerUnbilled fax credit usage so far this period, in cents.
faxCreditUsage.creditsUsedintegerNumber of fax page credits used so far this period.
baseFee.priceCentsintegerThe flat base subscription price, in cents, billed once per term.
baseFee.term"MONTH"Billing cadence for the base fee. Currently always MONTH.
nextBillingDatestring (ISO 8601) | nullWhen both charges above are next billed - as two separate invoices landing the same day, not combined into one.
totalCentsintegerConvenience sum of faxCreditUsage.balanceCents and baseFee.priceCents. Informational only - they're billed separately.
paymentMethodOnFilebooleanWhether a default payment method is on file for your account.
cardExpiredboolean | nullWhether the default payment method's card has expired. null if there's no card on file (e.g. bank account, or no payment method at all).
manageBillingUrlstring | nullLink to this account's billing page, to update the payment method or review invoices.
{
  "faxCreditUsage": {
    "balanceCents": 350,
    "creditsUsed": 7
  },
  "baseFee": {
    "priceCents": 199,
    "term": "MONTH"
  },
  "nextBillingDate": "2026-09-14T16:08:53.671Z",
  "totalCents": 549,
  "paymentMethodOnFile": true,
  "cardExpired": false,
  "manageBillingUrl": "https://api.fax.live/billing"
}