# Product Catalog API V3 - Developer Guide

- **Applies to:** `/api/v3/product`
- **API Version:** V3
- **Resource:** Product Catalog
- **Operations:** Create, Fetch, Update, Partial Update, Delete
- **Supports:** Single-product and bulk operations for retrieval and deletion


## 1. Overview

### 1.1 The Product Object

A product catalog is a collection of products on which Reviews appear on your website. You can use product catalogs to organize products into catalogs and categories, apply product-specific configurations, and customize product review experiences.

The Product Catalog API allows you to create, retrieve, update, partially update, and delete product records. Product records can contain:

- Source information
- Catalog assignments
- Category assignments
- Product attributes
- Pricing information
- Media attachments
- Workflow properties
- Product lifecycle status


### 1.2 Product Data Model

A product consists of several logical components:

```text
Product
├─ id
├─ source
│  ├─ sourceType
│  ├─ sourceProductId
│  ├─ sourceId
│  └─ channelType
├─ catalogIds[]
├─ categoryIds[]
├─ title
├─ description
├─ link
├─ price
├─ specification
├─ subSpecification
├─ attachment
├─ workflow
└─ delisted
```

The source information identifies where the product originated. Catalog and category mappings determine how the product is organized within Sprinklr. Pricing, specifications, media attachments, and workflow metadata enrich the product record.

### 1.3 Product Identification Model

Products are identified by a unique product identifier.

| Identifier | Purpose |
|  --- | --- |
| `id` | Internal product identifier |
| `sourceProductId` | Product identifier in the source system |
| `productId` | API query parameter used for retrieval, updates, and deletion |


Source systems can also provide additional identifiers such as SKU, GTIN, MPN, retailer ID, and group ID.

### Supported Operations

| Operation | Method | Endpoint |
|  --- | --- | --- |
| Create a product | POST | `/api/v3/product` |
| Fetch products | GET | `/api/v3/product?productId={productIds}` |
| Replace a product | PUT | `/api/v3/product?productId={productId}` |
| Update product fields | PATCH | `/api/v3/product?productId={productId}` |
| Delete products | DELETE | `/api/v3/product?productId={productIds}` |


## 2. Base URLs and Environments

### Base URL

```text
https://api3.sprinklr.com/{env}/api/v3/product
```

Replace `{env}` with the environment identifier assigned to your Sprinklr account. The default documented value is `prod`.

## 3. Authentication and Common Headers

All operations require an access token and API key.

### Required Headers

| Header | Value | Purpose |
|  --- | --- | --- |
| `Authorization` | `Bearer {Access Token}` | Authenticates the user |
| `Key` | `{API Key}` | Authenticates the application |
| `Accept` | `application/json` | Requests a JSON response |
| `Content-Type` | `application/json` | Identifies the request body as JSON |


### Example

```http
Authorization: Bearer {Access Token}
Key: {API Key}
Accept: application/json
Content-Type: application/json
```

### 3.1 Permissions

The source documentation does not specify the permissions required to use this API.

## 4. Write Operations

### 4.1 Create a Product

Creates a product and associates it with one or more product catalogs. A successful request returns the created product record.

#### Endpoint

```http
POST https://api3.sprinklr.com/{env}/api/v3/product
```

#### Request Body

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `source` | Object | Yes | Source details for the product |
| `catalogIds` | Array of Strings | No | Identifiers of catalogs that contain the product |
| `categoryIds` | Array of Strings | No | Identifiers of categories assigned to the product |
| `title` | String | No | Product title |
| `description` | String | No | Product description |
| `link` | String | No | Product URL |
| `price` | Object | No | Pricing information |
| `standardPrice` | Number | No | Standard product price |
| `sellingPrice` | Number | No | Selling price |
| `currency` | String | No | Currency for the standard or selling price |
| `availability` | String | No | Product availability status |
| `inventory` | Integer | No | Available inventory quantity |
| `gtin` | String | No | Global Trade Item Number |
| `mpn` | String | No | Manufacturer part number |
| `brand` | String | No | Brand name |
| `retailerId` | String | No | Retailer-specific identifier |
| `sku` | String | No | Stock keeping unit |
| `groupId` | String | No | Identifier used to group product variants |
| `specification` | Map of String to String | No | Attributes that distinguish a variant from other products in the same group |
| `subSpecification` | Map of String to Object | No | Additional attributes associated with a specification attribute |
| `attachment` | Object | No | Media attached to the product |
| `workflow` | Object | No | Workflow properties associated with the product |
| `delisted` | Boolean | No | Indicates whether the product is delisted |


#### Source Object

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `sourceType` | String | Yes | Type of product source |
| `sourceProductId` | String | Yes | Unique product identifier in the source system |
| `sourceId` | String | No | Identifier of the source account or system |
| `channelType` | String | Yes | Channel associated with the product source |


#### Price Object

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `value` | Number | Yes, when `price` is included | Product price amount |
| `currency` | String | No | Currency associated with the price amount |


#### Attachment Object

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `type` | String | Yes, when `attachment` is included | Attachment type |
| `url` | String | No | URL of the attached media |
| `alternateText` | String | No | Alternative text for the attachment |


#### Workflow Object

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `assignment` | Object | No | Assignment details associated with the product |
| `modifiedTime` | Integer | No | Workflow modification time in epoch milliseconds |
| `customProperties` | Map of String to Array of Strings | No | Custom properties associated with the product |
| `queues` | Array of Objects | No | Queue information associated with the product workflow |
| `spaceWorkflows` | Array of Objects | No | Workspace-level workflows associated with the product |


#### Request

```bash
curl --location 'https://api3.sprinklr.com/{env}/api/v3/product' \
  --header 'Authorization: Bearer {Access Token}' \
  --header 'Key: {API Key}' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "source": {
      "sourceType": "ACCOUNT",
      "sourceProductId": "SKU-200897",
      "sourceId": "{sourceId}",
      "channelType": "SOURCE_AGNOSTIC"
    },
    "catalogIds": ["{catalogId}"],
    "categoryIds": ["FRAGRANCE"],
    "title": "Sample Product",
    "description": "Sample product description",
    "link": "https://example.com/products/sku-200897",
    "price": {
      "value": 78.00,
      "currency": "USD"
    },
    "groupId": "20097",
    "attachment": {
      "type": "IMAGE",
      "url": "https://example.com/images/product.jpg"
    },
    "workflow": {
      "customProperties": {
        "{customFieldId}": ["New"]
      }
    }
  }'
```

#### Response

A successful request returns `201 Created` and the newly created product.

```json
{
  "data": {
    "id": "6a9968815d82d94f23d44994",
    "source": {
      "sourceType": "ACCOUNT",
      "sourceId": "{sourceId}",
      "sourceProductId": "SKU-200897",
      "channelType": "SOURCE_AGNOSTIC"
    },
    "catalogIds": ["{catalogId}"],
    "categoryIds": ["FRAGRANCE"],
    "title": "Sample Product",
    "description": "Sample product description",
    "link": "https://example.com/products/sku-200897",
    "price": {
      "value": 78.0,
      "currency": "USD"
    },
    "groupId": "20097",
    "attachment": {
      "url": "https://example.com/images/product.jpg",
      "encryptedUrl": "enc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "type": "IMAGE"
    },
    "workflow": {
      "customProperties": {
        "{customFieldId}": ["New"]
      }
    },
    "delisted": false
  },
  "errors": []
}
```

### 4.2 Update a Product

Replaces an existing product with the product definition supplied in the request body. Include all product attributes that you want to retain.

#### Endpoint

```http
PUT https://api3.sprinklr.com/{env}/api/v3/product?productId={productId}
```

#### Query Parameters

| Parameter | Type | Required | Description |
|  --- | --- | --- | --- |
| `productId` | String | Yes | Identifier of the product to update |


#### Request

```bash
curl --location --request PUT \
  'https://api3.sprinklr.com/{env}/api/v3/product?productId={productId}' \
  --header 'Authorization: Bearer {Access Token}' \
  --header 'Key: {API Key}' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{
    "source": {
      "sourceType": "ACCOUNT",
      "sourceProductId": "{sourceProductId}",
      "sourceId": "{sourceId}",
      "channelType": "SOURCE_AGNOSTIC"
    },
    "catalogIds": ["{catalogId}"],
    "categoryIds": ["{categoryId}"],
    "title": "Updated product title",
    "description": "Updated product description",
    "link": "https://example.com/products/{sourceProductId}",
    "price": {
      "value": 99.0
    },
    "specification": {
      "{attributeName}": "{attributeValue}"
    },
    "groupId": "{groupId}",
    "attachment": {
      "type": "IMAGE",
      "url": "https://example.com/images/product.jpg"
    },
    "workflow": {
      "customProperties": {
        "{customFieldId}": ["{customFieldValue}"]
      }
    },
    "delisted": false
  }'
```

#### Response

```http
HTTP/1.1 204 No Content
```

The response body is empty.

### 4.3 Update Product Fields

Updates selected fields in an existing product. Fields not included in the request are preserved.

#### Endpoint

```http
PATCH https://api3.sprinklr.com/{env}/api/v3/product?productId={productId}
```

#### Query Parameters

| Parameter | Type | Required | Description |
|  --- | --- | --- | --- |
| `productId` | String | Yes | Identifier of the product to update |


#### Supported Request Fields

| Field | Type | Description |
|  --- | --- | --- |
| `title` | String | Product title |
| `description` | String | Product description |
| `link` | String | Product URL |
| `standardPrice` | Number | Standard product price |
| `sellingPrice` | Number | Selling price |
| `currency` | String | Product price currency |
| `availability` | String | Product availability status |
| `inventory` | Integer | Available inventory quantity |
| `gtin` | String | Global Trade Item Number |
| `mpn` | String | Manufacturer part number |
| `brand` | String | Brand name |
| `retailerId` | String | Retailer-specific identifier |
| `sku` | String | Stock keeping unit |
| `groupId` | String | Identifier used to group product variants |
| `specification` | Map of String to String | Attributes that distinguish a product variant |
| `subSpecification` | Map of String to Object | Additional specification attributes |
| `catalogIds` | Array of Strings | Catalog identifiers |
| `categoryIds` | Array of Strings | Category identifiers |
| `attachment` | Object | Product media |
| `workflow` | Object | Product workflow properties |
| `delisted` | Boolean | Indicates whether the product is delisted |


#### Request

```bash
curl --location --request PATCH \
  'https://api3.sprinklr.com/{env}/api/v3/product?productId={productId}' \
  --header 'Authorization: Bearer {Access Token}' \
  --header 'Key: {API Key}' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{
    "sellingPrice": 69.99,
    "currency": "USD",
    "inventory": 8,
    "availability": "IN_STOCK"
  }'
```

#### Response

```http
HTTP/1.1 204 No Content
```

The response body is empty.

### 4.4 Delete Products

Deletes one or more products. To delete multiple products, supply their identifiers as a comma-separated list.

#### Endpoint

```http
DELETE https://api3.sprinklr.com/{env}/api/v3/product?productId={productIds}
```

#### Query Parameters

| Parameter | Type | Required | Description |
|  --- | --- | --- | --- |
| `productId` | String | Yes | One product ID or a comma-separated list of product IDs |


#### Delete a Product

```bash
curl --location --request DELETE \
  'https://api3.sprinklr.com/{env}/api/v3/product?productId={productId}' \
  --header 'Authorization: Bearer {Access Token}' \
  --header 'Key: {API Key}' \
  --header 'Accept: application/json'
```

#### Delete Multiple Products

```bash
curl --location --request DELETE \
  'https://api3.sprinklr.com/{env}/api/v3/product?productId={productId1},{productId2}' \
  --header 'Authorization: Bearer {Access Token}' \
  --header 'Key: {API Key}' \
  --header 'Accept: application/json'
```

#### Response

```http
HTTP/1.1 204 No Content
```

The response body is empty.

## 5. Read Operations

### 5.1 Fetch Products

Retrieves one or more products. Supply one product ID or a comma-separated list of product IDs.

#### Endpoint

```http
GET https://api3.sprinklr.com/{env}/api/v3/product
```

#### Query Parameters

| Parameter | Type | Required | Description |
|  --- | --- | --- | --- |
| `productId` | String | Yes | Product identifier or comma-separated list of product identifiers |


#### Fetch a Product

```bash
curl --location \
  'https://api3.sprinklr.com/{env}/api/v3/product?productId={productId}' \
  --header 'Authorization: Bearer {Access Token}' \
  --header 'Key: {API Key}' \
  --header 'Accept: application/json'
```

#### Fetch Multiple Products

```bash
curl --location \
  'https://api3.sprinklr.com/{env}/api/v3/product?productId={productId1},{productId2}' \
  --header 'Authorization: Bearer {Access Token}' \
  --header 'Key: {API Key}' \
  --header 'Accept: application/json'
```

#### Response

A successful request returns `200 OK` and one or more products in the `data` array.

```json
{
  "data": [
    {
      "id": "{productId}",
      "source": {
        "sourceType": "ACCOUNT",
        "sourceId": "{sourceId}",
        "sourceProductId": "{sourceProductId}",
        "channelType": "SOURCE_AGNOSTIC"
      },
      "catalogIds": ["{catalogId}"],
      "categoryIds": ["{categoryId}"],
      "title": "Sample Product",
      "description": "Sample product description",
      "link": "https://example.com/products/{sourceProductId}",
      "price": {
        "value": 78.0,
        "currency": "USD"
      },
      "groupId": "{groupId}",
      "attachment": {
        "url": "https://example.com/images/product.jpg",
        "encryptedUrl": "{encryptedUrl}",
        "type": "IMAGE"
      },
      "workflow": {
        "customProperties": {
          "{customFieldId}": ["{customFieldValue}"]
        }
      },
      "delisted": false
    }
  ],
  "errors": []
}
```

### Response Schema

| Field | Type | Description |
|  --- | --- | --- |
| `id` | String | Unique identifier of the product |
| `source` | Object | Source details associated with the product |
| `catalogIds` | Array of Strings | Catalog identifiers associated with the product |
| `categoryIds` | Array of Strings | Category identifiers associated with the product |
| `title` | String | Product title |
| `description` | String | Product description |
| `link` | String | Product URL |
| `price` | Object | Product pricing information |
| `specification` | Map of String to String | Product attributes |
| `groupId` | String | Product group identifier |
| `attachment` | Object | Product media |
| `workflow` | Object | Product workflow properties |
| `delisted` | Boolean | Indicates whether the product is delisted |


### Response Attachment Object

| Field | Type | Description |
|  --- | --- | --- |
| `url` | String | Attachment URL |
| `encryptedUrl` | String | Encrypted attachment URL |
| `type` | String | Attachment type |


## 6. Response Format and Status Codes

### 6.1 V3 Response Envelope

Create and Fetch operations return a response envelope containing `data` and `errors`.

Create response:

```json
{
  "data": {},
  "errors": []
}
```

Fetch response:

```json
{
  "data": [],
  "errors": []
}
```

### 6.2 Response Cardinality

| Operation | `data` Type |
|  --- | --- |
| Create | Object |
| Fetch | Array of Objects |


### 6.3 Response Codes

| HTTP Code | Operation | Meaning |
|  --- | --- | --- |
| `200 OK` | GET | The requested products were returned |
| `201 Created` | POST | The product was created |
| `204 No Content` | PUT | The product was replaced |
| `204 No Content` | PATCH | The product fields were updated |
| `204 No Content` | DELETE | The products were deleted |


## 8. Supported Values

### 8.1 Source Types

| Value | Evidence |
|  --- | --- |
| `ACCOUNT` | Used in the request and response examples |
| `EXTERNAL` | Listed as an example source type |


### 8.2 Channel Types

| Value | Evidence |
|  --- | --- |
| `SOURCE_AGNOSTIC` | Used in the request and response examples |


### 8.3 Attachment Types

| Value |
|  --- |
| `IMAGE` |
| `VIDEO` |
| `CAROUSEL` |
| `LINK` |
| `DOC` |


### 8.4 Availability Values

| Value | Evidence |
|  --- | --- |
| `IN_STOCK` | Used in the partial-update example |


Additional availability values are not documented in the available source.

## 9. Use Cases

### 9.1 Create Products From an External Commerce System

1. Extract product information from the commerce platform.
2. Map source identifiers and catalog assignments.
3. Send a POST request to create each product.
4. Store the returned product IDs for future operations.


### 9.2 Synchronize Product Catalogs

1. Retrieve existing products with GET.
2. Compare the returned data with the source system.
3. Use PUT to replace complete outdated records.
4. Use PATCH to change selected fields.
5. Delete obsolete products when appropriate.


### 9.3 Update Inventory and Pricing

Use PATCH when only operational fields change.

```json
{
  "sellingPrice": 69.99,
  "currency": "USD",
  "inventory": 8,
  "availability": "IN_STOCK"
}
```

### 9.4 Manage Product Variants

Use:

- `groupId` to associate related variants.
- `specification` to distinguish products in the same variant group.
- `subSpecification` to store additional attributes associated with a specification.


## 10. Caveats and Best Practices

### Choose PUT or PATCH Carefully

- Use PUT to replace the complete product definition.
- Use PATCH to update selected fields while preserving omitted fields.


### Preserve Fields During PUT

Include every field that you want to retain. PUT replaces the existing product with the submitted payload.

### Parse Dynamic Specifications

Treat `specification`, `subSpecification`, and `workflow.customProperties` as dynamic map structures. Do not assume fixed property names.

### Support Bulk Operations

GET and DELETE accept comma-separated product IDs. Use bulk operations to reduce API calls when appropriate.

### Handle Encrypted Media URLs

Attachment responses can include both `url` and `encryptedUrl`. Support both fields in your response model.

### Protect Credentials

Use placeholders in examples and store access tokens and API keys securely. Do not commit credentials to source control or application logs.