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.

    List surfaces

    View source
    GET
    /platform/v1/catalogs/{catalog_id}/surfaces
    curl --request GET \
    --url 'https://api.eu1.luigisbox.ai/platform/v1/catalogs/example/surfaces?tag_id=lbt_a1b2c3&page=1&size=20' \
    --header 'Authorization: Bearer <token>'
    catalog_id
    required
    Catalog Id
    string
    tag_id
    Any of:
    string

    Restrict to members of this surface-dimension tag. Every tagged surface response carries the lbt_ id it accepts under tags[].id. A tag that does not exist, belongs to another organization, or groups another dimension simply matches nothing.

    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.

    Successful Response

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

    The items on this page.

    Array<object>
    Surface
    object
    catalog_id
    required
    Catalog Id
    string
    created_at
    required
    Created At
    string format: date-time
    default_version
    required
    Any of:
    integer
    id
    required
    Id
    string
    input_type
    required
    Any of:
    string
    intent
    required
    Intent

    The kind of discovery this Surface performs — it fixes which Discovery API endpoint serves the Surface and what input a request must supply (search a query, recommender anchor objects, collection a scope). It is the contract, not the algorithm: a search Surface may retrieve lexically, semantically or both. Immutable — it is the middle slot of the surface id lbs_<intent>_<slug>, so changing it means a new Surface.

    string
    Allowed values: search recommender collection
    output_types
    required
    Output Types

    Catalog object types this surface may answer with. Non-empty; duplicates collapse and input order is preserved. Acts as an allowlist: a request asking for a type absent from this list is rejected rather than answered with fewer results. It is a property of the surface, not of its kind — a recommender declares whatever it recommends, so a category recommender carries category.

    Array<string>
    slug
    required
    Slug
    string
    tags
    required
    Tags

    The surface-dimension tags this surface belongs to, ordered by name, each carrying both its id and its name — the id is what the tag_id filter takes, the name is what a person reads, and neither needs a further request. Read-only here: membership is changed through POST /platform/v1/tags, or PATCH /platform/v1/tags/{tag_id} with add_members / remove_members, which carry {catalog_id, surface_id} pairs. A surface belongs to at most 20 tags.

    Array<object>
    TagRef

    A tag as another entity’s response reports it: the id to act on, and the name to show.

    Both, because each answers a different question and neither substitutes for the other. The id is what every write and filter takes, so acting on the tag needs no lookup; the name is what a person reads, so displaying it needs none either. A bare id would force a second request for something the server already had in hand.

    Not the full :class:Tag: an entity’s tag list is a reference, not a copy — repeating the members and audit columns of a tag on every surface that belongs to it would grow without bound and go stale between the two.

    A tag a caller sends stays a bare id (CampaignCreate.surface_tags and its siblings). A request field cannot take this shape without making the write response impossible to send back unchanged, so the rule is: send an id, receive an id and a name.

    object
    id
    required
    Id

    The tag’s id — what tag_id filters and the tag writes take.

    string
    name
    required
    Name

    Tag name as namespace:value, lowercased on write (intent:SEARCH is stored as intent:search). The intent, language and recommender namespaces are platform-managed: writing one requires platform:reserved-tags:write and deleting one requires platform:reserved-tags:delete.

    string
    <= 256 characters /^[a-z][a-z0-9_-]{0,63}:[^\s:]{1,191}$/
    updated_at
    required
    Updated At
    string format: date-time
    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": [
    {
    "intent": "search"
    }
    ]
    }

    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

    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"
    }