Skip to content
Catalog

Variants and prices

Create products with options and variants, and change their prices with the Admin API.

Create the "Polo de algodón" with Color and Talla, one variant per combination, and change its prices one by one or in bulk.

Requirements

  • An Admin token in ECOMIQ_TOKEN. See Quickstart.
  • The catalog:create, catalog:update, and catalog:delete permissions, depending on what you do.

Create the product

Declare the options in options and one variant per combination in variants.

  • Each variant sets its value for each option in options, by name or by key.
  • Options that do not exist in the store are created.
  • The product's price, compareAtPrice, and costPrice apply to variants that do not send their own.
  • With several variants, mark exactly one with isDefault: true.
product.json
{
  "name": "Polo de algodón",
  "description": "Polo de algodón pima para uso diario.",
  "status": "draft",
  "price": 89,
  "compareAtPrice": 99,
  "costPrice": 45,
  "options": [
    { "name": "Color", "key": "color", "values": ["Azul", "Negro"] },
    { "name": "Talla", "key": "talla", "values": ["S", "M", "L"] }
  ],
  "variants": [
    {
      "name": "Azul / S",
      "sku": "POL-001-AZ-S",
      "options": { "Color": "Azul", "Talla": "S" }
    },
    {
      "name": "Azul / M",
      "sku": "POL-001-AZ-M",
      "options": { "Color": "Azul", "Talla": "M" },
      "isDefault": true
    },
    {
      "name": "Negro / S",
      "sku": "POL-001-NG-S",
      "options": { "Color": "Negro", "Talla": "S" }
    },
    {
      "name": "Negro / M",
      "sku": "POL-001-NG-M",
      "options": { "Color": "Negro", "Talla": "M" }
    }
  ]
}
curl -X POST https://api.ecomiq.pe/api/v1/catalog/products \
  -H "Authorization: Bearer $ECOMIQ_TOKEN" \
  -H "Content-Type: application/json" \
  --data @product.json
Response (excerpt)
{
  "id": "7204558912004325302",
  "name": "Polo de algodón",
  "slug": "polo-de-algodon",
  "status": "draft",
  "variants": [
    {
      "id": "7204558912004325377",
      "name": "Azul / M",
      "sku": "POL-001-AZ-M",
      "isDefault": true,
      "price": 89,
      "compareAtPrice": 99,
      "costPrice": 45,
      "options": [
        { "name": "Color", "key": "color", "value": "Azul" },
        { "name": "Talla", "key": "talla", "value": "M" }
      ],
      "status": "active"
    }
  ]
}

The API responds 201 with the product and its variants. Store each variant id next to its SKU; IDs are strings.

The product stays a draft. To activate it, send { "status": "active" } to PATCH /v1/catalog/products/{productId}.

Add a variant

Add the blue L size. If you omit price or compareAtPrice, the product's values apply. costPrice is not inherited: send it if you use it.

curl -X POST https://api.ecomiq.pe/api/v1/catalog/products/7204558912004325302/variants \
  -H "Authorization: Bearer $ECOMIQ_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Azul / L",
    "sku": "POL-001-AZ-L",
    "price": 89,
    "compareAtPrice": 99,
    "costPrice": 45,
    "options": { "Color": "Azul", "Talla": "L" }
  }'
Response (excerpt)
{
  "id": "7204558912004325381",
  "productId": "7204558912004325302",
  "name": "Azul / L",
  "sku": "POL-001-AZ-L",
  "status": "active",
  "price": 89,
  "compareAtPrice": 99,
  "costPrice": 45,
  "currency": "PEN",
  "options": [
    { "name": "Color", "key": "color", "value": "Azul" },
    { "name": "Talla", "key": "talla", "value": "L" }
  ]
}

The API responds 201. A repeated SKU, or an option combination that another variant already has, responds 409.

Change the price of a variant

PATCH /v1/catalog/variants/{variantId} changes only the fields you send. Here, Azul / M moves to 85 and its cost to 42.

curl -X PATCH https://api.ecomiq.pe/api/v1/catalog/variants/7204558912004325377 \
  -H "Authorization: Bearer $ECOMIQ_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "price": 85, "compareAtPrice": 99, "costPrice": 42 }'

The 200 response returns the updated variant.

  • If compareAtPrice isn't greater than price, it is removed.
  • null in compareAtPrice or costPrice removes it.
  • Every change to price or compareAtPrice is saved in the price history.
  • The product price is the price of its cheapest active variant.

The same route also changes name, sku, barcode, and status.

To edit variants through PATCH /v1/catalog/products/{productId}, see Products: there null doesn't remove prices, and you use clearCompareAtPrice and clearCostPrice.

Change prices in bulk

POST /v1/catalog/products/batch/prices takes up to 100 rows in items. Each row picks its target with targetKind:

  • product: every variant of the product, by its id.
  • variant: one variant, by its id.
  • sku: one variant, by SKU, case-insensitive.

This example puts the three blue sizes on sale.

curl -X POST https://api.ecomiq.pe/api/v1/catalog/products/batch/prices \
  -H "Authorization: Bearer $ECOMIQ_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "promotionStart",
    "items": [
      { "targetKind": "sku", "target": "POL-001-AZ-S", "price": 79, "compareAtPrice": 99 },
      { "targetKind": "sku", "target": "POL-001-AZ-M", "price": 79, "compareAtPrice": 99 },
      { "targetKind": "sku", "target": "POL-001-AZ-L", "price": 79, "compareAtPrice": 99 }
    ]
  }'
Response
{
  "results": [
    { "index": 0, "id": null, "status": "updated", "errors": [] },
    { "index": 1, "id": null, "status": "updated", "errors": [] },
    { "index": 2, "id": null, "status": "updated", "errors": [] }
  ]
}

200 returns results[] in the order received. Check the failed rows: the others still apply. With targetKind: sku, id is null; use index to find the row.

For more rows, send filters instead of items, with price, compareAtPrice, or clearCompareAtPrice. It returns 202 with an operation.

  • Omit price to keep the current price.
  • clearCompareAtPrice: true removes the compare-at price.
  • reason is saved in the history; it defaults to bulkEdit.
  • costPrice can't be changed in bulk: use PATCH on each variant.

Delete a variant

Delete Negro / S. The API responds 204, with no body.

curl -X DELETE https://api.ecomiq.pe/api/v1/catalog/variants/7204558912004325379 \
  -H "Authorization: Bearer $ECOMIQ_TOKEN"

To hide a variant without deleting it, send { "status": "inactive" } with PATCH. Only active variants count toward the product price and stock.

Create a price list

A price list sets the price of specific variants. The cart uses that price while the list is active and valid.

  • items sets a unitPrice per variant.
  • breaks changes the price from minQuantity units, with a minimum of 2.
  • validFrom and validTo limit the validity window.
  • With customerId, the list applies only to that customer.
curl -X POST https://api.ecomiq.pe/api/v1/catalog/price-lists \
  -H "Authorization: Bearer $ECOMIQ_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Mayoristas",
    "currency": "PEN",
    "isActive": true,
    "priority": 1,
    "scope": "product",
    "productId": "7204558912004325302",
    "items": [
      {
        "variantId": "7204558912004325377",
        "unitPrice": 70,
        "breaks": [{ "minQuantity": 12, "unitPrice": 65 }]
      },
      { "variantId": "7204558912004325380", "unitPrice": 70 }
    ]
  }'
Response
{
  "id": "7204558912004321823"
}

When several lists cover a variant, the customer's list wins, then the highest priority. To change a list, send it in full to PUT /v1/catalog/price-lists/{priceListId}. It replaces the content and responds 204.

Errors

StatuscodeWhat to do
400Common.ValidationCheck errors: a field is missing or has the wrong format.
400Product.TooManyVariantsA product allows up to 2048 variants.
404Variant.NotFoundThe variant doesn't exist in the store or was deleted.
409Variant.AlreadyExistsAnother variant already uses that SKU: change it.
409Variant.OptionsTakenAnother variant of the product has that combination.
409Variant.ChangedThe variant changed since you read it: read it again.

Next steps

Last updated:

On this page