Create or update a product
Send the product without an id to create it. If the product_reference
already exists on your channel, that product is updated instead. To update,
send the same product_reference again, or our id.
The response is the product as stored, including the id we assigned.
- A
200means we stored the product, not that a listing exists. Your channel needs a category rule first. See What makes a product go live. - The
variantsarray replaces the product's variants. A variant you leave out is deleted. Always send the complete list. Do not send an empty list or leavevariantsout: today that deletes every variant but leaves the listing live with its old stock. To take a product down, use Delete a product. idvalues are per-environment and take precedence overproduct_reference. Only send one you are certain of. See Important concepts.
Product fields
condition, delivery_type, discreet_listing, handling_time and
quantity_per_lot do not reach your listings today. Only rules on your channel
set them. Add the rules in Bob Sync, on your channel's Rules page. gtin
cannot be set at all today.
| Field | Type | Required | Notes |
|---|---|---|---|
id |
integer | no | Our key, assigned on create. Per-environment. Takes precedence over product_reference. |
product_reference |
string | yes | Your reference for the product. Unique within your channel and stable. |
name |
string | yes | The listing title. Required to list. |
description |
string | yes | Cut off at 7,500 characters. HTML is allowed; scripts, embeds, iframes, objects and forms are stripped. |
condition |
string | no | NEW, SECOND_HAND, REFURBISHED or OPEN_BOX. Set only by a channel rule today, not by this field. |
delivery_type |
string | no | STANDARD_SHIPPING, DIGITAL_DELIVERY, ALLOWS_COLLECTION or COLLECTION_ONLY. Set only by a channel rule today, not by this field. |
discreet_listing |
boolean | no | Hides the buyer's user name. Defaults to false. Set only by a channel rule today, not by this field. |
gtin |
string | no | Global Trade Item Number. Not currently carried through to listings. Defaults to null. |
handling_time |
integer | no | Days to have an order ready for collection, at most 15. Set only by a channel rule today, not by this field. |
quantity_per_lot |
integer | no | Minimum purchase quantity. Defaults to 1. Set only by a channel rule today, not by this field. |
tags |
string | no | Comma-separated tags for the listing. |
vendor |
string | no | The vendor of the product. |
images |
array of ProductImage | yes, to list | A product with no images cannot become a listing. |
variants |
array of Variant | yes, to list | At least one. Replaces the product's variants; a variant left out is deleted. |
ProductImage fields
| Field | Type | Required | Notes |
|---|---|---|---|
src |
string | yes | An absolute URL. |
position |
integer | no | Sort order, ascending. |
Variant fields
| Field | Type | Required | Notes |
|---|---|---|---|
variant_id_text |
string | yes | Your reference for the variant, unique within the product. An unrecognised value creates a new variant. |
sku |
string | recommended | Shown on the listing and returned as tradersReference on order webhooks. Your key for matching a sale to your stock. |
price |
number | yes | Must be above zero to list. |
quantity |
integer | yes | At least 1 and below 100,000 to list. |
weight |
number | recommended | Kilograms. Used to estimate shipping at checkout. |
price_compare |
number | no | Shown struck through, only when greater than price. |
image_src |
string | no | The variant's image. If the URL is also in images, the listing switches to it when the variant is selected. |
barcode |
string | no | Barcode data. Stored but not currently displayed. |
position |
integer | no | Sort order, ascending. |
name |
string | no | On a product with one variant, added to the listing title as "product name - variant name". Not displayed on a product with two or more variants. |
description |
string | no | On a product with one variant, replaces the product description when not empty. Not displayed on a product with two or more variants. |
options |
array of Option | conditional | Size, colour and so on. Required when the product has two or more variants. See Important concepts. |
Validation
This endpoint does not currently check product_reference, condition,
delivery_type or handling_time. A missing reference or an unrecognised
value is accepted with a 200. Bulk upload does check them. Send valid values
on both.
Listing-detail fields in the response
condition, delivery_type, discreet_listing, gtin, handling_time and
quantity_per_lot are not stored on the product, so the response shows:
| Call | What the response shows |
|---|---|
| Create | Empty: "", 0, false or null. |
| Update | The values you sent. |
| Fetch products | Empty, always. |
An empty value does not mean the request was rejected.
Failures
| Status | Body | Meaning |
|---|---|---|
400 |
failed to JSON decode the request body ... |
The body is not valid JSON. |
404 |
failed to get product: ... |
The product lookup failed on our side. Retry. |
413 |
{"message":"Request Entity Too Large"}, or an HTML page on Sandbox |
The body is over 1 MB on Sandbox or 6 MB on Production. |
429 |
... is busy. Will retry... |
The same product is already being processed. Retry shortly. |
500 |
product does not belong to given channel |
The id belongs to a product on another channel. |
500 |
handler failed, because handler function crashed: ... |
The id does not exist on this environment. See Important concepts. |
500 |
failed to insert product, failed to update product or failed to update product variants |
A write failed on our side. Retry. |
A 500 with either of the first two messages is caused by the request. Check
the id you sent before retrying.
Response
200 with the stored product, including the id we assigned. The example
is a create, so the listing-detail fields are empty.
See the example response.