Contents
Carrier webhooks
Inbound tracking events, one URL per carrier connection:
https://api-commerce.nucleoplatform.com/api/oms/v1/webhooks/tracking/{connection_id}.
The connection ID is the UUID of the merchant's carrier connection in Nucleo. The connection ID and its webhook secret are set up with Nucleo — ask the merchant or Nucleo support.
Body: the Nucleo format (events[]). Authentication: X-Nucleo-Signature header = hex HMAC-SHA256 of
the raw body with the connection's webhook secret.
Base URL, authentication and conventions of this API are on the Shipment Tracking API page.
/webhooks/tracking/{connection}Push tracking events for a carrier connection
Receives parcel events for the shipments of one carrier connection: body {"events": [ … ]} (or a
single event object), header X-Nucleo-Signature: hex(HMAC-SHA256(raw body, webhook_secret)).
status can be a Nucleo status, a carrier code translated by the connection's status map, or empty
(Nucleo infers it from description, in Italian, English, German, French or Spanish).
Order of checks. JSON body first, then the signature.
Matching. Events are matched to shipments by tracking_number (the most recent parcel with
that number). Events for unknown parcels are ignored without error (applied: 0).
Idempotency. An event identical to one already stored (same shipment, tracking number, minute,
status and description) is ignored, so retries and overlapping deliveries are safe. applied counts
only new events.
Effects. The shipment takes the status of its most recent event. delivered marks the shipment
delivered and closes its open delivery-exception and held-parcel anomalies; when every shipment of
a shipped order is delivered and nothing is left to ship (split orders), the order becomes
delivered. exception, held and returned_to_sender open an anomaly for the merchant, except a
parcel waiting at a pickup point (exception_code: at_pickup_point).
Rate limit: 600 requests per minute per calling IP.
X-Nucleo-Signature headerPath parameters
connectionstring (uuid)requiredID of the carrier connection in Nucleo.
Example:5f0c7e2a-8b3d-4c1e-9a6f-2d4b8e1c7a35
Request bodyapplication/json
One of the following shapes:
GenericWebhook
eventsarray of GenericEventrequiredAttributes of each item
tracking_numberstringrequiredParcel tracking number, as stored on the Nucleo shipment.
Example:0612345678901statusstringA Nucleo status (see
TrackingStatus), a carrier status code mapped by the connection's status map, or empty to let Nucleo infer it fromdescription.Example:delivereddescriptionstringEvent text (stored up to 500 characters).
Example:Delivered to recipientoccurred_atstring (date-time)When the event happened, ISO 8601. Defaults to the time of receipt. An unreadable value is stored with the time Nucleo received the event.
locationstringWhere it happened (stored up to 160 characters).
Example:Milanoexception_codestringDetail for
exceptionandheld.One ofaddress_wrongrecipient_absentrefuseddamagedcustomsheld_at_depotat_pickup_pointlostother
GenericEvent
tracking_numberstringrequiredParcel tracking number, as stored on the Nucleo shipment.
Example:0612345678901statusstringA Nucleo status (see
TrackingStatus), a carrier status code mapped by the connection's status map, or empty to let Nucleo infer it fromdescription.Example:delivereddescriptionstringEvent text (stored up to 500 characters).
Example:Delivered to recipientoccurred_atstring (date-time)When the event happened, ISO 8601. Defaults to the time of receipt. An unreadable value is stored with the time Nucleo received the event.
locationstringWhere it happened (stored up to 160 characters).
Example:Milanoexception_codestringDetail for
exceptionandheld.One ofaddress_wrongrecipient_absentrefuseddamagedcustomsheld_at_depotat_pickup_pointlostother
Responses
200Accepted.
appliedis the number of new events stored:0for duplicates, unknown parcels and events that are not parcel tracking. application/jsonHeadersX-RateLimit-LimitRequests allowed per minute.X-RateLimit-RemainingRequests left in the current minute.
result"OK"requiredappliedintegerrequiredmin 0
400The body is not a JSON object.application/json
result"KO"requirederrorstringrequiredOne ofunknown connectioninvalid jsonunauthorizedtoo many invalid signaturestoo many invalid keys
401Wrong or missing
X-Nucleo-Signature.application/jsonresult"KO"requirederrorstringrequiredOne ofunknown connectioninvalid jsonunauthorizedtoo many invalid signaturestoo many invalid keys
404No carrier connection with this ID (
unknown connection). A non-UUID ID gets the generic route-not-found message. application/jsonOne of the following shapes:
WebhookError
result"KO"requirederrorstringrequiredOne ofunknown connectioninvalid jsonunauthorizedtoo many invalid signaturestoo many invalid keys
Message
messagestringrequired
429Too many requests from this IP (
message, withRetry-After). application/jsonHeadersRetry-AfterSeconds to wait (IP rate limit only).
One of the following shapes:
Message
messagestringrequired
WebhookError
result"KO"requirederrorstringrequiredOne ofunknown connectioninvalid jsonunauthorizedtoo many invalid signaturestoo many invalid keys
curl -X POST https://api-commerce.nucleoplatform.com/api/oms/v1/webhooks/tracking/5f0c7e2a-8b3d-4c1e-9a6f-2d4b8e1c7a35 \
-H "X-Nucleo-Signature: $NUCLEO_SIGNATURE" \
-H 'Content-Type: application/json' \
-d '{
"events": [
{
"tracking_number": "0612345678901",
"status": "",
"description": "Consegnata al destinatario",
"occurred_at": "2026-10-06T11:05:00Z",
"location": "Milano"
},
{
"tracking_number": "0612345678902",
"status": "exception",
"exception_code": "recipient_absent",
"description": "Recipient not at home, second attempt tomorrow",
"occurred_at": "2026-10-06T11:20:00Z",
"location": "Torino"
}
]
}'const res = await fetch("https://api-commerce.nucleoplatform.com/api/oms/v1/webhooks/tracking/5f0c7e2a-8b3d-4c1e-9a6f-2d4b8e1c7a35", {
method: "POST",
headers: {
"X-Nucleo-Signature": `${process.env.NUCLEO_SIGNATURE}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"events": [
{
"tracking_number": "0612345678901",
"status": "",
"description": "Consegnata al destinatario",
"occurred_at": "2026-10-06T11:05:00Z",
"location": "Milano"
},
{
"tracking_number": "0612345678902",
"status": "exception",
"exception_code": "recipient_absent",
"description": "Recipient not at home, second attempt tomorrow",
"occurred_at": "2026-10-06T11:20:00Z",
"location": "Torino"
}
]
}),
});
const data = await res.json();
console.log(res.status, data);<?php
require 'vendor/autoload.php';
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api-commerce.nucleoplatform.com/api/oms/v1/webhooks/tracking/5f0c7e2a-8b3d-4c1e-9a6f-2d4b8e1c7a35', [
'headers' => [
'X-Nucleo-Signature' => getenv('NUCLEO_SIGNATURE'),
],
'json' => [
'events' => [
[
'tracking_number' => '0612345678901',
'status' => '',
'description' => 'Consegnata al destinatario',
'occurred_at' => '2026-10-06T11:05:00Z',
'location' => 'Milano',
],
[
'tracking_number' => '0612345678902',
'status' => 'exception',
'exception_code' => 'recipient_absent',
'description' => 'Recipient not at home, second attempt tomorrow',
'occurred_at' => '2026-10-06T11:20:00Z',
'location' => 'Torino',
],
],
],
'http_errors' => false,
]);
echo $response->getStatusCode(), PHP_EOL;
echo $response->getBody();{
"result": "OK",
"applied": 2
}{
"result": "KO",
"error": "invalid json"
}{
"result": "KO",
"error": "unauthorized"
}{
"result": "KO",
"error": "unknown connection"
}{
"message": "Too Many Attempts."
}