Skip to content
Last updated

Introducing the Intelligence API

Knowing how your customer service is performing is key to making the right decisions. The Intelligence API gives you the same data that powers analytics in Dixa, so you can bring it into your own dashboards, reports and tools.

Our Intelligence API is designed for:

  • Retrieving metrics, such as the number of closed conversations, response times, CSAT or AI agent feedback, for a period of time.
  • Retrieving records, the individual events behind each metric, such as every closed conversation, every agent presence interval or every tool an AI agent called.
  • Narrowing both down with the same filters you know from Dixa, such as queue, team, agent, channel or tag.

Beta Disclaimer

The Intelligence API is part of the beta version of the Dixa API. It may change before it is promoted to v1.

How it differs from the rest of the Dixa API

Most of the Dixa API has one endpoint per resource, such as conversations, agents or queues. The Intelligence API works differently: it is catalogue-driven.

A small, fixed set of endpoints serves every metric and record. The catalogue tells you which metrics and records exist, and how each of them can be queried: which filters it accepts, which values it returns and which records it is built from. When we add a new metric, it shows up in the catalogue, and you can query it through the same endpoints without any changes on your side.

Common use cases

  • Feeding key metrics, such as response time or CSAT per team, into your BI tool or data warehouse.
  • Building your own dashboards with the same numbers your team sees in Dixa.
  • Drilling down from a metric into the records behind it, e.g. to find the conversations that were abandoned before an agent picked them up.

Metrics and records

Every metric and record belongs to a category: conversations, agents or aiagents. The category decides which endpoint you query:

AI agent metrics and records cover AI agents joining conversations, the tools they call and the feedback end users give on their answers.

A metric returns a handful of values, such as count, average or percentage. A record returns a page of rows, one per event.

Getting started

Step 1: Find the metric or record in the catalogue

The List metrics and List records endpoints return the catalogue. Add category=conversations, category=agents or category=aiagents to narrow it down.

curl -H "Authorization: <API token>" "https://dev.dixa.io/beta/intelligence/metrics?category=conversations"

Each entry in the catalogue tells you everything you need to build a query:

  • id: the metric or record id that goes in the URL, e.g. closedConversations.
  • primaryFilters: how the query can be anchored, by period and, for many conversation entries, by conversationIds.
  • filters: the attributes you can filter on, the operators each attribute accepts, and the defaultOperator used when you leave the operator out.
  • aggregates (metrics only): the values the response contains.
  • fields (records only): the columns a row can contain, and their types.
  • relatedRecordIds and relatedMetricIds: the records a metric is built from, and the metrics a record feeds into.

Step 2: Look up the filter values

Filters take ids, not names. The List filter values endpoint returns the ids and display names for one attribute, e.g. all your queues:

curl -H "Authorization: <API token>" "https://dev.dixa.io/beta/intelligence/filters/queue/values"

Agents, queues, teams and tags are identified by UUIDs, the same ids the rest of the Dixa API uses. AI agents are listed under the aiAgent attribute; this endpoint is the place to look up their ids. Fixed values, such as channels, are identified by names such as Email or PstnPhone. Deactivated agents, queues and tags, and deleted AI agents, are still listed, marked with deactivated: true, since past activity still refers to them.

The catalogue and filter values are paginated. To fetch the next page, call the link in meta.next of the response as it is.

Step 3: Send the query

The metric or record id goes in the URL, and the query goes in the request body:

curl -X POST "https://dev.dixa.io/beta/intelligence/conversations/metrics/closedConversations" \
  -H "Authorization: <API token>" \
  -H "Content-Type: application/json" \
  -d '{
    "primaryFilter": {
      "period": { "interval": { "from": "2026-06-01T00:00:00Z", "to": "2026-06-30T23:59:59.999Z" } }
    },
    "filters": [
      { "attribute": "queue", "values": ["2f9b6d51-38c4-4a72-9e15-7c8b3f6a2d90"], "operator": "IsOne" }
    ],
    "timezone": "Europe/Copenhagen"
  }'

The response contains every value the metric offers:

{ "data": { "count": 1284 } }

Building the request body

  • primaryFilter anchors the query and is one of:
    • A period with an interval, e.g. { "period": { "interval": { "from": "2026-06-01T00:00:00Z", "to": "2026-06-30T23:59:59.999Z" } } }. Both from and to are inclusive, and from must be before to. Both must end in Z or a UTC offset, such as 2026-06-01T00:00:00+02:00.
    • A period with a preset, e.g. { "period": { "preset": "Last7Days" } }, resolved in the timezone of the request. Last7Days and other Last{N}{Unit}s presets include the current unit, so Last7Days includes today. PreviousWeek, PreviousMonth and the other Previous{Unit} presets cover the last full unit, and ThisMonth and the other This{Unit} presets cover the current unit so far.
    • A list of conversationIds, e.g. { "conversationIds": [8123456, 8123481] }, if the catalogue entry allows it. The query then ignores any period.
  • filters narrows the query down. Each filter has an attribute, a list of values and, optionally, an operator. All filters must match. IsEmpty and IsNotEmpty take an empty list of values. A filter on an attribute the catalogue entry doesn't list, or with an operator the attribute doesn't accept, is rejected rather than ignored.
  • timezone is required. Presets and day boundaries are evaluated in this timezone.

Record queries also accept:

  • pagination, with an optional pageLimit of up to 1000 rows and the pageKey of the page you want.
  • includeLabels, which defaults to true. Set it to false to receive ids without display names.

Reading the response

Metrics return every value listed under aggregates in the catalogue entry. If nothing matched the query, count is 0 and the other values, such as average or percentage, are null. Durations are in milliseconds.

Records return one page of rows under data, and the keys of the next and previous pages under meta. To fetch the next page, send the same query again with meta.next as pagination.pageKey. The page key is opaque, so pass it on unchanged.

Within a row:

  • A column without a value is left out, so rows can have different keys.
  • A reference, such as an agent or a queue, is an object with an id and, unless you set includeLabels to false, a label.
  • A reference that no longer exists, such as a deleted queue, is left out of the row.

Further information

  • Ids, attributes and JSON keys are written in camelCase, e.g. closedConversations or initialDirection. Operators, presets and fixed values are written in PascalCase, e.g. IsOne, Last7Days or PstnPhone.
  • Read the catalogue rather than hard-coding ids and filters, so new metrics and filters reach your integration automatically. Check the deprecated flag of an entry before relying on it.
  • An unknown metric or record id returns HTTP status 404 Not Found, and an invalid query returns 400 Bad Request with a message explaining what is wrong.
  • Authentication and rate limits work the same way as for the rest of the Dixa API. Read more in API Standards & Rules, and see How to create an API token to get started.