How to Capture a CSAT Web-Form Webhook and Escalate Detractors to Slack and Monday

Receive CSAT survey scores from a web form on a Spojit webhook, isolate the low scores, summarize the customer's comment with Miraxa, get a lead's approval on a make-good gesture, then alert your team in Slack and open a recovery task in Monday.com.

What This Integration Does

When a customer finishes a CSAT survey, the score that matters most is the low one: a detractor who just told you they are unhappy. This workflow catches those scores the instant the survey vendor posts them, reads the verbatim comment, drafts a short summary plus a suggested follow-up, and routes a make-good gesture (for example a refund credit or a personal call) past a support lead for approval. Once approved, it posts an alert to your Slack channel and opens a recovery task on a Monday.com board so nobody on the team has to watch a dashboard. Happy responses simply pass through without noise.

The run is triggered by an HTTP POST from your survey vendor to a Spojit Webhook trigger. The parsed survey payload flows through a Condition that keeps only low scores, an Agent-mode Connector node that produces a structured summary, a Human node that pauses for sign-off, and finally the Slack and Monday.com Connector nodes that fan out the alert and the task. A Response node and an http call acknowledge the vendor's callback so it does not retry. Each survey submission is its own execution, so re-running one detractor never touches another, and high scores end the run early with no side effects.

Prerequisites

  • A Slack connection (OAuth) with permission to post messages, and the target channel's ID (for example C012AB3CD45).
  • A Monday.com connection (API key) and a board for customer recovery tasks, with its boardId and the IDs of any columns you want to set.
  • A survey vendor that can POST JSON to a URL (a webhook or outbound integration in the survey tool), or a web form configured to post to a URL.
  • A Webhook signing connection. If your vendor signs requests, set up a matching scheme; otherwise use the Custom or Spojit scheme. See Setting Up a Webhook Connection.
  • At least one Spojit user or role to act as the approval slot for the make-good gesture.

Step 1: Receive the survey with a Webhook trigger

Add a Trigger node and set its type to Webhook. Attach your webhook signing connection so Spojit can verify each request, then copy the generated workflow URL into your survey vendor's outbound webhook or your web form's POST target. Spojit parses the request body into JSON and exposes it as {{ input }}, replying 202 with an executionId the moment it accepts the call.

Assume your survey vendor posts a body like this:

{
  "responseId": "resp_8842",
  "score": 2,
  "scale": 5,
  "comment": "Driver left the parcel in the rain and the box was soaked.",
  "customer": { "name": "Dana Lowe", "email": "dana@example.com" },
  "callbackUrl": "https://api.surveyvendor.com/v1/responses/resp_8842/ack"
}

You now have fields such as {{ input.score }}, {{ input.comment }}, and {{ input.customer.email }} available downstream. To learn more about the trigger, see Setting Up a Webhook Trigger.

Step 2: Isolate detractors with a Condition node

Add a Condition node directly after the trigger. Configure the test to keep only low scores: compare {{ input.score }} as less than or equal to 2 (the common CSAT detractor cutoff on a 1 to 5 scale). Route the true branch into the escalation steps below and leave the false branch empty so promoters and passives end the run quietly.

If your survey uses a 0 to 10 NPS-style scale instead, adjust the cutoff (detractors are {{ input.score }} less than or equal to 6) and check {{ input.scale }} to be sure you are reading the scale you expect. For more on branching, see Using Condition Nodes.

Step 3: Summarize the comment with an Agent-mode Connector node

On the true branch, add a Connector node in Agent mode. This is where Miraxa, the intelligent layer across your automation, reads the raw verbatim comment and turns it into something your team can act on. Give it a prompt that references the survey fields:

A customer left a low CSAT score of {{ input.score }} out of {{ input.scale }}.
Their comment was: "{{ input.comment }}".
Summarize the core problem in one sentence, judge how upset the customer
sounds, and suggest a single concrete follow-up the team should take.

Turn on the node's Response Schema so the output is reliable JSON you can map into later steps rather than free text. Define a schema like this:

{
  "type": "object",
  "properties": {
    "summary":       { "type": "string" },
    "sentiment":     { "type": "string", "enum": ["frustrated", "disappointed", "neutral"] },
    "suggestedFollowUp": { "type": "string" },
    "makeGoodGesture":   { "type": "string" }
  },
  "required": ["summary", "sentiment", "suggestedFollowUp", "makeGoodGesture"]
}

Store the result in an output variable such as analysis, giving you {{ analysis.summary }}, {{ analysis.suggestedFollowUp }}, and {{ analysis.makeGoodGesture }}. For the trade-offs between the two modes, see How to Choose Between Agent Mode and Direct Mode.

Step 4: Get sign-off on the make-good with a Human node

Add a Human node so a support lead approves the proposed gesture before any commitment goes out. Set a clear Label (for example Approve make-good gesture) and a Message that pulls in the analysis so the approver has full context:

Detractor: {{ input.customer.name }} ({{ input.score }}/{{ input.scale }})
Problem: {{ analysis.summary }}
Proposed gesture: {{ analysis.makeGoodGesture }}
Suggested follow-up: {{ analysis.suggestedFollowUp }}

Fill in the Notification title and body, set Urgency to High, and add at least one Approval slot holding the support lead user or a support Role. Optionally set a Timeout (minutes) so a stale request does not block forever. Approvers act in the Approvals inbox at /approvals. When approved, the node continues and outputs { approved: true, outcome: "APPROVED" }. Note that a rejection or timeout halts the run, so the Slack and Monday.com steps only ever fire on an approved gesture. See Using Human Approval Nodes.

Step 5: Alert the team with Slack send-message

After approval, add a Connector node in Direct mode on the slack connector and pick the send-message tool. Map the inputs:

  • channel: your support channel ID, for example C012AB3CD45.
  • text: a templated alert built from the survey and analysis fields.
:rotating_light: Detractor alert - {{ input.customer.name }} scored {{ input.score }}/{{ input.scale }}
Problem: {{ analysis.summary }}
Approved make-good: {{ analysis.makeGoodGesture }}
Customer: {{ input.customer.email }}

For richer formatting you can add the optional blocks field, but plain text is enough to get the alert flowing. See the Slack connector reference for all available tools.

Step 6: Open a recovery task with Monday.com create-item

Add another Connector node in Direct mode on the monday connector and choose the create-item tool so the team has a tracked task. Map the inputs:

  • boardId: your recovery board ID.
  • name: a descriptive item title, for example Recover {{ input.customer.name }} - CSAT {{ input.score }}/{{ input.scale }}.
  • columnValues: a structured object keyed by your column IDs, carrying the email, summary, and follow-up.
{
  "email_col":    { "email": "{{ input.customer.email }}", "text": "{{ input.customer.email }}" },
  "status_col":   { "label": "New" },
  "long_text_col": { "text": "{{ analysis.summary }} | Follow-up: {{ analysis.suggestedFollowUp }}" }
}

Replace email_col, status_col, and long_text_col with the real column IDs from your board (read them with the get-board tool if you are unsure). See the Monday.com connector reference for details.

Step 7: Acknowledge the survey vendor's callback

Many survey vendors expect a callback confirming you processed the response. Add a final Connector node in Direct mode on the http connector and use the http-post tool to call the vendor's acknowledgement endpoint at {{ input.callbackUrl }}, passing any API key your vendor requires in the Authorization header and a small JSON body:

{ "status": "received", "responseId": "{{ input.responseId }}" }

If the original webhook is synchronous and your vendor waits for a body, you can instead (or additionally) add a Response node at the end of the true branch to return { "ok": true, "responseId": "{{ input.responseId }}" } to the caller. The http connector pattern lets Spojit reach any external REST API; see How to Connect to Any REST API Using HTTP Requests.

Tips

  • Keep the Agent-mode prompt focused on summarizing and suggesting. The Response Schema does the heavy lifting of forcing clean fields, which keeps AI credit usage and output drift low.
  • Set the Human node Urgency to High and a sensible timeout so detractor recovery does not stall behind routine approvals.
  • Use a Slack thread_ts on follow-up messages if you later want to keep all updates about one detractor in a single thread.
  • Look up Monday.com column IDs once with get-board, then hardcode them in columnValues; column IDs are stable even when the column titles change.

Common Pitfalls

  • Reading the wrong scale: a score of 2 is a detractor on a 1 to 5 scale but a promoter on a 0 to 10 scale. Always branch against the scale your vendor actually sends.
  • Webhook replays: some vendors retry if they do not get a fast response. The trigger returns 202 immediately, but make sure your Step 7 acknowledgement actually reaches the vendor, and consider enabling event-id dedup so a retry does not open a second Monday.com task.
  • Monday.com columnValues use column IDs, not titles, and each column type expects a specific shape (status uses label, email uses email plus text). A mismatched shape is the most common reason an item is created with blank fields.
  • Remember that a rejected or timed-out Human approval halts the run, so the Slack and Monday.com steps will not fire. If you need a record of declined gestures, capture that before the Human node or in a separate branch.

Testing

Before pointing your live survey at the workflow, send a small test payload to the webhook URL with a low score (for example "score": 1) using your survey vendor's test tool or any HTTP client. Confirm the Condition takes the true branch, check that the Agent node's output variable holds clean schema fields in the execution log, then approve the request in the /approvals inbox and verify the Slack alert and the Monday.com item appear. Send a second test with a high score (for example "score": 5) and confirm the run ends quietly with no Slack or Monday.com side effects. See Understanding Execution Logs to inspect each step's input and output.

Learn More

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