Macha

Designing a Zendesk Custom Ticket Status Model

Abbas, Customer Support & AI, Macha

Written by

Ankeet Guha, Co-founder & CTO, Macha

Reviewed by

Published September 9, 2026

Updated September 9, 2026

A Zendesk custom ticket status is a label attached to a built-in status category, and only four of the six accept one. It is not a new workflow state. Everything that drives your automation reads the category underneath while the label sits on top, which means each custom status you add is another thing for agents to pick, and only some of your workflows can tell the difference. This guide covers what the category actually controls, how to count which of your statuses are being used, and what to do with the ones that are not.

Designing a Zendesk Custom Ticket Status Model

The mechanism: category first, label second

Every ticket carries two fields. status holds the category, one of six values Zendesk defines: new, open, pending, hold, solved, closed. custom_status_id points at whichever custom status is applied.

Custom statuses sit on top, but not on all six. Zendesk is explicit that "you cannot assign a ticket status to the New or Closed status categories", so in practice you get four: Open, Pending, On hold and Solved, and On hold only appears if that status is activated. Category is also fixed once set, since "you can't move it to a different status category".

That constraint explains something in our own data below. "New on-boarding request" sits under open despite its name, because Zendesk won't let you file a status under New. SLA targets key off the category, so two custom statuses under pending are identical to a policy: Zendesk states that "the SLA metrics use the status categories instead of the custom ticket statuses you created". Triggers, automations and views are converted to the Status Category condition when you activate custom statuses but can be pointed at a specific ticket status afterwards, and a trigger action can set one. Explore reports on the label directly through the Ticket custom status name attribute. The custom label is what an agent sees in the status dropdown and what an end user sees on their request.

So the label is real to agents, to customers and to Explore, and invisible to your SLA policies. Creating "Waiting on vendor" under pending does not create a state your SLAs can treat differently from ordinary pending. If you want different SLA behavior you need a different category or a different field, not a different label.

What status sprawl looks like

Here is the ticket statuses page on a Zendesk Enterprise demo instance. Zendesk groups the list by category and prints its own description for each one.

Zendesk ticket statuses across four category headings, with a misspelled status and two blank descriptions
Zendesk ticket statuses across four category headings, with a misspelled status and two blank descriptions

Three things in that screenshot are worth noticing, and none of them are unusual.

A misspelled status is live. "Escelation" appears in the agent view and, in the right-hand column, in the end user view as well. Customers are reading the typo on their own requests.

Two custom statuses have no description at all: "New on-boarding request" and "On-going investigation". "New on-boarding request" and "On-going investigation" both have an empty description column, so an agent picking it has nothing telling them when it applies.

All three custom statuses sit in a category that already had one. "Escelation" and "New on-boarding request" sit under open alongside the built-in Open, and "On-going investigation" sits under pending alongside Pending. Nothing about them behaves differently from Open.

Count what's actually used

This is the number nobody has, because the admin page does not show it. The Admin Center statuses page has no usage column, no last-used date and no way to sort by adoption, so a status created once in 2024 looks exactly like the one your team uses hourly. Explore can report on it, which is the vendor's answer, but it doesn't help the admin standing on the page deciding what to cut.

You can get it from the API in a loop. List the statuses, then count tickets against each one:

GET /api/v2/custom_statuses.json
GET /api/v2/search/count.json?query=type:ticket custom_status_id:<id>

Wired together, that is a short script. It prints one row per status and needs nothing but curl and jq:

#!/usr/bin/env bash
# status-usage.sh — how many tickets actually use each ticket status.
Z="https://$ZD_SUBDOMAIN.zendesk.com/api/v2"
A="$ZD_EMAIL/token:$ZD_TOKEN"
total=0

printf '%-26s %-9s %-9s %7s\n' "NAME (agent view)" "CATEGORY" "STATE" "TICKETS"
while IFS=$'\t' read -r id cat label active; do
  n=$(curl -s -u "$A" -G "$Z/search/count.json" \
        --data-urlencode "query=type:ticket custom_status_id:$id" | jq .count)
  [ "$active" = "true" ] && state=active || state=inactive
  printf '%-26s %-9s %-9s %7s\n' "$label" "$cat" "$state" "$n"
  total=$((total + n))
done < <(curl -s -u "$A" "$Z/custom_statuses.json" \
         | jq -r '.custom_statuses[] | [.id, .status_category, .agent_label, .active] | @tsv')

# %53s pads by BYTES, and the box-drawing character is three of them, so a naive
# width lands the rule well left of the column. Pad with spaces, then print it.
printf '%*s%s\n' 46 '' '────────'
printf '%54s\n' "$total"
Script output: eight ticket statuses with category, state and ticket count, totalling 499
Script output: eight ticket statuses with category, state and ticket count, totalling 499

Run against the instance above, 499 tickets:

StatusCategoryTickets
Newnew347
Solvedsolved121
Openopen27
Pendingpending3
Escelation (custom)open1
New on-boarding request (custom)open0
On-going investigation (custom)pending0
On-hold (inactive)hold0

Three custom statuses were created. Between them they hold one ticket out of 499, and two have never been used at all.

Two caveats on that number, because they matter. The 499 is a sum of the per-status counts, so it is no independent measure of the corpus, and closed tickets need thinking about. Zendesk documents that "any tickets that are solved with a status in the Solved status category retain that ticket status even after they are closed", so a Solved-category custom status can carry closed tickets that this count may not reach. Treat the totals as a floor. And this is a demo instance: 347 of the 499 are still sitting in New, which tells you nobody there works tickets the way a real desk does. The shape of the finding transfers. The magnitude is not a benchmark.

Why the list grows

It's worth naming the incentive, because the sprawl isn't carelessness. Zendesk puts Create ticket status as a primary blue button on the page and surfaces no adoption data on it at all. Creating one is a single click; discovering that it was never used requires writing an API loop. A vendor building a feature naturally optimizes for that feature being adopted, and the interface reflects that.

Nothing here is dishonest. The effect is that the cheapest action is always to add another status, and the cost of doing so never surfaces where an admin would see it.

What sprawl actually breaks

Not your workflows. Everything category-driven keeps working, which is exactly why nobody notices.

What it breaks is reporting. In Explore, a "tickets by status" breakdown now splits your open tickets across three labels instead of one. Anyone building a dashboard has to know that Escelation and New on-boarding request are open tickets, or their numbers are wrong. That knowledge lives in someone's head rather than in the data model.

It also degrades the agent's decision. A dropdown with eight statuses defined and seven active where three mean the same thing takes longer to use and produces less consistent data, and inconsistent status data is what makes the reporting problem worse over time.

Designing a model that holds

One status per genuinely distinct state, per category. If you can't say what a person does differently when a ticket is in this status versus the built-in one, you don't need it.

Write the description. It's the only place the rule lives. An empty description means the status means whatever each agent assumes.

Check the end-user label separately. It's a different field, and it's the one your customers read. A typo there is public.

Use tags or a custom field for reasons, not statuses. "Waiting on vendor" and "Waiting on customer" are usually both pending. The distinction is a reason, and reasons belong in a field you can report on without fragmenting the status dimension.

Deactivate rather than delete. Deactivating leaves historical tickets intact and readable, and Zendesk warns to check your business rules first because rules referencing a deleted status stop running. On our instance "On-hold" is deactivated, which is why it is missing from the statuses page above, filtered to Active. The API loop still returns it, which is the point of counting from the API.

Re-count quarterly. The API loop above takes a minute. Any status at zero after a quarter is a candidate for deactivation.

If you want the definitional layer rather than the design one, our guide to Zendesk ticket statuses covers what each built-in status means. This post is about auditing and designing the custom layer on top.

Scope statuses to the forms that need them. If the list is long because different teams need different statuses, you don't have to shorten it for everyone. Zendesk lets you associate ticket statuses with forms, which "results in a shorter list of ticket statuses in the status picker" for the agents on that form. It is the tab next to Ticket statuses on the same page, and on Suite Growth and above it is usually a better answer than deleting a status somebody still needs.

One more thing worth checking before you read a status as sprawl: if your account was created on or after 13 February 2024, Zendesk seeded an extra In Progress status into the Open category for you. A status nobody remembers creating is not always evidence that somebody created it.

Common questions

What's the difference between status and status category in Zendesk? The category is one of six fixed values (new, open, pending, hold, solved, closed) and drives SLA behavior. A custom status is a label mapped to a category, and only four categories accept one: Open, Pending, On hold and Solved.

Can I change a custom status's category later? No. Zendesk states that "you can't move it to a different status category" once created, so the category choice is permanent.

Can I delete a custom ticket status? Deactivate it instead. Deactivation keeps historical tickets readable and stops the status appearing in the dropdown for new work.

Do custom statuses affect SLA targets? Only through their category. Two custom statuses under pending are identical as far as SLA policies are concerned.

Can I hide Zendesk's default statuses? The built-in statuses can't be removed, though some can be deactivated. Note also that the status picker shows the first 10 active statuses, and an account is capped at 100, so sprawl has a hard edge.

How do I find out which statuses my team actually uses? The admin page doesn't total it for you, though Explore does report on the status label. For a quick count, loop /api/v2/search/count.json with custom_status_id:<id> for each status, as above. See our Zendesk API guide if you haven't used the search endpoint before.

Where an AI layer fits

A status model tells you where a ticket sits. It doesn't decide what happens next, and no amount of status design will, because that decision needs someone to read the ticket.

Macha runs on top of the Zendesk you already have. It reads the ticket, including custom field values and attachments, and can classify it, write the status and custom field values back, add an internal note, or post a public reply, using your existing triggers and webhooks as the entry point. Because it writes the fields you already defined, your status model stays the system of record. It suits teams already committed to Zendesk who want agents acting inside the ticket. Setup runs through the Zendesk integration, and billing is per ticket, so one thread with one person is one charge however many replies it takes.

Start your free trial and connect your Zendesk in a few minutes.

Macha

About Macha

Macha is an AI agent platform that works on top of the help desk you already use — Zendesk, Freshdesk, Gorgias, or Front — and connects to the rest of your stack, even your own internal systems. Its AI agents resolve tickets and automate entire workflows end to end, all set up in plain English, no code. Learn more about Macha →

Zendesk
5.0 on Zendesk Marketplace

Loved by support teams worldwide

See what support teams are saying about Macha AI.

The application seems excellent to me! We are still testing, and we need support for some details and they were extremely efficient too!

Daniela Costa

Daniela Costa

Head of Support, Seabra

Macha has been a great addition to our support toolkit. It generates clear, well-organized responses that fit naturally into our workflow. One feature we particularly appreciate is its ability to automatically reply in the same language as the ticket.

Marius F

Marius F

Support Head, Zentana

We've been using Macha for a little while now and it's been really great addition so far! It's powerful, convenient, and makes getting work done a lot easier for our agents.

Alexander Wedén

Alexander Wedén

Head of Support

Support team is very helpful and responsive. Really enjoy how lightweight this is within Zendesk itself vs other more intrusive tools.

Cathleen Wright

Cathleen Wright

Zendesk Admin, Cortex IO

So far it's pretty good! Our queries are a little nuanced, so we can't always use it, but it's got enough utility for us. It can even incorporate our bilingual country with greetings in a second language.

Jae Oliver

Jae Oliver

Head of Support, Wise

Really enjoying using Macha, it has made a noticeable difference to our support team in a short amount of time. I really like the ticket summary feature, saves us a lot of time.

Harry Jackson

Harry Jackson

Head of Support, Crumb

Macha AI is a great addition to my workspace! It's powerful, convenient, and it really makes productivity so much easier for our agents!

Dave G

Dave G

Head of Support, Cyber Power Systems

Very impressed! AI integration for Zendesk has certainly come a long way and Macha seems to set the standard for now. This will for sure save lot of time in our support team.

Pauli Juel

Pauli Juel

Head of CS, Dokument24

Macha has been working great for us so far! The auto-responses are accurate and our resolution time has dropped significantly.

Lana T

Lana T

Zendesk Admin, Swotzy

Macha AI is a great addition. The knowledge base feature means our agents always have the right answers at their fingertips.

Mischa Wolf

Mischa Wolf

Head of Support, Topi

We're enjoying this integration so far. It's made our support team more efficient and our customers get faster responses.

Paula G

Paula G

Head of Customer Support, Xly Studio

The team enjoys using it. It saves considerable time on common questions and the integration options are excellent.

Kilian Leister

Kilian Leister

Support Head, Didriksons

Ready to supercharge your team with AI?

Get started in minutes. Connect your tools, configure your agents, and let AI handle the rest.

500 free credits · no time limit, no credit card