Search products
Filter product by multiple criteria
Filter structure and format is described under Resources section in this guide
Product search has also support to filter products based on relationship properties. Relationship filter structure and format is described later in this document.
Please take notice of the use of attribute labels instead of attribute names in the request (see more examples below)
Restrictions
-
Search requests
-
Requests are limited to 50 attributes (plus ID and SKU which are always returned). Attributes (both system and user) and properties count in this limit. Requests having more than 50 attributes will be rejected and a 422 code will be returned from API
-
User attributes MUST be prefixed with “attributes.” (including the dot at the end) + the label of the attribute . So for example, if there is an attribute named “In Stock” and labeled as "in_stock" we MUST add it to the request as “attributes.in_stock”. Attribute names and labels can be obtained by
means of the filters/product endpoint -
Relationship columns can also be requested. These MUST be prefixed with “relationships.” (including the dot at the end) + the label of the relationship (response is described in later in this section). Examples:
- relationships.gift_basket
- relationships.recommended_products
-
Search filters MUST include all necessary columns. If an attribute is not explicitly requested it won’t be returned by the API.
Available attributes can be obtained by means of the available https://pim.plytix.com/api/v1/filters/ endpoint. “key” value is what MUST be used in requests.
Requesting non-existing attributes will return a 422 error code
You are allowed to sort by columns not included in “attributes” field however this attribute won’t be returned User attributes MUST be prefixed with “attributes.” (including the dot at the end) + the label of the attribute -
Search filters will return a 422 error code if any of the following conditions are met:
a) The field does not exist
b) Operator is not allowed for the given field (available operators and fields can be obtained using /filters/{item} endpoint)
c) Value has no meaning for the given operator. The arity of available operators can be found in API documentation -
Search filters will return a 428 status code if the filtered results include more than 10000 products and the order field is filled.
-
Pagination: the number of items that can be requested (pagination.page_size) is limited to a maximum of 100 items. A 422 code will be returned from API if this limit is exceeded. If pagination is omitted 25 items of the first page will be returned
-
Only one relationship can be selected in filters
-
Relationship information in responses
When relationship columns are requested, product response will include a new field named ‘relationships’ with the following structure
| Field | Description | Type |
|---|---|---|
| relationships | relationship array | array of relationship information |
Relationship information
| Field | Description | Type |
|---|---|---|
| relationship_id | relationship id | string |
| label | relationship label | string |
| related_products | related products | Array of product relationship data |
Relationship Data
| Field | Description | Type |
|---|---|---|
| product_id | product ID | string |
| quantity | quantity | number |
Requesting the attributes ["categories", "label", "attributes.color", "relationships.gift_basket"] returns products shaped like this:
{ "id": "5d8200527313382d939838c4", "sku": "1234567890", "categories": [], "label": "Strawberry_soap", "attributes": { "color": "red" }, "relationships": [ { "relationship_id": "5ddbf89efbe0f86e3c1574c6", "label": "gift_basket", "related_products": [ { "product_id": "5c98ef754a6c252c96793574", "quantity": 1 } ] } ] }Relationship filters
This section describes the structure and format for relationship filters. A Relationship filter is compound of several fields, some of them are mandatory while others depend on the values and options selected.
Structure
| Field | Description | Mandatory | Type |
|---|---|---|---|
| relationship_id | relationship Identifier | YES | string |
| operator | only ‘exists’ and ‘!exists’ are supported | YES | string |
| product_ids | list of product constraints | NO | Array of object (only for “exists” operator) |
Complex filters can be built defining additional constraints on relationship quantity operator when relationship “exists” operator is selected. Please check the examples section.
Product_ids structure
| Field | Description | Mandatory | Type |
|---|---|---|---|
| id | product id | YES | string |
| qty_operator | quantity operator | YES | string |
| value | filter value | string | array of integer |
Available operators:
| Operator | Arity | Type | Description |
|---|---|---|---|
| exists | Unary | - | Existence check. True when the item has its value defined |
| !exists | Unary | - | Non-existence check. True when the item has its value undefined |
| eq | Binary | value | Equality check. True if the item has the same value as the one provided When applied to a text value, the comparison ignores case |
| in | Binary | list | Match check. Determines if the value matches any of the values specified in the list Note: Multiselect and Dropdown attributes are case sensitive |
| gt | Binary | value | Greater than. True if items' value is greater than provided |
| gte | Binary | value | Greater than or equal to. True if item's value is greater than or equal to provided |
| lt | Binary | value | Less than. True if item's value is less than provided |
| lte | Binary | value | Less than or equal to. True if item's value is less than or equal to provided |
| bte | Binary | value | Between. Requires two values True if item's value is between provided values |
| last_days | Unary | value | Date is greater than the given days check. The filter will only take into account full days (current time is dismissed) |
Examples
1.- Return default page (1) with default items per page (25) using default order (no order)
Note that this query will return just ID and SKU as no attributes have been provided
{ "filters":[ [ {"field":"modified","operator":"gt","value":"2018-11-01"}, {"field":"modified","operator":"lt","value":"2018-11-30"} ], [ {"field":"attributes.name","operator":"like","value":"unicorn"} ] ] }2.- Return default page (1) with default items per page (25) using default order (no order) of product attributes SKU, Label and user attributes "In Stock" and "Volumen (liters)". Please take notice of the the use of attribute labels instead of attribute names in the request
{ "attributes":["sku", "label", "attributes.in_stock", "attributes.volume_liters"] }3.- Return page 3 of products modified [ between November the 1st AND November the 30th] OR [ contains the literal 'unicorn' ] ordered by SKU descending
returning system_attributes: id, sku, created, and user attribute "In Stock", "Product name", "Quantity" (labels: in_stock, name, qty)
{ "filters":[ [ {"field":"modified","operator":"gt","value":"2018-11-01"}, {"field":"modified","operator":"lt","value":"2018-11-30"} ], [ {"field":"attributes.name","operator":"like","value":"unicorn"} ] ], "pagination":{"order":"-sku","page":3,"page_size":25}, "attributes":["created", "attributes.in_stock", "attributes.name", "attributes.qty"]}Relationship filter examples
The following examples assume that:
- There is a Symmetrical relationship named ‘Recommended products’.RP-001 is recommended with RP-002 (quantity 2) and RP-003 (quantity 3).
So RP-002 is recommended with RP-001, and RP-003 is recommended with RP-001, however RP-002 is not related to RP-003. - There is an Asymmetrical relationship named “Gift basket”.
Product GF-Basket ‘includes’ GF-Wine (2 bottles), GF-Chocolates (3 packs), GF-Emmental (1 piece)
-
Find products where the “recommended products” relationship is defined (exists).
{ "attributes":["relationships.recommended_products"], "filters":[], "relationship_filters":[[ { "relationship_id":"5d89c6c696c8f4a322df4bbc", "operator":"exists", "product_ids":[] }]], "pagination": { "order":"", "page":1, "page_size":25 } }The response should include RP-001, RP-002, and RP-003
-
Find products where “recommended products” is not defined (!exists).
{ "attributes":["relationships.recommended_products"], "filters":[], "relationship_filters":[[ { "relationship_id":"5d89c6c696c8f4a322df4bbc", "operator":"!exists", "product_ids":[] }]], "pagination":{ "order":"", "page":1, "page_size":25 } }The response should not include RP-001, RP-002 or RP-003
-
Find the products for which the “recommended products” relationship is defined (a.k.a exists) with the RP-002 product
{ "filters":[], "attributes":["relationships.recommended_products"], "relationship_filters":[[ { "product_ids":[ { "id":"5d89c68596c8f4a322df4bb9", "qty_operator":"exists", "value":null }], "relationship_id":"5d89c6c696c8f4a322df4bbc", "operator":"exists" }]], "pagination": { "order":null, "page":1, "page_size":25 } }Response should include RP-001
{ "data": [ { "attributes": {}, "id": "5d89c67796c8f4a322df4bb8", "sku": "RP-001", "relationships": [ { "relationship_id": "5d89c6c696c8f4a322df4bbc", "label": "recommended_products", "related_products": [ { "product_id": "5d89c68596c8f4a322df4bb9", "quantity": "2" }, { "product_id": "5d89c69496c8f4a322df4bba", "quantity": "3" } ] } ] } ], "pagination": { "count": 1, "order": null, "page": 1, "page_size": 25, "total_count": 3 } } -
Filter the products for which the relationship with the product RP-001 is defined and whose quantity is greater than 2Please, note that the "value" field is an array of one element
{ "filters": [], "attributes": [ "relationships.recommended_products" ], "relationship_filters": [ [ { "product_ids": [ { "id": "5d89c67796c8f4a322df4bb8", "qty_operator": "gt", "value": [ 2 ] } ], "relationship_id": "5d89c6c696c8f4a322df4bbc", "operator": "exists" } ] ], "pagination": { "order": null, "page": 1, "page_size": 25 } }Response should exclude RP-002, due to its quantity being 2, and include RP-003
{ "data": [ { "attributes": {}, "id": "5d89c69496c8f4a322df4bba", "sku": "RP-003", "relationships": [ { "relationship_id": "5d89c6c696c8f4a322df4bbc", "label": "recommended_products", "related_products": [ { "product_id": "5d89c67796c8f4a322df4bb8", "quantity": "3" } ] } ] } ], "pagination": { "count": 1, "order": null, "page": 1, "page_size": 25, "total_count": 3 } } -
Filter the products for which the relationship is defined with the product RP-001 and whose quantity is between 1 and 2Please, notice that the "value" field in this case, value array must include both values, i.e. [1, 2]
{ "filters": [], "attributes": [ "relationships.recommended_products" ], "relationship_filters": [ [ { "product_ids": [ { "id": "5d89c67796c8f4a322df4bb8", "qty_operator": "bte", "value": [ 1, 2 ] } ], "relationship_id": "5d89c6c696c8f4a322df4bbc", "operator": "exists" } ] ], "pagination": { "order": null, "page": 1, "page_size": 25 } }Response should exclude RP-003, which has a quantity of 3, and include RP-002
{ "data": [ { "attributes": {}, "id": "5d89c68596c8f4a322df4bb9", "sku": "RP-002", "relationships": [ { "relationship_id": "5d89c6c696c8f4a322df4bbc", "label": "recommended_products", "related_products": [ { "product_id": "5d89c68596c8f4a322df4bb9", "quantity": "2" } ] } ] } ], "pagination": { "order": null, "page": 1, "page_size": 25 } } -
Find all products where ‘Gift basket’ is defined
{ "filters": [], "attributes": [ "relationships.gift_basket" ], "relationship_filters": [ [ { "product_ids": [], "relationship_id": "5d89d4fd96c8f4a322df4bc0", "operator": "exists" } ] ], "pagination": { "order": null, "page": 1, "page_size": 25 } }The response should include 'GF-Basket' product.
{ "data": [ { "attributes": {}, "id": "5d89d51a96c8f4a322df4bc1", "sku": "GF-Basket", "relationships": [ { "relationship_id": "5d89d4fd96c8f4a322df4bc0", "label": "gift_basket", "related_products": [ { "product_id": "5d89d51a96c8f4a322df4bc2", "quantity": "2" }, { "product_id": "5d89d52f96c8f4a322df4bc3", "quantity": "3" }, { "product_id": "5d89d54396c8f4a322df4bc4", "quantity": "1" } ] } ] } ], "pagination": { "count": 1, "order": null, "page": 1, "page_size": 25, "total_count": 7 } }
Authorization
bearerAuth Obtain a token via POST /auth/api/get-token (15 minute lifetime), then send it as Authorization: Bearer <token>.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
curl -X POST 'https://example.com/api/v1/products/search' \ -H 'Content-Type: application/json' \ --data-raw '{ "filters": [ [ { "field": "status", "operator": "eq", "value": "Draft" }, { "field": "categories", "operator": "in", "value": [ "5c4ed7f62f0985001c233274" ] } ], [ { "field": "categories", "operator": "!exists", "value": null } ] ], "attributes": [ "thumbnail", "assets", "label", "categories", "modified", "created", "status" ], "pagination": { "order": "sku", "page": 1, "page_size": 25 }}'{ "data": [ { "attributes": {}, "id": "5c4ed8002f0985001d233274", "num_variations": 0, "sku": "Sample - 002" }, { "attributes": {}, "id": "5c4ed8002f09850020233274", "num_variations": 0, "sku": "Sample - 003" }, { "attributes": {}, "id": "5c4ed8002f0985001e233275", "num_variations": 0, "sku": "Sample - 001" }, { "attributes": {}, "id": "5c4ed8002f0985001f233274", "num_variations": 0, "sku": "Sample - 004" }, { "attributes": {}, "id": "5c4ed8002f0985001a233274", "num_variations": 5, "sku": "Sample - 005" }, { "attributes": {}, "id": "5c4ed8002f0985001b233274", "num_variations": 2, "sku": "Sample - 009" }, { "_parent_id": "5c4ed8002f0985001a233274", "attributes": {}, "id": "5c4ed80c2f0985001a23327e", "num_variations": 0, "sku": "Sample - 008" }, { "_parent_id": "5c4ed8002f0985001a233274", "attributes": {}, "id": "5c4ed80c2f0985001e233279", "num_variations": 0, "sku": "Sample - 007" }, { "_parent_id": "5c4ed8002f0985001a233274", "attributes": {}, "id": "5c4ed80c2f0985001b23327a", "num_variations": 0, "sku": "Sample - 006" }, { "_parent_id": "5c4ed8002f0985001b233274", "attributes": {}, "id": "5c4ed80c2f0985001d233278", "num_variations": 0, "sku": "Sample - 011" }, { "_parent_id": "5c4ed8002f0985001b233274", "attributes": {}, "id": "5c4ed80c2f09850021233275", "num_variations": 0, "sku": "Sample - 010" }, { "_parent_id": "5c4ed8002f0985001a233274", "attributes": {}, "id": "5c4eeb97050d860001717698", "num_variations": 0, "sku": "new variant from API" }, { "_parent_id": "5c4ed8002f0985001a233274", "attributes": {}, "id": "5c4eec84908d2d00011c8e0b", "num_variations": 0, "sku": "new variant from APId" }, { "attributes": {}, "id": "5c4ef0c59311990001fc3db0", "num_variations": 0, "sku": "Black Kettle" }, { "attributes": {}, "id": "5c4ef1709311990001fc3db1", "num_variations": 0, "sku": "Black Kettle_1" }, { "attributes": {}, "id": "5c4ef29d9311990001fc3db2", "num_variations": 0, "sku": "Black Kettle_11" }, { "attributes": {}, "id": "5c4ef3829311990001fc3db3", "num_variations": 0, "sku": "Black Kettle_111" }, { "attributes": {}, "id": "5c4ef3a9bedb5e000189befc", "num_variations": 0, "sku": "Black Kettle_1111" }, { "attributes": {}, "id": "5c4ef7f7bedb5e000189befd", "num_variations": 0, "sku": "Black Kettle111111" }, { "attributes": {}, "id": "5c4ef836bedb5e000189befe", "num_variations": 0, "sku": "Black Kettle111111111" } ], "pagination": { "count": 20, "order": null, "page": 1, "page_size": 25, "total_count": 20 }}