How to handle customer complaints at a small firm without a help desk

A client emails that the revised file is late. Your account lead replies on a call, says "I will sort it out by Friday" and goes back to other work. Nobody else heard the promise, nobody wrote it down, and on Friday the client is still waiting. The original problem was small. The missed promise is the complaint that costs you the account, a review or a dispute. This guide shows how to handle customer complaints at a small firm without a help desk: one owner per complaint, a limit on what each role may concede, and a weekly Slack check that finds promises whose date has passed. It gives you a log you can build in a spreadsheet today and a Slack routine that keeps it honest.
It is for the person who owns the outcome at a firm of 5 to 100 people, not for consumers filing a complaint or support teams working tickets.
The short version
Handling a complaint at this size comes down to five rules. The rest of the article implements them.
- Every complaint gets one named owner within a business day, whoever heard it first.
- Every complaint becomes one row in a shared log with seven columns, including what was promised and the date it was promised by.
- Each role has a written limit on what it may concede without asking, in dollars and in hours.
- A row is not closed when the customer is answered. It is closed when the promised action is done and the customer has had a chance to say it worked.
- Once a week, someone reads the log for promises past their date. In Slack, the agent can do that read and post the result.
Why complaints go wrong at a small firm
Most advice on this topic is accurate and still leaves a small firm stuck. Xero's guide gives seven steps and says to acknowledge a complaint within 24 hours, even when you have no solution yet. Its process advice is documentation, response standards and follow-up, and it does not say who approves a discount or what the record should look like. Another guide, from Help Scout, a support software vendor, argues that staff should have permission to make guided judgement calls on refunds and extensions instead of passing the customer up the chain, and that a follow-up system should confirm that the promised refund or replacement was delivered. That is good advice for a company with a support team, and a small firm has neither the team nor the system.
The gap shows up in three places.
Ownership is by accident. The complaint belongs to whoever saw the email first, or whoever the customer called. SessionTalk's complaint guide, which is vendor marketing for a phone product but has the most operational detail of the three, says the complaint should have one owner who is responsible for movement and communication, even when other people do the investigating. It says the customer should not have to chase each department.
Authority is unwritten. The same guide says to define what each role can do without waiting for approval and gives examples: frontline staff rearrange a missed appointment or waive a modest fee, team leads approve a replacement or a larger credit, owners handle exceptional settlements and anything risky. It gives no amounts, which is correct, because the amounts depend on your margins. But a small firm that reads "define approval limits" and moves on has nothing written, and each teammate guesses. The guess is either too low, so every small fix waits a day for the owner, or too high, so credits leak.
The promise lives in one head. SessionTalk's guide says a promise is not a resolution until the replacement arrives, the fault is tested or the appointment happens. If the log records "customer upset, looking into it" and not "will send revised file by Friday 3 pm", there is nothing to check on Friday.
Community accounts show what happens when the decision is made under pressure instead of in advance. In one Hacker News thread, a small software owner describes a customer who disputed a payment a year after buying, then threatened bad reviews and a police complaint over about 200 dollars. Commenters split between refunding to end it and holding firm. That is one owner's account, not a measured pattern, but it shows the cost of having no rule: the owner is deciding alone, angry, with no written limit to point to.
The complaint log: seven columns and nothing more
A firm with no help desk does not need a case-management tool. It needs one Google Sheet that everyone can add to. SessionTalk lists a dozen possible fields, including severity, evidence, root-cause tags and follow-up dates. Those are useful at scale. At 5 to 100 people, seven columns carry the job, and each earns its place.
| Column | What goes in it | Why it exists |
|---|---|---|
| Customer | Account or person, plus a link to the CRM record | So nobody asks them to explain again |
| Date received | The day the complaint arrived, by any channel | Starts the 24 hour acknowledgement clock |
| Issue | One or two plain sentences of what happened and the effect on them | The customer's own words where you can |
| Owner | One named person | The only column that can never be a team name |
| What was promised | The credit, redo, callback or answer, exactly as said | The thing the weekly check will test |
| Promised by | A real calendar date, not "this week" | The date the weekly check sorts on |
| Status | Open, Action done, or Closed | Two finish lines, explained below |
Promised by must be a date. A cell that says "end of week" cannot be checked by a person at 9 am on Monday and cannot be checked reliably by an agent either. If the owner does not know the date yet, the promise is "an update by" a date. SessionTalk's guide says to give a dated next action even when the answer is not yet available, and that a realistic update delivered early builds more trust than an ambitious promise missed. Treat an update as a promise and log it.
Status has two finish lines. "Action done" means the credit was applied, the file was resent or the call took place. "Closed" means the customer has also had a reasonable chance to respond. SessionTalk says to close the record only when the promised action is complete and the customer has had that chance, and warns that a record can be marked closed while the customer is still waiting. Keeping the two statuses separate stops the common failure where the owner sends the fix, marks the row done and never hears that it did not work.
Here is one made-up row to show the level of detail. It is an illustration, not a real customer.
| Customer | Date received | Issue | Owner | What was promised | Promised by | Status |
|---|---|---|---|---|---|---|
| Harbor Lane Studio | 2026-03-02 | Logo files arrived two days after the agreed date; client had to move a print order | Dana | Revised files plus a callback to confirm print specs | 2026-03-06 | Open |
Try Kipwise Agent free in Slack: mention it once in a thread and it does the repetitive work, with your permissions.
Write the concession table before the next complaint
Xero's guide says to offer compensation when you are clearly at fault, such as a defective product or a service not delivered, and that for smaller issues a sincere apology and a quick fix are usually enough. It also notes that refund or remedy obligations can depend on consumer-protection law, warranties and contract terms, so a firm in a regulated sector or with signed terms should check those first. Help Scout's advice is to give staff boundaries and not rigid policies. A concession table is how you turn both into something a teammate can read in ten seconds.
Build it with your own figures. Leave every cell blank until the owner has looked at margins; the table below gives the structure, not the amounts.
| Role | May do without asking | Dollar ceiling | Hours ceiling | Must tell |
|---|---|---|---|---|
| Whoever took the complaint | Apology, a callback, a redo of the disputed item | Owner sets | Owner sets | The owner, in the thread, after |
| Account lead | Fee waiver, a goodwill credit, priority work | Owner sets | Owner sets | The owner, in the thread, before |
| Owner | Anything above, a refund, a settlement | Owner sets | Not applicable | Nobody |
| Always the owner, any amount | Anything involving a dispute, a legal or police threat, a safety, privacy or security issue |
The last row follows SessionTalk's severity ladder, which sends possible safety, security, privacy, legal or serious reputational risk straight to a senior person regardless of how calmly the customer wrote.
Write each concession limit in dollars and in hours, because a free redo or a goodwill call costs staff time that a dollar limit never counts. This is a recommendation, not something the opened guides say. They give tiers by role and, in one case, examples such as a replacement or priority work, but a limit stated only in dollars lets a teammate promise a full redo that costs a day of an expensive person's time and call it free. At a firm that sells hours, the hours column is often the one that actually protects margin. If you already have a dollar limit for spending, the delegation of authority table is a good model for the layout, and the refund policy guide covers the refund half of the same question.
Run it in Slack
Everything above works with a spreadsheet and discipline. The part that decays is the discipline, so put the routine where the complaints already arrive. Slack's help pages describe how threads keep a discussion attached to the message that started it, and in channels you are notified of replies to a thread you started, replied to or were mentioned in. One thread per complaint, in a channel such as #customer-issues, gives each complaint one visible home with its owner already watching.
This is the sequence for the Kipwise agent, using only what it does today.
- Post the complaint. The teammate who received it posts it in #customer-issues and mentions the agent once. Plain replies in that thread continue the conversation without another mention.
- Check the record. With HubSpot connected, the agent looks up the person, the company, deals and tickets using the asker's own CRM access. With Stripe connected, it looks up the customer, payments, invoices and subscriptions. Each is connected separately and uses the asker's own permissions. If it finds nothing, the right outcome is that it says so, and a person checks another way.
- Draft the acknowledgement. The agent writes a draft or reply in the asker's Gmail Drafts. Before anything is sent, it shows the recipient, subject and a preview on an Approve or Deny card, and only the person who asked can use that card. Nothing goes out unless they approve.
- Add the row. The agent can read a range of a Google Sheet and add rows. Each change waits for an Approve card that expires after 30 minutes, and if it expires the row is not added. Editing a sheet is a separate Google connection from reading one, so whoever logs complaints connects it once.
- Decide the concession. The owner decides against the table. The agent does not decide it. The agent can issue a Stripe refund, invoice or coupon only when explicitly asked, and for complaints this guide recommends that the owner or account lead asks, never the first teammate on the thread.
The agent supplies the lookup, the draft and the paperwork. Every conversation with the customer, the size of any credit or refund, any dispute or legal threat and the decision to close a row stay with a person. The agent does not detect sentiment, route complaints or reply to customers by itself, and this article does not claim it does.
The weekly check on every promise
None of the guides above shows how to run this step, and it is where the log pays for itself. SessionTalk suggests a weekly review of about 20 minutes and tracking how often promises are kept. Help Scout says to create a system that confirms the promised refund or replacement was actually delivered. For a firm with no help desk, a person doing that every week is the first thing to slip.
Ask the agent, once, in plain language, something like: every Monday at 9 am, read the complaint log, list the rows where Promised by is before today and Status is not Closed, and show each with its owner. Creating a scheduled task needs your approval once. Later runs post in the channel without asking again, using the same tools and permissions as a live request from the person who set it up, so that person must be able to read the sheet. For the mechanics and failure modes of recurring jobs, the scheduled jobs guide goes deeper.
Sort the weekly check by the promised-by date, not by how old the complaint is, because a customer who was promised a callback on Friday judges you on Friday, not on the day the complaint arrived. An old complaint whose remedy was delivered on time is fine. A two-day-old complaint with a promise that expired this morning is the one that turns into a second complaint. Listing by age, which is what most spreadsheets and ticket views do by default, buries the second kind under the first. This ordering is a recommendation built from the guides' advice to track promises kept, and it fits a small firm because the list stays short.
The Monday post should end with one decision per overdue row, made by the owner of that row in the thread: do it today, move the date and tell the customer, or hand it to someone else and say so.
Handle failure and edge cases
The agent finds nothing in the CRM or Stripe. That can mean a different name, a different email or a customer who was never billed through that account. Ask the teammate for another identifier, and do not draft an acknowledgement that states facts the lookup did not confirm. Acknowledge, and promise only the next update.
Two people already replied. Pick the owner in the thread and say so. The customer should hear from one person, which is the point of SessionTalk's one-owner rule. The other person logs what they said in What was promised, because the customer remembers the words, not the log.
The complaint is really a scope request. A client who says the work is wrong sometimes wants something the contract never included. Log it, then follow the scope creep guide for the conversation instead of conceding by reflex. Xero's guide says that for an unreasonable request you should listen, explain your side calmly with facts and aim for the customer to feel heard even when you cannot meet the request.
The customer is angry in public. An unresolved complaint can turn into a negative review. Xero advises resolving issues privately and quickly before customers feel compelled to post. After a good resolution, the review request guide covers the other half of the same customer relationship; ask only after the row is Closed.
The weekly post does not arrive. Silence is not an all-clear. Ask the agent to list your scheduled jobs and what happened on earlier runs, including failures, and check that the sheet link and your access still work. Put a standing line in your Monday routine: if there is no post by 10 am, read the sheet yourself.
It is regulated or serious. Some sectors have complaint deadlines and handling rules written into law or licence terms. This guide is operational advice, not legal advice, and a regulated firm should add its own rules to the table first.
Verify it works
Run it on the next ten complaints before you call it a process. Three checks, read from the sheet and not from memory:
- Every row has an owner and a real Promised by date. Count rows missing either. The target is zero.
- Promises kept. Of the rows whose Promised by date has passed, how many were done on time? SessionTalk names this promise kept rate and the reopen rate as measures worth tracking. At your size you only need the raw counts.
- Reopens. How many rows marked Closed came back? If any did, read that row and ask whether Action done was marked too early.
Then read three or four rows end to end, because numbers alone can reward rushed closures.
What to do next
Today, open a new Google Sheet, paste the seven column names across row one, and add the one complaint that is open right now, with a real Promised by date. Then fill in the concession table for your own firm, dollars and hours, and send it to the two people who take most of your complaints. If you want the Slack routine, add the Kipwise agent to your workspace. Pricing is $10 per user per month, with a minimum of 3 users, and the install trial is $2 for 7 days on the fast model, or a $10 trial for 14 days with all models if you save a card or are on a paid Slack plan. Ask it to look up one real customer and draft an acknowledgement, and see whether the draft would have gone out the way you would have sent it.



