Download a job's PDF
https://api.granska.cloud/v1/jobs/:jobId/result.pdfDownloads a completed job's report or generated document as the same PDF the app exports.
What you get
A completed analysis job answers with the analysis report; a completed action job answers with the generated action document. It is the same document a user gets from the download button in the app: the same layout, the same fonts and the same wording, built from the same result and from your workspace's configuration — the review profile names that head each angle of a review package, and the section layout of the action. Only the file metadata, such as the creation time, differs between two downloads.
The response is Content-Type: application/pdf with a Content-Disposition filename made only of
letters, digits, -, _ and ., so it is safe to write to disk as it stands. Save the body as
binary; it is not JSON.
This is our document about the file you sent, not that file. The PDF you uploaded is never returned.
What it does not do
It renders, it does not store. The PDF is built from the job's result when you ask for it and
streamed back. It is not written to a database, a bucket or a cache, and the response carries
Cache-Control: no-store.
It does not keep the job alive. Downloading reads the job exactly as
reading a job does and changes nothing on it, so it does not reset the retention
clock. The retention sweep deletes the job and its stored result once it has not changed in the last
fifteen minutes, whether or not you have downloaded, and from then on this route answers 404 like
every other route that names the job — there is nothing left to render from. If you need the document
later, save the file.
It costs no run. Rendering is not an analysis, and this route draws nothing from your quota. You can download the same job as often as you like until it is swept.
curl https://api.granska.cloud/v1/jobs/job_7d41c9/result.pdf \
-H "Authorization: Bearer $TOKEN" \
--fail --output report.pdfHTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="analysis-job_7d41c9.pdf"
Cache-Control: no-store
%PDF-1.3 … (the report, as binary PDF)Request
| Parameter | Description |
|---|---|
jobIdstring·path·required | The id POST /v1/analyze or POST /v1/action returned, once GET /v1/jobs/:jobId reports it COMPLETED. |
Errors
Every refusal is the ordinary JSON error envelope, never a partial PDF — check the status before
saving the body. With curl --fail, as in the example, a refusal leaves no file behind.
A job still QUEUED or IN_PROGRESS, and a job that FAILED, has no document and answers
409 CONFLICT. Poll the job until it is COMPLETED. A job belonging to another
tenant answers 403, and so does an action job whose action your workspace is no longer licensed
for, because the action's layout is what the document is built from. A job that never existed, or
has already been swept, answers 404.
| Error | When |
|---|---|
401UNAUTHORIZED | The Authorization header is missing, is not a readable bearer token, or names no tenant. |
401TOKEN_EXPIRED | The access token was issued by this gateway and has since expired. Not probed: it needs a token older than its own lifetime. |
403FORBIDDEN | The job exists but belongs to another tenant, or it is an action job whose action is no longer licensed for this tenant, so its layout cannot be resolved. Not probed: it needs a job created by a second tenant. |
404NOT_FOUND | No job with that id, or the retention sweep has already removed it. Downloading the PDF does not delete the job and does not keep it alive; `sweepStaleData` removes it once it has been untouched for 15 minutes, and nothing is kept to render from after that. |
409CONFLICT | The job has no document to render: it is still QUEUED or IN_PROGRESS, or it FAILED. Poll GET /v1/jobs/:jobId until COMPLETED. Not probed: it needs a job that is mid-flight or failed. |
500INTERNAL_ERROR | An unexpected server-side failure. Not probable from outside — reaching it means something is wrong. |