# Agents

An agent is the profile an end user sees next to a reply. It is Support's own entity — not a projection of a Lessly account, not a copy of your workspace member list — and it exists because two different people need it: your end user, who reads "Maria from support replied", and you, who wants to configure what that says.

## The profile as it ships

An agent has one required field and four optional ones.

| Field | What it is |
|---|---|
| `displayName` | Required. The name shown next to this agent's replies, up to 255 characters |
| `title` | Job title shown under the name, e.g. "Support engineer". `null` if unset |
| `avatarUrl` | Absolute URL of an avatar image, up to 2048 characters. `null` if unset |
| `lesslyUserId` | The bound Lessly identity, or `null` for an unbound profile |
| `isActive` | `true` until the profile is deactivated |

Plus `id`, `createdAt` and `updatedAt`, which Support sets.

That is the entire profile. There is no signature block, no role or permission field, and no per-agent settings: what an agent may do follows from who called the API, not from the profile the call names.

## Binding a Lessly account

`lesslyUserId` is the seam between the two contours, and it is optional on purpose.

Bind it when a human should sign into the Workspace app and work as this profile. The value is stored verbatim, as an opaque string: nothing resolves it, nothing asks the platform whether that user exists, and nothing enriches the profile from it. Support records the binding — it does not read the platform's user directory.

The binding never leaves the authenticated plane. A profile read through the public HTTP perimeter comes back with no `lesslyUserId` key at all — absent, not `null`, because `null` here already means an unbound profile — so a response that seems to be missing the field is not a bug on your side; see [Public HTTP API](/ship/support/public-api#lesslyuserid-is-absent-here-not-null).

Leave it empty for a bot or for your own backend. An unbound profile is a first-class agent: it is assigned to threads and authors outbound messages exactly like a human one. The only thing it cannot do is receive a personal notification, because there is no workspace member behind it to notify.

At most one agent per product may claim a given Lessly user. Creating or updating a second agent with a binding that is already taken is refused as a conflict. Any number of agents may claim none.

## Creating, reading and editing

[`support_agent_create`](/reference/mcp-tools/support_agent_create) takes `displayName` and whichever of the optional fields you have.

[`support_agent_list`](/reference/mcp-tools/support_agent_list) returns the product's agents ordered by display name, and hides deactivated ones unless `includeInactive` is set. [`support_agent_get`](/reference/mcp-tools/support_agent_get) returns one by id, deactivated ones included — a screen rendering old messages has to be able to resolve their authors. An agent of another product is reported as not found, never as forbidden.

[`support_agent_update`](/reference/mcp-tools/support_agent_update) edits the profile, and it distinguishes two things a looser schema would flatten: an absent key leaves a field alone, an explicit `null` clears it. So `{"title": null}` removes the job title and `{"lesslyUserId": null}` unbinds the profile from its Lessly account, while omitting either leaves it as it was.

## Assignment

A thread has at most one assigned agent. [`support_thread_assign`](/reference/mcp-tools/support_thread_assign) sets it:

```json
{ "id": "b50f26b4…", "agentId": "13c893aa…" }
```

Passing `null` instead of an id returns the thread to the unassigned queue. That is an ordinary move, not an error, and it stays available even when the current assignee has since been deactivated.

The agent must belong to this product — one that does not is reported as not found — and must be active. Assigning a deactivated agent is refused.

Assignment is the only place Support routes anything. It does not round-robin, does not balance load, and does not assign anyone on its own: a new thread arrives unassigned and stays that way until something assigns it.

## Deactivation instead of deletion

There is no way to delete an agent. An agent authors messages, and deleting one would take the authorship of everything it ever wrote with it.

Setting `isActive` to `false` retires it instead. A deactivated agent keeps every message it wrote and stays on every thread it already sits on; what it loses is the right to be assigned to another one. Reactivating is the same call with `true`.

Deactivation is not anonymisation and does not silence the profile: it gates assignment, and nothing else. A message authored by a deactivated agent is accepted — which is what lets your backend finish a conversation a retired bot profile was holding.

## Where to go next

- [Threads and messages](/ship/support/threads-and-messages): the messages agents write.
- [Notifications](/ship/support/notifications): when an assignment reaches a person.
- [Tools, SDK and errors](/ship/support/tools-and-errors): every tool named here, and how it is called.
