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 Acceptedimmediately - Order is queued for background processing
- Webhook
order:createdconfirms successful creation - Webhook
order:failedreports creation failures - You MUST configure webhooks to receive operation results
Order Lifecycle
Orders in the UOS system follow a defined lifecycle:
- Creation: An order is created with status
pending - Processing: The order is being prepared or validated with status
processing - Picking: The order items are being picked with status
picking - Picked: All items have been picked with status
picked - Fulfillment: The order is:
- Shipped with status
shipped(for delivery orders) - Collected with status
collected(for pickup orders)
- Shipped with status
- 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.
| Value | Type | Description |
|---|---|---|
"0" | DELIVERY | Home delivery service - order will be shipped to customer |
"1" | CLICK_AND_COLLECT | Store pickup/collection service - customer collects from store |
"2" | SMART_POST | Parcel 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 organizationcat_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 IDstatus: Filter by order statusorder_number: Filter by order numberdate_from: Filter orders created on or after this datedate_to: Filter orders created on or before this datepage: 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-Originto 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_requestedandcustomer_requestare 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.