Build a webhook endpoint to collect PDFs and images

A webhook endpoint is a URL on your own server that thirds.ai calls when a PDF or image finishes, so your app gets each file without checking again and again. With thirds.ai, you save a design once, such as an invoice or a report. Then you send new details and get a finished file with your logo, colours, and fonts. Your endpoint checks each signed event and saves it, and a separate worker downloads the file. Neither step starts a new render, so you don't pay twice for one file. Each event gets up to eight delivery attempts.

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

This recipe needs code on your server. A verified free account gets 50 credits each month to try it, as pricing shows. To make the design itself without code, follow how to make a template you can reuse. The webhook guide owns the signature and delivery rules.

Webhook endpoint vs API endpoint

A webhook endpoint is a URL on your server that thirds.ai calls, and an API endpoint is a URL on thirds.ai that your code calls. You use both to collect a file. Your webhook endpoint hears that a PDF or image job finished. Your worker then calls the thirds.ai API endpoints to read that job and download its file. The event names the job and carries no file. If an event goes missing, your worker can still read the job directly.

How to create a webhook endpoint for thirds.ai events

Creating a webhook endpoint for thirds.ai gives your server a safe place to save each signed event before any work starts. It takes one registration request and four steps in your endpoint code. First you need a server you control, an HTTPS proxy in front of it, and a thirds.ai API key to register the URL. The URL must be public HTTPS on port 443, so localhost and private networks can't receive events.

Follow webhook registration to register your public https://YOUR_RECEIVER.example/thirds-events URL. The webhook endpoints reference lists each request to register, test, and replay. Save the returned secret as THIRDS_WEBHOOK_SECRET in the endpoint's secret store. The endpoint itself doesn't need your API key.

Build the endpoint with the Node or Python verifier from the webhook guide. Your endpoint 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 endpoint's clock in sync. To test your verifier on your own machine first, run the local checks in How do I verify webhook signatures in Node.js and Python?. Once a saved event names a succeeded job, your worker reads its file through file downloads.

Make the PDF or image that sends the event

You make the PDF or image that sends the event through the thirds.ai API, with the API workflow recipe and your own template and data. Register the webhook before you create the output, so the finished job has an endpoint to send its event to. A click on your app's create button, or its explicit render command, authorizes that render. Loading a page or receiving an event must never create one.

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

Download files from saved webhook events

A worker downloads each finished PDF or image from your saved webhook events in three steps: it reads the job, downloads the file, and checks the file's bytes. First 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.

Test the webhook endpoint before real files

You can test your thirds.ai webhook endpoint from the studio before you make a real PDF or image, and a test uses no credits. Open Webhooks, choose Deliveries and test for your destination, and click Send test event. Your endpoint gets one signed sample render.succeeded event. You can send one test per destination per minute.

The sample event names the job ID pdf_00000000000000000000000000000000. That ID has no render or download behind it. Let your endpoint verify and save the test like any event. Then have your worker record it and mark it done without reading the job. The delivery log shows the response code your endpoint sent. The webhook guide explains the log.

Fix common webhook endpoint problems

You can fix most thirds.ai webhook endpoint problems without another billed render, because the finished job stays readable and failed events can be replayed. Your endpoint has ten seconds to answer each delivery, so it saves the event and replies before any slow work. Find what happened in this table and follow its fix.

What happensWhat to do
Signature failsCheck the secret and clock. Make sure the proxy keeps the body as is.
Endpoint 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.

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.