Skip to main content

Invoice OCR in Zapier: Loop Over Every Attachment in a Shared Mailbox with PDF4me AI Document Parser

· 24 min read
SEO and Content Writer

PDF4me AI Document Parser is a Zapier action that reads a document with AI and returns its fields as JSON. Paired with Looping by Zapier, it handles the normal case in accounts payable: one email carrying several invoices, each attachment parsed in its own run.

Every invoice-OCR tool demonstrates the same thing, which is one document going in and clean fields coming out. That is not how invoices arrive. They arrive as an email to a shared inbox, from a supplier who attached three PDFs and wrote "PFA" in the body. The interesting problem is not reading one invoice, it is that a single trigger has to turn into several parses, and most walkthroughs quietly skip it by watching a folder where somebody has already split the files apart. This Zap does not skip it. Three steps, and the middle one is the loop.

The Zap at a glance
1. New Email in Shared Mailbox
Microsoft Outlook, polling every 2 minutes. One email is one supplier sending one or more invoices.
2. Create Loop From Line Items
Looping by Zapier. Turns the attachment list into one iteration per file.
3. AI - Document Parser
PDF4me. Runs your Analyzer against the attachment and returns the fields as JSON.
The short version

A supplier emails your shared mailbox with two invoices attached. Looping by Zapier splits the attachment list into one iteration per file, and each iteration runs the PDF4me AI Document Parser on its own attachment. You get one structured JSON per invoice, with a confidence score on every field, ready to map into Sheets, Airtable, or your ledger. Three steps, no code.

Why-Based Q&A​

Why trigger on a shared mailbox instead of a folder? Because that is where invoices already are. Asking suppliers to upload to a portal, or asking a person to save attachments into Dropbox first, adds a manual step at the exact point you are trying to automate. A shared mailbox is also the version of this that survives someone leaving: the address belongs to the function, not the individual.

Why do you need a loop at all? Because a Zap step runs once per trigger, and one email can carry any number of attachments. Without the loop you parse whichever attachment Zapier hands you first and silently drop the rest, which is the worst kind of bug: the Zap goes green and the invoices disappear. Looping turns the attachment list into one iteration per file.

Why an Analyzer instead of a fixed invoice schema? Because the fields you actually need are specific to your ledger. AI Document Parser runs an Analyzer you define once in the PDF4me dashboard, so the same action handles invoices today and purchase orders or delivery notes later. Change the schema and every Zap pointing at that Analyzer picks it up without a rebuild.

Why do confidence scores matter more than the extracted values? Because OCR does not fail loudly. It returns a plausible wrong answer. The parser reports a score per field, so you can route anything below your threshold to a human instead of posting it. In the captured run the totals scored in the nineties while the billing state scored 59.8, which is exactly the distinction a review queue should act on.


What You'll Get​

Input: one email in a shared mailbox with any number of PDF invoices attached. Output: one Zap run per attachment, each returning the invoice as structured JSON with a per-field confidence score, ready to map into any downstream app.

Outlook showing an email with the subject invoice and the body PFA, carrying two attachments, Samples 2.pdf at 196 KB and Samples 1.pdf at 199 KB, listed as 2 attachments totalling 395 KB

Two attachments, one message, a two word body. This is the input the Zap has to cope with.

Zapier Zap history listing two successful runs of the Email Doc Parser Zap on Oct 15 2026 at 07:02:53 pm and 07:03:37 pm, each consuming 1 task, with the Outlook, Looping and PDF4me app icons shown on both rows

One email in, two runs out. Each loop iteration is its own Zap run in the history.


What You Need​

  • A Zapier account. Looping by Zapier is a built-in app, so there is nothing to install. Check your plan: multi-step Zaps are required, and every loop iteration counts as a task.
  • PDF4me API key. Get your API key. The captured Zap runs on the PDF4me app at version 1.30.0.
  • An Analyzer saved in the PDF4me dashboard. Open the Analyzer list. The built-in default_invoice_extraction Analyzer produces the output shown here, so you can start there and build your own later.
  • A Microsoft Outlook shared mailbox that receives supplier invoices, and an account with permission to read it. If you do not have one yet, Microsoft documents how to create one.
  • A test email you control, with at least two PDFs attached, so you can prove the loop runs more than once before pointing the Zap at live supplier mail.
Use the same invoice this walkthrough used
Attach this to your test email and your Doc Text should match the JSON shown below, field for field. It is a sample invoice with two line items, one of them a negative discount line, which is a useful thing to check a parser against.
Download sample-invoice-13594027.pdf

The Zap at a Glance​

  1. New Email in Shared Mailbox (Microsoft Outlook) polls the mailbox every 2 minutes.
  2. Create Loop From Line Items (Looping by Zapier) turns the attachment list into one iteration per file.
  3. AI - Document Parser (PDF4me) runs the Analyzer against the attachment from the current iteration.

Complete Zap overview​

Zapier editor showing the three step Email Doc Parser Zap: step 1 Microsoft Outlook New Email in Shared Mailbox with a 2 min polling badge reporting Found 1 new Email, step 2 Looping by Zapier Create Loop From Line Items reporting Sent 1 new Loop, and step 3 Pdf4me 1.30.0 AI - Document Parser reporting Sent 1 new Process Document

Three steps. The loop in the middle is what makes the third step run once per attachment.


Step 1: How do you trigger a Zap from a shared mailbox?​

Flow so far: nothing yet, this is the trigger.

An invoice arriving is the event, so the mailbox is the trigger.

  1. Create a Zap and pick Microsoft Outlook > New Email in Shared Mailbox.
  2. Connect the account that has permission to read the mailbox, then choose the shared mailbox address and the folder to watch. Watching Inbox is fine to start with.
  3. Test the trigger with the email you prepared. Zapier reports Found 1 new Email in Microsoft Outlook, and the attachment list becomes available to later steps as line items.

The polling interval on the captured Zap shows as 2 min, which is the Zapier plan's schedule rather than anything you configure on the step.

Tip. Use a dedicated folder, not the whole Inbox, as soon as this is more than a test. A server-side Outlook rule that files supplier mail into an Invoices folder gives you a clean trigger scope and a place to look when something does not fire. It also stops the Zap burning tasks on newsletters.


Step 2: How do you loop over every attachment on one email?​

Flow so far: the Outlook trigger.

This is the step that turns one email into one run per invoice.

  1. Add Looping by Zapier > Create Loop From Line Items.
  2. In Values to Loop, map the attachment line items from the trigger. The captured run loops two values together, which is the pattern to copy:
    • Attachments Name, the filename
    • Attachments File, the file itself
  3. Test the step. Zapier reports Sent 1 new Loop to Looping by Zapier and the Data out tab shows the first iteration plus a preview of all of them.

Create Loop From Line Items output​

Looping by Zapier step 2 Run details Data out tab showing Loop Iteration 1 with Attachments Name Samples 2.pdf and an Attachments File URL on zapier-dev-files.s3.amazonaws.com, a preview_loop_values block listing iteration 1 as Samples 2.pdf and iteration 2 as Samples 1.pdf, and the fields Loop Id, Loop Id And Iteration, Loop Iteration Is Last false, Loop Iteration Last 2 and Loop Total Iterations 2

Loop Total Iterations reads 2, one per attachment, and preview_loop_values names both files before either has been parsed.

What the loop hands you​

FieldValue in the captured runWhat you use it for
Loop Iteration1Which pass you are on, counting from 1
Attachments NameSamples 2.pdfThe filename for this iteration, useful for naming records downstream
Attachments FileA zapier-dev-files.s3.amazonaws.com URLThe file itself, and what you map into the parser
Loop Total Iterations2How many attachments the email carried
Loop Iteration Is LastfalseFire a summary or a notification only when this turns true
Loop Idd889b92b-c6a1-4abc-a6a1-a1d4c1c78e1dTies every iteration of one email together, which is what you group by downstream
preview_loop_valuesIteration 1 Samples 2.pdf, iteration 2 Samples 1.pdfThe whole list, visible on the first pass

Two details are worth noticing before you move on. The loop does not run in the order the attachments appear in Outlook: the mail showed Samples 2 first and the loop agreed, but you should never depend on that. And Loop Id is the only thing connecting the resulting rows back to the email they came from, so map it downstream now rather than wishing you had later.

Tip. Every iteration is a separate Zap run and consumes a task. An email with ten attachments is ten tasks, not one, which is the single most common surprise on the monthly bill. Zapier documents the loop limits, and they are worth reading before you point this at a busy mailbox.


Step 3: How do you turn each attachment into structured JSON?​

Flow so far: the trigger plus the loop.

Everything from here runs once per attachment, because it sits inside the loop.

  1. Add PDF4me > AI - Document Parser and connect your API key.
  2. Configure:
    • File: the Attachments File token from the loop, not from the trigger. This is the one thing people get wrong.
    • File Name and File Ext: build the name from the loop's Attachments Name.
    • AI Analyzer Id: pick your Analyzer from the dropdown. default_invoice_extraction produces the output below.
    • AI Analyzer Name (Deprecated): leave empty.
  3. Test. Zapier reports Sent 1 new Process Document to Pdf4me, and Data out carries the parsed fields.

AI - Document Parser output, first attachment​

PDF4me AI - Document Parser step 3 Run details Data out showing Trace Id 57525903-32b5-47ff-ad16-6c58179b5aa1, a Document Document Id of b9de2201-e98f-5659-b196-70d9bf18ff0e, and a Document Doc Text JSON holding invoiceNumber 13594027, vendorName Your Business Name, billTo John Smith, subTotal 37.5, two line items and a docConfidenceLevel block scoring every field

Doc Text carries the invoice. Every field also appears in docConfidenceLevel with a score attached.

AI - Document Parser output, second attachment​

The same PDF4me AI - Document Parser step on the second loop iteration, showing a different Trace Id 0b16be26-64be-4cee-a764-8a52f2a263df and Document Id 5450ac57-f16a-50ec-834f-10bf80c5b505, with the same invoice fields and slightly different confidence scores

A different Trace Id and a different Document Id, which is how you tell the two parses apart in logs.

Both attachments in this capture hold the same sample invoice, so the extracted figures match. What the second run proves is not that the parser handles two different layouts, it is that the third step executed twice from a single email.

What comes back​

Output fieldWhat it holds
Trace IdUnique per call. Quote it in a support ticket
Document Document IdPDF4me's id for the parsed document, different on every run
Document Doc TextThe JSON payload: the extracted fields plus docConfidenceLevel
Document File Name, Document Name, DocMetadataNaming and metadata, populated according to what you map in

Inside Doc Text the default_invoice_extraction Analyzer returns the header fields (invoiceNumber, invoiceDate, invoiceDateString, orderId, customerPO, paymentDeadline), the vendor block (vendorName, vendorAddress, vendorPhone, vendorEmail, and tax identifiers including vendorGSTIN, vendorPAN, vendorCIN, vendorVatUidNr, iban), the customer block (billTo, billToAddress, billToPhone, billToEmail, billToState, billToPincode), the totals (subTotal, cgst, sgst, cgstRate, sgstRate, totalTaxAmount, total) and a lineItems array. For the sample invoice that resolves to invoiceNumber 13594027, billTo John Smith, total 37.5, and two line items, the second of which is the -12.5 discount line.

Reading the confidence scores​

docConfidenceLevel mirrors the same shape with a number in place of every value. These are the scores from the two captured runs, and the spread is the point.

FieldRun 1Run 2What it tells you
vendorEmail98.998.9Machine-readable text, trust it
vendorName98.598.5Clean heading, trust it
billTo97.397.3Clean, trust it
subTotal9594.7Good, and worth a tolerance check against total
total92.892.8Good, but this is the field worth auto-checking
billToAddress79.581.9Multi-line and wrapped, review if it matters
billToPincode60.860.8The sample runs the city, state and postcode together
billToState59.859.8Lowest in the document, do not post this unreviewed

The same document scored slightly differently on two passes, which is normal for a model and is exactly why you set a threshold rather than trusting a single number. Pick a floor, route anything under it to a person, and let the rest through.


Run the Zap and Verify​

  1. Publish the Zap.
  2. Send a test email to the shared mailbox with two PDFs attached.
  3. Wait for the poll, then open Zap history.
  4. You should see two runs of the Zap, not one, each marked Successful and each consuming 1 task.
  5. Open each run and check step 3's Data out: the Trace Id and Document Document Id should differ between them, and Doc Text should hold that attachment's invoice.
  6. Check Loop Total Iterations on step 2. If it reads 1 when you attached two files, the problem is the mapping in Values to Loop, not the parser.

In the captured run the two Zap runs completed at 07:02:53 pm and 07:03:37 pm on Oct 15 2026, both Successful, 1 task each, from a single email carrying 395 KB of attachments.

What did you actually build? An invoice intake that starts where invoices actually land. Nobody downloads an attachment, nobody retypes a total, and an email with five invoices on it produces five structured records instead of one. The confidence scores give you somewhere sensible to draw the line between automatic and reviewed.


Common Variations You Can Add Without Rebuilding​

Write every invoice to a sheet
Add a Google Sheets or Airtable step after the parser, still inside the loop. Map Loop Id into its own column so every row from one email can be grouped back together.
Route low-confidence invoices to a human
Add a Filter by Zapier on a docConfidenceLevel field. Above your threshold it posts automatically, below it goes to a review queue or a Slack channel with the Trace Id attached.
Skip anything that is not an invoice
Suppliers attach signatures and logos too. A Filter on Attachments Name ending in .pdf, placed inside the loop, stops the parser being called on an image and wasting a task.
Parse something other than invoices
The action is schema-driven. Point AI Analyzer Id at a Classify Analyzer and one Zap handles invoices, purchase orders and delivery notes, returning the matched type with its fields.

How this compares to the other ways of doing invoice OCR​

Each row describes the alternative. The last row is this Zap.

ComparisonWho runs itWhere invoices come fromWhat you maintain
AP automation platform vs this ZapFinance, in a dedicated productA forwarding address into that productA per-document contract and its approval rules
OCR API called from code vs this ZapA developer, in an applicationWhatever your code fetchesThe code, the mailbox polling and the retries
ERP capture module vs this ZapFinance, inside the ERPA scanner or a drop folderLicences, and a workflow tied to that ERP
This ZapAnyone who can edit a ZapThe shared mailbox you already useThree steps and one Analyzer schema

Common questions​

What is invoice OCR?​

Invoice OCR is reading an invoice with software instead of a person, so that the supplier, the date, the line items and the total come out as data your systems can use. Classic OCR only recovered the characters on the page and left you to work out which number was the total; the AI parsers that replaced it return named fields directly.

That distinction matters when you choose a tool. A library that performs optical character recognition gives you text. A document parser gives you total, invoiceNumber and billTo, which is what a Zap can actually map into a spreadsheet.

How does looping by Zapier work?​

Looping by Zapier is a built-in app that re-runs the steps below it, once per item. Create Loop From Line Items takes a set of line items from an earlier step, such as the attachment list on an email, and starts one iteration per item.

Each iteration is a separate Zap run with its own entry in Zap history and its own task consumption. Inside an iteration you get Loop Iteration, Loop Total Iterations, Loop Iteration Is Last and a Loop Id shared by all iterations of the same source record.

What is OCR invoice processing?​

OCR invoice processing is the whole pipeline, not just the reading step: an invoice arrives, its fields are extracted, the values are checked, and the result is posted into a ledger or a review queue. The extraction is usually the easy part.

The parts that decide whether it works in practice are intake and exception handling. This Zap covers intake with the shared mailbox and the loop, and gives you the raw material for exception handling with docConfidenceLevel.

How do you automate accounts payable?​

Start with intake, because manual steps there undo everything downstream. Give suppliers one address, trigger on it, and make sure one email with several invoices produces several records rather than one.

Then decide what posts automatically. A confidence threshold on the extracted fields splits invoices into those your ledger can take unattended and those a person should see, and that split is what makes the automation safe to leave running.


Troubleshooting​

Only the first attachment gets parsed

Check Loop Total Iterations on step 2. If it reads 1, Values to Loop is mapped to a single field rather than the attachment line items, so the loop has nothing to iterate over. If it reads 2 but only one parse happened, step 3's File is mapped to the trigger instead of to the loop's Attachments File.

The task count is higher than you expected

This is the loop working as designed. One email with ten attachments is ten runs and ten tasks. Add a Filter inside the loop so signatures, logos and anything that is not a PDF never reach the parser.

Doc Text comes back empty or missing fields

The Analyzer decides which fields exist. An empty key means the schema asked for something this document does not contain, which is normal. An entirely empty Doc Text usually means the wrong AI Analyzer Id, or a file that reached the action without its extension, so check File Name and File Ext.

Values look right but post wrong downstream

Look at docConfidenceLevel before blaming the mapping. In this capture the totals scored above 92 while billToState scored 59.8, so a field can be present, plausible and still wrong. Keep the Trace Id on every record so you can match a bad row back to its run.


Next Steps​

The hard part of invoice automation was never reading the invoice. It was the envelope it arrived in, and a loop is what opens it.