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.
Outcome
You will be able to attach idempotency keys to fax requests, distinguish which failures mintfax retries from which ones your code retries, and build backoff logic that does not stampede the API when something goes wrong.
Prerequisites
- A mintfax account with a sandbox API key (
fx_test_...)
- curl or the
mintfax Node package
What is idempotent and what is not
GET, PUT, and DELETE endpoints are idempotent by design. Repeating them produces the same result.
POST endpoints create resources. Without an idempotency key, each POST creates a new fax. With one, mintfax treats the second request as a replay and returns the stored response.
| Method | Idempotent by default | Idempotency key supported |
|---|
GET | Yes | No (not needed) |
PUT | Yes | No (not needed) |
DELETE | Yes | No (not needed) |
POST | No | Yes |
Step 1: Generate an idempotency key
Generate a UUID (or any unique string up to 255 characters) on the client before you send the request. The key should stay the same across retries of the same operation.
One approach: hash the recipient number, a document fingerprint, and a reference ID from your system. That way, retrying the same logical fax always produces the same key.
curl -X POST https://api.mintfax.com/v1/fax \
-H "Authorization: Bearer fx_test_abc123def456" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-F "to=+12015550100" \
-F "file=@document.pdf"
Verify: Send the same request twice with the same key. The second response returns the same fax ID and queued status as the first, with no duplicate fax created.
Step 2: Understand key scope and TTL
Each idempotency record is keyed by your account ID plus the key you provide.
- Two different accounts can use the same key string without collision.
- Sandbox and live environments are separate scopes, so keys do not cross over.
- Keys expire after 24 hours. After that, the same string can be reused.
mintfax does not compare request bodies. If you reuse a key that has not expired, you get back the original response regardless of what the new body contains. Use one key per logical operation.
Every POST response includes an X-Idempotency-Key header. If you sent a key, the header echoes it back. If you omitted it, the header reads not provided; recommended.
Idempotency keys are optional. For production integrations, treat them as required.
The retry contract
Two layers of retries exist in a mintfax integration. Knowing which layer owns what keeps your code simple.
What mintfax retries for you
Once mintfax accepts a fax (HTTP 201), it owns delivery to the receiving machine. Busy signals, temporary line errors, negotiation failures - mintfax retries these automatically. The retries field controls how many attempts it makes (default 3, configurable 0-10 per fax or via account fax settings). You do not build retry logic for carrier failures.
Track delivery through webhook events (fax.delivered, fax.failed) or by polling GET /fax/{id}.
What you retry yourself
Your code retries when the HTTP request fails before mintfax can accept the fax:
- Network errors (timeouts, connection resets, DNS failures)
- HTTP 500 or 503 responses
Do not retry these:
| Status | Meaning | Action |
|---|
| 400 | Bad request | Fix the request body. See errors. |
| 401 | Unauthorized | Check your API key. |
| 402 | Insufficient balance | Top up your balance before retrying. |
| 422 | Validation failed | Fix the invalid fields. See errors. |
| 429 | Rate limited | Wait for the Retry-After header. See rate limits. |
Step 4: Build retry logic with backoff and jitter
For retryable failures, use exponential backoff with jitter. Jitter adds a random offset so that many clients failing at the same time do not all retry on the same tick.
delay = min(base * 2^attempt + random_jitter, max_delay)
Use a base delay of 1 second, a max delay of 30 seconds, jitter between 0 and 1 second, and cap at 5 attempts.
#!/bin/bash
IDEMPOTENCY_KEY="550e8400-e29b-41d4-a716-446655440000"
MAX_ATTEMPTS=5
BASE_DELAY=1
for attempt in $(seq 0 $((MAX_ATTEMPTS - 1))); do
response=$(curl -s -w "\n%{http_code}" -X POST https://api.mintfax.com/v1/fax \
-H "Authorization: Bearer fx_test_abc123def456" \
-H "Idempotency-Key: $IDEMPOTENCY_KEY" \
-F "to=+12015550100" \
-F "file=@document.pdf")
http_code=$(echo "$response" | tail -1)
if [ "$http_code" -eq 201 ] || [ "$http_code" -eq 200 ]; then
echo "Success"
break
elif [ "$http_code" -eq 500 ] || [ "$http_code" -eq 503 ]; then
delay=$(echo "$BASE_DELAY * (2 ^ $attempt) + $RANDOM / 32768" | bc -l)
delay=$(echo "if ($delay > 30) 30 else $delay" | bc -l)
echo "Attempt $((attempt + 1)) failed ($http_code). Retrying in ${delay}s..."
sleep "$delay"
else
echo "Non-retryable error: $http_code"
break
fi
done
Verify: Use the sandbox magic number +15005550004 (transient failure) to confirm your retry logic recovers after the first attempt fails. See the sandbox page for the full magic number list.
Detecting duplicates on the receiving side
If your downstream system processes the same webhook event twice, use the fax ID (id field in the response and the webhook payload) as your deduplication key. Store processed fax IDs and skip repeats.
Key requirements
| Property | Value |
|---|
| Max length | 255 characters |
| Recommended format | UUID v4 |
| Scope | Account ID + key (no collision across accounts) |
| TTL | 24 hours |
| Body matching | No (keyed only by account ID + key) |
Verify
Send a fax with an idempotency key using your sandbox API key. Repeat the request. The second response should return the same fax ID with no duplicate created. Then run your retry logic against +15005550004 to confirm backoff works.
What to do next
- Error catalog - see which errors are retryable and which require a fix
- Rate limits - understand rate-limit headers and how they interact with retries
- Sandbox - test retry flows with magic fax numbers