Skip to content

track_shipment: skill contract

track_shipment returns tracking for an order. Like order_status, it is customer-scoped: every call includes the customer_email the agent supplied, and your endpoint must confirm that email owns the order before returning anything.

Request: { "order_id": "#1001", "customer_email": "[email protected]" }
1. Look up order #1001.
2. Compare its customer email with "[email protected]".
3. Match: look up the shipment and return it in the response shape below.
4. No match, or no such order: return 404 with an empty body.

If you skip step 2, anyone who guesses an order number can get its carrier, tracking number and delivery date through an agent.

Compare the emails the same way as for order_status: normalize both, compare in constant time (see the compare function), and return the same 404 for a wrong email as for an order that does not exist. A 404 reaches the agent as “not found” and does not affect your endpoint’s health.

Machine-readable: /skills/v1/track_shipment.request.schema.json

FieldTypeRequiredNotes
order_idstringyesThe order number the customer knows, or your internal ID. 1–128 chars.
customer_emailstringyesThe email the agent says owns the order. Not verified by Sill. 3–320 chars.
{
"additionalProperties": false,
"properties": {
"customer_email": {
"maxLength": 320,
"minLength": 3,
"type": "string"
},
"order_id": {
"maxLength": 128,
"minLength": 1,
"type": "string"
}
},
"required": ["order_id", "customer_email"],
"type": "object"
}
{
"skill_id": "track_shipment",
"site_id": "01EXAMPLE00000000000000000",
"arguments": {
"order_id": "#1001",
"customer_email": "[email protected]"
},
"observed_at": "2026-07-05T18:22:15.140Z",
"nonce": "01K1EXAMPLE0000000000000000"
}

Machine-readable: /skills/v1/track_shipment.response.schema.json

Only order_id is required, so an order that has not shipped yet can be answered with { "order_id": "#1001", "status": "not_yet_shipped" }.

FieldTypeRequiredNotes
order_idstringyesEcho the order id. 1–256 chars.
tracking_numberstringnoCarrier-issued tracking number. 1–256 chars.
carrierstringnoCarrier name / code. 1–256 chars.
statusstringnoFree text, 1–64 chars. Common values: not_yet_shipped, in_transit, delivered, cancelled, or the carrier’s own status.
expected_deliverystringnoExpected delivery, ISO-8601 UTC. 20–40 chars.
tracking_urlstringnoThe carrier’s tracking page. Use an HTTPS URL. 1–2048 chars.

Return only these fields. A response with any other field, such as the customer’s name, shipping address or phone, fails the schema: it is not passed to the agent and counts as a failed call (3 failures in a row mark the skill UNREACHABLE).

{
"additionalProperties": false,
"properties": {
"carrier": { "maxLength": 256, "minLength": 1, "type": "string" },
"expected_delivery": { "maxLength": 40, "minLength": 20, "type": "string" },
"order_id": { "maxLength": 256, "minLength": 1, "type": "string" },
"status": { "maxLength": 64, "minLength": 1, "type": "string" },
"tracking_number": { "maxLength": 256, "minLength": 1, "type": "string" },
"tracking_url": { "maxLength": 2048, "minLength": 1, "type": "string" }
},
"required": ["order_id"],
"type": "object"
}
{
"order_id": "#1001",
"tracking_number": "1Z999AA10123456784",
"carrier": "UPS",
"status": "in_transit",
"expected_delivery": "2026-07-08T00:00:00.000Z",
"tracking_url": "https://www.ups.com/track?tracknum=1Z999AA10123456784"
}
{
"order_id": "#1001",
"status": "not_yet_shipped"
}

Return 404 with an empty body when the order does not exist or the email does not match the order’s customer email. Do not return an invented status instead: it tells the caller the order number exists.

Sill checks every 2xx response against the response schema. A response that fails is not passed to the agent and counts as a failed call; 3 failures in a row mark the skill UNREACHABLE. Common causes are an extra field such as shipping_address, and a status longer than 64 characters.

Sill cannot check that the email matched. Run the self-test with your own orders to confirm it.

Check the X-Sill-Signature header on every request before answering. The scheme is the same for every skill; see Verify the signature for tested TypeScript, Python and Go code.