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.

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.
MethodIdempotent by defaultIdempotency key supported
GETYesNo (not needed)
PUTYesNo (not needed)
DELETEYesNo (not needed)
POSTNoYes

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.

Step 3: Check the response header

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:
StatusMeaningAction
400Bad requestFix the request body. See errors.
401UnauthorizedCheck your API key.
402Insufficient balanceTop up your balance before retrying.
422Validation failedFix the invalid fields. See errors.
429Rate limitedWait 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

PropertyValue
Max length255 characters
Recommended formatUUID v4
ScopeAccount ID + key (no collision across accounts)
TTL24 hours
Body matchingNo (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