List time slots for pickup
POST /v2/fulfillment/users/{user_id}/service_options/cart/pickup
Lists the available pickup service options for the customer's location and cart items. In this context, service options are time slots, such as Within 5 hours or Friday 9am-11am. Availability is based on current and anticipated shopper availability for the relevant store location. The list includes immediate and scheduled time slots.
After a time slot is selected, save the service_option_id. You specify the ID when reserving the time slot.
Include all the items in the cart in the request. Connect can surface any errors—such as items missing from the catalog—early in the user flow and also precompute some validations to optimize performance.
Security
| Name | In | Description |
|---|---|---|
Authorization | header | The Authorization header with the bearer token acquired during authentication. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
user_id | path | string | The ID of the user. |
Request
Each items[] in the request requires either a count or a weight. The field that needs to be defined depends on that product's catalog configuration. For more information, see Product quantity types.
| Field | Type | Required | Description |
|---|---|---|---|
items | Array(OrderItem) | The items for delivery. | |
location_code | string | The location code of the store fulfilling the order. | |
with_eta_options | boolean | Returns ETA options instead of immediate when true. For more information, contact your Instacart Representative. Defaults to false. |
OrderItem Object
| Field | Type | Required | Description |
|---|---|---|---|
line_num | string | The item's line number in the order. | |
count | integer | The count of the item. Must be a non-negative integer. Depending on the item's catalog configuration, either this field or 'weight' is required. | |
weight | number | For items sold by weight, the numerical weight of the item. Depending on the item's catalog configuration, either this field or 'count' is required. The API interprets this value as whatever unit of measure is defined for the item in the catalog, such as lb or kg. Must be a non-negative number. | |
special_instructions | string | Any special instructions about the item selection. | |
replacement_policy | string | One of "no_replacements", "users_choice" (default if replacement_items specified), or "shoppers_choice" (default otherwise). | |
metadata | Hash | The item-level metadata. | |
replacement_items | Array(Replacement_items) | A list of requested replacement items if the original item could not be found. This field needs to be turned on via configuration. Contact your Instacart Connect representative. | |
item | Item | The item's code. |
Replacement_items Object
One of the following:
| Field | Type | Required | Description |
|---|---|---|---|
upc | string | The item's universal product code (upc). |
or
| Field | Type | Required | Description |
|---|---|---|---|
rrc | string | The item's retailer reference code (rrc). |
Item Object
One of the following:
| Field | Type | Required | Description |
|---|---|---|---|
upc | string | The item's universal product code (upc). |
or
| Field | Type | Required | Description |
|---|---|---|---|
rrc | string | The item's retailer reference code (rrc). |
Request examples
- cURL
- Java
- Python
- Go
curl --request POST \
--url 'https://connect.instacart.com/v2/fulfillment/users/{user_id}/service_options/cart/pickup' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"items": [
{
"line_num": "string",
"count": 1,
"weight": 1,
"special_instructions": "string",
"replacement_policy": "no_replacements",
"metadata": {
"key1": "value1",
"key2": "value2"
},
"replacement_items": [
{
"upc": "string"
}
],
"item": {
"upc": "string"
}
}
],
"location_code": "string",
"with_eta_options": true
}'
HttpResponse<String> response = Unirest.post("https://connect.instacart.com/v2/fulfillment/users/{user_id}/service_options/cart/pickup")
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.header("Authorization", "Bearer <token>")
.body("{\n \"items\": [\n {\n \"line_num\": \"string\",\n \"count\": 1,\n \"weight\": 1,\n \"special_instructions\": \"string\",\n \"replacement_policy\": \"no_replacements\",\n \"metadata\": {\n \"key1\": \"value1\",\n \"key2\": \"value2\"\n },\n \"replacement_items\": [\n {\n \"upc\": \"string\"\n }\n ],\n \"item\": {\n \"upc\": \"string\"\n }\n }\n ],\n \"location_code\": \"string\",\n \"with_eta_options\": true\n}")
.asString();
import http.client
conn = http.client.HTTPSConnection("connect.instacart.com")
payload = "{\n \"items\": [\n {\n \"line_num\": \"string\",\n \"count\": 1,\n \"weight\": 1,\n \"special_instructions\": \"string\",\n \"replacement_policy\": \"no_replacements\",\n \"metadata\": {\n \"key1\": \"value1\",\n \"key2\": \"value2\"\n },\n \"replacement_items\": [\n {\n \"upc\": \"string\"\n }\n ],\n \"item\": {\n \"upc\": \"string\"\n }\n }\n ],\n \"location_code\": \"string\",\n \"with_eta_options\": true\n}"
headers = {
'Accept': "application/json",
'Content-Type': "application/json",
'Authorization': "Bearer <token>"
}
conn.request("POST", "/v2/fulfillment/users/{user_id}/service_options/cart/pickup", 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/v2/fulfillment/users/{user_id}/service_options/cart/pickup"
payload := strings.NewReader("{\n \"items\": [\n {\n \"line_num\": \"string\",\n \"count\": 1,\n \"weight\": 1,\n \"special_instructions\": \"string\",\n \"replacement_policy\": \"no_replacements\",\n \"metadata\": {\n \"key1\": \"value1\",\n \"key2\": \"value2\"\n },\n \"replacement_items\": [\n {\n \"upc\": \"string\"\n }\n ],\n \"item\": {\n \"upc\": \"string\"\n }\n }\n ],\n \"location_code\": \"string\",\n \"with_eta_options\": true\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 <token>")
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 |
|---|---|---|---|
service_options | Array(ServiceOption) | The returned service options. | |
warnings | Array(Error) | Any warnings associated with this request. | |
flags | Flags | Additional properties of the address. |
ServiceOption Object
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | The service option ID. | |
service_option_reference | string | A unique service option reference that acts as a token you pass in downstream requests to place a hold. | |
date | string | The date and time the service is scheduled to take place in ISO 8601 format. | |
handoff_time | string | Indicates in ISO 8601 format when the handoff between the store associate and the Instacart shopper is expected to occur. Only applicable to last mile delivery orders and not supported in Fulfillment API v3. | |
window | Window | The fulfillment window. | |
availability | OptionAvailability | Indicates whether the service option is available and, if it's not, provides details about why. |
OptionAvailability Object
| Field | Type | Required | Description |
|---|---|---|---|
available | boolean | Indicates whether the service option is available. If | |
reasons | Array(string) | If | |
item_codes | Array(string) | The codes of the items which caused the service option to be unavailable. |
Window Object
One of the following:
| Field | Type | Required | Description |
|---|---|---|---|
start_at | string | The delivery window's starting date and time in ISO 8601 format. | |
end_at | string | The delivery window's ending date and time in ISO 8601 format. | |
type | string | The type of service option. One of | |
asap | boolean | Indicates whether delivery is scheduled to occur as soon as possible. |
or
| Field | Type | Required | Description |
|---|---|---|---|
immediate_hour | integer | The number of hours from the time of order creation by which fulfillment is expected to be complete. For example, if | |
type | string | Indicates that the service option is |
Error Object
| Field | Type | Required | Description |
|---|---|---|---|
error | ErrorDetails | Information relevant to the error. | |
meta | MetaError | The error metadata. |
ErrorDetails Object
| Field | Type | Required | Description |
|---|---|---|---|
message | string | The error message. | |
error_code | integer | The error code. |
MetaError Object
| Field | Type | Required | Description |
|---|---|---|---|
items | Array(ItemInfo) | The items that triggered the error. |
ItemInfo Object
| Field | Type | Required | Description |
|---|---|---|---|
item_code | string | The retailer reference code (RRC) or universal product code (UPC) of an item that triggered the error. |
Flags Object
| Field | Type | Required | Description |
|---|---|---|---|
long_distance_delivery | boolean | Whether a delivery to the address will be a long distance delivery. |
Reasons for unavailability of a service option
| Reason | Description |
|---|---|
State law restricts amount of {beer/wine/spirits} to {#} fl oz, cart quantity is: {#} fl oz. | The quantity of this alcohol type exceeds the state law limit. |
Error validating alcohol quantities. Please try again. | The quantity of alcohol can’t be validated. |
Unmatched city and county | The city and county of the store and customer must match. |
Unfortunately alcohol pickup is not available at this location. Please remove alcohol from your basket or try delivery. | Alcohol pickup is not available at this location. |
Response examples
200 Success
200Pickup service options returned200With warnings
{
"service_options": [
{
"id": 233,
"service_option_reference": "ezppZD0-MjMzLCA6dHlwZT0-MSwgOndpbmRvdz0-PEluc3RhY2FydDo6Q3VzdG9tZXJzOjpBdmFpbGFiaWxpdHk6OlYxOjpUaW1lc3RhbXBXaW5kb3c6IHN0YXJ0c19hdDogPEdvb2dsZTo6UHJvdG9idWY6OlRpbWVzdGFtcDogc2Vjb25kczogMTUxOTI2NDgwMCwgbmFub3M6IDA-LCBlbmRzX2F0OiA8R29vZ2xlOjpQcm90b2J1Zjo6VGltZXN0YW1wOiBzZWNvbmRzOiAxNTE5MjcyMDAwLCBuYW5vczogMD4-fQ==",
"date": "2018-02-21",
"window": {
"start_at": "2018-02-22T02:00:00Z",
"end_at": "2018-02-22T04:00:00Z",
"type": "scheduled",
"asap": false
},
"availability": {
"available": true,
"reasons": [],
"item_codes": []
}
},
{
"id": 234,
"service_option_reference": "ezppZD0-MjM0LCA6dHlwZT0-MTYsIDp3aW5kb3c9PjxJbnN0YWNhcnQ6OkN1c3RvbWVyczo6QXZhaWxhYmlsaXR5OjpWMTo6VGltZXN0YW1wV2luZG93OiBzdGFydHNfYXQ6IDxHb29nbGU6OlByb3RvYnVmOjpUaW1lc3RhbXA6IHNlY29uZHM6IDE1MTkyNjQ4MDAsIG5hbm9zOiAwPiwgZW5kc19hdDogPEdvb2dsZTo6UHJvdG9idWY6OlRpbWVzdGFtcDogc2Vjb25kczogMTUxOTI3MjAwMCwgbmFub3M6IDA-Pn0=",
"date": "2018-02-21",
"window": {
"start_at": "2018-02-22T02:00:00Z",
"end_at": "2018-02-22T04:00:00Z",
"type": "eta",
"asap": false
},
"availability": {
"available": true,
"reasons": [],
"item_codes": []
}
}
],
"warnings": []
}
{
"service_options": [
{
"id": 251,
"service_option_reference": "ezppZD0-MjUxLCA6dHlwZT0-MSwgOndpbmRvdz0-PEluc3RhY2FydDo6Q3VzdG9tZXJzOjpBdmFpbGFiaWxpdHk6OlYxOjpUaW1lc3RhbXBXaW5kb3c6IHN0YXJ0c19hdDogPEdvb2dsZTo6UHJvdG9idWY6OlRpbWVzdGFtcDogc2Vjb25kczogMTUxOTI2NDgwMCwgbmFub3M6IDA-LCBlbmRzX2F0OiA8R29vZ2xlOjpQcm90b2J1Zjo6VGltZXN0YW1wOiBzZWNvbmRzOiAxNTE5MjcyMDAwLCBuYW5vczogMD4-fQ==",
"date": "2018-02-21",
"window": {
"start_at": "2018-02-22T02:00:00Z",
"end_at": "2018-02-22T04:00:00Z",
"type": "scheduled",
"asap": false
},
"availability": {
"available": true,
"reasons": [],
"item_codes": []
}
},
{
"id": 252,
"service_option_reference": "ezppZD0-MjUyLCA6dHlwZT0-MTYsIDp3aW5kb3c9PjxJbnN0YWNhcnQ6OkN1c3RvbWVyczo6QXZhaWxhYmlsaXR5OjpWMTo6VGltZXN0YW1wV2luZG93OiBzdGFydHNfYXQ6IDxHb29nbGU6OlByb3RvYnVmOjpUaW1lc3RhbXA6IHNlY29uZHM6IDE1MTkyNjQ4MDAsIG5hbm9zOiAwPiwgZW5kc19hdDogPEdvb2dsZTo6UHJvdG9idWY6OlRpbWVzdGFtcDogc2Vjb25kczogMTUxOTI3MjAwMCwgbmFub3M6IDA-Pn0=",
"date": "2018-02-21",
"window": {
"start_at": "2018-02-22T02:00:00Z",
"end_at": "2018-02-22T04:00:00Z",
"type": "eta",
"asap": false
},
"availability": {
"available": true,
"reasons": [],
"item_codes": []
}
}
],
"warnings": [
{
"error": {
"message": "1 item not found.",
"error_code": 2000
},
"meta": {
"items": [
{
"item_code": "133631"
}
]
}
}
]
}
4XX Errors
Error responses return either a single error or multiple errors.
| HTTP Code | Cause | Error Message | Error Code | Error Meta |
|---|---|---|---|---|
400 | User Not Found | "User Not Found" | 1001 | {"key":"user_id"} |
400 | Duplicate items were provided | "Duplicate items provided for this order." | 2007 | {"duplicate_items":[{"item_rrc":1234,"item_upc":"0001234567892","line_num":2}],"error_name":"DuplicateItemsError"} |
400 | Invalid Quantity, expected weight | "One of these items had an invalid quantity amount, 0001234567892 expected weight" | 2012 | {"upc":"0001234567892","item_code":"0001234567892","expected_param":"weight","error_name":"WrongQuantityParameterError"} |
400 | Invalid Quantity, expected count | "One of these items had an invalid quantity amount, 0001234567892 expected count" | 2012 | {"upc":"0001234567892","item_code":"0001234567892","expected_param":"count","error_name":"WrongQuantityParameterError"} |
400 | Invalid Quantity, expected count or weight | "One of these items had an invalid quantity amount, 0001234567892 expected count or weight" | 2012 | {"upc":"0001234567892","item_code":"0001234567892","expected_param":"count or weight","error_name":"WrongQuantityParameterError"} |
400 | Invalid location code | "Specified store is not available for pickup." | 1001 | {"key":"location_code"} |
400 | Missing location code | "can't be blank" | 1001 | {"key":"location_code"} |
400 | Invalid items | "1 item not found." | 2000 | {"upcs":["123"],"items":[{"item_upc":"123"}],"error_name":"ItemNotFoundError"} |
400 | Insufficient items to meet order pass threshold | "1 item not found. Insufficient items to meet order pass threshold." | 2008 | {"upcs":["123"],"items":[{"item_upc":"123"}],"item_found_ratio":0.5,"min_item_found_ratio":0.8,"total_cost_cents":1000,"min_total_cost_cents":2000,"error_name":"InsufficientItemsError"} |
403 | User Not Active | "User Not Active" | null | Not applicable |
404 | Resource not found | "Resource not found" | 4000 | Not applicable |