# Statistics per autocomplete redirect rule `POST /analytics/v1/channels/ac-searches/redirects/rules/stats` Per-rule redirect/fixit stats across the requested channels, one row per (rule, channel). ## Request example ```bash curl --request POST \ --url 'https://api.eu1.luigisbox.ai/analytics/v1/channels/ac-searches/redirects/rules/stats?channel_ids=&page=1&size=30' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "consent_granted": true, "context_criteria": [ { "attribute": "example", "operator": "in", "values": [ "example" ] } ], "date_from": "2026-04-15T12:00:00Z", "date_to": "2026-04-15T12:00:00Z", "device": [ "example" ], "external_ab_test_variant": [ "example" ], "internal_ab_test_id": [ "example" ], "internal_ab_test_variant": [ "example" ], "is_personalized": true, "landing_page": [ "example" ], "session_rank": { "exclude": false, "max": 1, "min": 1 }, "url_params": [ { "attribute": "example", "operator": "in", "values": [ "example" ] } ] }' ``` ## Query Parameters | Name | Type | Required | Description | Constraints | |---|---|---|---|---| | `channel_ids` | `Array` | Yes | One or more channel ids to aggregate over. Provide as repeated query parameters (``?channel_ids=A&channel_ids=B``). | — | | `rule_ids` | `anyOf(Array, null)` | No | Optional AB test rules IDs to filter the stats by. | — | | `page` | `integer` | No | 1-based page number. | >= 1 | | `size` | `integer` | No | Number of results per page. | >= 1; <= 200 | ## Request Body **Required.** ### application/json Schema: `object` #### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `consent_granted` | `anyOf(boolean, null)` | No | Consent Granted | — | | `context_criteria` | `Array` | No | Context Criteria | — | | `context_criteria[].attribute` | `string` | Yes | Attribute | >= 1 characters | | `context_criteria[].operator` | `string` | Yes | ComparisonOperator | allowed values: in, not_in, exists, not_exists, lt, lte, gt, gte, eq, neq | | `context_criteria[].values` | `anyOf(Array, null)` | No | Values | — | | `date_from` | `string` | Yes | Date From | format: date-time | | `date_to` | `anyOf(string, null)` | No | Date To | — | | `device` | `Array` | No | Device | — | | `external_ab_test_variant` | `Array` | No | External Ab Test Variant | — | | `internal_ab_test_id` | `Array` | No | Internal Ab Test Id | — | | `internal_ab_test_variant` | `Array` | No | Internal Ab Test Variant | — | | `is_personalized` | `anyOf(boolean, null)` | No | Is Personalized | — | | `landing_page` | `Array` | No | Landing Page | — | | `session_rank` | `anyOf(object, null)` | No | — | — | | `session_rank.exclude` | `boolean` | No | Exclude | — | | `session_rank.max` | `anyOf(integer, null)` | No | Max | — | | `session_rank.min` | `anyOf(integer, null)` | No | Min | — | | `url_params` | `Array` | No | Url Params | — | | `url_params[].attribute` | `string` | Yes | Attribute | >= 1 characters | | `url_params[].operator` | `string` | Yes | ComparisonOperator | allowed values: in, not_in, exists, not_exists, lt, lte, gt, gte, eq, neq | | `url_params[].values` | `anyOf(Array, null)` | No | Values | — | #### Request body example ```json { "consent_granted": true, "context_criteria": [ { "attribute": "example", "operator": "in", "values": [ "example" ] } ], "date_from": "2026-04-15T12:00:00Z", "date_to": "2026-04-15T12:00:00Z", "device": [ "example" ], "external_ab_test_variant": [ "example" ], "internal_ab_test_id": [ "example" ], "internal_ab_test_variant": [ "example" ], "is_personalized": true, "landing_page": [ "example" ], "session_rank": { "exclude": false, "max": 1, "min": 1 }, "url_params": [ { "attribute": "example", "operator": "in", "values": [ "example" ] } ] } ``` ## Responses | Status | Description | Content | |---|---|---| | `200` | Successful Response | application/json: object | | `400` | Malformed request | application/json: object | | `401` | Missing or invalid credentials | application/json: object | | `403` | Authenticated but not permitted | application/json: object | | `422` | Request validation failed | application/json: object | | `503` | Service temporarily unavailable | application/json: object | | `504` | Upstream timed out | application/json: object | ### 200 Successful Response #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `pagination` | `object` | Yes | Metadata about the current page of results. | — | | `pagination.page` | `integer` | Yes | 1-based page number. | — | | `pagination.size` | `integer` | Yes | Number of results per page. | — | | `pagination.total_pages` | `integer` | Yes | Total number of pages | — | | `pagination.total_results` | `integer` | Yes | Total number of results across all pages | — | | `results` | `Array` | Yes | Results | — | | `results[].channel_id` | `string` | Yes | Channel Id | — | | `results[].conversions` | `integer` | Yes | Conversions | — | | `results[].no_results` | `integer` | Yes | No Results | — | | `results[].original_query` | `string` | Yes | Original Query | — | | `results[].redirects` | `integer` | Yes | Redirects | — | | `results[].rule_id` | `integer` | Yes | Rule Id | — | | `results[].target_query` | `string` | Yes | Target Query | — | | `results[].target_url` | `string` | Yes | Target Url | — | | `results[].users` | `integer` | Yes | Users | — | ##### Response example ```json { "pagination": { "page": 1, "size": 1, "total_pages": 1, "total_results": 1 }, "results": [ { "channel_id": "example", "conversions": 1, "no_results": 1, "original_query": "example", "redirects": 1, "rule_id": 1, "target_query": "example", "target_url": "example", "users": 1 } ] } ``` ### 400 Malformed request #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `exception_details` | `object` | No | Machine-readable error context; empty object when there is nothing to add. | — | | `exception_details.error_code` | `string` | No | Stable machine code naming why a well-formed request was refused: snake_case, prefixed by its domain — e.g. `filter_unknown_field` or `cursor_mismatch`. Safe to branch on; `reason` is not. Absent when the status code says all there is to say. | — | | `exception_details.validation_errors` | `Array` | No | Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value. | — | | `exception_details.validation_errors[].loc` | `Array` | Yes | Path to the offending value from the request root, e.g. `["body", "filters", 0, "operator"]`. | — | | `exception_details.validation_errors[].msg` | `string` | Yes | What is wrong with the value at `loc`. | — | | `exception_details.validation_errors[].type` | `string` | Yes | Stable machine code for the problem, e.g. `missing` or `string_too_short`. | — | | `exception_details.*` | `any` | No | Additional property. | — | | `reason` | `string` | Yes | Human-readable, actionable error message. | — | | `request_id` | `anyOf(string, null)` | No | Request correlation ID (matches the X-Request-Id response header). | — | ##### Response example ```json { "exception_details": { "error_code": "example", "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example" } ``` ### 401 Missing or invalid credentials #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `exception_details` | `object` | No | Machine-readable error context; empty object when there is nothing to add. | — | | `exception_details.error_code` | `string` | No | Stable machine code naming why a well-formed request was refused: snake_case, prefixed by its domain — e.g. `filter_unknown_field` or `cursor_mismatch`. Safe to branch on; `reason` is not. Absent when the status code says all there is to say. | — | | `exception_details.validation_errors` | `Array` | No | Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value. | — | | `exception_details.validation_errors[].loc` | `Array` | Yes | Path to the offending value from the request root, e.g. `["body", "filters", 0, "operator"]`. | — | | `exception_details.validation_errors[].msg` | `string` | Yes | What is wrong with the value at `loc`. | — | | `exception_details.validation_errors[].type` | `string` | Yes | Stable machine code for the problem, e.g. `missing` or `string_too_short`. | — | | `exception_details.*` | `any` | No | Additional property. | — | | `reason` | `string` | Yes | Human-readable, actionable error message. | — | | `request_id` | `anyOf(string, null)` | No | Request correlation ID (matches the X-Request-Id response header). | — | ##### Response example ```json { "exception_details": { "error_code": "example", "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example" } ``` ### 403 Authenticated but not permitted #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `exception_details` | `object` | No | Machine-readable error context; empty object when there is nothing to add. | — | | `exception_details.error_code` | `string` | No | Stable machine code naming why a well-formed request was refused: snake_case, prefixed by its domain — e.g. `filter_unknown_field` or `cursor_mismatch`. Safe to branch on; `reason` is not. Absent when the status code says all there is to say. | — | | `exception_details.validation_errors` | `Array` | No | Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value. | — | | `exception_details.validation_errors[].loc` | `Array` | Yes | Path to the offending value from the request root, e.g. `["body", "filters", 0, "operator"]`. | — | | `exception_details.validation_errors[].msg` | `string` | Yes | What is wrong with the value at `loc`. | — | | `exception_details.validation_errors[].type` | `string` | Yes | Stable machine code for the problem, e.g. `missing` or `string_too_short`. | — | | `exception_details.*` | `any` | No | Additional property. | — | | `reason` | `string` | Yes | Human-readable, actionable error message. | — | | `request_id` | `anyOf(string, null)` | No | Request correlation ID (matches the X-Request-Id response header). | — | ##### Response example ```json { "exception_details": { "error_code": "example", "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example" } ``` ### 422 Request validation failed #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `exception_details` | `object` | No | Machine-readable error context; empty object when there is nothing to add. | — | | `exception_details.error_code` | `string` | No | Stable machine code naming why a well-formed request was refused: snake_case, prefixed by its domain — e.g. `filter_unknown_field` or `cursor_mismatch`. Safe to branch on; `reason` is not. Absent when the status code says all there is to say. | — | | `exception_details.validation_errors` | `Array` | No | Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value. | — | | `exception_details.validation_errors[].loc` | `Array` | Yes | Path to the offending value from the request root, e.g. `["body", "filters", 0, "operator"]`. | — | | `exception_details.validation_errors[].msg` | `string` | Yes | What is wrong with the value at `loc`. | — | | `exception_details.validation_errors[].type` | `string` | Yes | Stable machine code for the problem, e.g. `missing` or `string_too_short`. | — | | `exception_details.*` | `any` | No | Additional property. | — | | `reason` | `string` | Yes | Human-readable, actionable error message. | — | | `request_id` | `anyOf(string, null)` | No | Request correlation ID (matches the X-Request-Id response header). | — | ##### Response example ```json { "exception_details": { "error_code": "example", "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example" } ``` ### 503 Service temporarily unavailable #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `exception_details` | `object` | No | Machine-readable error context; empty object when there is nothing to add. | — | | `exception_details.error_code` | `string` | No | Stable machine code naming why a well-formed request was refused: snake_case, prefixed by its domain — e.g. `filter_unknown_field` or `cursor_mismatch`. Safe to branch on; `reason` is not. Absent when the status code says all there is to say. | — | | `exception_details.validation_errors` | `Array` | No | Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value. | — | | `exception_details.validation_errors[].loc` | `Array` | Yes | Path to the offending value from the request root, e.g. `["body", "filters", 0, "operator"]`. | — | | `exception_details.validation_errors[].msg` | `string` | Yes | What is wrong with the value at `loc`. | — | | `exception_details.validation_errors[].type` | `string` | Yes | Stable machine code for the problem, e.g. `missing` or `string_too_short`. | — | | `exception_details.*` | `any` | No | Additional property. | — | | `reason` | `string` | Yes | Human-readable, actionable error message. | — | | `request_id` | `anyOf(string, null)` | No | Request correlation ID (matches the X-Request-Id response header). | — | ##### Response example ```json { "exception_details": { "error_code": "example", "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example" } ``` ### 504 Upstream timed out #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `exception_details` | `object` | No | Machine-readable error context; empty object when there is nothing to add. | — | | `exception_details.error_code` | `string` | No | Stable machine code naming why a well-formed request was refused: snake_case, prefixed by its domain — e.g. `filter_unknown_field` or `cursor_mismatch`. Safe to branch on; `reason` is not. Absent when the status code says all there is to say. | — | | `exception_details.validation_errors` | `Array` | No | Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value. | — | | `exception_details.validation_errors[].loc` | `Array` | Yes | Path to the offending value from the request root, e.g. `["body", "filters", 0, "operator"]`. | — | | `exception_details.validation_errors[].msg` | `string` | Yes | What is wrong with the value at `loc`. | — | | `exception_details.validation_errors[].type` | `string` | Yes | Stable machine code for the problem, e.g. `missing` or `string_too_short`. | — | | `exception_details.*` | `any` | No | Additional property. | — | | `reason` | `string` | Yes | Human-readable, actionable error message. | — | | `request_id` | `anyOf(string, null)` | No | Request correlation ID (matches the X-Request-Id response header). | — | ##### Response example ```json { "exception_details": { "error_code": "example", "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example" } ```