Seller journeysListing management

Listing management, end to end

The full path from an empty catalog to a live, maintained listing — including the three constraints that most often surprise integrators.

Three things to design around before you start.

  • Category values are not round-trippable: reads return the name, writes require the ID.
  • Variants are fixed at creation. Only price and stock can change afterwards.
  • There is no bulk update. Bulk is create-only; maintenance is one call per product.
  1. Resolve the category ID

    Call GET /open/v1/categories and keep a mapping from your own taxonomy to the category_id values it returns. Product create and update require that ID; sending a name returns 400 CATEGORY_NOT_FOUND.

    The round-trip trap. GET /products/{id} returns "category": "Accessories" — a display name. POST and PUT /products/{id} require "category": "pcat_01J2X…" — the category_id. A naive read-modify-write loop therefore fails with 400 CATEGORY_NOT_FOUND. Keep the ID from your own mapping; never echo back the category value you read from a product.

  2. Host your images

    The API accepts image URLs, not uploads. Each must be https://, at most 2,048 characters, and publicly reachable at creation time. Up to 20 per product. There is no upload endpoint — serve images from your own CDN before you create the listing.

  3. Create the product
    POST/open/v1/productscatalog:write · 201
    {
      "title":       "Premium Leather Wallet",
      "description": "Full-grain leather, six card slots.",
      "category":    "pcat_01J2X…",     // category_id from GET /categories — NOT the name
      "images": [
        "https://cdn.example.com/wallet-front.jpg",
        "https://cdn.example.com/wallet-back.jpg"
      ],
      "variants": [
        { "title": "Black", "sku": "WALLET-BLK", "price": 259900, "stock": 45,
          "options": { "colour": "Black" } },
        { "title": "Tan",   "sku": "WALLET-TAN", "price": 259900, "stock": 30,
          "options": { "colour": "Tan" } }
      ]
    }

    At least one variant is required, each with a non-negative integer price in centavos and stock. Do not send status — it is set separately in the next step.

  4. Publish it
    POST/open/v1/products/{id}/statuscatalog:write

    Creation does not make a listing buyable. Send { "status": "live" } to publish. Statuses are live, unlisted and delisted.

  5. Maintain it
    To changeCallNote
    Title, description, category, imagesPUT /products/{id}Images replace the whole set — send the complete list, not a delta
    PricesPUT /products/{id}/priceAtomic across the variants you name
    StockPUT /products/{id}/stockAbsolute quantities, up to 100 variants per call
    VisibilityPOST /products/{id}/status
    Add or remove a variantSeller CenterRecreate the listing, or edit it in Seller Center.
    Category attribute valuesRead-only APIRead attribute definitions through the API; manage values in Seller Center.
  6. Keep stock in sync

    Use PUT /open/v1/products/{id}/stock for stock sync. It sets absolute per-variant quantities by variant_id in one call. This is the recommended path for stock sync — one absolute set per variant. The /inventory write routes are also available (see Inventory) if you prefer per-item updates.

    PUT /open/v1/products/prod_abc123/stock
    {
      "items": [
        { "variant_id": "var_blk", "stock_quantity": 42 },
        { "variant_id": "var_tan", "stock_quantity": 0 }
      ]
    }
  7. Onboard a large catalog
    POST/open/v1/products/bulkcatalog:write · 201

    Up to 5,000 products per request, 100 variants each. Batches over 50 run asynchronously and return a job — see Bulk operations & jobs. This endpoint creates only. It cannot update existing products; items carry no product ID and sending one is a validation error.