SendFAXMail
Developer integration · Business & Enterprise plans

Send a Fax from Python — Calling the REST API

There is no official Send FAX Mail Python SDK to pip install, and we would rather say that than ship a thin wrapper that lags the API. You call the REST API directly with a standard HTTP client — requests or httpx — which is a handful of lines. You put your bearer key in the Authorization header, POST a recipient and a document to /v1/faxes, and read the JSON fax object back. Adding an Idempotency-Key header makes a retried call safe. The same key and endpoints power everything else, so once one call works the rest follow the same shape.

Encrypted in transit (TLS)
HIPAA BAA included
US-based fax numbers
No activation fees
No contracts
7-day free trial

Plan requirement

The REST API is part of the Business ($79.99/mo) and Enterprise ($169.99/mo) plans. A key generated on a lower plan is refused at request time with a 403 plan_upgrade_required, so your Python code gets a clear error rather than a silent no-op until you upgrade.

How it works

Any Python HTTP library works because the API is plain JSON over HTTPS. With requests you call requests.post on /v1/faxes, pass headers={'Authorization': 'Bearer sfm_live_...'}, and hand over a JSON body with `to` and a `document` object (base64 content plus content_type) or a public `document_url`. The response is a fax resource with an id, a status, and a page count; a follow-up requests.get on /v1/faxes/:id returns the latest status. Include an Idempotency-Key header so a network retry returns the original fax instead of dialing twice, and check the status code for 401 (bad or revoked key), 403 (plan gate), and 429 (rate limited) so your script backs off cleanly. httpx works identically if you prefer async.

What you can do

  • POST /v1/faxes from requests or httpx with a bearer key in the header
  • Send inline base64 with a document object, or hand over a public document_url
  • Poll GET /v1/faxes/:id for delivery status and page count
  • List recent faxes with GET /v1/faxes for a batch reconciliation job
  • Pass an Idempotency-Key so a retried POST never double-sends
  • Handle 401 / 403 / 429 explicitly so the script fails or backs off predictably

Setup steps

  1. 1Confirm the account is on Business or Enterprise so the API is active
  2. 2Create an API key at /dashboard/developers with the faxes:send scope
  3. 3Store the key in an environment variable, never hard-coded in the source
  4. 4pip install requests (or httpx) — there is no Send FAX Mail package to install
  5. 5POST to /v1/faxes with the Authorization header, a `to` number, and a document
  6. 6Read the returned fax id and poll GET /v1/faxes/:id, or register a webhook for status

Example

import os, base64, requests

pdf = base64.b64encode(open("invoice.pdf", "rb").read()).decode()
resp = requests.post(
    "https://www.sendfaxmail.com/v1/faxes",
    headers={
        "Authorization": f"Bearer {os.environ['SFM_API_KEY']}",
        "Idempotency-Key": "invoice-4021",
    },
    json={"to": "+15551234567",
          "document": {"content": pdf, "content_type": "application/pdf"}},
)
print(resp.json()["id"], resp.json()["status"])

Python Fax — FAQ

No. There is no package to pip install from us. The API is plain JSON over HTTPS, so you call it with requests or httpx in a few lines. We prefer pointing you at the raw endpoints over publishing a wrapper that could drift behind the real API.

Either. For a local file, read the bytes, base64-encode them, and put them in a document object with a content_type. For a file already reachable at a public HTTPS URL, pass document_url instead and let our server fetch it behind an SSRF guard — that keeps your request body small for large PDFs.

Set an Idempotency-Key header with a value unique to that one fax. If the POST times out and your script retries with the same key, our API returns the fax it already created rather than dialing again. Reuse the key only for retries of that send, and use a fresh one for the next fax.

Two ways. Poll requests.get on /v1/faxes/:id using the id from the send response, and read the status field until it settles. Or, to avoid polling, register a webhook endpoint at /dashboard/developers and receive fax.delivered and fax.failed events at a small Python service (Flask or FastAPI) that verifies the X-SFM-Signature.

Build with the Python Fax

API access and webhooks are included on the Business and Enterprise plans. Create a key at /dashboard/developers and start sending.

7-day free trial · No credit card required