TikTok - Product management - OLD
Summary of Changes: (The purpose of this table is to keep traceability and Product team to highlight the things that were changed into the scope, based on comments or discussions)
Date | Version | Applied changes |
---|---|---|
30/05/2022 | 1.1 | Recovery Product - N/A; Get Wareouse List - N/A The field “Product ID“ mapping was edited with the correct one.; |
• “Item Account“ edited to “Product Account“ based on discussion • “Item“ edited to “Product“ based on discussion | | 31/05/2022 | 1.2 | more clarifications added into “Notes“ (based on a comment); Link to Update price corrected with the correct one; Updated info in additional information based on a comments; “product“ changed to variant based on a comments; More information added for the images & creating products | | 02/06/2022 | 1.3 | Changed the response example with the right one; additional validation is added for the file type based on discussion ( the file type should be always pdf) - weight, lenght; | | 02/06/2022 | 1.4 | Case 2: When the product is on status “deactivated“ was removed; More clarification into mapping sections added | | 09/06/2022 | 1.5 | Filed changed; Description img not applicable for now; | | 10/06/2022 | 1.6 | Additional clarifications added for the description image; Get Product Details API call added ; activate product status updated based on comment | | 13/06/2022 | 1.7 | Deactivate product - error handling; Sales & Product Attributes - additional description added; GetProductDetails - additional error message will be displayed - Added into status mapping based on TikTok changes for this API call; COD option flow handled via payment methods | | 14/06/2022 | 1.8 | Added note for img_data field based on TT confirmation; The note into Brand_ID field was removed; Additional validation added based on the tests for Delete product. | | 20/06/2022 | 1.9 | GTIN requirements added into Create Product mapping More details added for Get Product Details section | | 22/06/2022 | 2.0 | Create Product - additional statuses added based on a comment; Added clarification for “Frozen“ status in Get Product details section; Error message described for “Delete“ status in Get Product details section; Some more clarification regarding deactivate product error added based on discussion; | | 30/06/2022 | 2.1 | Images fields changed; Flag for images described | | 04/07/2022 | 2.2 | Added more clarifications for product status once images are uploaded (based on a comment); Payload for Create product has been updated with the last version payload in TikTok docs - new fields in the mapping table (rows 5,6,32,33,34) | | 07/07/2022 | 2.3 | Added more clarification re GTIN field; Priority of GTIN/EAN changed; Note with more clarification in Stock update section added | | 13/07/2022 | 2.4 | Added more clarification re GTIN field - Update product; Delete product; | | 18/07/2022 | 2.5 | Filled “No“ where integration is not required | | 19/07/2022 | 2.6 | Row 47 from Create product mapping was deleted (it was stated there when we receive info GTIN will be required to push but there were no payloads provided) | | 25/07/2022 | 2.7 | Some statuses were changed based on discussion and more details added in following subsections - product create, product update, get product details; | | 26/07/2022 | 2.8 | Added info for Category ID | | 27/07/2022 | 2.9 | Added more clarifications for Brand_ID field into mapping table for create product | | 01/08/2022 | 3.0 | Added Case 4 for Update Listing cron; + Added note for create listing; More info into statuses after success case; | | 02/08/2022 | 3.1 | Added info to SKU IMG ID | | 16/08/2022 | 3.2 | Size chart market as not required; Additional requirement add for product creation; Deactivation of product clarifications added | | 19/08/2022 | 3.3 | Additional note & status changed in Update Product section | | 06/10/2022 | 3.4 | Added requirement for Get product Details | | 11/10/2022 | 3.5 | Added into based on the bug
[TECHMP-4797](https://hemi.atlassian.net/browse/TECHMP-4797)
-
Getting issue details...
STATUS
for Create Product & Images uploaded | | 13/01/2023 | 3.51 | Cleanup on wording to point to correct table and functionality used for image IDs for better reading |
The purpose of this section is to describe in details the requirements for Product management in TikTok.
TikTok Shop is a “listing” oriented platform, and if there is the same product sold by multiple sellers, the product will appear as multiple listings.
TikTok shop allows us to create products, perform updates as full update, update price & update quantity, to deactivate product, to delete product, to recover product and reactivate the product.
Note: Every time we send products for creation we have to do internal check if all required attributes are part of the the product as Item Specifics according to their taxonomy which we download and store on the instance. Please see subsection TikTok - Taxonomy - OLD
Upload Images
When we are creating a product we are sending images too, but we have a separate call for “Upload images“, so we need first to call “Upload images“, to push images and then to download images ids, store them into TikTok Images and then to use theimg_id
to list the product.
API Call: POST/api/products/upload_imgs
API Docs: https://developers.tiktok-shops.com/documents/document/237482
Example Call:
{
"img_data": "aaaaaaaaaaaaaaa",
"img_scene": 1
}
Integration Field | Integration Notes | Integration required | Hemi Mapping | Hemi Notes |
---|---|---|---|---|
img_data |
string |
Input image format file. The picture file is a string generated by base64 encoding. Picture files,picture formats support JPG, JPEG, PNG, picture pixels at least 600600 and at most 2000020000, Max size of original image: 5MB | Yes | Product > Leading image Product > Main Image Product > Additional images
OR
Product Account TikTok > Leading Image Product Account TikTok > Main Image
Product Account TikTok > Additional Images | Тhe images that we want to publish and then to use them when creating a product.
We pick images from Product Account TikTok with priority!
Note: As per confirmation , the picture pixels are “…600x600 and at most 20000x20000“ |
| img_scene
| int32
Scenes using pictures:
1:"PRODUCT_IMAGE" The ratio of horizontal and vertical is recommended to be 1:1
2:"DESCRIPTION_IMAGE"
3:"ATTRIBUTE_IMAGE " The ratio of horizontal and vertical is recommended to be 1:1
4:"CERTIFICATION_IMAGE"
5:"SIZE_CHART_IMAGE" | Yes | 1. PRODUCT_IMAGE will be Product Leading images AND Product Additional Images
- DESCRIPTION_IMAGE - N/A
- ATTRIBUTE_IMAGE will be Product > Main image OR Product Account TikTok > Main Image
- CERTIFICATION_IMAGE will be Product Account TikTok > Certification Image - New field
- SIZE_CHART_IMAGE will be Product Account TikTok > Size chart image - New field | Please refer for following docs for Leading & Additional images: https://wearepentagon.atlassian.net/wiki/spaces/HEMI/pages/1494482956/Product+Listing+general+requirements#Images-management
If we take a picture from Leading image field and Additional image field, it will be “PRODUCT_IMAGE“; If the picture is taken from “Main Image“, we will send as “ATTRIBUTE_IMAGE“ If the picture is taken from “Certification Image“, we will send as “CERTIFICATION_IMAGE“ ; If the picture is taken from “Size chart Image“ field, we will send as “SIZE_CHART_IMAGE” ; Note: As per discussion with TT, we will not use Description image (it is not mandatory to be pushed when creating a product, so we simply will handle it on N/A) |
- Important: We load all the images and we set the scene based on from which field we have taken the image.
We need to have images uploaded before we proceed creating a product; We should not pick a products for creation, if the images are not uploaded!
Еxample file for img_data (Provided from Vladi):
Example Response:
{
"code": 0,
"message": "Success",
"request_id": "1111111111",
"data": {
"img_id": "aaaaabbbbb",
"img_url": "http://bbbbbbbb",
"img_height": 1000,
"img_width": 1000,
"img_scene": 1
}
}
Response Mapping:
Integration Field | Integration Notes | Integration required | Hemi Mapping | Hemi Notes | |
---|---|---|---|---|---|
request_id |
|||||
data |
|||||
img_id |
string | TikTok Images > TikTok Image ID | New field |
Table field with two columns. The first column would be for the Image ID and the second one - for the Image Scene.
For the name we would like to store the scene and the value will be the image id |
| | img_url
| string | | N/A | |
| | img_height
| int32 | | N/A | |
| | img_width
| int32 | | N/A | |
| | img_scene
| int 32
1:"PRODUCT_IMAGE"
2:"DESCRIPTION_IMAGE"
3:"ATTRIBUTE_IMAGE "
4:"CERTIFICATION_IMAGE"
5:"SIZE_CHART_IMAGE" | | TikTok Images > TikTok Image Scene | Enum field ; For the name we would like to store the scene and the value will be the image id |
When we send the images we will have List/Update the Whole Item = Pending.
Once we start sending the image, we will set List/Update the Whole Item = Sent. (Only for those which were on “Pending“!)
Once the images were send successfully, we will put List/Update the Whole Item back on Pending. (in order to be picked by the cron for create/update products)
Please note that we should set “Images Uploaded” status only for variants which were updated to “Sent”!
Note: We will have Product Status = Images Uploaded only if the product status was = Awaiting Creation or Removed. If it is published, we don’t touch the status
We will have a couple of validations:
1 The first will be to check if we have successfully pushed the images in order to download img_id & URLs;
2 If we have id store or a specific scene , we need to override with the new one;
3 we will not pick product for creation, if images are not uploaded;
Create Product
We need to have images uploaded before we proceed creating a product; We should not pick a products for creation, if the images are not uploaded!
We need to identify for which category we need to push the product certification information. Then, if for a specific category this information is needed, we need to upload the certification image into the node product certification (we do not need to upload file because at this stage we will not use “UploadFile“ call), and to use the returned file_id
for product creation. Also, we need to push the product certificate id, which is returned by “GetGatecoryRule“ call. We should not pick a product for creation, if the file is not uploaded (Only for products which required “Product Certification info”. More information regarding product certifications is available here TikTok - Taxonomy - OLD)
After sending the product for creation to marketplace, the product will be with status Suspended & Awaiting review. Once the review is successful - the product status will be set to “Live“ (Active). If the review is not successful, the product status will be Suspended & Failed.
**Important:*** If the cron pick a variant which need to be added to already published variation group, the listing create cron will pick the Channel Item ID and will assign it to the variant which we would want to publish. Also, the listing create cron should fill in the channel item ID only for variants on which have List/Update the Whole item = “Pending“ and Product Status = ”Images Uploaded”
We should be able to list product even if the table item account TikTok is empty, i.e. we do not have records. After successful product creation on TikTok, we should store the SKU ID, which is returned by TikTok into the table Item Account TikTok.
API Call: POST /api/products
API Docs: https://developers.tiktok-shops.com/documents/document/237483
Example Call:
{
"brand_id": "",
"category_id": "",
"delivery_service_ids": "",
"description": "",
"exemption_of_identifier_code": {
"exemption_reason": ""
},
"images": [
{
"id": ""
}
],
"is_cod_open": "",
"package_height": "",
"package_length": "",
"package_weight": "",
"package_width": "",
"product_attributes": [
{
"attribute_id": "",
"attribute_values": [
{
"value_id": "",
"value_name": ""
}
]
}
],
"product_certifications": [
{
"files": [
{
"id": "",
"name": "",
"type": ""
}
],
"id": "",
"images": [
{
"id": ""
}
]
}
],
"product_name": "",
"size_chart": {
"img_id": ""
},
"skus": [
{
"original_price": "",
"product_identifier_code": {
"identifier_code": "",
"identifier_code_type": ""
},
"sales_attributes": [
{
"attribute_id": "",
"attribute_name": "",
"custom_value": "",
"sku_img": {
"id": ""
},
"value_id": ""
}
],
"seller_sku": "",
"stock_infos": [
{
"available_stock": "",
"warehouse_id": ""
}
]
}
],
"warranty_period": "",
"warranty_policy": ""
}
Mapping:
Integration Field | Integration Notes | Integration required | Hemi Mapping | Hemi Notes | ||||
---|---|---|---|---|---|---|---|---|
1 | brand_id |
string | ||||||
You can only choose from brands that already have qualifications, and you need to ensure that the qualifications are within the validity period | No | Product > Brand | As per discussion we have agreed if we do not have filled brand, we will skip the node into the payload while sending the product; |
If we have a value into the brand field, we will send the brand ID.
*we fill in the brand name/label and then the integration should map it using the taxonomy and send the Brand ID.; |
| 2 | category_id
| | | | Must be a leaf category | Yes | Product Account> Primary Category ID | We need to use the values from column Category Path ( The column “Category Path“ from the Taxonomy Export file) |
| 3 | delivery_service_ids
| | | | This is an optional field ,if you keep empty in the delivery service field , then the system will set this field as "default" delivery option. | No | N/A | delivery_service_ids
=Shipped by seller ( hardcoded)
Note for info only: The other option is Shipped via platform which option is not part of the current scope and will not be build! |
| 4 | description
| | | | string | Yes | Product Account > Description | We would want to use the logic of design template.
If we have design template we will pick the design template;
If we haven’t design template, we will pick the default one.
If we haven’t the default one, we will pick the description; |
| 5 | exemption_of_identifier_code
| | | | This is the exemption reason for the product identifier code (GTIN) | No | N/A | Not required at this stage. We will proceed with the approach where we should always push GTIN. |
| 6 | | exemption_reason
| | | This is the exemption reason of the product:input one of them into this field, Type value:1-Brand or manufacturer does not provide a GTIN,2-Generic or non-branded product without GTIN,3-Product bundle,4-Product part without a GTIN | No | N/A | Not required at this stage. We will proceed with the approach where we should always push GTIN. |
| 7 | images
| | | | You can only use the request parameters of the UploadImg API as the request parameters up to 9 pictures, The first picture in the upload sequence will automatically be set as the header picture | Yes | | |
| 8 | | id
| | | string | Yes | Leading image(s) + Additional images
(as defined into the abstraction) | The images for the whole variation!
Leading image + Additional image : https://wearepentagon.atlassian.net/wiki/spaces/HEMI/pages/1494482956/Product+Listing+general+requirements#Images-management
We would want to send all images from these fields.
We need to list all unique images for this variation! |
| 9 | is_cod_open
| | | | Bool
The category rule determines whether this parameter is required. If the category rule is "true", you can choose to turn on or off the cod . If the category rule is "false", you are not allowed to turn on the cod.
COD:Cash on Delivery | Yes | Product Account >Payment Method 1
OR
Product Account >Payment Method 2
OR
Account Payment | Depends on Category Rule ( true or false values)
Will be incorporated with the Payment method. Into the account we will have COD method , which can be assigned to products.
The correct payment method value which need to be set in Hemi is 'Cash on Delivery'
The Validation is follow:
If we have assigned COD to a product, for which category does not allow COD, the error should be displayed.
If we have payment method COD set as default method we also set an error for the products which categories does not support it. |
| 10 | package_height
| | | | int32
The unit is cm; max:35cm | No | Product >Height | By default, in Hemi the measure unit is “cm“ |
| 11 | package_length
| | | | int32
The unit is cm; max:60cm | No | Product >Length | By default, in Hemi the measure unit is “cm“ |
| 12 | package_weight
| | | | string
The unit is kilogram. (maximum is 20; Up to two digits after the decimal point | Yes | Product >Weight | Here we need to divided the mass value by 1000 in order to convert the grams into kg (In Hemi the measure unit for this field is “gram“) |
| 13 | package_width
| | | | int32
The unit is cm; max:40cm | No | Product >Width | By default, in Hemi the measure unit is “cm“ |
| 14 | product_attributes
| | | | | | | |
| 15 | | attribute_id
| | | Only support the input of the product attribute ID that is provided by the platform(from GetAttribute API) | No | Product Account > Item Specific Name | part of Taxonomy. Based on the validation and mapping we need to push the actual IDs; |
| 16 | | attribute_values
| | | []object | No | | |
| 17 | | | value_id
| | string | No | Product Account > Item Specific Value | |
| 18 | | | value_name
| | string
This field is for you fill in the custom attribute value . Here are some conditions of the field:1. This field cannot fill in mandirne.2. The maximum character is 35.3. This field support submits multiple values , but these custom values cannot be duplicated. | No | Product Account > Item Specific Value | part of Taxonomy
If we do not found the the value_name within the Taxonomy, we are able to push custom value here. |
| 19 | product_certifications
| | | | | | | |
| 20 | | files
| | | | No | | |
| 21 | | | id
| | You can only use the request parameters of the UploadFile API as the request parameters | No | N/A | |
| 22 | | | name
| | | No | N/A | |
| 23 | | | type
| | | No | N/A | |
| 24 | | id
| | | This is the certification id , you can get this id by "GetCategoryRule"API. | Yes | Product Account TikTok > Certifications > Name | 2 columns - first column to be name, and the second one to be the URL;
We will map the name from the taxonomy and use the ID;
This ID is returned for some categories and we should store this ID as a part of the taxonomy. It is mandatory to push when the “CategoryRule“ return this information. |
| 25 | | images
| | | | | | |
| 26 | | | id
| | You can only use the response parameters of the UploadImg API as this request parameter | Yes | Product Account TikTok > Certifications > Image URL | we would want to send all image ids from field Certification Image.
We need to search the URL into the TikTok images table and send the ID;
We need to group them by name;
images here need to be send only if GetCategoryRule return “product certification“ information. At all, the information in product_certifications
nodes need to be send ONLY if product certification is needed.
More detailed explanations for GetCategoryRule call, you can find in “TikTok Taxonomy - GetCategoryRule“ section. |
| 27 | product_name
| | | | | Yes | Product Account > Title | |
| 28 | size_chart
| | | | The category_rule determines whether this parameter is required. If the category rule is "true", it must be filled in, and if the category rule is "false", it is not allowed | No | | |
| 29 | | img_id
| | | Only support the input of the sales attribute ID provided by the platform | Yes | Product Account TikTok > Size chart image | this field need to be filled only if size_chart=true; If is not filled, error should be displayed; |
| 30 | skus
| | | | | | | All variants of the product |
| 31 | | original_price
| | | string
Indonesian rupiah, the minimum and maximum prices are 100 and 100 million, respectively
GBP, local to local business, the minimum and maximum are 0.01 and 5600, respectively
GBP, cross-border business, the minimum and maximum values are 0.01 and 134.5, respectively
Up to two digits after the decimal point
| Yes | Product Account > Price | |
| 32 | | product_identifier_code
| | | This is the GTIN code | | | |
| 33 | | | identifier_code
| | string
Identifier code logic:1. Must be a numeric type2. The number of characters needs to meet the requirements (GTIN: 14 digits, EAN: 8/13/14 digits, UPC: 12 digits, ISBN: 13 digits)3. Different SKUs are not allowed to use the same gtin code. | Yes | Product>EAN
OR
Product>UPC
OR
Product>ISBN
OR
Product>Barcode | If we have filled value in Product>Barcode, we will push GTIN _value = the value in the field Barcode;
If we have filled value in Product>EAN, we will push the GTIN _value = the value in the field EAN;
If we have filled value in Product>UPC, we will push the GTIN _value = the value in the field UPC;
If we have filled value in Product>ISBN, we will push the GTIN _value = the value in the field ISBN;
Once the GTIN has been assigned to an existing product, it can't be changed or deleted! For this reason we need to save the value we have pushed in GTIN field and use the value when performing update (Edit Product API). The specific here is we would want to display the value of this field, but into the UI, field to be read only. And also, we need to make sure if we delete a product, the information for GTIN also to be deleted.
Priority: EAN, UPC, ISBN, Barcode
Note: The field is mandatory to be pushed when we perform full update(edit) product. If not pushed, the product will be publish and active but after defined period it will be suspended (as per TT docs - https://developers.tiktok-shops.com/documents/document/240047)
If we try to push a product for creation, without GTIN filled, error message should appear ( Error message: GTIN is required) |
| 34 | | | identifier_code_type
| | int
Code type value: 1-GTIN、2-EAN、3-UPC、4-ISBN (input one of them to this field) | Yes | | If we have filled value in Product>Barcode, we will push the GTIN_type=1 - (GTIN)
If we have filled value in Product>EAN, we will push the GTIN_type= 2 (EAN)
If we have filled value in Product>UPC, we will push the GTIN_type= 3 (UPC)
If we have filled value in Product>ISBN, we will push the GTIN_type= 4 (ISBN) |
| 35 | | sales_attributes
| | | | | | |
| 36 | | | attribute_id
| | Only support the input of the sales attribute ID provided by the platform Enter up to three sales attributes | Yes | Product Account > Item Specific | Id of the attribute // This will be item specific name |
| 37 | | | custom_value
| | When creating a new sales attribute value, the merchant is required to enter a custom sales attribute value, and there can be no duplicate sales attribute values under the same sales attribute
It is recommended to avoid using Chinese because the copy will be displayed to local users
The character length must not exceed 20
There are up to 100 attribute values under each sale attribute | No | Product Account > Item Specific
Product Account > Variation Specific | This will be item & variation specific value.
If we not map according their values, we will push custom_value;
If is_custom = true, we can push a custom value which is different from the suggested values (from Get Attributes call) |
| 38 | | | sku_img
| | | | | |
| 39 | | | | id
| You can only use the request parameters of the UploadImg API as the request parametersAt most, you can set a picture for one sales attribute. When only part of the sales attribute value is set with a picture, the system will use the product header image to fill in the sales attribute value without a picture | Yes | Product Account TikTok> Main Image
OR
Product > Main Image | This field will be skipped at the moment. Please, see
[TECHMP-4482](https://hemi.atlassian.net/browse/TECHMP-4482)
-
Getting issue details...
STATUS
The image of the variant
We need to get the correct image and go search for it in TikTok Image table and then send the ID.
Example:
SKU 123 - Main image;
SKU 345 - Main image; |
| 40 | | | value_id
| | When creating a new sales attribute value, you do not need to enter value_id. After the custom_value request is submitted, the merchant will get the value_id assigned by the platform (which can be viewed in the response body) | No | N/A | Once we pushed custom_value, the TT “assign“ to us a value id, which is not neccessary to be stored.
If we not map according their values, we will push custom_value;
If is_custom = true, we can push a custom value which is different from the suggested values (from Get Attributes call) |
| 41 | | seller_sku
| | | string
The character length must not exceed 50
It is recommended to avoid using Chinese because the copy will be displayed to local users | No | Product > SKU | |
| 42 | | stock_infos
| | | | | | |
| 43 | | | available_stock
| |
The value should be non-negative numbers(include number 0)
The upper limit of the available stock value set at a time is 99999 | Yes | Product Account > Quantity | |
| 44 | | | warehouse_id
| | string
This field is a required field (because some sellers will have multiple warehouses, sellers can get warehouse ID from API GetproductDetail. You must fill in the warehouse when you modify SKU). | Yes | Location TikTok > Warehouse ID | New field
We will have only 1 warehouse. TikTok does not allow more than 1 WH.
Account Locations => Location => Location TikTok
We should pick the first account location for example and from there reach the location and get the ID from Location TikTok table.
Location TikTok will be a slave table of “Locations“
Note: If a client has 3 warehouses, but he would want to send sum of the stock, in Hemi we will have 3 locations per account, for which locations will have 3 different stock files, which will be updated in Location Quantities. Those 3 locations will be added into the Account Locations (will be summed by stock recalculation). Into Location TikTok we need to add the Warehouse ID which ID will be one ID for those 3 locations (TikTok does not allow us more than one WH ID) |
| 45 | warranty_period
| | | | | No | N/A | |
| 46 | warranty_policy
| | | | | No | N/A | |
Note: We will have the same product ids, across all variants (same logic as eBay)
Example Response:
{
"code": 0,
"message": "Success",
"request_id": "11111111",
"data": {
"product_id": "111111112222",
"skus": [
{
"id": "1111111111333333",
"seller_sku": "aaaaaa",
"sales_attributes": [
{
"attribute_id": "111",
"value_id": "1231241234"
},
{
"attribute_id": "222",
"value_id": "123124123124"
}
]
},
{
"id": "2222332323",
"seller_sku": "bbbbb",
"sales_attributes": [
{
"attribute_id": "33333",
"value_id": "123124123123"
},
{
"attribute_id": "44444",
"value_id": "1312312312412"
}
]
}
]
}
}
Response Mapping:
Integration Field | Integration Notes | Integration required | Hemi Mapping | Hemi Notes | |||
---|---|---|---|---|---|---|---|
request_id |
|||||||
data |
|||||||
product_id |
Yes | Product Account > Channel item ID | |||||
skus |
|||||||
id |
Product Account TikTok > SKU ID | New field | |||||
Note: The value of this field & the value in field “Channel item ID“ are required when we perform updates as Update Price, Stock, etc. | |||||||
seller_sku |
N/A | ||||||
sales_attributes |
|||||||
attribute_id |
N/A | ||||||
value_id |
N/A |
If we not submit product certification information to a product which is in this category that requires this information, we will receive success response, but the product status will be “3-failed(initial creation)“:
Example for such response:
{
"code": 0,
"message": "Success",
"request_id": "20220526090601010190209075055FE708",
"data": {
"product_id": "1729431764033767883",
"skus": [
{
"id": "1729431764033833419",
"sales_attributes": [
{
"attribute_id": "100153",
"value_id": "7101968292507600646"
}
],
"seller_sku": "9999999999"
}
]
}
}
When we send the product for creation, we will have:
Listing status= Inactive; Product Status = Images Uploaded ; List/Update the Whole Item = Pending
Once we successfully create a product, we should set statuses on:
Listing status= Inactive; Product Status = Product Created ; List/Update the Whole Item = Sent
If we receive an error, we will have List/Update the whole item = error and the error will be stored into Revise item error field and the statuses will be:
Listing status= Inactive; Product Status = Images Uploaded
*Important: Listing create cron should put variants which need to be added on Listing status= Inactive; Product Status = Product Published**
*Important:** We will not set the status to Product Published in Hemi, because we need to incorporate Get Product Details API call, which will compare the TikTok product statuses with Hemi statuses. The “GetProductDetails“ call is added in separate section below Create Products.
Possible error codes & messages:
Code | HTTP Code | Message |
---|---|---|
102000 | 500 | internal service error |
203154 | 200 | category is not exist |
203150 | 200 | Category is invalid |
203155 | 200 | Product name is empty |
203156 | 200 | Seller is inactivated |
203157 | 200 | Seller warehouse is empty |
203158 | 200 | Product description is invalid |
203160 | 200 | Product id is invalid |
203161 | 200 | image list is invalid |
203162 | 200 | Product price is invalid |
203163 | 200 | Product package weight is invalid |
203164 | 200 | Product package size is invalid |
203165 | 200 | Brand is is invalid |
203166 | 200 | Product name is invalid |
203167 | 200 | The number of SKU exceed the limit |
203168 | 200 | Seller warehouse is invalid |
203169 | 200 | The stock of sku exceed the limit |
203170 | 200 | The product brand is expired.Please modify and re_submit. |
203171 | 200 | Sale attribute is invalid |
203174 | 200 | Warranty policy exceed limit. |
203175 | 200 | Size chart image is nil. |
203176 | 200 | Sku name exceed limit. |
203177 | 200 | Multiple warehouse in one product. |
203178 | 200 | Required qualification is miss. |
203179 | 200 | The attribute is invalid. |
203186 | 200 | Qualification id is invalid. |
203201 | 200 | Size chart is invalid |
203202 | 200 | Category does not support COD |
203203 | 200 | Qualification image and file exceed limit error |
203206 | 200 | skus is invalid |
203207 | 200 | price is locked |
203208 | 200 | package is invalid |
203197 | 200 | Stock count is invalid. |
203187 | 200 | warranty policy contains non-local language |
203188 | 200 | description contains non-local language |
203189 | 200 | seller sku contains non-local language |
203223 | 200 | desc image invalid |
203224 | 200 | desc P tag invalid |
203225 | 200 | desc list tag invalid |
203226 | 200 | product main image is invalid |
203227 | 200 | product qualification image is invalid |
203228 | 200 | sale property image is invalid |
203229 | 200 | size chart image is invalid |
Get Product Details
This call need to be incorporated, because we do not receive product status into the response for “Create Product“ call. In order to make sure we have successfully list a product on TikTok, we should use their statuses and map them to our internal statuses.
From the example call below, we need to use only product_status
;
The cron should pick products with following statuses:
Product Status = Product Created/Product Published; List update the whole item = Sent
We should incorporate a cron which will compare the statuses of the products in TikTok and based on their statuses, to set our internal statuses as follow:
TikTok Product Status | Hemi Product / Listing Statuses | Notes |
---|---|---|
1-DRAFT | N/A | |
2- PENDING | N/A | |
3- FAILED (INITIAL CREATION) | Listing status= Inactive Product Status = Product Created + List/Update the Whole item = Error | TikTok updates 13/06/2022: GetProductDetail API will return the reason as a new response data - qc_reasons. When the value of response data - product_status is 3-failed(initial creation), there will be the reason in this new response data. |
4- LIVE | Listing status= Active Product Status = Product Published + List update the whole item = Not Needed | |
5- SELLER DEACTIVATED | Listing status= Inactive Product Status = Product Published + List update the whole item = Not Needed + List update the whole item = Not Needed | |
6 - PLATFORM_DEACTIVATED | Listing status= Inactive Product Status = Product Published + List/Update the Whole item = Error | We will set this status if we receive product_status 6 - PLATFORM_DEACTIVATED; |
7- FREEZE | Listing status= Inactive Product Status = Product Created + List/Update the Whole item = Error TBD | We will handle such case as described in “Hemi Product/ Listing Statuses“ because TikTok does not provide detailed information regarding the Freeze status. |
8- DELETED | Listing status= Inactive Product Status = Product Removed + List/Update the Whole item = Error | The error message which will be displayed “The product was deleted from the marketplace“ |
*Important Note:** Get Product Details cron should pick only variants with Channel Item IDs and SKU IDs!!!
API Call: GET /api/products/details
API Docs: https://developers.tiktok-shops.com/documents/document/237488
Еxample response:
{
"code": 0,
"data": {
"brand": {
"id": "",
"name": "",
"status": ""
},
"category_list": [
{
"id": "",
"is_leaf": "",
"local_display_name": "",
"parent_id": ""
}
],
"create_time": "",
"delivery_services": [
{
"delivery_option_name": "",
"delivery_service_id": "",
"delivery_service_status": ""
}
],
"description": "",
"images": [
{
"height": "",
"id": "",
"thumb_url_list": "",
"url_list": "",
"width": ""
}
],
"is_cod_open": "",
"package_height": "",
"package_length": "",
"package_weight": "",
"package_width": "",
"product_attributes": [
{
"id": "",
"name": "",
"values": [
{
"id": "",
"name": ""
}
]
}
],
"product_certifications": [
{
"files": [
{
"id": "",
"list": "",
"name": "",
"type": ""
}
],
"id": "",
"images": [
{
"height": "",
"id": "",
"thumb_url_list": "",
"url_list": "",
"width": ""
}
],
"title": ""
}
],
"product_id": "",
"product_name": "",
"product_status": "",
"qc_reasons": [
{
"reason": "",
"sub_reasons": ""
}
],
"size_chart": {
"height": "",
"id": "",
"thumb_url_list": "",
"url_list": "",
"width": ""
},
"skus": [
{
"id": "",
"price": {
"currency": "",
"original_price": "",
"price_include_vat": ""
},
"sales_attributes": [
{
"id": "",
"name": "",
"sku_img": {
"height": "",
"id": "",
"thumb_url_list": "",
"url_list": "",
"width": ""
},
"value_id": "",
"value_name": ""
}
],
"seller_sku": "",
"stock_infos": [
{
"available_stock": "",
"warehouse_id": ""
}
]
}
],
"update_time": "",
"video": {
"duration": "",
"id": "",
"media_type": "",
"post_url": "",
"video_infos": [
{
"backup_url": "",
"bitrate": "",
"file_hash": "",
"format": "",
"height": "",
"main_url": "",
"size": "",
"url_expire": "",
"width": ""
}
]
},
"warranty_period": {
"warranty_description": "",
"warranty_id": ""
},
"warranty_policy": ""
},
"message": "Success",
"request_id": "202203070749000101890810281E8C70B7"
Update Product
This subsection will be separated into Full Update (Edit Product in TikTok documentation), Update Price, Update Quantity, End Item (Deactivate Product), End Listing (Delete Product).
Also, we have to incorporate additional API calls for Activate product (after product deactivation) and Recover product (After product has been deleted);
Full Update (Edit Product)
In order to perform full update we will use “EditProduct“ API.
As per the requirements for the GTIN field on TikTok: When we call edit_product API to update a product which already has a GTIN assigned (The field GTIN type -identifier_code_type
& GTIN value - identifier_code
should be the same as the fields we have pushed when we create a product. They will be saved and will be pushed once we send updates) and we try to change the GTIN, error message should be returned. Once the GTIN has been assigned to an existing product, it can't be changed or deleted!
API Call: PUT /api/products
API Docs: https://developers.tiktok-shops.com/documents/document/237485
We are able to perform full update when we have the following internal statuses:
Case 1:
Product Status = Product Published ; Listing Status= Active; List / Update the whole item= Pending;
If update was successful, we will have following statuses:
Product Status =Product Published ; Listing Status= Active; List/ Update the whole item= Sent;
If we receive an error message, we will have following statuses:
Product Status = Product Published; Listing Status=Active; List / Update the whole item= Error;
Respective error need to be stored in Update Item Error field;
Case 2:
Product Status = Product Created ; Listing Status=Inactive ; List / Update the whole item= Pending;
If update was successful, we will have following statuses:
Product Status = Product Created ; Listing Status=Inactive ; List / Update the whole item= Sent; (In order get product details cron to verify the statuses)
If we receive an error message, we will have following statuses:
Product Status = Product Created; Listing Status=Inactive; List / Update the whole item= Error;
Respective error need to be stored in Update Item Error field;
Case 3: (For deletion variant)
Product Status = Product Published ; Listing Status= Active; Delete Variant= Yes;
If update was successful, we will have following statuses:
Product Status = Product Removed ; Listing Status= Inactive; + deletion of Channel Item ID, SKU_ID & GTIN value!
If we receive an error message, we will have following statuses and we need to store the error in Delete Variant Error field:
Product Status = Product Published ; Listing Status= Active ;
Case 4: (For adding variant!)
Product Status = Images Uploaded; Listing Status = Inactive; List / Update the whole item= Pending; + Channel Item ID to not be empty!
If update was successful, we will have following statuses: - Only to the new added variant!
Product Status = Product Created ; Listing Status=Inactive ; List / Update the whole item= Sent; (In order get product details cron to verify the statuses)
If we receive an error when adding variant, we need to store this error for every variants from the variation group BUT we do not changed listing & product statuses to variants!
List / Update the whole item= Error; We need to store the error in the respectively error field, which is Update Item Error field.
*Note: If we want to add a variant which already has been removed (Product status=Product Removed), we should put List/Update the whole item = Pending,** to start the cron for Uploading Images (in order to change the status to “Images Uploaded“) , then to start Create listing cron, which will assign the Channel item ID to the variant and after all this actions, to run the Update listing cron, which will pick the variant and add it to the existing product!
*Note:** If we have case 3, we should not add the variant into the payload, and also Channel Item ID, SKU ID and GTIN should be removed!
Example call:
{
"brand_id": "",
"category_id": "",
"delivery_service_ids": "",
"description": "",
"images": [
{
"id": ""
}
],
"is_cod_open": "",
"package_height": "",
"package_length": "",
"package_weight": "",
"package_width": "",
"product_attributes": [
{
"attribute_id": "",
"attribute_values": [
{
"value_id": "",
"value_name": ""
}
]
}
],
"product_certifications": [
{
"files": [
{
"id": "",
"name": "",
"type": ""
}
],
"id": "",
"images": [
{
"id": ""
}
]
}
],
"product_id": "",
"product_name": "",
"size_chart": {
"img_id": ""
},
"skus": [
{
"id": "",
"original_price": "",
"sales_attributes": [
{
"attribute_id": "",
"custom_value": "",
"sku_img": {
"id": ""
},
"value_id": ""
}
],
"seller_sku": "",
"stock_infos": [
{
"available_stock": "",
"warehouse_id": ""
}
]
}
],
"warranty_period": "",
"warranty_policy": ""
}
Test call example request:
{
"category_id": "989192",
"description": "<p>The design of everyday things</p>",
"images": [
{
"id": "tos-maliva-i-o3syd03w52-us/f68e64fb44ed4eedae871f35701746a6"
}
],
"is_cod_open": false,
"package_height": 10,
"package_length": 10,
"package_weight": "0.5",
"package_width": 5,
"product_attributes": [
{
"attribute_id": "100091",
"attribute_values": [
{
"value_id": "7098684758929983237",
"value_name": "7"
}
]
}
],
"product_id": "1729430908771994059",
"product_name": "Book The design of everyday things",
"size_chart": {
"img_id": "tos-maliva-i-o3syd03w52-us/f68e64fb44ed4eedae871f35701746a6"
},
"skus": [
{
"id": "1729430908995668427",
"original_price": "0.02",
"sales_attributes": [
{
"attribute_id": "100091",
"custom_value": "7",
"sku_img": {
"id": "tos-maliva-i-o3syd03w52-us/f68e64fb44ed4eedae871f35701746a6"
},
"value_id": "7098684758929983237"
}
],
"stock_infos": [
{
"available_stock": 2,
"warehouse_id": "7097151957604779781"
}
]
}
]
}
Mapping is the same as product create, except when we update product, we need to check if we have all images uploaded. If images are not uploaded, first we need to upload them and then to update the product.
Example response:
{
"code": 0,
"message": "Success",
"request_id": "123123123",
"data": {
"product_id": "123123123123",
"skus": [
{
"id": "123123123",
"seller_sku": "aaaa",
"sales_attributes": [
{
"attribute_id": "123123123123",
"value_id": "123123123123"
}
]
},
{
"id": "123123123",
"seller_sku": "bbbb",
"sales_attributes": [
{
"attribute_id": "123123123",
"value_id": "123123123123"
}
]
}
]
}
}
*Important :** As per additional tests performed, we are able to add new variant to existing product, using EditProduct API call. In order to do this, we should simply not push the SKU_IDs. SKU_IDs need to be pushed only if we want to update an already existing variant! Also, we need to keep the existing SKU at the same time! If this is not done, not only the old SKU will be deleted, but also the new one will not be successfully added! I.e. all products which are published need to be pushed in Edit Product Call + all variants which are will status awaiting creation + list/update the whole item = pending;
Example:
{
"category_id": "601226",
"description": "<p>Blue T-shirt</p>",
"images": [
{
"id": "tos-maliva-i-o3syd03w52-us/ef016dc087bd4c69a773a3af17aa62f0"
}
],
"is_cod_open": false,
"package_height": 40,
"package_length": 40,
"package_weight": "0.2",
"package_width": 30,
"product_id": "1729431148659444171",
"product_name": "Blue T-shirt",
"skus": [
{
"id": "1729431148854675915",
"original_price": "0.02",
"sales_attributes": [
{
"attribute_id": "100000",
"custom_value": "Blue"
},
{
"attribute_id": "100007",
"custom_value": "40"
}
],
"stock_infos": [
{
"available_stock": 3,
"warehouse_id": "7097151957604779781"
}
]
}, // Below is the new variant which is added to the product. The specific here is when we want to add new variant to product, we did not push the SKU_ID.
{
"original_price": "0.02",
"sales_attributes": [
{
"attribute_id": "100000",
"custom_value": "Red"
},
{
"attribute_id": "100007",
"custom_value": "44"
}
],
"stock_infos": [
{
"available_stock":43,
"warehouse_id": "7097151957604779781"
}
]
}
]
}
Possible error codes/messages:
Code | HTTP Code | Message |
---|---|---|
102000 | 500 | internal service error |
203154 | 200 | category is not exist |
203150 | 200 | Category is invalid |
203155 | 200 | Product name is empty |
203156 | 200 | Seller is inactivated |
203157 | 200 | Seller warehouse is empty |
203158 | 200 | Product description is invalid |
203160 | 200 | Product id is invalid |
203161 | 200 | image list is invalid |
203162 | 200 | Product price is invalid |
203163 | 200 | Product package weight is invalid |
203164 | 200 | Product package size is invalid |
203165 | 200 | Brand is is invalid |
203166 | 200 | Product name is invalid |
203167 | 200 | The number of SKU exceed the limit |
203168 | 200 | Seller warehouse is invalid |
203169 | 200 | The stock of sku exceed the limit |
203170 | 200 | The product brand is expired.Please modify and re_submit. |
203171 | 200 | Sale attribute is invalid |
203174 | 200 | Warranty policy exceed limit. |
203175 | 200 | Size chart image is nil. |
203176 | 200 | Sku name exceed limit. |
203177 | 200 | Multiple warehouse in one product. |
203178 | 200 | Required qualification is miss. |
203179 | 200 | The attribute is invalid. |
203186 | 200 | Qualification id is invalid. |
203201 | 200 | Size chart is invalid |
203202 | 200 | Category does not support COD |
203203 | 200 | Qualification image and file exceed limit error |
203206 | 200 | skus is invalid |
203207 | 200 | price is locked |
203208 | 200 | package is invalid |
203197 | 200 | Stock count is invalid. |
203187 | 200 | warranty policy contains non-local language |
203188 | 200 | description contains non-local language |
203189 | 200 | seller sku contains non-local language |
203223 | 200 | desc image invalid |
203224 | 200 | desc P tag invalid |
203225 | 200 | desc list tag invalid |
203226 | 200 | product main image is invalid |
203227 | 200 | product qualification image is invalid |
203228 | 200 | sale property image is invalid |
203229 | 200 | size chart image is invalid |
Update Price
Note: There are 2 separate APIs for price & stock update
API Call: PUT /api/products/prices
API Docs:https://developers.tiktok-shops.com/documents/document/237492
We are able to update the price when we have the following internal statuses:
Product status = Product Published; Listing Status = Active; Update price - Pending
If update was successful, we will have following statuses:
Product status -Product Published ; Listing Status -Active ; Update Price - Not Needed
If we receive an error, we will have:
Product status -Product Published ; Listing Status -Active ; Update Price - Error
We must store the respectively error into the field “Update Price Error“
In order to perform price update, we need to push the product_id
, SKU_id
and the original_price
that we would want to set. This means that we are able to push different price to a different variants of the product (because we need to push the sku_ids).
Example Call:
{
"product_id": "",
"skus": [
{
"id": "",
"original_price": ""
},
{
"id": "",
"original_price": ""
}
]
}
Call Mapping:
Integration Field | Integration Notes | Integration required | Hemi Mapping | Hemi Notes | |
---|---|---|---|---|---|
product_id |
Yes | Product Account > Channel Item ID | |||
skus |
Yes | ||||
id |
Yes | Product Аccount TikTok > SKU ID | The SKU ID is a value, returned by TikTok , once we successfully create a product. | ||
original_price |
Indonesian rupiah, the minimum and maximum prices are 100 and 100 million, respectively |
GBP, local to local business, the minimum and maximum are 0.01 and 5600, respectively GBP, cross-border business, the minimum and maximum values are 0.01 and 134.5, respectively Up to two digits after the decimal point | Yes | Product Account > Price | |
Example Response:
{
"code": 0,
"data": {
"failed_sku_ids": ""
},
"message": "Success",
"request_id": "202203070749000101890810281E8C70B7"
}
Possible Error codes & messages:
Code | HTTP Code | Message |
---|---|---|
102000 | 500 | internal service error |
203169 | 200 | Product id is invalid. |
203162 | 200 | Product price is invalid. |
203195 | 200 | Warehouse ID is invalid. |
203196 | 200 | SKU ID is invalid. |
203199 | 200 | Seller has no permission. |
203193 | 200 | product id is not exist |
203156 | 200 | Seller is inactivated |
203200 | 200 | the current product status is not allowed to be operated. |
203206 | 200 | skus is invalid |
203207 | 200 | price is locked |
Update Stock
The purpose of this section is to define the requirements of updating quantity to TikTok.
API Call: PUT /api/products/stocks
API Docs: https://developers.tiktok-shops.com/documents/document/237486
Case1:
We can perform stock update, If we have following internal statuses:
Product status -Product Published; Listing Status - Active ; **Update Quantity - Pending**
If update was successful, we will have following statuses:
Product status -Product Published ; Listing Status -Active ; Update Quantity - Not Needed
If we receive an error, we will have:
Product status -Product Published; ; Listing Status - Active Update Quantity - Error
-
Important: If we push zero stock to a product, the product will be automatically deactivated from the channel! If we want to deactivate the product, we should use the separate API call “Deactivate Product“.
NOT
Note: We can perform stock update to each variant of a product (Using SKU ID) but deactivation can be done only for whole product (For deactivation we need to push only Product ID).
So If we want to stop selling 1 variant, we simply push 0 stock to it
If we want to stop selling whole product and all of its variant, we can send 0 stock and then to stop selling it from the channel.
Case 2: When the product has been ended successfully, we will have:
Product status -Product Published; Listing Status - Inactive; Update Quantity - Pending;
Once we receive success, we should have following:
Product status -Product Published ; Listing Status - Active; Update Quantity - Not Needed
If we receive an error, we will have:
Product status -Product Published ; Listing Status -Inactive ; Update Quantity - Error;
We must store the respectively error into the field “Error Updating Quantity“
-
Important: If we push positive quantity to already deactivated product, the status will be changed automatically to Live on TikTok (“Active“ in Hemi). In order to activate the product we should send “Activate Product“ call and then, we have to send positive quantity with “UpdateStock“ call.
NOT
-
Important for Case 2: TikTok notes: “The SKU stock can be updated only this SKU in live status.(you cannot successfully modify the stock if the product in other status)“- TT answer: Modifying the stock requires the product to be in live status, which is necessary
-
If we have raised “End item“ flag, it should push zero quantity to a variant! The product will be deactivated when all its variant are with 0 quantity. Please, see detailed explanation in “Deactivation“ API subsection.
Example Call:
{
"product_id": "",
"skus": [
{
"id": "",
"stock_infos": [
{
"available_stock": "",
"warehouse_id": ""
}
]
},
{
"id": "",
"stock_infos": [
{
"available_stock": "",
"warehouse_id": ""
}
]
}
]
}
On TikTok marketplace, we can push quantity to each variant of a product, using the SKU IDs.
Call Mapping:
Integration Field | Integration Notes | Integration required | Hemi Mapping | Hemi Notes | ||
---|---|---|---|---|---|---|
product_id |
string | Yes | Product Account > Channel Item ID | |||
skus |
object[] | |||||
The SKU stock can be updated only this SKU in live status.(you cannot successfully modify the stock if the product in other status | Yes | |||||
id |
string | |||||
SKU_ID | Yes | Product Аccount TikTok > SKU ID | ||||
stock_infos |
object[] | Yes | ||||
available_stock |
int32 | |||||
The value should be non-negative numbers(include number 0)And less then 99999 | Yes | Product Account > Quantity | ||||
warehouse_id |
string | No | N/A |
Upon successful response we will receive code “0“ status with message “Success“ for each update we’ve requested.
Example Response:
{
"code": 0,
"message": "Success",
"request_id": "12312312312",
"data": {}
}
If we would want to update stock for a product, which have variations, we should push the Product ID, that we have received and store into Channel Item ID, and the “SKU ID“ for each variant that we have stored in “Product Account TikTok > SKU ID“.
- Note: We send each variant one by one (each variant in separate call). This was agreed because if we send update to lets say 2 variants and one of them failed, TikTok does not specify the failed SKU into the error response. Having in mind the APIs limits are 50 requests per seconds, we have agreed to send stock updates one by one for each variant in order if there is an error, the error to be raised only on the failed SKU but not applied to all SKUs we have sent.
Possible Error codes & Messages:
Code | HTTP Code | Message |
---|---|---|
102000 | 500 | internal service error |
203169 | 200 | Product id is invalid. |
203195 | 200 | Warehouse ID is invalid. |
203196 | 200 | SKU ID is invalid. |
203199 | 200 | Seller has no permission. |
203193 | 200 | product id is not exist |
203197 | 200 | Stock count is invalid. |
203156 | 200 | Seller is inactivated |
203200 | 200 | the current product status is not allowed to be operated. |
203206 | 200 | skus is invalid |
Deactivate Product
We are not able to deactivate products in following statuses: draft, frozen and deleted products cannot be deactivated.
“Draft status“ - product has been created but it is not on live. - If we try to deactivate a product in draft status, we should receive error that need to be stored;
“Frozen“ - product was suspended and it is not live - If we try to deactivate a product in frozen status, we should receive error that need to be stored; - TBD with TT
Deactivate Product function is used to stop a product from being “available” to the end buyer but without removing the product from the Marketplace. It is generally used to send a “deactivation” to ensure the product is not being sold anymore.
-
Important: For TikTok, “Deactivate“ API call will deactivate the product and all its variant! ( Will be covered within the stock update cron!!!) and if all the variants of the products are with zero stock, we will send deactivation call.
End item flag will send only 0 stock
Respectively, if the product status is “deactivated“, and we push positive stock to the product, the status will be still “deactivated“. In order to push product back on “Active”, first we need to call “Activate Product“ call and then to send stock updates;
API Call: POST /api/products/inactivated_products
API Docs: https://developers.tiktok-shops.com/documents/document/237489
In order to deactivate product, we should have following statuses and all variants of product with 0 quantities:
Product status - Product Published; Listing Status - Active ; Qty=0 ;
After successful update we will have:
Product status -Product Published ; Listing Status - Inactive;
If error:
Product status - Product Published; Listing Status - Active ; List/Update the whole item = Error and into Update Item Error field** to store the error with specific tag [DEACTIVATION]
Example Call:
{
"product_ids": [
"123123123123",
"123123123",
"123123123",
"1231231231"
]
}
We need to push product_ids
, which is Channel item ID field in Hemi, for products that we want to deactivate; This means when we send “Deactivate Product“ call, it will deactivate the product and all its variants.
We will deactivate only if all variants into variations are with 0 stock.
Example Response:
{
"code": 0,
"message": "Success",
"request_id": "123123123",
"data": {
"failed_product_ids": [
"123123123",
"12312312312"
]
}
}
Possible Error codes & Messages:
Code | HTTP Code | Message |
---|---|---|
102000 | 500 | internal service error |
203169 | 200 | Product id is invalid. |
203156 | 200 | Seller is inactivated |
203222 | 200 | product ids exceed limit |
Activate Product
This API is for sellers to activate the already deactivated (off shelf) product (except the deleted product/frozen product /draft product).
API Call: POST api/products/activate
API Docs: https://developers.tiktok-shops.com/documents/document/237490
Batch request API(20 per time)
When the seller activates the product via this API ,after API gets the information successfully , the product system side will send the product to audit team. (so product will pending for audit and waiting for the result).
Case1: Positive Quantity is a must!
In order to activate product we could incorporate the cron which will look for following statuses:**
Product status=Product Published; Listing status - Inactive; List update the whole item = Pending;
After successful run, we will have following statuses:
Product status=Product Published; Listing status - Active; List update the whole item = Pending
If error, we will have:
Product status=Product Published; Listing status - Inactive; List update the whole item = Error
We should need the respective Error into Update item error field.
Case2: When positive stock updates needs to be sent to the MP (Positive Quantity is a must!)
In order to activate product we could incorporate the cron which will look for following statuses:**
Product status=Product Published; Listing status - Inactive; Update Quantity = Pending;
After successful run, we will have following statuses:
Product status=Product Published; Listing status - Active; Update Quantity = Pending
If error, we will have:
Product status=Product Published; Listing status - Inactive; Update Quantity = Error
- Important for Case 2: If we push positive quantity to already deactivated product, the status will not be changed automatically to “Active“(Live on TikTok). In order to activate the product we should send “Activate Product“ and then we have to send positive quantity with “UpdateStock“ call.
Following described flows above, will make a product “available” to the end buyer.
Example Call:
{
'product_ids': [
'1729385838007780943',
'1729382606675281112'
]
}
In order to activate a product which has been deactivated, we need to push the product_id
which is equivalent to our Channel item ID. If successful, it will activate the products & all its variants.
Integration Field | Integration Notes | Integration required | Hemi Mapping | Hemi Notes |
---|---|---|---|---|
product_id |
string | Yes | Product Account > Channel Item ID |
Example Response:
{
'code': 0,
'message': 'Success',
'request_id': '202112030628210102310290700307F0E8',
'data': {
'failed_product_ids': [
'1729385838007780943'
]
}
}
End Listing (Delete Product)
End listing is used to remove the whole listing & listing variants.
Products that are with statuses “frozen“ and “deleted“ cannot be deleted.****
Delete product call shouldn’t remove images. And if we re create a product, using ““Recover“ API, we do not need to upload again the images.
In order to delete a product, we should have following statuses:
Product Status - Product Published OR Product Created and End Listing = Yes.
After successful deleted item we set the statuses:
Product Status - Product Removed ( + delete fields like SKU_ID GTIN, GTIN Type)
If we receive an error we need to store the respectively Error into the field End listing error. and End listing = No
Note: “Yes“ flag will trigger the update.
Note: The flags “delete variant“ and “end listing“ have priority over any of the listing and update flags
API Call: DELETE /api/products
API Docs: https://developers.tiktok-shops.com/documents/document/237484
Example Call:
{
"product_ids": [
"123123123",
"123123123",
"1231231231",
"12312312123"
]
}
Call Mapping:
Integration Field | Integration Notes | Integration required | Hemi Mapping | Hemi Notes |
---|---|---|---|---|
product_id |
string | Yes | Product Account > Channel Item ID |
Example Response:
{
"code": 0,
"message": "Success",
"request_id": "123123123",
"data": {
"failed_product_ids": [
"123123123",
"123123123"
]
}
}
Under failed_product_ids
we will receive list of products that failed to update(delete).
Note: As we push product_ids
in order to delete a product, this means the product and all its variant will be deleted to! If we would want to stop selling a variant, we need to push 0 stock to the variant we would want to stop sell.
Additional validation:
During the performed tests, we have identify we can receive following error message:
response: {
"code": 101000,
"message": "param is invalid ; detail:param product_ids Check invalid",
"request_id": "202206141209320101071211221C2B9858",
"data": null
}
The following error message could be received if we push invalid product ids, for example:
{
"product_ids": [
"1729431148659444171",
"172943114865944417121" // this ID is longer than the ID above and invalid.
]
}
We need to have a validation for product_ids
field and also, if we receive such message (in which we do not have failed_product_ids) we need to apply error on all product_ids.
Possible Error codes & Messages:
Code | HTTP Code | Message |
---|---|---|
102000 | 500 | internal service error |
203169 | 200 | Product id is invalid. |
203156 | 200 | Seller is inactivated |
203200 | 200 | the current product status is not allowed to be operated. |
203222 | 200 | product ids exceed limit |
Additional Information:
- Workflow steps
Create Product Flow:
**In order to create a product, first we have to do internal check if all required attributes are part of the the product as Item Specifics according to their taxonomy. After that, we should make call for upload product images - with this call we will store image URLs into item account TikTok.

Edit Product Flow:

- Type of communication
- Hemisphere requirements for execution
For TikTok integration we need to make sure the protect flags are working as expected:
Protect Quantity will blocks communication to the relevant variant for any stock updates; In order to send activation of product we should have at least one variant without protect qty; (protect qty=0)
Protect Price will blocks communication to the relevant variant for any price updates. We will store also lastSuccessfulPriceSentValue
& lastSuccessfulPriceSentTime
;
Protect the whole item - ****will blocks all content communication for the relevant product to the marketplace except Stock; (We cannot exclude stock & price from the payload)
Closed - will stop all the updates to the MPs;
Recover Product - N/A
Do not read
Waiting some more clarifications from TT. Maybe not needed. Instead of using this call, we could simply relist a product.
This API is for sellers to recover the deleted product (not the products with status “frozen“).
In order to recover product we could incorporate a cron which will look for following statuses:**
Product status=Product Removed; Listing status - Inactive; List update the whole item = Pending
After successful run, we will have following statuses:
Product status=Product Published; Listing status - Active; List update the whole item = Not Needed
If error, we will have:
Product status=Product Removed; Listing status - Inactive; List update the whole item = Error
API Call: POST api/products/recover
API Docs: https://developers.tiktok-shops.com/documents/document/237491
Example Call:
{
'product_ids': [
'1729384925891890096',
'1729382606675281112'
]
}
Example Response:
{
'code': 0,
'message': 'Success',
'request_id': '202112030626160102310290690107A637',
'data': {
'failed_product_ids': [
'1729384925891890096',
'1729382606675281112'
]
}
}
**Important*** If we recover a product, which was on status “deactivated“ before deleting it, the status will be still “deactivated“. In order to make the product available for sell, we need to call “Activate Product“ API.
GetWarehouses - N/A
Do not read
warehouse ID:7097150229983676165 - As we will have only 1 WH? - Need to be discussed
Pass in shop_id to get the information of all warehouses of the shop.
API Call: GET /api/logistics/get_warehouse_list
API Docs: https://developers.tiktok-shops.com/documents/document/237469
Example Call:
{
'code': 0,
'message': 'Success',
'request_id': '202112030628210102310290700307F0E8',
'data': {
'failed_product_ids': [
'1729385838007780943'
]
}
}
Response:
{
"code": 0,
"message": "Success",
"request_id": "202109090653160102450571902E003892",
"data": {
"warehouse_list": [
{
"warehouse_id": "7000714532876257026",
"warehouse_name": "cbtest",
"warehouse_type": 1,
"warehouse_sub_type": 3,
"warehouse_effect_status": 1,
"warehouse_address": {
"region": "People's Republic of China",
"state": "Chongqing City",
"city": "Chongqing City",
"district": "Wanzhou District",
"town": "",
"full_address": "ceshi",
"zipcode": "",
"phone": "(+86)12342087611",
"contact_person": "guo"
}
},
{
"warehouse_id": "7000714532876273410",
"warehouse_name": "cbtest",
"warehouse_type": 2,
"warehouse_sub_type": 3,
"warehouse_effect_status": 1,
"warehouse_address": {
"region": "People's Republic of China",
"state": "Chongqing City",
"city": "Chongqing City",
"district": "Wanzhou District",
"town": "",
"full_address": "ceshi",
"zipcode": "",
"phone": "(+86)12342087611",
"contact_person": "guo"
}
}
]
}
}
Upload File - N/A
DO NOT READ
As per discussion with TT - when we have a category, which is required to push certification information, it is enough to push the certification image id, i.e. we can skip upload file feature.
This API is to a upload a certification file for a product categories, that requires to push product_certification information when creating a product from such category. (Example for such category is category_id = 910728 (Power Banks).
API Call: POST /api/products/upload_files
API Docs: https://developers.tiktok-shops.com/documents/document/237481
Example Call:
{
"file_data": "aaaaaaaaaaaiasdjflkasdjfklasjdfl",
"file_name": "a.pdf"
}
Call Mapping:
Integration Field | Integration Notes | Integration required | Hemi Mapping | Hemi Notes |
---|---|---|---|---|
file_data |
Import the file in pdf format. The file is a string generated by base64 encoding. The original file size must not exceed 10M. | Yes | TikTok >Certification File | New field |
Need to store the URL to the file into this field | ||||
file_name |
Yes | TikTok > Certification File name | New field |
Encoded file example:
Example Response:
{
"code": 0,
"message": "Success",
"request_id": "123333111131313131",
"data": {
"file_id": "aaaaaa",
"file_url": "http://bbbbbbbb",
"file_name": "file1.pdf",
"file_type": "PDF"
}
}
Response Mapping:
Integration Field | Integration Notes | Integration required | Hemi Mapping | Hemi Notes | |
---|---|---|---|---|---|
request_id |
|||||
data |
|||||
file_id |
string | Product Account TikTok> File ID | New field |
If we have already certificate ID, and we send new certificate, we need to store the new certififcate id
This field will be needed for product creation, only if the category of the product has product_certification information |
| | file_url
| string | | Product Account TikTok > File URL | |
| | file_name
| string | | N/A | Will be automatically picked from the URL |
| | file_type
| string | | N/A | Will be automatically picked from the URL |
We should not pick a product for creation, if the file is not uploaded (Only for products which required “Product Certification info”. More information regarding product certifications is available here TikTok - Taxonomy - OLD
- Important: The file type should be always PDF type.