πŸ“¦Products

πŸ’‘ Bulk upsert products with variants for a tenant


πŸš€ TL;DR - Quick Reference

Endpoint: POST /products/{tenantId}

Use When:

  • Adding new products to catalog

  • Updating prices or inventory

  • Syncing product information

  • Managing product variants (sizes, colors)

Required: ProductId, ProductVariants (can be empty array) Auth: x-replenit-auth-key header Returns: Count of upserted products

Quickest Example:

POST /products/{YOUR_TENANT_ID}
[{
  "ProductId": "P-42",
  "ProductName": "Premium Soap",
  "ProductVariants": []
}]

Jump to Full API Reference ↓


πŸ”— Endpoint

πŸ“‹ Parameters

Parameter
Type
Required
Description

tenantId

GUID

βœ… Yes

The tenant identifier (must exist)

πŸ“¨ Request

  • Body: JSON array of UpsertProductDto objects

  • Content-Type: application/json

βœ… Success Response

  • Status: 200 OK

  • Body: Response envelope with data.count

❌ Error Responses

Status
Description

400 Bad Request

Invalid or missing tenant identifier

404 Not Found

Tenant does not exist in our system

500 Internal Server Error

Unexpected server errors


🎯 Identifier Behavior

The product identifier is determined by your tenant's configuration:

Priority Setting
Identifier Used

productid

Product ID

sku

SKU

πŸ“ Note: Configure your identifier priority in the tenant settings


πŸ“„ Request Schema

UpsertProductDto Fields

Field
Type
Max Length
Required
Description

ProductId

string

100

βœ…

Unique product identifier

ProductName

string

200

❌

Product name/title

Taxonomy

string[]

-

❌

Product categories/tags

IsOfflineExclusive

bool

-

❌

Available offline only

ProductVariants

UpsertProductVariantDto[]

-

βœ…

Product variants (can be empty)

UpsertProductVariantDto Fields

|| Field | Type | Max Length | Required | Description | ||| --------------- | -------- | ---------- | -------- | --------------------------------- | ||| VariantId | string | 100 | βœ… | Unique variant identifier | ||| Sku | string | 200 | βœ… | Variant SKU | || Name | string | 600 | ❌ | Variant name | | Image | string | 2000 | ❌ | Image URL | | Size | string | 50 | ❌ | Size (e.g., "1l", "500ml") | | Stock | int | - | ❌ | Available inventory | | OriginalPrice | double | - | ❌ | Regular price | | SalePrice | double | - | ❌ | Discounted price | | Currency | string | 3 | ❌ | Currency code (ISO 4217) | | IsAvailable | bool | - | ❌ | Availability status | | Language | string | 10 | ❌ | Language code (IETF BCP 47) | | BrandName | string | 200 | ❌ | Brand name | | Url | string | 2000 | ❌ | Product page URL |

πŸ’‘ Note: Size is automatically parsed into SizeNumeric and SizeMetric on the server


πŸ—‘οΈ DELETE Endpoints

πŸ”— Delete Product

πŸ“‹ Parameters

Parameter
Type
Required
Description

tenantId

GUID

βœ… Yes

The tenant identifier

productId

string

βœ… Yes

The product ID to delete

βœ… Success Response

  • Status: 200 OK

  • Body: Response envelope with deleted product ID

πŸ”— Delete Product Variant

πŸ“‹ Parameters

Parameter
Type
Required
Description

tenantId

GUID

βœ… Yes

The tenant identifier

variantId

string

βœ… Yes

The variant ID to delete

βœ… Success Response

  • Status: 200 OK

  • Body: Response envelope with deleted variant ID

❌ Error Responses

Delete Product:

|| Status | Scenario | Example Response | || ------ | -------- | ---------------- | || 400 | Missing product ID | {"success": false, "message": "Product ID is required.", "data": {}} | || 404 | Tenant not found | {"success": false, "message": "Tenant not found.", "data": {}} | || 404 | Product not found | {"success": false, "message": "Product not found.", "data": {}} | || 500 | Storage failure | {"success": false, "message": "Failed to delete product.", "data": {}} |

Delete Variant:

|| Status | Scenario | Example Response | || ------ | -------- | ---------------- | || 400 | Missing variant ID | {"success": false, "message": "Variant ID is required.", "data": {}} | || 404 | Tenant not found | {"success": false, "message": "Tenant not found.", "data": {}} | || 404 | Variant not found | {"success": false, "message": "Variant not found.", "data": {}} | || 500 | Storage failure | {"success": false, "message": "Failed to delete variant.", "data": {}} |

Note: The tenant validation is performed automatically by middleware before reaching the endpoint. If tenant doesn't exist, you'll receive a 404 error immediately.

πŸš€ DELETE Examples

Delete Product - cURL

Delete Variant - Python

Delete Product - Node.js


πŸ’‘ Real-World Use Cases

Use Case 1: New Product Launch

Scenario: Launching a new product with multiple variants (sizes/colors)

What to send:

What happens:

  1. βœ… Product added to catalog

  2. 🎯 Can be used in product recommendation campaigns

  3. πŸ“Š Inventory tracked per variant


Use Case 2: Price Update (Sale)

Scenario: Running a limited-time sale on specific products

What to send:

What happens:

  1. βœ… Sale price updated

  2. 🎯 Can trigger "price drop" alerts to interested customers

  3. πŸ“Š Campaign ROI tracked with new pricing


Use Case 3: Out of Stock

Scenario: Product sold out, update availability

What to send:

What happens:

  1. βœ… Product marked as unavailable

  2. 🚫 Removed from recommendation engine

  3. πŸ“§ Can trigger "back in stock" notification setup


Use Case 4: Multi-Pack Product

Scenario: Product sold in packs (e.g., "4 x 500ml")

What to send:

Smart parsing: System automatically calculates:

  • SizeNumeric: 2.0 (litres total)

  • SizeMetric: "l"


πŸ“ Complete Example Request (All Fields)

πŸ“ Minimal Example Request (Required Fields Only)

πŸ“ Example with Excluded Product

πŸš€ cURL Example

🐍 Python Example

🟒 Node.js Example


πŸ“Š Response Examples

βœ… Success Response (200)

❌ Validation Error (400) - Missing Required Fields

πŸ“– What this means:

  • Your first product (index [0]) is missing required fields

  • ProductId is required for the product

  • The first variant (index [0]) is missing VariantId and Sku

βœ… How to fix:

πŸ’‘ Common causes:

  • Forgot to include required fields

  • Typo in field names (they are case-sensitive)

  • Sending empty object {}

❌ Validation Error (400) - String Length Exceeded

πŸ“– What this means:

  • One or more fields exceed their maximum allowed length

  • ProductId: maximum 100 characters

  • Image URLs: maximum 2000 characters

  • Currency: maximum 3 characters

βœ… How to fix:

  • Shorten the field values to meet length limits

  • For ProductId: use shorter IDs or codes

  • For Image: use URL shorteners or CDN paths

  • For Currency: use standard 3-letter codes (USD, EUR, etc.)

πŸ’‘ Field length limits: || Field | Max Length | |||-------|------------| || ProductId | 100 | || VariantId | 100 | || Sku | 200 | || Size, Color | 50 | || ProductName, BrandName | 200 | || Variant Name | 600 | || Image, Url | 2000 | || Currency | 3 | || Language | 10 |

❌ Not Found (404)

❌ Internal Server Error (500)


πŸ’‘ Best Practices

  1. Variant Management: Always include at least one variant, even for simple products

  2. Image URLs: Use HTTPS URLs for product images (max 2000 characters)

  3. Size Format: Use standard size notations (e.g., "1l", "500ml", "XL")

  4. Pricing: Ensure SalePrice is less than or equal to OriginalPrice

  5. Taxonomy: Use consistent category naming across products (hierarchical structure recommended)

  6. Stock Levels: Keep stock information updated to prevent overselling

  7. Language Format: Use IETF language tags (BCP 47):

  8. Currency Format: Use ISO 4217 currency codes:

  9. Batch Size: Recommended batch size is 50-100 products per request

  10. Product Identifiers: Ensure consistency between ProductId and SKU across your systems


🎨 Size Parsing Examples

Input
SizeNumeric
SizeMetric

"1l"

1

"l"

"500ml"

500

"ml"

"2.5kg"

2.5

"kg"

"XL"

null

"XL"


Last updated