Place a home delivery order
The foundational order-ingestion flow. Your storefront posts a customer order to Carriyo with a single delivery method and address; Carriyo's allocation engine picks the fulfillment location and returns the resulting Order with its fulfillment orders attached. No checkout-side delivery option, no collection method: just standard home delivery.
Scenario
A customer in London is buying two accessories, a pair of
wireless earbuds and a USB-C cable, total £92.98. You send the order to
Carriyo with a delivery_method of DELIVERY and a
single shipping address. Carriyo's allocation engine has both
items in stock at the London warehouse and produces a single
fulfillment order.
Prerequisites
- API credentials: see Getting started for the one-time setup.
- At least one fulfillment location configured for the merchant with inventory for the SKUs being ordered.
- Auto-allocation enabled for the merchant (the default). With
auto-allocation off, the order would land in
openand wait for manual allocation, see Allocation engine.
Create the order
Submit the order to Carriyo. No delivery_option is
set: Carriyo allocates against inventory without a customer-chosen
delivery 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_method": "DELIVERY",
"order_date": "2026-05-10T09:15:22.000Z",
"sales_channel": "web",
"payment": {
"currency": "GBP",
"order_total": 92.98
},
"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-EAR-003",
"sku": "SKU-EAR-003",
"description": "Wireless Earbuds",
"quantity": 1,
"unit_price": 79.99
},
{
"product_id": "SKU-CBL-004",
"sku": "SKU-CBL-004",
"description": "USB-C Cable",
"quantity": 1,
"unit_price": 12.99
}
]
}'
The response carries the created Order with allocation already applied. The two items are both available at the London warehouse, so Carriyo produces a single fulfillment order:
{
"tenant": "your-tenant",
"order_id": "OMP1A8B7C2D9KZ",
"merchant": "ACME",
"partner_order_reference": "YOUR_ORDER_REF",
"order_date": "2026-05-10T09:15:22.000Z",
"sales_channel": "web",
"status": "allocated",
"payment": {
"currency": "GBP",
"order_total": 92.98
},
"customer": {
"contact_name": "Oliver Bennett",
"contact_email": "oliver.bennett@example.co.uk",
"contact_phone": "+44 7700 900123"
},
"delivery_address": {
"contact_name": "Oliver Bennett",
"address1": "45 Gloucester Place",
"address2": "Marylebone",
"city": "London",
"postcode": "W1U 8HU",
"country": "GB"
},
"line_items": [
{ "id": "K7M3X", "sku": "SKU-EAR-003", "quantity": 1, "unit_price": 79.99 },
{ "id": "P9N4R", "sku": "SKU-CBL-004", "quantity": 1, "unit_price": 12.99 }
],
"fulfillment_orders": [
{
"fulfillment_order_id": "FOMP1A8B7VJAMFZ",
"location_id": "ACCOUNT_b5c325c0-edeb-4559-803c-d1b0ca3ec9c2",
"status": "allocated",
"delivery_method": "DELIVERY",
"delivery_address": {
"contact_name": "Oliver Bennett",
"address1": "45 Gloucester Place",
"address2": "Marylebone",
"city": "London",
"postcode": "W1U 8HU",
"country": "GB"
},
"line_items": [
{ "id": "K7M3X", "quantity": 1, "status": "allocated" },
{ "id": "P9N4R", "quantity": 1, "status": "allocated" }
],
"creation_date": "2026-05-10T09:15:23.105Z"
}
],
"creation_date": "2026-05-10T09:15:23.000Z"
}
What just happened
- The Order was accepted and immediately moved to
allocated. - The allocation engine found both line items in stock at one fulfillment location (the London warehouse), so it produced a single fulfillment order, the simplest possible outcome.
- Both line items are in
allocatedstatus under the FO and will move toprocessingand thenfulfilledas the warehouse picks, packs, and ships them. - The FO will produce a shipment when it's booked with a carrier.
Variation: items split across locations
The request you send is identical, but the response can change if
no single location has stock for every line item. In that case the
allocation engine produces multiple fulfillment orders, one
per chosen location. For example, if the earbuds are in stock at
the London warehouse and the cable is only in stock at the
Manchester warehouse, the fulfillment_orders array would contain
two entries:
"fulfillment_orders": [
{
"fulfillment_order_id": "FOMP1A8B7VJAMFZ",
"location_id": "ACCOUNT_b5c325c0-edeb-4559-803c-d1b0ca3ec9c2",
"status": "allocated",
"delivery_method": "DELIVERY",
"delivery_address": { /* same shipping address */ },
"line_items": [{ "id": "K7M3X", "quantity": 1, "status": "allocated" }]
},
{
"fulfillment_order_id": "FOMP1A8B7XJ9YZ2",
"location_id": "ACCOUNT_64c72d0e-19f5-4ec1-b572-d51c97688606",
"status": "allocated",
"delivery_method": "DELIVERY",
"delivery_address": { /* same shipping address */ },
"line_items": [{ "id": "P9N4R", "quantity": 1, "status": "allocated" }]
}
]
Both FOs ship to the same address (the customer didn't ask for
two destinations) but originate from different warehouses, so
each will produce its own shipment. The Order itself remains a
single record with status: allocated.
How splits are decided is covered on the Allocation engine page; Splits and merges explains the downstream consequences.
Pitfalls
partner_order_referenceis the dedupe key. Re-sending the same value returns an error rather than upserting. Generate it deterministically per customer order and reuse it on retries.- Payment is amount-based, not mode-based. Orders don't carry
a
payment_modeenum. Express cash-on-delivery by settingpayment.payment_on_deliveryto the amount due at delivery (omit or leave at zero for fully prepaid orders). - Allocation can land in
partially_allocated. If some items can be allocated and others can't (e.g. stock-out), the Order status ispartially_allocatedrather thanallocated. Listen for the order webhook and send the unallocated lines to ops.