The complete walkthrough
From a .olm file on your desk to a Gmail full of correctly-dated, labeled mail. Hands-on time: about 15 minutes. Elapsed time: depends on archive size — budget an evening for 10,000+ messages.
Step 0 — What you need
- Your
.olmarchive (Outlook for Mac: File → Export) — plus that backup copy - A Google account — free Gmail and Google Workspace both work
- The OLM to Gmail app — see the Download link above (downloads open soon)
Step 1 — Scan and convert
Open the app and point it at your .olm. The Scan step shows you what's inside — every folder and its message count — before anything happens. Then Convert: everything Outlook exported becomes standard mailbox files in an output folder you choose, one file per folder, each message tagged with the Gmail label it should receive. The .olm itself is only ever read, never modified. Junk and Deleted Items stay behind unless you tick the box to include them, and the app refuses to overwrite an earlier conversion unless you explicitly allow it.
Step 2 — The one-time Google setup (the four annoying minutes)
Why: Google gates full-mailbox access behind "restricted scope" rules. A shipped app with a shared key would need Google's paid security audit — instead, you create your own tiny Google Cloud project and authorize only yourself. Nobody else's credentials are ever involved.
- Go to console.cloud.google.com, signed in with the same account that owns the destination Gmail.
- Top bar → project selector → New project → name it anything ("Mail Import") → Create → make sure it's selected.
- Search bar → "Gmail API" → Enable.
- Search bar → "OAuth consent screen" (a.k.a. Google Auth Platform):
- Workspace accounts: choose Internal. Done.
- Personal @gmail.com: choose External, fill the two required fields, and under Test users add your own address. Testing mode allows you — and only you — with no verification process.
- Credentials (Clients) → Create OAuth client ID → Application type: Desktop app → Create → Download JSON.
- In the app's Connect step, pick the JSON file you just downloaded. It stays on your computer.
Step 3 — Upload
Click Upload. Your browser opens once — sign in, approve the two Gmail permissions, done. The app then:
- creates your label tree ("My Archive/Inbox", "My Archive/Taxes", …)
- imports each message with its true date — the original send date, not today's
- never marks anything as spam, and retries rate-limits automatically
- journals progress — close the app and re-run anytime; finished messages skip, failed messages retry
Step 4 — Verify like you mean it
- Start with the numbers: Gmail's label counts should match the folder counts
in
manifest.jsonin your output folder — chase down any gap - Then check your mail — every message you'd miss, not a sample. Work through each label: dates filed under the years they actually happened, contents that open, attachments that download
- Search
before:2015 label:my-archive— your history should appear, dated correctly - Skips on huge or malformed relics are reported, never silent — those messages
stay in your .olm forever, and
errors.jsonlin your output folder names each one; re-running the upload retries them - Messages with no parseable date are filed under Jan 1990 and counted as
dates_defaultedin manifest.json — searchbefore:1991to review them - Delete nothing — not the .olm, not the old mailbox — until every message you need is verified in Gmail
Troubleshooting
- "Access blocked" at OAuth → consent screen: you forgot to add yourself as a test user (External), or you're signed into the wrong account.
- 400 Invalid attachment → Gmail's virus scanner refused that message's attachment (often an ancient .zip or .exe). Skipped by design, listed in errors.jsonl.
- Everything dated today?! → you uploaded via an IMAP client instead of this tool. That's the exact disease this project cures.