Products & Variants

Products & Variants


The eBay product model

In eBay, a product (called an inventory item) is identified by a SKU that you assign. The SKU is the product's permanent ID — all subsequent operations (offers, updates, variant groups) reference it by SKU, not by a platform-generated ID.

A product contains the item's details — title, description, images, condition, dimensions, weight — but is not publicly listed until you create an Offer for it. Think of it as a catalog record that is separate from the public listing. See Listings & Offers for the offer flow.


API endpoints

MethodPathDescriptionAPI Reference
POST/api/v1/productsCreate a product (v1)ref
POST/api/v2/productsCreate a product (v2)ref
POST/api/v1/products/batchCreate multiple products in batchref
GET/api/v2/productsList all inventory itemsref
GET/api/v2/products/{sku}Get a single productref
PUT/api/v2/products/{sku}Update product or inventory/priceref
PUT/api/v2/products/{sku}Update inventory & price onlyref
DELETE/api/v2/products/{sku}Delete a productref
GET/api/v1/products/{key}/variantsGet product groupref
POST/api/v1/products/{key}/variantsCreate product groupref
PUT/api/v1/products/{key}/variantsUpdate product groupref

v1 vs v2 for product creation

For eBay, POST /api/v1/products is recommended over POST /api/v2/products. This is specific to eBay and does not apply to other platforms.

VersionHow it worksWhen to use
v1 /api/v1/productsPasses your request body directly to eBay's API without transformationRecommended. Lets you use eBay's exact native format, which you control fully
v2 /api/v2/productsGoes through EcartAPI's normalized product schema before reaching eBayUse for cross-platform workflows; less flexible for eBay-specific fields

eBay's product requirements — especially item specifics (aspects), package dimensions, and category-specific fields — change frequently. Using v1 means you work directly with eBay's native format and are not constrained by EcartAPI's normalization layer. This is particularly important for offers and variant groups, where eBay's API structure is more complex.

Creating a product

Both v1 and v2 call eBay's createOrReplaceInventoryItem endpoint. sku and marketplaceId are required. If a product with the same SKU already exists, the request returns an error — there is no upsert; you must delete and recreate.

Using v1 (recommended) — native eBay format:

POST /api/v1/products
{
  "product": {
    "sku": "MY-PRODUCT-001",
    "marketplaceId": "EBAY_US",
    "condition": "NEW",
    "product": {
      "title": "My Product Title",
      "description": "Product description",
      "aspects": {
        "Brand": ["My Brand"],
        "Type": ["T-Shirt"]
      },
      "imageUrls": ["https://example.com/image.jpg"],
      "packageWeightAndSize": {
        "dimensions": {
          "height": 10,
          "length": 15,
          "width": 10,
          "unit": "INCH"
        },
        "weight": {
          "value": 0.5,
          "unit": "POUND"
        }
      }
    },
    "availability": {
      "shipToLocationAvailability": {
        "quantity": 10
      }
    }
  }
}

Valid condition values: NEW, LIKE_NEW, NEW_OTHER, NEW_WITH_DEFECTS, CERTIFIED_REFURBISHED, SELLER_REFURBISHED, USED_EXCELLENT, USED_ACCEPTABLE


Price vs. stock: which endpoint updates what

This is one of the most common points of confusion:

What you want to changeEndpointPayload
Quantity onlyPUT /api/v2/products/{sku}{ "product": { "quantity": "10" } } — send only quantity, nothing else
Price onlyPUT /api/v1/listings/{offerId}{ "listing": { "pricingSummary": { "price": { "currency": "USD", "value": "24.99" } } } }
Quantity + price togetherPUT /api/v2/products/{sku}Include an offers array: { "product": { "offers": [{ "id": "OFFER_ID", "quantity": "10", "price": { "currency": "USD", "value": "24.99" } }] } }
Product details (title, images, condition, aspects)PUT /api/v2/products/{sku}Full product fields — do not include quantity or offers

Price lives on the Offer, not the inventory item. Sending a price field in PUT /api/v2/products/{sku} without an offers array returns 200 OK but does not change the price on eBay. Always update price via PUT /api/v1/listings/{offerId} or via the offers array when updating both together.

Deleting a product also deletes all unpublished offers for that SKU and removes it from any inventory item groups.


Migrating existing listings

If your eBay listings were created outside of the Inventory API — directly on eBay's site or via the old Trading API — they must be migrated before you can manage them via EcartAPI. Once migrated, they become Inventory API items accessible by SKU through all product endpoints.

Eligibility requirements

Before running the migration, verify that each listing meets all of the following conditions. Listings that don't comply will be rejected by eBay:

RequirementDetails
Listing typeMust be Fixed-Price
Listing durationMust be GTC (Good 'til Cancelled)
SKU assignedEvery item must have a seller-defined SKU. For multi-variation listings, each variation must also have its own individual SKU
Business PoliciesFulfillment, payment, and return policies must be applied. Legacy shipping/payment/return fields are not accepted. The payment policy must have immediate payment enabled and PayPal as the only payment method
LocationListing must include a postal/zip code or city. Country is always present in the Trading API and does not need to be added manually

Migration steps

  1. GET /api/v1/products/listings — fetch listings to get their IDs and verify SKUs are assigned → ref
  2. Verify each listing meets all eligibility requirements above
  3. POST /api/v2/products/listings/migrate — convert listings to Inventory API format → ref
  4. PUT /api/v2/products/{sku} — update inventory and price post-migration → ref
POST /api/v2/products/listings/migrate
{
  "listings": {
    "ids": [
      "123456789"
    ]
  }
}

Critical — variant listings and stock: If the listing contains variants, every variant must have at least 1 unit in stock before running the migration. Any variant with zero stock will be silently excluded — the product will be imported without those variants and they will not appear in GET /products or the product group. Variants with zero stock will show "status": "not available" in the offers response but will be absent from the Inventory API entirely.

Migration is a one-time operation. Once a listing is migrated, eBay returns an error if you attempt to migrate it again: "This listing is already migrated". There is no force or re-migrate option.

Recovery: when a variant was missed during migration

If a variant was excluded due to zero stock, you cannot re-run the migration. Add it manually:

1. Create the missing product → POST /api/v1/products (ref) using the same structure as the other variants (same title, images, aspects, weight), only changing the SKU.

2. Update the product group to include the new SKU. Always fetch the current group first — any omitted field will be overwritten:

GET  /api/v1/products/{inventoryItemGroupKey}/variants
POST /api/v1/products/{inventoryItemGroupKey}/variants   ← include new SKU in variantSKUs

3. Create and publish the offer for the missing SKU → POST /api/v1/products/listings (ref), matching the categoryId, listingPolicies, merchantLocationKey, and pricingSummary of the existing offers.

Last resort: If eBay rejects linking the new SKU to the already-migrated group, delete the product from eBay and recreate the entire variant structure from scratch — ensuring all variants have at least 1 unit in stock before migrating.


Product Variants (Groups)

eBay manages variants through Inventory Item Groups — a group that links multiple individual products (SKUs) together as variants, differentiated by aspects (e.g., Color, Size).

Prerequisites before publishing a variant group

  • Payoneer account linked
  • Enrolled in SELLING_POLICY_MANAGEMENT
  • Fulfillment, payment, and returns policies created
  • At least one location with a valid postal code

See Getting Started for the setup flow.

Complete flow: create and publish a variant group

Step 1 — Create variant products in batchref

POST /api/v1/products/batch

One entry per variant SKU. All variants should share the same base product.aspects but have different SKUs and variant-specific aspect values.

Step 2 — Create the Product Groupref

POST /api/v1/products/{inventoryItemGroupKey}/variants
{
  "variant": {
    "inventoryItemGroupKey": "MY-GROUP-001",
    "marketplaceId": "EBAY_US",
    "title": "My Product with Variants",
    "description": "Full product description",
    "aspects": {
      "Color": ["Red", "Blue"],
      "Size": ["S", "M", "L"]
    },
    "imageUrls": ["https://example.com/main-image.jpg"],
    "variantSKUs": ["SKU-RED-S", "SKU-RED-M", "SKU-BLUE-S", "SKU-BLUE-M"]
  }
}

Step 3 — Create offers in batchref

POST /api/v1/products/listings/batch

One offer per variant SKU. Each must include fulfillmentPolicyId, paymentPolicyId, returnPolicyId, and merchantLocationKey.

Step 4 — Publish the groupref

POST /api/v1/products/{inventoryItemGroupKey}/variants/publish

Calls eBay's publish_by_inventory_item_group, making the entire group live simultaneously.

Updating a product group

Always retrieve the current group first → ref. Then resubmit the full updated object — any omitted field will be overwritten or lost.