Skip to main content
GET
/
api
/
v1
/
jobs
/
{jobId}
Get job status
curl --request GET \
  --url https://pdfgorilla.io/api/v1/jobs/{jobId} \
  --header 'x-api-key: <api-key>'
{
  "jobId": "<string>",
  "status": "<string>",
  "expiresAt": {},
  "downloadUrl": {},
  "error": {}
}
After async generation you receive a jobId. Call this endpoint to read status, downloadUrl, and error.

Job response body

{
  "jobId": "cma1b2c3d4e5f6g7h8i9j0k",
  "status": "completed",
  "expiresAt": "2026-04-13T10:00:00.000Z",
  "downloadUrl": "https://...",
  "error": null
}
jobId
string
Same ID returned from generate-async.
status
string
One of: queued, processing, completed, failed, canceled, expired.
expiresAt
string | null
Cleanup deadline for this job record and its stored output. New jobs typically get this timestamp at creation time.
downloadUrl
string | null
Short-lived signed URL when status is completed. Expires after a few minutes. Call this endpoint again for a fresh URL, or use Download job PDF.
error
object | null
On failure: { "message": "Human-readable reason" }. Otherwise null.

Status lifecycle

  1. queued / processing: still running.
  2. completed: use downloadUrl or Download job PDF.
  3. failed: see error.message.
  4. canceled: stopped (for example via Cancel job).
  5. expired: retention ended; create a new job.

Request

Path parameters

jobId
string
required
Returned from POST /api/v1/templates/{templateId}/generate-async.

Headers

x-api-key
string
required
Your API key or Authorization: Bearer.

Responses

HTTP 200

Current job JSON (see fields above).

Errors

StatusMeaning
401Missing or invalid API key
404Job not found or wrong account

Example

curl https://pdfgorilla.io/api/v1/jobs/JOB_ID \
  -H "x-api-key: YOUR_API_KEY"

Polling example

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");
}
Prefer webhooks for production: Webhooks.