Merchant API for Grocery Partners

Recommended Product Feed

Stores should provide a product feed in JSON format containing all required information. Our recommended approach is to use Google's product data specifications to structure the product data. This JSON should be made available in a domain that can be accessed by a web crawler. We will query this page up to 4 times a day to get new product information and availability information.

Dealing with multiple locations

Many stores have different availabilities depending on warehouse location. If a store needs to support multiple locations, we strongly recommend using the happycart Merchant API directly. The API gives more flexibility for creating products and dealing with multiple locations.

If using the API isn't possible, there are two options:

  1. If products have different characteristics between different locations (eg. different price), then one JSON will need to be submitted for each location.

  2. If the products are similar but only have different availability on each location, then each product on the product feed should have an array with the IDs of the locations where they are available.

JSON Schema

Here is the JSON schema of the products that we expect in the feed:

{
  "type": "array",
  "items": {
    "type": "object",
    "title": "happycart Product Feed",
    "description": "This product data specification is used by the happycart API. It is based on Google's Product Feed requirements.",
    "default": {},
    "examples": [
      {
        "id": "878333",
        "title": "Mautner Markhof Estragon Senf",
        "description": "Das mild-süße Original wird aus feinster frisch vermahlener Senfsaat nach dem typischen Mautner Markhof-Verfahren hergestellt.",
        "link": "https://www.yourshopcomt/shop/p/mautner-markhof-estragonsenf-330-gr-163005",
        "image_link": "https://res.cloudinary.com/yourshop/products/2261696.jpg",
        "availability": "in stock",
        "delivery_area": ["10115", "10318"], // either ZIP codes or warehouse IDs
        "price": 329, // in cents
        "sale_price": 259, // in cents
        "amount": 330,
        "unit": "g",
        "price_per_kg": 784, // in cents
        "currency": "EUR", // ISO 4217
        "unit_pricing_measure": 1.5,
        "unit_pricing_measure_unit": "kg",
        "unit_pricing_base_measure": 100,
        "google_product_category": "1901",
        "product_type": "Grundnahrungsmittel > Senf & Kren",
        "brand": "Mautner Markhof",
        "gtin": "9011900139623",
        "product_details": [
          {
            "attribute_name": "vegetarian",
            "attribute_value": "true"
          },
          {
            "attribute_name": "vegan",
            "attribute_value": "true"
          },
          {
            "attribute_name": "gluten_free",
            "attribute_value": "true"
          },
          {
            "attribute_name": "lactose_free",
            "attribute_value": "true"
          }
        ],
        "tags": [
          "vegan",
          "vegetarian",
          "gluten_free",
          "lactose_free",
          "bio",
          "regional"
        ],
        "allergy_information": "Enthält: Senf und daraus gewonnene Erzeugnisse",
        "countries_of_origin": ["DE", "AT"], // ISO 3166-1
        "nutrition": {
          "base_unit": "g",
          "unit_amount": 100,
          "fat": 12,
          "fat_unit": "g",
          "saturated_fat": 0.5,
          "saturated_fat_unit": "g",
          "carbohydrates": 2,
          "carbohydrates_unit": "g",
          "sugars": 6.9,
          "sugars_unit": "g",
          "protein": 2.3,
          "protein_unit": "g",
          "fiber": 2.9,
          "fiber_unit": "g",
          "salt": 0.35,
          "salt_unit": "g",
          "sodium": 0.14,
          "sodium_unit": "g",
          "energy_kcal": 80
        },
        "deals": [
          {
            "type": "x_plus_y", // 2 + 1 free, in this example
            "x": 2,
            "y": 1,
            "discount_value": 1,
            "discount_unit": "CURRENCY",
            "start_date": "2021-01-01",
            "end_date": "2021-01-31"
          },
          {
            "type": "total", // -20% on total order for 4 purchases or more
            "discount_value": 20,
            "discount_unit": "PERCENT",
            "start_date": "2021-01-01",
            "end_date": "2021-01-31",
            "min_quantity": 4
          }
        ]
      }
    ],
    "required": [
      "id",
      "title",
      "description",
      "link",
      "image_link",
      "availability",
      "price",
      "unit_pricing_measure",
      "brand",
      ["gtin", "mpn", "identifier_exists"]
    ],
    "properties": {
      "id": {
        "$id": "#/properties/id",
        "type": "string",
        "title": "Your product’s unique identifier",
        "description": "Required. ID must be unique. Use the SKU (stock-keeping unit) where possible.",
        "default": "",
        "examples": ["878333"]
      },
      "title": {
        "$id": "#/properties/title",
        "type": "string",
        "title": "Your product’s name",
        "description": "Required. The product's name as stands on the packaging.",
        "default": "",
        "examples": ["Mautner Markhof Estragon Senf"]
      },
      "description": {
        "$id": "#/properties/description",
        "type": "string",
        "title": "Your product’s description",
        "description": "Required. Accurately describe your product.",
        "default": "",
        "examples": [
          "Das mild-süße Original wird aus feinster frisch vermahlener Senfsaat nach dem typischen Mautner Markhof-Verfahren hergestellt."
        ]
      },
      "link": {
        "$id": "#/properties/link",
        "type": "string",
        "title": "Your product’s landing page",
        "description": "Required. A link to this project on your page. Start with http or https. Use an encoded URL that complies with RFC 2396 or RFC 1738. For example, a comma would be represented as '%2C'.",
        "default": "",
        "examples": [
          "[https://www.yourshop.at/shop/p/mautner-markhof-estragonsenf-330-gr-163005](https://www.yourshop.at/shop/p/mautner-markhof-estragonsenf-330-gr-163005)"
        ]
      },
      "image_link": {
        "$id": "#/properties/image_link",
        "type": "string",
        "title": "The URL of your product’s main image",
        "description": "Required. A link to the main image for this product. Start with http or https. Use an encoded URL that complies with RFC 2396 or RFC 1738. For example, a comma would be represented as '%2C'. Use an accepted format: non-animated GIF (.gif), JPEG (.jpg/.jpeg), PNG (.png), BMP (.bmp), and TIFF (.tif/.tiff). Use an image of at least 100 x 100 pixels. Don't submit an image larger than 64 megapixels or larger than 16MB.",
        "default": "",
        "examples": [
          "[https://res.cloudinary.com/yourshop/products/2261696.jpg](https://res.cloudinary.com/yourshop/products/2261696.jpg)"
        ]
      },
      "availability": {
        "$id": "#/properties/availability",
        "type": "string",
        "title": "Your product's availability",
        "description": "Required. The status of the product. Must be one of ['in stock', 'out of stock', 'preorder']",
        "default": "",
        "enum": ["in stock", "out of stock", "preorder"],
        "examples": ["in stock"]
      },
      "price": {
        "$id": "#/properties/price",
        "type": "number",
        "title": "Your product’s price. In cents.",
        "description": "Required. Final product price paid by the customer in cents",
        "default": "",
        "examples": [329]
      },
      "sale_price": {
        "$id": "#/properties/sale_price",
        "type": "string",
        "title": "Your product's sale price. In cents.",
        "description": "Optional. Can be submitted in addition to 'price' for products which are on temporary sale.",
        "default": "",
        "examples": [299]
      },
      "currency": {
        "$id": "#/properties/currency",
        "type": "string",
        "title": "The currency of your product’s price",
        "description": "Required. Use the ISO 4217 currency code.",
        "default": "",
        "examples": ["EUR"]
      },
      "unit_pricing_measure": {
        "$id": "#/properties/unit_pricing_measure",
        "type": "number",
        "title": "The measure of your product as it is sold.",
        "description": "Required. The amount for the product.",
        "default": "",
        "examples": [1.5, 6, 1]
      },
      "unit_pricing_measure_unit": {
        "$id": "#/properties/unit_pricing_measure",
        "type": "string",
        "title": "The measure and dimension of your product as it is sold. The quantity part.",
        "description": "Required. The unit for the product. Supported units: 'g', 'mg', 'kg', 'ml', 'l', 'unit', 'stk'. 'unit' and 'stk' are similar, used to denote products sold by units.",
        "default": "",
        "examples": ["kg", "stk"]
      },
      "unit_pricing_base_measure": {
        "$id": "#/properties/unit_pricing_base_measure",
        "type": "number",
        "title": "The product’s base measure for pricing (e.g. 100ml means the price is calculated based on a 100ml units)",
        "description": "Optional. Needs to have the same unit as 'unit_pricing_measure'. Keep in mind that the price (or sale price, if active) is used to calculate the unit price of the product. For example, if price is 3 USD, unit_pricing_measure is 150 ml, and unit_pricing_base_measure is 100, the unit price is 2 USD / 100ml. Supported units: 'g', 'mg', 'kg', 'ml', 'l', 'unit', 'stk'. 'unit' and 'stk' are similar, used to denote products sold by units.",
        "default": "",
        "examples": [100, 1.5]
      },
      "google_product_category": {
        "$id": "#/properties/google_product_category",
        "type": "string",
        "title": "Google-defined product category for your product",
        "description": "Optional. Include either the full path of the category or the numerical category ID.",
        "default": "",
        "examples": ["1901"]
      },
      "product_type": {
        "$id": "#/properties/product_type",
        "type": "string",
        "title": "Product category that you define for your product",
        "description": "Optional. Include the full category. For example, include Home > Women > Dresses > Maxi Dresses instead of just Dresses",
        "default": "",
        "examples": ["Grundnahrungsmittel > Senf & Kren"]
      },
      "brand": {
        "$id": "#/properties/brand",
        "type": "string",
        "title": "Your product’s brand name",
        "description": "Required. Provide the brand name of the product generally recognized by consumers.",
        "default": "",
        "examples": ["Mautner Markhof"]
      },
      "gtin": {
        "$id": "#/properties/gtin",
        "type": "string",
        "title": "Your product’s Global Trade Item Number (GTIN)",
        "description": "One of 'gtin', 'mpn', or 'identifier_exists: no' are required. Exclude dashes and spaces. Submit only valid GTINs as defined in the official GS1 validation guide. If the product doesn't have a GTIN, submit a MPN instead.",
        "default": "",
        "examples": ["9011900139623"]
      },
      "mpn": {
        "$id": "#/properties/mpn",
        "type": "string",
        "title": "Your product’s Manufacturer Part Number (mpn)",
        "description": "One of 'gtin', 'mpn', or 'identifier_exists: no' are required. Only submit MPNs assigned by a manufacturer. Use the most specific MPN possible. For example, different colors of a product should have different MPNs.",
        "default": "",
        "examples": ["GO12345OOGLE"]
      },
      "identifier_exists": {
        "$id": "#/properties/mpn",
        "type": "string",
        "title": "Use to indicate whether or not the unique product identifiers (UPIs) GTIN, MPN, and brand are available for your product.",
        "description": "One of 'gtin', 'mpn', or 'identifier_exists: no' are required. If GTIN and MPN are not available, this needs to be set to 'no'. Defaults to 'yes' otherwise.",
        "default": "yes",
        "examples": ["no"]
      },
      "product_details": {
        "$id": "#/properties/product_details",
        "type": "array",
        "title": "Technical specifications or additional details of your product.",
        "description": "Optional. Objects containing attribute names and values for commonly request product details such as whether it's vegan. Possible attribute names: ['Vegetarian', 'Vegan', 'LactoseFree', 'GlutenFree', 'Bio']. Only provide an attribute name and value when the value is confirmed. For example, for a food product, only provide 'Vegetarian=False' if it is confirmed the product is indeed not vegetarian, and not just because False is the default value for Boolean attributes.",
        "default": null,
        "items": {
          "type": "object",
          "properties": {
            "attribute_name": {
              "$id": "#/properties/product_details/items/properties/attribute_name",
              "type": "string",
              "title": "The name of the attribute",
              "description": "Required. The name of the attribute",
              "default": "",
              "examples": ["vegetarian"]
            },
            "attribute_value": {
              "$id": "#/properties/product_details/items/properties/attribute_value",
              "type": "string",
              "title": "The value of the attribute",
              "description": "Required. The value of the attribute.",
              "default": "",
              "examples": ["true"]
            }
          }
        },
        "examples": [
          [
            {
              "attribute_name": "vegetarian",
              "attribute_value": "true"
            },
            {
              "attribute_name": "vegan",
              "attribute_value": "false"
            }
          ]
        ]
      },
      "allergy_information": {
        "$id": "#/properties/allergy_information",
        "type": "string",
        "title": "Allergen information in string format.",
        "description": "Optional.",
        "default": "",
        "examples": ["Enthält:Senf und daraus gewonnene Erzeugnisse"]
      },
      "country_of_origin": {
        "$id": "#/properties/country_of_origin",
        "type": "string",
        "title": "Country of origin.",
        "description": "Optional. Describes the country of origin of a product. Use alpha-2 codes for country codes, and only add one code.",
        "default": "",
        "examples": ["DE"]
      },
      "custom_label_2": {
        "$id": "#/properties/custom_label_1",
        "type": "string",
        "title": "Certification information.",
        "description": "Optional. String containing any certification information for a product.",
        "default": "",
        "examples": ["Deutsche Zöliakie Gesellschaft e. V. Glutenfrei-Symbol"]
      },
      "nutrition": {
        "$id": "#/properties/nutrition",
        "type": "object",
        "title": "Nutritional information.",
        "description": "Optional. Object containing nutritional information for a product. All values are optional.",
        "default": null,
        "examples": [
          {
            "base_unit": "g",
            "unit_amount": 100,
            "fat": 12,
            "fat_unit": "g",
            "saturated_fat": 0.5,
            "saturated_fat_unit": "g",
            "carbohydrates": 2,
            "carbohydrates_unit": "g",
            "sugars": 6.9,
            "sugars_unit": "g",
            "protein": 2.3,
            "protein_unit": "g",
            "fiber": 2.9,
            "fiber_unit": "g",
            "salt": 0.35,
            "salt_unit": "g",
            "sodium": 0.14,
            "sodium_unit": "g",
            "energy_kcal": 80
          }
        ]
      },
      "deals": {
        "$id": "#/properties/deals",
        "type": "array",
        "title": "Current deals for your product.",
        "description": "Optional. Objects containing information about current deals for your product.",
        "default": null,
        "example": [
          {
            "type": "x_plus_y", // 2 + 1 free, in this example
            "x": 2,
            "y": 1,
            "discount_value": 1,
            "discount_unit": "CURRENCY",
            "start_date": "2021-01-01",
            "end_date": "2021-01-31"
          },
          {
            "type": "total", // -20% on total order for 4 purchases or more
            "discount_value": 20,
            "discount_unit": "PERCENT",
            "start_date": "2021-01-01",
            "end_date": "2021-01-31",
            "min_quantity": 4
          }
        ]
      }
    }
  }
}
Previous
Merchant API Introduction