One product
GET/v1/products/{id}
scope products.read
By our id, or by your own with ?by=external_id.
Query parameters#
| Name | Example | |
|---|---|---|
by | — | Set to external_id to look up by your identifier |
Response#
| Field | Type | Description |
|---|---|---|
id | integer | OUR id for the listing. Use it in the path of the other product endpoints. |
external_id | string|null | YOUR id, as you sent it — the key upserts match on and what to reconcile against. null on a listing created in the dashboard rather than through this API. |
sku | string|null | Your stock-keeping unit, returned as you sent it. |
gtin | string|null | GTIN, as you sent it. |
mpn | string|null | Manufacturer part number, as you sent it. |
ean | string|null | EAN barcode, as you sent it. |
title | string | The listing title. |
description | string|null | The listing description, as stored. |
category_id | integer|null | The category, as a MASTER id — the same value you send on a write. |
status | string | Where the listing is in its life. active is the only one buyers can order from. Four database columns collapse into this one word, so read it rather than inferring from anything else.Accepts |
is_reviewed | boolean | Whether a moderator has approved it. A listing can be active and not yet reviewed; the product.approved and product.rejected webhooks fire when this changes. |
price | object | The asking price. |
price. | integer|null | Minor units — 249900 is 2 499,00. |
price. | string|null | Decided by the listing country, not by you. This is the currency an order for it settles in. |
price. | boolean | Whether offers are accepted on this listing. |
stock | integer|null | Units available, or null where none was ever set. |
shipping | object | Delivery facts about this listing. |
shipping. | boolean | Always true on anything this API created — see POST /v1/products. It can still read false on an older listing made in the dashboard before that was settled; the next write through this API repairs it. |
shipping. | boolean | Whether delivery is free on this listing regardless of your bands. |
shipping. | string | DERIVED from weight, dimensions and the category — there is no column for it. It decides how the courier is priced. |
shipping. | string | Which of your two shipping-absorption band sets governs this listing. This is the only way to connect a product to its bands, since absorption is configured per tier. Accepts |
shipping. | number|null | Declared weight. |
shipping. | number|null | Declared width. |
shipping. | number|null | Declared height. |
shipping. | number|null | Declared length. |
group_id | integer|null | The variant group this listing belongs to, or null. Set through POST /v1/product-groups. |
images | array | Photos, already in display order. |
images[]. | integer | What you send to PUT /v1/products/{id}/images/order and to the delete endpoint. |
images[]. | integer | Its place in the order, 0 being the main photo. |
images[]. | string|null | Where the file sits in our storage, when we host it. |
images[]. | string|null | The URL we serve it FROM, when you attached it by link and we never re-hosted it. One of these two is set, not both — an image with a source_url breaks if you move the file. |
attributes | array | The category attributes on this listing. |
attributes[]. | integer | The attribute, as a master id. |
attributes[]. | integer|null | The chosen option, for list attributes. |
attributes[]. | string|null | The free-text value, for attributes with no option list. One of these two is set. |
created_at | string | ISO-8601 UTC. |
updated_at | string | ISO-8601 UTC. This is what ?updated_since= compares against, so store it if you sync incrementally. |
Example
{
"id": 237224,
"external_id": "ERP-1001",
"sku": "MTB-29-001",
"gtin": null,
"mpn": null,
"ean": null,
"title": "Bicicleta MTB Hardtail 29 inch",
"description": "A hardtail mountain bike in very good condition, barely used.",
"category_id": 4291,
"status": "active",
"is_reviewed": true,
"price": {
"amount": 249900,
"currency": "RON",
"negotiable": true
},
"stock": 4,
"shipping": {
"ship_with_us": true,
"free_shipping": false,
"shipping_class": "bike",
"parcel_tier": "large",
"weight_kg": 14.5,
"width_cm": 80,
"height_cm": 120,
"length_cm": 180
},
"group_id": null,
"images": [
{
"id": 108876841,
"position": 0,
"path": "files/237224/mtb-front.jpg",
"source_url": null
}
],
"attributes": [
{
"field_id": 32,
"option_id": 226,
"value": null
}
],
"created_at": "2026-09-01T08:14:22Z",
"updated_at": "2026-09-11T16:02:51Z"
}