---
title: "Create Product"
method: POST
path: "/products"
tags: ["Products"]
---

# Create Product

`POST /products`

Creates a new product in draft status. The product will be synced to Shopify when activated. SKUs must be unique within your brand.

## Request body

- CreateProductRequest
  - `title` string, required — Product name
  - `body_html` string — Product description (HTML allowed)
  - `vendor` string — Brand/vendor name
  - `product_type` string — Product category
  - `tags` string — Comma-separated tags
  - `handle` string — URL slug (auto-generated if not provided)
  - `template_suffix` string — Template suffix
  - `published_scope` string — Published scope
  - `variants` ProductVariant[], required — At least one variant required
    - `title` string, required — Variant name
    - `sku` string, required — Unique SKU per brand (alphanumeric, hyphens, underscores). Different brands can use the same SKU.
    - `price` number, required — Price in brand currency
    - `compare_at_price` number — Compare at price
    - `inventory_quantity` integer, required — Stock quantity
    - `weight` number — Weight in specified unit
    - `weight_unit` string — Weight unit
    - `barcode` string — Product barcode
    - `requires_shipping` boolean — Requires shipping
    - `taxable` boolean — Is taxable
  - `images` ProductImage[] — Product images
    - `src` string, uri, required — Image URL (must be valid URL)
    - `alt` string — Alt text for accessibility
    - `position` integer — Display order

## Response `201`

Product created successfully

- ProductResponse — Response for creating a single product
  - `error` ApiError — Structured error object
    - `field` string, required — Field that caused the error
    - `message` string, required — Human-readable error message
  - `product` Product
    - `id` string — Unique product identifier (format: product_XXXXXXXXXXXXXXXX)
    - `title` string — Product name
    - `description` string — Product description
    - `handle` string — URL slug
    - `status` string — Product status
    - `variants` ProductVariantResponse[]
      - `id` string — Variant ID
      - `title` string — Variant name
      - `sku` string — Variant SKU
      - `price` number — Price in SAR (converted from brand currency)
      - `compare_at_price` number — Compare at price in SAR
      - `inventory_quantity` integer — Current stock quantity
      - `weight` number — Variant weight
      - `weight_unit` string — Weight unit
      - `requires_shipping` boolean — Requires shipping
      - `taxable` boolean — Is taxable
      - `barcode` string — Product barcode
      - `option1` string — Option 1 value
      - `option2` string — Option 2 value
      - `option3` string — Option 3 value
    - `images` ProductImageResponse[]
      - `id` string — Image ID
      - `src` string — Image URL
      - `alt` string — Alt text
      - `position` integer — Display order
    - `product_type` string — Product category
    - `vendor` string — Brand/vendor name
    - `tags` string — Comma-separated tags
    - `created_at` string, date-time — Creation timestamp
    - `updated_at` string, date-time — Last update timestamp
    - `synced` boolean — Whether product is synced to Shopify
    - `last_synced_at` string, date-time — Last sync timestamp
  - `message` string — Success or error message

## Other responses

- `400` — Validation errors or duplicate SKUs
- `401` — Unauthorized - Invalid or missing API key
- `403` — Forbidden - Access denied
- `429` — Rate limit exceeded
- `500` — Internal server error

---

[API](https://skmtc.net/maisonsafqa/apis/maison-safqa-brand-developer-api.md) · [All operations](https://skmtc.net/maisonsafqa/apis/maison-safqa-brand-developer-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/maisonsafqa/maison-safqa-brand-developer-api/revisions/5d94551e95c5/schema)
