curl --request GET \
--url https://pdfgorilla.io/api/v1/jobs/{jobId} \
--header 'x-api-key: <api-key>'{
"jobId": "<string>",
"status": "<string>",
"expiresAt": {},
"downloadUrl": {},
"error": {}
}Poll an async PDF job by ID for status, download URL, and errors.
curl --request GET \
--url https://pdfgorilla.io/api/v1/jobs/{jobId} \
--header 'x-api-key: <api-key>'{
"jobId": "<string>",
"status": "<string>",
"expiresAt": {},
"downloadUrl": {},
"error": {}
}jobId. Call this endpoint to read status, downloadUrl, and error.
{
"jobId": "cma1b2c3d4e5f6g7h8i9j0k",
"status": "completed",
"expiresAt": "2026-04-13T10:00:00.000Z",
"downloadUrl": "https://...",
"error": null
}
generate-async.queued, processing, completed, failed, canceled, expired.status is completed. Expires after a few minutes. Call this endpoint again for a fresh URL, or use Download job PDF.{ "message": "Human-readable reason" }. Otherwise null.queued / processing: still running.completed: use downloadUrl or Download job PDF.failed: see error.message.canceled: stopped (for example via Cancel job).expired: retention ended; create a new job.POST /api/v1/templates/{templateId}/generate-async.Authorization: Bearer.| Status | Meaning |
|---|---|
| 401 | Missing or invalid API key |
| 404 | Job not found or wrong account |
curl https://pdfgorilla.io/api/v1/jobs/JOB_ID \
-H "x-api-key: YOUR_API_KEY"
async function waitForPdf(jobId, apiKey) {
const deadline = Date.now() + 120_000;
while (Date.now() < deadline) {
await new Promise((r) => setTimeout(r, 2000));
const res = await fetch(`https://pdfgorilla.io/api/v1/jobs/${jobId}`, {
headers: { "x-api-key": apiKey },
});
const job = await res.json();
if (job.status === "completed") return job.downloadUrl;
if (job.status === "failed")
throw new Error(job.error?.message ?? "failed");
if (job.status === "canceled") throw new Error("canceled");
if (job.status === "expired") throw new Error("expired");
}
throw new Error("timeout");
}