Contents

Webhooks

Nucleo can call your server when something changes. In the connection's Settings, write your Webhook URL (https only, on a public address) and save. Your key receives the events of its scopes:

EventScopeWhen
order.createdorders:readA new order arrives from the sales channel or through POST /orders, or the merchant creates a replacement order.
order.status_changedorders:readThe order's public status changes (internal steps that keep the same public status send nothing).
shipment.shippedorders:readA shipment leaves: one event per shipment, also when an order ships in several parcels.
return.createdreturns:readA return is opened, or the warehouse receives one nobody announced.
return.status_changedreturns:readThe return's public status changes.

Webhooks are hints, not data: read the order or the return with the API to get its current state. Events can arrive out of order and, after a retry, more than once: skip an id you already handled. Keep your periodic sync with updated_since as a safety net. GET /ping tells whether webhooks are on and which events your key receives.

Base URL, authentication and conventions of this API are on the Commerce API page.

Webhookorder.created

A new order arrived

Sent when an order arrives from the sales channel or through POST /orders (also to the key that created it), or when the merchant creates a replacement order (for example to resend lost goods). Needs orders:read.

Request Nucleo sendsapplication/json

  • idstring (uuid)required

    Unique per event and the same on every retry. Skip an id you already handled.

  • typestringrequired
    One oforder.createdorder.status_changedshipment.shippedreturn.createdreturn.status_changed
  • created_atstring (date-time)required

    When the change happened in Nucleo.

  • dataobjectrequired

    Orders and shipments: order_id, order_number; order.created and order.status_changed add status (an order status), order.status_changed also previous_status; shipment.shipped adds shipment_id. Returns: return_id, return_number, order_id, order_number and status (a return status); return.status_changed also previous_status.

Expected response

  • 200Answer with any 2xx within 10 seconds; the body is ignored. Any other answer, a redirect or a timeout is retried with exponential backoff (after about 30 seconds, then 1, 2, 4, 8, 16 and 32 minutes): 8 attempts in about an hour, then Nucleo gives up and alerts the merchant. Every attempt carries the same id (also in X-Nucleo-Webhook-Id) and its number in X-Nucleo-Attempt. While the connection is paused or still a draft no webhook is sent, and the events of that time are not sent later: catch up with updated_since.
Body
{
  "id": "5b7e1c2d-3a4f-4b6c-8d9e-0f1a2b3c4d5e",
  "type": "order.created",
  "created_at": "2026-10-13T08:29:51Z",
  "data": {
    "order_id": "3f2a1b4c-5d6e-4f70-8a9b-0c1d2e3f4a5b",
    "order_number": "#1042",
    "status": "received"
  }
}
Response
HTTP 200 — Answer with any `2xx` within 10 seconds; the body is ignored. Any other answer, a redirect or a
timeout is retried with exponential backoff (after about 30 seconds, then 1, 2, 4, 8, 16 and 32
minutes): 8 attempts in about an hour, then Nucleo gives up and alerts the merchant. Every attempt
carries the same `id` (also in `X-Nucleo-Webhook-Id`) and its number in `X-Nucleo-Attempt`.
While the connection is paused or still a draft no webhook is sent, and the events of that time are
not sent later: catch up with `updated_since`.
Webhookorder.status_changed

An order changed status

Sent when the order's public status changes, with the new status and the previous_status. Needs orders:read.

Request Nucleo sendsapplication/json

  • idstring (uuid)required

    Unique per event and the same on every retry. Skip an id you already handled.

  • typestringrequired
    One oforder.createdorder.status_changedshipment.shippedreturn.createdreturn.status_changed
  • created_atstring (date-time)required

    When the change happened in Nucleo.

  • dataobjectrequired

    Orders and shipments: order_id, order_number; order.created and order.status_changed add status (an order status), order.status_changed also previous_status; shipment.shipped adds shipment_id. Returns: return_id, return_number, order_id, order_number and status (a return status); return.status_changed also previous_status.

Expected response

  • 200Answer with any 2xx within 10 seconds; the body is ignored. Any other answer, a redirect or a timeout is retried with exponential backoff (after about 30 seconds, then 1, 2, 4, 8, 16 and 32 minutes): 8 attempts in about an hour, then Nucleo gives up and alerts the merchant. Every attempt carries the same id (also in X-Nucleo-Webhook-Id) and its number in X-Nucleo-Attempt. While the connection is paused or still a draft no webhook is sent, and the events of that time are not sent later: catch up with updated_since.
Body
{
  "id": "8c9d0e1f-2a3b-4c4d-9e5f-6a7b8c9d0e1f",
  "type": "order.status_changed",
  "created_at": "2026-10-13T16:02:14Z",
  "data": {
    "order_id": "3f2a1b4c-5d6e-4f70-8a9b-0c1d2e3f4a5b",
    "order_number": "#1042",
    "status": "shipped",
    "previous_status": "in_fulfillment"
  }
}
Response
HTTP 200 — Answer with any `2xx` within 10 seconds; the body is ignored. Any other answer, a redirect or a
timeout is retried with exponential backoff (after about 30 seconds, then 1, 2, 4, 8, 16 and 32
minutes): 8 attempts in about an hour, then Nucleo gives up and alerts the merchant. Every attempt
carries the same `id` (also in `X-Nucleo-Webhook-Id`) and its number in `X-Nucleo-Attempt`.
While the connection is paused or still a draft no webhook is sent, and the events of that time are
not sent later: catch up with `updated_since`.
Webhookshipment.shipped

A shipment left

Sent for each shipment that leaves, also when the order ships in several parcels from different locations. shipment_id is the id of one of the order's shipments, with carrier and tracking. An order the customer collects in a store sends no shipment.shipped: it goes straight to delivered. Needs orders:read.

Request Nucleo sendsapplication/json

  • idstring (uuid)required

    Unique per event and the same on every retry. Skip an id you already handled.

  • typestringrequired
    One oforder.createdorder.status_changedshipment.shippedreturn.createdreturn.status_changed
  • created_atstring (date-time)required

    When the change happened in Nucleo.

  • dataobjectrequired

    Orders and shipments: order_id, order_number; order.created and order.status_changed add status (an order status), order.status_changed also previous_status; shipment.shipped adds shipment_id. Returns: return_id, return_number, order_id, order_number and status (a return status); return.status_changed also previous_status.

Expected response

  • 200Answer with any 2xx within 10 seconds; the body is ignored. Any other answer, a redirect or a timeout is retried with exponential backoff (after about 30 seconds, then 1, 2, 4, 8, 16 and 32 minutes): 8 attempts in about an hour, then Nucleo gives up and alerts the merchant. Every attempt carries the same id (also in X-Nucleo-Webhook-Id) and its number in X-Nucleo-Attempt. While the connection is paused or still a draft no webhook is sent, and the events of that time are not sent later: catch up with updated_since.
Body
{
  "id": "1d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
  "type": "shipment.shipped",
  "created_at": "2026-10-13T16:02:15Z",
  "data": {
    "order_id": "3f2a1b4c-5d6e-4f70-8a9b-0c1d2e3f4a5b",
    "order_number": "#1042",
    "shipment_id": "7c6b5a4f-3e2d-4c1b-9a0f-8e7d6c5b4a3f"
  }
}
Response
HTTP 200 — Answer with any `2xx` within 10 seconds; the body is ignored. Any other answer, a redirect or a
timeout is retried with exponential backoff (after about 30 seconds, then 1, 2, 4, 8, 16 and 32
minutes): 8 attempts in about an hour, then Nucleo gives up and alerts the merchant. Every attempt
carries the same `id` (also in `X-Nucleo-Webhook-Id`) and its number in `X-Nucleo-Attempt`.
While the connection is paused or still a draft no webhook is sent, and the events of that time are
not sent later: catch up with `updated_since`.
Webhookreturn.created

A return was opened

Sent when a return is opened on the sales channel, or when the warehouse receives a return nobody announced. Needs returns:read.

Request Nucleo sendsapplication/json

  • idstring (uuid)required

    Unique per event and the same on every retry. Skip an id you already handled.

  • typestringrequired
    One oforder.createdorder.status_changedshipment.shippedreturn.createdreturn.status_changed
  • created_atstring (date-time)required

    When the change happened in Nucleo.

  • dataobjectrequired

    Orders and shipments: order_id, order_number; order.created and order.status_changed add status (an order status), order.status_changed also previous_status; shipment.shipped adds shipment_id. Returns: return_id, return_number, order_id, order_number and status (a return status); return.status_changed also previous_status.

Expected response

  • 200Answer with any 2xx within 10 seconds; the body is ignored. Any other answer, a redirect or a timeout is retried with exponential backoff (after about 30 seconds, then 1, 2, 4, 8, 16 and 32 minutes): 8 attempts in about an hour, then Nucleo gives up and alerts the merchant. Every attempt carries the same id (also in X-Nucleo-Webhook-Id) and its number in X-Nucleo-Attempt. While the connection is paused or still a draft no webhook is sent, and the events of that time are not sent later: catch up with updated_since.
Body
{
  "id": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
  "type": "return.created",
  "created_at": "2026-10-18T16:20:03Z",
  "data": {
    "return_id": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
    "return_number": "R1042-1",
    "order_id": "3f2a1b4c-5d6e-4f70-8a9b-0c1d2e3f4a5b",
    "order_number": "#1042",
    "status": "requested"
  }
}
Response
HTTP 200 — Answer with any `2xx` within 10 seconds; the body is ignored. Any other answer, a redirect or a
timeout is retried with exponential backoff (after about 30 seconds, then 1, 2, 4, 8, 16 and 32
minutes): 8 attempts in about an hour, then Nucleo gives up and alerts the merchant. Every attempt
carries the same `id` (also in `X-Nucleo-Webhook-Id`) and its number in `X-Nucleo-Attempt`.
While the connection is paused or still a draft no webhook is sent, and the events of that time are
not sent later: catch up with `updated_since`.
Webhookreturn.status_changed

A return changed status

Sent when the return's public status changes, with the new status and the previous_status. Needs returns:read.

Request Nucleo sendsapplication/json

  • idstring (uuid)required

    Unique per event and the same on every retry. Skip an id you already handled.

  • typestringrequired
    One oforder.createdorder.status_changedshipment.shippedreturn.createdreturn.status_changed
  • created_atstring (date-time)required

    When the change happened in Nucleo.

  • dataobjectrequired

    Orders and shipments: order_id, order_number; order.created and order.status_changed add status (an order status), order.status_changed also previous_status; shipment.shipped adds shipment_id. Returns: return_id, return_number, order_id, order_number and status (a return status); return.status_changed also previous_status.

Expected response

  • 200Answer with any 2xx within 10 seconds; the body is ignored. Any other answer, a redirect or a timeout is retried with exponential backoff (after about 30 seconds, then 1, 2, 4, 8, 16 and 32 minutes): 8 attempts in about an hour, then Nucleo gives up and alerts the merchant. Every attempt carries the same id (also in X-Nucleo-Webhook-Id) and its number in X-Nucleo-Attempt. While the connection is paused or still a draft no webhook is sent, and the events of that time are not sent later: catch up with updated_since.
Body
{
  "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
  "type": "return.status_changed",
  "created_at": "2026-10-21T09:41:27Z",
  "data": {
    "return_id": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
    "return_number": "R1042-1",
    "order_id": "3f2a1b4c-5d6e-4f70-8a9b-0c1d2e3f4a5b",
    "order_number": "#1042",
    "status": "compliant",
    "previous_status": "received"
  }
}
Response
HTTP 200 — Answer with any `2xx` within 10 seconds; the body is ignored. Any other answer, a redirect or a
timeout is retried with exponential backoff (after about 30 seconds, then 1, 2, 4, 8, 16 and 32
minutes): 8 attempts in about an hour, then Nucleo gives up and alerts the merchant. Every attempt
carries the same `id` (also in `X-Nucleo-Webhook-Id`) and its number in `X-Nucleo-Attempt`.
While the connection is paused or still a draft no webhook is sent, and the events of that time are
not sent later: catch up with `updated_since`.
Was this page helpful?