Create shopping list page
POST /idp/v1/products/products_link
Creates a shopping list page on Instacart Marketplace and generates a shareable link. When users click the link, they can select a store, add products to their cart, and check out.
Prerequisites
Before you begin, ensure you have:
- A development API key.
- Access to Instacart's development server: https://connect.dev.instacart.tools.
When ready for production, create a production API key and update your endpoint to: https://connect.instacart.com.
Request structure
Each request must include an array of LineItem objects representing products. At minimum, specify a product name for each line item. Instacart uses product names to match and display products to users. When creating a LineItem object, determine whether the ingredient has a single measurement or multiple measurements. For example:
- Single measurement. A shopping list
LineItemmight be a 10.75 fl oz can of tomato soup. - Multiple measurements. A shopping list
LineItemcould include flour listed as 1 cup / 16 tbsp / 48 tsp.
Use the line_item_measurements array to specify measurement options for each line item. This array allows retailers to provide multiple measurements, so that Instacart can choose the best one for calculating the quantity. The quantity and unit fields directly on the LineItem object are deprecated. Use line_item_measurements instead.
Optionally, you can specify other page attributes, such as an image, description, and instructions. You can also include a link back to your site and specify if customers can exclude items they already have in their pantry.
Optional line item fields
- Quantities.
- Units of measurement (see Units of measurement for valid values).
- Filters.
- UPC codes.
When a line_item includes a UPC, Instacart prioritizes UPC-based search. If the product is unavailable, users are notified and can search for alternatives.
Best practices
- URL Caching. Cache the generated shopping list URL and reuse it. Only generate a new URL when the shopping list content changes.
- Units of Measurement. Only use units listed in the supported Units of measurement page. Unsupported units cause quantity matching to fail.
Authorization
| Name | In | Description |
|---|---|---|
| Authorization | header | A bearer token. In this context, the token is the API key that you received from Instacart when you signed up for Instacart Developer Platform. |
URL parameters
None.Request body
| Field | Type | Required | Description |
|---|---|---|---|
title | string | The title of the shopping list or recipe page. | |
image_url | string | The URL of the image to display on the shopping list or recipe page. Image size must be 500x500 pixels. | |
link_type | string | The type of product link to create. One of 'shopping_list' or 'recipe'. Defaults to shopping_list. | |
expires_in | integer | The number of days until the link expires. The maximum value is 365 days. When the link_type is 'recipe', the default is 30 days. When the link_type is 'shopping_list', there is no default value. | |
instructions | Array(string) | Text that provides additional context about the shopping list or recipe, such as instructions for making a recipe or a dietary recommendation. | |
line_items | Array(LineItem) | The line items (products) to include in the shopping list or recipe. | |
landing_page_configuration | LandingPageConfiguration | The configuration for the shopping list or recipe page. |
LineItem Object
| Field | Type | Required | Description |
|---|---|---|---|
name | string | The product name. Instacart uses the product name as a search term to find a matching product. | |
quantity | number | Deprecated. Use the 'line_item_measurements' array instead, which allows multiple measurements per line item. The product quantity. This value represents either the item count or measurement as defined by the 'unit' attribute. Defaults to 1.0. | |
unit | string | Deprecated. Use the 'line_item_measurements' array instead, which allows multiple measurements per line item. The unit of measurement associated with the quantity attribute. Some example units include each, package, tablespoon, teaspoon, ounce, or kilogram. Defaults to each. | |
display_text | string | The title of the matched ingredient to be displayed in the search results and ingredient list. If this is not provided, the 'name' field in the 'LineItem' object will be used. | |
product_ids | Array(integer) | The product IDs used to map ingredients to specific products. 'product_id' and 'upc' are mutually exclusive. | |
upcs | Array(string) | The Universal Product Code (UPC) is a unique 12- or 14-digit identifier for a product. 'product_id' and 'upc' are mutually exclusive. | |
line_item_measurements | Array(Measurement) | Optional measurement units used to specify the ingredient quantity in multiple ways. If this is not provided, the 'unit' and 'quantity' fields in the 'LineItem' object will be used. | |
filters | Filter | Optional filters used to specify product matching criteria. |
Measurement Object
| Field | Type | Required | Description |
|---|---|---|---|
quantity | number | The product quantity. This value represents either the item count or measurement as defined by the 'unit' attribute. Used by Instacart to determine the quantity of this item to add. Defaults to 1.0. | |
unit | string | The unit of measurement associated with the quantity attribute. Some example units include each, package, tablespoon, teaspoon, ounce, or kilogram. For countable items such as tomatoes, it is recommended to use the each value rather than specifying a weight. Defaults to each. |
Filter Object
| Field | Type | Required | Description |
|---|---|---|---|
brand_filters | Array(string) | Optional brand filters to match products. Add the brand names to the | |
health_filters | Array(string) | Optional health filters to match products. Valid values are ORGANIC, GLUTEN_FREE, FAT_FREE, VEGAN, KOSHER, SUGAR_FREE, LOW_FAT. If 'product_ids' or 'upcs' are provided, this filter is ignored. |
LandingPageConfiguration Object
| Field | Type | Required | Description |
|---|---|---|---|
partner_linkback_url | string | The URL link to the shopping list or recipe on the developer's app or website. | |
enable_pantry_items | boolean | Whether items can be marked as pantry items. Pantry items are items that a user might already have at home and doesn't need to add to the cart. Default is false and only supported on 'recipe' link_type. |
Request examples
- cURL
- Java
- Python
- Go
curl --request POST \
--url https://connect.instacart.com/idp/v1/products/products_link \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <API-key>' \
--header 'Content-Type: application/json' \
--data '{
"title": "string",
"image_url": "string",
"link_type": "string",
"expires_in": 1,
"instructions": [
"string"
],
"line_items": [
{
"name": "string",
"quantity": 1,
"unit": "string",
"display_text": "string",
"product_ids": [
1
],
"upcs": [
"string"
],
"line_item_measurements": [
{
"quantity": 1,
"unit": "string"
}
],
"filters": {
"brand_filters": [
"string"
],
"health_filters": [
"string"
]
}
}
],
"landing_page_configuration": {
"partner_linkback_url": "string",
"enable_pantry_items": true
}
}'
HttpResponse<String> response = Unirest.post("https://connect.instacart.com/idp/v1/products/products_link")
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.header("Authorization", "Bearer <API-key>")
.body("{\n \"title\": \"string\",\n \"image_url\": \"string\",\n \"link_type\": \"string\",\n \"expires_in\": 1,\n \"instructions\": [\n \"string\"\n ],\n \"line_items\": [\n {\n \"name\": \"string\",\n \"quantity\": 1,\n \"unit\": \"string\",\n \"display_text\": \"string\",\n \"product_ids\": [\n 1\n ],\n \"upcs\": [\n \"string\"\n ],\n \"line_item_measurements\": [\n {\n \"quantity\": 1,\n \"unit\": \"string\"\n }\n ],\n \"filters\": {\n \"brand_filters\": [\n \"string\"\n ],\n \"health_filters\": [\n \"string\"\n ]\n }\n }\n ],\n \"landing_page_configuration\": {\n \"partner_linkback_url\": \"string\",\n \"enable_pantry_items\": true\n }\n}")
.asString();
import http.client
conn = http.client.HTTPSConnection("connect.instacart.com")
payload = "{\n \"title\": \"string\",\n \"image_url\": \"string\",\n \"link_type\": \"string\",\n \"expires_in\": 1,\n \"instructions\": [\n \"string\"\n ],\n \"line_items\": [\n {\n \"name\": \"string\",\n \"quantity\": 1,\n \"unit\": \"string\",\n \"display_text\": \"string\",\n \"product_ids\": [\n 1\n ],\n \"upcs\": [\n \"string\"\n ],\n \"line_item_measurements\": [\n {\n \"quantity\": 1,\n \"unit\": \"string\"\n }\n ],\n \"filters\": {\n \"brand_filters\": [\n \"string\"\n ],\n \"health_filters\": [\n \"string\"\n ]\n }\n }\n ],\n \"landing_page_configuration\": {\n \"partner_linkback_url\": \"string\",\n \"enable_pantry_items\": true\n }\n}"
headers = {
'Accept': "application/json",
'Content-Type': "application/json",
'Authorization': "Bearer <API-key>"
}
conn.request("POST", "/idp/v1/products/products_link", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://connect.instacart.com/idp/v1/products/products_link"
payload := strings.NewReader("{\n \"title\": \"string\",\n \"image_url\": \"string\",\n \"link_type\": \"string\",\n \"expires_in\": 1,\n \"instructions\": [\n \"string\"\n ],\n \"line_items\": [\n {\n \"name\": \"string\",\n \"quantity\": 1,\n \"unit\": \"string\",\n \"display_text\": \"string\",\n \"product_ids\": [\n 1\n ],\n \"upcs\": [\n \"string\"\n ],\n \"line_item_measurements\": [\n {\n \"quantity\": 1,\n \"unit\": \"string\"\n }\n ],\n \"filters\": {\n \"brand_filters\": [\n \"string\"\n ],\n \"health_filters\": [\n \"string\"\n ]\n }\n }\n ],\n \"landing_page_configuration\": {\n \"partner_linkback_url\": \"string\",\n \"enable_pantry_items\": true\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Accept", "application/json")
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", "Bearer <API-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(res)
fmt.Println(string(body))
}
Response
| Field | Type | Required | Description |
|---|---|---|---|
products_link_url | string | Products link URL. |
Response examples
200 Success
200Create a product link successfully without affiliate_id
{
"products_link_url": "http://example.com"
}
4XX Errors
Error responses return either a single error or multiple errors.
| HTTP Code | Cause | Error Message | Error Code | Error Meta |
|---|---|---|---|---|
400 | Bad request missing required parameters* | "There were issues with your request" | 9999 | Not applicable |
400 | Bad request invalid health filters | "Invalid health filters: ["INVALID"]" | 1001 | {"key":"line_items[0].filters.health_filters"} |
400 | Bad request invalid measurement quantity | "Invalid quantity: -0.1. Cannot be lower than or equal to 0.0" | 1001 | {"key":"line_items[0].line_item_measurements[0].quantity"} |
400 | Bad request line item with both product_ids and upcs | "Line item cannot have both product_ids and upcs. They are mutually exclusive." | 1001 | {"key":"line_items[0].base"} |
400 | Bad request duplicate product_ids across line items | "Duplicate product identifiers found: product_id 12345" | 1001 | {"key":"line_items"} |
400 | Bad request duplicate upcs across line items | "Duplicate product identifiers found: upc 123456789012" | 1001 | {"key":"line_items"} |