# Vocabulary

URL: https://better-helpdesk.com/docs/vocabulary/

The words Better Helpdesk gives a fixed meaning, as they appear in its configuration, its API and these docs.



Several everyday words mean one particular thing in Better Helpdesk. The code, the types and these docs use them consistently, so knowing them makes the rest easier to read. The first one matters most.

## Agent [#agent]

An **agent** is a member of your support team: a user of your app whose identity came back with `isAgent: true`. Agents work in the agent UI, answer conversations and own deals. Their first request writes an agent row keyed to your user id. The identity may name a **role**: an `agent` works the queue, a `supervisor` also receives service-level notices and, once one exists, alone changes settings and the team, and a `viewer` reads and changes nothing. The **audit log** records every change an agent made through the agent UI.

An agent is never an AI. AI is the optional `ai` adapter, and what it produces is either a **suggestion**, a triage of type, priority, title and likely duplicates that an agent accepts or dismisses, or a **draft** reply that an agent may edit and send.

## People and identity [#people-and-identity]

The **host** is your app, the one Better Helpdesk is mounted in. It owns users, sessions and organizations.

`identify(request)` is the function through which the host says who is asking. It returns an **identity**: a `user`, the `orgs` they belong to, and `isAgent`. From another origin, where `identify` cannot see the session, the host signs an **identity token** instead, a short-lived JWT the widget sends along. A token never grants the agent UI.

In the database, an identity row is one way the helpdesk knows a person: a channel (`host` for your user id, `email` for an address, `visitor` for a browser token), the id in that channel, and whether it is **verified**, meaning proven by your app or by a signed email rather than only typed in. One person can have several.

A **customer** is anyone on the widget's side, signed in or not. A **visitor** is a customer nobody has signed in, known only by the visitor token their browser keeps.

## Contacts and companies [#contacts-and-companies]

A **contact** is a person, and a **company** is an organization. A company is linked to one of your organizations by its id, `externalOrgId`. Both carry a lead stage, tags and custom field values, and together they are the CRM.

A **participant** is a contact added to a conversation that belongs to someone else. A conversation belongs to the contact who started it; when its author shares it with their company (`sharedWithCompany`), the other members of that company can see it and reply too.

## Conversations [#conversations]

A **conversation** is the unit of support work. Elsewhere you might call it a ticket; the code says conversation. Each one has:

A **reference**, such as `ACME-1042`: the `referencePrefix` and a number from a sequence that starts at 1000. Customers and emails go by it.

An **inbox**, one of the keys of `inboxes`, such as `support` or `sales`. The inbox's configuration decides whether visitors may write to it, when agents are reminded, and what the widget says at the top. Its `allowedOrigins` are pooled with every other inbox's into one list of origins that may call the widget routes. "Inbox" is also the name of the agent UI's screen that lists conversations.

A **type**, a **status** and a **priority**. Types are `question`, `bug`, `feature` and `lead` unless you configure your own. Priorities are `low`, `normal`, `high` and `urgent` unless you configure your own list, lowest first; `priorityLabels` can show them as P3 to P1, and the two highest are the ones shown in colour. Statuses are named from the customer's side: `open` means the conversation is with your team, `pending` means it awaits the customer's reply, and `resolved` means it is done.

A **tier**, such as `gold` or `platinum`: the word your app attaches to a conversation through `resolveTier`, or an agent sets, which picks its service-level policy. A **channel**: where the conversation came in, `widget`, `email`, `agent` for one the team opened, or `api` for one opened from host code.

A **subject** and a **title**. The subject is what the customer called it, and the only name they ever see. The title is the team's name for it, from AI triage or a rename, and agents see it first.

**Tags**, free text the team adds, lower-cased and unique within a conversation. The inbox can be filtered by one.

**Messages**, written by a contact, an agent, or the system. An **internal** message is a note that only agents see. **Attachments** are stored through your storage adapter; the helpdesk keeps their keys and metadata.

**Context**: what the widget captured when the conversation started, such as the page URL, the window size, the language, recent errors, the referrer and campaign parameters, together with any strings your page passed in the widget's `context` prop. Agents also see what `resolveContext` returns about the customer's organization, which is asked for when shown rather than stored.

## Waiting, reminders and snoozing [#waiting-reminders-and-snoozing]

A conversation is **waiting** while the last word is the customer's; `waitingSince` records since when. When an inbox has `reminderAfterHours` and a conversation has waited that long, the agents get a reminder email, once.

An inbox can have **hours**, its business hours as weekly spans in a time zone. Such an inbox counts only open hours for its reminder and for how long a conversation has waited, and while it is closed the widget and the receipt say when it opens again.

A waiting conversation is **unread** in the inbox until an agent opens it after the customer's last message.

A **snoozed** conversation is a pending one with a `snoozedUntil` time. It gets no reminder and is left out of the waiting count until the scheduled jobs wake it back to `open` at that time, or a customer message wakes it sooner.

A **rating** is the customer's verdict on a resolved conversation, `good` or `bad`, or a score from 1 to 5 with `ratingScale: 5`, given in the widget or through the links in the reply email. A bad rating, or a score of 1 or 2, opens the conversation again.

## Service levels [#service-levels]

A **service level** is the `sla` policy: per tier and priority, a **response target**, the hours until the first public reply, and a **resolution target**, the hours until the conversation is resolved, each counted in business hours or round the clock. A conversation under a target carries a **deadline** for each (`respondBy`, `resolveBy`). The **clock** runs while the status is `open` and pauses while the customer has the ball; a snooze does not pause it. The jobs run sends a **warning** once a share of a target has passed and records a **breach** once the deadline has, each once per target, on the timeline and as an event.

## The CRM [#the-crm]

A **deal** belongs to a company. It moves through the deal stages, has a value in a currency and an owning agent, and keeps going if the contact it was opened with is deleted. An **activity** is a note, call, meeting or event logged against a contact, a company or a deal; `helpdesk.track()` records events from your own code.

A **lead stage** sits on a contact or a company, and a **deal stage** sits on a deal. They are separate ladders.

## Email [#email]

**Outbound** mail goes through your `email.send` adapter as one of six kinds: `customer-reply`, `customer-receipt` (the acknowledgement sent when the inbox has `receipt`), `agent-new`, `agent-reminder`, `agent-mention` (to a teammate picked with `@` in an internal note), and `agent-sla` (a service-level warning or breach).

**Inbound** mail arrives when a **relay**, any service that can forward a raw message to a URL, posts it to `{basePath}/inbound/` with `inboundWebhookSecret`. A message is **verified** when its From domain signed it. A reply finds its conversation by the message ids it answers, or by the reference in a plus-address such as `support+ACME-1042@example.com`, which `replyToAddress` puts into the Reply-To header.

## Jobs and retention [#jobs-and-retention]

A **job** is a piece of queued work in the `job` table, such as sending an email or running AI triage. Your scheduler runs them through `helpdesk.runJobs()` or `POST {basePath}/jobs` with `jobsSecret`. A run wakes snoozed conversations that are due, queues reminders and service-level notices, applies **retention**, which deletes resolved conversations `retentionDays` after they were resolved, and then works through due jobs within a time budget.

## The two interfaces [#the-two-interfaces]

The **widget** is `<helpdesk-widget>`, a launcher and a panel in a shadow root. `HelpdeskWidget` wraps it for React, and `widget.js` is the standalone build for pages that are not React. It talks to the `widget/*` routes, from another origin when any inbox lists that origin in `allowedOrigins`.

The **agent UI**, which the code also calls the admin, is `HelpdeskAdmin`, a React component you render on a page of your app. It talks to the `agent/*` routes. `adminUrl` is its absolute address: agent emails link to it, and changes are accepted only from its origin.

A **canned reply** is a saved answer that agents insert into a reply. **Settings** are the few values agents change in the agent UI, stored as one JSON value per key in the `setting` table.
