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
| Status | Meaning | Terminal? |
|---|
queued | Fax accepted and waiting for processing | No |
submitted | Sent to the carrier for transmission | No |
in_progress | Carrier is actively transmitting pages | No |
delivered | Carrier confirmed receipt. Credits captured. | Yes |
failed | All 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:
| Event | Fires when |
|---|
fax.queued | Fax accepted and placed in the processing queue |
fax.sending | Fax picked up from queue and submitted to the carrier |
fax.delivered | Carrier confirmed delivery (terminal) |
fax.failed | All retries exhausted, fax permanently failed (terminal) |
fax.retry_scheduled | Attempt 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:
- The carrier reports a failure (busy line, no answer, etc.).
- mintfax decrements
retries_remaining on the fax record.
- If retries remain, mintfax fires a
fax.retry_scheduled event and re-queues the fax with a backoff delay.
- 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
| Consideration | Polling | Webhooks |
|---|
| Setup complexity | None - just call GET /fax/{id} | Requires a public HTTPS endpoint |
| Latency | Depends on poll interval | Near real-time |
| Scale | Fine for low volume | Better at high volume |
| Infrastructure | No server required | Needs a reachable server |
| Best for | Scripts, debugging, batch checks | Production 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:
| Number | Outcome |
|---|
+15005550001 | Always delivers |
+15005550002 | Always busy |
+15005550005 | Permanent 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.