Gmail to Expensify: The Complete Workflow Guide
A Gmail-specific guide to what actually works with Expensify: manual forwards, the forwarding verification trap, Apps Script, Google Workspace routing caveats, and practical ways to deal with older receipts already buried in your inbox.
By ilios Galil · Founder, Expensent
Published March 27, 2026 · Updated April 22, 2026
In This Guide
- 1. The Gmail → Expensify problem: ongoing plus backfill
- 2. How Expensify receives mail (quick recap)
- 3. Method A — Manual forward
- 4. Method B — Gmail filters: the verification trap
- 5. Method C — Google Workspace routing rules
- 6. Method D — Apps Script and Gmail API
- 7. Method E — Inbox-aware tools
- 8. Which method for which user
- 9. Backfilling years of historical receipts
- 10. Troubleshooting Gmail-specific quirks
- 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.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.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 then reads the attached receipt or forwarded receipt content and turns it into an expense under the sender's account.
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.
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.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 forward-to-address filters.
- 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.
receipts@expensify.comis 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.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.
5. Method C — Google Workspace routing rules
If your Gmail account is actually a Google Workspace account, there is an admin-level mail-routing tool in the Admin Console. It matters enough to mention here, but it is not the clean native answer many people hope it is.
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.comon every message delivered tobilling@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 a Workspace admin wants to route invoice-like mail, but still not a guaranteed Expensify attribution fix.
The attraction is obvious: no per-user verification handshake, centralised policy management, and routing rules that can scope to a shared billing alias or an entire department. The catch is just as important: Google says routed or forwarded mail still appears to come from the original sender, while Expensify ties emailed receipts to linked sender addresses. That makes Workspace routing a mail admin tool, not a clean documented Expensify workaround. It also requires admin access you may not have, 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".
receipts@expensify.com, whether a compliance footer is required, and whether the rule needs logging. Also expect to test whether the routed message still lands correctly in Expensify under the right linked sender.Crucially, like every Gmail-native method, routing rules only apply to new mail going forward. They do not retroactively forward the old invoices already in everyone's inbox. Treat Method C as an admin caveat, not the main recommendation.
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.
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. It also gives you a cleaner way to review older inbox results than rebuilding filters or scripts from scratch. Expensent is the tool we build; the rest of this section is specific to it.
How Expensent connects Gmail to Expensify
- 1.OAuth into your Gmail account (personal
@gmail.comor Google Workspace). No app password, no filter, no admin ticket. - 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.Review what it found in the dashboard — grouped by next action: ready to forward, download from portal, needs review, false positive.
- 4.Forward any invoice with one click, or create a rule from an existing email in one click so the next invoice like it goes through automatically.
- 5.Backfill in one pass — pick a date range in Expensent (a few months, a year, or several years) 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:
| Method | Personal Gmail | Workspace | Ongoing | Backfill | Setup |
|---|---|---|---|---|---|
| A. Manual forward | Yes | Yes | Manual only | One by one | None |
| B. Gmail filters | Blocked (verification) | Blocked (verification) | — | — | — |
| C. Workspace routing | No | Yes (admin) | Automatic | No | Admin review |
| D. Apps Script | Yes | Yes | Every 5–60 min | Quota-limited | Developer |
| E. Expensent | Yes | Yes | Automatic | Historical review | Short setup |
Personal Gmail vs. Google Workspace in one line: personal Gmail users have Methods A, D, and E available. Workspace users can also test Method C with admin help, but it is a routing tool with sender-attribution caveats, not a clean documented Expensify fix. 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, skips messages it has already processed, 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 historical review and ongoing forwarding, or pair it with a custom script if you already maintain one.
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 original 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 → Settings → Account → Profile → 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?
Why won't Gmail let me add receipts@expensify.com as a forwarding address?
Do Google Workspace routing rules require admin access?
What Gmail search operators find invoice and receipt emails?
Does Gmail's "Promotions" tab block receipts from reaching Expensify?
Will Expensify accept receipts forwarded from a Gmail alias (+tag) address?
Does auto-forwarding break SPF/DKIM in a way Expensify cares about?
Can I forward from a delegated Gmail mailbox to Expensify?
What's the daily email quota for a Gmail Apps Script forwarder?
How do I stop forwarding a vendor once I've set up a rule?
Skip the Gmail verification trap entirely
Connect Gmail to Expensent. Forward any invoice with one click, create a rule so future similar emails go through automatically, and review older inbox results without relying on Gmail filters, Apps Script, or admin routing.
Get StartedWorks with personal Gmail and Google Workspace. See pricing.