Order status updates tell Releva where an order is after it has been paid for — confirmed, shipped, out for delivery, delivered, cancelled, refunded. They power post-purchase workflows, and they are what lets the AI sales agent answer “where is my order?” with a real status and a tracking link instead of an apology.
Do I need to call it? #
Only if you want post-purchase communication or order-status answers in chat. Nothing else in Releva depends on it: revenue, attribution and segmentation all come from the Cart Paid API, and a status update never changes any of them.
If your shop runs on Shopify, Magento 1 or Magento 2, our plugin already sends these events for you and there is nothing to build. On any other platform — or for statuses that live in your ERP rather than your shop — send them yourself as described below.
Endpoint #
Order statuses are sent as events, on the same endpoint as any other custom event, with the reserved action orderStatusChanged.
| URL | POST https://releva.ai/api/v0/events |
| Authentication | Authorization: Bearer <secretKey> — the secret key of the domain the order belongs to. |
| Content type | application/json |
| Max request body | 800 KB. |
Request Parameters #
Send one event each time an order’s status changes:
curl -H 'Content-Type: application/json' -H 'Authorization: Bearer <secretKey>' -XPOST https://releva.ai/api/v0/events -d'{
"events": [
{
"action": "orderStatusChanged",
"orderId": "orderId1",
"email": "user@email.com",
"profileId": "customer-77",
"timestamp": "2026-09-22T10:15:30.000Z",
"tags": ["shipped"],
"custom": {
"string": [
{"key": "state", "values": ["shipped"]},
{"key": "statusLabel", "values": ["On its way to you"]},
{"key": "orderName", "values": ["#1001"]},
{"key": "trackingNumber", "values": ["1Z999AA10123456784"]},
{"key": "trackingCompany", "values": ["Speedy"]},
{"key": "trackingUrl", "values": ["https://speedy.bg/track/1Z999AA10123456784"]}
]
},
"products": [
{"id": "12345_en", "variantId": "1001", "quantity": 2}
]
}
]
}'
| Field | Type | Description |
|---|---|---|
events[].action |
String | Always orderStatusChanged for an order status update. |
events[].orderId |
String | The order this status belongs to, exactly as you sent it to the Cart Paid API. Formally optional on this endpoint, but a status update without it belongs to no order and will never be found — always send it. |
events[].email |
String (Optional) | The customer’s email. At least one of email, phoneNumber or profileId is required. |
events[].phoneNumber |
String (Optional) | The customer’s phone number, in international format (+ followed by digits). |
events[].profileId |
String (Optional) | Your own customer id. Use the same identifiers you used on the order, so the status lands on the same profile. |
events[].timestamp |
ISO-8601 String (Optional) | When the status changed. Must include the time and a timezone offset, e.g. 2026-09-22T10:15:30.000Z. Defaults to now. |
events[].tags |
Array[String] | The status itself, as a single-entry array — ["shipped"], ["delivered"], ["cancelled"]. This is what workflows match on. |
events[].custom |
Object (Optional) | The status details — see the next section. |
events[].products |
Array[Object] (Optional) | The order’s line items (id, and optionally variantId and quantity), so the agent can show the customer what is in the shipment. Use the same product ids as on the order. |
The status details #
Everything a customer may be shown about the order travels in custom.string, and only these keys are recognised:
| Key | Description |
|---|---|
state |
The status code, matching what you put in tags — confirmed, shipped, in_transit, out_for_delivery, delivered, cancelled, refunded, or whatever vocabulary your platform uses. |
statusLabel |
What the customer should actually be told, in their language — “On its way to you”, “Ready for pickup”. Send it whenever your status codes are internal vocabulary a customer would not understand (an ERP code such as zeron_completed). When present, this is what the customer sees and the raw code is never shown. Free text, trimmed to 100 characters. |
orderName |
The order number as the customer knows it — #1001, EN1234 — when it differs from orderId. This is what a customer types when asked for their order number, so send it if you have it. Send it on the paid cart too, so both agree. |
trackingNumber |
The carrier’s tracking number. |
trackingCompany |
The carrier’s name. |
trackingUrl |
The tracking page the customer can open. |
Any other custom field you send is stored on the event and can be used in segments and workflows, but it is never surfaced to a customer in chat. That is deliberate: internal fields such as a cancellation reason can carry information a customer should not read (“suspected fraud”, “payment declined”), so the customer-facing side is an explicit list rather than a pass-through.
How the statuses are used #
- Workflows.
orderStatusChangedcan start a workflow, so you can send a “your order has shipped” email, a delivery notification, or a review request a few days after delivery. Branch on the value intags. - Order status in chat. When a customer asks about an order, the agent finds it by order number and answers with the latest status, the items, and the tracking link if you sent one. It looks at orders from the last 30 days, at most the 10 most recent, and up to 10 items per order.
- Revenue is untouched. A status update never adds to or subtracts from revenue, whatever
productsit carries. To take money back out of your reporting, use the Refund API — and send both when an order is refunded, as our Shopify connector does.
Send one event per status change. Releva keeps the whole history, and treats the most recent event per order as the current status — so an out-of-order or late delivery of an older status will not overwrite a newer one, as long as each event carries the timestamp of the change it describes.
Enabling order status answers in chat #
Two things have to be true for the AI sales agent to answer order-status questions: your platform’s integration has to be sending these events, and the order-status lookup has to be switched on for your store. If your shop sends status events through a custom integration rather than one of our plugins, ask your Releva contact to enable the lookup — otherwise the agent will decline to answer rather than guess at a status it cannot see.
Response Format #
A successful response will return HTTP Status 202 with an empty response body ({}).
An error response will return a HTTP 4xx or 5xx status code and have the following structure:
{
"message": "A description of the error and how to fix it, if it's a client error."
}
| Status | Meaning |
|---|---|
| 202 | Accepted. Events carrying no identifier at all are skipped; the rest of the batch is still recorded. |
| 400 | The request body failed validation, no event carried an identifier, or the Authorization header is missing, malformed or does not match a known domain. message names the offending field. |
| 402 | The domain is disabled. Please reach out to support@releva.ai to enable it. |
| 413 | The request body is larger than 800 KB. Send the events in smaller batches. |