# Ticket events

> ticket.created, ticket.updated and ticket.solved

Source: https://www.hey.support/docs/developer-guide/webhooks/events/ticket

---

A ticket is a problem your agent could not solve on its own, held as a record with a number until your team can. All three events carry the same `ticket` object, which is the same object `/v1/tickets` returns; `ticket.updated` adds a `change` field saying what happened.

## The ticket object

```json
{
  "ticket": {
    "id": "9c1f7e42-3b6a-4d18-8f52-2a0e7c4b9d31",
    "chatbot_id": 17,
    "conversation_id": 8214,
    "customer_id": 42,
    "number": 1042,
    "status": "open",
    "priority": "high",
    "sentiment": "frustrated",
    "category_id": 4,
    "category_name": "Damaged or wrong item",
    "subject": null,
    "summary": "Rear wheel arrived buckled",
    "name": "Ada Lovelace",
    "email": "ada@example.com",
    "phone": null,
    "answers": { "order_number": "A-1042" },
    "source": "card",
    "channel": "web",
    "language": "en",
    "assignee_user_id": 9,
    "rating": null,
    "first_reply_at": null,
    "last_customer_message_at": "2026-09-22T09:00:00.000Z",
    "last_agent_message_at": null,
    "solved_at": null,
    "closed_at": null,
    "reopened_count": 0,
    "created_at": "2026-09-22T09:00:00.000Z",
    "updated_at": "2026-09-22T09:00:00.000Z"
  }
}
```

`number` is what the customer quotes, unique per workspace rather than per agent. `category_name` is snapshotted, so a ticket stays readable after its category is deleted, and `summary` and `sentiment` are null until the triage pass has run. Internal notes never appear in any of these events.

## `ticket.created`

A problem the agent could not solve, now held with a number. `opening_message` is the customer's own first words.

```json
{
  "event": "ticket.created",
  "data": {
    "ticket": { "...": "as above" },
    "opening_message": "The rear wheel arrived buckled and the box was torn open."
  }
}
```

`source` says where it came from: `card` (the widget), `agent` (the agent opened it on a call or a channel), `handoff` (nobody took a request for a person), `manual` (your team), `api`, or `channel`.

## `ticket.updated`

One event for every change to a live ticket. `change` says which; adding an internal note is deliberately not one of them.

| `change`           | What happened                                                        |
| ------------------ | -------------------------------------------------------------------- |
| `replied`          | Your team wrote to the customer. `message` carries the reply.        |
| `customer_replied` | The customer wrote back. `message` carries it.                       |
| `reopened`         | The customer replied to a solved or closed ticket, which reopens it. |
| `assigned`         | The assignee changed.                                                |
| `closed`           | It closed, by hand or by the auto-close job.                         |
| `rated`            | The customer rated it. `ticket.rating` is 1 to 5.                    |

```json
{
  "event": "ticket.updated",
  "data": {
    "ticket": { "...": "as above" },
    "change": "customer_replied",
    "message": "Still nothing in the post, any update?"
  }
}
```

## `ticket.solved`

Its own event rather than an `updated` change, because it is the one a report counts. A ticket can be solved more than once: a customer reply reopens it, and solving it again fires this again.

```json
{
  "event": "ticket.solved",
  "data": { "ticket": { "...": "as above", "status": "solved", "solved_at": "2026-09-23T11:04:00.000Z" } }
}
```

<NextSteps>
  <IconCard icon="webhook" title="Webhooks overview" href="/docs/developer-guide/webhooks" description="The envelope, the headers and every event." />

  <IconCard icon="key-round" title="Verifying signatures" href="/docs/developer-guide/webhooks/signature" description="Check the HMAC before you act on a delivery." />
</NextSteps>
