Sending Product Offers to Marketplaces

Summary

Overview

The Product Offers syndication functionality allows for the smooth exchange of product offer data (such as price, stock, conditions, and promotions) between the Activation platform and various retailers and marketplaces, starting with Amazon Seller Central and MIRAKL-powered marketplaces. This documentation explains how to set up and use this feature effectively.

Currently, the export of product offers is technical and only available through the API.

The product offers API lets you create and update one or multiple offers for various products. It also supports partial updates, such as changing only prices, currencies, or stock levels.

It is not possible to delete product offers via the API. You can, however, set the quantity to “0” to ensure the product cannot be available for purchase on the channel side.

 

 

 

Data Flow

Here is how the end-to-end workflow works to send product offers:

  • You need to call the offer API (made available via a simple endpoint URL)
  • The data gets pushed from your source via the API
  • The data is then hosted on the Activation side, translating the logic to what the marketplaces expect.
  • A scheduler automatically sends the pushed product offer data via the API to the marketplaces every 15 minutes.
  • The product offer data is stored in Activation and attached to the corresponding product (s).

 

Access Token

  • To call the API successfully, you must access a token. Every new customer is assigned a unique access token when connecting a PIM to the Activation App.
  • Accessing the API requires the use of this access token.
  • To create a new access token to call the API you can generate it from the Activation app via this link
    1. Go to the Activation settings
    2. Select the “Activation settings” tab
    3. Click the generate token button with arrows

 

 

Offer description

To ensure you send the correct information when creating or updating product offers, review the sections below that detail the expected data in the API.

An offer is always associated with a product, and you can attach multiple offers to the same product.

An offer includes several sections (price, inventory, condition, promotion). Each offer is linked to one Activation channel and cannot be part of multiple Activation channels at the same time. You can update each section independently for one or more products.

 

Identifier

This data is needed to uniquely identify an offer and the product it is attached to.

  • You need to be able to identify how to attach a product to an offer, for that a product identifier is required such as an SKU or an EAN
  • You need to be able to identify an offer uniquely, for that, you can use a unique identifier such as an Offer SKU.
    • Each marketplace can have a specific way of identifying its offers
      • Amazon with the ASIN
      • MIRAKL-powered marketplaces with the Product Offer SKU

Price Section

This data relates to an offer price

  • Contains pricing information
    • Amount
    • Currency
    • Offer Times (start/end)
      • Additional time-related metrics
    • Potential discounts and promotions

Stock Section

This data relates to an offer inventory

  • Provides details about the product's stock:
    • Condition (new/used/refurbished)
    • Quantity
    • Days to ship (handling time)

Promotions

Each offer can have multiple promotions, each with a specific

  • Start/end time
  • Price
  • Condition

Sending Multiple Offers

  • You can create and update multiple offers per product, each with its specifications.
  • For example, Offer A could be for a "new" product, while Offer B could be for a "used/refurbished" product.

 

 

Current limitations

To date, it is not possible from the Activation app to:

  • see the product offer export job from your activation channel reports tab
 

 

MIRAKL marketplaces specific use case

Only one offer discount can be sent per offer. When you send multiple discounts, only the first one will be used. If you want to send multiple discounts for the same product, you will have to create as many offers as discounts for that product. It is not possible to send product condition (ie “used”) to MIRAKL.

 

 

Working with the API

You can review the API documentation in this API guide to understand how to successfully call it and push product offers to the supported marketplaces.

 

See below the different API body sections:

Verb

POST for creation

PUT for update

Required for the very first API call, creating the offer

From the second call onward, PUT could be used to update price and/or stock data

Headers

access_token  

  • Required
  • Equal to 'xxx', 'xxx' being the App authentication token
  • Provided by the Activation tech team
  • Works with the PIM connection

Path parameters

flow_id

  • Required
  • string
  • Identifier for the targeted flow (channel in Activation)

Query parameters

syndication_channel_product_identifier

  • required
  • string
  • Corresponds to the SKU in the PIM

offers:offer_sku

  • required
  • string
  • Corresponds to the Offer identifier for a partner (channel)
    • For Amazon, it needs to be syndication_channel_product_identifier
    • For MIRAKL, it corresponds to an identifier on the MIRAKL side. It might need to be created by MIRAKL (to be checked)

offers:offer_sku:prices:base

  • required for the first call (POST)
  • Optional (PUT call)
  • object

offers:offer_sku:prices:base:amount

  • required
  • number
  • product price

offers:offer_sku:prices:base:currency

  • required
  • number
  • product currency

offers:offer_sku:prices:base:startDate

  • Optional
  • string
  • format : yyyy-mm-dd
  • offer start date

offers:offer_sku:prices:base:endDate

  • Optional
  • String
  • format: yyyy-mm-dd
  • offer end date

offers:offer_sku:prices:discounted

  • required
  • array
  • could be empty
  • discount flag

offers:offer_sku:prices:discounted:amount

  • required
  • number
  • discounted product price

offers:offer_sku:prices:discounted:currency

  • required
  • number
  • discounted product currency

offers:offer_sku:prices:discounted:startDate

  • Optional
  • string
  • format : yyyy-mm-dd
  • discounted offer start date

offers:offer_sku:prices:discounted:endDate

  • Optional
  • String
  • format: yyyy-mm-dd
  • discounted offer end date

offers:offer_sku:stock

  • required if the price object is missing, otherwise optional
  • object

offers:offer_sku:stock:condition

  • required
  • string
  • Corresponds to the state of the product
  • Required format
    • new

offers:offer_sku:stock:quantity

  • required
  • number
  • Corresponds to the product stock count. 0 est accepté

offers:offer_sku:stock:daysToShip

  • Optional
  • number
  • Handling time is the number of days between when you receive payment for an item and when your package is scanned by your shipping carrier (eBay definition)

 

Examples

These are the different calls that can be made when calling the product offers API:

Complete informations (POST & PUT)

{
    "syndicationChannelProductIdentifier": {
        "offers": {
            "offerSku": {
                "prices": {
                    "base": {
                        "amount": 17.77,
                        "currency": "USD",
                        "startDate": "2024-01-01",
                        "endDate": "2024-12-31"
                    },
                    "discounted": [
	                    {
                        "amount": 12.50,
                        "currency": "USD",
                        "startDate": "2024-03-01",
                        "endDate": "2024-04-15"
	                    },
	                    {
                        "amount": 13.57,
                        "currency": "USD",
                        "startDate": "2024-04-16",
                        "endDate": "2024-05-01"
	                    },
                    ]
                },
                "stock": {
                    "condition": "new",
                    "quantity": 0,
                    "daysToShip": 5
                }
            }
        }
    }
}

Without discounted (POST & PUT)

{
    "syndicationChannelProductIdentifier": {
        "offers": {
            "offerSku": {
                "prices": {
                    "base": {
                        "amount": 17.77,
                        "currency": "USD",
                        "startDate": "2024-03-01",
                        "endDate": "2024-04-15"
                    },
                    "discounted": []
                },
                "stock": {
                    "condition": "new",
                    "quantity": 0,
                    "daysToShip": 5
                }
            }
        }
    }
}

Update only prices (PUT only)

{
    "syndicationChannelProductIdentifier": {
        "offers": {
            "offerSku": {
                "prices": {
                    "base": {
                        "amount": 17.77,
                        "currency": "USD",
                        "startDate": "2024-03-01",
                        "endDate": "2024-04-15"
                    },
                    "discounted": []
                }
            }
        }
    }
}

Update only stock (PUT only)

{
    "syndicationChannelProductIdentifier": {
        "offers": {
            "offerSku": {
                "stock": {
                    "condition": "new",
                    "quantity": 0,
                    "daysToShip": 5
                }
            }
        }
    }
}

 

Errors 

These are the different errors that can happen when calling the product offers API:

  • Wrong flow_id403 - Forbidden
  • Wrong access_token403 - Forbidden
  • Product not found | 200 - OK 
{
    "*syndication_channel_product_identifier*": [
        {
            "type": "product_not_found",
            "severity": "warning",
            "message": "Could not find product *syndication_channel_product_identifier*"
        }
    ]
}
  • Missing property | 400 - Bad Request
{
    "type": "update_sellable_product.bad_request",
    "message": "The request is not valid",
    "payload": {
        "errors": [
            {
                "instancePath": "/body/*syndication_channel_product_identifier*",
                "schemaPath": "#/properties/body/additionalProperties/required",
                "keyword": "required",
                "params": {
                    "missingProperty": "offers"
                },
                "message": "must have required property 'offers'"
            }
        ]
    }
}
  • Try to create an existing product | 400 - Bad Request
{
    "type": "update_sellable_product.bad_request",
    "message": "The request is not valid",
    "payload": {
        "errors": [
            {
                "instancePath": "/method",
                "schemaPath": "#/properties/method/const",
                "keyword": "const",
                "params": {
                    "allowedValue": "PUT"
                },
                "message": "must be equal to constant"
            }
        ]
    }
}
  • Try to update an offer that has not been created | 400 - Bad Request
{
    "*syndication_channel_product_identifier*": [
        {
            "type": "invalid_offer",
            "severity": "error",
            "message": "At least one of the product new offers has missing prices or stock"
        }
    ]
}
  • Wrong allowed value (example stock:condition) | 400 - Bad Request
{
    "type": "update_sellable_product.bad_request",
    "message": "The request is not valid",
    "payload": {
        "errors": [
            {
                "instancePath": "/body/*syndication_channel_product_identifier*/offers/offer_sku/stock/condition",
                "schemaPath": "#/properties/body/additionalProperties/properties/offers/additionalProperties/properties/stock/properties/condition/enum",
                "keyword": "enum",
                "params": {
                    "allowedValues": [
                        "new"
                    ]
                },
                "message": "must be equal to one of the allowed values"
            }
        ]
    }
}