# Get a collection `GET /platform/v1/catalogs/{catalog_id}/collections/{collection_id}` Get one of the catalog's collections by its id. ## Request example ```bash curl --request GET \ --url 'https://api.eu1.luigisbox.ai/platform/v1/catalogs//collections/collection:curated/new_arrivals/member:product' \ --header 'Authorization: Bearer ' ``` ## Path Parameters | Name | Type | Required | Description | Constraints | |---|---|---|---|---| | `catalog_id` | `string` | Yes | Catalog Id | — | | `collection_id` | `string` | Yes | Collection id, e.g. `collection:category/member:product`. Its `/` may be sent as is or percent-encoded. | — | ## Responses | Status | Description | Content | |---|---|---| | `200` | Successful Response | application/json: oneOf(object, object) | | `400` | Malformed request | application/json: object | | `401` | Missing or invalid credentials | application/json: object | | `403` | Authenticated but not permitted | application/json: object | | `404` | Resource not found | application/json: object | | `422` | Request validation failed | application/json: object | ### 200 Successful Response #### application/json Schema: `oneOf(object, object)` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `ancestry_attribute` | `anyOf(string, null)` | Yes | Attribute of the collection type holding the ancestor `@id`s of each collection object, or `null` for a collection type without hierarchy. | — | | `catalog_id` | `string` | Yes | Catalog the collection belongs to. | — | | `collection_type` | `string` | Yes | Catalog object type whose objects are the collections, e.g. `category`. It must exist in the catalog; `curated` and `all` are reserved. | — | | `created_at` | `string` | Yes | When the collection was registered. | format: date-time | | `id` | `string` | Yes | Collection id, built from the registration. A membership collection is `collection:{collection_type}/member:{member_type}`; a request serves one of its objects as `collection:{@id}/member:{member_type}`. A curated collection is `collection:curated/{slug}/member:{member_type}`, and a request serves it by this id. | — | | `kind` | `string` | Yes | `membership`: every object of `collection_type` is a collection of the member objects that reference it through `membership_attribute`. | allowed value: membership | | `member_type` | `string` | Yes | Catalog object type the collection returns. It must exist in the catalog. | — | | `membership_attribute` | `string` | Yes | Attribute of the member type holding the `@id` of every collection object the member belongs to. | — | | `updated_at` | `string` | Yes | When the collection was last changed; its registration time until then. | format: date-time | | `filters` | `oneOf(object, object)` | Yes | Filter over the member type, in map syntax, in its stored form: negations carry the `exists` added on write. | — | | `filters.$and` | `Array` | No | Nodes that must all match. | >= 1 items | | `filters.$and[].*` | `object` | No | Operators applied to one field. Several operators in one object combine as AND. | — | | `filters.$and[].*.eq` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$and[].*.exists` | `boolean` | No | — | — | | `filters.$and[].*.gt` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$and[].*.gte` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$and[].*.in` | `Array` | No | — | >= 1 items | | `filters.$and[].*.lt` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$and[].*.lte` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$and[].*.neq` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$and[].*.not_in` | `Array` | No | — | >= 1 items | | `filters.$not` | `oneOf(object, object)` | No | Filter over the member type, in map syntax, e.g. `{"label": {"eq": "new"}}`. Fields must exist on the member type; `@`-prefixed fields skip that check but not the value check. The `private:`, `signals:`, `ml:` and `lexical:` namespaces are refused. A negative condition (`neq`, `not_in`) is stored with an `exists` on the same field, so it means "has the field, and it differs"; a `$not` over a single positive condition gets the same. `@id`, `@type` and `@updated_at` are exempt. Once stored, at most 100 conditions (each added `exists` included; groups are not counted), in groups nested at most 10 deep, and 65536 bytes, with at most 100 values in one `in` / `not_in` list and integers that fit in 64 bits. A filter past the depth or condition cap is a `validation_errors` entry of type `filter_too_complex`. | — | | `filters.$not.*` | `object` | No | Operators applied to one field. Several operators in one object combine as AND. | — | | `filters.$not.*.eq` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$not.*.exists` | `boolean` | No | — | — | | `filters.$not.*.gt` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$not.*.gte` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$not.*.in` | `Array` | No | — | >= 1 items | | `filters.$not.*.lt` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$not.*.lte` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$not.*.neq` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$not.*.not_in` | `Array` | No | — | >= 1 items | | `filters.$or` | `Array` | No | Nodes of which at least one must match. | >= 1 items | | `filters.$or[].*` | `object` | No | Operators applied to one field. Several operators in one object combine as AND. | — | | `filters.$or[].*.eq` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$or[].*.exists` | `boolean` | No | — | — | | `filters.$or[].*.gt` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$or[].*.gte` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$or[].*.in` | `Array` | No | — | >= 1 items | | `filters.$or[].*.lt` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$or[].*.lte` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$or[].*.neq` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.$or[].*.not_in` | `Array` | No | — | >= 1 items | | `filters.*` | `object` | No | Operators applied to one field. Several operators in one object combine as AND. | — | | `filters.*.eq` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.*.exists` | `boolean` | No | — | — | | `filters.*.gt` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.*.gte` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.*.in` | `Array` | No | — | >= 1 items | | `filters.*.lt` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.*.lte` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.*.neq` | `string \| number \| integer \| boolean \| null` | No | — | — | | `filters.*.not_in` | `Array` | No | — | >= 1 items | | `name` | `string` | Yes | Human-readable name, for display. It takes no part in the id and cannot be changed. | — | | `slug` | `string` | Yes | Id segment chosen at registration. | — | ##### Response example ```json { "ancestry_attribute": "example", "catalog_id": "example", "collection_type": "example", "created_at": "2026-04-15T12:00:00Z", "id": "collection:category/member:product", "kind": "membership", "member_type": "example", "membership_attribute": "example", "updated_at": "2026-04-15T12:00:00Z" } ``` ### 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" } ``` ### 404 Resource not found #### 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" } ```