Skip to content

Email-to-Vault gateway

Email-to-Vault gateway

Forward client correspondence to a per-matter address and Pollen8 parses + indexes it into the Vault automatically.

Routing format

matter-<MATTER_NUMBER>@vault.<tenant_slug>.pollen8.ai
matter-<MATTER_NUMBER>+<TAG>@vault.<tenant_slug>.pollen8.ai

Example:

matter-2024-MA-031@vault.acme.pollen8.ai
matter-2024-MA-031+exhibit@vault.acme.pollen8.ai
  • <MATTER_NUMBER> matches Matter.matter_number within the tenant.
  • <TAG> (optional) is appended to the Vault doc’s tags array.
  • Wrong format / unknown matter / unknown tenant → email is dropped with skipped_reason set; nothing lands.

What gets created

  • One Vault doc per email body (subject + sender prepended as searchable headers), classification = correspondence, source = "email_gateway".
  • One Vault doc per attachment that yields text. PDFs + DOCX + XLSX run through the standard extractor; OCR’d PDFs get the ocr tag.
  • All children get source_matter_id set to the matched matter.

ACL mode defaults to open. If you want correspondence to be matter-team only, post-process the upload via the API or change the default by editing services/legal_email_gateway.py.

Infra setup

The gateway endpoint is POST /api/v1/legal/email-gateway/inbound with shared-secret bearer auth via POLLENIX_EMAIL_GATEWAY_SECRET. Wire it up by configuring your inbound-mail bus:

AWS SES → Lambda

  1. Verify the receiving domain in SES.
  2. Create an MX record pointing at SES.
  3. Create a Receipt Rule that triggers a Lambda on every inbound mail.
  4. Lambda parses the raw MIME (use mail-parser or the Python email module), base64-encodes attachments, and POSTs the normalized JSON to the gateway endpoint with the bearer secret.

SendGrid Inbound Parse

  1. Configure Inbound Parse with the receiving domain.
  2. Forward URL = the gateway endpoint.
  3. Use a small adapter (Cloudflare Worker or Lambda) to add the Bearer secret header and convert form-encoded multipart to JSON.

Mailgun Routes

Same pattern — adapter handles the format conversion + bearer auth.

Payload shape

{
"from": "opposing.counsel@example.com",
"to": "matter-2024-MA-031@vault.acme.pollen8.ai",
"subject": "Re: Section 8.2 redline",
"text": "Counsel, we agree with the redlined section…",
"html": "<p>…</p>",
"received_at": "2026-05-24T12:34:56Z",
"attachments": [
{
"filename": "redline-v3.docx",
"content_type": "application/vnd.openxmlformats-...wordprocessingml.document",
"content_base64": "UEsDBBQAAA..."
}
]
}

Max attachments per email: 20. Max base64 payload per attachment: ~80 MB. Beyond that, attachments are silently dropped.

Audit

Every gateway POST stamps last_event_at on the matched legal_vault_documents rows; failures get last_error. Replays are idempotent only by content — re-posting the same email creates new rows (no de-dup). Add idempotency keys at the forwarder layer if that matters for your traffic shape.