Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintfax.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

You sent a fax. Now you need to know what happened. mintfax gives you two ways to track delivery: poll the API for the current status, or receive webhook events as the status changes. This guide covers both approaches and helps you decide which one fits your integration.

Fax status lifecycle

Every fax moves through a predictable set of states:
queued -> submitted -> in_progress -> delivered
                                   -> failed
StatusMeaningTerminal?
queuedFax accepted and waiting for processingNo
submittedSent to the carrier for transmissionNo
in_progressCarrier is actively transmitting pagesNo
deliveredCarrier confirmed receipt. Credits captured.Yes
failedAll retry attempts exhausted. Credits released (hold refunded).Yes
A fax reaches exactly one terminal state. Once you see delivered or failed, the status will not change again.

Approach 1: Poll the API

Polling works well for one-off scripts, debugging, and simple integrations where you want to check status on your own schedule. Call GET /fax/{id} to retrieve the full fax record, including status, error_code, error_message, and timestamps.
curl https://api.mintfax.com/v1/fax/fax_01H7N9WXYZ8VC2QPK5MTRDE3FA \
  -H "Authorization: Bearer fx_test_abc123..."
The response includes everything you need to determine what happened:
{
  "id": "fax_01H7N9WXYZ8VC2QPK5MTRDE3FA",
  "status": "delivered",
  "to": "+12125551234",
  "pages": 3,
  "retries_remaining": 3,
  "created_at": "2026-05-09T14:22:01Z",
  "submitted_at": "2026-05-09T14:22:03Z",
  "completed_at": "2026-05-09T14:22:08Z"
}
If the fax failed, the response includes error_code and error_message:
{
  "id": "fax_01H7N9WXYZ8VC2QPK5MTRDE3FA",
  "status": "failed",
  "to": "+12125551234",
  "error_code": "line_busy",
  "error_message": "Recipient line busy after all retry attempts",
  "retries_remaining": 0,
  "completed_at": "2026-05-09T14:25:30Z"
}

Poll loop example

If you need to wait for a terminal status, poll with a delay between requests. Fax delivery typically takes 30 seconds to a few minutes depending on page count and carrier conditions.
# Poll every 5 seconds until the fax reaches a terminal status
FAX_ID="fax_01H7N9WXYZ8VC2QPK5MTRDE3FA"

while true; do
  STATUS=$(curl -s https://api.mintfax.com/v1/fax/$FAX_ID \
    -H "Authorization: Bearer fx_test_abc123..." \
    | jq -r '.status')

  echo "Status: $STATUS"

  if [ "$STATUS" = "delivered" ] || [ "$STATUS" = "failed" ]; then
    break
  fi

  sleep 5
done
Respect rate limits. Polling more frequently than once per second will trigger HTTP 429 responses. A 5-second interval is a reasonable default.

Approach 2: Webhooks

Webhooks push status updates to your server the moment they happen. Use them for production systems that need real-time delivery confirmation without polling overhead.

Set up a webhook endpoint

Register your endpoint and subscribe to the events you care about:
curl -X POST https://api.mintfax.com/v1/account/webhooks \
  -H "Authorization: Bearer fx_test_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://acme.com/webhooks/mintfax",
    "events": ["fax.delivered", "fax.failed", "fax.retry_scheduled"]
  }'

Events for delivery tracking

These are the events relevant to tracking a fax through its lifecycle:
EventFires when
fax.queuedFax accepted and placed in the processing queue
fax.sendingFax picked up from queue and submitted to the carrier
fax.deliveredCarrier confirmed delivery (terminal)
fax.failedAll retries exhausted, fax permanently failed (terminal)
fax.retry_scheduledAttempt failed but retries remain - will retry
For most integrations, subscribing to fax.delivered and fax.failed is enough. Add fax.retry_scheduled if you want visibility into transient failures before the final outcome.

Webhook payload

Every event payload includes event_id for deduplication and timestamp for ordering:
{
  "event": "fax.delivered",
  "event_id": "evt_01H7NA3WXYZ8VC2QPK5MTRDE3F",
  "timestamp": "2026-05-09T14:22:08Z",
  "data": {
    "id": "fax_01H7N9WXYZ8VC2QPK5MTRDE3FA",
    "status": "delivered",
    "to": "+12125551234",
    "pages": 3,
    "completed_at": "2026-05-09T14:22:08Z"
  }
}
Store each event_id you process and skip duplicates. Events may arrive out of order, so use timestamp and status to determine the latest state.

Per-fax webhook override

Need delivery updates for a specific fax sent to a different URL? Pass webhook_url when you send the fax:
curl -X POST https://api.mintfax.com/v1/fax \
  -H "Authorization: Bearer fx_test_abc123..." \
  -F "to=+12125551234" \
  -F "file=@document.pdf" \
  -F "webhook_url=https://acme.com/webhooks/urgent-fax"
The per-fax URL receives events for that fax only, in addition to any account-level webhook endpoints.

Retry behavior

mintfax retries failed delivery attempts automatically. By default, each fax gets up to 3 retries (configurable from 0 to 10 via fax settings). Here is how retries work:
  1. The carrier reports a failure (busy line, no answer, etc.).
  2. mintfax decrements retries_remaining on the fax record.
  3. If retries remain, mintfax fires a fax.retry_scheduled event and re-queues the fax with a backoff delay.
  4. If no retries remain, mintfax fires fax.failed and releases the credit hold.
The retries_remaining field on the fax record tells you how many attempts are left. When you poll a fax that is mid-retry, you will see a non-terminal status with a decremented retries_remaining value:
{
  "id": "fax_01H7N9WXYZ8VC2QPK5MTRDE3FA",
  "status": "queued",
  "retries_remaining": 1,
  "error_code": "line_busy",
  "error_message": "Recipient line busy"
}
This fax started with 3 retries, has used 2, and is queued for its final attempt. If this attempt also fails, the status moves to failed.

Choosing an approach

ConsiderationPollingWebhooks
Setup complexityNone - just call GET /fax/{id}Requires a public HTTPS endpoint
LatencyDepends on poll intervalNear real-time
ScaleFine for low volumeBetter at high volume
InfrastructureNo server requiredNeeds a reachable server
Best forScripts, debugging, batch checksProduction apps, real-time dashboards
You can use both. Poll for quick checks during development, and run webhooks in production for real-time updates. They are not mutually exclusive.

Test in the sandbox

Use sandbox magic numbers to exercise every delivery outcome without sending real faxes:
NumberOutcome
+15005550001Always delivers
+15005550002Always busy
+15005550005Permanent failure
Send to +15005550001 with a sandbox key (fx_test_...) to confirm your polling loop or webhook handler processes a delivered status. Send to +15005550005 to confirm your integration handles failed. See Sandbox for the full magic number matrix.

What to do next

  • Webhooks - endpoint setup, delivery behavior, and signature overview.
  • Webhook signing - verify that payloads came from mintfax with HMAC-SHA256.
  • Events - full list of event types and payload schemas.
  • Sandbox - magic numbers and simulated failure scenarios.
  • Errors - error codes, HTTP statuses, and recommended actions.