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.

    Update a surface

    View source
    PATCH
    /platform/v1/catalogs/{catalog_id}/surfaces/{surface_id}
    curl --request PATCH \
    --url https://api.eu1.luigisbox.ai/platform/v1/catalogs/example/surfaces/example \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --data '{ "input_type": "product", "output_types": [ "product", "category", "brand", "query", "article" ] }'

    Update the object types a surface is queried with and answers with. intent and slug are immutable — the surface id is derived from them. The new values reach the Discovery pipeline on the next cache write, not instantly.

    catalog_id
    required
    Catalog Id
    string
    surface_id
    required
    Surface Id
    string
    Media type application/json
    SurfaceUpdate

    Partial update. Only the fields the body names are applied.

    intent and slug are immutable — the surface id is derived from them, so changing either would rename the resource. input_type is settable only on a recommender and null-only on the other kinds; the router judges it against the stored kind, since a partial update never restates it.

    object
    input_type
    Any of:
    string
    >= 1 characters <= 64 characters
    output_types
    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>
    >= 1 items

    Successful Response

    Media type application/json
    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
    Example
    {
    "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"
    }

    Resource not found

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