Skip to main content

Jobs

Check job status, list your jobs, read per-file results, and get download links.

Authentication​

Which credential works depends on the route:

RouteAPI keyCognito JWT
GET /jobs/{job_id}✅✅
GET /jobs/{job_id}/files✅✅
GET /jobs/{job_id}/download✅✅
POST /jobs/{job_id}/cancel✅✅
GET /jobs❌✅
GET /jobs/{job_id}/webhooks/history❌✅

API keys are rejected at the gateway on the JWT-only routes. A job that belongs to another account returns 404 JOB_NOT_FOUND.


GET /jobs/{job_id}​

Get the status and details of one job.

curl https://api.podpdf.com/jobs/9f0a4b78-2c0c-4d14-9b8b-123456789abc \
-H "X-API-Key: your_api_key_here"

Response​

Common fields: job_id, status, job_type, mode, pages, created_at, completed_at, error_message.

{
"job_id": "9f0a4b78-2c0c-4d14-9b8b-123456789abc",
"status": "completed",
"job_type": "quick",
"mode": "html",
"pages": 3,
"truncated": false,
"created_at": "2026-09-12T10:30:00.000Z",
"completed_at": "2026-09-12T10:30:05.000Z",
"timeout_occurred": false,
"s3_url": "https://...pdf?X-Amz-Signature=...",
"s3_url_expires_at": "2026-09-12T11:30:05.000Z",
"error_message": null
}

s3_url is present only when the request used store: true.

Status values​

StatusMeaning
queuedAccepted, waiting to be processed (long and bulk jobs)
processingBeing rendered
completedFinished; for bulk jobs, every file converted
partial_failedBulk jobs only: some files converted, some failed or were skipped
failedNothing was produced; see error_message and error_code
timeoutQuick jobs only: the 30-second limit was reached
cancelledBulk jobs and mail merge campaigns: cancelled with POST /jobs/{job_id}/cancel. PDFs made before the cancel are in the output; emails sent before it stay sent

Job types​

quick (synchronous), long (asynchronous, one document), bulk (asynchronous, many documents), pdfop (PDF merge and split).

Merge and split jobs also return operation (merge or split), split_mode, input_files, input_pages, outputs_produced, and while a background job runs, output_count and processed_count.

Errors​

StatusCodeMeaning
401UNAUTHORIZEDMissing or invalid credentials
403ACCOUNT_NOT_FOUNDNo account for this user
404JOB_NOT_FOUNDUnknown job, or it belongs to another account

GET /jobs​

List your jobs, newest first. JWT only.

curl "https://api.podpdf.com/jobs?job_type=bulk&limit=20" \
-H "Authorization: Bearer <cognito_id_token>"

Query parameters​

ParameterTypeDefaultDescription
limitnumber50Between 1 and 100
next_tokenstring—Pagination token from a previous response
statusstring—draft, queued, processing, completed, partial_failed, failed, timeout, cancelled
job_typestring—quick, long, bulk
truncatedboolean—Kept for backward compatibility; new jobs are always false
monthstring—YYYY-MM, filters by creation month (UTC)

Response​

{
"jobs": [
{
"job_id": "3f5c2a7e-8b1d-4c9e-a2f4-6d7e8f9a0b1c",
"status": "completed",
"job_type": "bulk",
"bundle_type": "markdown",
"file_count": 12,
"success_count": 12,
"failure_count": 0,
"pages_total": 36,
"created_at": "2026-09-12T10:00:00.000Z",
"completed_at": "2026-09-12T10:01:40.000Z"
}
],
"next_token": "eyJqb2JfaWQiOiIzZjVjMmE3ZSJ9",
"count": 1
}

Pass next_token back as a query parameter to fetch the next page. It is null on the last page.


POST /jobs/{job_id}/cancel​

Cancel a bulk job or a mail merge campaign. Other job types return 409.

curl -X POST https://api.podpdf.com/jobs/9f0a7b1c-4d2e-4c1a-9f7e-2b3c4d5e6f70/cancel \
-H "X-API-Key: your_api_key_here"

What happens depends on how far the job has got:

Job statusResponseWhat you getWhat is charged
queued200, status: "cancelled"Nothing: no file was convertedNothing
processing202, status: "processing"The job stops before its next file. PDFs already made stay in its output ZIP; the other files are skipped with error_code: "CANCELLED"Only the PDFs already made
anything else409 JOB_NOT_CANCELLABLEThe job had already finishedAs usual
{
"job_id": "9f0a7b1c-4d2e-4c1a-9f7e-2b3c4d5e6f70",
"status": "processing",
"cancel_requested": true,
"message": "The job stops before its next file. PDFs already made are kept in the output and charged."
}

After a 202, keep polling GET /jobs/{job_id}: cancel_requested is true straight away, and status becomes cancelled once the current file finishes. If some PDFs were made, GET /jobs/{job_id}/download returns them. A bulk.job.cancelled webhook is sent in both cases. Cancelling twice is harmless.

A mail merge campaign stops within a few emails of a cancel. Emails already sent are charged; the rest are marked skipped with error_code: "CANCELLED", and a mailmerge.campaign.cancelled webhook follows. A draft cannot be cancelled: delete it with DELETE /mailmerge/campaigns/{id}.


GET /jobs/{job_id}/files​

Per-file results of a bulk or merge/split job. Other job types return 400 INVALID_PARAMETER.

For merge and split jobs, each row is one output file and also has page_range, size_bytes and warnings; download a single file with GET /jobs/{job_id}/files/{file_index}/download.

curl https://api.podpdf.com/jobs/3f5c2a7e-8b1d-4c9e-a2f4-6d7e8f9a0b1c/files \
-H "X-API-Key: your_api_key_here"
{
"job_id": "3f5c2a7e-8b1d-4c9e-a2f4-6d7e8f9a0b1c",
"status": "partial_failed",
"bundle_type": "html",
"count": 3,
"files": [
{
"index": 0,
"input": "reports/april.html",
"output": "reports/april.pdf",
"status": "success",
"pages": 3,
"error_code": null,
"error_message": null,
"blocked_requests": 0,
"missing_assets": 0,
"render_timeout": false
},
{
"index": 1,
"input": "reports/huge.html",
"output": null,
"status": "failed",
"pages": 0,
"error_code": "FILE_TOO_LARGE",
"error_message": "File exceeds the 10 MB limit",
"blocked_requests": 0,
"missing_assets": 0,
"render_timeout": false
},
{
"index": 2,
"input": "reports/zeta.html",
"output": null,
"status": "skipped",
"pages": 0,
"error_code": "BULK_PAGE_BUDGET_EXCEEDED",
"error_message": "Skipped: the batch page budget of 200 pages was reached",
"blocked_requests": 0,
"missing_assets": 0,
"render_timeout": false
}
]
}

files is empty until the job finishes.

FieldMeaning
statussuccess, failed, or skipped
blocked_requestsRequests the page made to local files or private addresses, which were blocked
missing_assetsReferences to files that were not in the bundle
render_timeoutThe page never went idle within 20 seconds and was printed as it was

Only success files are billed. The same list is included as manifest.json in the output ZIP.


GET /jobs/{job_id}/files/{file_index}/download​

A fresh download link for one output file of a merge or split job. file_index is the index from /files.

curl https://api.podpdf.com/jobs/5b2d8f40-1e7c-4a8b-9c3d-6e0f1a2b3c4d/files/2/download \
-H "X-API-Key: your_api_key_here"
{
"job_id": "5b2d8f40-1e7c-4a8b-9c3d-6e0f1a2b3c4d",
"file_index": 2,
"name": "payslip-003.pdf",
"download_url": "https://...payslip-003.pdf?X-Amz-Signature=...",
"expires_at": "2026-09-13T11:10:00.000Z",
"expires_in_seconds": 3600,
"content_type": "application/pdf",
"size_bytes": 48210
}
StatusCodeMeaning
400INVALID_PARAMETERThe job is not a merge/split job
404JOB_NOT_FOUNDUnknown job, or it belongs to another account
404FILE_NOT_FOUNDNo successful output at that index
409JOB_NOT_READYThe job hasn't finished
410OUTPUT_EXPIREDThe file was deleted after 7 days

GET /jobs/{job_id}/download​

Get a fresh download link for any job with stored output: bulk jobs, long jobs, merge and split jobs (the merged PDF, or a ZIP of every split file), and quick jobs submitted with store: true.

curl https://api.podpdf.com/jobs/3f5c2a7e-8b1d-4c9e-a2f4-6d7e8f9a0b1c/download \
-H "X-API-Key: your_api_key_here"
{
"job_id": "3f5c2a7e-8b1d-4c9e-a2f4-6d7e8f9a0b1c",
"download_url": "https://...-output.zip?X-Amz-Signature=...",
"expires_at": "2026-09-12T11:10:00.000Z",
"expires_in_seconds": 3600,
"content_type": "application/zip",
"size_bytes": 1843200
}

Links last one hour. Call this endpoint again for a new one — files are kept for 30 days.

Errors​

StatusCodeMeaning
404JOB_NOT_FOUNDUnknown job, or it belongs to another account
404OUTPUT_NOT_AVAILABLEThe job has no stored output (a quick job without store: true)
409JOB_NOT_READYThe job has not reached completed or partial_failed yet
410OUTPUT_EXPIREDThe file was deleted after 30 days

GET /jobs/{job_id}/webhooks/history​

Delivery history for the webhooks triggered by one job. JWT only. See Webhooks for the record shape and filters.


Next Steps​