Unified Order Service
Home
Getting Started
  • Core API
  • Drone API
Resources
Home
Getting Started
  • Core API
  • Drone API
Resources
    • Core API Reference
    • Orders API Reference
    • Order Items API
    • Channels API Reference
    • Places API Reference
    • Storage Locations API Reference
    • Webhooks API Reference
      • Order Failed Webhook - Operation Type Specification
    • API Keys Reference

Order Items API

This document provides details about the Order Items API endpoints, which allow you to list, retrieve, add, update, and delete items within an order.

List Order Items

Returns a paginated list of items in an order, with optional filtering by status.

URL: /v1/orders/{orderId}/items

Method: GET

Auth required: Yes

Parameters:

NameLocated inDescriptionRequiredType
orderIdpathOrder ID or order numberYesstring
statusqueryFilter items by statusNostring
limitqueryNumber of items per page (default: 20)Nointeger
offsetqueryOffset for pagination (default: 0)Nointeger

Example Request:

GET /v1/orders/ORD12345/items

Success Response:

Code: 200 OK

Content example:

{
  "data": [
    {
      "item_id": "PROD123",
      "sku": "PROD123-VAR1",
      "name": "Product Name",
      "quantity": 2,
      "price": 29.99,
      "status": "pending",
      "image_url": "https://example.com/product-123.jpg",
      "properties": {
        "color": "blue",
        "size": "medium"
      },
      "created_at": "2023-01-15T12:00:00Z",
      "updated_at": "2023-01-15T12:00:00Z"
    },
    {
      "item_id": "PROD456",
      "sku": "PROD456",
      "name": "Another Product",
      "quantity": 1,
      "price": 15.99,
      "status": "pending",
      "image_url": null,
      "properties": {},
      "created_at": "2023-01-15T12:00:00Z",
      "updated_at": "2023-01-15T12:00:00Z"
    }
  ],
  "pagination": {
    "total": 2,
    "limit": 20,
    "offset": 0
  }
}

Error Response:

Code: 404 Not Found

Content:

{
  "error": {
    "code": "ORDER_NOT_FOUND",
    "message": "No order found with ID or order number ORD12345"
  }
}

Get Order Item

Returns detailed information about a specific item in an order.

URL: /v1/orders/{orderId}/items/{itemId}

Method: GET

Auth required: Yes

Parameters:

NameLocated inDescriptionRequiredType
orderIdpathOrder ID or order numberYesstring
itemIdpathItem IDYesstring

Example Request:

GET /v1/orders/ORD12345/items/PROD123

Success Response:

Code: 200 OK

Content example:

{
  "item_id": "PROD123",
  "sku": "PROD123-VAR1",
  "name": "Product Name",
  "quantity": 2,
  "price": 29.99,
  "status": "pending",
  "image_url": "https://example.com/product-123.jpg",
  "properties": {
    "color": "blue",
    "size": "medium"
  },
  "created_at": "2023-01-15T12:00:00Z",
  "updated_at": "2023-01-15T12:00:00Z"
}

Error Response:

Code: 404 Not Found

Content:

{
  "error": "Item not found",
  "message": "No item found with ID PROD123 in order ORD12345"
}

Add Item to Order

Adds a new item to an existing order.

URL: /v1/orders/{orderId}/items

Method: POST

Auth required: Yes

Parameters:

NameLocated inDescriptionRequiredType
orderIdpathOrder ID or order numberYesstring
product_idbodyProduct ID (becomes item_id)Yesstring
variant_idbodyVariant ID (becomes sku)Nostring
namebodyProduct nameNostring
quantitybodyQuantity (must be positive)Yesnumber
pricebodyPrice per unitNonumber
image_urlbodyURL of the product imageNostring
propertiesbodyAdditional product propertiesNoobject

Note: If an item with the same product_id already exists in the order, the quantity will be added to the existing item instead of creating a new one.

Example Request:

POST /v1/orders/ORD12345/items
{
  "product_id": "PROD123",
  "variant_id": "PROD123-VAR1",
  "name": "Product Name",
  "quantity": 2,
  "price": 29.99,
  "image_url": "https://example.com/product-123.jpg",
  "properties": {
    "color": "blue",
    "size": "medium"
  }
}

Success Response:

Code: 201 Created

Content example:

{
  "item_id": "PROD123",
  "sku": "PROD123-VAR1",
  "name": "Product Name",
  "quantity": 2,
  "price": 29.99,
  "status": "pending",
  "image_url": "https://example.com/product-123.jpg",
  "properties": {
    "color": "blue",
    "size": "medium"
  },
  "created_at": "2023-01-15T12:00:00Z",
  "updated_at": "2023-01-15T12:00:00Z"
}

Error Responses:

Code: 400 Bad Request

Content:

{
  "error": "Invalid request",
  "message": "Missing required field: product_id"
}

OR

{
  "error": "Invalid request",
  "message": "Item quantity must be a positive number"
}

Code: 404 Not Found

Content:

{
  "error": {
    "code": "ORDER_NOT_FOUND",
    "message": "No order found with ID or order number ORD12345"
  }
}

Code: 409 Conflict

Content:

{
  "error": "Conflict",
  "message": "Cannot add items to an order with status \"shipped\""
}

Note: Items can only be added to orders with status "draft", "pending", or "created".

Update Order Item

Updates an existing item in an order.

URL: /v1/orders/{orderId}/items/{itemId}

Method: PUT

Auth required: Yes

Parameters:

NameLocated inDescriptionRequiredType
orderIdpathOrder ID or order numberYesstring
itemIdpathItem IDYesstring
namebodyProduct nameNostring
quantitybodyQuantity (must be positive)Nonumber
pricebodyPrice per unitNonumber
statusbodyItem statusNostring
image_urlbodyURL of the product imageNostring
propertiesbodyAdditional product propertiesNoobject

Example Request:

PUT /v1/orders/ORD12345/items/PROD123
{
  "quantity": 3,
  "price": 27.99,
  "status": "picked",
  "image_url": "https://example.com/updated-product-123.jpg"
}

Success Response:

Code: 200 OK

Content example:

{
  "item_id": "PROD123",
  "sku": "PROD123-VAR1",
  "name": "Product Name",
  "quantity": 3,
  "price": 27.99,
  "status": "picked",
  "image_url": "https://example.com/updated-product-123.jpg",
  "properties": {
    "color": "blue",
    "size": "medium"
  },
  "created_at": "2023-01-15T12:00:00Z",
  "updated_at": "2023-01-15T13:30:00Z"
}

Error Responses:

Code: 400 Bad Request

Content:

{
  "error": "Invalid request",
  "message": "Item quantity must be a positive number"
}

Code: 404 Not Found

Content:

{
  "error": "Item not found",
  "message": "No item found with ID PROD123 in order ORD12345"
}

Code: 409 Conflict

Content:

{
  "error": "Conflict",
  "message": "Cannot update items in an order with status \"shipped\""
}

Note: Items can only be updated in orders with status "draft", "pending", "created", or "processing".

Remove Item from Order

Removes an item from an order.

URL: /v1/orders/{orderId}/items/{itemId}

Method: DELETE

Auth required: Yes

Parameters:

NameLocated inDescriptionRequiredType
orderIdpathOrder ID or order numberYesstring
itemIdpathItem IDYesstring

Example Request:

DELETE /v1/orders/ORD12345/items/PROD123

Success Response:

Code: 204 No Content

Error Responses:

Code: 404 Not Found

Content:

{
  "error": "Item not found",
  "message": "No item found with ID PROD123 in order ORD12345"
}

Code: 409 Conflict

Content:

{
  "error": "Conflict",
  "message": "Cannot remove items from an order with status \"shipped\""
}

Note: Items can only be removed from orders with status "draft", "pending", or "created".

Item Fields Reference

The following table describes all fields available in an order item:

Field NameTypeRequiredDescription
item_idstringYesUnique identifier for the item
skustringNoStock keeping unit (variant ID)
namestringNoProduct name
quantitynumberYesQuantity of the item (positive)
pricenumberNoPrice per unit
statusstringNoCurrent status of the item
image_urlstringNoURL of the product image
propertiesobjectNoAdditional product properties
collected_productobjectNoDetails of the actual product collected during fulfillment
created_atstringYesISO 8601 timestamp of creation
updated_atstringYesISO 8601 timestamp of last update

Note: The image_url field is optional and can be null. When provided, it should be a valid URL pointing to the product image.

Collected Product Information

The collected_product field contains detailed information about the actual product that was picked/collected during fulfillment. This field is populated when an item has been physically picked and provides comprehensive details about what was actually collected.

Collected Product Structure

The collected_product object includes:

FieldTypeDescription
idstringUnique identifier of the collected product
amountnumberActual quantity collected
shopkeeper_timestampstring (date-time)When the item was collected by the picker
collectedbooleanWhether the item was successfully collected
eanstringEAN/barcode of the collected product
skustringSKU of the collected product
namestringName of the collected product
pricenumberProduct price
imagesintegerNumber of images available
image_guidarrayArray of image objects for the collected product

Example with Collected Product

{
  "item_id": "PROD123",
  "name": "Original Product",
  "quantity": 2,
  "price": 29.99,
  "status": "picked",
  "collected_product": {
    "id": "COLLECTED-456",
    "amount": 2,
    "shopkeeper_timestamp": "2023-06-01T14:30:00Z",
    "collected": true,
    "ean": "5000112637922",
    "sku": "PROD123-VAR1",
    "name": "Actual Collected Product",
    "price": 29.99,
    "images": 1,
    "image_guid": [
      {
        "id": "img-collected-456",
        "url": "https://example.com/collected-product.jpg",
        "width": 800,
        "height": 600,
        "mime_type": "image/jpeg"
      }
    ]
  }
}

Image Handling

The Unified Order Service provides automatic image handling for order items across different channel types. Here's how images are processed:

Image URL Support

Order items can include product images in multiple ways:

  1. Direct image_url field - At the top level of the item
  2. Properties image_url - Inside the properties object
  3. Substitute suggestions - Each substitute item can have its own image_url

Priority order: properties.image_url > image_url field

Channel-Specific Image Processing

Drone API Integration

When orders are converted to Drone API format, the image handling is automatically enhanced:

  • Items with images get converted to the image_guid structure with default metadata:

    • images: 1 (count)
    • image_guid array with:
      • id: Generated from item ID (e.g., "img-item-123")
      • url: Original image URL
      • width: 1024 (default)
      • height: 1024 (default)
      • mime_type: "image/png" (default)
      • media_type_code: "PICTURE"
      • file_size: 0 (default)
      • created_at: Current timestamp
      • updated_at: Current timestamp
  • Items without images get:

    • images: 0
    • image_guid: [] (empty array)

Example: Order with Images

Input (Salesforce/Standard format):

{
  "items": [
    {
      "item_id": "354645165",
      "name": "Coca Cola Zero 1.25 Ltr",
      "quantity": 2,
      "price": 1.5,
      "properties": {
        "image_url": "https://example.com/coca-cola-zero.jpg",
        "sub_suggestions": [
          {
            "item_id": "354645164",
            "name": "Coca Cola Original Taste 1.25 Ltr",
            "image_url": "https://example.com/coca-cola-original-taste.jpg"
          }
        ]
      }
    },
    {
      "item_id": "654245842",
      "name": "British Chicken Tikka Masala",
      "quantity": 1,
      "price": 4.2,
      "properties": {
        "image_url": null
      }
    }
  ]
}

Output (Drone API format):

{
  "products": [
    {
      "id": "354645165",
      "name": "Coca Cola Zero 1.25 Ltr",
      "images": 1,
      "image_guid": [
        {
          "id": "img-354645165",
          "url": "https://example.com/coca-cola-zero.jpg",
          "width": 1024,
          "height": 1024,
          "mime_type": "image/png",
          "media_type_code": "PICTURE",
          "file_size": 0,
          "created_at": "2023-06-01T12:00:00Z",
          "updated_at": "2023-06-01T12:00:00Z"
        }
      ]
    },
    {
      "id": "654245842",
      "name": "British Chicken Tikka Masala",
      "images": 0,
      "image_guid": []
    }
  ]
}

Best Practices

  1. Use valid URLs: Ensure image URLs are accessible and return valid image content
  2. Include images for better picking: Products with images improve picker accuracy and speed
  3. Optimize image sizes: While the system uses default dimensions (1024x1024), consider the actual image optimization on your end
  4. Handle missing images gracefully: The system automatically handles items without images
  5. Use HTTPS URLs: Preferred for security and compatibility

Supported Channel Types

Image handling is currently supported for:

  • ✅ Salesforce channels - Full support for image_url in properties and substitutes
  • ✅ Drone API channels - Automatic conversion to image_guid structure
  • ✅ Base/Standard format - Direct image_url field support
  • 🔄 Other channel types - May have varying levels of support

For channel-specific image requirements, consult the individual channel documentation.

Substitution Support

Overview

The UOS system supports product substitutions during the picking process. For items to show substitution options in the picker app, they must be properly flagged as substitutable in the order data.

Required Fields for Substitutable Items

For an item to support substitutions, at least one of the following must be provided:

FieldLocationTypeDescription
substitutableitem levelbooleanMain substitution flag - set to true
allowed_substitutionsitem levelarrayArray of substitute item IDs
sub_enabledpropertiesbooleanAlternative substitution flag - set to true
sub_suggestionspropertiesarrayArray of detailed substitute information

Salesforce Channel Requirements

⚠️ Important for Salesforce integrations: To ensure substitution options appear in the picker app, Salesforce channels must include substitution data in their order payloads.

Required Payload Structure

{
  "items": [{
    "item_id": "MAIN-PRODUCT-123",
    "name": "Main Product",
    "quantity": 1,
    "price": 10.99,
    "substitutable": true,  // ✅ REQUIRED: Main substitution flag
    "allowed_substitutions": ["SUB-PRODUCT-456", "SUB-PRODUCT-789"], // ✅ REQUIRED: Substitute IDs
    "properties": {
      "sub_enabled": true,  // ✅ ALTERNATIVE: Can use this instead of substitutable
      "sub_suggestions": [  // ✅ OPTIONAL: Detailed substitute info
        {
          "item_id": "SUB-PRODUCT-456",
          "name": "Substitute Product 1",
          "price": 9.99,
          "barcode": "1234567890123",
          "images": 2,
          "image_guid": [
            {
              "id": "img-sub-456-1",
              "url": "https://example.com/substitute-product-456.jpg",
              "width": 800,
              "height": 600,
              "mime_type": "image/jpeg"
            }
          ]
        },
        {
          "item_id": "SUB-PRODUCT-789",
          "name": "Substitute Product 2", 
          "price": 11.99,
          "barcode": "9876543210987"
        }
      ]
    }
  }]
}

Common Issues (QCOM-887 Type Problems)

❌ Problematic payload (substitutions won't appear):

{
  "items": [{
    "item_id": "MAIN-PRODUCT-123",
    "substitutable": false,  // ❌ Not enabled
    "allowed_substitutions": [], // ❌ Empty
    "properties": {
      "sub_enabled": false,  // ❌ Not enabled
      "sub_suggestions": []  // ❌ Empty
    }
  }]
}

Troubleshooting Substitution Issues

If substitution options are not appearing in the picker app:

  1. Check order data - Verify that substitution flags are set correctly
  2. Review logs - Look for diagnostic messages about substitution flags
  3. Validate payload - Ensure at least one substitution field is properly populated
  4. Test with sample data - Use the correct payload structure above

Diagnostic Logging

The system logs substitution analysis for debugging:

INFO: Item PRODUCT-123 marked as substitutable: explicit=true, sub_enabled=true, has_suggestions=true, has_allowed_subs=true
DEBUG: Item PRODUCT-456 NOT substitutable: no substitution flags or data found

Substitution Data Transformation

The system automatically transforms substitution data between different formats:

  • Simple format: Array of substitute item IDs
  • Detailed format: Full substitute product information
  • Picker app format: Enhanced with images and metadata

For detailed substitution workflow examples, see the Drone API Products documentation.

Last Updated: 12/1/25, 11:31 AM
Prev
Orders API Reference
Next
Channels API Reference