How to Auto-Draft Cited Front Replies from Your Knowledge Base on a Webhook

When a new inbound message lands in Front, Spojit retrieves cited passages from your support knowledge collection, drafts a grounded reply with sources listed, holds it for a teammate to approve, then posts the reply back into the Front conversation.

What This Integration Does

Support agents spend most of their time re-explaining things your documentation already answers. This workflow turns each new inbound Front message into a ready-to-review draft that is backed by your own knowledge base. A Knowledge node finds the most relevant passages from your support collection, a Connector node in Agent mode writes a reply that quotes only those passages and lists its sources, and a teammate approves the wording before anything reaches the customer. Nothing is sent automatically, so you keep a human in the loop while cutting first-response time.

The run starts from a Webhook trigger. You register a Front application webhook subscription (using the http connector) that posts to your workflow URL whenever an inbound message is received. Spojit parses the JSON body, queries your knowledge collection, builds a structured draft (an answer plus a source list), pauses at a Human node, and only then calls Front to send the message. Each inbound message produces one execution; if the same event is delivered twice you can opt into deduplication on the trigger so a customer is never answered twice. Rejected drafts halt the run and send nothing.

Prerequisites

  • A Front connection in Spojit (API token), added under Connections. See the Front connector reference.
  • The Front channel ID you reply from, plus the inbox you want to watch. Use list-inboxes once to find them.
  • A persistent Knowledge collection holding your support documentation (help articles, macros, policy PDFs), already embedded. See Creating a Knowledge Collection and Uploading Documents to a Collection.
  • A Webhook signing connection so the trigger can verify inbound calls. Front does not sign with a built-in scheme, so use the Custom scheme. See Setting Up a Webhook Trigger.
  • A Front API token with permission to manage application webhooks (for Step 6), and at least one teammate or role to act as an approver.

Step 1: Receive the inbound message with a Webhook trigger

Add a Trigger node and set its type to Webhook. Spojit gives you a unique workflow URL and returns 202 with an executionId to every caller. Attach your Custom signing connection so unsigned or tampered calls are rejected, and turn on event-id deduplication using Front's delivery id header if you want replays ignored.

The trigger output is the parsed JSON body Front posts. A Front inbound message event exposes the conversation and the message text. Reference the fields you need downstream, for example {{ input.conversation.id }}, the sender handle, and the message body. If your payload nests the text differently, open the first execution log to confirm the exact path before wiring later steps.

Step 2: Pull the customer's question into a clean variable

Add a Transform node to isolate the question text and any context you want the draft to consider (subject line, prior message snippet). Produce a single field such as question so later nodes do not depend on the raw webhook shape. For example, map the inbound body and subject into:

{
  "question": "{{ input.subject }} - {{ input.body_text }}",
  "conversationId": "{{ input.conversation.id }}",
  "customerHandle": "{{ input.recipient }}"
}

If you need richer conversation context, add a Connector node on the front connector in Direct mode with the get-conversation tool, passing id as {{ transform.conversationId }}, and feed its result into the Transform.

Step 3: Retrieve cited passages with a Knowledge query

Add a Knowledge node in Query mode. Set Collection to your persistent support collection, set Prompt to the customer's question, and set Result Count to 5 so the draft has enough grounding without drowning in passages. Pick the Model for synthesis.

To get passages you can cite by name, attach a Response Schema that forces the retrieved sources into a structured shape:

{
  "type": "object",
  "properties": {
    "passages": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "text": { "type": "string" },
          "source": { "type": "string" }
        },
        "required": ["text", "source"]
      }
    }
  },
  "required": ["passages"]
}

Set the Output Variable to kb. Later steps read {{ kb.passages }}. Always query with the same embedding model the collection was created with. For more on this node, see Querying Your Knowledge Base.

Step 4: Draft a grounded reply with an Agent-mode Connector node

Add a Connector node on the front connector in Agent mode. Agent mode runs an AI agent that reasons over the retrieved passages and produces a customer-ready reply, while a Response Schema forces clean JSON you can act on deterministically. In the prompt, instruct it to answer only from the supplied passages and to refuse or escalate when the passages do not cover the question:

Draft a friendly reply to this customer message:
{{ transform.question }}

Use ONLY these knowledge passages. Do not invent facts.
{{ kb.passages }}

Return an "answer" written for the customer and a "sources"
array naming each passage you relied on. If the passages do
not answer the question, set needsHuman to true.

Attach this Response Schema so the output is predictable:

{
  "type": "object",
  "properties": {
    "answer": { "type": "string" },
    "sources": { "type": "array", "items": { "type": "string" } },
    "needsHuman": { "type": "boolean" }
  },
  "required": ["answer", "sources", "needsHuman"]
}

Set the Output Variable to draft. See Using Connector Nodes in Agent Mode and How to Use Structured Output for Reliable AI Data Extraction.

Step 5: Hold the draft for a teammate to approve

Add a Human node so a support agent reviews the wording and the cited sources before the customer ever sees them. Set a Label like Approve Front reply and put the draft in the Message so reviewers see it inline:

Proposed reply to {{ transform.customerHandle }}:

{{ draft.answer }}

Sources: {{ draft.sources }}

Fill the required Approval slots with the team or role that handles tier-one support; any atom in a slot satisfies it, and the run continues only when every slot is satisfied. Set a Timeout (minutes) so unattended drafts do not stall forever, and optionally turn on Email approvers. Approvers act in the Approvals inbox. On approval the run continues with { approved: true }; on reject or timeout the run halts and nothing is sent. Branching on rejection is not supported, so a rejected draft simply means no reply goes out. See Using Human Approval Nodes.

Step 6: Post the approved reply back into Front

Add a Connector node on the front connector in Direct mode and select the send-message tool. Map the fields:

  • channelId: your reply channel id, for example cha_123.
  • to: an array with the customer's handle, for example ["{{ transform.customerHandle }}"].
  • subject: a reply subject such as Re: {{ input.subject }} for email channels.
  • body: the approved answer plus a rendered source list. The field accepts HTML:
{{ draft.answer }}
<hr>
<p><strong>Sources</strong>: {{ draft.sources }}</p>

You can pass options such as { "tag_ids": [] } to tag the conversation as auto-drafted. To register the webhook that fires Step 1, add a one-off Connector node on the http connector using http-post to call Front's application webhooks endpoint, for example https://api2.frontapp.com/application_webhooks, sending your Front API token in the Authorization header and your Spojit workflow URL in the body. See Using Connector Nodes in Direct Mode and How to Connect to Any REST API Using HTTP Requests.

Step 7: Skip empty answers (optional)

Add a Condition node between the draft and the Human node to short-circuit when the knowledge base has no answer. Branch on {{ draft.needsHuman }}: when true, route to a Send Email node that notifies your support lead that a message needs a manual reply instead of drafting one; when false, continue to approval. This keeps reviewers focused on drafts that are actually grounded. See Using Condition Nodes.

Tips

  • Keep Result Count small (3 to 5). Too many passages dilute the draft and increase AI cost in Agent mode.
  • Re-embed your collection whenever your help docs change so cited passages stay current; stale sources are the most common cause of confident-but-wrong drafts.
  • Use the Custom signing scheme on the webhook trigger and rotate the secret if you ever expose the URL, so only Front can start runs.
  • Ask Miraxa to scaffold the canvas: "Build a workflow with a Webhook trigger, a Knowledge query into my support collection, an Agent-mode Front node with a Response Schema, a Human approval, then a Front send-message," then fine-tune fields in the properties panel.

Common Pitfalls

  • Wrong payload path. Front's inbound event nests the message and conversation; confirm the exact path in the first execution log before binding {{ input.conversation.id }} and the message text.
  • Duplicate replies. If Front retries delivery, enable event-id deduplication on the trigger, or you may draft and send the same answer twice.
  • Embedding model mismatch. Querying a collection with a different embedding model than it was created with returns poor or empty passages. Match the model used at creation.
  • Reject expectations. A rejected or timed-out Human approval halts the run; there is no "on reject" branch. Use the Step 7 Condition (or a separate notify path) if you need an explicit fallback.

Testing

Before pointing real traffic at it, run the workflow with the Run button while temporarily switching the trigger to Manual, passing a sample Front inbound body that mirrors a real question your docs answer. Confirm the Knowledge node returns relevant {{ kb.passages }}, that the Agent-mode draft cites only those sources, and that the Human node appears in your Approvals inbox. Approve it and verify the reply lands in the Front conversation. Once that round trip is clean, switch the trigger back to Webhook, register the Front application webhook (Step 6), and test with a single real inbound message scoped to one inbox.

Learn More

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