PDF to Images API
Convert each page of a PDF document to an image (PNG or JPEG), packaged as a downloadable ZIP file. Conversion runs asynchronously: submit the PDF here, poll the status API, then download the result with the retrieve API.
Pages are rendered at 150 DPI. This API powers Unstract's image output mode, where page images are answered directly by vision-capable LLMs, and can also be used standalone.
| Endpoint | /pdf-to-images |
| URL | https://llmwhisperer-api.us-central.unstract.com/api/v2/pdf-to-images |
| Method | POST |
| Headers | unstract-key: <YOUR API KEY> |
| Body | application/octet-stream |
Parameters
| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
| format | string | png | No | Output image format. Either png or jpeg. Any other value is rejected with 400. |
| tag | string | default | No | Auditing feature. Set a value which will be associated with the invocation of the API. This can be used for cross referencing in usage reports. |
| file_name | string | sample.pdf | No | Auditing feature. The document name associated with this invocation in usage reports. |
| pages_to_extract | string | (all pages) | No | Pages to convert, in the same syntax as the whisper API but validated strictly: single pages and ranges separated by commas, e.g. 1-5,7,21-, with no empty items (1-5, or 1,,3), no page 0, no reversed ranges, ASCII digits only and at most 999 selected pages. -3 means pages 1 to 3 and 21- means page 21 to the end. Only the selected pages are converted and billed, in ascending order and without duplicates, and they are numbered page_001, page_002, … in the ZIP regardless of their page numbers in the document. Pages past the end of the document are ignored, so 1-10 also works on a 5-page document. See page selection errors. |
| max_total_image_bytes | integer | (no limit) | No | Upper limit, in bytes, on the total size of the page images: the sum of the raw PNG/JPEG bytes, before ZIP compression and before base64 encoding. A conversion whose images would exceed it fails with error_code: "size_limit_exceeded" and is not charged. Set it to the request-size limit of the LLM that will read the images, so a document too large for that LLM fails here instead of after conversion. Must be a positive integer in plain digits. See size limit. |
Example Curl Request
curl -X POST --location 'https://llmwhisperer-api.us-central.unstract.com/api/v2/pdf-to-images?format=png&pages_to_extract=1-5,7&max_total_image_bytes=20000000' \
-H 'Content-Type: application/octet-stream' \
-H 'unstract-key: <Your API Key>' \
--data-binary '@your-document.pdf'
Response
| HTTP Status | Content-Type | Description |
|---|---|---|
| 202 | application/json | The conversion job was accepted. Use the returned whisper_hash to poll status and retrieve the result. |
| 400 | application/json | No file provided, an invalid format value, a malformed pages_to_extract value (including page 0 or a reversed range), or a max_total_image_bytes value that is not a positive integer. |
| 415 | application/json | The uploaded file is not a PDF. This API accepts PDF input only. |
| 503 | application/json | The feature is unavailable because object storage is not configured on the deployment (see availability). |
Example 202 Response
{
"message": "PDF to Images Job Accepted",
"status": "processing",
"whisper_hash": "xxxxxxxx|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"format": "png",
"pages_to_extract": "1-5,7",
"max_total_image_bytes": 20000000
}
pages_to_extract and max_total_image_bytes are echoed only when they were sent, so a client can tell the service applied them.
Example 415 Response
{
"message": "PDF-to-images only supports PDF files. Received: 'docx'"
}
Limits and billing
- Maximum 999 pages per conversion. The limit applies to the pages converted: the whole document, or the pages selected with
pages_to_extract. A larger conversion fails with an error asking you to split the document or select fewer pages (the page files use three-digit sequential naming,page_001…page_999). - Billing is per converted page. With
pages_to_extract, only the selected pages are converted and billed. The charge is committed when the conversion completes. - A conversion that exceeds
max_total_image_bytesis never charged, see size limit. - Free tier: the conversion is all-or-nothing. If the number of pages to convert exceeds your remaining daily quota, the job fails without converting (and without charging) any pages.
Page selection errors
A pages_to_extract value that is wrong for any document is rejected with 400 when the job is submitted, so no job is created and no whisper_hash is returned:
- a value that is not a list of pages and ranges, for example
abc,1--2or1,,2; - a page number of
0, as in0or0-5; - a reversed range, as in
5-3.
A value that is valid but selects no page of this document, for example 10-20 on a 5-page document, can only be checked once the document's page count is known. The job is accepted and then fails before anything is converted or charged. The failed job's status is error, its message starts with error_in_conversion: invalid_page_range: and ends with nothing was charged, and its metadata carries error_code: "invalid_page_range", the pages_to_extract value and the document's total_page_count.
Size limit
With max_total_image_bytes, the service adds up the size of each page image as it is rendered. As soon as the total goes above the limit, it stops rendering and fails the job. A total exactly equal to the limit is allowed. The job's status is error, its message starts with error_in_conversion: size_limit_exceeded: and ends with nothing was charged, and its metadata carries:
| Field | Description |
|---|---|
error_code | size_limit_exceeded |
max_total_image_bytes | The limit that was sent. |
rendered_bytes | Image bytes rendered before the job stopped, including the page that went over the limit. The full conversion would be at least this large. |
pages_rendered | Pages rendered before the job stopped, including the page that went over the limit. |
page_count | Pages the conversion would have rendered: the whole document, or the pages selected with pages_to_extract. |
format | The requested image format. |
from_memory | true when the job failed without rendering because the same document was already rejected (see below). |
rejections_today | When known, how many size-limit rejections your account has had today. For information only; it does not affect billing or later requests. |
The service remembers a rejected document for a day. If you submit the same file again with the same format and pages_to_extract, and a max_total_image_bytes that is the same or smaller, the job fails at once without rendering, with from_memory: true. rendered_bytes and pages_rendered then describe the earlier conversion. To convert the document, select fewer pages, use jpeg (usually smaller than png), or send a larger limit.
Availability
The result artifacts are held in a dedicated object store. On LLMWhisperer cloud this is always configured. On-prem deployments must configure IMAGE_OUTPUT_STORAGE_CONF and IMAGE_OUTPUT_BUCKET; without them the endpoint returns 503.