Expensent
Expensent
PricingIntegrationsGuidesAboutContactGet Started
Menu
PricingIntegrationsGuidesAboutContactHelp
Privacy PolicyTerms of Service
Theme
Get Started
Home/Guides/Gmail to Expensify Workflow

Gmail to Expensify: The Complete Workflow Guide

Five ways to get Gmail receipts into Expensify — from a one-off manual forward to a Google Workspace routing rule — plus a backfill playbook for the years of old invoices already buried in your inbox.

Last updated: April 2026

In This Guide

  1. 1. The Gmail → Expensify problem: ongoing plus backfill
  2. 2. How Expensify receives mail (quick recap)
  3. 3. Method A — Manual forward
  4. 4. Method B — Gmail filters: the verification trap
  5. 5. Method C — Google Workspace routing rules
  6. 6. Method D — Apps Script and Gmail API
  7. 7. Method E — Inbox-aware tools
  8. 8. Which method for which user
  9. 9. Backfilling years of historical receipts
  10. 10. Troubleshooting Gmail-specific quirks
  11. 11. Frequently Asked Questions

1. The Gmail → Expensify problem: ongoing plus backfill

If you've landed here, you probably already know the destination: receipts@expensify.com. Forwarding a single receipt there is well documented in our main Expensify email receipts guide. What that guide doesn't cover — and what this one does — is the real-world operational problem of connecting Gmail (personal or Google Workspace) to Expensify at scale, on an ongoing basis, and retroactively across years of old mail.

There are two jobs to solve, not one:

  1. 1.Ongoing: every new receipt from now on — every time Stripe, AWS, Shopify, or your SaaS vendor sends an invoice, it should end up in Expensify without you having to remember to forward it.
  2. 2.Backfill: the three years of receipts already in your inbox — the moment you sign up for Expensify, there's a pile of historical invoices already sitting in Gmail that your accountant would love to have.

Native Gmail features are built around job #1 and mostly fail at it. None of them solve job #2 at all. That asymmetry is what this guide exists to untangle.

2. How Expensify receives mail (quick recap)

A two-sentence refresher so the rest of this guide makes sense. Expensify ingests receipts through receipts@expensify.com, and it only accepts mail from senders whose address is registered as a primary or secondary login on an Expensify account. SmartScan reads either the PDF/JPG/PNG attachment or the inline HTML of a forwarded vendor email and turns it into an expense under the sender's account.

Full walkthrough of the single-receipt flow: prerequisites, file format and size limits, Copilot delegation, and the step-by-step forward are all in How to email receipts to Expensify. This page assumes you already have that basic forwarding working and want to scale it up.

3. Method A — Manual forward

The baseline. Open the receipt in Gmail, hit Forward, type receipts@expensify.com, send. Done. SmartScan handles the rest and the expense appears in your Expensify account a few minutes later.

Pros: zero setup, no permissions to beg for from IT, works identically on personal Gmail and Google Workspace, and every forward is intentional so you never accidentally send Expensify something that isn't a receipt. Cons: it depends on you remembering to do it every single time, which is exactly the kind of thing humans forget. If you only get a handful of receipts a month and you already live in your inbox, Method A is genuinely fine. Most people need something more durable.

Pro tip: turn on Gmail's keyboard shortcuts (Settings → See all settings → General → Keyboard shortcuts on), then use f to forward the open message. It takes the forward from a 30- second detour to a 3-second one, which is the difference between doing it and not.

4. Method B — Gmail filters: the verification trap

The next thing everyone tries is a Gmail filter with Forward it to set to receipts@expensify.com. In theory this is perfect: narrow the filter to from:(billing@stripe.com OR receipts@uber.com), set the action to forward, and you're done. In practice, you will get stuck on the very first step.

The verification trap, step by step

  1. 1.Gmail will not let a filter forward to any address that isn't already on your verified list (Settings → Forwarding and POP/IMAP). Personal Gmail caps the list at 20 verified addresses.
  2. 2.To add receipts@expensify.com, Gmail sends a confirmation code email to that address and asks you to paste it back into Settings.
  3. 3.receipts@expensify.com is an ingestion endpoint. There is no inbox to log into, no way to read the code, no human on the other side to forward it back to you.
  4. 4.Dead end. The verification step cannot be completed, so the destination cannot be added, so the filter cannot be created.

This is not a bug, a misconfiguration, or a missing permission. It's how Gmail is designed: the verification handshake exists to prevent malicious filters from silently exfiltrating your mail, and there is no user-facing way to opt out. Every personal @gmail.com account hits this wall.

Mark this one as "does not work" and move on. You'll see countless forum threads recommending Gmail filters for this. They all end with the original poster discovering the verification trap and never updating the thread.

5. Method C — Google Workspace routing rules

If your Gmail account is actually a Google Workspace account (your email lives on your own domain, billed to Google), there is a second lever that bypasses the verification trap entirely: Gmail routing rules in the Admin Console. Routing rules run at the MTA level before mail reaches the user's mailbox, and they do not require the destination to be verified.

Where it lives

Google Admin Console → Apps → Google Workspace → Gmail → Routing. You need super-admin or delegated Gmail admin permissions. The two rule types worth knowing:

  • •Recipient rules can add an envelope recipient to any message matching an address pattern (for example, BCC receipts@expensify.com on every message delivered to billing@yourdomain.com).
  • •Content compliance rules can match on sender, subject, headers, attachment type, or body text, and apply an action like "add more recipients" pointing at receipts@expensify.com. Useful when the sender is shared but only invoices matter.

Pros: no per-user verification handshake, centralised policy management, propagates automatically to every user in the Workspace domain, can scope to a shared billing alias or an entire department. Cons: it requires admin access you may not have, changes take up to about 20 minutes to propagate, and the matching syntax is substring- and regex-based rather than semantic — so a routing rule for subject:invoice will happily forward the marketing email whose subject line is "Invoice your friends for a free month".

Corporate IT note: routing rules are considered a mail compliance control and usually require a change ticket. Expect your IT team to ask who owns receipts@expensify.com, whether a compliance footer is required, and whether the rule needs logging. Budget a week, not an afternoon.

Crucially, like every Gmail-native method: routing rules only apply to new mail going forward. They do not retroactively forward the 2,000 invoices already in everyone's inbox. For that, keep reading.

6. Method D — Apps Script and Gmail API

Method D is the DIY developer option. You write a Google Apps Script that uses GmailApp.search() to find matching messages and MailApp.sendEmail() (or GmailMessage.forward()) to push them to receipts@expensify.com. A time-driven trigger runs the script every 5, 10, 15, 30, or 60 minutes. No verification handshake required — the script sends as you, from your own mailbox, so Expensify sees an authenticated login as the sender.

Sketch of the script (illustrative, not production)

function forwardReceipts() {
  var query = 'label:unprocessed has:attachment ' +
              '(subject:invoice OR subject:receipt)';
  var threads = GmailApp.search(query, 0, 20);
  threads.forEach(function (thread) {
    thread.getMessages().forEach(function (msg) {
      msg.forward('receipts@expensify.com');
    });
    thread.removeLabel(GmailApp.getUserLabelByName('unprocessed'));
    thread.addLabel(GmailApp.getUserLabelByName('sent-to-expensify'));
  });
}

Pros: works on personal Gmail (unlike Method C), can handle both ongoing forwards and — with a widened query and a higher batch size — a bounded historical backfill, and costs nothing if you stay inside Google's free quotas. Cons: you are now a script maintainer. When Google deprecates a method, or a vendor changes its subject format, or you hit a quota, the script stops silently.

Quota warning: consumer Gmail gives Apps Script roughly 100 MailApp.sendEmail() recipients per day; Google Workspace gives most plans around 1,500. Each forwarded receipt counts as one recipient, subject to Google's current published quota. That is fine for day-to-day forwarding; it is a serious limitation for backfilling three years of invoices in one pass. You will have to resume across multiple days if the historical queue is big.

The Gmail API route (instead of Apps Script) gives you finer control and cleaner OAuth scopes (gmail.send, gmail.readonly), but the quota and maintenance picture is the same. Method D is a solid fit if you already write code for a living and genuinely enjoy owning one more tiny system. For everyone else, skip to Method E.

7. Method E — Inbox-aware tools (Expensent)

Method E is the practical answer for almost everyone who landed on this page. It's an inbox-aware tool that connects to Gmail via OAuth — not through a Gmail filter — so the verification trap from Method B simply doesn't apply, and the backfill problem that Methods A–D cannot solve becomes a single scan through your history. Expensent is the tool we build; the rest of this section is specific to it.

How Expensent connects Gmail to Expensify

  1. 1.OAuth into your Gmail account (personal @gmail.com or Google Workspace). No app password, no filter, no admin ticket. 5-minute setup.
  2. 2.Paste receipts@expensify.com as the destination. Expensent forwards as you, from your own authenticated address, so SmartScan attaches the expense to your Expensify account.
  3. 3.Review what it found in the dashboard — grouped by status: ready to forward (has a PDF attachment), portal download (the invoice lives on the vendor's website), needs review, false positive.
  4. 4.Forward any invoice with one click, or create a rule for a specific email + subject pattern so the next invoice like it goes through automatically.
  5. 5.Backfill in one pass — point Expensent at the last three years of Gmail and let it work through history. No Apps Script quota to ration across days.

Pros: sidesteps the verification trap, works on personal Gmail and Workspace identically, handles backfill (the one thing none of Methods A–D can do well), one-click rule creation from a real example, no scripts to maintain. Cons: it's a third-party tool, it's paid, and it asks for a Gmail OAuth scope to read and send mail on your behalf — the usual trade-off for any OAuth-based inbox tool.

If you want to go deeper, the Expensify integration page walks through the feature set, and our sibling guide on never missing a receipt in Expensify covers the longer-term habit side of the problem.

8. Which method for which user

Side-by-side, across the five methods:

MethodPersonal GmailWorkspaceOngoingBackfillSetup
A. Manual forwardYesYesManual onlyOne by oneNone
B. Gmail filtersBlocked (verification)Blocked (verification)———
C. Workspace routingNoYes (admin)AutomaticNo~20 min + IT
D. Apps ScriptYesYesEvery 5–60 minQuota-limitedDeveloper
E. ExpensentYesYesAutomaticYears in one pass5 minutes

Personal Gmail vs. Google Workspace in one line: personal Gmail users have Methods A, D, and E available; Workspace users also get Method C, but only if they have admin access or a friendly admin to file a ticket with. Method B is a dead end for everyone.

9. Backfilling years of historical receipts

Backfill is the job Gmail itself refuses to do. Filters and routing rules only act on incoming mail; they will not go back and re-send messages you received last year. If you just signed up for Expensify and want the last 24–36 months of receipts to actually live there, here are the realistic options in order of effort.

Step 1 — Find the receipts with a Gmail search

Start with a query like this in the Gmail search box. Tune it for your own senders.

has:attachment filename:pdf
(subject:(invoice OR receipt OR "order confirmation")
  OR from:(billing@ OR invoices@ OR receipts@))
newer_than:3y

Refine until the result set looks mostly like actual receipts. Then you have a choice about how to get them to Expensify.

Step 2 — Pick a backfill method

  • •Manual — works, but at one forward every ~5 seconds, 500 receipts is about 40 minutes of repetitive clicking. Doable for an evening, painful for years of history.
  • •Apps Script — can iterate your saved search in batches, but Google's daily send quota (~100 on consumer Gmail, ~1,500 on Workspace) forces you to spread the backfill across days. Good for small backfills, bad for big ones.
  • •Inbox-aware tool (Expensent) — not bound by Gmail's Apps Script quota, de-duplicates receipts across threads, lets you review candidates before forwarding, and is the only option that pairs backfill with ongoing forwarding out of the box.
  • •Hybrid — use the tool for the last three years of backfill, then set up a Workspace routing rule for ongoing mail if your company already depends on admin-managed routing.

Whichever method you pick, do the backfill first, then switch on ongoing forwarding second. If you reverse the order, the tool will forward an invoice while it's also being backfilled, and you'll end up chasing duplicates in Expensify. Related reading: SmartScan troubleshooting for when backfilled receipts come through with missing data, and Expensify for accountants if you're doing this on behalf of a client rather than yourself.

10. Troubleshooting Gmail-specific quirks

Forwarded receipt arrives without the PDF attachment

Cause: Gmail sometimes strips attachments when you forward inline instead of "as attachment," particularly on mobile. Fix: use the desktop web client and choose "Forward" (not "Forward as attachment") — Expensify's SmartScan actually prefers inline HTML plus the original PDF, which the desktop client preserves.

"Message clipped — view entire message"

Cause: Gmail truncates very long HTML bodies (>102 KB) in the web view, and some forwards include only the visible portion. Fix: open the original message, click "view entire message" once to expand, then forward — or attach the receipt PDF directly instead of relying on inline HTML.

Receipt lands in Gmail's Promotions tab and gets missed

Cause: Gmail's Categories classifier is not invoice-aware and regularly routes legitimate receipts to Promotions. Fix: either turn off Category tabs entirely (Settings → Inbox → Categories), or create a Gmail filter matching the vendor and set "Never send it to Spam" plus "Categorize as: Primary." Filters can still categorize — they just can't forward to an unverified address.

Expensify returns "unrecognized sender"

Cause: the forward was sent from a Gmail alias, a delegated mailbox, or a Workspace send-as identity that is not registered on your Expensify account. Fix: open Expensify → Account Settings → Contact Methods and add the sending address as a secondary login. Verify it, then re-forward.

11. Frequently Asked Questions

Can I forward historical Gmail receipts to Expensify in bulk?
Not with any native Gmail feature. Gmail filters and Workspace routing rules only act on new mail going forward — they cannot retroactively forward a message that already sits in your inbox. Your options for backfill are: (1) manually forward each matching email from a Gmail search (slow), (2) write a Google Apps Script that iterates GmailApp.search() results and calls MailApp.sendEmail() until your daily quota runs out, or (3) use an inbox-aware tool like Expensent that connects via OAuth and can work through years of history in a single scan. Backfill is the single biggest gap in the native Gmail toolkit.
Why won't Gmail let me add receipts@expensify.com as a forwarding address?
Gmail's Settings → Forwarding and POP/IMAP flow requires you to add a destination address and then confirm a code that Gmail emails to that destination. receipts@expensify.com is an ingestion endpoint — it accepts mail but there is no human inbox you can log in to in order to retrieve the verification code. That is why the forwarding setup fails at the confirmation step. The same restriction applies to any Gmail filter whose action is "Forward it to" — Gmail only lets you pick from addresses that have already been verified.
Do Google Workspace routing rules require admin access?
Yes. Recipient and content compliance rules live under Admin Console → Apps → Google Workspace → Gmail → Routing, and only Workspace super admins or delegated Gmail admins can create them. They do not require each user to verify the destination, which is why they sidestep the receipts@expensify.com verification trap. Personal @gmail.com accounts have no admin console and cannot use this approach at all — you will need one of the other four methods in this guide.
What Gmail search operators find invoice and receipt emails?
A good starting query is has:attachment filename:pdf (invoice OR receipt OR "order confirmation" OR statement) newer_than:3y. You can tighten it with from: clauses for known billing senders (for example from:(stripe.com OR paypal.com OR intuit.com)), or widen it with subject:(invoice OR receipt). Save the query as a Gmail search URL so you can re-run it before each backfill pass. Keep in mind that these operators search Gmail, not Expensify — you still have to get the matching messages into receipts@expensify.com somehow.
Does Gmail's "Promotions" tab block receipts from reaching Expensify?
Not directly. Gmail's Category tabs (Primary, Promotions, Updates, etc.) are purely a display grouping in the Gmail UI — they do not change what filters, routing rules, or OAuth-connected apps can see. An Apps Script using GmailApp.search() or an inbox-aware tool using the Gmail API will read messages regardless of which tab they land in. The only time tabs matter is when you are manually forwarding and simply do not notice a receipt because it was routed to Promotions. A quick fix is to create a filter that marks receipts as Primary.
Will Expensify accept receipts forwarded from a Gmail alias (+tag) address?
Expensify identifies the sender by the authenticated envelope address, so forwards from user+receipts@gmail.com will only be accepted if user+receipts@gmail.com is registered as a login or secondary login on your Expensify account. The simpler pattern is to register your base address (user@gmail.com) and forward from that. If you rely on plus-addressing to segment work from personal mail, add the plus variant as a secondary login in Account Settings → Contact Methods before you start forwarding.
Does auto-forwarding break SPF/DKIM in a way Expensify cares about?
When Gmail auto-forwards a message, the envelope sender is rewritten, which can cause SPF to fail at Expensify's inbound MTA for the original vendor domain. DKIM signatures on the original message usually survive because the body is not modified, and ARC headers are added by Gmail. In practice, Expensify treats forwards from a verified user login as authenticated, so SPF failure on the original vendor domain does not block ingestion. Where it can matter is duplicate detection — if the same receipt arrives via both the vendor and your forward, Expensify may create two expense records.
Can I forward from a delegated Gmail mailbox to Expensify?
Gmail delegation (Settings → Accounts → Grant access to your account) lets a delegate read and send mail on behalf of the owner, including forwarding. The forwarded message is sent from the owner's address, so Expensify will attribute the receipt to the owner's login, not the delegate's. If you want the delegate (for example, an external bookkeeper) to be the submitter, use Expensify's Copilot feature instead: the delegate forwards from their own verified address and puts the owner's email in the subject line.
What's the daily email quota for a Gmail Apps Script forwarder?
Google publishes a MailApp.sendEmail() daily quota of 100 recipients per day for consumer @gmail.com accounts and 1,500 recipients per day for most Google Workspace plans, subject to Google's current documented limits. An Apps Script that forwards every receipt counts against that quota one recipient at a time, so a busy inbox on a consumer account can hit the ceiling quickly. Quotas reset on a rolling 24-hour window. If your backfill exceeds the quota, the script throws an exception mid-run and you will need to resume the next day — which is why scripts are not a great fit for bulk historical imports.
How do I stop forwarding a vendor once I've set up a rule?
It depends on which method you picked. For Gmail filters, open Settings → Filters and Blocked Addresses and delete the filter. For Google Workspace routing, open Admin Console → Apps → Gmail → Routing and remove the rule (allow ~20 minutes for propagation). For an Apps Script, disable or delete the time-driven trigger in the script editor. For Expensent, open the forwarding rule in the dashboard and delete or pause it — the next invoice from that vendor stops being forwarded immediately.

Skip the Gmail verification trap entirely

Connect Gmail to Expensent in 5 minutes. Forward any invoice with one click, create a rule so the next one goes through automatically, and backfill years of old receipts in a single pass — no filters, no Apps Script, no admin ticket.

Get Started

Works with personal Gmail and Google Workspace. See pricing.

Expensent
Expensent

Finds your invoices. Forwards them your way.

ProductPricingIntegrationsHow it WorksComparevs Manual Forwardingvs Gmail Filters
Works WithExpensifyQuickBooksXeroFreshBooksZoho ExpenseSAP ConcurWaveRampBILL.comDext
Guides
QuickBooksExpensifyXeroFreshBooksBrexRampSAP ConcurDextBILL.comWaveZoho ExpenseDivvyEmburseHubdocPleoRydooRevolut Business
CompanyAbout UsContactHelp CenterPrivacy PolicyTerms of ServiceLegal Information

© 2025–2026 Expensent. All rights reserved.

Stripe Climate badgeExpensent contributes a portion of revenue to remove CO2 from the atmosphere.