order_status: skill contract
order_status returns an order’s status and line items. 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. Only your systems can make that check.
Check the customer first
Section titled “Check the customer first”Request: { "order_id": "#1001", "customer_email": "[email protected]" }
1. Look up order #1001.2. Compare its customer email with "[email protected]".3. Match: return the order 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 read that order through an agent, including the items and dates.
Normalize both emails the same way before comparing, and compare in constant time so response timing does not reveal a near match. In Node.js:
import { timingSafeEqual } from 'node:crypto';
function emailsMatch(a: string, b: string): boolean { const na = a.trim().toLowerCase().normalize('NFKC'); const nb = b.trim().toLowerCase().normalize('NFKC'); const ba = Buffer.from(na, 'utf8'); const bb = Buffer.from(nb, 'utf8'); if (ba.length !== bb.length) return false; return timingSafeEqual(ba, bb);}Return the same 404 for a wrong email and for an order that does not exist, so a caller cannot tell which order numbers are real. A 404 reaches the agent as “not found” and does not affect your endpoint’s health.
Request
Section titled “Request”Machine-readable: /skills/v1/order_status.request.schema.json
| Field | Type | Required | Notes |
|---|---|---|---|
order_id | string | yes | The order number the customer knows (for example #1001) or your internal ID. 1–128 chars. |
customer_email | string | yes | The 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"}Example request
Section titled “Example request”{ "skill_id": "order_status", "site_id": "01EXAMPLE00000000000000000", "arguments": { "order_id": "#1001", }, "observed_at": "2026-07-05T18:22:15.140Z", "nonce": "01K1EXAMPLE0000000000000000"}Response
Section titled “Response”Machine-readable: /skills/v1/order_status.response.schema.json
| Field | Type | Required | Notes |
|---|---|---|---|
order_id | string | yes | Echo the order id. 1–256 chars. |
status | enum | yes | pending, paid, fulfilled, cancelled or refunded. Map your own statuses to the closest one. |
placed_at | string | yes | When the order was placed, ISO-8601 UTC, for example 2026-06-30T14:12:03Z. 20–40 chars. |
fulfilled_at | string | no | When the order was fulfilled, ISO-8601 UTC. 20–40 chars. |
line_items | array | yes | Up to 128 items. Each has sku, title, quantity, unit_price. |
Return only these fields. A response with any other field, such as the customer’s name, address, phone, payment method or internal notes, 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).
Each line item:
| Field | Type | Required | Notes |
|---|---|---|---|
sku | string | yes | 1–256 chars. |
title | string | yes | 1–512 chars. |
quantity | integer | yes | 0 or more. |
unit_price | object | yes | { amount, amount_decimal, currency }, as in browse_catalog. |
{ "additionalProperties": false, "properties": { "fulfilled_at": { "maxLength": 40, "minLength": 20, "type": "string" }, "line_items": { "items": { "additionalProperties": false, "properties": { "quantity": { "minimum": 0, "type": "integer" }, "sku": { "maxLength": 256, "minLength": 1, "type": "string" }, "title": { "maxLength": 512, "minLength": 1, "type": "string" }, "unit_price": { "additionalProperties": false, "properties": { "amount": { "type": "number" }, "amount_decimal": { "maxLength": 64, "minLength": 1, "type": "string" }, "currency": { "maxLength": 8, "minLength": 3, "type": "string" } }, "required": ["amount", "amount_decimal", "currency"], "type": "object" } }, "required": ["sku", "title", "quantity", "unit_price"], "type": "object" }, "maxItems": 128, "type": "array" }, "order_id": { "maxLength": 256, "minLength": 1, "type": "string" }, "placed_at": { "maxLength": 40, "minLength": 20, "type": "string" }, "status": { "enum": ["pending", "paid", "fulfilled", "cancelled", "refunded"], "type": "string" } }, "required": ["order_id", "status", "placed_at", "line_items"], "type": "object"}Example response
Section titled “Example response”{ "order_id": "#1001", "status": "fulfilled", "placed_at": "2026-06-30T14:12:03.000Z", "fulfilled_at": "2026-07-02T09:41:18.000Z", "line_items": [ { "sku": "beans_medium_12oz", "title": "Medium roast, 12 oz bag", "quantity": 2, "unit_price": { "amount": 1800, "amount_decimal": "18.00", "currency": "USD" } } ]}When to return 404
Section titled “When to return 404”Return 404 with an empty body when:
- the order does not exist;
- the email does not match the order’s customer email;
- the order is deleted or archived.
Do not return a placeholder order (empty line_items, status: "pending") instead: it tells the caller the order number exists.
What Sill checks
Section titled “What Sill checks”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:
- an extra field at any depth, such as
customer_addressorpayment_method; - a
statusoutside the five values; - a
placed_atshorter than 20 or longer than 40 characters.
Sill cannot check that the email matched. Run the self-test with your own orders to confirm it.
Verify the signature
Section titled “Verify the signature”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.
See also
Section titled “See also”- Contract overview — request envelope, response handling and signature code.
track_shipment— the sibling customer-scoped skill.