Skip to main content

Order feed

The order feed allows the merchant to push order data into the OpenApp recommendation engine. For every order, the feed contains the purchased basket - product id, ean, quantities and prices - and the identifier of the user who placed it.

info

Orders placed through the OpenApp checkout are ingested into the recommendation engine automatically. Sending them through this feed as well is redundant - re-sending an orderId replaces the stored order, so no harm is done, but there is nothing to gain. Use this feed for orders from your other sales channels (own webshop checkout, mobile app, physical stores).

info

After the initial catalogue ingestion, OpenApp needs time to process the data before order ingestion and recommendations retrieval become available. Until processing completes, the endpoint responds 409 RecommendationsNotReadyException. Wait for confirmation from OpenApp before starting the backfill.

Two usage patterns are supported by the same endpoint:

  • Initial backfill: after activation, push your order history (we recommend at least the last 12 months) in batches to give the engine a warm start. Do not include cancelled orders in the initial backfill; only send cancellations for orders that were previously ingested.
  • Ongoing feed: push new orders as they are placed, individually or in periodic batches (for example hourly).

Request

Orders are pushed by a POST to the following endpoint:

POST {{OpenAppUrl}}/merchant/v1/recommendations/orders

A single request can contain at most 100 orders.

{
"orders": [
{
"orderId": "WS1213ASDZXC231A",
"loggedUser": "user-id-from-webshop",
"createdAt": "2026-06-09T17:23:00.000Z",
"channel": "WEB",
"currency": "PLN",
"products": [
{
"id": "id123-red",
"ean": "5901234123457",
"quantity": 2,
"unitPrice": 6000,
"linePrice": 12000
},
{
"id": "id124",
"ean": "5901234123464",
"quantity": 1,
"unitPrice": 6000,
"linePrice": 6000
}
]
},
{
"orderId": "WS1213ASDZXC231B",
"loggedUser": "user-id-from-webshop",
"status": "CANCELLED",
"createdAt": "2026-06-09T18:05:00.000Z",
"channel": "IN_STORE",
"currency": "PLN",
"products": [
{
"id": "id124",
"ean": "5901234123464",
"quantity": 3,
"unitPrice": 5500,
"linePrice": 16500
}
]
}
]
}

The loggedUser value is the merchant's own stable user identifier - OpenApp does not attempt to associate it with any OpenApp account. Every order must identify the user who placed it.

The product id must match the catalogue variant id. Products not yet known from the catalogue are ignored and reported back in ignoredProducts - the order itself is still ingested. Because re-sending an orderId replaces the stored order, the merchant can re-send a previously rejected or partially ignored order after the next catalogue synchronization to capture the missing products.

Order status and cancellations

The optional status field defaults to CREATED. When a user cancels an order that has already been sent to the feed, re-send it with status: CANCELLED - OpenApp will remove it from the recommendation engine. Because ingestion is an upsert on orderId, the cancellation is applied by replacing the order with its cancelled counterpart.

Response

Orders are ingested independently: a problem with one order does not affect the rest of the batch. OpenApp responds with 200 OK containing the number of accepted orders, a rejected list for orders that failed validation, and an ignoredProducts list for products that were unknown to the catalogue.

{
"accepted": 99,
"rejected": [
{
"orderId": "WS1213ASDZXC231F",
"error": "VALIDATION_FAILED",
"message": "createdAt is missing"
}
],
"ignoredProducts": [
{
"orderId": "WS1213ASDZXC231A",
"productIds": [
"id999"
]
}
]
}

The whole request fails only when the request itself is malformed or too large - see the errors below.

Errors

Error nameCode
OrderValidationException400
TooManyOrdersException413
RecommendationsNotReadyException409