How to Answer Customer Emails Using a Knowledge Base With Human Review

Build a Spojit workflow where an inbound customer email is answered from your own Knowledge collection, a teammate reviews and approves the drafted reply, and Resend sends it from your own domain.

What This Integration Does

Support teams answer the same questions over and over, and the answers already live in your help docs, policy pages, and past replies. This workflow turns that material into a self-serve answering pipeline: when a customer emails you, Spojit reads the question, queries a Knowledge collection built from your documents, and drafts a grounded reply. Because the answer goes to a customer, a Human approval step puts a person in the loop before anything is sent, so you get the speed of an automated draft with the safety of a real review.

The workflow is triggered by an Email trigger that polls a connected Gmail mailbox. Each new message starts one run. The question text flows into a Knowledge Query, the drafted answer is held by a Human node until an approver acts, and only on approval does the Resend connector send the reply. If the approver rejects or the request times out, the run halts and nothing is sent. Runs are independent: every email gets its own draft and its own approval, and re-running never re-sends an already-handled message because each poll only picks up new mail.

Prerequisites

  • A Gmail mailbox connected as an Email trigger source. Add it under Connections -> Add connection -> Gmail (trigger) (OAuth, read-only is enough for this workflow).
  • A Resend connection with a verified sending domain, added under Connections -> Add connection. You need the domain verified so replies send from your own address.
  • A persistent Knowledge collection that already contains your support material (help articles, policies, FAQs). Create it in the Knowledge section of the sidebar and upload documents with Upload & Embed before building this workflow.
  • At least one teammate (or yourself) to act as an approver, plus the recipient domains you reply to allowed where required by your workspace.

Step 1: Add the Email trigger

Add a Trigger node and set its type to Email. Choose your connected Gmail mailbox and the folder to watch (typically the inbox), then set a poll interval (1 to 60 minutes, default 2). To keep the workflow focused on real questions, set an optional Subject regex or a From allowlist. The trigger output gives you the fields you will use downstream, including {{ input.from }}, {{ input.subject }}, {{ input.textBody }}, and {{ input.conversationId }}. The customer question for this workflow is {{ input.textBody }} (the plain-text body), with {{ input.subject }} as helpful context.

Step 2: Query your Knowledge collection

Add a Knowledge node and set its mode to Query. Pick your persistent support Collection (not Transient, since the knowledge is long-lived and shared across workflows). In Prompt, combine the subject and body so the query has full context, and instruct the model to answer only from retrieved material:

You are answering a customer support email. Write a clear, friendly reply
that answers the question using ONLY the information in the retrieved
documents. If the documents do not cover the question, say that a human
will follow up and do not guess.

Subject: {{ input.subject }}
Question: {{ input.textBody }}

Set Result Count to control how many document chunks are retrieved (default 5; raise it for broad questions). Pick the Model used for synthesis. To make the result easy to use downstream, add a Response Schema so the node returns structured output instead of free text:

{
  "type": "object",
  "properties": {
    "answer": { "type": "string" },
    "answered_from_docs": { "type": "boolean" }
  },
  "required": ["answer", "answered_from_docs"]
}

Set the Output Variable to kb. You can then reference the drafted answer as {{ kb.answer }} and the confidence flag as {{ kb.answered_from_docs }}.

Step 3: Gate on whether the docs covered the question

Add a Condition node to branch on {{ kb.answered_from_docs }}. Send the true branch into the review step below. Use the false branch for questions your Knowledge base could not answer: connect it to a Send Email node that quietly notifies your support inbox that a message needs a manual reply, so unanswered questions are never silently dropped. This keeps the automated path limited to questions you can actually answer well.

Step 4: Require human approval before sending

On the true branch, add a Human node so a person reviews the draft before it reaches the customer. Set a Label like Approve support reply and a Message that shows the reviewer exactly what will go out, using upstream variables:

Customer: {{ input.from }}
Subject: {{ input.subject }}

Drafted reply:
{{ kb.answer }}

Set a Timeout (minutes) so a stale request does not block forever (a timeout is treated as a reject and halts the run). Configure the Notification title and Notification body (both support {{ variables }}), set Urgency, and turn on Email approvers if you want reviewers emailed directly. In Approval slots, add at least one slot with a User, Role, or Team atom; approval completes only when every slot is satisfied. Reviewers act in the Approvals inbox at /approvals. On approval the node outputs { approved: true, approvalId, outcome: "APPROVED" } and the run continues; on rejection or timeout the run halts and no reply is sent.

Step 5: Send the approved reply with Resend

After the Human node, add a Connector node for Resend in Direct mode and select the send-email tool. Map the fields so the reply goes back to the original sender from your verified domain:

from:    support@yourdomain.com
to:      {{ input.from }}
subject: Re: {{ input.subject }}
text:    {{ kb.answer }}

Use a from address on the domain you verified on your Resend connection. Reference the approved draft with {{ kb.answer }} and reply on the original thread by prefixing the subject with Re:. Direct mode is the right choice here: it is a single, predictable tool call with no AI cost. If you later want a batch path (for example, sending the same answer to several recipients), Resend also exposes send-batch-emails.

Step 6: Confirm internally (optional)

Add a Send Email node after the Resend step to post a short internal confirmation to your team that a reply was approved and sent. Set Recipients to your support distribution list, a templated Subject like Reply sent to {{ input.from }}, and a Body echoing the answer. Send Email uses Spojit's built-in mail service and needs no connection, which keeps the internal note separate from the customer-facing Resend send. Set If sending fails to Continue anyway so a failed internal note never blocks the workflow.

Tips

  • Always embed and query the same collection with the same embedding model. If retrieval feels off, check that the documents in the collection cover the questions you actually receive, and raise Result Count for broad topics.
  • Keep the Knowledge Prompt strict about answering only from retrieved documents and saying so when coverage is missing. The answered_from_docs flag in the Response Schema is what powers your Condition gate.
  • Use the Human node Message to show the full draft inline so reviewers can approve without leaving the Approvals inbox. Set a sensible Timeout so off-hours questions do not stall indefinitely.
  • Ask Miraxa, the intelligent layer across your automation, to scaffold this for you: "Build a workflow with an Email trigger that queries a Knowledge collection, pauses on a Human node, then sends the reply with the Resend send-email tool." Then fine-tune each node in the properties panel.

Common Pitfalls

  • Sending from an unverified domain. The Resend from address must be on a domain verified on your connection, or the send is rejected. Verify the domain before going live.
  • Forgetting that a rejected or timed-out Human approval halts the run. There is no "on reject do X" branch downstream, so handle missed reviews with a sensible timeout and an internal notification rather than expecting the workflow to continue.
  • Querying the wrong collection or an empty one. A persistent collection with no relevant documents returns weak answers; confirm documents show status READY before relying on them.
  • Poll interval expectations. The Email trigger checks for new mail on a schedule (default every 2 minutes), so replies are near-real-time but not instant. Tighten the interval only as far as you need.

Testing

Before turning the workflow on, narrow the Email trigger with a Subject regex (for example, a temporary test tag) or a From allowlist containing only your own address, then send yourself a question your Knowledge collection can answer. Watch the run in execution history: confirm the Knowledge node returns a sensible {{ kb.answer }}, that the Human node appears in the Approvals inbox, and that approving it sends a Resend email to the right address from your verified domain. Reject one run to confirm it halts cleanly without sending. Once the path is reliable, widen the trigger filters to your real support traffic.

Learn More

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.