Automate document conversion to PDF and image previews in n8n with Uploadcare
In this guide, you’ll build an n8n workflow that converts a DOCX file to PDF (or a PDF page to a PNG preview) with Uploadcare, then emails the finished link. By the end, you’ll have a hands-off pipeline you can point at any output format you need.
The Uploadcare Conversion API is an endpoint that turns an uploaded document into another format. This post wires that pattern into n8n with the Webhook, HTTP Request, Wait, and If nodes. It builds on the main n8n + Uploadcare integration guide, which covers account setup, binary data, and multipart uploads, so here you can stay focused on conversion.
If you want a fully ready-to-import workflow.json version of this tutorial, you can find it in the document-conversion folder of the repo.
Diagram of the n8n workflow for document conversion with UploadcarePrerequisites
To follow along with this tutorial, you’ll need the following:
- A free Uploadcare account with your public and secret keys from API keys.
- A running n8n instance, Cloud or self-hosted.
- A Gmail account connected to n8n for the optional email-delivery step.
- Familiarity with the main n8n + Uploadcare integration guide.
How the workflow works together
- A Webhook node receives a document in a binary field named
file. - An HTTP Request node uploads the file to the Uploadcare Upload API, which returns a UUID.
- An HTTP Request node starts an async conversion with
POST /convert/document/, which returns a token. - A Wait node pauses, then an HTTP Request node checks the conversion status by token.
- An IF node loops back through the Wait node until the job reports
finished. - A Set node builds the CDN URL of the converted file, then a Gmail node delivers it.
Step 1: Receive and upload the document
The Webhook node is your entry point, and an HTTP Request node uploads whatever document it receives to Uploadcare.
In your own project, you can trigger the workflow with a form, a Slack file upload,
or any other source that can send a POST request with a file. For this tutorial, you’ll test with Postman.
Add the Webhook node
- Click the + button to add a node and search for Webhook.
- Set the HTTP Method to
POST. - Note the Production URL n8n generates, this is where you send the document.
Send this webhook a POST request with your document in a binary field named file.
n8n exposes that file as a binary property the next node can read.
n8n Webhook node set to POST with a binary file fieldTo test, you can use a tool like Postman to send a POST request with a file attached to the Webhook URL.
Postman configured to send a DOCX file in a binary field named fileConfigure the upload HTTP Request node
- Add an HTTP Request node after the Webhook node.
- Set the Method to
POST. - Set the URL to the Uploadcare direct upload endpoint:
https://upload.uploadcare.com/base/. - Toggle Send Body to
trueand selectForm-Dataas the Body Content Type.
Add the upload body parameters
Under Body Parameters, add three parameters:
-
A Form Data field named
UPLOADCARE_PUB_KEYwith your public key as the value, which authenticates the upload against your project. -
A Form Data field named
UPLOADCARE_STOREwith the value1, so the file is stored permanently. It needs to survive long enough to convert. -
An n8n Binary File field named
file, with the Input Data Field Name set to the binary property from the Webhook node (file).
n8n HTTP Request node configured for the Uploadcare uploadYou should receive a response containing the UUID of the uploaded file:
{ "file": "6ac598cf-2278-44b7-a5ad-345810b09017" }That UUID is the handle you’ll convert next.
Step 2: Start the conversion
Now that the document is in Uploadcare, let’s start the conversion.
The Conversion API is part of the Uploadcare REST API, which runs the conversion asynchronously:
the POST returns a token instead of the finished file, and you poll for the result.
Configure the start-conversion HTTP Request node
- Add an HTTP Request node after the upload node.
- Set the Method to
POST. - Set the URL to
https://api.uploadcare.com/convert/document/.
Add the required headers
The REST API expects an authorization header on every call. Under Headers, add two:
- An Authorization header with the value
Uploadcare.Simple YOUR_PUBLIC_KEY:YOUR_SECRET_KEY. - An Accept header with the value
application/vnd.uploadcare-v0.7+json, which pins the API version.
Build the request body
-
Toggle Send Body to
trueand selectJSONas the Body Content Type and Specify the body content asUsing JSON. -
Paste the following into the JSON field. Each entry in
pathsis the source UUID plus a conversion operation, and/document/-/format/pdf/tells Uploadcare what to convert and into what:{ "paths": [ "{{ $json.file }}/document/-/format/pdf/" ] } -
Open Options → Response and set Response Format to
JSON.
n8n HTTP Request node starting an async Uploadcare conversionNote: The Conversion API responds with the content type application/vnd.uploadcare-v0.7+json.
n8n doesn’t auto-detect that vendor +json type as JSON,
so without Response Format set to JSON it hands you the body as a raw string under a data field,
and expressions like {{ $json.result[0].token }} come back empty.
Setting Response Format to JSON makes n8n parse the body so you can read its fields directly.
If you want a PNG preview of the first page instead of a PDF,
you can swap the path for {{ $json.file }}/document/-/format/png/-/page/1/
(see generating a PDF thumbnail for more on page previews).
The response includes a result array. Grab result[0].token with a Set node;
that’s what you’ll poll on next.
Extract the token with a Set node
- Add a Set node after the conversion node by clicking the + button -> Data Transformation -> Set.
- Add a field named
tokenand set its value to the expression{{ $json.result[0].token }}.
n8n Set node extracting the conversion tokenNote: Keep the Uploadcare.Simple authorization header server-side only, because it carries your secret key.
The upload in Step 1 uses the public key, but the Conversion API needs the secret key, so this call must never run in client code.
Step 3: Poll for the result
With the conversion running, you need to wait for it to finish. Because the conversion is asynchronous, the pattern is wait, then check.
Add the Wait node
- Add a Wait node after the Set node.
- Set Resume to
After Time Intervaland the Wait Amount to10seconds.
If you expect large files, you can raise that above 10 seconds to cut down on status calls.
The Wait node is what makes the loop work: even large documents keep polling until they report finished, so nothing stalls.
n8n Wait node pausing before the status checkConfigure the status-check HTTP Request node
-
Add an HTTP Request node after the Wait node.
-
Set the Method to
GET. -
Set the URL to the status endpoint with the token from Step 2:
https://api.uploadcare.com/convert/document/status/{{ $('Extract Token').first().json.token }}/
Reference the token from the Extract Token node by name, not{{ $json.token }}. When the job isn’t finished yet, the retry loop feeds the previous status response (which has notoken) back into this node, so{{ $json.token }}would be empty on the second pass and the URL would collapse to.../status//, returning a 404. Pulling it from$('Extract Token')keeps the token stable across every retry. -
Under Headers, add the same Authorization and Accept headers you set on the conversion node.
-
Open Options → Response and set Response Format to
JSON, just as you did on the conversion node, so the status fields parse instead of arriving as a string underdata.
n8n HTTP Request node checking conversion status by tokenTest the status with an IF node
The status response moves through pending and processing before reaching finished (or failed).
To test it, add an IF node after the status-check node that compares the status field to finished:
- Add an IF node after the status-check node.
- Set the Value 1 field to the expression
{{ $json.status }}. - Choose the
Stringtype and theequalsoperation. - Set Value 2 to
finished.
{
"leftValue": "={{ $json.status }}",
"rightValue": "finished",
"operator": { "type": "string", "operation": "equals" }
}Connect the true output (index 0) onward to delivery, and connect the false output (index 1) back to the Wait node to check again.
n8n IF node comparing the conversion status to finishedThat false branch is what makes the loop work: even large documents keep polling until they report finished, so nothing stalls.
Tip: if you expect large files, raise the Wait node above 10 seconds to cut down on status calls.
Step 4: Deliver the converted file
With the polling loop in place, all that’s left is delivery.
When the job finishes, the status response contains result.uuid, the UUID of the new converted file.
Build the output CDN URL with a Set node
-
Add a Set node on the IF node’s true branch.
-
Add a field named
urland set its value to the expression that builds the CDN URL:https://2ta6v1zvst.ucarecd.net/{{ $json.result.uuid }}/
That URL points straight at the finished PDF (or PNG) on the Uploadcare CDN.
Note: 2ta6v1zvst.ucarecd.net is this project’s CDN domain.
You can find yours in the Uploadcare Dashboard under Delivery → CDN Domain names,
and use it in place of the shared ucarecdn.com host in the URLs throughout this guide.
n8n Set node building the output CDN URLEmail the link and respond
Add a Gmail node after the Set node, select your Gmail account credential,
leave Resource as Message and Operation as Send, and put the url field in the message body.
n8n Gmail NodeAlso, add a Respond to Webhook node after the Gmail node to send a response back to Postman (or whatever source triggered the workflow) with the converted file’s CDN URL:
n8n Respond to Webhook node sending the CDN URL back to the sourceFrom here you can push the link to Slack, save it to a database, or attach it to a record, whatever fits your stack.
Conclusion
In this guide, you’ve learned how to upload a document over a Webhook node,
start an async PDF or PNG conversion with the Uploadcare Conversion API,
poll the status endpoint by token until the job reports finished,
and turn the result into a ready-to-share CDN link delivered by email.
The polling loop keeps the workflow self-contained, so it handles a one-page memo and a long report the same way.
You can try it out in your own project by importing the workflow.json from the document-conversion folder,
add your keys, and change the conversion path to match the output format you need. For more endpoints,
see the Uploadcare docs, and see the webhooks reference if you’d rather switch to event-driven delivery.
For related reads, see how to convert docs to PDF and the image transformations developer guide.
FAQs
Which document formats can the Uploadcare Conversion API convert?
The Uploadcare Conversion API accepts common office and document formats as input,
such as DOC, DOCX, and ODT, and can output pdf, png, and jpg.
You set the output format in the conversion path, for example -/format/pdf/.
Do I need my Uploadcare secret key for this workflow?
Yes, for the conversion step. The upload in Step 1 authenticates with the public key,
but the Conversion API is part of the REST API and needs the Uploadcare.Simple authorization header built from your public and secret keys.
Keep that call server-side so the secret key never reaches client code.
How do I get an image preview of a single PDF page?
Use a path like <UUID>/document/-/format/png/-/page/1/.
The page operation selects the page number, and format/png (or jpg) renders it as an image rather than a document.
Why poll the status endpoint instead of waiting for a webhook?
For a self-contained workflow, poll: the conversion is asynchronous, so you wait, then check the token until the job reports finished.
For event-driven delivery, configure a webhook in the Uploadcare Dashboard
and trigger a separate Webhook node when the converted file is ready.