Skip to main content

Auto-Merge Every PDF Dropped into a Dropbox Folder in Power Automate: A 6-Step Dynamic Workflow

· 23 min read
SEO and Content Writer

The painful part of "merge these PDFs" tickets is not the merging, it is knowing what is in the folder at run time. Names change, files come and go, somebody adds a fifth document at 4:55 pm. This walkthrough builds the exact pattern in Power Automate with PDF4me Merge multiple PDF files, Dropbox, and a single Apply to each loop. Six flow actions. Zero hardcoded filenames. Every PDF currently in the watched folder gets stitched together the moment a new file lands, and the output name carries the file count so each run is uniquely identifiable.

The flow at a glance
1. When a file is created
Dropbox trigger on /blog data/merge files dropbox. Fires the moment any file lands.
2. List files in folder
Dropbox action on the same folder. Returns every current file as an array of metadata objects.
3. Initialize variable
Name Files, Type Array. Buffer for the binary content of every file.
4. Apply to each
Loop body(List_files_in_folder). Inside, Get file content by Id, then Append to array with base64ToBinary on $content.
5. Merge multiple PDFs
PDF4me action. Body/docContent the Files array, Output File Name Output.pdf. One consolidated PDF out.
6. Create file
Dropbox /blog data/merge blog template/output. File Name expression concat(merge-, length(List_files_in_folder), .pdf).
The short version

A When a file is created Dropbox trigger fires on every new upload. List files in folder returns a snapshot of every file currently in the folder (in this run, four PDFs: PDFA_Sample.pdf, sample_3_page.pdf, sample_pdf.pdf, sample.pdf). An Apply to each loop walks that list, calls Get file content by Id, and pushes base64ToBinary(body('Get_file_content')?['$content']) onto an array variable named Files. PDF4me's Merge multiple PDF files consumes the array and emits one PDF. Dropbox Create file writes it back as merge-4.pdf, because there were four input files. Drop a fifth file in tomorrow and the next run produces merge-5.pdf automatically.

Why-Based Q&A

Why use the trigger and List files in folder together? The trigger gives you a single new-file event but not a guaranteed up-to-date list of everything else in the folder. List files in folder snapshots the current state at run time, so the merge always reflects exactly what is on disk right now, not what was there when the trigger fired or when the flow was designed.

Why fetch by Id instead of Path? File names can collide or change. Dropbox Ids are stable, unique, and immune to rename. Mapping Id from List files into Get file content means the loop keeps working even if a user renames a file mid-batch, or two files have the same display name in different subfolders.

Why base64ToBinary(...) on $content? Dropbox Get file content returns the file as a base64 string wrapped in a $content property. PDF4me's Merge multiple PDF files action expects a collection of binary buffers, not base64 strings. base64ToBinary(body('Get_file_content')?['$content']) is the bridge that converts each file the moment it lands in the array.

Why build the output filename with concat() and length()? Hardcoding Output.pdf means every run overwrites the last. concat('merge-', string(length(body('List_files_in_folder'))), '.pdf') stamps the file count into the name, so consecutive runs land as merge-3.pdf, merge-4.pdf, merge-5.pdf. Bonus: a quick look at the output folder tells you how many files were in scope each time.


What You'll Get

Input: A Dropbox folder at /blog data/merge files dropbox containing whatever PDFs you drop into it. This walkthrough uses four: PDFA_Sample.pdf, sample_3_page.pdf, sample_pdf.pdf, sample.pdf. Output: A single consolidated PDF in /blog data/merge blog template/output/ named merge-N.pdf where N is the file count at run time. Drop more files and the next run automatically picks them up.

The Dropbox folder before the run

Dropbox folder /blog data/merge files dropbox listing four PDFs sorted by name: PDFA_Sample.pdf 16.5 KB, sample_3_page.pdf 2.48 KB, sample_pdf.pdf 2.14 KB, sample.pdf 97.67 KB, all set to Access Only you

The Dropbox folder after the run

Dropbox output folder listing merge-3.pdf 37.22 KB and merge-4.pdf 110.78 KB, each output named after the number of files in scope when the flow ran

The second run had four files in the folder, so the output is merge-4.pdf. The earlier run had three.


What You Need

  • Power Automate. Open Power Automate. Any plan with premium connectors (PDF4me Connect is premium).
  • PDF4me API key. Get your API key. Connect it the first time you add a PDF4me action.
  • Dropbox. Source folder for the input PDFs, destination folder for the merged output. SharePoint, OneDrive, and Google Drive work identically with their matching connectors.
  • A handful of PDFs. Any size, any combination. The walkthrough uses four samples: PDFA_Sample.pdf, sample_3_page.pdf, sample_pdf.pdf, sample.pdf. Drop them in to mirror every screenshot.

Grab the input set and the expected output first. Download the four samples into /blog data/merge files dropbox on your Dropbox, then publish the flow. Your first run should produce a merge-4.pdf identical to the one linked here.


The Flow at a Glance

  1. Dropbox: When a file is created (trigger).
  2. Dropbox: List files in folder. Returns every file currently in the watched folder.
  3. Initialize variable named Files (Array).
  4. Apply to each on body('List_files_in_folder'):
    • Dropbox: Get file content by Id.
    • Append to array variable with base64ToBinary(body('Get_file_content')?['$content']).
  5. PDF4me: Merge multiple PDF files into a single PDF file. Files in, Output.pdf out.
  6. Dropbox: Create file. File Name concat('merge-', string(length(body('List_files_in_folder'))), '.pdf').

Complete flow overview

Power Automate flow canvas showing six actions stacked top to bottom: When a file is created, List files in folder, Initialize variable, Apply to each containing Get file content and Append to array variable iterating 4 times, Merge multiple PDF files into a single PDF file, Create file

Six actions. The Apply to each card shows "1 of 4" because the watched folder held four PDFs at run time.


Step 1: Dropbox: When a File Is Created (Trigger)

Flow so far: trigger only.

  1. In Power Automate click Create, choose Automated cloud flow.
  2. Name the flow (e.g. Auto-Merge Dropbox Folder), pick Dropbox: When a file is created as the trigger, click Create.
  3. Connect Dropbox if you have not already.
  4. Configure:
    • Folder: /blog data/merge files dropbox
    • Advanced parameters: leave at the default (0 of 1 showing).

Trigger configuration

Power Automate Dropbox When a file is created trigger with Folder set to /blog data/merge files dropbox and Advanced parameters collapsed showing 0 of 1, Connected to Dropbox

The trigger polls the watched folder and fires on every new upload. Default polling cadence varies by plan, typically 1 to 5 minutes.


Step 2: Dropbox: List Files in Folder

Flow so far: trigger plus List files in folder.

The trigger fires on a single new file. The merge needs every PDF currently in the folder. List files in folder takes a fresh snapshot of the folder contents at run time.

  1. Click + New step, search Dropbox, pick List files in folder.
  2. Configure:
    • Folder: /blog data/merge files dropbox (the same path as the trigger)

List files configuration

Power Automate Dropbox List files in folder action with Folder set to /blog data/merge files dropbox, Connected to Dropbox
  1. The action returns body('List_files_in_folder'), an array of file metadata objects. Each object carries Id, Name, DisplayName, Path, LastModified, and Size. The next step iterates this array.

Tip. If your folder has mixed content (PDFs alongside images and Office docs) and you only want to merge PDFs, add a Filter array action after this step with the expression endsWith(toLower(item()?['Name']), '.pdf') and feed the filtered array into the loop instead.


Step 3: Initialize Variable Files

Flow so far: trigger plus List files plus Initialize variable.

The merge action wants a collection of binaries. Allocate an empty array to collect them.

  1. Click + New step, pick Initialize variable.
  2. Configure:
    • Name: Files
    • Type: Array
    • Value: leave blank

Initialize variable configuration

Power Automate Initialize variable action configured with Name Files and Type Array and an empty Value field

Step 4: Apply to Each Plus Get File Content Plus Append to Array

Flow so far: trigger plus List files plus Initialize variable plus Apply to each.

This is the heart of the flow. Loop over every file the snapshot returned, fetch its bytes, convert to binary, push onto Files.

Step 4a: Apply to each (pick the source)

  1. Click + New step, pick Apply to each.
  2. Configure:
    • Select an output from previous steps (expression): body('List_files_in_folder')
Power Automate Apply to each action with Select an output from previous steps set to the expression body open quote List_files_in_folder close quote close paren, the Body token from List files in folder shown

Step 4b: Get file content (inside the loop)

  1. Inside the loop click Add an action, pick Dropbox: Get file content.
  2. Configure:
    • File: pick the Id token from the List files in folder dynamic content (it auto-resolves to the current item's Id).
    • Infer Content Type: Yes (under Advanced parameters)
Power Automate Dropbox Get file content action with File set to the Id token from List files in folder, Advanced parameter Infer Content Type Yes, dynamic content panel open on the right showing Id, Name, DisplayName, Path, LastModified, Size tokens from List files in folder

Step 4c: Append to array variable (inside the loop)

  1. Below Get file content, Add an action, pick Append to array variable.
  2. Configure:
    • Name: Files
    • Value (expression, click fx): base64ToBinary(body('Get_file_content')?['$content'])
Power Automate Append to array variable inside Apply to each loop, Name Files, Value set to the expression base64ToBinary body open quote Get_file_content close quote close paren question dollar content close bracket shown in the expression editor

This is the one line that ties everything together. Dropbox returns each file as { "$content": "<base64 string>", "$content-type": "application/pdf" }. The merge action wants a binary buffer. base64ToBinary(...) on $content bridges the two. Skip the conversion and the merge action errors with "invalid content".


Step 5: PDF4me: Merge Multiple PDF Files Into a Single PDF File

Flow so far: trigger plus List files plus Initialize variable plus Apply to each plus Merge multiple PDFs.

The whole array goes in and one PDF comes out.

  1. Below the Apply to each loop click + New step, search PDF4me, pick Merge multiple PDF files into a single PDF file.
  2. Connect PDF4me Connect with your API key (first time only).
  3. Configure:
    • Body/docContent: pick the Files variable token
    • Output File Name: Output.pdf

Merge action configuration

Power Automate PDF4me Merge multiple PDF files into a single PDF file action with Body/docContent set to the Files variable and Output File Name Output.pdf, dynamic content panel open showing Variables Files, Apply to each, Current item, List files in folder, Body
  1. The PDFs are concatenated in array order, which is the order Dropbox returned them in (typically alphabetical by name). If you need a different order, sort body('List_files_in_folder') with a Select action before the loop, e.g. by LastModified for newest-first.

Tip. The internal Output.pdf name is just the PDF metadata title, not the Dropbox filename. The real Dropbox name is set in step 6. Keep this as a stable placeholder so you can grep flow runs by it in the Power Automate run history.


Step 6: Dropbox: Create File with a Dynamic Filename

Flow so far: trigger plus List files plus Initialize variable plus Apply to each plus Merge multiple PDFs plus Create file.

Write the merged PDF back to Dropbox with a runtime-computed filename that includes the file count.

  1. Click + New step, pick Dropbox: Create file.
  2. Configure:
    • Folder Path: /blog data/merge blog template/output
    • File Name (expression, click fx): concat('merge-', string(length(body('List_files_in_folder'))), '.pdf')
    • File Content: pick the File Content token from the Merge multiple PDFs action

File name expression

Power Automate Dropbox Create file action Folder Path /blog data/merge blog template/output, File Name expression concat open paren merge dash comma string open paren length open paren body open quote List_files_in_folder close quote close paren close paren comma dot pdf close paren, File Content from the merge action

Final action ready

Power Automate Dropbox Create file action with Folder Path /blog data/merge blog template/output, File Name token concat expression, File Content token from Merge multiple PDF files into a single PDF file action, dynamic content panel showing File Content, headers/FileName, headers/PageCount tokens

The same expression also exposes headers/PageCount on the merge output, useful if you ever want to log how many pages the consolidated PDF carries.

Tip. If you would rather stamp the run with a date than a file count, swap the expression for concat('merge-', utcNow('yyyy-MM-dd-HHmmss'), '.pdf'). Files land as merge-2026-06-12-094501.pdf and re-runs never collide.


Run the Flow and Verify

  1. Save the flow at the top right.
  2. Drop a file (or four) into /blog data/merge files dropbox. Anything will do, the polling interval kicks the trigger within a couple of minutes.
  3. Open the Run history at the top right and watch the actions turn green. Apply to each should show the right iteration count, "1 of 4" if four files were in the folder.
  4. Open Dropbox at /blog data/merge blog template/output/. A file named merge-4.pdf is waiting. Open it, every PDF from the input folder is stitched into one document.

What did you actually build? A zero-touch consolidation pipeline that reacts to every new upload, reads the entire folder state at run time, and writes a single uniquely-named PDF carrying every current file. No hardcoded lists, no scheduled batch job, no manual click. The same pattern handles 4 PDFs or 400 with zero changes. Same recipe works in Make (Iterator over Dropbox List Files) and Zapier (Looping by Zapier over Find File results).


Common Variations You Can Add Without Rebuilding

Filter to PDFs only
Insert a Filter array action between step 2 and step 3 with endsWith(toLower(item()?['Name']), '.pdf'). The loop then ignores .docx, .png, and anything else in the folder.
Sort by newest first
Add a Select action that maps the list and sort with sort(body('List_files_in_folder'), 'LastModified'). Reverse with reverse(...) if you want newest at the top of the merged PDF.
Convert to PDF/A after merge
Insert PDF4me Create PDF/A between step 5 and step 6 with Compliance PDF/A-2b. The output that lands in Dropbox is now ISO 19005 archive-compliant.
Archive source files
After step 6 add another Apply to each over List files and call Dropbox Move file to push each input into /processed. Next run only sees fresh uploads.

Troubleshooting

Merge action errors with "invalid content"

The Append to array Value expression is not wrapped in base64ToBinary(...). Without the conversion the array carries base64 strings instead of binary buffers and PDF4me rejects them. Re-open Append to array, switch to the expression editor, and paste base64ToBinary(body('Get_file_content')?['$content']) verbatim.

Apply to each runs zero times

The trigger fired but List files returned an empty array. Check the trigger and List files Folder values are identical. Path mismatches (one with a trailing slash, the other without) are a common cause.

The file name comes out as merge-.pdf

The length() call did not resolve at design time. Make sure you pasted the expression into the File Name field via the fx expression editor, not as plain text. Plain text leaves the curly braces as literal characters and the function never runs.

Output overwrites the previous run

Two consecutive runs with the same file count produce identical names (merge-4.pdf). Either swap the expression to a timestamp (concat('merge-', utcNow('yyyy-MM-dd-HHmmss'), '.pdf')) or append a GUID with guid().


Next Steps

The same six-step pattern (watch then list then loop-to-array then merge then save with a runtime name) handles any "react to a folder" automation. Drop a new file in tomorrow, the run picks it up. No edits, no re-deploy.