Introduction
Customer complaints are goldmines for product and process improvement, but most organisations treat them like noise. A complaint lands in your support inbox, someone reads it, maybe leaves a note, and then it vanishes into the archive. Months later, you're still fielding the same issue because no one connected the dots between complaint data and actionable process changes.
The problem gets worse as complaint volume grows. Manual analysis becomes a bottleneck. You'd need someone to read through dozens of complaints weekly, categorise them, identify patterns, and then draft recommendations for operations or product teams. That person becomes a full-time complaint translator, and half their work gets lost because nobody's reading their reports.
This workflow solves that by automating the entire journey from complaint to action plan. We'll capture complaints from your support channel, analyse them for themes and severity, extract structured insights, and generate a prioritised action plan that lands directly in your team's project management system. Everything happens with zero manual handoff, meaning complaints flow straight to decision-makers without human gatekeeping.
The Automated Workflow
We're using three tools here: Accio AI to extract structured complaint data, Cogram to synthesise patterns and themes from complaint batches, and Terrakotta AI to draft the actual improvement recommendations. The orchestration glue holding it together is n8n, which is free to self-host and flexible enough for complex workflows like this.
The Overall Architecture
The workflow operates on a daily schedule (configurable to hourly if you prefer). Each morning, n8n queries your support system for new complaints from the past 24 hours, passes them through Accio for extraction, batches them through Cogram for theme detection, feeds the results into Terrakotta for recommendation drafting, and finally pushes the completed action plan to your team's shared workspace or project management tool.
The key is that each tool specialises in one task. Accio extracts structure from messy complaint text. Cogram finds patterns across many complaints at once. Terrakotta generates human-readable recommendations. n8n just orchestrates the timing and data handoff.
Setting Up n8n
First, you'll want n8n running. If you're self-hosting, the setup is straightforward with Docker.
docker run -it --rm \
-p 5678:5678 \
-v ~/.n8n:/home/node/.n8n \
n8nio/n8n
Then navigate to localhost:5678 and create your account. The web interface is intuitive; you build workflows visually and n8n handles the backend logic.
Step 1:
Capture Complaints from Your Support Channel
Most support systems have APIs or webhook capabilities. This example assumes you're using a REST API (Zendesk, Intercom, or Freshdesk all work similarly).
Create a new n8n workflow and add an "HTTP Request" node as the trigger. Set it to fire on a schedule (Daily at 9 AM, for instance). Configure it to hit your support API's endpoint for recent tickets.
For Zendesk, the endpoint looks like this:
GET https://yoursubdomain.zendesk.com/api/v2/tickets.json?status=open&created_at>[date]
Add authentication headers with your API key:
{
"Authorization": "Bearer YOUR_ZENDESK_API_TOKEN",
"Content-Type": "application/json"
}
The response gives you a list of tickets. n8n will parse the JSON automatically. You'll get something like this:
{
"tickets": [
{
"id": 12345,
"subject": "App crashes when uploading images",
"description": "Every time I try to upload more than 3 images at once, the app just closes. Tried on WiFi and mobile data, same issue.",
"status": "open",
"created_at": "2024-01-15T10:30:00Z"
},
{
"id": 12346,
"subject": "Billing charged twice",
"description": "I was charged £49.99 twice this month. My subscription is monthly but I see two charges on my card statement.",
"status": "open",
"created_at": "2024-01-15T11:45:00Z"
}
]
}
Use an "Item Lists" node to separate each ticket into individual items so the next steps process them one at a time or in batches, depending on your volume.
Step 2:
Extract Structured Data with Accio AI
Accio AI is designed to pull structured information from unstructured text. It's quick and handles variations in complaint phrasing well.
Add a new node in n8n for an HTTP Request to Accio's API. You'll send each complaint's description and subject, and Accio returns structured fields like severity, category, and root cause.
Here's the request configuration:
POST https://api.accio-ai.com/v1/extract
Headers:
{
"Authorization": "Bearer YOUR_ACCIO_API_KEY",
"Content-Type": "application/json"
}
Body:
{
"text": "{{ $node['Zendesk Query'].json['description'] }}",
"schema": {
"severity": "enum: critical|high|medium|low",
"category": "enum: bug|billing|feature_request|performance|documentation|other",
"affected_component": "string",
"root_cause_hypothesis": "string",
"customer_impact": "string"
}
}
Accio returns something like:
{
"extraction": {
"severity": "critical",
"category": "bug",
"affected_component": "Image upload module",
"root_cause_hypothesis": "Memory leak in batch upload handler",
"customer_impact": "Users unable to perform core workflow when uploading multiple files"
}
}
Store this structured output somewhere n8n can reference it later. Use a "Set" node to add it to the complaint data.
Step 3:
Batch and Analyse Patterns with Cogram
Once you've processed a batch of complaints (let's say the last 50), you need to find common themes. This is where Cogram shines. It's built for analysing conversations and documents to extract summaries and patterns.
Create a new node that collects all the extracted complaint data into a single payload. If you're running this daily, you might have 20-50 complaints. Format them as a structured list.
{
"complaints": [
{
"id": 12345,
"subject": "App crashes when uploading images",
"severity": "critical",
"category": "bug",
"affected_component": "Image upload module",
"root_cause_hypothesis": "Memory leak in batch upload handler"
},
{
"id": 12346,
"subject": "Billing charged twice",
"severity": "high",
"category": "billing",
"affected_component": "Payment processor integration",
"root_cause_hypothesis": "Duplicate charge logic in retry handler"
}
]
}
Send this to Cogram's API endpoint:
POST https://api.cogram.com/v1/analyse
Headers:
{
"Authorization": "Bearer YOUR_COGRAM_API_KEY",
"Content-Type": "application/json"
}
Body:
{
"content": "{{ $node['Collected Complaints'].json | json.stringify() }}",
"analysis_type": "theme_extraction",
"focus_areas": [
"recurring_issues",
"severity_distribution",
"affected_systems",
"customer_segments"
]
}
Cogram returns a summary of themes, organised by frequency and severity:
{
"analysis": {
"key_themes": [
{
"theme": "Image upload failures",
"frequency": 12,
"severity_average": "critical",
"affected_users": 47,
"description": "Multiple reports of app crashing or hanging during batch image uploads, particularly on slower connections."
},
{
"theme": "Duplicate billing charges",
"frequency": 8,
"severity_average": "high",
"affected_users": 23,
"description": "Customers report being charged multiple times for a single subscription month."
}
],
"severity_distribution": {
"critical": 12,
"high": 8,
"medium": 5,
"low": 2
}
}
}
This structured analysis is now ready for the next step: turning it into actionable recommendations.
Step 4:
Generate Action Plan with Terrakotta AI
Terrakotta AI is specialised in generating process and procedure documents. It takes structured input and produces polished, actionable output. Perfect for turning analysis into an improvement plan.
Create another HTTP Request node pointing to Terrakotta:
POST https://api.terrakotta-ai.com/v1/generate
Headers:
{
"Authorization": "Bearer YOUR_TERRAKOTTA_API_KEY",
"Content-Type": "application/json"
}
Body:
{
"document_type": "action_plan",
"input": {
"analysis": "{{ $node['Cogram Analysis'].json.analysis | json.stringify() }}",
"complaint_count": "{{ $node['Complaint Count'].json.total }}",
"analysis_period": "Last 24 hours",
"team_context": "Engineering, Product, Operations"
},
"format_preferences": {
"structure": "prioritised_by_impact",
"include_sections": [
"executive_summary",
"priority_actions",
"detailed_recommendations",
"success_metrics"
],
"tone": "professional_technical"
}
}
Terrakotta generates something like:
CUSTOMER COMPLAINT ANALYSIS: ACTION PLAN
Generated: 2024-01-15
Period Analysed: Last 24 hours
Total Complaints: 27
EXECUTIVE SUMMARY
27 customer complaints were received over the past 24 hours, with two dominant themes accounting for 75% of issues: image upload failures (12 complaints, critical severity) and duplicate billing charges (8 complaints, high severity). Immediate action is required on the image upload issue to prevent further customer churn.
PRIORITY ACTIONS (Next 48 hours)
1. Image Upload Module: Engage engineering to investigate memory leak in batch upload handler. Customer impact affects 47 users. Estimated fix: 6-8 hours.
2. Billing System: Review retry logic in payment processor integration. Risk of data corruption. Estimated fix: 4-6 hours.
DETAILED RECOMMENDATIONS
...
Store this generated action plan in a variable. You'll push it to your team's workspace next.
Step 5:
Post the Action Plan to Your Team
The final step is getting this in front of the right people. n8n can post to Slack, Microsoft Teams, Notion, Linear, or Asana.
For Slack, use the "Slack" node (built into n8n):
{
"text": "Daily Customer Complaint Analysis - Action Plan Ready",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "{{ $node['Terrakotta Generation'].json.document }}"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Key Metrics*\nTotal Complaints: {{ $node['Complaint Count'].json.total }}\nCritical Issues: {{ $node['Cogram Analysis'].json.analysis.severity_distribution.critical }}\nAnalysis Period: Last 24 hours"
}
}
],
"channel": "#operations-team"
}
Alternatively, if you use Linear for issue tracking, post directly to it:
POST https://api.linear.app/graphql
With a GraphQL mutation to create an issue:
{
"query": "mutation { issueCreate(input: { teamId: \"TEAM_ID\", title: \"Action Plan: Customer Complaints\", description: \"{{ $node['Terrakotta Generation'].json.document }}\", priority: 1 }) { issue { id url } } }"
}
This creates a tracked item in your workflow system, ensuring nothing gets missed.
Putting It All Together in n8n
Your complete workflow looks like:
- Schedule trigger (daily at 9 AM)
- Query Zendesk for new tickets
- Item Lists to iterate through tickets
- Accio API call to extract structure
- Collect all extracted data
- Cogram API call to analyse themes
- Terrakotta API call to generate plan
- Post to Slack / Linear / your system of choice
Connect each node's output to the next node's input. n8n provides a visual workflow builder, so you're literally drawing arrows between boxes. The platform handles all the data transformation and API calls.
The Manual Alternative
If you prefer more control at certain stages, you can adjust the workflow. For example, you might skip the Cogram step and have a human quickly review the Accio extractions before they reach Terrakotta. This adds a quality gate but loses some automation benefit.
Another approach is to run the workflow weekly instead of daily, allowing a larger sample size for pattern detection. This reduces noise and might surface more meaningful themes, though you'll have slightly longer latency between complaint and action.
You could also use Make (Integromat) or Zapier instead of n8n. Zapier's pricing gets expensive with multiple steps, but Make is reasonably priced and has a similar workflow-building interface. The API calls remain identical; only the orchestration interface changes.
Pro Tips
1. Handle Duplicate Complaints
Set a field in Accio's extraction schema that captures complaint ID and hash the complaint text. Before passing to Cogram, deduplicate based on hash or similarity score. This prevents the same issue from being counted multiple times and skewing your themes.
2. Watch Your API Rate Limits
Accio and Cogram both have rate limits. If you're processing 100+ complaints daily, check your tier. Most reasonable plans offer 1000+ requests per month. Spreading the workflow across different times (one batch at 9 AM, another at 5 PM) can help. n8n has a "Rate Limit" node for throttling requests.
3. Implement Error Handling
Add conditional branching in n8n. If Accio returns an error (malformed complaint text, API timeout), log it separately and notify yourself. Don't let a single bad complaint break the entire chain. Use the "Try/Catch" pattern or n8n's error handling nodes.
4. Archive Processed Complaints
Tag complaints you've already processed so you don't re-analyse them next time. This saves API calls. Create a custom field in Zendesk called "analysed_date" and set it when Accio processes the complaint. Query only complaints without this tag.
5. Review and Refine Monthly
Every month, look at which action plans actually led to changes. This feedback helps you tweak your schema in Accio, your theme detection parameters in Cogram, and your recommendation tone in Terrakotta. AI-powered workflows improve with feedback loops.
6. Cost Optimisation
Batch complaints if possible. Sending one complaint at a time to Terrakotta costs the same as sending fifty. If you're on a usage-based plan, run the full analysis once daily rather than hourly. The time-lag is usually acceptable for process improvement.
Cost Breakdown
| Tool | Plan Needed | Monthly Cost | Notes |
|---|---|---|---|
| Accio AI | Professional | £40–80 | Scales with extraction volume; 1000+ extractions/month fits most teams |
| Cogram | Team | £60–120 | Analysis-heavy tier; supports batch processing |
| Terrakotta AI | Business | £50–100 | Document generation; typically 1–2 calls daily |
| n8n | Self-hosted (free) | £0 | No licensing cost; only cloud hosting if you use n8n Cloud (£20–50/month optional) |
| Your support platform API | Existing | Included | Assuming you already pay for Zendesk, Intercom, Freshdesk, etc. |
| Total | £150–350 | Highly cost-effective for a team of 5–20 people handling 500+ complaints monthly |
The workflow pays for itself if it saves even a few hours of manual analysis per week. Most teams report 8–15 hours of analyst time saved monthly, which at £25–40 per hour easily justifies the cost.