post
https://www.locally.com/headless/api/1.0/cart/delivery/options/used
Select the delivery option for the cart.
Request Parameters
🏷️ header · unmarked parameters are query params
| Parameter | Type | Required | Description |
|---|---|---|---|
Locally-Api-Token 🏷️ | string | Yes | Locally API token must be passed in the header to authenticate the API consumer. |
hash | string | Yes | The hash of the cart. |
delivery_estimate_id | string | Yes | The delivery estimate ID to select. |
Example Request
curl 'https://www.locally.com/headless/api/1.0/cart/delivery/options/used' \
--request POST \
--header 'Locally-Api-Token: {{API_TOKEN}}' \
--url-query 'hash={{CART_HASH}}' \
--url-query 'delivery_estimate_id=928101'const response = await fetch(
'https://www.locally.com/headless/api/1.0/cart/delivery/options/used?hash={{CART_HASH}}&delivery_estimate_id=928101',
{
method: 'POST',
headers: { 'Locally-Api-Token': '{{API_TOKEN}}' }
}
);
const data = await response.json();import requests
response = requests.post(
'https://www.locally.com/headless/api/1.0/cart/delivery/options/used',
params={
'hash': '{{CART_HASH}}',
'delivery_estimate_id': '928101'
},
headers={'Locally-Api-Token': '{{API_TOKEN}}'}
)
data = response.json()hash and delivery_estimate_id are passed in the query string — the request takes no body. delivery_estimate_id is the delivery_estimate_id value of a delivery option returned by Get delivery options.
Example Response
{
"success": true,
"data": {
"status": 1,
"status_code": 200,
"message": "Delivery options selected successfully",
"data": {
"id": 4821,
"delivery_carrier_id": 2,
"cart_id": 1523847,
"store_id": 37175,
"is_test": 0,
"status": 0,
"carrier_proprietary_id": "",
"customer_fee": 6.99,
"carrier_fee": 6.99,
"tip_amount": "0.00",
"chosen_estimate_id": 928101,
"used_estimate_id": 928101,
"tracking_code": "",
"pickup_ready_by": "2026-07-16 15:30:00",
"estimated_pickup_at": "2026-07-16 15:45:00",
"estimated_dropoff_at": "2026-07-16 16:20:00",
"scheduled_dispatch_at": null,
"delivery_estimates": "",
"delivery_carrier_payloads": "",
"delivery_people": "",
"created_at": "2026-07-16 14:02:11",
"updated_at": "2026-07-16 14:05:38",
"fingerprint": "",
"dropoff_picture_url": "",
"signature_picture_url": "",
"last_error": null,
"shipping_label_url": null,
"label_options": null,
"proprietary_tracking_code": null
},
"session": {
"id": "4f6d0e2b8c1a9e3d5b7f0a2c4e6d8b1a3c5e7f90"
}
},
"msg": ""
}Response Explanation
success— Boolean outcome of the call. Whenfalse, the response also carries a top-levelerror_codeand explanatorymsg— always checksuccess, not just the HTTP status.data.status— Inner envelope from the shared cart controller: a1/0result flag (booleans serialize as integers) with its own HTTP-stylestatus_codeand human-readablemessage.data.data— The order's delivery record. It exists only once the order is placed as a delivery order; without one this endpoint returns 404Delivery option not found.data.data.is_test— Mirrors the cart's test flag:1for orders placed with atest_*API key. Test deliveries are simulated instead of dispatched to a real carrier — see Testing Your Integration.data.data.status— Delivery lifecycle stage:0pending,1canceled,2pickup,3pickup_complete,4dropoff,5delivered.data.data.customer_fee— Delivery fee the shopper pays, in dollars, locked in at order time.carrier_feeis the carrier's own charge and can differ;tip_amountis a courier tip serialized as a decimal string.data.data.used_estimate_id— The estimate actually dispatched: this call sets it to thedelivery_estimate_idyou passed (0until first set) and re-pointsdelivery_carrier_idaccordingly.chosen_estimate_idremains the shopper's checkout pick.data.data.tracking_code— Tracking URL for courier deliveries once dispatched. Parcel shipments instead populateproprietary_tracking_code(a tracking number) andshipping_label_url; all stay empty ornulluntil dispatch.data.session.id— Locally session ID, returned on every response. Replay it via theLocally-Api-Session-Idheader to persist the shopper's session between calls; expired IDs are transparently replaced with fresh ones.msg— Human-readable error text; empty string on success. In production, unexpected server errors are masked asApp server errorwith alookupreference — see Handling Errors in Production.
200Successful
400Bad Request
401Unauthorized
402Request Failed
403Forbidden
404Not Found
429Too Many Requests
500Server Error

