Recipes

Collect files when a webhook arrives

Use with your agent

Give this prompt to your AI agent. The agent does the task for you.

Read https://thirds.ai/docs/integrations/webhook-delivery and help me build a signed webhook receiver and collect finished files without creating duplicate renders

Let your server collect a finished PDF or image as soon as thirds.ai sends its result. The receiver saves each verified event to a private inbox. A separate worker reads the job and downloads the file. Neither step starts a render.

Set up the receiver

You need a server you control and an HTTPS proxy in front of it. Follow webhook registration to register your public https://YOUR_RECEIVER.example/thirds-events URL. Save the returned secret as THIRDS_WEBHOOK_SECRET in the receiver's secret store. The receiver doesn't need your API key.

Build the receiver with the Node or Python verifier from the webhook guide. Your receiver does four things, in this order:

  1. It reads the raw body and the thirds-signature header.
  2. It checks the signature before it parses the JSON. It rejects an event that fails.
  3. It saves the event to a private inbox, keyed by the event id. A repeated ID adds no new work.
  4. It returns a small 2xx response after the save.

Let the process listen on 127.0.0.1. Set your HTTPS proxy to forward only POST requests for /thirds-events to that local port. Preserve the raw body and thirds-signature header. Keep the proxy's request size and time limits enabled. Don't log request bodies, signing secrets, or authorization headers.

Use durable storage for the inbox, and keep the receiver's clock in sync. The webhook guide owns the signature and delivery rules.

Start an approved output

Complete the API workflow recipe with your template and data. Register the webhook before you create the output. Pressing your app's create button or running its explicit render command authorizes that render. Loading a page or receiving an event must never create one.

The event identifies a job. It is not the file itself. Your worker uses the job ID to read the authoritative result from thirds.ai. It must not send your API key to a URL supplied by an unchecked event.

Collect the inbox

Set THIRDS_API_KEY in the worker's secret store. Use a key from the same account as the webhook destination and render. Run the worker from your existing job runner after events arrive.

For each saved event, the worker takes data.job.id and data.job.output. It builds the job URL itself from https://thirds.ai, so it never trusts a URL from the event. Read a PDF job like this, or use /v1/image/{id} when output is image:

GET /v1/pdf/{id}
curl --fail-with-body --silent --show-error \
  https://thirds.ai/v1/pdf/pdf_00000000000000000000000000000000 \
  -H 'Authorization: Bearer YOUR_API_KEY'

When status is succeeded, add https://thirds.ai before download.url and save the file. The download doesn't need your API key:

GET /v1/downloads/{token}
curl --fail --silent --show-error \
  'https://thirds.ai/v1/downloads/YOUR_SIGNED_DOWNLOAD_TOKEN' \
  --output report.pdf

Compare the file's byte count and SHA-256 with artifact.byte_size and artifact.sha256. Mark the event done only after the check passes. A failed or cancelled job has no file, so record that result and mark the event done.

Open a sample collected file before you connect your own delivery step. Keep the job ID, byte size, and SHA-256 with the source record, then use the storage recipe. Email and customer delivery remain steps in your own app.

Recover without another render

What happensWhat to do
Signature failsCheck the secret and clock. Ensure the proxy does not change the body.
Receiver cannot save an eventRestore its disk access and space. Let thirds.ai retry delivery.
The same event arrives twiceKeep the inbox and worker state. The repeat refers to the same job.
Download or worker stopsRun the worker again. It reads the same job for a fresh link.
A result event is missedRead the known job directly or replay delivery through the webhook API.
Job fails or its artifact expiresFollow the shared recovery guide before you authorize new work.

Webhook recovery explains retries, replay, disabled destinations, and secret rotation. Download recovery explains fresh links and file expiry. Repairing delivery does not need another billed render.

Ready to make your first file?

Start in the playground with a gallery template, or get an API key and send your first request from your own terminal.