Connect your app

Retry requests and download files

Use with your agent

Read https://thirds.ai/docs/recovery and add safe retries, job polling, and verified downloads to my thirds.ai integration

A request can reach thirds.ai even when your app loses the response. Keep the job ID as soon as you receive it, then check that job before you create another output. This guide shows how to retry a request and collect its file without paying for a duplicate.

Retry a request without a second job

Give each intended output one Idempotency-Key. Save the key with the request and reuse it after a connection timeout. The same account, operation, key, and input return the same job. Even if retries arrive together, they create at most one job and one credit reservation.

Keys last 24 hours. A reused key can return Idempotency-Replayed: true during that period. If you change the input, the same key returns 409 idempotency_conflict.

For saved templates, send an exact version number in requests you may retry. If you leave it out, publishing a new template version can change which version the request selects.

The wait field changes only how long the response waits. It does not change the output or its price. After a key expires, it no longer protects you from a second job. Keep the job ID beside your own record, such as the invoice that needs that PDF.

Poll the job until it ends

POST /v1/pdf and POST /v1/image return a job object. A 200 response means the job has finished, which can include failure or cancellation. Read status to find out which. A 202 response means you need to check the job again. Send wait: false to skip the initial wait.

Check GET /v1/pdf/{id} or GET /v1/image/{id} with an API key from the same account. Use Location and Retry-After when the response includes them. Set a time deadline for polling in your app. If the deadline ends first, save the job ID and check it later.

StatusNext step
queuedWait before you check again.
runningKeep polling with a delay while the render runs.
succeededRead download and save the file.
failedStop polling and inspect error.category and error.code.
cancelledStop polling. This job produces no new output.

A job in one of the last three states never restarts. thirds.ai retries some internal failures before the job reaches its final state. Keep checking the same job while it runs. You can use webhooks to receive the result on your server instead of polling.

Handle errors by code

Request errors include an error object with a stable code and request_id. Failed jobs include an error with category and code. Use these fields to decide what your app does next. The message text can change.

ErrorWhat to do
400 or 422 validation errorCorrect the named request fields or template data.
401 authentication errorCheck the API key and Bearer header.
403 account_suspendedContact support and stop submitting work.
409 idempotency_conflictFind the original request, or use a new key if you want a new output.
402 credit or spend-cap errorFollow billing recovery.
429 rate_limited, account_concurrency_limited, or key_concurrency_limitedWait for Retry-After, then retry with the same key. Send fewer requests at once.
429 abuse_limitedStop repeated failures. Fix their cause and follow the retry delay.
503 overloadedWait for Retry-After, then retry the same request with the same key.
Job category invalid_input or unsafe_assetFix the HTML, script, or asset before you create another render.
Job category resource_limit or timeoutReduce the work or fix JavaScript readiness. The same unchanged request can fail again.
Job category renderer_failure or internal_failureInternal recovery has ended. Use a new job with a limit on retries, or contact support.

The OpenAPI contract lists response fields. If you contact support, include the job ID, request ID, and error code. Keep API keys, signed links, and private content out of support messages and logs.

Download and keep the file

Read a successful job to get a fresh download.url while its file remains available. This signed link lasts 15 minutes. Resolve the path against https://thirds.ai before you download it. Anyone with the link can collect the file without an API key, so keep it private.

Save the file in your own storage before artifact.expires_at. Account outputs stay available for 30 days. Anonymous playground outputs stay for one hour. The two expiry fields tell you different things. download.expires_at is the link deadline, and artifact.expires_at is the file deadline.

An expired valid link returns 403. Read the job again for a fresh link. A missing, deleted, or expired file returns 404. A new link cannot restore that file. If download is null, check status and artifact.removed_reason.

Before you mark delivery complete, compare the file's byte count and SHA-256 with artifact.byte_size and artifact.sha256. If a transfer stops early, download the file again. You do not need another render.

Delete an output

Call DELETE /v1/pdf/{id} or DELETE /v1/image/{id} to remove a file before its expiry date. You can repeat the delete request safely. A successful job stays in history. A failed or cancelled job leaves history, but you can still read it by ID. Deletion does not change credits or retry keys. Queued and running jobs return 409.

Deletion stops new downloads. A download that has already opened the file can finish. The credit charge for a successful output stays in place. thirds.ai removes render input after the job ends. See the privacy policy for storage and backup terms.

Stay within the limits

Every plan has the same render limits. Higher plans give you more credits and a different place in the queue.

LimitMaximum
HTML input5 MiB
Template data1 MiB of canonical JSON
One fetched asset10 MiB
All fetched assets20 MiB across at most 128 assets
PDF output100 pages and 25 MiB
Image output32,000,000 pixels and 25 MiB
Worker render time30 seconds
Live jobs per account16
Live jobs per API key8
API-key request rate5 per second, with an idle burst of 21

Memory, CPU, browser processes, and temporary storage also have safety limits. You pay no credits for a limit failure, but repeated failures count toward abuse controls. Reduce source size, asset count, or document length before you retry.

Free accounts get a monthly credit grant. Anonymous playground use has its own limit of 200 renders per browser each month. There is no lifetime render quota. See credits and billing for credit grants, expiry dates, and spending limits.