Place an order with a delivery option
This recipe covers the end-to-end flow that ties Carriyo's checkout-time
delivery options to the order allocation engine. The shopper picks a
delivery option on your storefront; you pass the chosen option's code
back to Carriyo when creating the order; Carriyo's allocation engine uses
the option to constrain which fulfillment locations are eligible.
Scenario
A customer in London is checking out two items in a £763.74 cart.
After entering the delivery address, your storefront calls Carriyo
to fetch the delivery options that match the cart and the address.
The customer picks Express Delivery. You then create the Order
in Carriyo, passing the delivery_option.code so allocation knows
which option was sold.
Prerequisites
- API credentials: see Getting started for the one-time setup.
- At least one delivery option configured for the merchant in the Dashboard, with associated fulfillment locations.
- Inventory at one or more of those fulfillment locations.
Step 1, fetch delivery options
Call Carriyo with the cart, the customer's address, and the set of fulfillment locations you want to consider. The locations passed in are the candidate pool; Carriyo intersects them with the locations configured on each delivery option.
curl -X POST 'https://api.carriyo.com/checkout/delivery-options' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'tenant-id: YOUR_TENANT_ID' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"merchant": "ACME",
"delivery_methods": ["DELIVERY"],
"payment": {
"currency": "GBP",
"order_total": 763.74
},
"line_items": [
{
"product_id": "SKU-CAM-001",
"quantity": 1,
"weight": { "value": 0.5, "unit": "kg" }
},
{
"product_id": "SKU-LAP-002",
"quantity": 1,
"weight": { "value": 1.5, "unit": "kg" }
}
],
"customer": {
"country": "GB",
"city": "London",
"address1": "45 Gloucester Place",
"postcode": "W1U 8HU",
"contact_name": "Oliver Bennett"
},
"fulfillment_locations": [
{ "partner_location_code": "WH-UK-01" },
{ "partner_location_code": "STORE-UK-LON-01" },
{ "partner_location_code": "STORE-UK-MAN-01" },
{ "partner_location_code": "STORE-UK-EDI-01" },
{ "partner_location_code": "STORE-UK-BHM-01" }
]
}'
The response is a list of options that passed every condition the merchant configured (geographic, weight, value, etc.):
[
{
"id": "012694a1-04af-42fd-ba4d-beeaca2034ed",
"delivery_method": "DELIVERY",
"code": "EXPRESS_DELIVERY",
"name": "Express Delivery",
"carrier_account_id": "782b9b83-6d95-4468-8998-38f28b5a7c11",
"description": "Next-day delivery across the UK.",
"shipping_fee": { "amount": 4.99, "currency": "GBP" },
"estimated_arrival_to": "2026-05-10T18:00:00.000Z"
},
{
"id": "f29acd11-34c2-4874-96f6-4a2530a82886",
"delivery_method": "DELIVERY",
"code": "PREMIUM_LONDON",
"name": "Premium London Delivery",
"carrier_account_id": "1ee1b219-d64e-4e67-8bc4-ff1c8c955457",
"description": "Same-day delivery within Greater London.\nFree for orders over £50.",
"shipping_fee": { "amount": 9.99, "currency": "GBP" },
"estimated_arrival_to": "2026-05-09T18:00:00.000Z"
}
]
Render each entry as a delivery choice on the checkout. Show
name, description, shipping_fee, and estimated_arrival_to.
Step 2, capture the customer's choice
The customer picks Express Delivery. Persist the option's
code (EXPRESS_DELIVERY) on the cart. The code is the bridge to
the order create call: it's stable across deployments, whereas the
option's id is mutable.
Step 3, create the order
Submit the order to Carriyo with delivery_option.code set to the
chosen option:
curl -X POST 'https://api.carriyo.com/orders' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'tenant-id: YOUR_TENANT_ID' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"merchant": "ACME",
"partner_order_reference": "YOUR_ORDER_REF",
"delivery_option": { "code": "EXPRESS_DELIVERY" },
"order_date": "2026-05-08T07:40:08.477Z",
"sales_channel": "web",
"payment": {
"currency": "GBP",
"order_total": 763.74
},
"customer": {
"contact_name": "Oliver Bennett",
"contact_email": "oliver.bennett@example.co.uk",
"contact_phone": "+44 7700 900123"
},
"delivery_address": {
"contact_name": "Oliver Bennett",
"contact_email": "oliver.bennett@example.co.uk",
"contact_phone": "+44 7700 900123",
"address1": "45 Gloucester Place",
"address2": "Marylebone",
"city": "London",
"country": "GB",
"postcode": "W1U 8HU"
},
"billing_address": {
"contact_name": "Oliver Bennett",
"contact_email": "oliver.bennett@example.co.uk",
"contact_phone": "+44 7700 900123",
"address1": "45 Gloucester Place",
"address2": "Marylebone",
"city": "London",
"country": "GB",
"postcode": "W1U 8HU"
},
"line_items": [
{
"product_id": "SKU-CAM-001",
"sku": "SKU-CAM-001",
"description": "Action Camera",
"quantity": 1,
"unit_price": 309.29
},
{
"product_id": "SKU-LAP-002",
"sku": "SKU-LAP-002",
"description": "Laptop 14-inch",
"quantity": 1,
"unit_price": 454.45
}
]
}'
The response carries the created Order with allocation already applied. Carriyo used the chosen delivery option to constrain location selection:
{
"tenant": "your-tenant",
"order_id": "OMOX893M9QYBBD5",
"merchant": "ACME",
"partner_order_reference": "YOUR_ORDER_REF",
"order_date": "2026-05-08T07:40:08.477Z",
"sales_channel": "web",
"status": "allocated",
"payment": { "currency": "GBP", "order_total": 763.74 },
"customer": {
"contact_name": "Oliver Bennett",
"contact_phone": "+44 7700 900123",
"contact_email": "oliver.bennett@example.co.uk"
},
"billing_address": {
"contact_name": "Oliver Bennett",
"contact_phone": "+44 7700 900123",
"contact_email": "oliver.bennett@example.co.uk",
"address1": "45 Gloucester Place",
"address2": "Marylebone",
"city": "London",
"postcode": "W1U 8HU",
"country": "GB"
},
"line_items": [
{
"id": "VUV7D",
"sku": "SKU-CAM-001",
"product_id": "SKU-CAM-001",
"quantity": 1,
"unit_price": 309.29
},
{
"id": "7OL4C",
"sku": "SKU-LAP-002",
"product_id": "SKU-LAP-002",
"quantity": 1,
"unit_price": 454.45
}
],
"fulfillment_orders": [
{
"fulfillment_order_id": "FOMOX893VJAMFZCK",
"location_id": "ACCOUNT_b5c325c0-edeb-4559-803c-d1b0ca3ec9c2",
"status": "allocated",
"delivery_method": "DELIVERY",
"delivery_option": {
"code": "EXPRESS_DELIVERY",
"id": "012694a1-04af-42fd-ba4d-beeaca2034ed",
"name": "Express Delivery"
},
"delivery_address": {
"contact_name": "Oliver Bennett",
"address1": "45 Gloucester Place",
"address2": "Marylebone",
"city": "London",
"postcode": "W1U 8HU",
"country": "GB"
},
"line_items": [{ "id": "VUV7D", "quantity": 1, "status": "allocated" }],
"creation_date": "2026-05-08T18:07:11.621Z"
},
{
"fulfillment_order_id": "FOMOX893VJEIWVQ9",
"location_id": "ACCOUNT_64c72d0e-19f5-4ec1-b572-d51c97688606",
"status": "allocated",
"delivery_method": "DELIVERY",
"delivery_option": {
"code": "EXPRESS_DELIVERY",
"id": "012694a1-04af-42fd-ba4d-beeaca2034ed",
"name": "Express Delivery"
},
"delivery_address": {
"contact_name": "Oliver Bennett",
"address1": "45 Gloucester Place",
"address2": "Marylebone",
"city": "London",
"postcode": "W1U 8HU",
"country": "GB"
},
"line_items": [{ "id": "7OL4C", "quantity": 1, "status": "allocated" }],
"creation_date": "2026-05-08T18:07:11.621Z"
}
],
"creation_date": "2026-05-08T18:07:11.505Z"
}
What just happened
- The Order was accepted and immediately moved to
allocated. - Allocation produced two fulfillment orders because the two
line items couldn't all ship from a single location: the
Action Cameracame from one location and theLaptopfrom another. - Both FOs carry the chosen
delivery_option(EXPRESS_DELIVERY). The allocation engine considered only the locations associated with that option, so location selection respected the customer's choice. - Each FO holds its own
delivery_address(same in this case because the customer picked one shipping address). With a cross-merchant or multi-destination order, FOs can carry different addresses, see the Fulfillment orders page.
Each FO will produce a Shipment when it's booked with a carrier.
Pitfalls
- Pass
code, notid. Thedelivery_option.codeis your stable identifier. Theid(UUID) changes if a merchant deletes and recreates an option. - Allocation can fail. If the chosen delivery option's
associated locations don't carry inventory for the items, the
Order may land in
partially_allocatedor triggerauto_allocation_failed. Listen for the order webhook and escalate a fallback to ops. - Currency must match. The currency on the delivery options request, the option, and the order create payload must match.