# Field report: building a Zendesk replacement with AI, 24 checks and 21 spec gaps

Source: https://personalsoftwarefactory.com/guides/zendesk-replacement-build-test
Updated: 2026-10-17

> We had an AI builder build a small-team help desk from our spec, one phase at a time, and checked every acceptance item in a real browser. It passed all 24 checks in the end, and exposed 21 gaps in the spec, the most of any build so far. What it took, what broke, what it costs next to Zendesk, and what we still haven't tested.

## The short answer

Yes, for a small team answering support email. We gave Claude, working in Type, our [Help Desk blueprint](/blueprints/help-desk) and had it follow the four phase prompts in order. The final build passed **24 of 24 acceptance checks** in one browser run on a fresh database, with **64 automated tests**. It handles tickets from email and a web form, Zendesk's six statuses and lifecycle rules, public replies and internal notes, email threading, first-response targets, canned replies, weekly reports, CSV export and deleting a customer's data on request.

It was also the hardest of our [thirteen build tests](/how-we-test). The build exposed **21 gaps in the spec**, places where the builder had to guess because the spec was silent, ambiguous or contradicted itself. That is the most of any blueprint we have tested; the median across the other twelve is 8. Every gap is now fixed in the published spec.

What it is not: a tested production deployment. Real email in and out, production sign-in, a real scheduler and hosting were not part of the test. The [last section](#what-we-did-not-test) lists exactly what was and wasn't checked.

## What we built, and what we left out

The blueprint copies the part of Zendesk a team of 2 to 25 people uses when support arrives by email. We read Zendesk's pricing page and its help center articles on ticket statuses and triggers in October 2026, and kept their rules where a small team needs them:

- **Six statuses, the Zendesk way.** New, Open, Pending, On-hold, Solved and Closed. Assigning a New ticket opens it. A customer's reply reopens a Pending, On-hold or Solved ticket. Nobody can set Closed by hand: the system closes Solved tickets after four days, and a reply to a closed ticket starts a follow-up ticket that links back to it.
- **One owner per ticket.** A ticket can't be solved without an assignee, and you can't deactivate an agent who still has open tickets.
- **Replies that thread.** Every public reply is emailed with the ticket number in the subject and the right `In-Reply-To` header, so the customer's answer lands back on the same ticket.
- **Internal notes that stay internal.** Notes are never emailed, quoted or included in anything the customer receives.
- **First-response targets.** Each priority has a target (Urgent 1 hour, High 4, Normal 8, Low 24), and the queue shows Due soon and Overdue, oldest first.
- **A stale-reply warning.** If a colleague replied while you were writing, sending stops with "Ben Cho replied 2 minutes ago. Review the ticket before sending." Your draft is kept.

Left out on purpose: live chat, phone, social channels, AI agents and AI replies, a knowledge base, a trigger builder, skills-based routing, business-hours targets and satisfaction surveys. If you need those, Zendesk's Suite plans include them.

## What it costs next to Zendesk

Zendesk prices per agent per month. On the prices we saw on zendesk.com/pricing in October 2026:

| Team | Zendesk Support Team ($19 per agent per month, paid yearly) | Zendesk Suite Team ($55 per agent per month, paid yearly) |
|---|---|---|
| 3 agents | $684 a year | $1,980 a year |
| 5 agents | $1,140 a year | $3,300 a year |
| 10 agents | $2,280 a year | $6,600 a year |

The build has no per-seat price, but it isn't free: you pay for hosting, a database, an email provider for sending and receiving, and the time to build and look after it. For a team on Support Team with a handful of agents, the saving is a few hundred dollars a year. The case for building is stronger when you'd otherwise need a Suite plan, when you want rules Zendesk doesn't offer on your plan, or when you want the tickets in your own database. Our [build-or-buy guide](/guides/build-vs-buy-saas) has the full decision.

## How the build went, phase by phase

The builder received the blueprint as one Markdown file and sent itself the four phase prompts one at a time. After each phase, the acceptance checks for that phase ran as browser scripts that click through the app as the named person, starting from a fresh load of the seed data. After the last phase, all 24 checks ran again in one final pass.

1. **Foundation.** Agents, sign-in for development, the seed data and the ticket model.
2. **Queues, tickets and replies.** The five queues with counts, the ticket page, public replies and internal notes, the first-response states and the stale-reply warning.
3. **Email in, threading and follow-ups.** An inbound email endpoint fed by an email provider, threading by ticket number and message headers, duplicates ignored, follow-ups to closed tickets.
4. **Auto-close, reports and data deletion.** The scheduled job that closes solved tickets, weekly reports, CSV export and deleting a customer's data.

Each phase prompt ends with one sentence: "list what you built and anything in the spec you had to interpret." That sentence is what surfaced the gaps.

## The 21 gaps, grouped

The full list, with each fix, is in the [blueprint's build notes](/blueprints/help-desk). They fall into five groups.

### The seed data couldn't support the checks (4 gaps)

The seed agents had no email addresses and the seeded tickets had no messages, so checks that open a ticket's thread had nothing to show. One seeded ticket was "solved by" a reply sent a day before it could have been. A deletion check couldn't fail on fresh data because there were no outbox rows to delete. And only the last phase told the tester to reset the seed before running checks, so earlier phases' checks ran on data later phases had already changed.

**Lesson:** seed data is part of the spec. Every check needs data that can make it fail.

### Numbers on a boundary, or with no rounding rule (3 gaps)

The worked example for ticket #1001 sat exactly on the Due soon boundary, so "Due soon" and "Due in 1 h" were both defensible. The spec quoted exact durations without saying how to round them. A report check depended on which weekday the seed was loaded.

**Lesson:** don't put worked examples on a boundary, and say how every displayed number is rounded.

### Sections that disagreed with each other (4 gaps)

One rule said a ticket stays New until it is assigned or replied to, while the lifecycle table let an agent change its status directly. The threading rule had no sender check, which contradicted an edge case that said a stranger's reply must not attach to a ticket. The builder followed the earlier wording, as builders do. "Tickets solved" in the reports had two readings, and the Solved queue didn't say whether Closed tickets belong in it.

**Lesson:** when two sections describe the same behaviour, one of them will drift. Say it once and refer to it.

### Things the spec required but never defined (4 gaps)

The data model had nowhere to store the support form's rate limit, a ticket-number counter that survives deletion, or email retry attempts. No screen showed the deletion event a check inspects. The queues' sort orders were ambiguous, and the spec required an audit trail without listing which events each action writes. The builder invented answers for some of these and skipped others.

**Lesson:** for every rule, ask where its data lives and where someone will see it.

### Email is where the real-world details hide (6 gaps)

Common email providers can't send the Bearer header the inbound endpoint required, so it now also accepts HTTP Basic auth. "The last email in the thread" could pick up an internal note. A requester without a name broke the canned-reply greeting. The spec didn't say how a long inbound subject becomes a ticket subject, what happens when a solved ticket's assignee has been deactivated and the customer replies, or which header the scheduler sends and how many times a failed email is retried.

**Lesson:** any feature that talks to the outside world, here inbound and outbound email, needs its exact formats, headers and retry rules written down. That is consistent with what we saw across all thirteen builds: the [hiring pipeline](/blueprints/hiring-pipeline), with a public form and data retention, had the second-most gaps (18). See [What AI app builders get wrong](/guides/what-ai-builders-get-wrong) for the patterns across every build.

## What we did not test

- **Production sign-in.** Google sign-in was built, but every check used the development "sign in as" switcher.
- **Real email, in and out.** Outgoing emails were logged in the outbox. Inbound email was tested with requests in the endpoint's JSON shape, and a unit test posts Postmark's documented example payload.
- **The hourly schedule.** The job endpoint and the "run job now" control were tested, not a real scheduler.
- **Hosting.** The test build ran on SQLite on one server. Secure cookies over HTTPS and the rate limit behind a real proxy were not tested.

These gaps are not special to the help desk. We list what every build left untested in [Is an AI-built internal tool ready for production?](/guides/ai-built-tools-production-readiness).

## Build it yourself

The [Help Desk blueprint](/blueprints/help-desk) is free: one Markdown file with the data model, the 15 business rules, screens, seed data, the four phase prompts and all 24 acceptance checks, with the 21 fixes already in. Paste it into Claude, ChatGPT, Cursor, Lovable, Replit or Type and send the phases one at a time. If you find a gap we missed, tell us on the [About page](/about) and we'll fix it and credit it in the build notes.
