# Adaptive cards

**Base URL:** `https://{tenant}.{region}.qlikcloud.com`

## Table of Contents

| Method | Path | Description |
|--------|------|-------------|
| `GET` | [`/api/analytics/discovery-agent/adaptive-cards`](#get-apianalyticsdiscovery-agentadaptive-cards) | Retrieves Adaptive Card(s) in JSON format. Support fetching of a single card by metric ID or multiple cards by a list of metric IDs. Support filtering by app IDs, measures, dimensions, categories, breakdown dimension, analysis types and triggered time range. When filtering by measures, use appIds parameter to scope results to specific apps, as the same measure expression can exist across multiple apps. |

## API Reference

### GET /api/analytics/discovery-agent/adaptive-cards

Retrieves Adaptive Card(s) in JSON format. Support fetching of a single card by metric ID or multiple cards by a list of metric IDs. Support filtering by app IDs, measures, dimensions, categories, breakdown dimension, analysis types and triggered time range. When filtering by measures, use appIds parameter to scope results to specific apps, as the same measure expression can exist across multiple apps.

**Ranking behaviour:** When the endpoint is called *without any filter parameters* (bare `GET /adaptive-cards`), only the top-ranked result per metric (rank ≤ 1) or results without a rank field are returned. When *any* DB-reaching filter is supplied (`metricIds`, `dimensions`, `measures`, `appIds`, `breakdowns`, `analysisTypes`, `comparisonPeriods`, `timeRangeStart`, `timeRangeEnd`), ranking is not applied and all matching results are returned so that explicit filters are never silently constrained by rank.


- **Rate Limit:** Tier 1 (1000 requests per minute)

#### Query Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `analysisTypes` | string[] | No | Filter by analysis types. Repeat parameter to include multiple types (results may match any of the provided types). When this parameter is present, the rank filter is disabled and all matching analysis types are returned regardless of rank.  Enum: "recordHigh", "recordLow", "aboveModel", "belowModel", "spikesUp", "spikesDown", "newBaseLine", "trendChanges" |
| `appIds` | string[] | No | Filter by app ID(s). Use this to scope results to specific apps. When combined with measures, returns only cards matching BOTH criteria (AND logic). Repeat the parameter to supply multiple app IDs (OR logic within appIds).  **Recommendation:** Use consistent parameter order for better HTTP cache hit rates: 1. appIds (if present) 2. measures (if present) 3. other filters 4. pagination (limit, next, prev)  **Example - One app, multiple measures:** `?appIds=app-123&measures=Sum(Sales)&measures=Avg(Revenue)&measures=Count(Orders)`  **Example - Multiple apps, one measure:** `?appIds=app-retail&appIds=app-wholesale&measures=Sum(Sales)`  **Example - Multiple apps, multiple measures:** `?appIds=app-sales&appIds=app-hr&measures=Sum(Revenue)&measures=Avg(Salary)` |
| `breakdowns` | string[] | No | Filter by one or more breakdown selections in the form `dimension:value` (example `Region:EMEA`). Values are selected from the UI dropdown — not free text — and should match available dimension/value pairs. Repeat the parameter to supply multiple breakdowns; results match any of the provided breakdown pairs. |
| `categories` | string[] | No | List of category ids from the business glossary. Parsed by the API but not applied to the DB filter in the current implementation. |
| `comparisonPeriods` | string[] | No | Filter by comparison (aggregation) periods. Example values: D, W, M, Q, Y. When this parameter is present, the rank filter is disabled and all matching periods are returned regardless of rank.  Enum: "D", "W", "M", "Q", "Y" |
| `dimensions` | string[] | No | Filter by dimension(s). Matching is case-sensitive; leading and trailing whitespace will be trimmed. Repeat the parameter to supply multiple dimensions. |
| `limit` | integer | No | The maximum number of resources to return for a request. The limit must be an integer between 1 and 100 (inclusive). |
| `measures` | string[] | No | Filter by measure(s). Matching is case-sensitive; leading and trailing whitespace will be trimmed. Repeat the parameter to supply multiple measures. |
| `metricIds` | string[] | No | Comma-separated list of metric IDs to return Adaptive Cards for. When omitted the endpoint may return cards for multiple metrics visible to the tenant. |
| `next` | integer | No | The numeric offset to the next page of resources. Provide either the next or prev parameter, but not both. |
| `prev` | integer | No | The numeric offset to the previous page of resources. Provide either the next or prev parameter, but not both. |
| `sort` | string | No | The field to sort by, with +/- prefix indicating sort order Enum: "creationTime", "+creationTime", "-creationTime" |
| `timeRangeEnd` | string | No | Exclusive upper bound for analysis result end time. Use ISO 8601 format (example: 2023-10-31T00:00:00.000Z). The store applies this as endTime < timeRangeEnd. |
| `timeRangeStart` | string | No | Inclusive lower bound for analysis result end time. Use ISO 8601 format (example: 2023-10-01T00:00:00.000Z). The store applies this as endTime >= timeRangeStart. |
| `type` | string | No | Optional filter to request only one category: measures, dimensions, or breakdowns. When omitted, all categories are returned. Enum: "measures", "dimensions", "breakdowns" |

#### Header Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Authorization` | string | Yes | JWT containing tenant credentials. |

#### Responses

##### 200

Expected response to a valid request.

**Content-Type:** `application/json`

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `data` | object[] | Yes | Adaptive card |
| `links` | object | Yes |  |
| `inAppMetrics` | object[] | No |  |

<details>
<summary>Properties of `links`</summary>

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `next` | object | No |  |
| `prev` | object | No |  |
| `self` | object | No |  |

<details>
<summary>Properties of `next`</summary>

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `href` | string | No |  |

</details>

<details>
<summary>Properties of `prev`</summary>

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `href` | string | No |  |

</details>

<details>
<summary>Properties of `self`</summary>

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `href` | string | No |  |

</details>

</details>

<details>
<summary>Properties of `inAppMetrics`</summary>

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The ID of the in-app metric in the database. |
| `appId` | string | Yes | The ID of the app. |
| `links` | object | Yes |  |
| `status` | integer | Yes | Status of the in app metrics (0 - inactive, 1 - active). Enum: 0, 1 |
| `userId` | string | Yes | The ID of the user who created the in-app-metric. |
| `tenantId` | string | Yes | The ID of the tenant who owns the in-app metric. |
| `definition` | object | Yes |  |
| `updateTime` | string | Yes | The time when the in-app metric was last updated. |
| `creationTime` | string | Yes | The time when the in-app metric was created. |

<details>
<summary>Properties of `links`</summary>

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `self` | object | No |  |

<details>
<summary>Properties of `self`</summary>

_Properties truncated due to depth limit._

</details>

</details>

<details>
<summary>Properties of `definition`</summary>

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes |  |
| `status` | integer | No | Status of the in app metrics (0 - inactive, 1 - active). Enum: 0, 1 |
| `measure` | string | Yes |  |
| `upwardIs` | integer | No | Indicates whether an increase in the metric is considered neutral (0), positive (1) or negative (-1). Enum: 0, 1, -1 |
| `dimension` | string | Yes |  |
| `categories` | object[] | No |  |
| `glossaryId` | string | No | The ID of the glossary that the in-app metric belongs to. |
| `description` | string | No | A description of the in-app metric. |
| `analysisTypes` | string[] | Yes | Type of analysis performed on the in-app metric. Enum: "recordHigh", "recordLow", "aboveModel", "belowModel", "spikesUp", "spikesDown", "newBaseLine", "trendChanges" |
| `comparisonPeriods` | string[] | No | Comparison period for the analysis. Enum: "D", "W", "M", "Q", "Y" |
| `breakDownDimensions` | object[] | No | Breakdown dimension with filtering capabilities. - `dimension` is required. - `values` and `filter` are optional. If both are omitted (or `values` is empty and `filter` is null), the API interprets this as "analyze all values" for the given dimension. |
| `nextExecutionOffset` | integer | No | Number of days to offset the execution of analyses for this aggregation period. |

<details>
<summary>Properties of `categories`</summary>

_Properties truncated due to depth limit._

</details>

<details>
<summary>Properties of `breakDownDimensions`</summary>

_Properties truncated due to depth limit._

</details>

</details>

</details>

##### 400

Bad request.

**Content-Type:** `application/json`

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `errors` | object[] | No |  |

<details>
<summary>Properties of `errors`</summary>

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | string | Yes | The error code is in the form of 'OWL-xxx', ranges from 'OWL-001' to 'OWL-016'. |
| `title` | string | Yes |  |
| `detail` | string | No |  |

</details>

##### 401

Unauthorized, JWT invalid or not provided.

**Content-Type:** `application/json`

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `errors` | object[] | No |  |

<details>
<summary>Properties of `errors`</summary>

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | string | Yes | The error code is in the form of 'OWL-xxx', ranges from 'OWL-001' to 'OWL-016'. |
| `title` | string | Yes |  |
| `detail` | string | No |  |

</details>

##### 403

Forbidden, the requesting JWT does not allow for retrieval of in-app metrics (error code: OWL-003).

**Content-Type:** `application/json`

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `errors` | object[] | No |  |

<details>
<summary>Properties of `errors`</summary>

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | string | Yes | The error code is in the form of 'OWL-xxx', ranges from 'OWL-001' to 'OWL-016'. |
| `title` | string | Yes |  |
| `detail` | string | No |  |

</details>

##### 500

Internal server error.

**Content-Type:** `application/json`

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `errors` | object[] | No |  |

<details>
<summary>Properties of `errors`</summary>

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | string | Yes | The error code is in the form of 'OWL-xxx', ranges from 'OWL-001' to 'OWL-016'. |
| `title` | string | Yes |  |
| `detail` | string | No |  |

</details>

#### Examples

**JavaScript:**

```javascript
// qlik-api has not implemented support for `GET /api/analytics/discovery-agent/adaptive-cards` yet.
// In the meantime, you can use fetch like this:

const response = await fetch(
  '/api/analytics/discovery-agent/adaptive-cards',
  {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
    },
  },
)

```

**Qlik CLI:**

```bash
# qlik-cli has not implemented support for GET /api/analytics/discovery-agent/adaptive-cards yet.
```

**cURL:**

```bash
curl "https://{tenant}.{region}.qlikcloud.com/api/analytics/discovery-agent/adaptive-cards" \
-H "Authorization: Bearer <access_token>"
```

**Example Response:**

```json
{
  "data": [
    {}
  ],
  "links": {
    "next": {
      "href": "http://example.com"
    },
    "prev": {
      "href": "http://example.com"
    },
    "self": {
      "href": "http://example.com"
    }
  },
  "inAppMetrics": [
    {
      "id": "67cab2cf3d74cae279940b99",
      "appId": "9b89de1e-9a1b-11ef-9974-563d08542bef",
      "links": {
        "self": {
          "href": "http://example.com"
        }
      },
      "status": 1,
      "userId": "FyPG6xWp6prDU6BXQ3g7LY9gWR_YRkkx",
      "tenantId": "efSCcpNYuayTysONkUcE3F80zYQ_LV9w",
      "definition": {
        "name": "Profit by region Europe",
        "status": 1,
        "measure": "Sum({<Region='Europe'>} Profit)",
        "upwardIs": 1,
        "dimension": "ShipDate",
        "categories": [
          {
            "glossaryId": "fe7df4a8-abb4-42da-95e7-4ee8db22a7cb",
            "categoryIds": [
              "6db0fd8e-2115-4ac6-8d51-1729adbc4cfd"
            ]
          }
        ],
        "glossaryId": "5a7482f5-892a-4194-9f48-366ccb48a1e7",
        "description": "This metric shows the profit by region in Europe.",
        "analysisTypes": [
          "recordHigh",
          "aboveModel",
          "spikesUp"
        ],
        "comparisonPeriods": [
          "D",
          "W",
          "M",
          "Q",
          "Y"
        ],
        "breakDownDimensions": [
          {
            "filter": {
              "type": "values",
              "values": [
                "Europe",
                "Asia"
              ]
            },
            "values": [
              "Europe",
              "Asia"
            ],
            "dimension": "Region"
          }
        ],
        "nextExecutionOffset": 7
      },
      "updateTime": "2023-10-01T12:00:00Z",
      "creationTime": "2023-10-01T12:00:00Z"
    }
  ]
}
```

---
