Skip to main content

Async PDF generation: retries and monitoring

Async PDF generation is designed for long-running or high-volume PDF jobs. Instead of waiting for the PDF to be generated in the original HTTP request, CraftMyPDF accepts the job, places it in a queue, and returns a transaction_ref immediately.

When the PDF is ready, CraftMyPDF sends the result to your webhook_url. You can also use transaction records to review completed jobs and identify jobs that need follow-up. For the full API schema, request parameters, and response examples, see the CraftMyPDF API Reference.

What retry strategy is used for transient failures?

CraftMyPDF uses automatic retries with exponential backoff and jitter for transient failures. This helps handle temporary issues without immediately retrying every request at the same time.

For PDF generation, retryable failures are attempted again after a short delay. If another retry is needed, the wait time increases up to a capped maximum. This strategy is intended for temporary generation failures, short-lived service interruptions, and network-related issues.

For webhook delivery, CraftMyPDF retries temporary callback failures such as:

  • 429 throttling or rate-limit responses
  • 5xx server errors from your webhook endpoint
  • Network interruptions or connection failures

If your webhook endpoint returns 429 or 503 with a Retry-After header, CraftMyPDF uses that signal when scheduling the next delivery attempt.

For requests that receive a 429 response from the CraftMyPDF API, your application should pause before sending more requests. The public API rate limits are documented in the Rate limiting section of the API reference.

Timeout and payload limits vary by regional endpoint. If a request is close to the regional timeout or payload limit, use async generation and review the limits in Regional API endpoints.

For temporary platform availability issues, check the CraftMyPDF status page and subscribe to updates if you process large batches or time-sensitive jobs.

Are automatic retries performed?

Yes. PDF generation is attempted up to 3 times in total. After a failed attempt, the first retry starts after a short delay, usually around a quarter of a second. If another retry is needed, the delay grows using exponential backoff with jitter, so repeated failures are spaced out instead of retried immediately. Each retry delay is capped at about 4 seconds, and if there is not enough processing time left to make another useful attempt, CraftMyPDF stops retrying and records the final result.

Webhook delivery is retried up to 3 times before CraftMyPDF gives up on the callback. Webhook retry delays also use exponential backoff with jitter. The first retry is usually delayed by about 1 second, later retries may wait longer, and the delay is capped at about 8 seconds. A Retry-After response can extend the wait, up to a short safety cap.

Because jitter is used, retry intervals are intentionally not exact. Your integration should not depend on callbacks arriving at a precise second.

How are failed requests tracked and surfaced?

When you call /v1/create-async, the response includes:

  • status
  • transaction_ref
  • is_async: true

Save the transaction_ref in your system. It is the main identifier for matching the original request to the final webhook callback and transaction history.

When generation finishes, the webhook callback includes query parameters such as:

  • file: the generated PDF URL, when generation succeeds
  • transaction_ref: the transaction reference for the job
  • status: the final status of the request
  • message: a status or error message
  • details: additional details when available

You can also use /v1/list-transactions to review transaction history. Transaction records include fields such as transaction_ref, transaction_type, exec_tm, created_at, resp_file_size, and resp_status.

For async jobs, important resp_status values include:

  • webhook_success: the file was generated and the webhook was delivered successfully
  • webhook_failed: the file was generated, but webhook delivery failed
  • error: an error occurred while recording or processing the transaction
  • unknown: the final status could not be determined

CraftMyPDF also provides request logging for API requests. By default, request logs are retained for 2 weeks. See Request logging for more details.

Can transient and permanent failures be distinguished?

During retry processing, failures should be treated as transient until CraftMyPDF finishes its retry attempts.

For end-user reconciliation, the practical way to identify a permanent webhook delivery failure is the transaction status webhook_failed. This means the PDF may have been generated, but CraftMyPDF could not deliver the callback to your webhook endpoint after retrying.

If a transaction is not marked as webhook_failed, do not classify it as a permanent webhook failure based only on an individual retry response. Instead, reconcile it using the webhook callback, request logs, and /v1/list-transactions.

What monitoring and reconciliation options are available?

For large-volume async processing, we recommend tracking each job on your side as well as using CraftMyPDF transaction records.

A typical reconciliation workflow is:

  1. Submit an async generation request to /v1/create-async.
  2. Store the returned transaction_ref with your own customer ID, order ID, invoice ID, or batch ID.
  3. Make your webhook handler idempotent, so repeated callbacks for the same transaction_ref do not create duplicate records or send duplicate emails.
  4. Log the full webhook callback, including transaction_ref, status, message, details, and file.
  5. Mark the job as complete only after receiving a successful callback or confirming the transaction status.
  6. Periodically compare your submitted transaction_ref values against webhook receipts and /v1/list-transactions.
  7. Investigate any job with no callback, webhook_failed, error, or unknown.

Example async flow

The following example shows the information you should keep for each async request.

1. Submit the async request

curl -X POST "https://api.craftmypdf.com/v1/create-async" \
--header "Content-Type: application/json" \
--header "X-API-KEY: YOUR_API_KEY" \
--data '{
"template_id": "05f77b2b18ad809a",
"webhook_url": "https://example.com/webhooks/craftmypdf",
"expiration": 60,
"data": {
"invoice_number": "INV-1001",
"customer_name": "Example Customer",
"total_amount": 199.00
}
}'

The response includes a transaction reference:

{
"status": "success",
"transaction_ref": "a0430897-2c94-40e1-a09b-57403d811ceb",
"is_async": true
}

Store this value in your database:

internal_id: invoice-1001
transaction_ref: a0430897-2c94-40e1-a09b-57403d811ceb
status: submitted

2. Receive the webhook callback

When generation is finished, CraftMyPDF calls your webhook URL with the result:

https://example.com/webhooks/craftmypdf?file=https%3A%2F%2F...%2Foutput.pdf&transaction_ref=a0430897-2c94-40e1-a09b-57403d811ceb&status=success&message=completed

Your webhook handler should find the matching record by transaction_ref, store the file URL, and mark the job as complete.

3. Reconcile missing or failed callbacks

If a job remains in submitted or processing longer than expected, check /v1/list-transactions and look for its transaction_ref.

  • If resp_status is webhook_success, your webhook may have received the callback but failed to record it.
  • If resp_status is webhook_failed, the PDF may have been generated but your webhook endpoint did not accept the callback.
  • If resp_status is error or unknown, review your request logs and contact support with the transaction_ref.