Product Data Model
Understand the product entity hierarchy and the required creation order
Before managing products via the API, it is essential to understand how entities relate to each other and in what order they must be created.
Entity Hierarchy
flowchart TD
CAT["<b>Catalog</b><br/><i>read-only</i>"]
PROD["<b>Product</b><br/>name, description, status"]
OPT["<b>Option</b><br/>e.g. Size, Color"]
VAL["<b>OptionValue</b><br/>e.g. S, M, L"]
VAR["<b>Variant</b><br/>price, stock, status"]
MED["<b>Media</b><br/>images"]
TAG["<b>Category</b><br/>global label"]
CAT -->|contains| PROD
PROD -->|has| OPT
OPT -->|has| VAL
PROD -->|has| VAR
VAR -->|has| MED
TAG -.->|"assigned via tag_ids"| PROD
style CAT fill:#f3e8ff,stroke:#7c3aed,color:#1e1e1e
style PROD fill:#ede9fe,stroke:#7c3aed,color:#1e1e1e
style OPT fill:#e0f2fe,stroke:#0284c7,color:#1e1e1e
style VAL fill:#e0f2fe,stroke:#0284c7,color:#1e1e1e
style VAR fill:#dcfce7,stroke:#16a34a,color:#1e1e1e
style MED fill:#dcfce7,stroke:#16a34a,color:#1e1e1e
style TAG fill:#fef3c7,stroke:#d97706,color:#1e1e1e| Entity | Description |
|---|---|
| Catalog | Main container for products. Created automatically with the merchant. The API only allows querying it with GET /v1/catalogs. |
| Product | Catalog item with a name, description, and status. |
| Category | Global label to organize products (e.g. "Ropa", "Electrónica"). Assigned to the product via tag_ids. |
| Option | Variation group (e.g. "Size", "Color"). |
| OptionValue | Value within an option (e.g. "S", "M", "L" for Size). |
| Variant | Specific combination of option values with its own price (e.g. "Polo Negro - Talla M"). |
| Media | Image or file associated with a variant, not directly with the product. |
Required Creation Order
sequenceDiagram
participant M as Merchant
participant API as Business API
M->>API: GET /v1/catalogs
API-->>M: catalog_id
M->>API: POST /v1/products
API-->>M: product_id
M->>API: POST .../options
API-->>M: option_value_ids
M->>API: POST .../variants (with option_values)
API-->>M: variant_id
M->>API: POST .../media
M->>API: POST .../categories- Get catalog —
GET /v1/catalogs→ yourcatalog_id - Create product —
POST /v1/productswithcatalog_id - Create options —
POST /v1/products/{id}/options→ save the value IDs - Create variants —
POST /v1/products/{id}/variantswithoption_values - Add media —
POST /v1/products/{product_id}/variants/{variant_id}/media - Assign categories —
POST /v1/products/{id}/categorieswithtag_ids
Categories (POST /v1/categories) are global and can be created at any time — they don't depend on the product.
Key Rules
Catalogs are read-only. They are created automatically when the merchant is registered. The API only allows querying them with GET /v1/catalogs.
Options MUST exist before creating variants. The option_values field is required and needs at least 1 ID. If you send option_values: [] or omit the field, you will receive a 422 error.
Categories are global. Creating a category does not associate it with any product. You must explicitly assign it with POST /v1/products/{product_id}/categories using tag_ids (array of IDs).
Images belong to variants, not to products. Each variant can have its own images.
Why are options required before variants?
Internally, each product needs at least one option with values to function correctly in the catalog. This applies even for simple products that have no real variations (no size, color, etc.).
Product with variations (e.g. "Polo Negro"):
- Option: "Talla" → Values: "S", "M", "L"
- 3 variants, one per size
Simple product (e.g. "Dona Glaseada"):
- Option: "Presentación" → Value: "Estándar"
- 1 variant with that value
The option name is free-form. Examples: "Talla", "Color", "Presentación".
Statuses
| Entity | Possible statuses |
|---|---|
| Product | published |
| Variant | available (available), not_available (not available) |
