Skip to main content

Outcome

You will send a fax to a sandbox magic number, poll for its status, receive a webhook event, and verify the signature. Everything runs against the sandbox. No real faxes are sent, and no real card is charged; the sandbox uses simulated credits on the same hold, capture, and release path as live.

Prerequisites

  • A mintfax sandbox API key (mfx_test_...). Sign up here if you do not have one.
  • Python 3.9 or later.
  • A PDF file to fax. Any single-page PDF works.
  • A publicly reachable URL for webhooks, or a tunnel tool such as ngrok.
Install the two libraries this guide uses:
requests is the HTTP client used throughout this guide. The Standard Webhooks library handles signature verification for you. There is no official mintfax Python SDK; the API is plain REST and works with any HTTP client.

Step 1: Send a fax

Post a fax to the sandbox success number +15005550001. This number always delivers on the first attempt. Create send_fax.py:
Run it:
Verify: The response status is 201 and the status field is queued. Save the returned id for the next step. The Idempotency-Key header makes this request safe to retry. If the network drops and you re-run the same script with the same key, mintfax returns the original response without sending a duplicate fax. Keys expire after 24 hours. See Idempotency keys for the full contract.

Async variant with httpx

If your application is async, swap requests for httpx:
The request shape is identical. Only the client changes.

Step 2: Check fax status

Poll GET /v1/faxes/{id} until the fax reaches a terminal state (delivered or failed). Create check_status.py:
Run it with the fax ID from step 1:
Verify: The fax reaches delivered and the loop exits.

Step 3: Receive a webhook event

mintfax sends a fax.delivered or fax.failed event to your webhook URL when a fax reaches a terminal state. mintfax follows the Standard Webhooks specification, so the reference library handles signature verification for you. Create webhook_server.py:
Start the server, then expose it with ngrok (or any tunnel):
Copy the ngrok HTTPS URL and register it as your environment’s webhook endpoint in the mintfax dashboard or via the API. Send another fax (step 1). The event is sent when the fax reaches a terminal state. Verify: The console prints Received fax.delivered for fax_... and the signature check passes. The signature is computed over the raw request bytes as HMAC-SHA256 of {webhook-id}.{webhook-timestamp}.{body}. Verifying a re-serialized JSON body will fail because whitespace and key order change the byte stream. The Standard Webhooks library handles this, along with constant-time comparison and the 5-minute timestamp tolerance. See Verify webhook signatures for what the library does and how to rotate secrets without dropping deliveries.

Step 4: Handle errors

Swap the destination number in send_fax.py to trigger different outcomes: The fax record’s error_code and error_message fields tell you what went wrong and whether a retry makes sense. Rejection-kind scenarios (+15005550006 for insufficient balance, +15005550099 for validation failure) fail the API call itself with a 402 or 422 envelope before any fax record is created. See the Error catalog for every error code and its recommended action. The Sandbox guide lists all magic numbers and the scenarios they simulate. For network errors, timeouts, and HTTP 500 or 503 responses, retry with exponential backoff and reuse the same Idempotency-Key so a mintfax-side accept during a client-side timeout does not produce a duplicate fax. The Idempotency keys guide covers backoff, jitter, and which status codes are safe to retry.

Verify

You have now:
  1. Sent a fax with POST /v1/faxes and an idempotency key.
  2. Polled for status until delivery.
  3. Received a webhook event and verified its signature.
  4. Triggered error scenarios with sandbox magic numbers.
Everything above ran in the sandbox. To send real faxes, swap your sandbox key for a live key (mfx_live_...), purchase credits, and use a real fax number as the destination.

What to do next

  • Verify webhook signatures - the full signing contract, secret rotation, and reference libraries in other languages.
  • Idempotency keys - key scope, TTL, replay headers, and retry patterns with backoff and jitter.
  • Error catalog - every error code, when it fires, and the recommended action.
  • Sandbox - magic numbers, simulated failures, and sandbox-live parity.
Last modified on September 29, 2026