Products
Bulk upsert product catalog records for a tenant
Overview
The Products endpoint supports bulk creation and updates of product catalog records for a tenant.
Each request processes an array of product objects and applies upsert semantics based on the tenant’s product identifier configuration.
This endpoint is used to synchronize product catalogs, variants, pricing, attributes, and availability from upstream systems into Replenit. Product data is a prerequisite for accurate order ingestion, decisioning, recommendations, and downstream activation.
Quick Reference
Endpoint
| POST /products/{tenantId} |
Usage
- Create new products and variants
- Update product attributes and pricing
- Synchronize product catalog from external systems
- Maintain SKU and variant consistency
- Enable accurate linking for orders, replenishment, and recommendations
Identifiers
- Product matching is determined by tenant configuration
- Common identifiers include ProductId or Sku
- Identifier behavior is tenant-specific
Authentication
- x-replenit-auth-key header required
Response
- Returns the number of processed records
Endpoint
| POST /products/{tenantId} |
Parameters
| Parameter | Type | Required | Description |
| tenantId | GUID | Yes | Tenant identifier |
Request
- Body: JSON array of UpsertProductDto objects
- Content-Type: application/json
Success Response
- Status: 200 OK
- Body: Response envelope containing data.count
Error Responses
| Status | Description |
| 400 | Invalid request payload |
| 404 | Tenant not found |
| 500 | Internal server error |
Identifier Behavior
Product matching is determined by the tenant’s product identifier priority configuration.
Identifier Priority
| Priority Setting | Identifier Used | Description |
| productid | ProductId | External product identifier |
| sku | Sku | SKU-based identification |
Matching Rules
- If the configured identifier exists, the product record is updated
- If the configured identifier does not exist, a new product record is created
- Secondary identifiers may be stored but are not used for matching
Example
| { “ProductId”: “P-100”, “Sku”: “SKU-100”, “Name”: “Premium Shampoo” } |
Identifier priority can be viewed or modified in the tenant configuration within the Replenit platform.
Product identifiers used in Replenit must be consistent with identifiers used in upstream and downstream systems, including:
- Order ingestion
- Recommendation logic
- Analytics and reporting
- Marketing and activation platforms
When ProductId is used as the primary identifier, the same identifier must be used across order items and downstream systems.
When Sku is used as the primary identifier, SKUs must be globally unique across variants.
Inconsistent product identifiers may result in unlinked orders, incorrect attribution, or degraded decision quality.
Product Identifier Configuration
Product matching and resolution in Replenit is controlled by the tenant-level Product Identifier Selection.
This configuration defines which field is used as the primary identifier when ingesting and resolving products across the platform.
Where to Configure
The product identifier can be viewed or modified in the Replenit platform under:
Replenit Dashboard → Settings → Tenant Settings → Product Identifier Selection
This setting requires Admin access.
If you do not have access, contact your platform administrator or your Replenit Customer Success Manager (CSM).
Supported Identifier Modes
| Configuration | Identifier Used | Description |
| productid | ProductId | Uses the external product identifier provided by your system |
| sku | Sku | Uses SKU as the primary product identifier |
Behavior During Ingestion
- The configured identifier is used to match incoming products to existing records
- If a matching product exists, it is updated
- If no matching product exists, a new product is created
- Secondary identifiers may be stored but are not used for matching
Impact on APIs
This configuration affects:
- Products API
- Product upsert and deletion behavior
- Orders API
- Resolution of OrderItems against the product catalog
- Decisioning
- Accurate product attribution for downstream actions
Operational Requirement
Ensure that the identifier used in API payloads (ProductId or Sku) is:
- Consistently generated in upstream systems
- Stable over time
- Aligned with the configured Product Identifier Selection
Misalignment between payload identifiers and tenant configuration may result in unresolved or duplicated products.
Request Schema
UpsertProductDTO
| Field | Type | Max Length | Required | Description |
| ProductId | string | 100 | Conditional | External product identifier |
| Sku | string | 100 | Conditional | SKU identifier |
| Name | string | 255 | Yes | Product name |
| Description | string | – | No | Product description |
| Brand | string | 100 | No | Brand name |
| Category | string | 255 | No | Product category |
| ImageUrl | string | – | No | Primary product image |
| IsActive | boolean | – | No | Product availability flag |
| Currency | string | 3 | No | ISO 4217 currency code |
| Price | number | – | No | Current selling price |
| OriginalPrice | number | – | No | Pre-discount price |
| Variants | VariantDto[] | – | No | Product variants |
VariantDTO
| Field | Type | Max Length | Required | Description |
| VariantId | string | 100 | No | External variant identifier |
| Sku | string | 100 | Yes | Variant SKU |
| Price | number | – | No | Variant price |
| OriginalPrice | number | – | No | Variant original price |
| Size | string | 50 | No | Size attribute |
| Color | string | 50 | No | Color attribute |
| IsActive | boolean | – | No | Variant availability |
Examples
Minimal Product
| [ { “ProductId”: “P-001”, “Name”: “Basic Product” } ] |
Standard Product
| [ { “ProductId”: “P-100”, “Sku”: “SKU-100”, “Name”: “Premium Shampoo”, “Brand”: “Acme”, “Category”: “Hair Care”, “Currency”: “EUR”, “Price”: 19.99, “OriginalPrice”: 24.99, “IsActive”: true } ] |
Product with Variants
| [ { “ProductId”: “P-200”, “Name”: “Conditioner”, “Brand”: “Acme”, “Category”: “Hair Care”, “Variants”: [ { “VariantId”: “V-200-250”, “Sku”: “SKU-200-250ML”, “Price”: 14.99, “Size”: “250ml”, “IsActive”: true }, { “VariantId”: “V-200-500”, “Sku”: “SKU-200-500ML”, “Price”: 24.99, “Size”: “500ml”, “IsActive”: true } ] } ] |
cURL Example
| curl -X POST “https://api.replen.it/products/{tenantId}” \ -H “Content-Type: application/json” \ -H “x-replenit-auth-key: YOUR_BASE64_ACCESS_KEY” \ -d @products.json |
Python Example
| import requests url = “https://api.replen.it/products/{tenantId}” headers = { “Content-Type”: “application/json”, “x-replenit-auth-key”: “YOUR_BASE64_ACCESS_KEY” } products = [ { “ProductId”: “P-100”, “Name”: “Premium Shampoo”, “Price”: 19.99, “Currency”: “EUR” } ] response = requests.post(url, headers=headers, json=products) print(response.json()) |
Node.js Example
| const axios = require(‘axios’); axios.post( ‘https://api.replen.it/products/{tenantId}’, [ { ProductId: ‘P-100’, Name: ‘Premium Shampoo’, Price: 19.99, Currency: ‘EUR’ } ], { headers: { ‘x-replenit-auth-key’: ‘YOUR_BASE64_ACCESS_KEY’ } } ); |
Response Examples
Success
| { “success”: true, “message”: “Products saved.”, “data”: { “count”: 5, “processedAt”: “2024-12-22T14:05:51Z” } } |
Validation Error – Missing Identifier
| { “status”: 400, “errors”: { “”: [ “At least one of the following properties must have a value: ProductId, Sku” ] } } |
Related Documentation
Authentication
Replenit Ingestion API | Authentacition
Customers API
Replenit Ingestion API | Customers
Orders API
Replenit Ingestion API | Orders
Error Responses
Replenit Ingestion API | Error Responses
Rate Limits
Replenit Ingestion API | Rate Limits

