Guides

Generic Metrics Endpoints


Overview

The metrics-api provides 5 new endpoints for flexible database table querying and analytics. Three endpoints support metrics aggregation operations on any public reporting table, while two additional endpoints provide table discovery and schema information capabilities.

The metrics-api enables flexible querying capabilities for any database table, allowing for time-series analysis, grouping operations, and aggregations. This makes it ideal for business intelligence, performance monitoring, and data analytics use cases.

This document provides endpoint descriptions, exact request and response payloads, practical examples, and field constraints for all 5 endpoints.

Timezone Handling

For UI/End Users

Send your start and end dates in your local time (as you see them), and include either timezone_offset with your region's fixed offset (e.g., "UTC+05:00" for India, "UTC-08:00" for Pacific Time) or timezone with a timezone name (e.g., "Europe/Athens", "America/New_York"). The system handles all timezone conversions and returns results in your local time.

Example with timezone_offset: If you're in India (UTC+05:00) and want data from 10:00 AM to 12:00 PM local time:

{
  "start": "2025-01-15 10:00:00",
  "end": "2025-01-15 12:00:00",
  "timezone_offset": "UTC+05:00"
}

Example with timezone: If you're in Athens and want data from 10:00 AM to 12:00 PM local time:

{
  "start": "2025-01-15 10:00:00",
  "end": "2025-01-15 12:00:00",
  "timezone": "Europe/Athens"
}

The system filters and returns data using your local time; no UTC conversion needed.

If you provide both timezone_offset and timezone, timezone_offset takes precedence.

Endpoints

Get Available Tables

Endpoint

GET /{version:v3|v4}/tables

Description

Retrieves a list of all available database tables that can be queried through the metrics API. This endpoint helps clients discover which tables are accessible for metrics operations.

Request Example

GET /metrics-api/{version:v3|v4}/tables
Authorization: Bearer <token>
Content-Type: application/json

Response Payload

{
  "tables": [
    "string"  // Array of available table names ]
}

Response Example

{
    "tables": [
        "AGENT_ASSIST_AGENT_KPIS",
        "AGENT_ASSIST_CORE_KPIS",
        "AGENT_ASSIST_FLOW_COMPLETION_RATE",
        "AGENT_ASSIST_INTENT_DISTRIBUTION"
    ]
}

Describe Table Structure

Endpoint

GET /{version:v3|v4}/tables/{tableName}

Description

Retrieves the schema and column information for a specific database table. This endpoint provides detailed metadata about the table structure including column names, data types, and primary key information. The response excludes any columns configured as excluded in the application settings.

Request Example

GET /metrics-api/{version:v3|v4}/tables/AGENT_ASSIST_AGENT_KPIS
Authorization: Bearer <token>
Content-Type: application/json

Response Payload

{
  "columns": [
    {
      "name": "string",    // Column name
      "type": "string",    // Data type (e.g., "BIGINT", "VARCHAR", "TIMESTAMP")
      "pk": boolean        // Primary key indicator (true/false)
    },...
  ]
}

Response Example

{
    "columns": [
        {
            "name": "OCP_GROUP_NAME",
            "type": "VARCHAR(16777216)",
            "pk": true
        },
        {
            "name": "CCAAS_PROVIDER",
            "type": "VARCHAR(16777216)",
            "pk": true
        },
        {
            "name": "LOCALE",
            "type": "VARCHAR(16777216)",
            "pk": true
        },
        {
            "name": "VENDOR",
            "type": "VARCHAR(16777216)",
            "pk": true
        },
        {
            "name": "REGION",
            "type": "VARCHAR(16777216)",
            "pk": true
        },
        {
            "name": "STREAM_START_DATETIME",
            "type": "TIMESTAMP_NTZ(9)",
            "pk": true
        },
        {
            "name": "AGENT_SKILL",
            "type": "VARCHAR(16777216)",
            "pk": true
        },
        {
            "name": "AGENT_ID",
            "type": "VARCHAR(16777216)",
            "pk": true
        },
        {
            "name": "TEST_FLAG",
            "type": "BOOLEAN",
            "pk": true
        },
        {
            "name": "DIALOGS_COUNT",
            "type": "NUMBER(18,0)",
            "pk": false
        },
        {
            "name": "TOTALDURATION",
            "type": "NUMBER(38,0)",
            "pk": false
        },
        {
            "name": "INTENTS_HANDLED",
            "type": "NUMBER(18,0)",
            "pk": false
        },
    ]
}

Time Series Aggregation

Endpoint

POST /{version:v3|v4}/tables/{tableName}/timeseries

Description

Performs time series aggregation on the specified database table. This endpoint allows flexible querying of time-series data with custom metrics, filters, and grouping options, and optional calculated expressions. It's designed for tables that implement the Aggregable interface.

The endpoint supports calculating new metrics from existing metrics using mathematical expressions (e.g., ratios, percentages). All calculations are performed at the database level for optimal performance.

Request Payload

{
  "filters": [
    {
      "column": "string",      // Primary Key column name (required)
      "values": ["string"]     // Array of filter values (required)
    }
  ],
  "start": "string",           // yyyy-MM-dd HH:mm:ss format (required)
  "end": "string",             // yyyy-MM-dd HH:mm:ss format (required)
  "timezone": "string",        // Timezone (optional, default: "UTC")
  "timezone_offset": "string",  // Fixed UTC offset (optional, e.g., "UTC+05:00", "UTC-08:00")
  "time_column": "string",     // Timestamp column name (required)
  "ocp_group_names": ["string"], // Array of group names (required)
  "ocp_organization_id": "string", // OCP organization ID (optional)
  "metrics": [
    {
      "name": "string",        // Column name for aggregation (required)
      "operator": "string",    // sum|avg|min|max|count (required)
      "alias": "string"        // Custom name for result (required)
    }
  ],
  "expressions": [             // Optional: Calculated metrics
    {
      "expression": "string",  // Mathematical expression (e.g., "metric1 / metric2") (required)
      "alias": "string"        // Output name for calculated metric (required)
    }
  ],
  "downsampling": "string",    // FIVE_MIN|HOUR|DAY|WEEK|MONTH|YEAR (required)
  "drilldown": boolean         // Include filter columns in response (optional, default: false)
}

At least one of ocp_organization_id or ocp_group_names must be provided.

  • If ocp_organization_id is provided, the user will be validated based on organization-level access.

  • If ocp_group_names is provided, the user will be validated based on group-level access. Both can be provided together.


Detailed Field Descriptions

Field

Type

Required

Default

Description

filters

Array

Required

List of filter conditions using primary key (PK) columns. Each entry contains a column (PK column name) and values (array of filter values). When drilldown=false, values cannot be empty. When drilldown=true, values can be an empty array to drill down over all values.

filters.column

String

Required

PK column name to filter by. Cannot be of type TIMESTAMP or exist in the excludedColumns list.

filters.values

Array of strings

Required

Array of values to filter by. Must not be empty unless drilldown=true.

start

String

Required

Start of the time range for data retrieval. Format: yyyy-MM-dd HH:mm:ss. Must be earlier than end.

end

String

Required

End of the time range for data retrieval. Format: yyyy-MM-dd HH:mm:ss. Must be later than start.

timezone

String

Optional

UTC

IANA timezone identifier for time calculations (for example, Europe/Athens, America/New_York). Used when timezone_offset is not provided. Handles daylight saving time (DST).

timezone_offset

String

Optional

Fixed UTC offset for time calculations (for example, UTC+05:00, UTC-08:00). Takes precedence over timezone when both are provided. Supports full-hour offsets only. Returned timestamps in the response represent local time in the specified offset.

time_column

String

Required

Name of the TIMESTAMP column used for time-based filtering and grouping. Must be of type TIMESTAMP and a primary key column in the target table.

ocp_group_names

Array of strings

Conditionally required

OCP group names for access control. Required if ocp_organization_id is not provided. Must not be empty if ocp_organization_id is absent.

ocp_organization_id

String

Conditionally required

OCP organization ID for organization-level access control. Required if ocp_group_names is not provided. When present, user access is validated at the organization level.

metrics

Array

Required

List of non-PK metric columns to aggregate. Each entry requires a name (column to aggregate), operator (sum, avg, min, max, or count), and alias (output name in the response).

metrics.name

String

Required

Column name to aggregate. Must be a non-PK column.

metrics.operator

String

Required

Aggregation function to apply. Accepted values: sum, avg, min, max, count.

metrics.alias

String

Required

Custom output name for the metric in the response. Must be unique and cannot conflict with expression aliases.

expressions

Array

Optional

List of calculated metrics derived from base metrics using mathematical expressions. Each entry requires an expression and an alias.

expressions.expression

String

Required (if using expressions)

Mathematical expression referencing metric aliases and numeric literals (for example, metric1 / metric2, (a + b) / c). Supports +, -, *, /, and parentheses. Division by zero returns null. All expressions are validated for security and syntax.

expressions.alias

String

Required (if using expressions)

Output name for the calculated metric in the response. Must be unique and cannot conflict with metric aliases.

downsampling

String

Required

Time interval for data aggregation into time buckets. Accepted values: FIVE_MIN, HOUR, DAY, WEEK, MONTH, YEAR.

drilldown

Boolean

Optional

false

Determines whether filter columns are included in grouping. When false, data is grouped by time intervals only. When true, data is grouped by time intervals and filter columns.


Drilldown Logic

The drilldown functionality in time series aggregation provides detailed breakdown capabilities for analyzing data at different granularity levels:

  • When drilldown is set to true: The response includes detailed breakdown data for each time period, showing individual data points across all combinations of filters and ocp_group_names. Creates separate data points for every combination of applied filter values and OCP group names specified in the request.

  • When drilldown is set to false: The response contains only the aggregated metrics for each time period without detailed breakdown information.


Response Payload

[
  {
    "metric": "string",        // Metric alias or expression alias
    "filters": {               // Applied filters (displayed when drilldown=true)
      "column_name": "value",
      "ocp_group_names": "value",     // Present when ocp_group_names provided
      "ocp_organization_id": "value"  // Present when ocp_organization_id provided
    },
    "dps": {                   // Data points (timestamp -> value)
      "timestamp": number      // Can be null for division by zero (expression result)
    }
  }
]
Detailed Field Descriptions

Field

Type

Required

Default

Description

Response array

Array of objects

List of metric objects returned, one per metric and one per expression specified in the request. For example, a request with two metrics and one expression returns three objects. When no data is found, an empty array [] is returned.

metric

String

Always present

The alias name from the request, matching either a metric alias or an expression alias.

filters

Object

Always present

{}

Object containing all applied filters, along with ocp_group_names and ocp_organization_id when provided in the request. Returns an empty object {} when no filters are applied or when drilldown=false. Keys are filter column names; values are strings representing the specific filter value for that series.

filters.{column_name}

String

Conditional

Present when drilldown=true. Key is the filter column name; value is the specific filter value for that time series.

filters.ocp_group_names

String

Conditional

Present when ocp_group_names is provided in the request and drilldown=true. Displays the group name applied to that series.

filters.ocp_organization_id

String

Conditional

Present when ocp_organization_id is provided in the request and drilldown=true. Displays the organization ID applied to that series.

dps

Object

Always present

Time-series data points as timestamp-value pairs. Keys are timestamps in yyyy-MM-dd HH:mm:ss.S format; values are the aggregated metric results. Time intervals are based on the downsampling value from the request.

dps.{timestamp}

Number or null

Always present

Aggregated value for the time interval. Handles three scenarios: a valid non-zero result is returned as-is; null is returned when division by zero occurs in an expression (not 0 or an error); and 0 is automatically filled in for any time intervals within the requested date range that contain no data, ensuring all expected intervals are present in the response.

When drilldown=true, the response contains one object per metric (or expression) per filter combination.

For example, two metrics, one expression, and two filter value combinations produce six objects in total.

Data Point Value Handling

The dps (data points) map handles three distinct scenarios for timestamp values:

  1. Zero values (0): When the database returns an actual zero value (e.g., SUM(metric) = 0), it is preserved as 0 in the response. Zero represents a valid calculation result where the aggregated value is zero.

  2. Null values (null): When the database returns NULL (typically from division by zero in expressions using NULLIF), it is preserved as null in the JSON response. This represents an invalid calculation or missing data (similar to NaN behavior).

  3. Missing timestamps: For time intervals within the requested date range that have no data returned by the query, the mapper automatically fills them with 0. This ensures all expected time intervals are present in the response for consistent charting.

Example:

{
  "metric": "completion_rate",
  "dps": {
    "2024-01-01 00:00:00.0": 0.85,    // Valid calculation
    "2024-01-01 01:00:00.0": null,    // Division by zero (NULL from database)
    "2024-01-01 02:00:00.0": 0,       // Valid calculation resulting in zero
    "2024-01-01 03:00:00.0": 0        // Missing timestamp filled with 0
  }
}


Request & Response Examples

Example 1: Basic Time Series Without Expressions (drilldown=false)

Request:

POST /metrics-api/v3/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/timeseries

{
  "metrics": [
    {
      "name": "COUNTFLOWINSTANCEID",
      "operator": "sum",
      "alias": "total_flows"
    },
    {
      "name": "TOTALDURATION",
      "operator": "sum",
      "alias": "total_duration"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill", "agentSkill"]
    }
  ],
  "downsampling": "DAY",
  "start": "2025-10-05 00:00:00",
  "end": "2025-10-07 23:59:59",
  "time_column": "STREAM_START_DATETIME",
  "drilldown": false,
  "timezone": "UTC",
  "ocp_group_names": ["ocp-qa", "group_123"]
}

Response:

[
  {
    "metric": "total_flows",
    "filters": {},
    "dps": {
      "2025-10-05 00:00:00.0": 0,
      "2025-10-06 00:00:00.0": 19,
      "2025-10-07 00:00:00.0": 3
    }
  },
  {
    "metric": "total_duration",
    "filters": {},
    "dps": {
      "2025-10-05 00:00:00.0": 0,
      "2025-10-06 00:00:00.0": 3,
      "2025-10-07 00:00:00.0": 1
    }
  }
]

Explanation:

  • No expressions, so only base metrics are returned

  • drilldown=false, so filters is empty and data is aggregated across all filter values

  • One time series per metric showing overall trends


Example 2: Basic Time Series Without Expressions (drilldown=true)

Request:

POST /metrics-api/v3/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/timeseries

{
  "metrics": [
    {
      "name": "COUNTFLOWINSTANCEID",
      "operator": "sum",
      "alias": "total_flows"
    },
    {
      "name": "TOTALDURATION",
      "operator": "sum",
      "alias": "total_duration"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill", "agentSkill"]
    },
    {
      "column": "INTENT",
      "values": ["Card"]
    }
  ],
  "downsampling": "DAY",
  "start": "2025-10-05 00:00:00",
  "end": "2025-10-07 23:59:59",
  "time_column": "STREAM_START_DATETIME",
  "drilldown": true,
  "timezone": "UTC",
  "ocp_group_names": ["group_123"]
}

Response:

[
  {
    "metric": "total_flows",
    "filters": {
      "AGENT_SKILL": "vb_skill",
      "INTENT": "Card",
      "ocp_group_names": "group_123"
    },
    "dps": {
      "2025-10-05 00:00:00.0": 0,
      "2025-10-06 00:00:00.0": 3,
      "2025-10-07 00:00:00.0": 3
    }
  },
  {
    "metric": "total_flows",
    "filters": {
      "AGENT_SKILL": "agentSkill",
      "INTENT": "Card",
      "ocp_group_names": "group_123"
    },
    "dps": {
      "2025-10-05 00:00:00.0": 0,
      "2025-10-06 00:00:00.0": 0,
      "2025-10-07 00:00:00.0": 0
    }
  },
  {
    "metric": "total_duration",
    "filters": {
      "AGENT_SKILL": "vb_skill",
      "INTENT": "Card",
      "ocp_group_names": "group_123"
    },
    "dps": {
      "2025-10-05 00:00:00.0": 0,
      "2025-10-06 00:00:00.0": 1,
      "2025-10-07 00:00:00.0": 1
    }
  },
  {
    "metric": "total_duration",
    "filters": {
      "AGENT_SKILL": "agentSkill",
      "INTENT": "Card",
      "ocp_group_names": "group_123"
    },
    "dps": {
      "2025-10-05 00:00:00.0": 0,
      "2025-10-06 00:00:00.0": 0,
      "2025-10-07 00:00:00.0": 0
    }
  }
]

Explanation:

  • No expressions, only base metrics

  • drilldown=true, so separate time series are created for each filter combination

  • filters object contains the specific filter values for each series

  • Multiple series per metric (one per filter combination)


Example 3: Time Series With Expressions (drilldown=false)

Request:

POST /metrics-api/v3/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/timeseries

{
  "metrics": [
    {
      "name": "FLOW_INSTANCES_COMPLETED",
      "operator": "sum",
      "alias": "completed_flows"
    },
    {
      "name": "FLOW_INSTANCES_TOTAL",
      "operator": "sum",
      "alias": "total_flows"
    },
    {
      "name": "TOTALDURATION",
      "operator": "sum",
      "alias": "total_duration"
    }
  ],
  "expressions": [
    {
      "expression": "(completed_flows / total_flows) * 100",
      "alias": "completion_rate"
    },
    {
      "expression": "total_duration / total_flows",
      "alias": "avg_duration_per_flow"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill"]
    }
  ],
  "downsampling": "DAY",
  "start": "2025-10-05 00:00:00",
  "end": "2025-10-07 23:59:59",
  "time_column": "STREAM_START_DATETIME",
  "drilldown": false,
  "timezone": "UTC",
  "ocp_group_names": ["group_123"]
}

Response:

[
  {
    "metric": "completed_flows",
    "filters": {},
    "dps": {
      "2025-10-05 00:00:00.0": 0,
      "2025-10-06 00:00:00.0": 22,
      "2025-10-07 00:00:00.0": 0
    }
  },
  {
    "metric": "total_flows",
    "filters": {},
    "dps": {
      "2025-10-05 00:00:00.0": 0,
      "2025-10-06 00:00:00.0": 127,
      "2025-10-07 00:00:00.0": 0
    }
  },
  {
    "metric": "total_duration",
    "filters": {},
    "dps": {
      "2025-10-05 00:00:00.0": 0,
      "2025-10-06 00:00:00.0": 16773,
      "2025-10-07 00:00:00.0": 0
    }
  },
  {
    "metric": "completion_rate",
    "filters": {},
    "dps": {
      "2025-10-05 00:00:00.0": null,
      "2025-10-06 00:00:00.0": 17.3228,
      "2025-10-07 00:00:00.0": null
    }
  },
  {
    "metric": "avg_duration_per_flow",
    "filters": {},
    "dps": {
      "2025-10-05 00:00:00.0": null,
      "2025-10-06 00:00:00.0": 132.0709,
      "2025-10-07 00:00:00.0": null
    }
  }
]

Explanation:

  • Expressions are included: completion_rate and avg_duration_per_flow

  • drilldown=false, so filters is empty

  • Response includes both base metrics (3) and expressions (2) = 5 total series

  • null values appear when division by zero occurs (e.g., when total_flows = 0)

  • Expression values are calculated per time interval


Example 4: Time Series With Expressions (drilldown=true)

Request:

POST /metrics-api/v3/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/timeseries

{
  "metrics": [
    {
      "name": "FLOW_INSTANCES_COMPLETED",
      "operator": "sum",
      "alias": "completed_flows"
    },
    {
      "name": "FLOW_INSTANCES_TOTAL",
      "operator": "sum",
      "alias": "total_flows"
    }
  ],
  "expressions": [
    {
      "expression": "(completed_flows / total_flows) * 100",
      "alias": "completion_rate"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill", "agentSkill"]
    },
    {
      "column": "INTENT",
      "values": ["Card"]
    }
  ],
  "downsampling": "DAY",
  "start": "2025-10-05 00:00:00",
  "end": "2025-10-07 23:59:59",
  "time_column": "STREAM_START_DATETIME",
  "drilldown": true,
  "timezone": "UTC",
  "ocp_group_names": ["group_123"]
}

Response:

[
  {
    "metric": "completed_flows",
    "filters": {
      "AGENT_SKILL": "vb_skill",
      "INTENT": "Card",
      "ocp_group_names": "group_123"
    },
    "dps": {
      "2025-10-05 00:00:00.0": 0,
      "2025-10-06 00:00:00.0": 22,
      "2025-10-07 00:00:00.0": 0
    }
  },
  {
    "metric": "completed_flows",
    "filters": {
      "AGENT_SKILL": "agentSkill",
      "INTENT": "Card",
      "ocp_group_names": "group_123"
    },
    "dps": {
      "2025-10-05 00:00:00.0": 0,
      "2025-10-06 00:00:00.0": 0,
      "2025-10-07 00:00:00.0": 0
    }
  },
  {
    "metric": "total_flows",
    "filters": {
      "AGENT_SKILL": "vb_skill",
      "INTENT": "Card",
      "ocp_group_names": "group_123"
    },
    "dps": {
      "2025-10-05 00:00:00.0": 0,
      "2025-10-06 00:00:00.0": 127,
      "2025-10-07 00:00:00.0": 0
    }
  },
  {
    "metric": "total_flows",
    "filters": {
      "AGENT_SKILL": "agentSkill",
      "INTENT": "Card",
      "ocp_group_names": "group_123"
    },
    "dps": {
      "2025-10-05 00:00:00.0": 0,
      "2025-10-06 00:00:00.0": 0,
      "2025-10-07 00:00:00.0": 0
    }
  },
  {
    "metric": "completion_rate",
    "filters": {
      "AGENT_SKILL": "vb_skill",
      "INTENT": "Card",
      "ocp_group_names": "group_123"
    },
    "dps": {
      "2025-10-05 00:00:00.0": null,
      "2025-10-06 00:00:00.0": 17.3228,
      "2025-10-07 00:00:00.0": null
    }
  },
  {
    "metric": "completion_rate",
    "filters": {
      "AGENT_SKILL": "agentSkill",
      "INTENT": "Card",
      "ocp_group_names": "group_123"
    },
    "dps": {
      "2025-10-05 00:00:00.0": null,
      "2025-10-06 00:00:00.0": null,
      "2025-10-07 00:00:00.0": null
    }
  }
]

Explanation:

  • Expressions included: completion_rate

  • drilldown=true, so separate series for each filter combination

  • filters object contains specific values for each series

  • Response includes: 2 base metrics × 2 filter combinations = 4 base metric series, plus 1 expression × 2 filter combinations = 2 expression series (total 6 series)

  • null values when division by zero occurs (e.g., when total_flows = 0 for a specific filter combination)


Example 5: Using timezone_offset

Request:

POST /metrics-api/v3/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/timeseries
{
  "metrics": [
    {
      "name": "COUNTFLOWINSTANCEID",
      "operator": "sum",
      "alias": "total_flows"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill"]
    }
  ],
  "downsampling": "HOUR",
  "start": "2025-10-05 07:00:00",
  "end": "2025-10-05 10:00:00",
  "time_column": "STREAM_START_DATETIME",
  "drilldown": false,
  "timezone_offset": "UTC+05:00",
  "ocp_group_names": ["ocp-qa"]
}

Response:

[
  {
    "metric": "total_flows",
    "filters": {},
    "dps": {
      "2025-10-05 07:00:00.0": 5,
      "2025-10-05 08:00:00.0": 12,
      "2025-10-05 09:00:00.0": 8,
      "2025-10-05 10:00:00.0": 3
    }
  }
]

Explanation:

  • timezone_offset is used instead of timezone

  • Timestamps in the response represent UTC+05:00 local time (not UTC)

  • The start/end dates in the request are interpreted as UTC+05:00 local time

  • Data is filtered and grouped based on UTC+05:00 timezone


Example 6: Using ocp_organization_id

Request:

POST /metrics-api/v3/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/timeseries
{
  "metrics": [
    {
      "name": "COUNTFLOWINSTANCEID",
      "operator": "sum",
      "alias": "total_flows"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill"]
    }
  ],
  "downsampling": "DAY",
  "start": "2025-10-05 00:00:00",
  "end": "2025-10-07 23:59:59",
  "time_column": "STREAM_START_DATETIME",
  "drilldown": true,
  "timezone": "UTC",
  "ocp_organization_id": "org-123",
  "ocp_group_names": ["ocp-qa"]
}

Response:

[
  {
    "metric": "total_flows",
    "filters": {
      "AGENT_SKILL": "vb_skill",
      "ocp_group_names": "ocp-qa",
      "ocp_organization_id": "org-123"
    },
    "dps": {
      "2025-10-05 00:00:00.0": 0,
      "2025-10-06 00:00:00.0": 19,
      "2025-10-07 00:00:00.0": 3
    }
  }
]

Explanation:

  • Both ocp_organization_id and ocp_group_names are provided

  • Both appear in the response filters object when drilldown=true

  • User access is validated for both organization-level and group-level access

  • Data is filtered by both organization ID and group names


Simple Aggregations

Endpoint

POST /{version:v3|v4}/tables/{tableName}/aggregations

Description

Performs simple aggregation operations on the specified database table without time-series or grouping. This endpoint provides basic statistical aggregations across the entire filtered dataset. It's designed for tables that implement the Aggregable interface.

When to Use Simple Aggregations

  • Use case: Overall statistics without time-based or categorical breakdowns

  • Examples:

    • "What's the total count of all flows?"

    • "What's the average duration across all records?"

    • "What are the min/max values for a metric?"

Request Payload

{
  "filters": [
    {
      "column": "string",      // Primary Key column name (required)
      "values": ["string"]     // Array of filter values (required)
    }
  ],
  "start": "string",           // yyyy-MM-dd HH:mm:ss format (required)
  "end": "string",             // yyyy-MM-dd HH:mm:ss format (required)
  "timezone": "string",        // Timezone (optional, default: "UTC")
  "time_column": "string",     // Timestamp column name (required)
  "timezone_offset": "string",  // Fixed UTC offset (optional, e.g., "UTC+05:00", "UTC-08:00")
  "ocp_group_names": ["string"], // Array of group names (required*)
  "ocp_organization_id": "string", // OCP organization ID (optional)
  "metrics": [
    {
      "name": "string",        // Column name for aggregation (required)
      "operator": "string",    // sum|avg|min|max|count (required)
      "alias": "string"        // Custom name for result (required)
    }
  ]
}

At least one of ocp_organization_id or ocp_group_names must be provided. If ocp_organization_id is provided, the user will be validated based on organization-level access. If ocp_group_names is provided, the user will be validated based on group-level access. Both can be provided together.

Detailed Field Descriptions

Field

Type

Required

Default

Description

filters

Array

Required

List of filter conditions using primary key (PK) columns. Each entry contains a column (PK column name) and values (array of filter values). Values cannot be empty, and the column must be a PK column in the target table.

filters.column

String

Required

PK column name to filter by. Cannot be of type TIMESTAMP or exist in the excludedColumns list.

filters.values

Array of strings

Required

Array of values to filter by. Must not be empty.

start

String

Required

Start of the time range for data retrieval. Format: yyyy-MM-dd HH:mm:ss. Must be earlier than end.

end

String

Required

End of the time range for data retrieval. Format: yyyy-MM-dd HH:mm:ss. Must be later than start.

timezone

String

Optional

UTC

IANA timezone identifier for time calculations (for example, Europe/Athens, America/New_York). Used when timezone_offset is not provided. Handles daylight saving time (DST).

timezone_offset

String

Optional

Fixed UTC offset for time calculations (for example, UTC+05:00, UTC-08:00). Takes precedence over timezone when both are provided. Supports full-hour offsets only.

time_column

String

Required

Name of the TIMESTAMP PK column used for time-based filtering. Must be of type TIMESTAMP and a primary key column in the target table.

ocp_group_names

Array of strings

Conditionally required

OCP group names for access control. Required if ocp_organization_id is not provided. Must not be empty if ocp_organization_id is absent. Included in the response filters object as "ocp_group_names": ["value1", "value2"].

ocp_organization_id

String

Conditionally required

OCP organization ID for organization-level access control. Required if ocp_group_names is not provided. When present, user access is validated at the organization level. Included in the response filters object as "ocp_organization_id": ["value"].

metrics

Array

Required

List of calculation operations to perform. Each entry requires a name (column to aggregate), operator (sum, avg, min, max, or count), and alias (output name in the response).

metrics.name

String

Required

Column name to aggregate.

metrics.operator

String

Required

Aggregation function to apply. Accepted values: sum, avg, min, max, count.

metrics.alias

String

Required

Custom output name for the metric in the response.



Response Payload

{
  "filters": {                 // Applied filters including ocp_group_names param
    "column_name": ["value"]
    "ocp_group_names": ["value1", "value2"], // Present when ocp_group_names provided
    "ocp_organization_id": ["value"]         // Present when ocp_organization_id provided
  },
  "metrics": [
    {
      "name": "string",        // Metric alias
      "values": number        // Calculated metric value
    }
  ]
}
Detailed Field Descriptions

Field

Type

Required

Default

Description

filters

Array

Required

List of filter conditions using primary key (PK) columns. Each entry contains a column (PK column name) and values (array of filter values). Values cannot be empty, and the column must be a PK column in the target table.

filters.column

String

Required

PK column name to filter by. Cannot be of type TIMESTAMP or exist in the excludedColumns list.

filters.values

Array of strings

Required

Array of values to filter by. Must not be empty.

start

String

Required

Start of the time range for data retrieval. Format: yyyy-MM-dd HH:mm:ss. Must be earlier than end.

end

String

Required

End of the time range for data retrieval. Format: yyyy-MM-dd HH:mm:ss. Must be later than start.

timezone

String

Optional

UTC

IANA timezone identifier for time calculations (for example, Europe/Athens, America/New_York). Used when timezone_offset is not provided. Handles daylight saving time (DST).

timezone_offset

String

Optional

Fixed UTC offset for time calculations (for example, UTC+05:00, UTC-08:00). Takes precedence over timezone when both are provided. Supports full-hour offsets only.

time_column

String

Required

Name of the TIMESTAMP PK column used for time-based filtering. Must be of type TIMESTAMP and a primary key column in the target table.

ocp_group_names

Array of strings

Conditionally required

OCP group names for access control. Required if ocp_organization_id is not provided. Must not be empty if ocp_organization_id is absent. Included in the response filters object as "ocp_group_names": ["value1", "value2"].

ocp_organization_id

String

Conditionally required

OCP organization ID for organization-level access control. Required if ocp_group_names is not provided. When present, user access is validated at the organization level. Included in the response filters object as "ocp_organization_id": ["value"].

metrics

Array

Required

List of calculation operations to perform. Each entry requires a name (column to aggregate), operator (sum, avg, min, max, or count), and alias (output name in the response).

metrics.name

String

Required

Column name to aggregate.

metrics.operator

String

Required

Aggregation function to apply. Accepted values: sum, avg, min, max, count.

metrics.alias

String

Required

Custom output name for the metric in the response.

When no data are found the response is an empty object:

{}

Request & Response Examples

Example 1: Basic Aggregations

Request:

POST /metrics-api/v3/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/aggregations

{
  "metrics": [
    {
      "name": "COUNTFLOWINSTANCEID",
      "operator": "sum",
      "alias": "total_flows"
    },
    {
      "name": "TOTALDURATION",
      "operator": "avg",
      "alias": "avg_duration"
    },
    {
      "name": "TOTALDURATION",
      "operator": "count",
      "alias": "count_records"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill"]
    }
  ],
  "start": "2025-05-06 14:00:00",
  "end": "2025-10-09 14:00:00",
  "time_column": "STREAM_START_DATETIME",
  "ocp_group_names": ["ocp-qa", "group_123"]
}

Response:

{
  "filters": {
    "AGENT_SKILL": ["vb_skill"],
    "ocp_group_names": ["ocp-qa", "group_123"]
  },
  "metrics": [
    {
      "name": "total_flows",
      "values": 127
    },
    {
      "name": "avg_duration",
      "values": 132.070866
    },
    {
      "name": "count_records",
      "values": 10
    }
  ]
}

Explanation:

  • Returns overall statistics across the entire filtered dataset

  • No time-based or categorical grouping

  • All metrics are calculated over the same filtered dataset

  • Values are returned as strings to preserve decimal precision


Example 2: Multiple Operators on Same Column

Request:

POST /metrics-api/v3/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/aggregations

{
  "metrics": [
    {
      "name": "TOTALDURATION",
      "operator": "sum",
      "alias": "sum_duration"
    },
    {
      "name": "TOTALDURATION",
      "operator": "avg",
      "alias": "avg_duration"
    },
    {
      "name": "TOTALDURATION",
      "operator": "min",
      "alias": "min_duration"
    },
    {
      "name": "TOTALDURATION",
      "operator": "max",
      "alias": "max_duration"
    },
    {
      "name": "TOTALDURATION",
      "operator": "count",
      "alias": "count_duration"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill", "agentSkill"]
    }
  ],
  "start": "2025-05-06 14:00:00",
  "end": "2025-10-09 14:00:00",
  "time_column": "STREAM_START_DATETIME",
  "ocp_group_names": ["ocp-qa", "group_123"]
}

Response:

{
  "filters": {
    "AGENT_SKILL": ["vb_skill", "agentSkill"],
    "ocp_group_names": ["ocp-qa", "group_123"]
  },
  "metrics": [
    {
      "name": "sum_duration",
      "values": 5
    },
    {
      "name": "avg_duration",
      "values": 0.500000
    },
    {
      "name": "min_duration",
      "values": 0
    },
    {
      "name": "max_duration",
      "values": 1
    },
    {
      "name": "count_duration",
      "values": 10
    }
  ]
}

Explanation:

  • Multiple operators can be applied to the same column

  • Each operator requires a unique alias

  • Useful for getting comprehensive statistics (sum, average, min, max, count) in a single request


Example 3: Aggregations Without Filters

Request:

POST /metrics-api/v3/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/aggregations

{
  "metrics": [
    {
      "name": "COUNTFLOWINSTANCEID",
      "operator": "sum",
      "alias": "total_flows"
    },
    {
      "name": "TOTALDURATION",
      "operator": "avg",
      "alias": "avg_duration"
    }
  ],
  "filters": [],
  "start": "2025-05-06 14:00:00",
  "end": "2025-10-09 14:00:00",
  "time_column": "STREAM_START_DATETIME",
  "ocp_group_names": ["ocp-qa", "group_123"]
}

Response:

{
  "filters": {
    "ocp_group_names": ["ocp-qa", "group_123"]
  },
  "metrics": [
    {
      "name": "total_flows",
      "values": 150
    },
    {
      "name": "avg_duration",
      "values": 125.500000
    }
  ]
}

Explanation:

  • Empty filters array means no column filters are applied

  • Only time range and ocp_group_names are used for filtering

  • Returns overall statistics across all data in the specified time range and groups


Example 4: Using timezone_offset

Request:

POST /metrics-api/v3/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/aggregations
{
  "metrics": [
    {
      "name": "COUNTFLOWINSTANCEID",
      "operator": "sum",
      "alias": "total_flows"
    },
    {
      "name": "TOTALDURATION",
      "operator": "avg",
      "alias": "avg_duration"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill"]
    }
  ],
  "start": "2025-05-06 14:00:00",
  "end": "2025-10-09 14:00:00",
  "time_column": "STREAM_START_DATETIME",
  "timezone_offset": "UTC+05:00",
  "ocp_group_names": ["ocp-qa"]
}

Response:

{
  "filters": {
    "AGENT_SKILL": ["vb_skill"],
    "ocp_group_names": ["ocp-qa"]
  },
  "metrics": [
    {
      "name": "total_flows",
      "values": 127
    },
    {
      "name": "avg_duration",
      "values": 132.070866
    }
  ]
}

Explanation:

  • timezone_offset is used instead of timezone

  • The start/end dates in the request are interpreted as UTC+05:00 local time

  • Data is filtered based on UTC+05:00 timezone


Example 5: Using ocp_organization_id

Request:

POST /metrics-api/v3/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/aggregations
{
  "metrics": [
    {
      "name": "COUNTFLOWINSTANCEID",
      "operator": "sum",
      "alias": "total_flows"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill"]
    }
  ],
  "start": "2025-05-06 14:00:00",
  "end": "2025-10-09 14:00:00",
  "time_column": "STREAM_START_DATETIME",
  "timezone": "UTC",
  "ocp_organization_id": "org-123",
  "ocp_group_names": ["ocp-qa"]
}

Response:

{
  "filters": {
    "AGENT_SKILL": ["vb_skill"],
    "ocp_group_names": ["ocp-qa"],
    "ocp_organization_id": ["org-123"]
  },
  "metrics": [
    {
      "name": "total_flows",
      "values": 127
    }
  ]
}

Explanation:

  • Both ocp_organization_id and ocp_group_names are provided

  • Both appear in the response filters object

  • User access is validated for both organization-level and group-level access

  • Data is filtered by both organization ID and group names


Group Aggregation

Endpoint

POST /{version:v3|v4}/tables/{tableName}/groups

Description

Performs group-based aggregation on the specified database table. This endpoint allows grouping data by specific columns and calculating metrics for each group. It's designed for tables that implement the Aggregable interface.

The endpoint supports:

  • Base Metrics: Aggregate operations (sum, avg, min, max, count) on table columns

  • Expressions: Calculated metrics derived from base metrics using mathematical expressions

  • Percentage Calculations: Distribution percentages within groups

  • Multi-dimensional Grouping: Group by multiple columns simultaneously

Request Payload

{
  "filters": [
    {
      "column": "string",      // Primary Key column name (required)
      "values": ["string"]     // Array of filter values (required)
    }
  ],
  "start": "string",           // yyyy-MM-dd HH:mm:ss format (required)
  "end": "string",             // yyyy-MM-dd HH:mm:ss format (required)
  "timezone": "string",        // Timezone (optional, default: "UTC")
  "time_column": "string",     // Timestamp column name (required)
  "timezone_offset": "string",  // Fixed UTC offset (optional, e.g., "UTC+05:00", "UTC-08:00")
  "ocp_group_names": ["string"], // Array of group names (required*)
  "ocp_organization_id": "string", // OCP organization ID (optional)
  "metrics": [
    {
      "name": "string",        // Column name for aggregation (required)
      "operator": "string",    // sum|avg|min|max|count (required)
      "alias": "string"        // Custom name for result (required)
    }
  ],
  "expressions": [             // Optional: Calculated metrics
    {
      "expression": "string",  // Mathematical formula using metric aliases (required)
      "alias": "string"        // Output name for expression result (required)
    }
  ],
  "group_by": {
    "columns": ["string"],     // Primary Key columns for grouping (required)
    "percentage": ["string"]   // Subset of columns for percentage (optional)
  }
}

At least one of ocp_organization_id or ocp_group_names must be provided. If ocp_organization_id is provided, the user will be validated based on organization-level access. If ocp_group_names is provided, the user will be validated based on group-level access. Both can be provided together.

Detailed Field Descriptions

Field

Type

Required

Default

Description

filters

Array

Required

List of filter conditions using primary key (PK) columns. The filter object can be empty. Only PK columns are allowed. A column can appear in both filters and group_by.columns: in filters only, data is filtered but not grouped; in both, results are grouped but restricted to the filtered values; in group_by.columns only, results are grouped by all values of that column.

filters.column

String

Required

PK column name to filter by. Cannot be of type TIMESTAMP or exist in the excludedColumns list.

filters.values

Array of strings

Required

Array of values to filter by.

start

String

Required

Start of the time range for data retrieval. Format: yyyy-MM-dd HH:mm:ss. Must be earlier than end.

end

String

Required

End of the time range for data retrieval. Format: yyyy-MM-dd HH:mm:ss. Must be later than start.

timezone

String

Optional

UTC

IANA timezone identifier for time calculations (for example, Europe/Athens, America/New_York). Used when timezone_offset is not provided. Handles daylight saving time (DST).

timezone_offset

String

Optional

Fixed UTC offset for time calculations (for example, UTC+05:00, UTC-08:00). Takes precedence over timezone when both are provided. Supports full-hour offsets only.

time_column

String

Required

Name of the TIMESTAMP PK column used for time-based filtering and grouping. Must be of type TIMESTAMP and a primary key column in the target table.

ocp_group_names

Array of strings

Conditionally required

OCP group names for access control. Required if ocp_organization_id is not provided. Must not be empty if ocp_organization_id is absent. Included in the response filters object as "ocp_group_names": ["value1", "value2"].

ocp_organization_id

String

Conditionally required

OCP organization ID for organization-level access control. Required if ocp_group_names is not provided. When present, user access is validated at the organization level. Included in the response filters object as "ocp_organization_id": ["value"].

metrics

Array

Required

List of metric aggregations to compute on non-PK columns. Each entry requires a name, operator, and alias. Only non-PK columns can be aggregated. Percentage calculations are only allowed with sum or count operators.

metrics.name

String

Required

Column name to aggregate. Must be a non-PK column.

metrics.operator

String

Required

Aggregation function to apply. Accepted values: sum, avg, min, max, count.

metrics.alias

String

Required

Custom output name for the metric in the response. Must be unique and cannot conflict with expression aliases.

expressions

Array

Optional

List of calculated metrics derived from base metrics using mathematical expressions. Expressions are evaluated per group after base metrics are aggregated. Cannot reference other expression aliases, only metric aliases.

expressions.expression

String

Required (if using expressions)

Mathematical formula referencing metric aliases (for example, (completed / total) * 100). Supports +, -, *, /, and parentheses.

expressions.alias

String

Required (if using expressions)

Output name for the calculated metric in the response. Must be unique and cannot conflict with metric aliases.

group_by

Object

Required

Configuration for grouping results. Contains columns (PK columns to group by) and an optional percentage subset.

group_by.columns

Array of strings

Required

PK columns to group results by. Cannot be of type TIMESTAMP. Can overlap with filters — a column can appear in both.

group_by.percentage

Array of strings

Optional

Subset of group_by.columns for percentage calculation. Only supported when all metrics use sum or count operators. Not supported with avg, min, or max.


Expressions Functionality

The groups endpoint supports calculated metrics using mathematical expressions. Expressions allow you to derive new metrics from base metrics using standard arithmetic operations.

Expressions enable you to:

  • Calculate ratios (e.g., completion rates, success percentages)

  • Compute averages (e.g., average duration per call)

  • Perform complex calculations (e.g., weighted averages, percentages)

  • Create derived metrics without storing them in the database

Expression Syntax

Expressions are written as mathematical formulas using:

  • Metric aliases: Reference base metrics by their alias names

  • Arithmetic operators: +, -, *, /, ()

  • Constants: Numeric values (e.g., 100, 60, 0.5)

Important Rules:

  • Expressions can only reference metric aliases from the metrics array

  • Expressions cannot reference other expression aliases (no chaining)

  • Division by zero is automatically handled (returns null)

  • Results are rounded to 4 decimal places

Expression Examples

Example 1: Simple Ratio

{
  "expression": "completed_flows / total_flows",
  "alias": "completion_rate"
}

Calculates: completed_flows ÷ total_flows (e.g., 0.85 = 85%)

Example 2: Percentage

{
  "expression": "(completed_flows / total_flows) * 100",
  "alias": "completion_percentage"
}

Calculates: (completed_flows ÷ total_flows) × 100 (e.g., 85.0 = 85%)

Example 3: Average Calculation

{
  "expression": "sum_total_duration / sum_total_calls",
  "alias": "avg_duration_per_call"
}

Calculates: sum_total_duration ÷ sum_total_calls (average duration)

Example 4: Complex Expression

{
  "expression": "((successful_completions / total_flows) * 100) + bonus_points",
  "alias": "weighted_score"
}

Calculates a weighted score using multiple operations.


Percentage Calculation Logic

The percentage calculation feature allows you to see how each group contributes to a larger total. Understanding how percentages are calculated helps you interpret the results correctly and make data-driven decisions.

When you request percentages, you specify which grouping columns should be used as the basis for the calculation:

  1. If percentage array is provided: Percentages show how each group compares to the total for the specified columns.

  2. If percentage is null, empty, or omitted: No percentages are calculated.

Understanding Percentage Calculation

Think of percentage calculation as answering: "What portion of the total does this group represent?"

The key is understanding what "the total" means:

  • The total is determined by the columns you specify in the percentage array

  • The percentage shows how much each group contributes to that total

  • All percentages for the same total will sum to 100%

Restrictions

  • Percentage calculations are only supported for sum and count operators

  • Not supported for avg, min, or max operators

  • Percentage columns must be a subset of group_by.columns

Example: Percentage Logic Explained

Consider this request:

{
  "group_by": {
    "columns": ["AGENT_SKILL", "FLOW_INSTANCE_STATUS"],
    "percentage": ["AGENT_SKILL"]
  }
}

What this means:

  • You're grouping results by both AGENT_SKILL and FLOW_INSTANCE_STATUS

  • Percentages are calculated relative to each AGENT_SKILL (not the overall total)

In Business Terms:

  • For each agent skill, you'll see what percentage of that skill's flows have each status

  • This lets you compare status distributions across different skills

  • Each skill's percentages will sum to 100%

Example Data:

Agent Skill    | Flow Status | Flow Count
---------------|------------|------------
vb_skill       | COMPLETED  | 22
vb_skill       | FAILED     | 39
vb_skill       | REJECTED   | 66
18645244       | FAILED     | 1

Percentage Calculation for vb_skill:

  • Total flows for vb_skill = 22 + 39 + 66 = 127

  • COMPLETED: 22 out of 127 = 17.32% of vb_skill's flows

  • FAILED: 39 out of 127 = 30.71% of vb_skill's flows

  • REJECTED: 66 out of 127 = 51.97% of vb_skill's flows

  • Note: These percentages sum to 100% for vb_skill

Percentage Calculation for 18645244:

  • Total flows for 18645244 = 1

  • FAILED: 1 out of 1 = 100.00% of 18645244's flows

Business Insight:

  • vb_skill has a mix of statuses (17% completed, 31% failed, 52% rejected)

  • 18645244 only has failed flows (100%)

  • This comparison helps identify which skills need attention

When to Use Different Percentage Columns

Scenario 1: Percentage of Overall Total

{
  "group_by": {
    "columns": ["AGENT_SKILL"],
    "percentage": ["AGENT_SKILL"]
  }
}

What it shows:

  • What percentage of the total flows each skill represents

  • All percentages sum to 100% across all skills

  • Use case: "Which skills handle the most volume?"

Example Result:

  • vb_skill: 85% of all flows

  • agent_skill: 15% of all flows

  • Total: 100%


Scenario 2: Percentage Within Each Group

{
  "group_by": {
    "columns": ["AGENT_SKILL", "FLOW_INSTANCE_STATUS"],
    "percentage": ["AGENT_SKILL"]
  }
}

What it shows:

  • What percentage each status represents within each skill

  • Percentages sum to 100% for each skill separately

  • Use case: "What's the status breakdown for each skill?"

Example Result:

  • vb_skill → COMPLETED: 20%, FAILED: 30%, REJECTED: 50% (sums to 100%)

  • agent_skill → COMPLETED: 60%, FAILED: 25%, REJECTED: 15% (sums to 100%)

  • Insight: Each skill has its own 100% breakdown, allowing comparison of status distributions


Scenario 3: Percentage Over Multiple Dimensions

{
  "group_by": {
    "columns": ["AGENT_SKILL", "FLOW_INSTANCE_STATUS", "REGION"],
    "percentage": ["AGENT_SKILL", "REGION"]
  }
}

What it shows:

  • What percentage each status represents within each (AGENT_SKILL, REGION) combination

  • Percentages sum to 100% for each unique (AGENT_SKILL, REGION) pair

  • Use case: "How do statuses vary by skill and region?"

Example Result:

  • (vb_skill, us-east) → COMPLETED: 25%, FAILED: 35%, REJECTED: 40% (sums to 100%)

  • (vb_skill, us-west) → COMPLETED: 15%, FAILED: 25%, REJECTED: 60% (sums to 100%)

  • Insight: Same skill can have different status distributions in different regions


Response Payload

{
  "filters": {                 // Applied filters
    "column_name": ["value"]
    "ocp_group_names": ["group_a", "group_b"]  // Present when ocp_group_names provided
    "ocp_organization_id": ["value"]          // Present when ocp_organization_id provided
  },
  "group_by": {
    "columns": ["string"],     // Grouping columns used
    "percentage": ["string"]   // Percentage columns (if specified)
  },
  "metrics": [
    {
      "name": "string",        // Metric or expression alias
      "groups": [
        {
          "key": ["string"],   // Group combination values
          "value": "object",   // Calculated metric value
          "percentage": {      // Percentage calculation (if requested)
            "value": "object",
            "calculated_over": ["string"]
          }
        }
      ]
    }
  ]
}
Response Field Descriptions

Field

Type

Always present

Default

Description

filters

Object

Yes

Object containing all applied filters, along with ocp_group_names and ocp_organization_id when provided in the request. Keys are filter column names; values are arrays of filter values. Returns an empty object {} when no data is found.

filters.{column_name}

Array of strings

Conditional

Key-value pair where the key is the filter column name and the value is an array of the filter values applied.

filters.ocp_group_names

Array of strings

Conditional

Present when ocp_group_names is provided in the request. Contains the group names used for access control (for example, ["group_a", "group_b"]).

filters.ocp_organization_id

Array of strings

Conditional

Present when ocp_organization_id is provided in the request. Contains the organization ID as a single-element array (for example, ["org-123"]).

group_by

Object

Yes

Object containing the grouping and percentage configuration used in the request. Always present since group_by is mandatory in the request.

group_by.columns

Array of strings

Yes

PK column names used for grouping. Never empty.

group_by.percentage

Array of strings

Conditional

Percentage columns used for calculation. Only present when specified in the request. Only supported with sum or count operators; not supported with avg, min, or max.

metrics

Array of objects

Yes

Array of aggregated metrics and expressions, one object per metric or expression from the request. Base metrics appear first (in request order), followed by expressions (in request order).

metrics[].name

String

Yes

The alias name from the request, matching either a metric alias or an expression alias.

metrics[].groups

Array of objects

Yes

Contains the grouped results for this metric or expression. Contains one object per unique group combination when grouping is applied.

metrics[].groups[].key

Array of strings

Yes

Values for each group_by column, in the same order as the group_by.columns array. Never empty when grouping is applied.

metrics[].groups[].value

Number or null

Yes

The aggregated result for base metrics (based on the operator: sum, avg, min, max, or count), or the calculated result for expressions. Returns null when division by zero occurs in an expression.

metrics[].groups[].percentage

Object

Conditional

Present only when percentage columns are specified in the request. Contains the calculated percentage value and the context it was calculated over. Applies to both base metrics and expressions.

metrics[].groups[].percentage.value

Number

Conditional

The calculated percentage value (for example, 30.71).

metrics[].groups[].percentage.calculated_over

Array of strings

Conditional

Values of the percentage columns used as the denominator for the percentage calculation. Indicates the subset of data the percentage was calculated against (for example, ["vb_skill"] means the percentage was calculated over all rows where that column equals vb_skill).

When no data is found, the response is an empty object {}.


Request & Response Examples

Example 1: Basic Group Aggregation with Percentage

Request:

POST /metrics-api/v4/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/groups

{
  "metrics": [
    { 
      "name": "COUNTFLOWINSTANCEID",
      "operator": "sum", 
      "alias": "sum_COUNTFLOWINSTANCEID"
    },
    { 
      "name": "TOTALDURATION",
      "operator": "sum", 
      "alias": "sum_TOTALDURATION"
    } 
  ],
  "filters": [
    {
      "column": "FLOW_INSTANCE_STATUS",
      "values": ["active"]
    }
  ],
  "start": "2025-10-05 11:00:00.000",
  "end": "2025-10-11 12:02:00.000",
  "time_column": "STREAM_START_DATETIME", 
  "timezone": "UTC",
  "group_by": {
    "columns": ["AGENT_SKILL", "FLOW_INSTANCE_STATUS"],
    "percentage": ["AGENT_SKILL"]
  },
  "ocp_group_names": ["ocp-qa", "group_123"]
}

Response:

{
  "filters": {
    "FLOW_INSTANCE_STATUS": ["active"],
    "ocp_group_names": ["ocp-qa", "group_123"]
  },
  "group_by": {
    "columns": ["AGENT_SKILL", "FLOW_INSTANCE_STATUS"],
    "percentage": ["AGENT_SKILL"]
  },
  "metrics": [
    {
      "name": "sum_COUNTFLOWINSTANCEID",
      "groups": [
        {
          "key": ["vb_skill", "active"],
          "value": 120,
          "percentage": {
            "value": 72.73,
            "calculated_over": ["vb_skill"]
          }
        },
        {
          "key": ["agentSkill", "active"],
          "value": 45,
          "percentage": {
            "value": 100.00,
            "calculated_over": ["agentSkill"]
          }
        }
      ]
    },
    {
      "name": "sum_TOTALDURATION",
      "groups": [
        {
          "key": ["vb_skill", "active"],
          "value": 1500,
          "percentage": {
            "value": 72.73,
            "calculated_over": ["vb_skill"]
          }
        },
        {
          "key": ["agentSkill", "active"],
          "value": 320,
          "percentage": {
            "value": 100.00,
            "calculated_over": ["agentSkill"]
          }
        }
      ]
    }
  ]
}

Explanation:

  • Filtering by FLOW_INSTANCE_STATUS = "active" and grouping by both AGENT_SKILL and FLOW_INSTANCE_STATUS

  • Filter column (FLOW_INSTANCE_STATUS) is different from the primary grouping column (AGENT_SKILL)

  • Percentages calculated over AGENT_SKILL only

  • For vb_skill, the percentage shows what portion of all vb_skill flows have status active

  • The calculated_over field shows ["vb_skill"], indicating the percentage is relative to all vb_skill rows

  • ocp_group_names appears in the response filters object (automatically added)


Example 2: Group Aggregation with Expressions

Request:

POST /metrics-api/v4/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/groups
{
  "metrics": [
    {
      "name": "FLOW_INSTANCES_COMPLETED",
      "operator": "sum",
      "alias": "completed_flows"
    },
    {
      "name": "FLOW_INSTANCES_TOTAL",
      "operator": "sum",
      "alias": "total_flows"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill"]
    }
  ],
  "start": "2025-11-01 00:00:00",
  "end": "2025-12-31 23:59:59",
  "time_column": "STREAM_START_DATETIME",
  "timezone": "UTC",
  "group_by": {
    "columns": ["AGENT_SKILL"]
  },
  "expressions": [
    {
      "expression": "(completed_flows / total_flows) * 100",
      "alias": "completion_rate"
    }
  ],
  "ocp_group_names": ["group_123"]
}

Response:

{
  "filters": {
    "AGENT_SKILL": ["vb_skill"],
    "ocp_group_names": ["group_123"]
  },
  "group_by": {
    "columns": ["AGENT_SKILL"]
  },
  "metrics": [
    {
      "name": "completed_flows",
      "groups": [
        {
          "key": ["vb_skill"],
          "value": 22
        }
      ]
    },
    {
      "name": "total_flows",
      "groups": [
        {
          "key": ["vb_skill"],
          "value": 127
        }
      ]
    },
    {
      "name": "completion_rate",
      "groups": [
        {
          "key": ["vb_skill"],
          "value": 17.3228
        }
      ]
    }
  ]
}

Explanation:

  • Base metrics are calculated first (completed_flows, total_flows)

  • Expression is calculated using base metric values: completion_rate = (22 / 127) * 100 = 17.3228%

  • Expression appears in the response with the same structure as base metrics

  • ocp_group_names appears in the response filters object (automatically added)


Example 3: Group Aggregation Without Percentage

Request:

POST /metrics-api/v4/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/groups
{
  "metrics": [
    { 
      "name": "COUNTFLOWINSTANCEID",
      "operator": "sum", 
      "alias": "sum_COUNTFLOWINSTANCEID"
    },
    { 
      "name": "TOTALDURATION",
      "operator": "sum", 
      "alias": "sum_TOTALDURATION"
    } 
  ],
  "filters": [
    {
      "column": "FLOW_INSTANCE_STATUS",
      "values": ["active"]
    }
  ],
  "start": "2025-10-05 11:00:00.000",
  "end": "2025-10-11 12:02:00.000",
  "time_column": "STREAM_START_DATETIME",
  "timezone": "UTC",
  "group_by": {
    "columns": ["AGENT_SKILL", "FLOW_INSTANCE_STATUS"]
  },
  "ocp_group_names": ["ocp-qa", "group_123"]
}

Response:

{
  "filters": {
    "FLOW_INSTANCE_STATUS": ["active"],
    "ocp_group_names": ["ocp-qa", "group_123"]
  },
  "group_by": {
    "columns": ["AGENT_SKILL", "FLOW_INSTANCE_STATUS"]
  },
  "metrics": [
    {
      "name": "sum_COUNTFLOWINSTANCEID",
      "groups": [
        {
          "key": ["vb_skill", "active"],
          "value": 120
        },
        {
          "key": ["agentSkill", "active"],
          "value": 45
        }
      ]
    },
    {
      "name": "sum_TOTALDURATION",
      "groups": [
        {
          "key": ["vb_skill", "active"],
          "value": 1500
        },
        {
          "key": ["agentSkill", "active"],
          "value": 320
        }
      ]
    }
  ]
}

Explanation:

  • Filtering by FLOW_INSTANCE_STATUS = "active" and grouping by both AGENT_SKILL and FLOW_INSTANCE_STATUS

  • Filter column (FLOW_INSTANCE_STATUS) is different from the primary grouping column (AGENT_SKILL)

  • No percentage field in group_by, so no percentage calculations are performed

  • Response contains only metric values without percentage information

  • Simpler response structure when percentages are not needed

  • ocp_group_names appears in the response filters object (automatically added)


Example 4: Group Aggregation with Expressions and Percentage

Request:

POST /metrics-api/v4/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/groups
{
  "metrics": [
    {
      "name": "FLOW_INSTANCES_COMPLETED",
      "operator": "sum",
      "alias": "completed_flows"
    },
    {
      "name": "FLOW_INSTANCES_TOTAL",
      "operator": "sum",
      "alias": "total_flows"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill", "agent_skill"]
    }
  ],
  "start": "2025-11-01 00:00:00",
  "end": "2025-12-31 23:59:59",
  "time_column": "STREAM_START_DATETIME",
  "timezone": "UTC",
  "group_by": {
    "columns": ["AGENT_SKILL"],
    "percentage": ["AGENT_SKILL"]
  },
  "expressions": [
    {
      "expression": "(completed_flows / total_flows) * 100",
      "alias": "completion_rate"
    }
  ],
  "ocp_group_names": ["group_123"]
}

Response:

{
  "filters": {
    "AGENT_SKILL": ["vb_skill", "agent_skill"],
    "ocp_group_names": ["group_123"]
  },
  "group_by": {
    "columns": ["AGENT_SKILL"],
    "percentage": ["AGENT_SKILL"]
  },
  "metrics": [
    {
      "name": "completed_flows",
      "groups": [
        {
          "key": ["vb_skill"],
          "value": 22,
          "percentage": {
            "value": 100.00,
            "calculated_over": ["vb_skill"]
          }
        },
        {
          "key": ["agent_skill"],
          "value": 8,
          "percentage": {
            "value": 26.67,
            "calculated_over": ["agent_skill"]
          }
        }
      ]
    },
    {
      "name": "total_flows",
      "groups": [
        {
          "key": ["vb_skill"],
          "value": 127,
          "percentage": {
            "value": 84.67,
            "calculated_over": ["vb_skill"]
          }
        },
        {
          "key": ["agent_skill"],
          "value": 23,
          "percentage": {
            "value": 15.33,
            "calculated_over": ["agent_skill"]
          }
        }
      ]
    },
    {
      "name": "completion_rate",
      "groups": [
        {
          "key": ["vb_skill"],
          "value": 17.3228,
          "percentage": {
            "value": 73.33,
            "calculated_over": ["vb_skill"]
          }
        },
        {
          "key": ["agent_skill"],
          "value": 34.7826,
          "percentage": {
            "value": 26.67,
            "calculated_over": ["agent_skill"]
          }
        }
      ]
    }
  ]
}

Explanation:

  • Base metrics are calculated first (completed_flows, total_flows)

  • Expression is calculated: completion_rate = (completed_flows / total_flows) * 100

  • Percentages are calculated for both base metrics and expressions

  • Base metric percentages show distribution across skills (e.g., total_flows: vb_skill has 84.67% of all flows)

  • Expression percentages show distribution of expression values (e.g., completion_rate: vb_skill's completion rate represents 73.33% of the total completion rate values)

  • ocp_group_names appears in the response filters object (automatically added)


Example 5: Filter Column Exists in Group By

This example demonstrates the case where a filter column is also used in the GROUP BY clause. This is useful when you want to filter to specific values of a dimension while still grouping by that same dimension.

Request:

POST /metrics-api/v4/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/groups
{
  "metrics": [
    { 
      "name": "COUNTFLOWINSTANCEID",
      "operator": "sum", 
      "alias": "sum_COUNTFLOWINSTANCEID"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill", "agentSkill"]
    }
  ],
  "start": "2025-10-05 11:00:00.000",
  "end": "2025-10-11 12:02:00.000",
  "time_column": "STREAM_START_DATETIME", 
  "group_by": {
    "columns": ["AGENT_SKILL", "FLOW_INSTANCE_STATUS"]
  },
  "ocp_group_names": ["ocp-qa"]
}

Response:

{
  "filters": {
    "AGENT_SKILL": ["vb_skill", "agentSkill"],
    "ocp_group_names": ["ocp-qa"]
  },
  "group_by": {
    "columns": ["AGENT_SKILL", "FLOW_INSTANCE_STATUS"]
  },
  "metrics": [
    {
      "name": "sum_COUNTFLOWINSTANCEID",
      "groups": [
        {
          "key": ["vb_skill", "COMPLETED"],
          "value": 88
        },
        {
          "key": ["vb_skill", "FAILED"],
          "value": 39
        },
        {
          "key": ["agentSkill", "COMPLETED"],
          "value": 5
        },
        {
          "key": ["agentSkill", "FAILED"],
          "value": 2
        }
      ]
    }
  ]
}

Explanation:

  • AGENT_SKILL appears in both filters and group_by.columns

  • The WHERE clause filters to only ["vb_skill", "agentSkill"]

  • Results are grouped by both AGENT_SKILL and FLOW_INSTANCE_STATUS

  • This allows you to see metrics broken down by status for only the specific agent skills you're interested in

  • Use Case: Compare performance by status between specific applications/skills

  • Key Point: When a filter column exists in GROUP BY, you can filter to specific values while still grouping by that dimension to see breakdowns within the filtered subset

  • ocp_group_names appears in the response filters object (automatically added)


Example 6: Using timezone_offset

Request:

POST /metrics-api/v4/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/groups
{
  "metrics": [
    { 
      "name": "COUNTFLOWINSTANCEID",
      "operator": "sum", 
      "alias": "sum_COUNTFLOWINSTANCEID"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill"]
    }
  ],
  "start": "2025-10-05 11:00:00.000",
  "end": "2025-10-11 12:02:00.000",
  "time_column": "STREAM_START_DATETIME", 
  "group_by": {
    "columns": ["AGENT_SKILL", "FLOW_INSTANCE_STATUS"]
  },
  "timezone_offset": "UTC+05:00",
  "ocp_group_names": ["ocp-qa"]
}

Response:

{
  "filters": {
    "AGENT_SKILL": ["vb_skill"],
    "ocp_group_names": ["ocp-qa"]
  },
  "group_by": {
    "columns": ["AGENT_SKILL", "FLOW_INSTANCE_STATUS"]
  },
  "metrics": [
    {
      "name": "sum_COUNTFLOWINSTANCEID",
      "groups": [
        {
          "key": ["vb_skill", "COMPLETED"],
          "value": 88
        },
        {
          "key": ["vb_skill", "FAILED"],
          "value": 39
        }
      ]
    }
  ]
}

Explanation:

  • timezone_offset is used instead of timezone

  • The start/end dates in the request are interpreted as UTC+05:00 local time

  • Data is filtered based on UTC+05:00 timezone


Example 7: Using ocp_organization_id

Request:

POST /metrics-api/v4/tables/AGENT_ASSIST_FLOW_COMPLETION_RATE/groups
{
  "metrics": [
    { 
      "name": "COUNTFLOWINSTANCEID",
      "operator": "sum", 
      "alias": "sum_COUNTFLOWINSTANCEID"
    }
  ],
  "filters": [
    {
      "column": "AGENT_SKILL",
      "values": ["vb_skill"]
    }
  ],
  "start": "2025-10-05 11:00:00.000",
  "end": "2025-10-11 12:02:00.000",
  "time_column": "STREAM_START_DATETIME", 
  "group_by": {
    "columns": ["AGENT_SKILL", "FLOW_INSTANCE_STATUS"]
  },
  "timezone": "UTC",
  "ocp_organization_id": "org-123",
  "ocp_group_names": ["ocp-qa"]
}

Response:

{
  "filters": {
    "AGENT_SKILL": ["vb_skill"],
    "ocp_group_names": ["ocp-qa"],
    "ocp_organization_id": ["org-123"]
  },
  "group_by": {
    "columns": ["AGENT_SKILL", "FLOW_INSTANCE_STATUS"]
  },
  "metrics": [
    {
      "name": "sum_COUNTFLOWINSTANCEID",
      "groups": [
        {
          "key": ["vb_skill", "COMPLETED"],
          "value": 88
        },
        {
          "key": ["vb_skill", "FAILED"],
          "value": 39
        }
      ]
    }
  ]
}

Explanation:

  • Both ocp_organization_id and ocp_group_names are provided

  • Both appear in the response filters object

  • User access is validated for both organization-level and group-level access

  • Data is filtered by both organization ID and group names


Empty Response

When no data are found, the response is an empty object:

{}

Quick Start Guide for Clients

  1. Discover Available Tables
    First, call the Get Available Tables endpoint to see what tables you can query:

    GET /metrics-api/{version:v3|v4}/tables
    
  2. Understand Table Structure
    Choose a table and call Describe Table Structure to see what columns are available:

    GET /metrics-api/{version:v3|v4}/tables/{tableName}
    
    1. Look for these column types in the response:

      • Primary Key columns (marked as isPrimaryKey: true) → Use for filters and group_by

      • Timestamp columns (dataType contains "TIMESTAMP") → Use for time_column

      • Numeric columns (INTEGER, DECIMAL, FLOAT, etc.) → Use for metrics

  3. Choose Your Analysis Type
    Based on what you want to analyze, pick the right endpoint:

    1. For Time-Based Analysis → Use Time Series Aggregation

      • When to use: You want to see how metrics change over time.

      • Column requirements:

        • time_column: Any timestamp column - Required

        • metrics: Any numeric columns - Required

        • filters: Only Primary Key columns - Optional

        • expressions: Calculated metrics from existing metrics - Optional - When to use: You want to calculate derived metrics like ratios, percentages, or complex formulas

      • Example: "Show me average duration per hour for the last 24 hours."

      • Example with expressions: "Show me completion rate (success / total) per hour for the last 24 hours" -

    2. For Overall Statistics → Use Simple Aggregations

      • When to use: You want overall statistics without time or grouping.

      • Column requirements:

        • metrics: Any numeric columns for calculations - Required

        • filters: Only Primary Key columns - Optional

      • Example: "What's the overall average duration and total count?"

    3. For Group Comparisons → Use Group Aggregation

      • When to use: You want to compare metrics across different categories.

      • Column requirements:

        • group_by.columns: Only Primary Key columns, not present in filters - Required

        • group_by.percentage: Must be a subset of group_by.columns - Optional - calculates percentage of each group. Only allowed when using sum or count operators. Not supported for avg, min, or max operators.

        • metrics: Any numeric columns for calculations - Required

        • filters: Only Primary Key columns - Optional

        • expressions: Calculated metrics from existing metrics - Optional - When to use: You want to calculate derived metrics like ratios, percentages, or averages from grouped data.

      • Example: "Show me total count grouped by activity_type and status".

      • Example with expressions: "Show me completion rate (completed / total) grouped by agent_skill".

  4. Build Your Request
    Use the table structure information to build your request:
    From table description, identify:

    • Primary Key columns (marked as isPrimaryKey: true) → Use for filters, group_by.columns and group_by.percentage

    • Timestamp columns (dataType contains "TIMESTAMP") → Use for time_column

    • Numeric columns (INTEGER, DECIMAL, FLOAT, etc.) → Use for metrics

Key Rules

  • Filters: Only Primary Key columns can be used

  • Group By Columns: Only Primary Key columns can be used

  • Group By Percentage: Must be a subset of group_by.columns (also PK columns)

  • Metrics: Any numeric column.

  • Time Column: Any timestamp column

  • Expressions: Reference metric aliases from the metrics array

Date Format
All date fields use the format: yyyy-MM-dd HH:mm:ss

Downsampling Options (for timeseries endpoint)

  • FIVE_MIN - 5 minute intervals

  • HOUR - 1 hour intervals

  • DAY - 1 day intervals

  • WEEK - 1 week intervals

  • MONTH - 1 month intervals

  • YEAR - 1 year intervals

Supported Operators

  • sum - Sum of values

  • avg - Average of values

  • min - Minimum value

  • max - Maximum value

  • count - Count of records