# Queue metrics

> GET /v1/chat/queues/metrics/{ids} · Queues and routing API

Source: https://developer.kustomer.com/api/queues-and-routing/queue-metrics

```http
GET https://{orgname}.api.kustomerapp.com/v1/chat/queues/metrics/{ids}
Authorization: Bearer <API key>
```

## Authorization

Requires any one of these roles: `org.permission.queue.read`; or legacy `org.admin`, `org.user`. The API key or user must hold at least one of them. Legacy roles predate permission sets and still work.

Query for queue metrics by a single or multiple queue IDs.

### Rate limit
This endpoint is rate limited as a metrics endpoint.

### Metrics
1. Latest Wait Time: The time that the latest customer waited on a queue.
     note: If a requested queue has no activity for a day, it will return a `null` latest wait time.
2. Latest Wait Time Since Queue Entry or Last Unpause: The time that the latest customer waited on a queue, calculated as the shorter of the following two time spans:
    * Seconds from queue entry to queue exit
    * Seconds from last unpause to queue exit
3. Latest Wait Time Before or After Last Pause: The time that the latest customer waited on a queue, calculated in the following order:
    * If the conversation was not snoozed, then return total queue time
    * If item was snoozed and then un-snoozed, return time from unpause to queue exit
    * If item was snoozed, but exited the queue before being un-snoozed, then return time from queue entry to snooze.

## About Queue metrics

Queue metrics report how long the most recent customer waited in each queue before an agent took the conversation. Use them to show customers an expected wait or to watch queue health from your own tools.

Kustomer measures queue wait time from [work items](https://developer.kustomer.com/api/queues-and-routing#work-items): the time between an item entering a [queue](https://developer.kustomer.com/api/queues-and-routing#queues) and leaving it. This endpoint returns the latest of those measurements for each queue you ask about. It's a snapshot of recent experience, not a forecast, but it's a good basis for messages such as "the current wait is about 3 minutes" in a chat or on a help page. For historical reporting, use Kustomer's reports instead.

#### The three wait times

Snoozing a conversation pauses its work item, which can make a raw queue time misleading. Each queue returns three variants:

| Attribute | Meaning |
| --- | --- |
| `latestWaitTimeSeconds` | How long the latest customer waited in the queue. |
| `latestWaitTimeSinceQueueEntryOrLastUnpauseSeconds` | The shorter of: entry to exit, or last unpause to exit. Ignores waiting that happened before the last unpause. |
| `latestWaitTimeBeforeOrAfterLastPauseSeconds` | The total queue time if the item was never paused; the time from unpause to exit if it was paused and then resumed; or the time from entry to the pause if it left the queue while still paused. |

For an item that was never paused, all three are the same. Values are whole seconds, rounded up. A queue with no activity for a day returns `null`. `name` is the queue's display name, and the `latestWaitTimeWorkItem` relationship, when present, points at the work item that was measured.

#### Choosing the window

`rangeFrom` limits the measurement to queue activity in the last `rangeFrom` seconds, up to 86,400 (24 hours). A short window such as 3600 keeps the answer current; a queue with no activity in that window returns `null` rather than an old value.

#### Which endpoint to use

| To | Call |
| --- | --- |
| Get the latest wait times for one or more queues | [`GET /v1/chat/queues/metrics/{ids}`](https://developer.kustomer.com/api/queues-and-routing/queue-metrics) |
| Find the queue IDs to ask about | [`GET /v1/routing/queues`](https://developer.kustomer.com/api/queues-and-routing/get-queues) |

Pass up to 80 queue IDs, comma-separated, in the path. IDs that aren't queues in your org are left out of the response. The endpoint is rate limited as a metrics endpoint, so cache the result for a short time rather than calling it on every page view. Any `org.user` or `org.admin` key can call it, as can a key with `org.permission.queue.read`.

Related: [Queues](https://developer.kustomer.com/api/queues-and-routing#queues), [Work items](https://developer.kustomer.com/api/queues-and-routing#work-items), [Rate limits](https://developer.kustomer.com/docs/concepts/rate-limits)

### Recipes

#### 1. Show customers the current wait for a queue

Display a message such as "the current wait is about 3 minutes" on a help page or before a chat starts, based on the latest real wait.

**Step 1.** [`GET /v1/routing/queues`](https://developer.kustomer.com/api/queues-and-routing/get-queues.md). Find the queue's ID by its `key` once, and keep it in your configuration.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/routing/queues?key=$QUEUE_KEY" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/routing/queues --query key=$QUEUE_KEY | jq -r '.data[0].id'
```

**Step 2.** [`GET /v1/chat/queues/metrics/{ids}`](https://developer.kustomer.com/api/queues-and-routing/queue-metrics.md). Ask for the queue's metrics over a short window, such as the last hour. `latestWaitTimeSinceQueueEntryOrLastUnpauseSeconds` ignores waiting that happened before a conversation's last unsnooze, which suits a customer-facing estimate. A `null` value means nobody waited in that window; show a generic message instead of a number.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/chat/queues/metrics/$QUEUE_ID?rangeFrom=3600" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/chat/queues/metrics/$QUEUE_ID --query rangeFrom=3600 \
  | jq '.data[0].attributes.latestWaitTimeSinceQueueEntryOrLastUnpauseSeconds | if . == null then null else (. / 60 | ceil) end'
```

> Cache the answer for a minute or so on your server instead of calling the API on every page view; the endpoint is rate limited as a metrics endpoint.

#### 2. Alert when any queue's wait gets too long

Check every queue's latest wait in one call and flag the ones over a threshold, for example from a scheduled job that posts to your chat tool.

**Step 1.** [`GET /v1/routing/queues`](https://developer.kustomer.com/api/queues-and-routing/get-queues.md). Collect the queue IDs. One metrics call takes up to 80, comma-separated in the path.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/routing/queues?pageSize=100" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
QUEUE_IDS=$(kusty api GET /v1/routing/queues --all | jq -r '.data.id' | head -80 | paste -sd, -)
```

**Step 2.** [`GET /v1/chat/queues/metrics/{ids}`](https://developer.kustomer.com/api/queues-and-routing/queue-metrics.md). Request all of them and keep the queues whose `latestWaitTimeSeconds` is over your threshold. IDs that aren't queues in your org are left out of the response, and queues without recent activity return `null`.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/chat/queues/metrics/$QUEUE_IDS?rangeFrom=1800" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/chat/queues/metrics/$QUEUE_IDS --query rangeFrom=1800 \
  | jq -r '.data[] | select((.attributes.latestWaitTimeSeconds // 0) > 600) | "\(.attributes.name): \(.attributes.latestWaitTimeSeconds)s"'
```

> Keep to 80 IDs per call and split longer lists into batches; a path that gets too long fails with `414 URI Too Long`.

### Example object

A real record from [`GET /v1/chat/queues/metrics/{ids}`](https://developer.kustomer.com/api/queues-and-routing/queue-metrics.md):

```json
{
  "type": "session_queue",
  "id": "11a7998f2d3f9f8800aaaaaa",
  "attributes": {
    "name": "Billing",
    "latestWaitTimeSeconds": 45,
    "latestWaitTimeSinceQueueEntryOrLastUnpauseSeconds": 7,
    "latestWaitTimeBeforeOrAfterLastPauseSeconds": 7
  },
  "relationships": {
    "org": {
      "data": {
        "type": "org",
        "id": "55d7998f2d3f9f8800099aed"
      },
      "links": {
        "self": "/v1/orgs/55d7998f2d3f9f8800099aed"
      }
    },
    "queue": {
      "data": {
        "type": "queue",
        "id": "11a7998f2d3f9f8800aaaaaa"
      },
      "links": {
        "self": "/v1/routing/queues/11a7998f2d3f9f8800aaaaaa"
      }
    },
    "latestWaitTimeWorkItem": {
      "data": {
        "type": "work-item",
        "id": "A1a7998f2d3f9f8800aaaaab"
      },
      "links": {
        "self": "/v1/routing/work-items/A1a7998f2d3f9f8800aaaaab"
      }
    }
  }
}
```

Fields:

- `id` (string): The queue's ID. Each record in the response is one of the queues you asked for.
- `attributes.name` (string): The queue's display name.
- `attributes.latestWaitTimeSeconds` (integer): How long the latest customer waited in the queue, in whole seconds rounded up. `null` when the queue had no activity in the window.
- `attributes.latestWaitTimeSinceQueueEntryOrLastUnpauseSeconds` (integer): The latest wait counted from queue entry or from the last unpause, whichever is shorter, so time before a snooze ended doesn't count.
- `attributes.latestWaitTimeBeforeOrAfterLastPauseSeconds` (integer): The latest wait adjusted around a snooze. The same as `latestWaitTimeSeconds` for items that were never paused.
- `relationships.queue` (object): The queue these metrics describe, with the same ID as the record.
- `relationships.latestWaitTimeWorkItem` (object): The work item whose wait was measured, when the response includes it.

### Relationships

- Points to **Queues** via `relationships.queue`: The queue whose latest wait times these queue metrics report.
- Points to **Work items** via `relationships.latestWaitTimeWorkItem`: The work item whose time in the queue produced the latest wait in queue metrics. Not every response includes it.

### Permissions

Fewest roles for a read-only integration: `org.permission.queue.read`. For every endpoint: `org.permission.queue.read`.

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `ids` | string | yes | Comma separated list of queue IDs to be included in the response. Limit of 80. |

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `rangeFrom` | integer | no | Time range, in seconds, used for queue metrics analytics. |

## Responses

### 200

OK

- `data` (array<object>, required): (max items 80)
  - `type` (string, required): One of: `session_queue`.
  - `id` (string, required): Queue ID.
  - `attributes` (object, required)
    - `name` (string): Queue display name.
    - `latestWaitTimeSeconds` (integer, nullable): Latest queue wait time in seconds.
    - `latestWaitTimeSinceQueueEntryOrLastUnpauseSeconds` (integer, nullable): Latest queue wait time in seconds, calculated from queue entry or last unpause.
    - `latestWaitTimeBeforeOrAfterLastPauseSeconds` (integer, nullable): Latest queue wait time in seconds, adjusted around the last pause when present.
  - `relationships` (object, required)
    - `org` (object)
    - `queue` (object)
    - `latestWaitTimeWorkItem` (object): Present when the analytics response includes the work item used for latest wait time.

```json
{
  "data": [
    {
      "type": "session_queue",
      "id": "11a7998f2d3f9f8800aaaaaa",
      "attributes": {
        "name": "Billing",
        "latestWaitTimeSeconds": 45,
        "latestWaitTimeSinceQueueEntryOrLastUnpauseSeconds": 7,
        "latestWaitTimeBeforeOrAfterLastPauseSeconds": 7
      },
      "relationships": {
        "org": {
          "data": {
            "type": "org",
            "id": "55d7998f2d3f9f8800099aed"
          },
          "links": {
            "self": "/v1/orgs/55d7998f2d3f9f8800099aed"
          }
        },
        "queue": {
          "data": {
            "type": "queue",
            "id": "11a7998f2d3f9f8800aaaaaa"
          },
          "links": {
            "self": "/v1/routing/queues/11a7998f2d3f9f8800aaaaaa"
          }
        },
        "latestWaitTimeWorkItem": {
          "data": {
            "type": "work-item",
            "id": "A1a7998f2d3f9f8800aaaaab"
          },
          "links": {
            "self": "/v1/routing/work-items/A1a7998f2d3f9f8800aaaaab"
          }
        }
      }
    }
  ]
}
```

### 400

Bad Request

### 401

Unauthorized

### 403

Forbidden

### 414

URI Too Long

## Example request

```bash
curl --request GET \
  --url 'https://api.kustomerapp.com/v1/chat/queues/metrics/5f184e74c61792001af42e49,5f184e74c61792001af42e50' \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```
