The REST v2 /orders endpoint currently requires product_id for all order items, making it impossible to add shipping charges, taxes, fees, or discounts. This is a critical blocker for migrating from XML-RPC to REST API before the 2026 deadline.
With the announcement that XML-RPC will be deprecated and brownouts starting in 2025, we’ve begun migrating to REST v2 API.
However, we’ve discovered that the REST v2 /orders endpoint has severe limitations compared to XML-RPC:
What Works 
POST/v2/orders{"order_items":[{"product_id":"123","quantity":1}]}
Result: HTTP 201 - Order created successfully
What Fails 
Attempt 1: Custom Line Item with Price
{"order_items":[{"description":"Shipping Charge","price":10.00,"quantity":1}]}
Result: HTTP 400 - "Unrecognized property: price"
Attempt 2: Using product_id = 0
{"order_items":[{"product_id":0,"description":"Sales Tax","quantity":1}]}
Result: HTTP 400 - "product_id"
Attempt 3: Using item_type
{"order_items":[{"description":"Shipping","item_type":"SHIPPING","price":10.00,"quantity":1}]}
Result: HTTP 400 - "Unrecognized property: item_type"
We also tested REST v1 /orders/{orderId}/items with the same results - it also requires a valid product_id.
The XML-RPC addOrderItem method supports product_id = 0 for custom line items:
// Shipping
addOrderItem(invoice_id, 0, 1, 10.00, 1, “Shipping”, “Standard Shipping”)
// Tax
addOrderItem(invoice_id, 0, 2, 2.50, 1, “Sales Tax”, “CA Sales Tax”)
// Discount
addOrderItem(invoice_id, 0, 7, -5.00, 1, “Discount”, “SAVE10 Coupon”)
// Custom Fee
addOrderItem(invoice_id, 0, 13, 3.00, 1, “Processing Fee”, “”)
This flexibility is essential for e-commerce integrations.
We need the REST v2 /orders endpoint to support custom line items without product_id, similar to XML-RPC capabilities:
Supported item_type Values:
-
PRODUCT(default, requires product_id) -
SHIPPING(custom price, no product_id) -
TAX(custom price, no product_id) -
DISCOUNT(negative price, no product_id) -
FEEorOTHER(custom price, no product_id)
Backward Compatibility:
-
If
product_idprovided: Use product pricing (current behavior) -
If
product_idomitted/null anditem_typespecified: Use custompricefield -
If
priceomitted: Default to 0
Questions for Keap Team
-
Is there a planned timeline for custom line item support in v2?
-
Is there an alternative v2 endpoint we should use for e-commerce orders?
-
Will v1 REST
/orders/{id}/itemsbe enhanced to support custom items? -
What is the recommended migration path for integrations using addOrderItem with product_id = 0?