Unified Order Service
Home
Getting Started
  • Core API
  • Drone API
Resources
Home
Getting Started
  • Core API
  • Drone API
Resources
  • Introduction

    • Getting Started
    • System Overview
    • Authentication
  • Core Concepts

    • Working with Orders
    • Working with Channels
    • Places
    • Storage Locations
    • Places Management Dashboard
  • Integration

    • Webhooks
    • Order Status Workflows
    • FCM Push Notifications
  • Advanced Topics

    • API Keys
    • Order Versioning
    • Picking App Integration Guide
    • Subscriptions
    • Cancellation Reasons

Working with Orders

Orders are the central entity in the Unified Order Service. This guide explains how to create, retrieve, update, and manage orders through the API.

IMPORTANT: UNDERSTAND ASYNC OPERATIONS FIRST

Before creating orders, you MUST understand that UOS uses asynchronous processing. When you create an order, you receive an immediate 202 Accepted response, but the order is processed in the background. You will receive the final result via webhook.

Read this first: Asynchronous Platform Architecture

Key Points:

  • API returns 202 Accepted immediately
  • Order is queued for background processing
  • Webhook order:created confirms successful creation
  • Webhook order:failed reports creation failures
  • You MUST configure webhooks to receive operation results

Order Lifecycle

Orders in the UOS system follow a defined lifecycle:

  1. Creation: An order is created with status pending
  2. Processing: The order is being prepared or validated with status processing
  3. Picking: The order items are being picked with status picking
  4. Picked: All items have been picked with status picked
  5. Fulfillment: The order is:
    • Shipped with status shipped (for delivery orders)
    • Collected with status collected (for pickup orders)
  6. Completion: The order is fully processed with status completed

Alternative paths:

  • Cancellation: The order is cancelled with status cancelled
  • Failure: The order processing failed with status failed

Working with Channel-Specific Schemas

Different sales channels have unique requirements for order data. The Unified Order Service provides channel-specific schemas to help you correctly format orders for each channel.

Getting the Base Schema

To retrieve the base order schema that applies to all channels:

curl -X GET "https://api.uos.example.com/v1/channels/base-schema" \
  -H "Authorization: Bearer YOUR_API_KEY"

Getting a Channel-Specific Schema

To retrieve the schema for a specific channel:

curl -X GET "https://api.uos.example.com/v1/channels/{channelId}/order-schema" \
  -H "Authorization: Bearer YOUR_API_KEY"

This endpoint returns a JSON Schema that defines:

  • Required fields specific to the channel
  • Field formats and validations
  • Channel-specific properties

Channel-Specific Examples

Each channel type has different requirements. For example:

Uber Eats Orders

Uber Eats orders require specific fields like food_type for items and restaurant information:

{
  "channel_id": "uber-eats-channel-123",
  "order_number": "UE-1234567890",
  "order_date": "2023-08-15T14:30:00Z",
  "items": [
    {
      "item_id": "item-1234",
      "name": "Double Cheeseburger",
      "quantity": 2,
      "price": 8.99,
      "image_url": "https://example.com/images/double-cheeseburger.jpg",
      "food_type": "main_course",
      "properties": {
        "customizations": [
          { "name": "No Pickles", "price": 0 },
          { "name": "Extra Cheese", "price": 1.50 }
        ]
      }
    }
  ],
  "channel_specific_data": {
    "restaurant_id": "uber-rest-12345",
    "delivery_info": {
      "estimated_delivery_time": "25-40 minutes",
      "delivery_address": "123 Delivery Ave, San Francisco, CA 94107"
    }
  }
}

Amazon Orders

Amazon orders require specific fulfillment information:

{
  "channel_id": "amazon-channel-123",
  "order_number": "113-1234567-8910111",
  "order_date": "2023-08-15T14:30:00Z",
  "items": [
    {
      "item_id": "ASIN-B0123456",
      "name": "Product Name",
      "quantity": 1,
      "price": 29.99,
      "image_url": "https://example.com/images/amazon-product.jpg",
      "properties": {
        "amazon_sku": "SKU12345",
        "condition": "new"
      }
    }
  ],
  "channel_specific_data": {
    "amazon_order_id": "113-1234567-8910111",
    "marketplace_id": "ATVPDKIKX0DER",
    "fulfillment_channel": "MFN"
  }
}

Formatting Order Responses

You can request orders in their specific channel format by adding the format=channel parameter:

curl -X GET "https://api.uos.example.com/v1/orders/{orderId}?format=channel" \
  -H "Authorization: Bearer YOUR_API_KEY"

This returns the order formatted according to the channel's specifications, which can be useful when you need to present channel-specific data to users or integrate with external systems.

Delivery Types

Orders can specify a delivery type to indicate how the order should be fulfilled. The delivery type is specified within the shipping information structure for better organization and DTS compliance.

ValueTypeDescription
"0"DELIVERYHome delivery service - order will be shipped to customer
"1"CLICK_AND_COLLECTStore pickup/collection service - customer collects from store
"2"SMART_POSTParcel locker or post office pickup - delivered to pickup point

DTS-Compliant Structure (Recommended)

The delivery type should be specified within the shipping_info.delivery_slot structure:

{
  "channel_id": "channel-123",
  "order_number": "ORD-001",
  "shipping_info": {
    "method": "delivery",
    "delivery_slot": {
      "date": "2025-10-08",
      "start_time": "12:00",
      "end_time": "13:00",
      "delivery_type": "0",
      "delivery_window": "12:00-13:00",
      "time_zone": "UTC"
    }
  }
  // ... other order fields
}

Legacy Support

For backward compatibility, the top-level delivery_type field is still supported:

{
  "channel_id": "channel-123",
  "order_number": "ORD-001",
  "delivery_type": 1,  // Legacy format (integer)
  // ... other order fields
}

Note: The DTS-compliant structure takes precedence when both formats are present.

Product Arrays

Orders support multiple ways to organize products for enhanced flexibility and DTS compliance:

DTS-Compliant Structure (Recommended)

Use separate arrays for different types of items:

{
  "channel_id": "channel-123",
  "order_number": "ORD-001",
  "products": [
    {
      "item_id": "80836",
      "name": "[6]Co-op White Finger Rolls 6 Pack",
      "quantity": 1,
      "price": 1.15,
      "cat_1": "BAKERY",
      "cat_1_id": "7000",
      "cat_2": "MORNING GOODS", 
      "cat_2_id": "714",
      "collected_product": {
        "item_id": "5000128733212",
        "quantity": 1,
        "price": 1.15,
        "fulfilment_flags": ["picked"]
      },
      "fulfilment_flags": ["age_restricted", "refrigerated"]
    }
  ],
  "extra": [
    {
      "item_id": "delivery-fee-1",
      "name": "Delivery Fee",
      "quantity": 1,
      "price": 2.99,
      "properties": {
        "fee_type": "delivery"
      }
    }
  ]
}

Enhanced Category Information

Products now support hierarchical categories optimized for picking operations:

  • cat_1/cat_1_id: Primary category (e.g., "BAKERY"/"7000")
  • cat_2/cat_2_id: Secondary category (e.g., "MORNING GOODS"/"714")
  • cat_3/cat_3_id: Tertiary category for fine-grained organization
  • cat_4/cat_4_id: Quaternary category for maximum specificity

Collected Product Information

The collected_product field provides detailed information about items that have been physically picked:

{
  "collected_product": {
    "item_id": "5000128733212",
    "name": "Actual collected product name",
    "quantity": 1,
    "price": 1.15,
    "barcode": "5000128733212",
    "fulfilment_flags": ["picked", "substituted"],
    "properties": {
      "picking_status": "completed",
      "vat_percentage": 20,
      "row_total": 1.15
    }
  }
}

Legacy Support

The traditional items array continues to work for backward compatibility:

{
  "items": [
    {
      "item_id": "PROD-001",
      "name": "Product 1", 
      "quantity": 2,
      "price": 9.99
    }
  ]
}

Creating an Order

To create a new order, send a POST request to the /v1/orders endpoint with the order data.

Example Request

curl -X POST "https://api.uos.example.com/v1/orders" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel_id": "channel-123",
    "order_number": "ORD-001",
    "order_date": "2023-06-01T12:00:00Z",
    "customer_info": {
      "name": "John Doe",
      "email": "john@example.com",
      "phone": "123-456-7890"
    },
    "items": [
      {
        "item_id": "PROD-001",
        "name": "Product 1",
        "quantity": 2,
        "price": 9.99,
        "image_url": "https://example.com/images/product-1.jpg"
      },
      {
        "item_id": "PROD-002",
        "name": "Product 2",
        "quantity": 1,
        "price": 19.99,
        "image_url": "https://example.com/images/product-2.jpg"
      }
    ],
    "totals": {
      "subtotal": 39.97,
      "shipping": 5.00,
      "tax": 4.50,
      "total": 49.47
    },
    "shipping_info": {
      "method": "standard",
      "address": {
        "line1": "123 Main St",
        "city": "Metropolis",
        "postal_code": "12345",
        "country": "US"
      }
    },
    "delivery_type": 0
  }'

Response

{
  "message": "Order creation accepted",
  "jobId": "job-123456",
  "orderData": {
    // The order data you submitted
  }
}

Retrieving Orders

Getting a List of Orders

To retrieve a list of orders, send a GET request to the /v1/orders endpoint.

curl -X GET "https://api.uos.example.com/v1/orders?channel_id=channel-123" \
  -H "Authorization: Bearer YOUR_API_KEY"

Parameters:

  • channel_id (required): Filter orders by channel ID
  • status: Filter by order status
  • order_number: Filter by order number
  • date_from: Filter orders created on or after this date
  • date_to: Filter orders created on or before this date
  • page: Page number for pagination (default: 1)
  • limit: Number of orders per page (default: 10)
  • format: Response format (standard or channel)

Getting a Specific Order

To retrieve a specific order, send a GET request to the /v1/orders/{orderId} endpoint.

curl -X GET "https://api.uos.example.com/v1/orders/order-123" \
  -H "Authorization: Bearer YOUR_API_KEY"

Updating an Order

To update an existing order, send a PUT request to the /v1/orders/{orderId} endpoint with the updated order data.

curl -X PUT "https://api.uos.example.com/v1/orders/order-123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel_id": "channel-123",
    "order_number": "ORD-001",
    "items": [
      // Updated items with image_url fields
    ]
  }'

Updating Order Status

To update only the order status, send a PATCH request to the /v1/orders/{orderId}/status endpoint.

curl -X PATCH "https://api.uos.example.com/v1/orders/order-123/status" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "processing"
  }'

Force Transition Header (Advanced)

For systems that need to bypass status transition validation, you can use the X-Force-Transition header. This is useful when syncing order statuses that have already progressed through intermediate steps in external systems.

curl -X PATCH "https://api.uos.example.com/v1/orders/order-123/status" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Force-Transition: true" \
  -H "X-Command-Origin: your-system-name" \
  -H "X-Correlation-Id: corr-123456" \
  -d '{
    "status": "completed",
    "metadata": {
      "source": "your_system",
      "updated_by": "scheduler"
    }
  }'

Important:

  • ✅ Only forward transitions can bypass validation (e.g., picking → completed)
  • ❌ Backward transitions are always rejected, even with the FORCE header
  • 🔒 Include X-Command-Origin to prevent webhook loopbacks

See Status Workflows for detailed information about force transitions.

Status-Specific Metadata

When updating the status, certain statuses require specific metadata:

Cancelled Status

{
  "status": "cancelled",
  "metadata": {
    "cancellation_reason": "customer_requested",
    "notes": "Customer changed their mind"
  }
}

Note: Both customer_requested and customer_request are accepted for customer-initiated cancellations. See Cancellation Reasons for all valid values.

Picking Status

{
  "status": "picking",
  "metadata": {
    "picker_id": "PICKER123"
  }
}

Shipped Status

{
  "status": "shipped",
  "metadata": {
    "tracking_number": "TRACK123456",
    "carrier": "DHL"
  }
}

Collected Status

{
  "status": "collected",
  "metadata": {
    "collected_by": "John Smith"
  }
}

Order History

Getting Order Version History

To view the history of an order, send a GET request to the /v1/orders/{orderId}/history endpoint.

curl -X GET "https://api.uos.example.com/v1/orders/order-123/history" \
  -H "Authorization: Bearer YOUR_API_KEY"

Getting a Specific Order Version

To retrieve a specific version of an order, send a GET request to the /v1/orders/{orderId}/versions/{version} endpoint.

curl -X GET "https://api.uos.example.com/v1/orders/order-123/versions/2" \
  -H "Authorization: Bearer YOUR_API_KEY"

Getting Order Status History

To view the status history of an order, send a GET request to the /v1/orders/{orderId}/status-history endpoint.

curl -X GET "https://api.uos.example.com/v1/orders/order-123/status-history" \
  -H "Authorization: Bearer YOUR_API_KEY"

Working with Drone API

The Drone API provides specialized endpoints for in-store operations, such as picking and packing. To work with orders in the Drone API:

Getting a List of Orders

curl -X GET "https://api.uos.example.com/dts/drone/orders?store_guid=store-123" \
  -H "Authorization: Bearer YOUR_API_KEY"

Getting Order Details

curl -X GET "https://api.uos.example.com/dts/drone/order/info?orderId=order-123" \
  -H "Authorization: Bearer YOUR_API_KEY"

Getting Order Products (Line Items)

The /order/products endpoint returns comprehensive product information including image data for visual identification during picking:

curl -X GET "https://api.uos.example.com/dts/drone/order/products?orderId=order-123" \
  -H "Authorization: Bearer YOUR_API_KEY"

Note: This endpoint includes image metadata with URLs, dimensions, and format information to support visual product identification during the picking process.

Updating Order Status

curl -X GET "https://api.uos.example.com/dts/drone/order/set_status?orderId=order-123&status=3" \
  -H "Authorization: Bearer YOUR_API_KEY"

Picking App Scope Restriction

The picking app can only set statuses 2 (picking), 3 (picked), and 6 (cancelled). Attempts to set other statuses will return HTTP 422 error. See the Drone API Reference for complete details on allowed transitions.

For more information about the Drone API, refer to the Drone API Reference.

Last Updated: 12/17/25, 7:04 AM
Next
Working with Channels