check_availability
check_availability looks up real-time stock for a single SKU. Response is boolean-plus-optional-detail — the boolean is required; every other field is optional.
Request
Section titled “Request”Machine-readable: /skills/v1/check_availability.request.schema.json
| Field | Type | Required | Notes |
|---|---|---|---|
sku | string | yes | Your SKU. 1–256 chars. |
{ "additionalProperties": false, "properties": { "sku": { "maxLength": 256, "minLength": 1, "type": "string" } }, "required": ["sku"], "type": "object"}Example request
Section titled “Example request”{ "skill_id": "check_availability", "site_id": "01EXAMPLE00000000000000000", "arguments": { "sku": "beans_medium_12oz" }, "observed_at": "2026-07-05T18:22:15.140Z", "nonce": "01K1EXAMPLE0000000000000000"}Response
Section titled “Response”Machine-readable: /skills/v1/check_availability.response.schema.json
| Field | Type | Required | Notes |
|---|---|---|---|
sku | string | yes | Echo the requested SKU. |
in_stock | boolean | yes | true when at least one unit is available. |
quantity_on_hand | integer | no | Non-negative. Omit if you do not want to expose a precise count. |
estimated_ship_days | integer | no | Non-negative. Business days until dispatch. |
fulfillment_location | string | no | 1–256 chars. Merchant-defined identifier (warehouse code, city, region). |
If the SKU does not exist in your catalog, return { "sku": "<requested>", "in_stock": false }. Do NOT return an error status — a not-found SKU is a valid negative answer for availability.
{ "additionalProperties": false, "properties": { "estimated_ship_days": { "minimum": 0, "type": "integer" }, "fulfillment_location": { "maxLength": 256, "minLength": 1, "type": "string" }, "in_stock": { "type": "boolean" }, "quantity_on_hand": { "minimum": 0, "type": "integer" }, "sku": { "maxLength": 256, "minLength": 1, "type": "string" } }, "required": ["sku", "in_stock"], "type": "object"}Example response
Section titled “Example response”{ "sku": "beans_medium_12oz", "in_stock": true, "quantity_on_hand": 42, "estimated_ship_days": 1, "fulfillment_location": "US-EAST-WAREHOUSE"}What Sill checks
Section titled “What Sill checks”- Extra fields are rejected.
additionalProperties: false— do not include per-variant data, aisle numbers, or internal SKUs. - Wrong types.
quantity_on_hand: "42"(string) is rejected — must be an integer.
Verifying Sill’s signature
Section titled “Verifying Sill’s signature”Every request Sill POSTs to your endpoint carries a X-Sill-Signature: t=<unix>,v1=<hex> header, where <hex> is HMAC-SHA256("<t>.<raw-body>") with your shared secret. Reject stale timestamps (older than ~5 minutes) and compare in constant time.
TypeScript (compact)
Section titled “TypeScript (compact)”import { createHmac, timingSafeEqual } from 'node:crypto';
export function verify(header: string, body: string, secret: string): boolean { const map = Object.fromEntries(header.split(',').map((p) => p.split('=', 2))); const t = Number(map.t); const sig = String(map.v1 ?? ''); if (!Number.isFinite(t) || sig.length === 0) return false; if (Math.abs(Math.floor(Date.now() / 1000) - t) > 300) return false; const expected = createHmac('sha256', secret).update(`${t}.${body}`).digest(); const got = Buffer.from(sig, 'hex'); if (expected.length !== got.length) return false; return timingSafeEqual(expected, got);}Python (compact)
Section titled “Python (compact)”import hmac, hashlib, time
def verify(header: str, body: bytes, secret: bytes) -> bool: parts = dict(p.split('=', 1) for p in header.split(',') if '=' in p) try: t = int(parts['t']) except (KeyError, ValueError): return False sig = parts.get('v1', '') if abs(int(time.time()) - t) > 300 or not sig: return False expected = hmac.new(secret, f'{t}.'.encode() + body, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, sig)Go (compact)
Section titled “Go (compact)”func Verify(header string, body []byte, secret []byte) bool { var t int64 = -1 var sig string for _, p := range strings.Split(header, ",") { kv := strings.SplitN(p, "=", 2) if len(kv) != 2 { continue } switch kv[0] { case "t": n, err := strconv.ParseInt(kv[1], 10, 64) if err != nil { return false } t = n case "v1": sig = kv[1] } } if t < 0 || sig == "" { return false } diff := time.Now().Unix() - t if diff < 0 { diff = -diff } if diff > 300 { return false } mac := hmac.New(sha256.New, secret) mac.Write([]byte(strconv.FormatInt(t, 10) + ".")) mac.Write(body) got, err := hex.DecodeString(sig) if err != nil { return false } return hmac.Equal(mac.Sum(nil), got)}See also
Section titled “See also”- Contract overview — envelope shape, versioning, and the full HMAC verification samples.
browse_catalog— how agents typically discover a SKU to check.