openapi: 3.0.3 info: title: Gravitee.io APIM - Management API - Analytics description: |- This API allows to query analytics data from the Gravitee.io APIM. The API provides three types of data representations: - **Measures**: Return aggregated values for specified metrics - **Facets**: Group data by facet values with optional sorting and limits, eventually leading to measures. - **Time Series**: Return data points over time with optional grouping by facet, eventually leading to measures. Each endpoint allows to query multiple metrics at once within a time range, following the same top-level filters, parameters and dimensions. contact: name: The Gravitee.io APIM Team url: https://github.com/gravitee-io/issues/issues/ email: team-apim@graviteesource.com license: name: Apache 2.0 url: http://www.apache.org/licenses/LICENSE-2.0.html version: 2.0.0 tags: - name: computation description: Analytics computation operations for data processing and aggregation - name: definition description: Gravitee analytics definition containing metrics, facets and filters that can be used to query analytics data. - name: dashboards description: Custom dashboard management operations for creating, reading, updating, and deleting analytics dashboards servers: - url: "/management/v2" description: APIM Management API v2 - Default base URL - url: "/management/v2/organizations/{orgId}" description: APIM Management API v2 - Base URL to target specific organizations variables: orgId: description: The unique ID of your organization default: DEFAULT paths: /environments/{envId}/analytics/definition/apis: get: operationId: queryApiSpecs summary: Query available APIs for analytics description: | Returns a list of available APIs for analytics, that can be used to obtain available metrics each one of them. tags: - definition parameters: - $ref: "#/components/parameters/EnvId" responses: "200": description: | The response contains a list of available APIs for analytics, that can be used to obtain available metrics each one of them. content: application/json: schema: $ref: "#/components/schemas/ApiSpecsResponse" examples: apis: summary: API Specs Response value: data: - name: "HTTP_PROXY" label: "HTTP Proxy" - name: "MESSAGE" label: "Message" - name: "LLM" label: "LLM" - name: "MCP" label: "MCP" - name: "NATIVE" label: "Native" "500": description: Internal server error while getting available API specs. content: application/json: schema: $ref: "#/components/schemas/Error" /environments/{envId}/analytics/definition/apis/{apiName}/metrics: get: operationId: queryMetricSpecs summary: Query available metrics for an API type description: | Returns a list of available metrics for a specific API type, including their supported measures, facets, and filters. tags: - definition parameters: - $ref: "#/components/parameters/EnvId" - $ref: "#/components/parameters/ApiName" responses: "200": description: | The response contains a list of available metrics for the specified API type, with their configurations including measures, facets, and filters. content: application/json: schema: $ref: "#/components/schemas/MetricSpecsResponse" examples: http-proxy-metrics: summary: HTTP Proxy API Metrics value: data: - name: "HTTP_REQUESTS" label: "HTTP Requests" apis: ["HTTP_PROXY", "LLM"] measures: ["COUNT"] facets: ["API", "APPLICATION", "GATEWAY"] filters: ["API", "APPLICATION", "HTTP_STATUS"] - name: "HTTP_GATEWAY_RESPONSE_TIME" label: "Gateway response time" apis: ["HTTP_PROXY", "LLM"] unit: "MILLISECONDS" measures: ["AVG", "MIN", "MAX", "P50", "P90", "P95", "P99"] facets: ["API", "APPLICATION", "GATEWAY"] filters: ["API", "APPLICATION", "HTTP_STATUS"] "400": description: Bad request - Invalid API name for metrics. content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error while getting metric specifications. content: application/json: schema: $ref: "#/components/schemas/Error" /environments/{envId}/analytics/definition/metrics/{metricName}/filters: get: operationId: queryFilterSpecsForMetric summary: Query available filters for a specific metric description: | Returns a list of available filters that can be applied to a specific metric within an API type, including their operators and value constraints. tags: - definition parameters: - $ref: "#/components/parameters/EnvId" - $ref: "#/components/parameters/MetricName" responses: "200": description: | The response contains a list of available filters for the specified metric, including their supported operators, types, and optional enum values or ranges. content: application/json: schema: $ref: "#/components/schemas/FilterSpecsResponse" examples: http-requests-filters: summary: HTTP Requests Metric Filters value: data: - name: "API" label: "API" type: "KEYWORD" operators: ["EQ", "IN"] - name: "APPLICATION" label: "Application" type: "KEYWORD" operators: ["EQ", "IN"] - name: "HTTP_STATUS" label: "Status Code" type: "NUMBER" operators: ["EQ", "LTE", "GTE"] range: min: 100 max: 600 - name: "HTTP_STATUS_CODE_GROUP" label: "Status Code Group" type: "ENUM" operators: ["EQ", "IN"] enumValues: ["1xx", "2xx", "3xx", "4xx", "5xx"] "400": description: Bad request - Invalid metric name for filters. content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: API type or metric not found. content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error while getting filter specifications for the metric. content: application/json: schema: $ref: "#/components/schemas/Error" /environments/{envId}/analytics/definition/metrics/{metricName}/facets: get: operationId: queryFacetSpecsForMetric summary: Query available facets for a specific metric description: | Returns a list of available facets that can be used to group data for a specific metric within an API type, including their data types. tags: - definition parameters: - $ref: "#/components/parameters/EnvId" - $ref: "#/components/parameters/MetricName" responses: "200": description: | The response contains a list of available facets for the specified metric that can be used for grouping analytics data, including their data types. content: application/json: schema: $ref: "#/components/schemas/FacetSpecsResponse" examples: http-requests-facets: summary: HTTP Requests Metric Facets value: data: - name: "API" label: "API" type: "KEYWORD" - name: "APPLICATION" label: "Application" type: "KEYWORD" - name: "GATEWAY" label: "Gateway" type: "KEYWORD" "400": description: Bad request - Invalid metric name for facets. content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error while getting facet specifications for the metric. content: application/json: schema: $ref: "#/components/schemas/Error" /environments/{envId}/observability/filters/definition: get: operationId: queryObservabilityFilterDefinitions summary: Query available filter definitions for observability description: | Returns the full list of available filter definitions that can be applied to observability queries, including their operators, types, and value constraints. tags: - definition parameters: - $ref: "#/components/parameters/EnvId" responses: "200": description: | The response contains a list of all available filter definitions for observability features, including their supported operators, types, and optional enum values or ranges. content: application/json: schema: $ref: "#/components/schemas/FilterSpecsResponse" examples: filter-definitions: summary: Filter Definitions value: data: - name: "API" label: "API" type: "KEYWORD" operators: ["EQ", "IN"] - name: "HTTP_STATUS" label: "Status Code" type: "NUMBER" operators: ["EQ", "LTE", "GTE"] range: min: 100 max: 599 - name: "API_TYPE" label: "API Type" type: "ENUM" operators: ["EQ", "IN"] enumValues: ["HTTP_PROXY", "LLM", "MESSAGE", "MCP", "NATIVE"] "500": description: Internal server error while getting filter definitions. content: application/json: schema: $ref: "#/components/schemas/Error" /environments/{envId}/observability/filters/resolve: post: operationId: resolveObservabilityFilterLabels summary: Resolve display labels for observability filter values description: | Resolves stable filter value identifiers (for example API, APPLICATION, or PLAN ids) into display labels. This endpoint is used when hydrating dashboard filters from the URL, where labels are intentionally not stored. tags: - definition parameters: - $ref: "#/components/parameters/EnvId" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ResolveFilterLabelsRequest" responses: "200": description: Resolved display labels grouped by filter name. content: application/json: schema: $ref: "#/components/schemas/ResolveFilterLabelsResponse" examples: resolved-labels: summary: API labels value: entries: - filterName: "API" labels: "67e246cb-ab02-4da4-8f47-f9fa3e061d6b": "Public API" "400": description: The request exceeds the maximum number of entries or identifiers. content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error while resolving filter labels. content: application/json: schema: $ref: "#/components/schemas/Error" /environments/{envId}/observability/filters/{filterName}/values: get: operationId: getObservabilityFilterValues summary: Get values for an observability filter description: | Returns a paginated list of distinct values for a given filter within an optional time range. - ENUM filters return their static enum values. - KEYWORD filters return distinct values from the analytics data store. - NUMBER and STRING filters are not supported and return 400. tags: - definition parameters: - $ref: "#/components/parameters/EnvId" - name: filterName in: path required: true description: The filter name for which to retrieve values schema: $ref: "#/components/schemas/FilterName" - name: from in: query required: false description: Start of the time range (epoch milliseconds). Only applies to KEYWORD filters. schema: type: integer format: int64 - name: to in: query required: false description: End of the time range (epoch milliseconds). Only applies to KEYWORD filters. schema: type: integer format: int64 - name: page in: query required: false description: Page number (starting from 1) schema: type: integer minimum: 1 maximum: 10000 default: 1 - name: perPage in: query required: false description: Number of items per page schema: type: integer minimum: 1 default: 10 - name: query in: query required: false description: | Optional search string (case-insensitive). For ENUM filters, matches enum labels by substring. For KEYWORD filters backed by analytics data (Elasticsearch), matches the stored keyword value exactly. For ID-based filters (API, APPLICATION, PLAN), matches display names by substring. schema: type: string responses: "200": description: A paginated list of filter values. content: application/json: schema: $ref: "#/components/schemas/FilterValuesResponse" examples: keyword-values: summary: KEYWORD filter values (direct-value) value: data: - value: "gateway-1" - value: "gateway-2" pagination: page: 1 perPage: 10 pageCount: 1 pageItemsCount: 2 totalCount: 2 enum-values: summary: ENUM filter values value: data: - value: "GET" - value: "POST" - value: "PUT" pagination: page: 1 perPage: 10 pageCount: 1 pageItemsCount: 3 totalCount: 3 "400": description: | The filter type does not support value listing (NUMBER or STRING filters). content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error while getting filter values. content: application/json: schema: $ref: "#/components/schemas/Error" /environments/{envId}/analytics/measures: post: operationId: queryMeasures summary: Query measures analytics description: | Return aggregated values for specified metrics within a time range. tags: - computation parameters: - $ref: "#/components/parameters/EnvId" requestBody: description: | A measures request is a request to obtain a single set of measures, without grouping them by bucket. - Measures requests allow to return aggregated values for the specified metric and measures. - Available measures can change depending on the required metric. - The measures object is always represented as the leaf node of the response for other types of analytics requests. - Additional filters can be applied at the metric level, allowing to refine the representation of the metric. required: true content: application/json: schema: $ref: "#/components/schemas/MeasuresRequest" examples: single-metric: summary: Single metric with multiple measures request value: timeRange: from: "2025-01-01T00:00:00Z" to: "2025-01-31T23:59:59Z" metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] multiple-metrics: summary: Multiple metrics request value: timeRange: from: "2025-01-01T00:00:00Z" to: "2025-01-31T23:59:59Z" metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] - name: "HTTP_GATEWAY_RESPONSE_TIME" measures: ["AVG"] responses: "200": description: | A measures response provides aggregated values for the metrics defined in the request. content: application/json: schema: $ref: "#/components/schemas/MeasuresResponse" examples: single-metric: summary: Single metric with multiple values response value: metrics: - name: "HTTP_REQUESTS" measures: - name: "COUNT" value: 2984 multiple-metrics: summary: Multiple metrics response value: metrics: - name: "HTTP_REQUESTS" measures: - name: "COUNT" value: 2984 - name: "HTTP_GATEWAY_RESPONSE_TIME" measures: - name: "AVG" value: 89.5 "400": description: Bad request - Invalid Measures Request. content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error while computing measures. content: application/json: schema: $ref: "#/components/schemas/Error" /environments/{envId}/analytics/facets: post: operationId: queryFacets summary: Query facets analytics description: | Group data by facet values with optional ranging, sorting and limits. Facet requests are limited to 3 dimensions in the by clause. Sorting and ranging always apply to the last given facet. tags: - computation parameters: - $ref: "#/components/parameters/EnvId" requestBody: description: | A facets request is a request to obtain measures grouped by facet. - Each metric follows the same top-level facets, limits and order. - Each facet can be in turn grouped by one facet to provide a multi-dimensional representation of the data. - Facets are represented as a tree of facet buckets, following the order given in the `by` clause of the request. - Additional filters can be applied at the metric level, allowing to refine the representation of the metric. required: true content: application/json: schema: $ref: "#/components/schemas/FacetsRequest" examples: single-facet-with-sort: summary: Single facet with sort request value: timeRange: from: "2025-01-01T00:00:00Z" to: "2025-01-31T23:59:59Z" by: ["API"] limit: 5 metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] sorts: [{ "measure": "COUNT", "order": "DESC" }] single-facet-with-ranges: summary: Single facet with ranges request value: timeRange: from: "2025-01-01T00:00:00Z" to: "2025-01-31T23:59:59Z" by: ["HTTP_STATUS"] ranges: [{ "from": 100, "to": 399 }, { "from": 400, "to": 599 }] metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] multiple-facets: summary: Multiple facets request value: timeRange: from: "2025-01-01T00:00:00Z" to: "2025-01-31T23:59:59Z" by: ["API", "APPLICATION"] metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] responses: "200": description: Facets analytics response content: application/json: schema: $ref: "#/components/schemas/FacetsResponse" examples: single-facet-with-sort: summary: Single facet with sort response value: metrics: - name: "HTTP_REQUESTS" buckets: - key: "07ba30d4-7b42-418b-a3f9-2ad684947b82" name: "api-1" type: LEAF measures: - name: "COUNT" value: 1234 - key: "a0131e80-d886-462a-8c0b-1d205e42cc12" name: "api-2" type: LEAF measures: - name: "COUNT" value: 989 single-facet-with-ranges: summary: Single facet with ranges value: metrics: - name: "HTTP_REQUESTS" buckets: - key: "07ba30d4-7b42-418b-a3f9-2ad684947b82" name: "api-1" type: GROUP buckets: - key: "100-399" name: "100-399" type: LEAF measures: - name: "COUNT" value: 989 - key: "400-599" name: "400-599" type: LEAF measures: - name: "COUNT" value: 784 - key: "a0131e80-d886-462a-8c0b-1d205e42cc12" name: "api-2" type: GROUP buckets: - key: "100-399" name: "100-399" type: LEAF measures: - name: "COUNT" value: 879 - key: "400-599" name: "400-599" type: LEAF measures: - name: "COUNT" value: 364 multiple-facets: summary: Single facet with ranges value: metrics: - name: "HTTP_REQUESTS" buckets: - key: "07ba30d4-7b42-418b-a3f9-2ad684947b82" name: "api-1" type: GROUP buckets: - key: "4dad61f1-3977-4aee-b37d-a840a87a5dd1" name: "app-2" type: LEAF measures: - name: "COUNT" value: 989 - key: "4c5eb203-7e97-4bdf-92a0-d75bfe8fa4bc" name: "app-5" type: LEAF measures: - name: "COUNT" value: 784 - key: "a0131e80-d886-462a-8c0b-1d205e42cc12" name: "api-2" type: GROUP buckets: - key: "290ea4a9-8b1f-4532-9c39-42f1b6b42fce" name: "app-2" type: LEAF measures: - name: "COUNT" value: 879 - key: "6514fc4d-811e-4383-83cb-11628b99b6e9" name: "app-4" type: LEAF measures: - name: "COUNT" value: 364 "400": description: Bad request - Invalid Facets Request. content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error while computing facets. content: application/json: schema: $ref: "#/components/schemas/Error" /environments/{envId}/analytics/time-series: post: operationId: queryTimeSeries summary: Query time series analytics description: | Return data points over time with optional grouping by facets. Time series responses will include the lower and upper bound of the time range as the first and last buckets. tags: - computation parameters: - $ref: "#/components/parameters/EnvId" requestBody: description: | A time series request is a request to obtain data points over time, organized by a specified interval. - The time series buckets can be themselves nested by facets (up to 2), allowing to group data by multiple nested facets over time. - Facets are represented as a tree of facet buckets, following the order given in the by clause of the request. - Each metric follows the same top-level interval, facets and filters. - Additional filters can be applied at the metric level, allowing to refine the representation of the metric. required: true content: application/json: schema: $ref: "#/components/schemas/TimeSeriesRequest" examples: single-metric: summary: Single metric request value: timeRange: from: "2025-11-22T16:40:30Z" to: "2025-11-22T16:45:30Z" interval: 3600000 metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] multiple-metrics: summary: Multiple metrics request value: timeRange: from: "2025-11-22T16:40:30Z" to: "2025-11-22T16:45:30Z" interval: 3600000 metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] - name: "HTTP_GATEWAY_RESPONSE_TIME" measures: ["AVG"] single-metric-with-facet: summary: Single metric request with facet and range value: timeRange: from: "2025-11-22T16:40:30Z" to: "2025-11-22T16:45:30Z" interval: 60000 by: ["API"] ranges: [{ from: 100, to: 399 }, { from: 400, to: 599 }] metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] responses: "200": description: Time series analytics response content: application/json: schema: $ref: "#/components/schemas/TimeSeriesResponse" examples: single-metric: summary: Single metrics response value: metrics: - name: "HTTP_REQUESTS" buckets: - key: "2025-01-01T00:00:00Z" timestamp: 1735689600000 type: LEAF measures: - name: "COUNT" value: 1234 - key: "2025-01-01T00:01:00Z" timestamp: 1735689660000 type: LEAF measures: - name: "COUNT" value: 873 - key: "2025-01-01T00:01:00Z" timestamp: 1735689720000 type: LEAF measures: - name: "COUNT" value: 984 multiple-metric: summary: Multiple metrics response value: metrics: - name: "HTTP_REQUESTS" buckets: - key: "2025-01-01T00:00:00Z" timestamp: 1735689600000 type: LEAF measures: - name: "COUNT" value: 1234 - key: "2025-01-01T00:01:00Z" timestamp: 1735689660000 type: LEAF measures: - name: "COUNT" value: 873 - key: "2025-01-01T00:01:00Z" timestamp: 1735689720000 type: LEAF measures: - name: "COUNT" value: 984 - name: "HTTP_GATEWAY_RESPONSE_TIME" buckets: - key: "2025-01-01T00:00:00Z" timestamp: 1735689600000 type: LEAF measures: - name: "AVG" value: 43.43 - key: "2025-01-01T00:01:00Z" timestamp: 1735689660000 type: LEAF measures: - name: "AVG" value: 53.69 - key: "2025-01-01T00:01:00Z" timestamp: 1735689720000 type: LEAF measures: - name: "AVG" value: 60.80 single-metric-with-facet-and-range: summary: Single metric response with facet and ranges value: metrics: - name: "HTTP_REQUESTS" buckets: - key: "2025-01-01T00:00:00Z" timestamp: 1735689600000 type: GROUP buckets: - key: "100-399" name: "100-399" type: LEAF measures: - name: "COUNT" value: 587 - key: "400-599" name: "400-599" type: LEAF measures: - name: "COUNT" value: 487 - key: "2025-01-01T00:01:00Z" timestamp: 1735689660000 type: GROUP buckets: - key: "100-399" name: "100-399" type: LEAF measures: - name: "COUNT" value: 387 - key: "400-599" name: "400-599" type: LEAF measures: - name: "COUNT" value: 489 - key: "2025-01-01T00:01:00Z" timestamp: 1735689720000 type: GROUP buckets: - key: "100-399" name: "100-399" type: LEAF measures: - name: "COUNT" value: 345 - key: "400-599" name: "400-599" type: LEAF measures: - name: "COUNT" value: 743 "400": description: Bad request - Invalid Time Series Request content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error while computing time series. content: application/json: schema: $ref: "#/components/schemas/Error" /environments/{envId}/analytics/dashboards: parameters: - $ref: "#/components/parameters/EnvId" get: operationId: listDashboards summary: List custom analytics dashboards description: | Retrieves a paginated list of all custom analytics dashboards for the current environment. tags: - dashboards parameters: - name: page in: query description: Page number (starting from 1) required: false schema: type: integer minimum: 1 default: 1 - name: perPage in: query description: Number of items per page required: false schema: type: integer minimum: 1 default: 10 responses: "200": description: List of dashboards for the current environment. content: application/json: schema: $ref: "#/components/schemas/DashboardsResponse" examples: dashboards-list: summary: A paginated list of dashboards value: data: - id: "d0152e36-ad24-4f74-a4df-443074d5a796" name: "llm-proxy" createdBy: "e2b573b4-30c8-4c7b-a67b-ad4ab15502d1" createdAt: "2025-10-07T06:50:30Z" lastModified: "2025-10-07T06:50:30Z" labels: graviteeio/team: "apim" widgets: - id: "1" title: "Requests" type: "stats" layout: cols: 1 rows: 1 x: 0 "y": 0 request: type: "measures" timeRange: from: "2025-10-07T06:50:30Z" to: "2025-12-07T11:35:30Z" metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] pagination: page: 1 perPage: 10 pageCount: 1 pageItemsCount: 1 totalCount: 1 links: self: "/environments/{envId}/analytics/dashboards?page=1&perPage=10" "403": description: Forbidden - Insufficient permissions to list dashboards. content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error while listing dashboards. content: application/json: schema: $ref: "#/components/schemas/Error" post: operationId: createDashboard summary: Create a custom analytics dashboard description: | Creates a new custom analytics dashboard with the provided name, labels, and widget definitions. The dashboard will be assigned a unique ID and associated with the authenticated user as the creator. tags: - dashboards requestBody: description: | The dashboard definition to create. The request must include a name and may include labels and widget definitions. Each widget defines its type, layout position, and the analytics request it represents. required: true content: application/json: schema: $ref: "#/components/schemas/CreateUpdateDashboard" examples: simple-dashboard: summary: Simple dashboard with stats and facets widgets value: name: "llm-proxy" labels: graviteeio/team: "apim" widgets: - id: "1" title: "Requests" type: "stats" layout: cols: 1 rows: 1 y: 0 x: 0 request: type: "measures" timeRange: from: "2025-10-07T06:50:30Z" to: "2025-12-07T11:35:30Z" metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] - id: "2" title: "HTTP Statuses" type: "doughnut" layout: cols: 1 rows: 2 y: 1 x: 0 request: type: "facets" timeRange: from: "2025-10-07T06:50:30Z" to: "2025-12-07T11:35:30Z" by: ["HTTP_STATUS_CODE_GROUP"] metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] - id: "3" title: "EU Traffic per API" type: "line" layout: cols: 3 rows: 2 y: 3 x: 0 request: type: "facets" timeRange: from: "2025-10-07T06:50:30Z" to: "2025-12-07T11:35:30Z" filters: - name: "ZONE" operator: "EQ" value: "EU" by: ["API"] limit: 5 metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] responses: "201": description: | The dashboard has been successfully created. The response contains the full dashboard definition including the generated ID, creator, and timestamps. content: application/json: schema: $ref: "#/components/schemas/Dashboard" examples: created-dashboard: summary: Created dashboard response value: id: "d0152e36-ad24-4f74-a4df-443074d5a796" name: "llm-proxy" createdBy: "e2b573b4-30c8-4c7b-a67b-ad4ab15502d1" createdAt: "2025-10-07T06:50:30Z" lastModified: "2025-10-07T06:50:30Z" labels: graviteeio/team: "apim" widgets: - id: "1" title: "Requests" type: "stats" layout: cols: 1 rows: 1 y: 0 x: 0 request: type: "measures" timeRange: from: "2025-10-07T06:50:30Z" to: "2025-12-07T11:35:30Z" metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] headers: Location: description: URL of the newly created dashboard schema: type: string format: uri example: "/environments/{envId}/analytics/dashboards/d0152e36-ad24-4f74-a4df-443074d5a796" "400": description: Bad request - Invalid dashboard definition. content: application/json: schema: $ref: "#/components/schemas/Error" "403": description: Forbidden - Insufficient permissions to create a dashboard. content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error while creating the dashboard. content: application/json: schema: $ref: "#/components/schemas/Error" /environments/{envId}/analytics/dashboards/{dashboardId}: parameters: - $ref: "#/components/parameters/EnvId" - $ref: "#/components/parameters/dashboardId" get: operationId: getDashboard summary: Get a custom analytics dashboard description: | Retrieves a custom analytics dashboard by its unique identifier. tags: - dashboards responses: "200": description: The dashboard has been successfully retrieved. content: application/json: schema: $ref: "#/components/schemas/Dashboard" "403": description: Forbidden - Insufficient permissions to view this dashboard. content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: No dashboard found for the given identifier. content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error while retrieving the dashboard. content: application/json: schema: $ref: "#/components/schemas/Error" put: operationId: updateDashboard summary: Update a custom analytics dashboard description: | Updates an existing custom analytics dashboard. All provided fields will replace the existing values. tags: - dashboards requestBody: description: | The dashboard fields to update. All fields are optional; only provided fields will be updated. required: true content: application/json: schema: $ref: "#/components/schemas/CreateUpdateDashboard" responses: "200": description: The dashboard has been successfully updated. content: application/json: schema: $ref: "#/components/schemas/Dashboard" "400": description: Bad request - The provided dashboard update payload is invalid. content: application/json: schema: $ref: "#/components/schemas/Error" "403": description: Forbidden - Insufficient permissions to update this dashboard. content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: The dashboard to update was not found. content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error while updating the dashboard. content: application/json: schema: $ref: "#/components/schemas/Error" delete: operationId: deleteDashboard summary: Delete a custom analytics dashboard description: | Deletes a custom analytics dashboard by its unique identifier. tags: - dashboards responses: "204": description: The dashboard has been successfully deleted. "403": description: Forbidden - Insufficient permissions to delete this dashboard. content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: The dashboard to delete was not found. content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error while deleting the dashboard. content: application/json: schema: $ref: "#/components/schemas/Error" components: parameters: EnvId: name: envId in: path required: true description: The unique ID of your environment schema: type: string default: DEFAULT ApiName: name: apiName in: path required: true description: The API type identifier for which to retrieve metrics schema: $ref: "#/components/schemas/ApiName" MetricName: name: metricName in: path required: true description: The metric identifier for which to retrieve filter specifications schema: $ref: "#/components/schemas/MetricName" dashboardId: name: dashboardId in: path required: true description: The unique identifier of the dashboard schema: type: string example: "d0152e36-ad24-4f74-a4df-443074d5a796" From: name: from in: query required: false description: The start time of the range schema: type: integer format: int64 To: name: to in: query required: false description: The end time of the range schema: type: integer format: int64 schemas: ApiName: type: string enum: - HTTP_PROXY - MESSAGE - LLM - MCP - A2A - NATIVE - EDGE description: Available API names for analytics queries example: "HTTP_PROXY" MetricName: type: string enum: - HTTP_REQUESTS - HTTP_ERRORS - HTTP_ERROR_RATE - HTTP_REQUEST_CONTENT_LENGTH - HTTP_RESPONSE_CONTENT_LENGTH - HTTP_ENDPOINT_RESPONSE_TIME - HTTP_GATEWAY_RESPONSE_TIME - HTTP_GATEWAY_LATENCY - LLM_PROMPT_TOKEN_SENT - LLM_PROMPT_TOKEN_RECEIVED - LLM_PROMPT_TOKEN_SENT_COST - LLM_PROMPT_TOKEN_RECEIVED_COST - LLM_PROMPT_TOTAL_TOKEN - LLM_PROMPT_TOKEN_TOTAL_COST - MESSAGE_PAYLOAD_SIZE - MESSAGES - MESSAGE_ERRORS - MESSAGE_GATEWAY_LATENCY - EDGE_DETECTION_COUNT - EDGE_TOKENS_IN - EDGE_TOKENS_OUT - EDGE_HEARTBEAT_COUNT - NATIVE_CONNECTIONS_SUMMARY description: Available metric names for analytics queries FacetName: type: string enum: - API - APPLICATION - PLAN - API_PRODUCT - GATEWAY - TENANT - ZONE - HTTP_METHOD - HTTP_STATUS_CODE_GROUP - HTTP_STATUS - HTTP_PATH - HTTP_PATH_MAPPING - HOST - GEO_IP_COUNTRY - GEO_IP_REGION - GEO_IP_CITY - GEO_IP_CONTINENT - CONSUMER_IP - HTTP_USER_AGENT_OS_NAME - HTTP_USER_AGENT_DEVICE - MESSAGE_CONNECTOR_TYPE - MESSAGE_CONNECTOR_ID - MESSAGE_OPERATION_TYPE - LLM_PROXY_MODEL - LLM_PROXY_PROVIDER - MCP_PROXY_METHOD - MCP_PROXY_TOOL - MCP_PROXY_RESOURCE - MCP_PROXY_PROMPT - EDGE_PROVIDER - EDGE_PROCESS - EDGE_CLIENT - EDGE_TYPE - EDGE_VERSION - EDGE_MODEL - EDGE_TOOL - NATIVE_CONNECTION_STATUS description: Available facet names for grouping analytics data FilterName: type: string enum: - API - APPLICATION - PLAN - API_PRODUCT - GATEWAY - TENANT - ZONE - HTTP_METHOD - HTTP_STATUS_CODE_GROUP - HTTP_STATUS - HTTP_PATH - HTTP_PATH_MAPPING - HOST - GEO_IP_COUNTRY - GEO_IP_REGION - GEO_IP_CITY - GEO_IP_CONTINENT - CONSUMER_IP - HTTP_USER_AGENT_OS_NAME - HTTP_USER_AGENT_DEVICE - MESSAGE_CONNECTOR_TYPE - MESSAGE_CONNECTOR_ID - MESSAGE_OPERATION_TYPE - MESSAGE_SIZE - MESSAGE_COUNT - MESSAGE_ERROR_COUNT - HTTP_ENDPOINT_RESPONSE_TIME - HTTP_GATEWAY_LATENCY - HTTP_GATEWAY_RESPONSE_TIME - HTTP_REQUEST_CONTENT_LENGTH - HTTP_RESPONSE_CONTENT_LENGTH - LLM_PROXY_MODEL - LLM_PROXY_PROVIDER - MCP_PROXY_METHOD - MCP_PROXY_TOOL - MCP_PROXY_RESOURCE - MCP_PROXY_PROMPT - API_TYPE - ERROR_KEY - REQUEST_ID - TRANSACTION_ID - EDGE_PROVIDER - EDGE_PROCESS - EDGE_CLIENT - EDGE_TYPE - EDGE_VERSION - EDGE_MODEL - EDGE_TOOL - NATIVE_CONNECTION_STATUS - URI - ENTRYPOINT description: Available filter names for filtering analytics data ObservabilityFilterName: type: string enum: - API - APPLICATION - PLAN - API_PRODUCT - GATEWAY - TENANT - ZONE - HTTP_METHOD - HTTP_STATUS_CODE_GROUP - HTTP_STATUS - HTTP_PATH - HTTP_PATH_MAPPING - HOST - GEO_IP_COUNTRY - GEO_IP_REGION - GEO_IP_CITY - GEO_IP_CONTINENT - CONSUMER_IP - HTTP_USER_AGENT_OS_NAME - HTTP_USER_AGENT_DEVICE - MESSAGE_CONNECTOR_TYPE - MESSAGE_CONNECTOR_ID - MESSAGE_OPERATION_TYPE - MESSAGE_SIZE - MESSAGE_COUNT - MESSAGE_ERROR_COUNT - HTTP_ENDPOINT_RESPONSE_TIME - HTTP_GATEWAY_LATENCY - HTTP_GATEWAY_RESPONSE_TIME - HTTP_REQUEST_CONTENT_LENGTH - HTTP_RESPONSE_CONTENT_LENGTH - LLM_PROXY_MODEL - LLM_PROXY_PROVIDER - MCP_PROXY_METHOD - MCP_PROXY_TOOL - MCP_PROXY_RESOURCE - MCP_PROXY_PROMPT - API_TYPE - ERROR_KEY - REQUEST_ID - TRANSACTION_ID - PAYLOAD - EDGE_PROVIDER - EDGE_PROCESS - EDGE_CLIENT - EDGE_TYPE - EDGE_VERSION - EDGE_MODEL - EDGE_TOOL - NATIVE_CONNECTION_STATUS - URI - ENTRYPOINT description: Filter names for observability filter definitions, including logs-only filters such as PAYLOAD Operator: type: string enum: - EQ - IN - LTE - GTE - CONTAINS description: Filter operator MeasureName: type: string enum: - AVG - MIN - MAX - P50 - P90 - P95 - P99 - COUNT - PERCENTAGE - SUM description: Measure name identifier. Represents the type of measure/aggregation applied to a metric. example: "COUNT" Measure: type: object required: - name - value description: A single measure result containing the measure name and its value. properties: name: $ref: "#/components/schemas/MeasureName" value: type: number description: The measure value. example: 2984 example: name: "COUNT" value: 2984 UnitName: type: string enum: - BYTES - MILLISECONDS - NUMBER - PERCENT description: | Unit of measurement for metrics. Specifies the unit in which the metric values are expressed. example: "BYTES" ApiSpec: description: | An API type specification. Available metrics are defined by the API type. type: object properties: name: $ref: "#/components/schemas/ApiName" label: type: string description: A human-readable label for the API example: "HTTP Proxy" example: name: "HTTP_PROXY" label: "HTTP Proxy" FacetSpec: type: object required: - name - label - type description: Facet specification for analytics grouping properties: name: $ref: "#/components/schemas/FacetName" label: type: string description: Human-readable label for the facet example: "API" type: type: string enum: - STRING - KEYWORD - NUMBER description: Data type of the facet example: "KEYWORD" example: name: "API" label: "API" type: "KEYWORD" FilterSpec: type: object required: - name - label - type - operators description: Filter specification for filtering analytics. Available filters are defined for a specific metric. properties: name: $ref: "#/components/schemas/ObservabilityFilterName" label: type: string description: Human-readable label for the filter example: "API" type: type: string enum: - KEYWORD - STRING - NUMBER - ENUM description: Data type of the filter example: "KEYWORD" operators: type: array items: $ref: "#/components/schemas/Operator" description: List of supported operators for this filter example: ["EQ", "IN"] enumValues: type: array items: type: string description: Enum values (only applicable for enum type) example: ["GET", "POST", "PUT"] range: type: object properties: min: type: number description: Minimum value example: 100 max: type: number description: Maximum value example: 600 description: Value range (only applicable for integer/long types) example: min: 100 max: 600 apiTypes: type: array items: $ref: "#/components/schemas/ApiName" description: List of API types this filter applies to, derived from the metrics that reference it. example: ["HTTP_PROXY", "LLM"] signals: type: array items: $ref: "#/components/schemas/FilterSignal" description: >- List of observability surfaces (query engines) supporting this filter, derived from the engines' own definitions. Only populated by the observability filter-definitions operation; absent elsewhere (e.g. per-metric filter specs), meaning no surface restriction applies. An empty list means no surface supports the filter and it must not be offered anywhere. example: ["ANALYTICS", "LOGS"] example: name: "API" label: "API" type: "KEYWORD" operators: ["EQ", "IN"] apiTypes: ["HTTP_PROXY", "MESSAGE", "LLM", "MCP"] signals: ["ANALYTICS", "LOGS"] FilterSignal: type: string enum: - ANALYTICS - LOGS description: An observability surface (query engine) able to evaluate a filter. MetricSpec: type: object required: - name - label - apis - measures - facets - filters description: Metric specification for analytics queries properties: name: $ref: "#/components/schemas/MetricName" label: type: string description: Human-readable label for the metric example: "HTTP Requests" apis: type: array items: $ref: "#/components/schemas/ApiName" description: List of API types this metric applies to example: ["HTTP_PROXY", "LLM"] unit: $ref: "#/components/schemas/UnitName" measures: type: array items: $ref: "#/components/schemas/MeasureName" description: List of supported measures for this metric example: ["COUNT"] facets: type: array items: $ref: "#/components/schemas/FacetName" description: List of facets that can be used for grouping this metric example: ["API", "APPLICATION", "GATEWAY"] filters: type: array items: $ref: "#/components/schemas/FilterName" description: List of filters that can be applied to this metric example: ["API", "APPLICATION", "HTTP_STATUS"] example: name: "HTTP_REQUESTS" label: "HTTP Requests" apis: ["HTTP_PROXY", "LLM"] measures: ["COUNT"] facets: ["API", "APPLICATION", "GATEWAY"] filters: ["API", "APPLICATION", "HTTP_STATUS"] ApiSpecsResponse: type: object properties: data: type: array items: $ref: "#/components/schemas/ApiSpec" description: The response contains a list of available APIs for analytics queries. example: data: - name: "HTTP_PROXY" label: "HTTP Proxy" - name: "MESSAGE" label: "Message" - name: "LLM" label: "LLM" - name: "MCP" label: "MCP" FacetSpecsResponse: type: object description: The response contains a list of available facets for grouping a metric. properties: data: type: array items: $ref: "#/components/schemas/FacetSpec" example: data: - name: "API" label: "API" type: "KEYWORD" - name: "APPLICATION" label: "Application" type: "KEYWORD" - name: "GATEWAY" label: "Gateway" type: "KEYWORD" FilterSpecsResponse: type: object description: The response contains a list of available filters for filtering analytics data. properties: data: type: array items: $ref: "#/components/schemas/FilterSpec" example: data: - name: "API" label: "API" type: "KEYWORD" operators: ["EQ", "IN"] - name: "HTTP_METHOD" label: "HTTP Method" type: "ENUM" operators: ["EQ", "IN"] enumValues: ["GET", "POST", "PUT"] - name: "HTTP_STATUS" label: "Status Code" type: "NUMBER" operators: ["EQ", "LTE", "GTE"] range: min: 100 max: 600 FilterValueItem: type: object required: - value description: A single filter value, optionally with an associated ID for ID-based filters (e.g. API, APPLICATION, PLAN). properties: value: type: string description: The display value of the filter option. example: "gateway-1" id: type: string description: The unique identifier associated with the value, present for ID-based filters. example: "67e246cb-ab02-4da4-8f47-f9fa3e061d6b" FilterValuesResponse: type: object description: A paginated list of filter values. properties: data: type: array items: $ref: "#/components/schemas/FilterValueItem" description: List of filter values for the current page pagination: $ref: "#/components/schemas/Pagination" example: data: - value: "gateway-1" - value: "gateway-2" - value: "gateway-3" pagination: page: 1 perPage: 10 pageCount: 1 pageItemsCount: 3 totalCount: 3 ResolveFilterLabelsRequestEntry: type: object required: - filterName - ids properties: filterName: $ref: "#/components/schemas/FilterName" ids: type: array description: Stable identifiers to resolve for the filter. maxItems: 100 items: type: string example: filterName: "API" ids: - "67e246cb-ab02-4da4-8f47-f9fa3e061d6b" ResolveFilterLabelsRequest: type: object required: - entries properties: entries: type: array description: Filter identifiers grouped by filter name. maxItems: 10 items: $ref: "#/components/schemas/ResolveFilterLabelsRequestEntry" ResolveFilterLabelsResponseEntry: type: object required: - filterName - labels properties: filterName: $ref: "#/components/schemas/FilterName" labels: type: object additionalProperties: type: string description: Map of id to display label. example: filterName: "API" labels: "67e246cb-ab02-4da4-8f47-f9fa3e061d6b": "Public API" ResolveFilterLabelsResponse: type: object properties: entries: type: array items: $ref: "#/components/schemas/ResolveFilterLabelsResponseEntry" MetricSpecsResponse: type: object description: The response contains a list of available metrics for a specific API type, including their supported measures, facets, and filters. properties: data: type: array items: $ref: "#/components/schemas/MetricSpec" example: data: - name: "HTTP_REQUESTS" label: "HTTP Requests" apis: ["HTTP_PROXY", "LLM"] measures: ["COUNT"] facets: ["API", "APPLICATION", "GATEWAY"] filters: ["API", "APPLICATION", "HTTP_STATUS"] - name: "HTTP_GATEWAY_RESPONSE_TIME" label: "Gateway response time" apis: ["HTTP_PROXY", "LLM"] unit: "MILLISECONDS" measures: ["AVG", "MIN", "MAX", "P50", "P90", "P95", "P99"] facets: ["API", "APPLICATION", "GATEWAY"] filters: ["API", "APPLICATION", "HTTP_STATUS"] Interval: description: | A fixed time interval for time series analytics queries. Intervals are be expressed in milliseconds or duration strings (e.g., 10s, 1m, 5h). oneOf: - type: string pattern: ^\d+[smhd]$ description: Shorthand for expressing interval in seconds, minutes, hours or days as a string example: "1s" - type: number description: Interval in milliseconds example: 1000 TimeRange: type: object required: - from - to description: Time range for analytics queries properties: from: type: string format: date-time description: Start timestamp as an ISO 8601 date string or an epoch unix timestamp example: "2025-01-01T00:00:00Z" to: type: string format: date-time description: End timestamp as an ISO 8601 date string or an epoch unix timestamp example: "2025-01-01T00:00:00Z" example: from: "2025-01-01T00:00:00Z" to: "2025-01-31T23:59:59Z" WidgetType: type: string enum: - stats - doughnut - pie - polarArea - time-series-line - time-series-bar - vertical-bar - horizontal-bar description: | The type of widget visualization. - **stats**: A single number KPI / stat widget displaying aggregated values. - **doughnut**: A doughnut chart widget for displaying proportional data. - **pie**: A pie chart widget for displaying proportional data. - **polarArea**: A polar area chart widget for displaying proportional data with varying radii. - **time-series-line**: A line chart widget for displaying data over time. - **time-series-bar**: A stacked bar chart widget for displaying data over time. - **vertical-bar**: A vertical bar chart widget for displaying comparative data across categories. - **horizontal-bar**: A horizontal bar chart widget for displaying comparative data across categories. example: "stats" WidgetLayout: type: object required: - cols - rows - x - y description: Layout positioning and sizing of a widget within the dashboard grid. properties: cols: type: integer minimum: 1 description: Number of columns the widget spans example: 1 rows: type: integer minimum: 1 description: Number of rows the widget spans example: 1 x: type: integer minimum: 0 description: Horizontal position (column index) in the grid example: 0 y: type: integer minimum: 0 description: Vertical position (row index) in the grid example: 0 example: cols: 1 rows: 1 x: 0 y: 0 WidgetRequest: type: object required: - type - timeRange - metrics description: | Defines the analytics request associated with a widget. This determines what data the widget displays. The `type` field selects the analytics request type. The structure aligns with the computation request schemas (see computation tag): - **measures**: Returns aggregated values. Same shape as `MeasuresRequest` (timeRange, metrics, filters). - **facets**: Groups data by facet values. Same shape as `FacetsRequest` (timeRange, by, metrics, limit, filters, ranges). - **time-series**: Returns data points over time. Same shape as `TimeSeriesRequest` (timeRange, interval, metrics, by, limit, filters, ranges). properties: type: type: string enum: - measures - facets - time-series description: The type of analytics request this widget represents (measures, facets, or time series) example: "measures" timeRange: $ref: "#/components/schemas/TimeRange" metrics: type: array minItems: 1 items: $ref: "#/components/schemas/MetricRequest" description: | List of metric requests to process. Uses `MetricRequest` which supports metric name, measures, and optional filters. interval: $ref: "#/components/schemas/Interval" by: type: array maxItems: 3 items: $ref: "#/components/schemas/FacetName" description: List of facet names to group by. Required when type is `facets`, optional for `time-series`, not applicable for `measures`. limit: type: integer minimum: 1 description: Maximum number of buckets to return. Applicable when type is `facets` or `time-series`. filters: type: array items: $ref: "#/components/schemas/Filter" description: Top-level filters applied to all metrics in this widget request. example: type: "measures" timeRange: from: "2025-10-07T06:50:30Z" to: "2025-12-07T11:35:30Z" filters: - name: "API" operator: "EQ" value: "7b6ebef3-6236-4ac5-815e-d3dcef83df5d" metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] Widget: type: object required: - id - title - type - layout - request description: A widget within a dashboard, defining its visualization type, position, and data source. properties: id: type: string description: Unique identifier of the widget within the dashboard example: "1" title: type: string minLength: 3 maxLength: 256 description: Display title of the widget example: "Requests" description: type: string maxLength: 512 description: Optional description of the widget example: "Total number of API requests" type: $ref: "#/components/schemas/WidgetType" layout: $ref: "#/components/schemas/WidgetLayout" request: $ref: "#/components/schemas/WidgetRequest" example: id: "1" title: "Requests" type: "stats" layout: cols: 1 rows: 1 x: 0 "y": 0 request: type: "measures" timeRange: from: "2025-10-07T06:50:30Z" to: "2025-12-07T11:35:30Z" metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] CreateUpdateDashboard: type: object required: - name description: Request body for creating a new custom analytics dashboard. properties: name: type: string minLength: 3 maxLength: 256 description: The name of the dashboard example: "llm-proxy" labels: type: object description: >- Key-value pairs of labels for organizing and categorizing dashboards. additionalProperties: type: string x-propertyNames: pattern: "^[^.]+$" example: graviteeio/team: "apim" widgets: type: array items: $ref: "#/components/schemas/Widget" description: List of widget definitions to include in the dashboard example: name: "llm-proxy" labels: graviteeio/team: "apim" widgets: - id: "1" title: "Requests" type: "stats" layout: cols: 1 rows: 1 x: 0 "y": 0 request: type: "measures" timeRange: from: "2025-10-07T06:50:30Z" to: "2025-12-07T11:35:30Z" metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] Dashboard: type: object required: - id - name - createdBy - createdAt - lastModified - widgets description: A custom analytics dashboard with its full definition including metadata, labels, and widgets. properties: id: type: string description: Unique identifier of the dashboard example: "d0152e36-ad24-4f74-a4df-443074d5a796" name: type: string description: The name of the dashboard example: "llm-proxy" createdBy: type: string description: The identifier of the user who created the dashboard. Deprecated — this field currently returns a raw user ID. In a future version it will be replaced by a structured object with display name and other user metadata. example: "e2b573b4-30c8-4c7b-a67b-ad4ab15502d1" deprecated: true createdAt: type: string format: date-time description: Timestamp when the dashboard was created (ISO 8601) example: "2025-10-07T06:50:30Z" lastModified: type: string format: date-time description: Timestamp when the dashboard was last modified (ISO 8601) example: "2025-10-07T06:50:30Z" labels: type: object description: >- Key-value pairs of labels for organizing and categorizing dashboards. additionalProperties: type: string x-propertyNames: pattern: "^[^.]+$" example: graviteeio/team: "apim" widgets: type: array items: $ref: "#/components/schemas/Widget" description: List of widget definitions in the dashboard default: [] example: id: "d0152e36-ad24-4f74-a4df-443074d5a796" name: "llm-proxy" createdBy: "e2b573b4-30c8-4c7b-a67b-ad4ab15502d1" createdAt: "2025-10-07T06:50:30Z" lastModified: "2025-10-07T06:50:30Z" labels: graviteeio/team: "apim" widgets: - id: "1" title: "Requests" type: "stats" layout: cols: 1 rows: 1 x: 0 "y": 0 request: type: "measures" timeRange: from: "2025-10-07T06:50:30Z" to: "2025-12-07T11:35:30Z" metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] DashboardsResponse: type: object description: Paginated response containing a list of custom analytics dashboards. properties: data: type: array items: $ref: "#/components/schemas/Dashboard" description: List of dashboards for the current page pagination: $ref: "#/components/schemas/Pagination" links: $ref: "#/components/schemas/Links" example: data: - id: "d0152e36-ad24-4f74-a4df-443074d5a796" name: "llm-proxy" createdBy: "e2b573b4-30c8-4c7b-a67b-ad4ab15502d1" createdAt: "2025-10-07T06:50:30Z" lastModified: "2025-10-07T06:50:30Z" labels: graviteeio/team: "apim" widgets: - id: "1" title: "Requests" type: "stats" layout: cols: 1 rows: 1 x: 0 "y": 0 request: type: "measures" timeRange: from: "2025-10-07T06:50:30Z" to: "2025-12-07T11:35:30Z" metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] pagination: page: 1 perPage: 10 pageCount: 1 pageItemsCount: 1 totalCount: 1 links: self: "/environments/{envId}/analytics/dashboards?page=1&perPage=10" Pagination: description: Generic object to handle pagination data. type: object properties: page: type: integer description: The current page. perPage: type: integer description: The number of items requested per page. pageCount: type: integer description: The total number of pages. pageItemsCount: type: integer description: The number of items for the current page. totalCount: type: integer format: int64 description: The total number of items, or `-1` if the count could not be computed within the configured timeout. Links: description: List of links for pagination properties: self: type: string description: Link to current resource first: type: string description: In a paginated response, link to the first page last: type: string description: In a paginated response, link to the last page previous: type: string description: In a paginated response, link to the previous page. Maybe null if current is the first page next: type: string description: In a paginated response, link to the next page. Maybe null if current is the last page Filter: description: | Filter specification for analytics queries. Filters can be used at the top level of a request to refine the analytics results, or nested within a metrics to refine specific measures. oneOf: - $ref: "#/components/schemas/StringFilter" - $ref: "#/components/schemas/NumberFilter" - $ref: "#/components/schemas/ArrayFilter" discriminator: propertyName: operator mapping: EQ: "#/components/schemas/StringFilter" CONTAINS: "#/components/schemas/StringFilter" LTE: "#/components/schemas/NumberFilter" GTE: "#/components/schemas/NumberFilter" IN: "#/components/schemas/ArrayFilter" example: name: "API" operator: "EQ" value: "7b6ebef3-6236-4ac5-815e-d3dcef83df5d" StringFilter: description: Filter specification for string values type: object required: [name, operator, value] properties: name: $ref: "#/components/schemas/FilterName" operator: $ref: "#/components/schemas/Operator" value: type: string description: Filter value (string for EQ) example: { name: "API", operator: "EQ", value: "api-id" } NumberFilter: description: Filter specification for numeric values type: object required: [name, operator, value] properties: name: $ref: "#/components/schemas/FilterName" operator: $ref: "#/components/schemas/Operator" value: type: integer description: Filter value (number for LTE/GTE) example: { name: "HTTP_STATUS", operator: "GTE", value: 200 } ArrayFilter: description: Filter specification for array values. type: object required: [name, operator, value] properties: name: $ref: "#/components/schemas/FilterName" operator: $ref: "#/components/schemas/Operator" value: type: array items: type: string description: Filter value (array for IN operator) example: { name: "HTTP_STATUS_CODE_GROUP", operator: "IN", value: ["2xx", "3xx"] } MeasuresRequest: type: object required: - timeRange - metrics description: Request for measures query - returns aggregated metric values properties: timeRange: $ref: "#/components/schemas/TimeRange" filters: type: array items: $ref: "#/components/schemas/Filter" description: Top-level filters example: - name: "API" operator: "EQ" value: "7b6ebef3-6236-4ac5-815e-d3dcef83df5d" - name: "HTTP_STATUS_CODE_GROUP" operator: "IN" value: ["2xx", "3xx"] metrics: type: array items: $ref: "#/components/schemas/MetricRequest" description: List of measure metric requests to process example: timeRange: from: "2025-01-01T00:00:00Z" to: "2025-01-31T23:59:59Z" filters: - name: "API" operator: "EQ" value: "7b6ebef3-6236-4ac5-815e-d3dcef83df5d" metrics: - name: "HTTP_GATEWAY_RESPONSE_TIME" measures: ["P90", "P95", "P99"] FacetsRequest: type: object required: - timeRange - by - metrics description: Request for facets query - groups data by facet values properties: timeRange: $ref: "#/components/schemas/TimeRange" by: type: array minItems: 1 maxItems: 3 items: $ref: "#/components/schemas/FacetName" description: List of facet names to group by (applies to all metrics) limit: type: integer minimum: 1 description: Maximum number of buckets to return (applies to all metrics) filters: type: array items: $ref: "#/components/schemas/Filter" description: Top-level filters example: - name: "APPLICATION" operator: "EQ" value: "aeacb40a-36e5-4294-8d9c-b6fa4752ec7b" - name: "HTTP_METHOD" operator: "IN" value: ["GET", "POST"] metrics: type: array minItems: 1 items: $ref: "#/components/schemas/FacetMetricRequest" description: List of facet metric requests to process ranges: $ref: "#/components/schemas/Ranges" example: timeRange: from: "2025-01-01T00:00:00Z" to: "2025-01-31T23:59:59Z" by: ["API", "APPLICATION"] limit: 2 metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] sort: [{ measure: "COUNT", order: "DESC" }] Ranges: description: Ranges to apply to facet metrics. At the moment, only number ranges are supported. type: array items: $ref: "#/components/schemas/NumberRange" NumberRange: type: object required: [from, to] properties: from: type: number to: type: number example: { from: 100, to: 600 } description: A numeric range. This can be used to break down buckets into ranges of values. TimeSeriesRequest: type: object required: - timeRange - interval - metrics description: | A time series request is a request to obtain data points over time, organized by a specified interval. The time series buckets can be themselves nested by facets, allowing to group data by multiple nested facets over time. properties: interval: $ref: "#/components/schemas/Interval" timeRange: $ref: "#/components/schemas/TimeRange" by: type: array maxItems: 2 items: $ref: "#/components/schemas/FacetName" description: List of facet names to group time-series buckets (up to two facets) limit: type: integer minimum: 1 description: Maximum number of nested buckets to return filters: type: array items: $ref: "#/components/schemas/Filter" description: Top-level time series filters example: - name: "APPLICATION" operator: "EQ" value: "aeacb40a-36e5-4294-8d9c-b6fa4752ec7b" - name: "HTTP_METHOD" operator: "IN" value: ["GET", "POST"] metrics: type: array minItems: 1 items: $ref: "#/components/schemas/FacetMetricRequest" description: List of facet metric requests to process ranges: $ref: "#/components/schemas/Ranges" example: timeRange: from: "2025-01-01T00:00:00Z" to: "2025-01-31T23:59:59Z" interval: 3600000 by: ["API"] filters: - name: "API" operator: "EQ" value: "7b6ebef3-6236-4ac5-815e-d3dcef83df5d" metrics: - name: "HTTP_REQUESTS" measures: ["COUNT"] - name: "HTTP_GATEWAY_RESPONSE_TIME" measures: ["AVG"] MetricRequest: type: object required: - name description: Simple metric request that is not involved in a faceted query. properties: name: $ref: "#/components/schemas/MetricName" measures: type: array items: $ref: "#/components/schemas/MeasureName" description: List of measures to compute for this metric filters: type: array items: $ref: "#/components/schemas/Filter" description: Request-level filters example: name: "HTTP_REQUESTS" measures: ["COUNT"] FacetMetricRequest: type: object required: - name description: A metric request that is involved in a faceted query, and handle sorting buckets by measures. properties: name: $ref: "#/components/schemas/MetricName" measures: type: array items: $ref: "#/components/schemas/MeasureName" description: List of measures to compute for this metric filters: type: array items: $ref: "#/components/schemas/Filter" description: Request-level filters sorts: $ref: "#/components/schemas/Sorts" Measures: type: array items: $ref: "#/components/schemas/Measure" description: | Array of measure results. Each measure contains a name and value. The measures array is always represented as the leaf node of the buckets tree for other types of analytics requests. Example: [{"name": "COUNT", "value": 2984}, {"name": "AVG", "value": 89.5}] example: - name: "COUNT" value: 2984 - name: "AVG" value: 89.5 Sorts: type: array items: $ref: "#/components/schemas/Sort" description: | Array of sort criteria. Each sort criteria contains a name and order. example: - by: "APPLICATION" measure: "COUNT" order: "DESC" limit: 2 Sort: type: object required: - measure - order properties: measure: $ref: "#/components/schemas/MeasureName" order: $ref: "#/components/schemas/SortOrder" description: Sort order specification SortOrder: type: string enum: - ASC - DESC description: Sort order Bucket: description: | A bucket represents a single facet bucket. Buckets can be nested and eventually lead to a leaf bucket with measures. oneOf: - $ref: "#/components/schemas/BucketLeaf" - $ref: "#/components/schemas/BucketGroup" discriminator: propertyName: type mapping: LEAF: "#/components/schemas/BucketLeaf" GROUP: "#/components/schemas/BucketGroup" BucketLeaf: description: A leaf bucket represents a set of measure values for a given facet key. type: object required: [key, name, type, measures] properties: key: { type: string } name: { type: string } type: type: string enum: [LEAF] description: Indicates this bucket is a leaf node containing measures. measures: $ref: "#/components/schemas/Measures" BucketGroup: description: A group bucket represents a set of nested buckets for a given facet key. type: object required: [key, name, type, buckets] properties: key: { type: string } name: { type: string } type: type: string enum: [GROUP] description: Indicates that this bucket is a grouping node containing nested buckets. buckets: $ref: "#/components/schemas/BucketList" BucketList: type: array items: $ref: "#/components/schemas/Bucket" description: List of buckets that can contain either measures or nested buckets TimeSeriesBucketList: type: array items: $ref: "#/components/schemas/TimeSeriesBucket" description: List of time series buckets ordered chronologically. Nested buckets inside are regular BucketList, not TimeSeriesBucketList. TimeSeriesBucket: description: | A time-series bucket represents a single time-series bucket. Buckets can be nested and eventually lead to a leaf bucket with measures. oneOf: - $ref: "#/components/schemas/TimeSeriesBucketLeaf" - $ref: "#/components/schemas/TimeSeriesBucketGroup" discriminator: propertyName: type mapping: LEAF: "#/components/schemas/TimeSeriesBucketLeaf" GROUP: "#/components/schemas/TimeSeriesBucketGroup" TimeSeriesBucketLeaf: description: A leaf bucket represents a set of measure values for a given time series key. type: object required: [key, timestamp, type, measures] properties: type: type: string enum: [LEAF] description: Indicates this bucket is a time series leaf node containing measures. key: type: string format: date-time description: The time series bucket timestamp key (ISO 8601), leading to measures. timestamp: type: integer format: int64 description: Timestamp in milliseconds since Unix epoch (optional) example: 1735689600000 measures: $ref: "#/components/schemas/Measures" TimeSeriesBucketGroup: description: A bucket group represents a bucket that nests facet buckets for a given time series key. type: object required: [key, timestamp, type, buckets] properties: type: type: string enum: [GROUP] description: Indicates this bucket is a time-series group node containing buckets. key: type: string format: date-time description: The time series bucket timestamp key (ISO 8601) timestamp: type: integer format: int64 description: Timestamp in milliseconds since Unix epoch (optional) example: 1735689600000 buckets: $ref: "#/components/schemas/BucketList" MeasuresResponse: type: object required: - metrics description: Response for measures query - contains aggregated metric values properties: metrics: type: array items: type: object required: - name properties: name: $ref: "#/components/schemas/MetricName" unit: $ref: "#/components/schemas/UnitName" measures: $ref: "#/components/schemas/Measures" description: List of measure metric responses example: metrics: - name: "HTTP_REQUESTS" unit: "NUMBER" measures: - name: "COUNT" value: 2984 FacetsResponse: type: object required: - metrics description: Response for facets query - contains grouped data by facet values properties: metrics: type: array description: List of facet metric responses. Each metric can have either measures or buckets for grouping. items: type: object required: - name properties: name: $ref: "#/components/schemas/MetricName" unit: $ref: "#/components/schemas/UnitName" buckets: $ref: "#/components/schemas/BucketList" example: metrics: - name: "HTTP_REQUESTS" unit: "NUMBER" buckets: - key: "49ddd7db-35d6-497e-b497-2dc16af0cdcc" name: "api-1" type: GROUP buckets: - key: "e65289b0-35b2-40e7-8d41-711fba7fdc96" name: "app-1" type: LEAF measures: - name: "COUNT" value: 45 - key: "4c65d87a-008a-4a4c-b11a-a38b7a662fcc" name: "app-2" type: LEAF measures: - name: "COUNT" value: 34 - key: "71091fd9-a6a9-4c7f-afdb-d837ea28058c" name: "app-3" type: LEAF measures: - name: "COUNT" value: 989 TimeSeriesResponse: type: object required: - metrics description: Response for time series query - contains time-ordered data points properties: metrics: type: array items: type: object required: - name properties: name: $ref: "#/components/schemas/MetricName" unit: $ref: "#/components/schemas/UnitName" buckets: $ref: "#/components/schemas/TimeSeriesBucketList" description: List of time series metric responses. Root level buckets are TimeSeriesBucketList, nested buckets inside are regular BucketList. example: metrics: - name: "HTTP_REQUESTS" unit: "NUMBER" buckets: - key: "2025-01-01T00:00:00Z" timestamp: 1735689600000 type: GROUP buckets: - key: "a5954f6e-1d95-463a-9a41-2442c575d022" name: "api-1" type: LEAF measures: - name: "COUNT" value: 1234 - key: "12bff449-1556-491c-8e34-c1c93b27e1cb" name: "api-2" type: LEAF measures: - name: "COUNT" value: 989 - key: "2025-01-01T00:01:00Z" timestamp: 1735689660000 type: GROUP buckets: - key: "a5954f6e-1d95-463a-9a41-2442c575d022" name: "api-1" type: LEAF measures: - name: "COUNT" value: 873 - key: "12bff449-1556-491c-8e34-c1c93b27e1cb" name: "api-2" type: LEAF measures: - name: "COUNT" value: 938 Error: description: | The generic error object returned by any endpoint of the Gravitee APIM API. type: object properties: httpStatus: type: integer format: int32 description: The error code example: 400 message: type: string description: A global response error message example: Bad request technicalCode: type: string description: A technical code to identify the error example: invalid.import.definition parameters: type: object description: | Parameters add information about the context of the error. additionalProperties: type: string example: name: "HTTP_REQUESTS" type: "TIME_SERIES" interval: "-3600000" details: type: array description: A list of details about the error items: type: object properties: message: type: string description: A fine grained error message regarding a failing property. example: Bad request location: type: string description: The json path of the field in error. example: updateApi.properties[0].key invalidValue: oneOf: - type: string - type: number - type: boolean - type: array items: oneOf: - type: string - type: number - type: boolean - type: object - type: object description: The invalid value (can be any type) example: "-1d" example: - message: "Interval must be a positive duration (e.g., '1h', '1d')" location: "requests[0].interval" invalidValue: "-1d" example: httpStatus: 400 message: "Bad request - Invalid Time Series Request" technicalCode: "invalid.analytics.request" parameters: field: "requests[0].interval" value: "-1d" interval.value: "-1d" details: - message: "Invalid interval value" location: "requests[0].interval" invalidValue: "-1d" - message: "Interval must be a positive duration (e.g., '1h', '1d')" location: "requests[0].interval" invalidValue: "-1d"