How to Route Front Conversations to the Right Team Using AI and Tagging

Use Spojit to catch an inbound Front conversation, let Miraxa read it and pick the destination team and topic tags, then apply routing tags so the message lands with the right group automatically.

What This Integration Does

When customer messages all flow into a shared Front account, the slow part is triage: a human has to read each new conversation, decide which team owns it (billing, technical support, sales, and so on), and tag it so the right people pick it up. This workflow removes that manual step. An inbound message starts a Spojit workflow, an Agent-mode Connector node reads the conversation text and returns a structured decision (the target team plus a short list of topic tags), and Spojit then applies the matching tags in Front so your existing inbox rules and team views surface the conversation to the correct group.

The workflow runs once per inbound event. Front sends a webhook to your workflow's URL, Spojit verifies it and hands the parsed JSON body to the trigger, and the steps run in order. The intelligent layer chooses a team and tags, a Condition node branches on the chosen team, and the front connector adds the tags to that conversation. The workflow leaves the conversation tagged and routed; it does not move or reply to the message unless you add a step to do so. Re-runs are safe to make idempotent: tags are additive in Front, and you can dedupe on the event id so a replayed webhook does not double-tag.

Prerequisites

  • A Front connection in Spojit with an API token, added under Connections. See the Front connector reference for setup.
  • A Front account where you can configure outbound webhooks (a Front rule or app that POSTs to a URL on each new inbound conversation).
  • The Front conversation ID available in the webhook payload (the value you pass to get-conversation and add-tag).
  • Routing tags created in Front ahead of time (for example one tag per team), so each team has a stable tag ID you can apply.
  • A signing connection for the webhook trigger so Spojit can verify the incoming request. See Setting Up a Webhook Connection.

Step 1: Start with a Webhook trigger

Add a Trigger node and set its type to Webhook. Spojit gives the workflow a unique URL; point your Front webhook (rule or app) at it so each new inbound conversation POSTs its event. Pick a signing connection so Spojit can verify the request (use the Custom scheme if you are signing with Front's secret, or Spojit for a Spojit-generated secret). The trigger output is the parsed JSON body, available as {{ input }}. Capture the conversation id from the payload, for example {{ input.conversation.id }}, into a variable you reuse downstream. The trigger returns 202 with an executionId, so Front gets a fast acknowledgement while the rest of the workflow runs.

Step 2: Fetch the full conversation from Front

Add a Connector node on the front connector in Direct mode and pick the get-conversation tool. Map its id field to the conversation id from the trigger:

{
  "id": "{{ input.conversation.id }}"
}

Direct mode is deterministic and costs no AI credits, which is what you want for a predictable single lookup. The result gives you the subject and message details to feed into the next step. Save the output to a variable such as conversation so you can reference fields like {{ conversation.subject }} in the prompt.

Step 3: Let Miraxa pick a team and tags with a Response Schema

Add a second Connector node, this time in Agent mode, and write a prompt that hands the intelligent layer the conversation text and asks for a routing decision. Force a predictable, parseable result by turning on the Response Schema so the node returns strict JSON instead of prose. A prompt and schema like this work well:

Prompt:
Read this customer conversation and decide which team should own it
and up to three short topic tags. Teams: billing, technical, sales, general.

Subject: {{ conversation.subject }}
Body: {{ conversation.last_message.body }}
Response Schema:
{
  "type": "object",
  "properties": {
    "team":   { "type": "string", "enum": ["billing", "technical", "sales", "general"] },
    "tags":   { "type": "array", "items": { "type": "string" } },
    "summary":{ "type": "string" }
  },
  "required": ["team", "tags"]
}

Save the output to a variable such as routing. You can now reference {{ routing.team }} and {{ routing.tags }} downstream. Constraining team with an enum keeps the branching predictable; the Condition node only ever has to match one of the known values.

Step 4: Branch on the chosen team with a Condition node

Add a Condition node that checks {{ routing.team }}. Create one branch per team value: for example a true branch when {{ routing.team }} equals billing, another for technical, and so on, with a default branch for general. Each branch will apply a different routing tag. This is where the AI decision turns into a deterministic path: the intelligent layer made the judgement call once, and from here everything is a fixed, auditable action. If you prefer to keep the design compact, you can branch on just the priority teams and let everything else fall through to general.

Step 5: Confirm the target inbox and look up the team's teammates

On each branch, add a Connector node on the front connector in Direct mode using list-inboxes to confirm the inbox the team works from still exists before you tag into it. This tool takes no inputs and returns every inbox in the account; check that the inbox name your branch expects is present so the conversation does not get tagged toward an inbox that was renamed or removed. In the same branch you can call list-teammates (also no inputs) to resolve who is on that team, which is useful if you later add an assignment or notification step. Save these to variables such as inboxes and teammates.

Step 6: Apply the routing tags in Front

Still on the branch, add a final Connector node on the front connector in Direct mode using the add-tag tool. It takes the conversationId and an array of tag_ids. Tag IDs are stable identifiers; the simplest approach is to hard-code the team's routing tag id per branch, and optionally call list-tags once to look up the ids while you are building. A billing branch call looks like this:

{
  "conversationId": "{{ input.conversation.id }}",
  "tag_ids": ["tag_billing_routing_id"]
}

Tags in Front are additive, so applying the same routing tag again on a replay is harmless. With the tag applied, your existing Front inbox rules and team views surface the conversation to the right group, and the routing is done. If you also want to notify the team, add a Connector node with the front send-message tool or a Send Email node on the same branch.

Tips

  • Keep the enum in the Response Schema in lockstep with your Condition branches and your hard-coded tag ids; if the model can return a value you do not branch on, that conversation slips through untagged.
  • Use Direct mode for every Front call (fetch, list, tag) and reserve Agent mode for the single routing decision. That keeps AI credit usage to one step per conversation.
  • Ask Miraxa to scaffold the Condition and tagging branches for you, for example: "Add a Condition node on {{ routing.team }} with a branch for billing that connects to a front add-tag node," then fine-tune the tag ids in the properties panel.
  • Store team-to-tag mappings in one place (a Transform node or a short JSON variable) so adding a team is a one-line change rather than a new hard-coded branch.

Common Pitfalls

  • Webhook replays double-fire. Front (or a retry) can deliver the same event twice. Turn on opt-in dedup using the event-id header on the Webhook trigger so a replay does not re-run the routing.
  • Tag names versus tag ids. The add-tag tool needs tag_ids, not tag names. Run list-tags once to capture the ids; passing a human-readable name silently fails to match.
  • Token scope. If add-tag or get-conversation returns an authorization error, the Front API token on your connection lacks the needed access. Re-check the token under Connections.
  • Empty or truncated body. If the model picks general too often, the conversation body in the prompt is probably thin. Pull the latest message detail from get-conversation rather than relying only on the webhook summary.

Testing

Before turning this on for live traffic, test on a single, known conversation. Use the Run button with a sample webhook body that points at one real Front conversation id, then watch the execution in the run history: confirm get-conversation returned the subject and body, that the Agent-mode node produced a valid routing object matching your schema, that the Condition node took the branch you expected, that list-inboxes found the target inbox, and that add-tag applied the right tag in Front. Once one conversation routes correctly end to end, point the Front webhook at the workflow URL and enable it.

Learn More

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