Catalog API2026-11Preview

Products

A listing you saved from an import, with your title and prices and the stores it sells on.
  • Shopify is where products are pushed. Orders from the marketplaces your Shopify store sells on reach us through Shopify too: Connect a store.
  • A WooCommerce or Wix store keeps its own products and sends its orders with Create an order.

The Product object

idstring
Starts prd_.
titlestring
Your title. The seller's stays on the import.
statusstring
active, or paused (by you, or by a sync rule when a cost rose too far or the seller ran out).
sourceobject
Marketplace, listing link and seller in China.
options[]array
Option names, at most three, as your store shows them.
price_range, cost_rangeobject
Your prices and the seller's, across variants.
channels[]array
Where it is listed: the store, its own product id, and its status there.
syncobject
The sync rule it follows and when we last read the listing.
importstring
The import it was saved from.
product
{
  "id": "prd_8f2k",
  "title": "Heavyweight Washed Hoodie",
  "status": "active",
  "source": {
    "marketplace": "weidian",
    "url": "https://weidian.com/item.html?itemID=7750970856",
    "seller": "Ruoyi Studio"
  },
  "options": ["Color", "Size"],
  "variants_count": 6,
  "price_range": {
    "min": { "amount": "49.99", "currency": "USD" },
    "max": { "amount": "54.99", "currency": "USD" }
  },
  "cost_range": {
    "min": { "amount": "38.00", "currency": "CNY" },
    "max": { "amount": "42.00", "currency": "CNY" }
  },
  "channels": [
    {
      "channel": "shopify",
      "shop": "acme-goods.myshopify.com",
      "external_id": "gid://shopify/Product/8812042",
      "status": "draft",
      "pushed_at": "2026-11-04T09:20:03Z"
    }
  ],
  "sync": {
    "rule": "rule_default",
    "last_checked_at": "2026-11-04T09:12:40Z"
  },
  "import": "imp_2c9d",
  "created_at": "2026-11-04T09:20:01Z",
  "updated_at": "2026-11-04T09:20:03Z"
}

List products

GET/v1/products

Your products, newest first.

Scopeproducts:read

Query parameters

statusstring
Optional. active or paused.
channelstring
Optional. shopify, for the ones listed there.
changed_sincestring
Optional. A time: only products whose cost or stock moved since.
limit, cursor
Pagination
curl "https://www.ninjabuy.com/api/v1/products?status=active&limit=2" \
  -H "Authorization: Bearer $NINJABUY_API_KEY" \
  -H "NinjaBuy-Version: 2026-11"
Response 200
HTTP/2 200 OK

{
  "data": [
    {
      "id": "prd_8f2k",
      "title": "Heavyweight Washed Hoodie",
      "status": "active",
      "variants_count": 6
    },
    {
      "id": "prd_1x0a",
      "title": "Canvas Tote",
      "status": "active",
      "variants_count": 3
    }
  ],
  "has_more": true,
  "cursor": "c_1x0a"
}

Retrieve a product

GET/v1/products/{id}

One product with its source, channels and sync state. Its variants are on their own route.

Scopeproducts:read

Path parameters

idstringrequired
The product's id.

Errors

StatusTypeWhen
404not-foundNo such product on this account.
curl "https://www.ninjabuy.com/api/v1/products/prd_8f2k" \
  -H "Authorization: Bearer $NINJABUY_API_KEY" \
  -H "NinjaBuy-Version: 2026-11"
Response 200
HTTP/2 200 OK

{
  "id": "prd_8f2k",
  "title": "Heavyweight Washed Hoodie",
  "status": "active",
  "source": {
    "marketplace": "weidian",
    "url": "https://weidian.com/item.html?itemID=7750970856",
    "seller": "Ruoyi Studio"
  },
  "options": ["Color", "Size"],
  "variants_count": 6,
  "price_range": {
    "min": { "amount": "49.99", "currency": "USD" },
    "max": { "amount": "54.99", "currency": "USD" }
  },
  "cost_range": {
    "min": { "amount": "38.00", "currency": "CNY" },
    "max": { "amount": "42.00", "currency": "CNY" }
  },
  "channels": [
    {
      "channel": "shopify",
      "shop": "acme-goods.myshopify.com",
      "external_id": "gid://shopify/Product/8812042",
      "status": "draft",
      "pushed_at": "2026-11-04T09:20:03Z"
    }
  ],
  "sync": {
    "rule": "rule_default",
    "last_checked_at": "2026-11-04T09:12:40Z"
  },
  "import": "imp_2c9d",
  "created_at": "2026-11-04T09:20:01Z",
  "updated_at": "2026-11-04T09:20:03Z"
}

Update a product

PATCH/v1/products/{id}

Change the title or description, or pause and resume it. Send only what changes. Prices are per variant (Variants); a pushed product carries the change to your store on its next push.

Scopeproducts:write

Path parameters

idstringrequired
The product's id.

Body

titlestring
Optional.
descriptionstring
Optional. HTML your store shows.
statusstring
Optional. active or paused. Paused sets stock to 0 on your channels.
sync_rulestring
Optional. A sync rule id; the default rule when null.

Errors

StatusTypeWhen
404not-foundNo such product on this account.
curl -X PATCH "https://www.ninjabuy.com/api/v1/products/prd_8f2k" \
  -H "Authorization: Bearer $NINJABUY_API_KEY" \
  -H "NinjaBuy-Version: 2026-11" \
  -H "Content-Type: application/json" \
  -d '{ "status": "paused" }'
Response 200
HTTP/2 200 OK

{
  "id": "prd_8f2k",
  "title": "Heavyweight Washed Hoodie",
  "status": "paused",
  "source": {
    "marketplace": "weidian",
    "url": "https://weidian.com/item.html?itemID=7750970856",
    "seller": "Ruoyi Studio"
  },
  "options": ["Color", "Size"],
  "variants_count": 6,
  "price_range": {
    "min": { "amount": "49.99", "currency": "USD" },
    "max": { "amount": "54.99", "currency": "USD" }
  },
  "cost_range": {
    "min": { "amount": "38.00", "currency": "CNY" },
    "max": { "amount": "42.00", "currency": "CNY" }
  },
  "channels": [
    {
      "channel": "shopify",
      "shop": "acme-goods.myshopify.com",
      "external_id": "gid://shopify/Product/8812042",
      "status": "draft",
      "pushed_at": "2026-11-04T09:20:03Z"
    }
  ],
  "sync": {
    "rule": "rule_default",
    "last_checked_at": "2026-11-04T09:12:40Z"
  },
  "import": "imp_2c9d",
  "created_at": "2026-11-04T09:20:01Z",
  "updated_at": "2026-11-04T09:20:03Z"
}

Push to Shopify

POST/v1/products/{id}/push

Lists the product on your linked Shopify store: one Shopify product, a variant per SKU you kept, its photos, each variant stocked at the Fulfilled by NinjaBuy location, so the orders for it come to us.

  • The first push creates it as a draft: the title and photos came from a Chinese marketplace, so read them before your buyers do, then publish in Shopify.
  • Pushing again updates the same Shopify product: prices and stock are set again, variants you dropped are removed. Status, title, description and photos stay as you left them in Shopify unless you send new ones.
  • Stock is the seller's count, capped at 100: we buy on demand, so it is how many orders Shopify takes before it shows sold out.
  • Your store must sell in US$, since that is what the prices are in. Sold-out variants are skipped and named in skipped[].

Scopeproducts:write

Path parameters

idstringrequired
The product's id.

Body

shopstring
Which linked store, as acme-goods.myshopify.com. Needed only when you linked several.
title, descriptionstring
Optional. Sent to Shopify only when you send them.

Errors

StatusTypeWhen
409no-linked-storeNo Shopify store is linked to this account, or several are and shop is missing.
409store-not-readyThe store's access lapsed, or our location is not set up yet: open the NinjaBuy app in Shopify once.
422store-currencyThe store does not sell in US$.
422too-many-optionsThe listing has more than three options; Shopify takes three.
422unprocessableEvery variant is sold out, or Shopify refused a field; detail passes its words on.
curl -X POST "https://www.ninjabuy.com/api/v1/products/prd_8f2k/push" \
  -H "Authorization: Bearer $NINJABUY_API_KEY" \
  -H "NinjaBuy-Version: 2026-11" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "shop": "acme-goods.myshopify.com" }'
Response 200
HTTP/2 200 OK

{
  "channel": "shopify",
  "shop": "acme-goods.myshopify.com",
  "external_id": "gid://shopify/Product/8812042",
  "status": "draft",
  "created": true,
  "variants": 5,
  "skipped": [{ "sku": "5187209555", "reason": "sold_out" }],
  "admin_url": "https://admin.shopify.com/store/acme-goods/products/8812042"
}

Delete a product

DELETE/v1/products/{id}

Stops syncing it and sets its stock to 0 on your channels; the Shopify product stays for you to archive. Orders already placed still ship.

Scopeproducts:write

Path parameters

idstringrequired
The product's id.

Errors

StatusTypeWhen
404not-foundNo such product on this account.
curl -X DELETE "https://www.ninjabuy.com/api/v1/products/prd_8f2k" \
  -H "Authorization: Bearer $NINJABUY_API_KEY" \
  -H "NinjaBuy-Version: 2026-11"
Response 200
HTTP/2 200 OK

{ "id": "prd_8f2k", "deleted": true }