Skip to content

    Pre-launch API. The concepts described here are settled, but the API shape is not: request and response fields, parameters and defaults can still change. Build against it, and talk to your Luigi's Box contact before you put an integration into production.

    Single searches, newest first

    View source
    POST
    /analytics/v1/searches/events
    curl --request POST \
    --url 'https://api.eu1.luigisbox.ai/analytics/v1/searches/events?channel_ids=example&page=1&size=20' \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --data '{ "date_range": { "date_from": "2026-04-15T12:00:00Z", "date_to": "2026-04-15T12:00:00Z" }, "filters": { "$and": [ { "applied_filter": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "consent_granted": { "eq": true }, "device": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "external_ab_test_variant": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "filtered": { "eq": true }, "followed_by_search": { "eq": true }, "identity": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "internal_ab_test_id": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "internal_ab_test_variant": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "landing_page": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "landing_page_host": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "no_results": { "eq": true }, "personalized": { "eq": true }, "platform": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "query": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "redirected": { "eq": true }, "result_type": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "returning": { "eq": true }, "session_rank": { "eq": 1, "gt": 1, "gte": 1, "in": [ 1 ], "lt": 1, "lte": 1, "neq": 1, "not_in": [ 1 ] }, "traffic_source": { "eq": "direct", "in": [ "direct" ], "neq": "direct", "not_in": [ "direct" ] }, "traffic_source_type": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "url_host": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "url_path": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] } } ], "$not": { "applied_filter": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "consent_granted": { "eq": true }, "device": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "external_ab_test_variant": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "filtered": { "eq": true }, "followed_by_search": { "eq": true }, "identity": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "internal_ab_test_id": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "internal_ab_test_variant": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "landing_page": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "landing_page_host": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "no_results": { "eq": true }, "personalized": { "eq": true }, "platform": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "query": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "redirected": { "eq": true }, "result_type": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "returning": { "eq": true }, "session_rank": { "eq": 1, "gt": 1, "gte": 1, "in": [ 1 ], "lt": 1, "lte": 1, "neq": 1, "not_in": [ 1 ] }, "traffic_source": { "eq": "direct", "in": [ "direct" ], "neq": "direct", "not_in": [ "direct" ] }, "traffic_source_type": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "url_host": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "url_path": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] } }, "$or": [ { "applied_filter": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "consent_granted": { "eq": true }, "device": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "external_ab_test_variant": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "filtered": { "eq": true }, "followed_by_search": { "eq": true }, "identity": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "internal_ab_test_id": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "internal_ab_test_variant": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "landing_page": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "landing_page_host": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "no_results": { "eq": true }, "personalized": { "eq": true }, "platform": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "query": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "redirected": { "eq": true }, "result_type": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "returning": { "eq": true }, "session_rank": { "eq": 1, "gt": 1, "gte": 1, "in": [ 1 ], "lt": 1, "lte": 1, "neq": 1, "not_in": [ 1 ] }, "traffic_source": { "eq": "direct", "in": [ "direct" ], "neq": "direct", "not_in": [ "direct" ] }, "traffic_source_type": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "url_host": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] }, "url_path": { "eq": "example", "exists": true, "in": [ "example" ], "matches": "example", "neq": "example", "not_in": [ "example" ] } } ] }, "touchpoints": [ "autocomplete" ] }'

    Each list as it was shown, for example the latest searches without results.

    channel_ids
    required
    Channel Ids

    One or more channel ids to aggregate over. Provide as repeated query parameters (?channel_ids=A&channel_ids=B).

    Array<string>
    >= 1 items

    One or more channel ids to aggregate over. Provide as repeated query parameters (?channel_ids=A&channel_ids=B).

    page
    Page

    1-based page number.

    integer
    default: 1 >= 1

    1-based page number.

    size
    Size

    Number of items per page.

    integer
    default: 20 >= 1 <= 100

    Number of items per page.

    Media type application/json
    SearchEventListRequest

    Request for a page of searches, newest first; ties break on channel_id, session_id, then event_id.

    object
    date_range
    required
    DateRange

    The time range of the report.

    object
    date_from
    required
    Date From

    Start, inclusive.

    string format: date-time
    date_to
    required
    Date To

    End, exclusive.

    string format: date-time
    filters
    Any of:
    One of:

    A group node: exactly one of $and, $or, $not.

    object
    >= 1 properties <= 1 properties
    $and

    Nodes that must all match.

    Array
    >= 1 items
    One of:
    object recursive
    $not
    One of:
    object recursive
    $or

    Nodes of which at least one must match.

    Array
    >= 1 items
    One of:
    object recursive
    touchpoints
    required
    Touchpoints

    Where the lists were shown. As with channel_ids, the touchpoints are pooled: one total, one series line and one row per key across all of them, and group_by: ["touchpoint"] splits them. Pooled, the counts of searches, impressions, clicks, transactions and key events add up, and so does money; users, sessions and queries count once however many of the touchpoints they appear at; and a rate is taken over the pooled lists. searches counts the lists shown, so an autocomplete submitted as a search counts once at each touchpoint, and an average position mixes the two touchpoints’ scales. A reformulation is a change of query on the next list at the same touchpoint.

    Array<string>
    >= 1 items unique items
    Allowed values: autocomplete serp

    Successful Response

    Media type application/json
    Page[SearchEvent]
    object
    items
    required
    Items

    The items on this page.

    Array<object>
    SearchEvent

    One search, as it was run and answered.

    object
    applied_filters
    required
    Applied Filters

    The filter values the search applied, one item per value; private filters are left out. A filter whose name starts with _ is the client’s own bookkeeping and never counts.

    Array<object>
    AppliedFilter

    One filter value a search applied.

    object
    name
    required
    Name

    Filter name, e.g. color.

    string
    value
    required
    Value

    Value applied, e.g. red.

    string
    channel_id
    required
    Channel Id

    The channel the search ran in, as a request may cover several.

    string
    device
    required
    Any of:
    string
    event_id
    required
    Event Id

    The search’s id, unique within its session.

    string
    filtered
    required
    Filtered

    The search applied a filter. A filter whose name starts with _ is the client’s own bookkeeping and never counts.

    boolean
    no_results
    required
    No Results

    The search returned nothing and was not redirected.

    boolean
    occurred_at
    required
    Occurred At

    When the search ran, in UTC.

    string format: date-time
    platform
    required
    Any of:
    string
    query
    required
    Query

    The query, lowercased and trimmed.

    string
    redirected
    required
    Redirected

    A redirect rule sent the search elsewhere.

    boolean
    session_id
    required
    Session Id

    The session the search belongs to.

    string
    touchpoint
    required
    SearchReportTouchpoint

    Where the list was shown, as a request may cover several.

    string
    Allowed values: autocomplete serp
    url
    required
    Any of:
    string
    page
    required
    Page

    1-based page number.

    integer
    size
    required
    Size

    Number of items per page.

    integer
    total
    required
    Total

    Total number of items across all pages.

    integer
    Example
    {
    "items": [
    {
    "touchpoint": "autocomplete"
    }
    ]
    }

    Malformed request

    Media type application/json
    ErrorResponse

    Canonical error body — every non-2xx response uses this shape.

    object
    exception_details
    ExceptionDetails

    Machine-readable error context; empty object when there is nothing to add.

    object
    error_code
    Error Code

    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.

    string
    validation_errors
    Validation Errors

    Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value.

    Array<object>
    ValidationProblem

    One field-level reason a request was rejected.

    object
    loc
    required
    Loc

    Path to the offending value from the request root, e.g. ["body", "filters", 0, "operator"].

    Array
    msg
    required
    Msg

    What is wrong with the value at loc.

    string
    type
    required
    Type

    Stable machine code for the problem, e.g. missing or string_too_short.

    string
    key
    additional properties
    any
    reason
    required
    Reason

    Human-readable, actionable error message.

    string
    request_id
    Any of:
    string
    Example generated
    {
    "exception_details": {
    "error_code": "example",
    "validation_errors": [
    {
    "loc": [
    "example"
    ],
    "msg": "example",
    "type": "example"
    }
    ]
    },
    "reason": "example",
    "request_id": "example"
    }

    Missing or invalid credentials

    Media type application/json
    ErrorResponse

    Canonical error body — every non-2xx response uses this shape.

    object
    exception_details
    ExceptionDetails

    Machine-readable error context; empty object when there is nothing to add.

    object
    error_code
    Error Code

    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.

    string
    validation_errors
    Validation Errors

    Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value.

    Array<object>
    ValidationProblem

    One field-level reason a request was rejected.

    object
    loc
    required
    Loc

    Path to the offending value from the request root, e.g. ["body", "filters", 0, "operator"].

    Array
    msg
    required
    Msg

    What is wrong with the value at loc.

    string
    type
    required
    Type

    Stable machine code for the problem, e.g. missing or string_too_short.

    string
    key
    additional properties
    any
    reason
    required
    Reason

    Human-readable, actionable error message.

    string
    request_id
    Any of:
    string
    Example generated
    {
    "exception_details": {
    "error_code": "example",
    "validation_errors": [
    {
    "loc": [
    "example"
    ],
    "msg": "example",
    "type": "example"
    }
    ]
    },
    "reason": "example",
    "request_id": "example"
    }

    Authenticated but not permitted

    Media type application/json
    ErrorResponse

    Canonical error body — every non-2xx response uses this shape.

    object
    exception_details
    ExceptionDetails

    Machine-readable error context; empty object when there is nothing to add.

    object
    error_code
    Error Code

    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.

    string
    validation_errors
    Validation Errors

    Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value.

    Array<object>
    ValidationProblem

    One field-level reason a request was rejected.

    object
    loc
    required
    Loc

    Path to the offending value from the request root, e.g. ["body", "filters", 0, "operator"].

    Array
    msg
    required
    Msg

    What is wrong with the value at loc.

    string
    type
    required
    Type

    Stable machine code for the problem, e.g. missing or string_too_short.

    string
    key
    additional properties
    any
    reason
    required
    Reason

    Human-readable, actionable error message.

    string
    request_id
    Any of:
    string
    Example generated
    {
    "exception_details": {
    "error_code": "example",
    "validation_errors": [
    {
    "loc": [
    "example"
    ],
    "msg": "example",
    "type": "example"
    }
    ]
    },
    "reason": "example",
    "request_id": "example"
    }

    Request validation failed, or the report cannot answer it as asked (exception_details.problems).

    Media type application/json
    ReportError

    The 422 body of a report request.

    object
    exception_details
    required
    ReportExceptionDetails

    Machine-readable error context.

    object
    error_code
    Error Code

    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.

    string
    problems
    Problems

    Why the report cannot answer the request as asked; validation_errors covers malformed fields.

    Array<object>
    ReportProblem

    One reason a report request cannot be answered.

    object
    code
    required
    ReportProblemCode

    Stable code of the problem; switch on it, not on message.

    string
    Allowed values: too_many_groups too_many_high_cardinality_groups too_many_points ab_test_variant_without_test nothing_to_compare report_too_large
    loc
    required
    Loc

    Where in the request, as in validation_errors[].loc, e.g. ["body", "group_by", 1].

    Array
    message
    required
    Message

    What to change.

    string
    validation_errors
    Validation Errors

    Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value.

    Array<object>
    ValidationProblem

    One field-level reason a request was rejected.

    object
    loc
    required
    Loc

    Path to the offending value from the request root, e.g. ["body", "filters", 0, "operator"].

    Array
    msg
    required
    Msg

    What is wrong with the value at loc.

    string
    type
    required
    Type

    Stable machine code for the problem, e.g. missing or string_too_short.

    string
    key
    additional properties
    any
    reason
    required
    Reason

    Human-readable, actionable error message.

    string
    request_id
    Any of:
    string
    Example
    {
    "exception_details": {
    "problems": [
    {
    "code": "too_many_groups"
    }
    ]
    }
    }

    Service temporarily unavailable

    Media type application/json
    ErrorResponse

    Canonical error body — every non-2xx response uses this shape.

    object
    exception_details
    ExceptionDetails

    Machine-readable error context; empty object when there is nothing to add.

    object
    error_code
    Error Code

    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.

    string
    validation_errors
    Validation Errors

    Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value.

    Array<object>
    ValidationProblem

    One field-level reason a request was rejected.

    object
    loc
    required
    Loc

    Path to the offending value from the request root, e.g. ["body", "filters", 0, "operator"].

    Array
    msg
    required
    Msg

    What is wrong with the value at loc.

    string
    type
    required
    Type

    Stable machine code for the problem, e.g. missing or string_too_short.

    string
    key
    additional properties
    any
    reason
    required
    Reason

    Human-readable, actionable error message.

    string
    request_id
    Any of:
    string
    Example generated
    {
    "exception_details": {
    "error_code": "example",
    "validation_errors": [
    {
    "loc": [
    "example"
    ],
    "msg": "example",
    "type": "example"
    }
    ]
    },
    "reason": "example",
    "request_id": "example"
    }