# Statuses

A status is where a thread sits. Support does not fix the list: your product owns its own dictionary, and every status in it carries a **category** that Support reads instead of the name.

## Names are yours, categories are ours

A status has a `name` your customers and specialists see, unique within the product, one to a hundred characters. It has a `color` — a six-digit hex string such as `#2563eb` — and an `order`, the position it takes in the dictionary, lowest first.

It also has a `category`, and there are exactly four: `open`, `pending`, `resolved`, `closed`. This is the level Support itself understands. The queue filter groups by it, the one piece of automation Support has keys off it, and nothing anywhere reads a status name.

That split is the point of the dictionary. Rename `pending` to "waiting on customer", split `open` into "triage" and "in progress", add "won't fix" in the `closed` category — none of it changes behaviour, because behaviour was never attached to the names.

## The seeded default set

A thread cannot exist without a status, and Support gets no hook to run when a product starts using it. So the dictionary seeds itself the first time it is read: [`support_status_list`](/reference/mcp-tools/support_status_list) on a product that has never touched its settings creates four statuses, one per category, and returns them.

| Name | Category | Colour | Order |
|---|---|---|---|
| `open` | `open` | `#2563eb` | 0 |
| `pending` | `pending` | `#d97706` | 1 |
| `resolved` | `resolved` | `#16a34a` | 2 |
| `closed` | `closed` | `#6b7280` | 3 |

Seeding is idempotent and safe under concurrency: two calls racing on a fresh product still produce one set of four.

`support_status_list` returns the dictionary in display order — by `order`, ties broken by name — and hides archived statuses unless `includeArchived` is set.

## Adding and editing

[`support_status_create`](/reference/mcp-tools/support_status_create) takes all four fields; none is optional, because a status with no colour or no position has nowhere to render. A duplicate name in the same product is a conflict.

[`support_status_update`](/reference/mcp-tools/support_status_update) changes `name`, `color`, `order` — and `category`, but only while no thread references the status. Once threads sit on it the category is frozen, and asking to change it is refused as a conflict naming the status. The reason is history: the category is what every metric is derived from, so re-categorising a status in use would silently rewrite what those metrics said about the past. The way forward is to create a status in the category you want and move the threads to it.

Order is a plain integer you set; Support does not renumber the others for you, and duplicate orders are legal — they simply fall back to sorting by name.

## Retiring one

There is no delete. A status that threads sit on cannot be made to vanish without deciding what happens to those threads, so the only way out is [`support_status_archive`](/reference/mcp-tools/support_status_archive), and it takes that decision as an argument:

```json
{ "id": "d6284a3e…", "targetStatusId": "4463741a…" }
```

Every thread on the archived status moves to the target in the same transaction that flips the flag, so there is no moment at which a thread points at an archived status. The target must be a different status of this product, and it must itself be live — archiving into an archived status is refused.

An archived status stays readable, so old threads and reports still render its name, and it is refused as a destination from then on.

## The one automatic transition

Support moves a thread by itself exactly once.

A **public inbound** message posted to a thread whose status is in the `pending` category pulls that thread back onto the product's default open status — the non-archived `open`-category status with the lowest order. The move happens in the same transaction as the message, so a thread is never left one without the other.

Each of the three conditions is doing work:

- **Inbound**, because the rule is "the customer came back". An outbound message is the support side talking, which is usually what put the thread on `pending` in the first place.
- **Public**, because an internal note is invisible to the end user and therefore no evidence that they replied.
- **`pending` category**, because a thread anywhere else is not this rule's business. An `open` thread stays on whichever `open`-category status it is on, custom or not; a `resolved` or `closed` thread is not reopened by a reply.

It reads the category, never the name — so the rule survives renaming `pending` to anything you like, and it applies to every `pending`-category status you invent, not only the seeded one.

Everything else is a deliberate move. [`support_thread_status_set`](/reference/mcp-tools/support_thread_status_set) takes the destination and nothing more:

```json
{ "id": "b50f26b4…", "statusId": "87e60f77…" }
```

There are no transition rules: any status may follow any other, in any order, and a thread may go back and forth. The category is never a parameter — it is a property of the status the thread lands on, and accepting it separately would let a caller assert a category the status does not have. A status of another product is reported as not found; an archived one is refused.

## Where to go next

- [Threads and messages](/ship/support/threads-and-messages): the threads that sit on these statuses.
- [Notifications](/ship/support/notifications): why a status change is not worth a bell.
- [Tools, SDK and errors](/ship/support/tools-and-errors): every tool named here, and how it is called.
