PDF extraction
How to build Gmail PDF email intake with an API
Watch Gmail for PDF attachments, send them to okraPDF, and route extracted rows into Sheets, Slack, Airtable, or your app.
Email intake is the most common document ingestion path. Vendors send invoices. Customers send forms. Brokers send statements. The workflow starts when a PDF lands in an inbox, not when a user opens a dashboard.
This is API-feasible today, but it has real permission work. The Gmail API users.watch method can set up mailbox push notifications, and Google’s Gmail push notification guide uses Cloud Pub/Sub to deliver mailbox changes to your backend. Gmail scopes that read message bodies or attachments are restricted Google Workspace scopes, so a public SaaS integration needs OAuth verification and careful scope minimization.
Pick the intake model
There are three practical models.
| Model | Best for | Tradeoff |
|---|---|---|
| Forwarding to an okraPDF inbox | Fastest production setup | Uses email forwarding rules, not Gmail OAuth |
| Zapier, Make, or n8n Gmail trigger | No-code workflows | Depends on automation platform limits |
| Direct Gmail API watch | Product-grade native integration | Requires OAuth verification and Pub/Sub |
If you need a customer-facing Gmail connector, plan for the direct API path. If you need the workflow working this week, use forwarding or an automation platform.
Direct Gmail API architecture
The direct path looks like this:
- User connects Gmail with OAuth.
- Your app stores refresh tokens securely.
- Your backend calls
users.watchfor the mailbox or label. - Gmail publishes notifications to a Cloud Pub/Sub topic.
- Your worker receives the Pub/Sub push.
- Your worker calls Gmail to list changes since the last history ID.
- Your worker downloads PDF attachments.
- Your worker uploads each PDF to okraPDF.
- okraPDF sends
document.processedwhen extraction is ready. - Your app writes rows to Sheets, CRM, Slack, or an internal database.
The watch notification tells you something changed. It is not the attachment itself. You still need to fetch the message and attachment through Gmail.
Use labels aggressively
Do not watch an entire mailbox unless you must. A better production pattern is:
- Create a Gmail label such as
okraPDF/Intake. - Ask the user to create a filter that applies the label to relevant messages.
- Watch that label.
- Store the Gmail message ID and attachment ID with the okraPDF document ID.
This reduces noise, limits accidental ingestion, and makes debugging much easier.
Attachment filtering
Only send real PDFs into okraPDF.
Check:
- MIME type is
application/pdf - Filename ends in
.pdf - Attachment size is within your upload limits
- The message is not already processed
- The sender or recipient matches the intended intake rule
Use message ID plus attachment ID as your idempotency key. Email systems retry, users forward the same file, and Pub/Sub can redeliver messages.
No-code Gmail setup
For Zapier:
- Trigger: Gmail New Attachment.
- Filter: attachment filename ends with
.pdf. - Action: okraPDF Upload PDF.
- Second Zap trigger: okraPDF PDF Ready.
- Destination: Google Sheets, Slack, Airtable, or CRM.
For Make or n8n, use the same shape: Gmail trigger, filter PDF attachments, HTTP upload to okraPDF, then receive the okraPDF ready event.
Security and compliance
Gmail intake touches sensitive mailbox data. Use least-privilege scopes, store tokens encrypted, let users disconnect, and delete mailbox-derived data when it is no longer needed. Separate message metadata from attachment payloads in storage so deletion and audit are straightforward.
For many teams, an okraPDF-generated inbound email address is safer than Gmail OAuth. The user forwards only the messages they want processed, and okraPDF never receives broad mailbox access.
Failure handling
Create a failure queue with:
- Gmail message ID
- Sender
- Subject
- Attachment filename
- Failure reason
- okraPDF document ID if upload succeeded
Do not silently drop non-PDF attachments. Mark them skipped. The difference between skipped, uploaded, processed, and failed is what keeps an email intake workflow supportable.