Back to Alchemy
Alchemy RecipeIntermediateautomation

Customer feedback analysis and sentiment-driven action plan creation

24 March 2026

Introduction

Customer feedback arrives constantly across email, support tickets, surveys, and social media. Most teams read through it manually, identify patterns, and create action plans weeks later. By then, the insights are stale and the feedback backlog has grown into something impossible to manage.

This workflow automates that entire cycle. You'll capture feedback, analyse sentiment in bulk, categorise issues by urgency and type, then generate prioritised action plans without anyone touching the data in between. From raw feedback to executable tasks: zero manual handoff.

The three tools here do one thing each and do it well. Accio-ai extracts structured data from unstructured text, terrakotta-ai handles sentiment classification at scale, and twig generates coherent action items from analysis. Wire them together with an orchestration platform and you've got a system that runs on schedule or on demand.

The Automated Workflow

You'll need to pick an orchestration tool first. Zapier works if you want the fastest setup with a visual interface; n8n gives you more control and runs on your own infrastructure; Make is somewhere in between; Claude Code is best if you want to write actual Python and deploy it yourself. This guide assumes n8n, which balances flexibility and ease of use.

The overall flow looks like this:

  1. Collect feedback from your source (email inbox, support system, survey tool).
  2. Pass each piece of feedback through accio-ai to extract key entities and topics.
  3. Send the extracted data and original text to terrakotta-ai for sentiment scoring.
  4. Group results by sentiment and topic using a transform step.
  5. Pass grouped feedback to twig to generate action plans.
  6. Store the output somewhere accessible (Google Sheets, a database, or your project management tool).

Step 1: Setting up the trigger and initial collection

Your n8n workflow starts with a trigger. The most practical options are a webhook (to push feedback in real time from your support tool), a scheduled poll (to grab emails from an inbox every hour), or a manual trigger for testing.

Here's an example webhook that accepts incoming feedback:


POST /webhook/customer-feedback
Content-Type: application/json

{
  "feedback_id": "fb_12345",
  "customer_email": "alice@company.com",
  "feedback_text": "The dashboard is slow to load and the export feature doesn't work with CSV files. We need this fixed before our month-end close.",
  "source": "support_ticket",
  "timestamp": "2024-01-15T09:30:00Z"
}

In n8n, create a Webhook node that listens for POST requests. Set the HTTP method to POST and save the URL. You'll use this to push feedback from your support platform.

Step 2: Extract structure with accio-ai

Accio-ai reads messy text and pulls out entities, intents, and key topics. This is essential because you can't group feedback accurately without knowing what it's actually about.

Call the accio-ai API like this:


POST https://api.accio-ai.io/v1/extract
Authorization: Bearer YOUR_ACCIO_API_KEY
Content-Type: application/json

{
  "text": "The dashboard is slow to load and the export feature doesn't work with CSV files. We need this fixed before our month-end close.",
  "entity_types": ["feature", "issue_type", "urgency"],
  "return_confidence": true
}

The response will give you structured output:

{
  "entities": [
    {
      "type": "feature",
      "value": "dashboard",
      "confidence": 0.98
    },
    {
      "type": "feature",
      "value": "export",
      "confidence": 0.97
    },
    {
      "type": "issue_type",
      "value": "performance",
      "confidence": 0.95
    },
    {
      "type": "issue_type",
      "value": "functionality",
      "confidence": 0.92
    },
    {
      "type": "urgency",
      "value": "high",
      "confidence": 0.89
    }
  ],
  "intent": "bug_report"
}

In n8n, add an HTTP Request node configured like this:

  • Method: POST
  • URL: https://api.accio-ai.io/v1/extract
  • Authentication: Bearer token (use an n8n credential to store YOUR_ACCIO_API_KEY)
  • Body: Map the feedback text from the webhook trigger
  • Set the urgency constraint to ["high", "medium", "low"] in the request parameters

Set the node to continue on error so a failed extraction doesn't stop the whole workflow.

Step 3: Score sentiment with terrakotta-ai

Now you know what the feedback is about. Next, you need to know how the customer feels about it. Terrakotta-ai classifies sentiment and provides a numeric score.


POST https://api.terrakotta-ai.io/v1/sentiment
Authorization: Bearer YOUR_TERRAKOTTA_API_KEY
Content-Type: application/json

{
  "text": "The dashboard is slow to load and the export feature doesn't work with CSV files. We need this fixed before our month-end close.",
  "model": "default",
  "aspects": ["feature_dashboard", "feature_export"]
}

The response includes overall sentiment and aspect-level sentiment:

{
  "overall_sentiment": "negative",
  "sentiment_score": -0.82,
  "aspects": [
    {
      "aspect": "feature_dashboard",
      "sentiment": "negative",
      "score": -0.85
    },
    {
      "aspect": "feature_export",
      "sentiment": "negative",
      "score": -0.79
    }
  ],
  "confidence": 0.91
}

In n8n, add another HTTP Request node:

  • Method: POST
  • URL: https://api.terrakotta-ai.io/v1/sentiment
  • Body: Include the original feedback text and pass the extracted features as aspects
  • Store the sentiment_score in your working data

The aspect-level sentiment is useful because a customer might be happy with one feature but frustrated with another. You'll use this to categorise problems later.

Step 4: Group feedback by sentiment and topic

You've now got structured data for each piece of feedback: original text, extracted entities, sentiment score, and aspect sentiment. Before generating an action plan, group similar feedback together so you're not creating duplicate actions.

In n8n, use a Function node with JavaScript to group the feedback. Here's a simplified example:

// Input: array of feedback objects with extracted data and sentiment
const feedbackArray = $input.all().map(item => item.json);

const grouped = {};

feedbackArray.forEach(feedback => {
  const entities = feedback.entities.map(e => e.value).sort().join('|');
  const sentimentBucket = feedback.sentiment_score < -0.5 ? 'negative' : 'neutral';
  const key = `${entities}_${sentimentBucket}`;
  
  if (!grouped[key]) {
    grouped[key] = {
      entities: feedback.entities,
      sentiment_score: feedback.sentiment_score,
      feedback_list: [],
      count: 0
    };
  }
  
  grouped[key].feedback_list.push({
    text: feedback.feedback_text,
    customer: feedback.customer_email,
    timestamp: feedback.timestamp
  });
  grouped[key].count += 1;
});

return Object.values(grouped);

This creates buckets of similar feedback. For instance, all feedback about slow dashboard performance with negative sentiment goes into one group. If you've got 47 customers complaining about the same thing, you'll see that immediately.

Step 5: Generate action plans with twig

Now you pass grouped feedback to twig, which generates prioritised, specific action items. Twig reads the entities, sentiment, and count of similar issues, then writes things like "investigate why dashboard loads slowly for large datasets; check database query performance in the accounts view" rather than generic "fix performance issues."


POST https://api.twig-ai.io/v1/generate-actions
Authorization: Bearer YOUR_TWIG_API_KEY
Content-Type: application/json

{
  "feedback_group": {
    "entities": [
      {"type": "feature", "value": "dashboard"},
      {"type": "issue_type", "value": "performance"}
    ],
    "sentiment_score": -0.82,
    "feedback_count": 47,
    "sample_feedback": [
      {
        "text": "The dashboard is slow to load and the export feature doesn't work with CSV files. We need this fixed before our month-end close.",
        "customer": "alice@company.com",
        "timestamp": "2024-01-15T09:30:00Z"
      },
      {
        "text": "Dashboard takes 30 seconds to load during the morning. Blocks our daily standup.",
        "customer": "bob@company.com",
        "timestamp": "2024-01-15T09:45:00Z"
      }
    ],
    "context": "SaaS accounting platform"
  },
  "output_style": "actionable",
  "priority_basis": "frequency"
}

Twig returns:

{
  "priority": "critical",
  "priority_score": 9.2,
  "suggested_actions": [
    {
      "action": "Profile dashboard load times and identify slow queries",
      "owner": "backend_team",
      "timeline": "1 week",
      "rationale": "47 customer reports of slow dashboard loading; blocking daily workflows"
    },
    {
      "action": "Add CSV export format support to export feature",
      "owner": "product_team",
      "timeline": "2 weeks",
      "rationale": "Secondary issue mentioned in customer feedback; blocks month-end close workflows"
    },
    {
      "action": "Proactively notify customers of performance optimisation in next release",
      "owner": "support_team",
      "timeline": "Same day",
      "rationale": "High frustration level in feedback; early communication reduces churn risk"
    }
  ],
  "affected_customer_count": 47,
  "sentiment_summary": "Negative; customers frustrated by impact on core workflows"
}

In n8n, add an HTTP Request node to call twig:

  • Method: POST
  • URL: https://api.twig-ai.io/v1/generate-actions
  • Body: Pass the grouped feedback, sentiment scores, and customer count
  • Set priority_basis to "frequency" so issues affecting more customers rank higher

Step 6: Store and distribute the output

You've generated action plans. Now send them somewhere your team can actually use them.

Option A: Google Sheets (best for quick viewing and manual follow-up)

// In an n8n Function node, format the output for Sheets
const actionPlans = $input.all().map(item => item.json);

const sheetRows = actionPlans.flatMap(plan => {
  return plan.suggested_actions.map(action => ({
    Priority: plan.priority,
    PriorityScore: plan.priority_score,
    AffectedCustomers: plan.affected_customer_count,
    Action: action.action,
    Owner: action.owner,
    Timeline: action.timeline,
    Rationale: action.rationale,
    CreatedAt: new Date().toISOString()
  }));
});

return sheetRows;

Then use the Google Sheets node to append these rows to a sheet named "Action Plans".

Option B: Your project management tool (Jira, Asana, Linear)

Create issues directly from the action plan. For Jira, send:


POST https://your-domain.atlassian.net/rest/api/3/issues
Authorization: Bearer YOUR_JIRA_API_TOKEN
Content-Type: application/json

{
  "fields": {
    "project": {"key": "FEEDBACK"},
    "issuetype": {"name": "Task"},
    "summary": "Profile dashboard load times and identify slow queries",
    "description": "47 customer reports indicate the dashboard is slow to load, blocking daily workflows. Secondary issue: CSV export format not supported.",
    "priority": {"name": "Critical"},
    "labels": ["customer-feedback", "performance", "dashboard"],
    "assignee": {"name": "backend-team"}
  }
}

Option C: Slack notification (for urgent issues)

const actionPlans = $input.all().map(item => item.json);

actionPlans
  .filter(plan => plan.priority_score > 8)
  .forEach(plan => {
    // This feeds into a Slack node
    return {
      channel: "#product-feedback",
      text: `🚨 Critical: ${plan.suggested_actions[0].action}`,
      blocks: [
        {
          type: "section",
          text: {
            type: "mrkdwn",
            text: `*${plan.priority}* issue affecting ${plan.affected_customer_count} customers\n${plan.sentiment_summary}`
          }
        },
        {
          type: "section",
          text: {
            type: "mrkdwn",
            text: `*Action:* ${plan.suggested_actions[0].action}\n*Timeline:* ${plan.suggested_actions[0].timeline}`
          }
        }
      ]
    };
  });

Wire a Slack node into your workflow to send critical issues to your team in real time.

Putting it all together in n8n

Your workflow nodes in order:

  1. Webhook trigger (listens for incoming feedback)
  2. HTTP Request to accio-ai (extract entities)
  3. HTTP Request to terrakotta-ai (score sentiment)
  4. Function node (group feedback by entity + sentiment)
  5. HTTP Request to twig (generate action plans)
  6. Google Sheets or Jira or Slack node (distribute output)

Set the workflow to run every morning at 9 AM, or trigger it manually when you need an immediate analysis. Enable error handling on each API call so a timeout from one tool doesn't break the whole workflow.

The Manual Alternative

If you want direct control over the analysis, you can pull the data at each step and review it before moving forward. This takes longer but gives you the chance to filter or adjust the grouping manually.

Use the same orchestration tool to export results to a shared folder after step 5, then review the grouped feedback and action plans before distributing them. Add a pause node and a manual approval step. This is slower but useful if you're piloting the workflow and want to validate that accio-ai and twig are generating sensible results.

Alternatively, set up the workflow to run but export everything to a spreadsheet rather than creating Jira issues. Your team reviews the spreadsheet each week and decides which action plans to implement. This hybrid approach keeps the automation but adds a human checkpoint.

Pro Tips

Rate limits and batching

Terrakotta-ai and accio-ai have rate limits (usually 100-500 requests per minute depending on your plan). If you process feedback in real time, you'll hit the limit quickly. Instead, batch feedback: collect it for an hour, then send all items to the APIs in one workflow run. Use n8n's schedule feature to run your workflow every hour at minute 00.

Error handling

Add a Try/Catch node around each API call. If accio-ai fails to extract entities, log the failure and continue with the original text. If terrakotta-ai returns low confidence (below 0.7), flag it for manual review. Twig should always succeed if it receives valid input, but add a fallback that generates a generic action item if something goes wrong.

Cost optimisation

Accio-ai charges per request, and terrakotta-ai charges per request. Run the workflow once daily rather than in real time to control costs. If you process 500 feedback items per day at (for example) $0.002 per request, that's $1 per day or $30 per month per tool. Batching keeps your bill predictable.

Testing the workflow

Before sending 10,000 historical feedback items through the workflow, test with 5-10 examples. Check that accio-ai is extracting the right entities, terrakotta-ai is scoring sentiment correctly, and twig is generating actions that make sense. Adjust the requests if the output isn't what you expected.

Feedback source diversity

This workflow works with any source of feedback: email, Slack messages, support tickets, survey responses, or social media posts. The key is normalising each input to the same schema before the webhook trigger. If you're pulling from multiple sources, add a transform node that maps each source's fields to your standard feedback object.

Cost Breakdown

ToolPlan NeededMonthly CostNotes
accio-aiPay-as-you-go (500 requests/mo included free)£15–40Depends on request volume; ~£0.002 per request above free tier
terrakotta-aiStandard (up to 10,000 requests/mo)£25–50Includes 10,000 sentiment analyses; overage £0.005 per request
twigPro (unlimited)£60–100Price scales with feature set; includes unlimited action generation
n8nSelf-hosted (free) or Cloud Pro£0 or £30Self-hosted requires your own server; Cloud Pro includes monitoring and backups
Google Sheets or JiraFree or existing licence£0–10Sheets is free; Jira costs apply if you don't already use it
Total (low volume)£100–160/monthFor under 500 feedback items per month
Total (medium volume)£200–280/monthFor 1,000–5,000 feedback items per month
Total (high volume)£400–600/monthFor 10,000+ feedback items per month

The costs above assume running the workflow once daily and processing up to your plan's limits. Batching feedback reduces API calls and keeps you in lower cost tiers. If you're already paying for Jira or using Google Sheets, subtract those lines from your total.