Order API
The v3 Order API is described in more detail in the Swagger definition. Here is a summary of the endpoints.
Method | Endpoint | Description |
---|---|---|
GET | /api/v3/orders | Get orders by contact Gets all orders for a contact. Returns a paged result with links that can be used to get the next/previous result set (by default 10 per request). |
POST | /api/v3/orders | Register new order Creates an order. The creation is asynchronous. Use the information in the response to follow the progress and catch any errors OR send an embedded order action in the payload which will be used when the new order is created. |
GET | /api/v3/orders/{orderId} | Get specific order Gets a specific order by its unique order identifier. If the optional contactId is supplied, a verified check is made that the order is connected to the contact. |
PUT | /api/v3/orders/{orderId} | Replace order Replaces an order. The replacement is asynchronous. Use the information in the response to follow the progress and catch any errors OR send an embedded order action in the payload which will be used when the order is replaced. Note that the order must be replaced entirely and not partially. |
DELETE | /api/v3/orders/{orderId} | Delete order Delete an orders. The deletion is asynchronous. Use the information in the response to follow the progress and catch any errors. |
GET | /api/v3/orders/jobs/{jobId} | Get status of the asynchronous request Returns job status of the request made to change an order. All endpoints that create or change orders are asynchronous. These requests return a "201 Accepted" and a link to this endpoint where the client can poll for the progress of the change. If the request is successful, the return is a "302 Redirect" to the updated resource. If the request cannot be processed, the return is an Error. |
POST | /api/v3/orders/{orderId}/action | Trigger action events for a specific order. |
POST | /api/v3/orders/{orderId}/change-status | Update the internal and/or external status of a specific order. See section below for details. |
POST | /api/v3/orders/{orderId}/change-delivery | Update delivery method, tracking information, or delivery date on an existing order. See section below for details. |
The API uses an asynchronous pattern. This means that when you send in an order, it is received, stored and validated in separate processes. This means you won't know beforehand exactly how long it will take for your change to be applied. This also applies when a change is made to an existing order's status or to the delivery data attached to that order.
Reacting to a requested change
When you request for an order to be changed or created in the system, you might then want to react to it, for example by sending a confirmation email. There are two ways you can handle this:
Use the job reference ID that is returned in the response to poll Engage and see when the requested change is done (which is when the job status has the value "Completed").
include an embedded order action in the payload of your update/create request to instruct Engage what to do when the change is completed. This is similar to sending an order action to the /action endpoint, except you don't have to poll for "Completed" status. See more about order actions here.
If using option 2, the order action parameter you'll send in the request payload will have this structure:
... "orderAction": { "action": "ConfirmOrder", "language": "en-US", "data": { ... } } ...
Field | Type | Description |
---|---|---|
action | string | ConfirmOrder, ConfirmDelivery, ConfirmShipment, ConfirmCancellation, ConfirmCompletion, Custom |
language | string | Optional UI language tag |
data | string | Custom personalization data, used by the automation trigger |
This order action, as soon as the change you've requested is completed, will cause the Order Action automation trigger to be executed with whatever data you've placed in the "data" property. For example, to send an email.
Caution
When you POST or PUT an order containing an embedded order action, be aware that the embedded action will only be executed if the order is successfully processed and reaches the status “Completed”. If processing fails, due to data validation errors for example, any embedded action will be discarded and may need to be applied manually. To be absolutely sure, extra verification using the job ID can be added.
Steps in the order handling process
Here are the general steps in the order handling process:
Important
Only one order with the same orderId will ever be created.
The order request is posted to the /orders endpoint, where the format is validated.
If the format is valid then "202 Request has been accepted" will be received in the response along with a jobId, a status, the orderId and href, a HTTPS link at the job-status endpoint.
If the order format you sent was wrong, you'll get the response "400 Bad Request" along with a list of errors.
If an order with that orderId already exists, you'll get "409 Order already exists".
Due to asynchronous processing, in a high load scenario multiple requests might create the same order with the same orderId. Here the API might reply “202 Request has been accepted” but the order might already has already been created by another request. The job status endpoint in that case will respond with “409 Order already exists”.
There is also the case where the order data has the correct format, but the contact given does not exist in Engage. The system will indicate this by returning a status of "CompletedWithErrors". If this happens, you cannot continue, for example to try and send an action for that order. In this case, you will have to delete the order and create the contact first. Then you can try registering the order again.
The order is now put into order storage.
After the order is stored, the job status endpoint will return a 200 OK with Status: Completed.
Later, the order is connected to a contact and the article and store references are validated.
If a contact is missing a warning is added to the Integration log.
If article or store references are incorrect, a warning is logged to the integration log.
This process is easiest to navigate if you follow this pattern:
Create the order and ensure you get a "202 Request has been accepted" with a jobId in the response. If you intend to use an embedded order action, make sure to place it in your request payload.
The next step depends on your integration needs:
If you have no further processing to do on your side, you are done. The "202 Request has been accepted" response means that Engage has received the order and will process and store it.
If you need to continue working with the order, poll the status endpoint with the jobId until you get a 200 OK with Status: Completed which means the order has been stored and is ready to use. Or, if you sent an embedded order action in the payload, this will now be automatically triggered.
Important
When the errorDetails value is "Version conflict", it indicates that a concurrent operation has been detected. This happens when more than one request tries to perform an update on the same order. The first request starts processing and creates / updates the order asynchronously. A subsequent request, arriving while the first is still finalizing the update, will trigger a version conflict error because the order has already been saved or updated by the first request. This mechanism ensures that every order is created or updated only once.
More about change-status and change-delivery
These asynchronous endpoints are used for updating the status and delivery details of existing orders. These are useful when you need to keep order information in sync with external systems like warehouses, logistics providers, or ERPs, without replacing the entire order.
Change order status
The endpoint used to change the order status is:
POST /api/v3/orders/{orderId}/change-status
Important
This endpoint is asynchronous. It returns a job ID which you can use to track the progress of the update. Alternatively you can send an order action in the payload as described above.
Example payload:
{ "status": "InProgress", "externalStatus": "Picked", "lastChangedAt": "2025-06-09T10:55:00Z", "orderAction": { "action": "ConfirmOrder", "language": "en-US", "data": { ... } } }
Field | Type | Description |
---|---|---|
status | string | Current status of order, for example "InProgress", "Completed" |
externalStatus | string (max 255 chars) | Free-text external status ("Reserved", "Shipped") |
lastChangedAt | ISO 8601 datetime | Timestamp indicating the last change on the order |
orderAction | Object | Optional. The data that will be sent to the Order Action automation trigger as soon as the requested change is completed. |
The expected response is "202 Accepted" along with a location header you can poll for the status.
Change order delivery
This endpoint allows you to update the delivery method, the tracking information, or the delivery date for an existing order.
POST /api/v3/orders/{orderId}/change-delivery
Example payload:
{ "method": "DHL Home Delivery", "trackingNumber": "1234567890", "trackingUri": "https://dhl.com/track?1234567890", "deliveryDate": "2025-06-08T12:00:00Z", "lastChangedAt": "2025-06-09T10:55:00Z", "orderAction": { "action": "ConfirmDelivery", "language": "en-US", "data": { ... } } }
Field | Type | Description |
---|---|---|
method | string (max 255 chars) | Method of delivery |
trackingNumber | string (max 255 chars) | Tracking number for the delivery. |
trackingUri | URI | Tracking URI for the delivery. |
deliveryDate | ISO 8601 datetime | Expected delivery date/time |
lastChangedAt | ISO 8601 datetime | Timestamp indicating the last change on the order |
orderAction | Object | Optional. The data that will be sent to the Order Action automation trigger as soon as the requested change is completed. |
The expected response is "202 Accepted" along with a location header you can poll for status.
Use cases
Fulfillment Systems:
Update delivery status post-shipment with real-time data from logistics providers (e.g., DHL, PostNord, Bring).
Warehouse Automation:
Mark an order as “Picked” or “Packed” once physically handled, syncing external warehouse workflow with order status in Voyado.
Omnichannel Coordination :
Retailers using hybrid logistics (e.g., ship-from-store, click and collect) can ensure that Voyado reflects accurate fulfillment progress.
Other notes
Omitted fields are treated as intentional nulls and stored as null.
Both endpoints require a valid orderId.
Validation errors and missing orders return 400 or 404 respectively.