How to Auto-Index Emailed Policy Updates for AI Q&A with a Mailhook
Forward policy update emails to a Spojit mailhook so each attached PDF is embedded into a persistent Knowledge collection that staff can later query with AI.
What This Integration Does
Compliance, HR, and operations teams receive policy updates as emailed PDFs from vendors, regulators, or internal owners. Filing them by hand means the latest version is often buried in someone's inbox when a colleague needs an answer. This workflow gives every policy email a single destination: a unique mailhook address. The moment a policy PDF lands there, Spojit pulls the document bytes, embeds the text into a long-lived Knowledge collection, and confirms in Slack that the policy is now searchable. Staff then ask plain-language questions and Miraxa, the intelligent layer across your automation, answers from the indexed documents.
The run model is push-based and asynchronous. A new email to the mailhook address starts a run within seconds (no mailbox or OAuth needed). The Attachment node fetches the PDF bytes referenced by the trigger, a Knowledge node in Embed mode writes them into a persistent, workspace-scoped collection (overwriting the prior version when the file name matches), and a Slack message confirms the update. The collection is the durable state: it survives across runs and is readable by any other workflow that queries it. Re-sending the same policy file re-embeds and overwrites the existing entry, so the collection always reflects the most recent version.
Prerequisites
- A Spojit workspace where you can create workflows and manage the Knowledge section in the sidebar.
- A persistent Knowledge collection created ahead of time (see Step 1). Note the fixed embedding model chosen at creation:
Gemini Embedding 001orText Embedding 004. - A Slack connection added under Connections, with a channel (for example
#policy-updates) where confirmations should post. - Policy senders (vendors, regulators, internal owners) who can send to, or be forwarded to, a Spojit mailhook address. Decide whether you will restrict senders with a From allowlist.
- Policy updates that arrive as PDF attachments under 10 MB each (the per-attachment default limit).
Step 1: Create the persistent Knowledge collection
Open the Knowledge section in the sidebar and choose New Collection. Give it a clear name such as company-policies and an optional description. The embedding model is fixed at creation, so pick the one you will use everywhere: Gemini Embedding 001 (3072 dims) is the default. Save the collection. You can leave it empty for now; the workflow will populate it. This collection is persistent and workspace-scoped, which means any workflow (including a separate staff-facing Q&A workflow) can query it later. Always query a collection with the same embedding model it was embedded with.
Step 2: Add a Mailhook trigger and generate the address
Create a new workflow and open the Trigger node. Set Trigger Type to Mailhook. Optionally set an Address prefix (1 to 24 characters, default mh); something like policies makes the address recognizable. Choose Generate email address. Spojit produces a unique address in the form policies-<random16>@mailhook.spojit.com. Copy it and point your policy senders at it, or add a forwarding rule from an existing mailbox. To narrow what starts a run, set an optional From allowlist (only listed senders fire the workflow) and an optional Subject regex (for example (?i)policy|handbook|compliance). The trigger fires whether the address is in To, Cc, or Bcc, and duplicate messages are de-duplicated automatically. The trigger output is available as {{ input }}, including {{ input.subject }}, {{ input.from }}, {{ input.replyTo }}, and {{ input.attachments }}.
Step 3: Fetch the policy PDF with an Attachment node
Add an Attachment node after the trigger. This node only saves inside a Mailhook workflow, and it pulls the actual bytes of attachments the trigger referenced. Set Mode to Single so you receive the first matching file as a single object. Restrict to PDFs with Content type set to application/pdf and a Filename pattern of *.pdf. Turn on Fail if no attachment matches so a non-PDF email does not silently embed nothing. The node outputs:
{
"filename": "employee-handbook-2026.pdf",
"contentType": "application/pdf",
"size": 482133,
"content": "<base64 bytes>"
}
You will feed {{ attachment.content }} straight into the Knowledge node in the next step. Keep individual files under the 10 MB per-attachment limit and the 25 MB per-run limit.
Step 4: Embed the document into the collection
Add a Knowledge node and set its mode to Embed. Configure the fields:
- Collection: choose the persistent
company-policiescollection from Step 1 (not Transient, because you want this to last). - File Name: a stable, deterministic name so re-sends overwrite the prior version rather than piling up duplicates. Use the email subject or attachment filename, for example
{{ attachment.filename }}. - Document Type:
PDF. - Document Input:
{{ attachment.content }}(the base64 reference from the Attachment node). - Output Variable: name it
embedResultso you can reference the resulting chunk count downstream.
On save, Spojit splits the PDF into chunks and embeds them with the collection's fixed model. Because File Name is deterministic, sending an updated handbook with the same filename overwrites the existing document in place, keeping the collection current.
Step 5: Confirm the update in Slack
Add a Connector node in Direct mode, choose your Slack connection, and pick the send-message tool. This is a single, predictable call, so Direct mode keeps it deterministic with no AI cost. Map the channel (for example #policy-updates) and compose a templated message that pulls in upstream variables:
Policy indexed: {{ attachment.filename }}
From: {{ input.from }}
Subject: {{ input.subject }}
Chunks embedded: {{ embedResult.chunkCount }}
This policy is now searchable in the company-policies collection.
Because the mailhook is asynchronous and sends no reply to the original sender, this Slack confirmation is how your team learns the policy is live. If you also want to email the person who forwarded the update, add a Send Email node addressed to {{ input.replyTo }}.
Step 6: Let staff query the collection with AI
Indexing is only half the job; staff need to ask questions. Build a second, separate workflow (or extend this one with a different trigger) that uses a Knowledge node in Query mode against the same company-policies collection. Set the Prompt to the staff question, for example {{ input.question }}, keep Result Count at the default 5, and choose a synthesis Model. To return clean structured output to a chat surface or another system, add a Response Schema. Point the Output Variable at the answer and surface it however your team prefers (a Slack reply, an email, or a Response node for a synchronous caller). Staff can also simply ask Miraxa, the intelligent layer across your automation, questions about a policy in context once the documents are indexed.
Step 7: Optional human review before publishing sensitive policies
For policies that need sign-off before they become answerable (for example legal or safety documents), insert a Human node between the Attachment node and the Knowledge Embed node. Set an approval slot, a clear Message referencing {{ attachment.filename }}, and an optional Timeout (minutes). Approvers act in the Approvals inbox; on approval the run continues to the Embed step, and on reject the run halts so the document is never indexed. If you reuse the same review-and-notify logic across several workflows, factor it into a Subworkflow node and call it from each.
Tips
- Use a deterministic File Name in the Embed node so updated versions overwrite the old one instead of accumulating stale duplicates in the collection.
- Keep one embedding model for the lifetime of the collection. Mixing models between embed and query degrades results, and the model is fixed at collection creation for exactly this reason.
- Add a Subject regex on the Mailhook trigger so newsletters and replies that reach the address do not start unnecessary runs.
- If senders sometimes attach multiple PDFs, switch the Attachment node to
Multiplemode and wrap the Embed node in a Loop over{{ attachment.attachments }}, embedding each file with its own filename.
Common Pitfalls
- Saving an Attachment node in a workflow without a Mailhook trigger fails; the designer requires the Mailhook trigger for attachment fetching.
- Forgetting Fail if no attachment matches means a policy email with no PDF (or a wrong content type) embeds nothing and passes silently. Turn it on so the run errors visibly.
- Received emails are retained for 30 days and each attachment is capped at 10 MB (25 MB per run by default). Very large policy packs may need to be split before sending.
- Choosing Transient instead of a persistent collection in the Embed node discards the documents when the run completes, so nothing is searchable afterward. Use Transient only for one-off embed-then-query-in-the-same-run cases.
- Regenerating the mailhook address kills the old one instantly. If you rotate it, update every sender and forwarding rule or new policies will bounce.
Testing
Before announcing the address widely, send a single sample policy PDF to the mailhook from an allowed sender. Open the workflow's execution history and confirm the Attachment node returned a non-zero size and the Knowledge Embed node produced a chunk count in embedResult. Open the company-policies collection in the Knowledge section and check that the document appears with status READY. Then run the Query workflow with a question you know the answer to, like "What is the maximum carry-over leave?", and verify the response cites the right document. Once a small batch behaves correctly, distribute the mailhook address to your policy senders.
Learn More
- Mailhook trigger reference
- Attachment node reference
- Knowledge collections and RAG
- Slack connector reference
- How to Use RAG to Answer Questions from Company Documents
- How to Build a Policy Lookup System for Approval Workflows
- Querying Your Knowledge Base
- How to Auto-Index Incoming Emails into Your Knowledge Base