Hybrid fulfillment — walk-up + cloud API drop
Kiosk-X supports a hybrid model:
| Channel | Who drops the product | Cloud role |
|---|---|---|
walkup |
Machine firmware after local payment | Sync inventory / orders only |
api_drop |
Machine agent after cloud command | Enqueue → poll → motor → ack |
Traditional vending partner APIs have no remote dispense. Kiosk-X adds the command queue so Quest rewards, admin drops, and agent-driven fulfillment work without changing walk-up sales.
Quick flow (api_drop)
KEY=vtm_e08725ea09876af65f431c6a3742d7c0
BASE=https://api.kiosk-x.ai
M=866903013700011
# 1) Cloud asks for a drop (quest reward, remote vend, …)
curl -sS -X POST "$BASE/api/v1/fulfill" \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"channel":"api_drop","machineNo":"'"$M"'","aisleNo":3,"reason":"reward_quest","externalRef":"quest-42"}'
# 2) Device agent polls
curl -sS "$BASE/api/v1/machines/$M/commands/pending" -H "X-API-Key: $KEY"
# 3) Agent drives motor, then acks
curl -sS -X POST "$BASE/api/v1/machines/$M/commands/<commandId>/ack" \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"success":true,"outcome":"success","detail":"aisle 3 dropped"}'
On successful ack, Kiosk-X decrements aisle stock and writes a shipped order
(same shape as a walk-up sale). Reasons starting with reward set paidPrice to 0.
Walk-up channel
curl -sS -X POST "$BASE/api/v1/fulfill" \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"channel":"walkup","machineNo":"'"$M"'"}'
Returns dispense: false and points you at inventory/order sync endpoints.
No motor command is created.
Endpoints
| Method | Path | Scope | Who |
|---|---|---|---|
| POST | /api/v1/fulfill |
machines:read (walkup) / commands:write (api_drop) |
Cloud app |
| POST | /api/v1/machines/{machineNo}/commands/dispense |
commands:write |
Cloud app |
| GET | /api/v1/machines/{machineNo}/commands/pending |
commands:read |
Device agent |
| GET | /api/v1/machines/{machineNo}/commands/{commandId} |
commands:read |
Either |
| POST | /api/v1/machines/{machineNo}/commands/{commandId}/ack |
commands:write |
Device agent |
Architecture
Quest-X / admin / agent
│
├─ channel=walkup ──► customer pays on machine ──► firmware drop
│ └─ Partner sync: inventory + orders
│
└─ channel=api_drop ──► POST /fulfill
└─ pending command queue
└─ device agent poll
└─ motor Deliver
└─ POST .../ack
└─ stock + order
Notes
- Enqueue rejects empty or faulted aisles (
400). - Commands are owner-scoped like machines (operators only see their fleet).
- Sandbox keys already include
commands:readandcommands:write. - Physical hardware still needs a device agent (see
zhzn-vending-kiosk/agent); this API is the cloud half of that bridge.