Place an order with a delivery option

Updated May 29, 20263 min read

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 Camera came from one location and the Laptop from 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, not id. The delivery_option.code is your stable identifier. The id (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_allocated or trigger auto_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.