Tesco Taxonomy
Version | Date | Created / Updated | Notes |
---|---|---|---|
v1.0 | Hristiyan Georgiev | Initial version |
The Tesco taxonomy is pretty straight forward and it is not much different from what we are used to do. We basically have 3 levels - Categories, Attributes (called Prototypes) and Brands
The taxonomy has a hierarchy which defines both where products sit, and what attributes those products have, (via Prototypes) and also there is a separate query for Brands. Please note that we must send the ids and not the names.
Further points to note :
- Taxons are hierarchical, in that they can recursively have children.
- To ensure we query all descendants for a given taxon, we need to ensure we query the
children
at each layer, an example querying a 5 level taxonomy is shown below. - From a usability perspective, categorization hierarchies (taxonomies) with a depth greater than 5 are sum-optimal and should be avoided
Some queries in the Taxonomy require some variables so whenever we have a query with variables, we want to use the following variables :
Variable | Value | Note |
---|---|---|
pageSize |
50 | This will be our page size for this query |
endCursor |
Should be null when doing the first query, and then if in the response we have hasNextPage = true, we need to use the string returned in the endCursor field. |
Get Categories
API Docs : https://api.marketplacer.com/docs/seller-api/reference/queries/taxons/
GraphQL Query:
query getCategories($pageSize: Int, $endCursor: String){
taxons(first: $pageSize, after: $endCursor ) {
totalCount
pageInfo {
endCursor
hasNextPage
}
nodes {
id
displayName
treeName
prototype {
name
id
}
children {
nodes {
id
displayName
treeName
prototype {
name
id
}
children {
nodes {
id
displayName
treeName
prototype {
name
id
}
children {
nodes {
id
displayName
treeName
prototype {
name
id
}
children {
nodes {
id
displayName
treeName
prototype {
name
id
}
}
}
}
}
}
}
}
}
}
}
}
Example response :
{
"data": {
"taxons": {
"totalCount": 90,
"pageInfo": {
"endCursor": "MTU",
"hasNextPage": true
},
"nodes": [
{
"id": "VGF4b24tODA=",
"displayName": "cars",
"treeName": "cars",
"prototype": {
"name": "car",
"id": "UHJvdG90eXBlLTI0"
},
"children": {
"nodes": [
{
"id": "VGF4b24tMjM=",
"displayName": "Cat Events",
"treeName": "cars - Cat Events",
"prototype": {
"name": "Generic",
"id": "UHJvdG90eXBlLTE="
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMjQ=",
"displayName": "Cat Services",
"treeName": "cars - Cat Services",
"prototype": {
"name": "Generic",
"id": "UHJvdG90eXBlLTE="
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMTQx",
"displayName": "Grooming",
"treeName": "cars - Grooming",
"prototype": {
"name": "Default",
"id": "UHJvdG90eXBlLTc0"
},
"children": {
"nodes": []
}
}
]
}
},
{
"id": "VGF4b24tMg==",
"displayName": "Cats",
"treeName": "Cats",
"prototype": {
"name": "Blank",
"id": "UHJvdG90eXBlLTU1"
},
"children": {
"nodes": [
{
"id": "VGF4b24tMjA=",
"displayName": "Cat Food",
"treeName": "Cats - Cat Food",
"prototype": {
"name": "Cat food",
"id": "UHJvdG90eXBlLTU2"
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMjQ2",
"displayName": "Cat Nip",
"treeName": "Cats - Cat Nip",
"prototype": {
"name": "Cat food",
"id": "UHJvdG90eXBlLTU2"
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMTE4",
"displayName": "Cat Toys",
"treeName": "Cats - Cat Toys",
"prototype": {
"name": "Cat Toy test",
"id": "UHJvdG90eXBlLTQ0"
},
"children": {
"nodes": []
}
}
]
}
},
{
"id": "VGF4b24tMjQ4",
"displayName": "Cat_food_dry_test",
"treeName": "Cat_food_dry_test",
"prototype": {
"name": "Cat_Food_test",
"id": "UHJvdG90eXBlLTEyMA=="
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMjc3",
"displayName": "Cellular Technology",
"treeName": "Cellular Technology",
"prototype": {
"name": "Cellular - Simplex",
"id": "UHJvdG90eXBlLTEzMw=="
},
"children": {
"nodes": [
{
"id": "VGF4b24tMjc4",
"displayName": "Cellular Internet",
"treeName": "Cellular Technology - Cellular Internet",
"prototype": {
"name": "Cellular - Simplex",
"id": "UHJvdG90eXBlLTEzMw=="
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMjgx",
"displayName": "Cellular Legacy",
"treeName": "Cellular Technology - Cellular Legacy",
"prototype": {
"name": "Cellular Legacy",
"id": "UHJvdG90eXBlLTEzNg=="
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMjgw",
"displayName": "Cellular Phones",
"treeName": "Cellular Technology - Cellular Phones",
"prototype": {
"name": "Cellular - Complex",
"id": "UHJvdG90eXBlLTEzNQ=="
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMjc5",
"displayName": "Cellular Tablets",
"treeName": "Cellular Technology - Cellular Tablets",
"prototype": {
"name": "Cellular - Medium",
"id": "UHJvdG90eXBlLTEzNA=="
},
"children": {
"nodes": []
}
}
]
}
},
{
"id": "VGF4b24tNTQ=",
"displayName": "Clothing",
"treeName": "Clothing",
"prototype": {
"name": "Material",
"id": "UHJvdG90eXBlLTExOA=="
},
"children": {
"nodes": [
{
"id": "VGF4b24tMjQw",
"displayName": "Accessories",
"treeName": "Clothing - Accessories",
"prototype": {
"name": "Colour",
"id": "UHJvdG90eXBlLTMw"
},
"children": {
"nodes": [
{
"id": "VGF4b24tMjQx",
"displayName": "Bags and Backpacks",
"treeName": "Clothing - Accessories - Bags and Backpacks",
"prototype": {
"name": "Bags",
"id": "UHJvdG90eXBlLTE0NQ=="
},
"children": {
"nodes": []
}
}
]
}
},
{
"id": "VGF4b24tMTM4",
"displayName": "Clothing for Kids",
"treeName": "Clothing - Clothing for Kids",
"prototype": {
"name": "Default",
"id": "UHJvdG90eXBlLTc0"
},
"children": {
"nodes": [
{
"id": "VGF4b24tMTQw",
"displayName": "Kids Bottoms",
"treeName": "Clothing - Clothing for Kids - Kids Bottoms",
"prototype": {
"name": "Default",
"id": "UHJvdG90eXBlLTc0"
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMTkx",
"displayName": "Kids Swimwear",
"treeName": "Clothing - Clothing for Kids - Kids Swimwear",
"prototype": {
"name": "Default",
"id": "UHJvdG90eXBlLTc0"
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMTM5",
"displayName": "Kids Tops",
"treeName": "Clothing - Clothing for Kids - Kids Tops",
"prototype": {
"name": "Default",
"id": "UHJvdG90eXBlLTc0"
},
"children": {
"nodes": []
}
}
]
}
},
{
"id": "VGF4b24tMTMy",
"displayName": "Clothing for Men",
"treeName": "Clothing - Clothing for Men",
"prototype": {
"name": "Default",
"id": "UHJvdG90eXBlLTc0"
},
"children": {
"nodes": [
{
"id": "VGF4b24tMTM0",
"displayName": "Men Bottoms",
"treeName": "Clothing - Clothing for Men - Men Bottoms",
"prototype": {
"name": "Womens Apparel",
"id": "UHJvdG90eXBlLTkz"
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMTky",
"displayName": "Men Swimwear",
"treeName": "Clothing - Clothing for Men - Men Swimwear",
"prototype": {
"name": "Default",
"id": "UHJvdG90eXBlLTc0"
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMTMz",
"displayName": "Men Tops",
"treeName": "Clothing - Clothing for Men - Men Tops",
"prototype": {
"name": "Default",
"id": "UHJvdG90eXBlLTc0"
},
"children": {
"nodes": []
}
}
]
}
},
{
"id": "VGF4b24tMTM1",
"displayName": "Clothing for Women",
"treeName": "Clothing - Clothing for Women",
"prototype": {
"name": "Default",
"id": "UHJvdG90eXBlLTc0"
},
"children": {
"nodes": [
{
"id": "VGF4b24tMTcx",
"displayName": "Bodysuits",
"treeName": "Clothing - Clothing for Women - Bodysuits",
"prototype": {
"name": "Womens Apparel",
"id": "UHJvdG90eXBlLTkz"
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMTM3",
"displayName": "Women Bottoms",
"treeName": "Clothing - Clothing for Women - Women Bottoms",
"prototype": {
"name": "Default",
"id": "UHJvdG90eXBlLTc0"
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMTkz",
"displayName": "Women Swimwear",
"treeName": "Clothing - Clothing for Women - Women Swimwear",
"prototype": {
"name": "Default",
"id": "UHJvdG90eXBlLTc0"
},
"children": {
"nodes": []
}
},
{
"id": "VGF4b24tMTM2",
"displayName": "Women Tops",
"treeName": "Clothing - Clothing for Women - Women Tops",
"prototype": {
"name": "Womens Apparel",
"id": "UHJvdG90eXBlLTkz"
},
"children": {
"nodes": []
}
}
]
}
},
{
"id": "VGF4b24tMTAx",
"displayName": "Sweets & Chocolates",
"treeName": "Clothing - Sweets & Chocolates",
"prototype": {
"name": "Test",
"id": "UHJvdG90eXBlLTEw"
},
"children": {
"nodes": []
}
}
]
}
}
]
}
}
}
From this response we need to store the category name (displayName
), the id
and the children categories names and ids.
Get Prototypes
After getting the categories we need to get the prototypes(attributes) for each category which means we need to query every single prototype
> id
from our above response. We have a separate query for this. Please note that we can include more than one prototype id in the query if we want/need to.
GraphQL query
query GetOptionValuesAndTypesForPrototype {
nodes(ids: "UHJvdG90eXBlLTEzNQ==") {
... on Prototype {
id
name
optionTypes {
nodes {
id
name
fieldType
appliedTo
optional
optionValues {
nodes {
id
name
displayName
}
}
}
}
}
}
}
Example response :
{
"data": {
"nodes": [
{
"id": "UHJvdG90eXBlLTEzNQ==",
"name": "Cellular - Complex",
"optionTypes": {
"nodes": [
{
"id": "T3B0aW9uVHlwZS0yNDY=",
"name": "Cellular Material",
"fieldType": "SINGLE_SELECT",
"appliedTo": "ADVERT",
"optional": false,
"optionValues": {
"nodes": [
{
"id": "T3B0aW9uVmFsdWUtNzM0",
"name": "Plastic",
"displayName": "Plastic"
},
{
"id": "T3B0aW9uVmFsdWUtNzM1",
"name": "Aluminium",
"displayName": "Aluminium"
},
{
"id": "T3B0aW9uVmFsdWUtNzM2",
"name": "Carbon Fiber",
"displayName": "Carbon Fiber"
}
]
}
},
{
"id": "T3B0aW9uVHlwZS0yNDc=",
"name": "Cellular Memory",
"fieldType": "SINGLE_SELECT",
"appliedTo": "VARIANT",
"optional": false,
"optionValues": {
"nodes": [
{
"id": "T3B0aW9uVmFsdWUtNzMw",
"name": "64Gb",
"displayName": "64Gb"
},
{
"id": "T3B0aW9uVmFsdWUtNzMx",
"name": "128Gb",
"displayName": "128Gb"
},
{
"id": "T3B0aW9uVmFsdWUtNzMy",
"name": "256Gb",
"displayName": "256Gb"
},
{
"id": "T3B0aW9uVmFsdWUtNzMz",
"name": "512Gb",
"displayName": "512Gb"
}
]
}
},
{
"id": "T3B0aW9uVHlwZS0yNDg=",
"name": "Cellular Network",
"fieldType": "MULTI_SELECT",
"appliedTo": "ADVERT",
"optional": false,
"optionValues": {
"nodes": [
{
"id": "T3B0aW9uVmFsdWUtNzI2",
"name": "2G",
"displayName": "2G"
},
{
"id": "T3B0aW9uVmFsdWUtNzI3",
"name": "3G",
"displayName": "3G"
},
{
"id": "T3B0aW9uVmFsdWUtNzI4",
"name": "4G",
"displayName": "4G"
},
{
"id": "T3B0aW9uVmFsdWUtNzI5",
"name": "5G",
"displayName": "5G"
}
]
}
},
{
"id": "T3B0aW9uVHlwZS0yNDk=",
"name": "Cellular Ports",
"fieldType": "MULTI_SELECT",
"appliedTo": "VARIANT",
"optional": false,
"optionValues": {
"nodes": [
{
"id": "T3B0aW9uVmFsdWUtNzIz",
"name": "USB-C",
"displayName": "USB-C"
},
{
"id": "T3B0aW9uVmFsdWUtNzI0",
"name": "3.5 mm Headphone",
"displayName": "3.5 mm Headphone"
},
{
"id": "T3B0aW9uVmFsdWUtNzI1",
"name": "USB-B",
"displayName": "USB-B"
}
]
}
},
{
"id": "T3B0aW9uVHlwZS0yNTA=",
"name": "Cellular Processor",
"fieldType": "FREE_TEXT",
"appliedTo": "ADVERT",
"optional": true,
"optionValues": {
"nodes": []
}
},
{
"id": "T3B0aW9uVHlwZS0yNTI=",
"name": "Cellular Color",
"fieldType": "FREE_TEXT",
"appliedTo": "VARIANT",
"optional": false,
"optionValues": {
"nodes": []
}
}
]
}
}
]
}
}
From the response we can see a couple of things :
id
- The id that we need to push
name
- this is what we want to map with in Hemi and display in our Taxonomy export
fieldType
- This indicates whether the specific attribute is a single select or multiple select option or free text
appliedTo
- Based on this we can understand whether this is an Item Specific or Variation specific in Hemi. Possible options are VARIANT and ADVERT
optional
- If false this means that it is mandatory. If true it means it is not mandatory
optionValues
- These are the actual attributes values
Get Brands
This is the third and most straightforward query. Its as simple as it gets - we need to keep the possible Tesco brands as part of our taxonomy. Again we need to send the ID but map the name in Hemi.
GraphQL query:
query BrandsQuery($pageSize: Int, $endCursor: String) {
brands(first: $pageSize, after: $endCursor) {
totalCount
pageInfo {
hasNextPage
endCursor
}
edges {
node {
id
name
}
}
}
}
Example response :
{
"data": {
"brands": {
"totalCount": 102,
"pageInfo": {
"hasNextPage": true,
"endCursor": "NTA"
},
"edges": [
{
"node": {
"id": "QnJhbmQtNjg=",
"name": "Adidas"
}
},
{
"node": {
"id": "QnJhbmQtMw==",
"name": "Advance"
}
},
{
"node": {
"id": "QnJhbmQtNA==",
"name": "Advocate 1"
}
},
{
"node": {
"id": "QnJhbmQtNjU=",
"name": "AGV"
}
},
{
"node": {
"id": "QnJhbmQtMjU=",
"name": "Albert Morot"
}
},
{
"node": {
"id": "QnJhbmQtMjg=",
"name": "Albino Rocca"
}
},
{
"node": {
"id": "QnJhbmQtMjA=",
"name": "Alcatraz"
}
},
{
"node": {
"id": "QnJhbmQtMjM=",
"name": "Alcorso"
}
},
{
"node": {
"id": "QnJhbmQtMTY=",
"name": "Aldo Conterno"
}
},
{
"node": {
"id": "QnJhbmQtOTM=",
"name": "All Day"
}
},
{
"node": {
"id": "QnJhbmQtNDU=",
"name": "Animal warehouse"
}
},
{
"node": {
"id": "QnJhbmQtMzQ=",
"name": "Apple"
}
},
{
"node": {
"id": "QnJhbmQtMjY=",
"name": "Awatere River"
}
},
{
"node": {
"id": "QnJhbmQtMTk=",
"name": "Aylesbury"
}
},
{
"node": {
"id": "QnJhbmQtNzE=",
"name": "Azathoth"
}
},
{
"node": {
"id": "QnJhbmQtMzE=",
"name": "Azienda Agricola Pro"
}
},
{
"node": {
"id": "QnJhbmQtMTU=",
"name": "B & G"
}
},
{
"node": {
"id": "QnJhbmQtMjc=",
"name": "Babo"
}
},
{
"node": {
"id": "QnJhbmQtMjQ=",
"name": "Bachelet Monnot"
}
},
{
"node": {
"id": "QnJhbmQtNDM=",
"name": "Bark and Jump"
}
},
{
"node": {
"id": "QnJhbmQtNjE=",
"name": "BBMate"
}
},
{
"node": {
"id": "QnJhbmQtMzg=",
"name": "Biggie Dub Brand"
}
},
{
"node": {
"id": "QnJhbmQtNTI=",
"name": "Black & Decker"
}
},
{
"node": {
"id": "QnJhbmQtODc=",
"name": "Black Hawk"
}
},
{
"node": {
"id": "QnJhbmQtNjM=",
"name": "Boffe"
}
},
{
"node": {
"id": "QnJhbmQtNjI=",
"name": "borp"
}
},
{
"node": {
"id": "QnJhbmQtNjY=",
"name": "Braztech"
}
},
{
"node": {
"id": "QnJhbmQtNTE=",
"name": "Breeders Choice"
}
},
{
"node": {
"id": "QnJhbmQtODE=",
"name": "Brother"
}
},
{
"node": {
"id": "QnJhbmQtMjk=",
"name": "Brown Brothers"
}
},
{
"node": {
"id": "QnJhbmQtNjA=",
"name": "BurgerBurner"
}
},
{
"node": {
"id": "QnJhbmQtNQ==",
"name": "Canidae"
}
},
{
"node": {
"id": "QnJhbmQtNDg=",
"name": "Cats and dogs"
}
},
{
"node": {
"id": "QnJhbmQtNDk=",
"name": "Cavendish"
}
},
{
"node": {
"id": "QnJhbmQtMTM=",
"name": "Chapel Hill"
}
},
{
"node": {
"id": "QnJhbmQtMzk=",
"name": "Cool's Cat Toys"
}
},
{
"node": {
"id": "QnJhbmQtNjk=",
"name": "Corellian Engineering Corporation"
}
},
{
"node": {
"id": "QnJhbmQtOTU=",
"name": "Cottee's"
}
},
{
"node": {
"id": "QnJhbmQtODk=",
"name": "Dine"
}
},
{
"node": {
"id": "QnJhbmQtNTY=",
"name": "Dolce and Kabana "
}
},
{
"node": {
"id": "QnJhbmQtODg=",
"name": "Fancy Feast"
}
},
{
"node": {
"id": "QnJhbmQtNjc=",
"name": "Fish Hats Galore"
}
},
{
"node": {
"id": "QnJhbmQtMTAw",
"name": "Funko"
}
},
{
"node": {
"id": "QnJhbmQtOTc=",
"name": "Fuzzyard"
}
},
{
"node": {
"id": "QnJhbmQtNzA=",
"name": "Galactic Empire"
}
},
{
"node": {
"id": "QnJhbmQtMzA=",
"name": "Gallo"
}
},
{
"node": {
"id": "QnJhbmQtMzU=",
"name": "Giant"
}
},
{
"node": {
"id": "QnJhbmQtOTQ=",
"name": "GiGwi"
}
},
{
"node": {
"id": "QnJhbmQtNDQ=",
"name": "Good boy"
}
},
{
"node": {
"id": "QnJhbmQtNTA=",
"name": "Google"
}
}
]
}
}
}
Note: Once we save the taxonomy, if we would like to update it, we need to delete the old taxonomy and simply to follow the steps above again, in order to get the new one.
Taxonomy export file
In order to generate the taxonomy file we will need to create a new record in Taxonomy export with: Marketplace = Tesco Status = pending Category for Export = Possible values are “all”, (we can also specify which exact categories) OR “brands” Email = email to which the file will be send
We want to have a logic and if the user has selected 5 or more categories for export, we want to export them in a single zip file. This will be valid also if all categories are being exported. More details on taxonomies can be found here - Taxonomy General requirements .
Please find example file structure how it should look like after export. We store each category in a separate file.
Column | Column | Column | Column | Column | Column | Column | Column | |||
---|---|---|---|---|---|---|---|---|---|---|
PrimaryCatName | Category Path | Is Leaf | Specifics | Item Specifics | Required | Type | Values | |||
Clothing | Clothing > Clothing for Kids > Kids Bottoms | Yes | Variation Specific | Colour Global | Yes | Single Select | White | Red | Black | |
Clothing | Clothing > Clothing for Kids > Kids Bottoms | Yes | Variation Specific | Pet Size | Yes | Single Select | XS | Small | Medium | 85g x 28 |
Clothing | Clothing > Clothing for Kids > Kids Bottoms | Yes | Item Specific | Material | Yes | Multiple select | Cotton | Plastic | Metal | |
Shoes | Shoes | No | Variation Specific | Colour Global | Yes | Single Select | White | Yellow | Purple | |
Shoes | Shoes | No | Variation Specific | Shoe Size | Yes | Single Select | 37 | 38 | 45 | |
Shoes | Shoes | No | Item Specifics | Colour | No | Free Text |
Brands file format
Tesco Brand |
---|
Adidas |
Advocate 1 |
Gallo |