REST API: Device Commands and Static Messages
See how to send time-bound commands and persistent static messages to Cloud Display Devices.
Watch on YouTubeUnderstanding command execution paths, static updates, timeouts, and field classification for Voodoo Cloud Display Devices.
Info
device(s) endpoint, with a focus on commands vs. statics, timeouts, and why certain fields are accepted, ignored, or reinterpreted.secondsseconds ≠ displaytimeoutEvery API request is classified into exactly one of these paths:
Which path is taken is determined by what fields are present, not by intent.
Watch commands and static messages being sent through the REST API, then use the detailed rules below when you build your integration.
See how to send time-bound commands and persistent static messages to Cloud Display Devices.
Watch on YouTubeCommands represent active work that a human is expected to complete.
A request is treated as a command if either of the following is true:
command field is present, orline1–line5 field is present (the system will implicitly convert this into a flash command)seconds{
"command": "display",
"line1": "Pack Order 12345",
"line2": "Qty: 3",
"color": "blue",
"seconds": 3600
}Tip
"line2": "Qty: 3" renders the text Qty: 3 on the second line of the display. In many workflows, it is better to use the convenience field "quantity": 3 instead, because that renders the quantity in the large box at the top left of the device.seconds = 0 means never timeout (LED stays on until batteries fail)Statics define what the device displays when no command is active.
A request is treated as a static update when:
command is present, andstatica–statice, locationoverride, brightness, or similar settings is presentIf any static line is provided, all static lines are normalized internally to ensure consistent display behavior.
{
"locationoverride": "PutWall 1|Cubby 34",
"statica": "Order 34455",
"staticb": "Waiting for Pack",
"arrow": "up"
}These parameters control completely different systems.
| Parameter | Applies To | Meaning |
|---|---|---|
| seconds | Commands | How long before a command expires and NACKs |
| displaytimeout | Statics | How long DeviceID/location is temporarily shown after a button press |
displaytimeout never affects LEDsdisplaytimeout cannot cause NACKsSome fields are settings, not actions:
These are remembered by the device and reused automatically.
Warning
Behind the scenes, the platform:
This allows integrators to send human-readable JSON while devices receive optimized instructions.
seconds values (hours/days)seconds = 0 to handle pauses in workThis approach:
Some integrations intentionally:
call event while the device is idleThis ensures explicit human intent and avoids silent retries.
| Field(s) | Classification | What it does | Notes / gotchas |
|---|---|---|---|
| command | Command selector | Forces the request onto the command execution path | If present, statics are not allowed in the same request (they'll be ignored/removed). |
| line1–line5 | Implicit command selector | If any line is present and no command, the system treats it as a command (typically flash) | This is the common "why did this become a command?" surprise. |
| Field(s) | Classification | What it does | Notes / gotchas |
|---|---|---|---|
| seconds | Command lifetime | How long until the command expires and can NACK | 0 means "never expire" → LED stays on until batteries die. |
| color / Color | Command attribute | LED color (normalized) | Accepts variants; normalized internally. |
| sound | Command attribute | Sound behavior (normalized) | Friendly values like beep/none may be translated to device-native encodings. |
| nonce | Command correlation | Caller-provided correlation ID | Useful for matching ACK/NACK/CALL responses. |
| location | Command addressing helper | Location alias used to resolve device and optionally auto-add arrow | When used in a command, it's treated as addressing/augmentation, not a persistent setting. |
| deviceid / deviceID / DeviceID | Targeting | Chooses the device | Canonicalized internally. |
| Field(s) | Classification | What it does | Notes / gotchas |
|---|---|---|---|
| statica–statice | Static display lines | Persistent "background" text shown when idle | If you set any static line, the platform normalizes the full set for consistent behavior. |
| locationoverride | Static setting | Persistent "area|location" style label shown when idle | Used for long-lived context; survives between commands. |
| brightness | Static setting | Persistent brightness setting | Do not include in command requests (it's a setting, not an action). |
| displaytimeout | Static UI setting | How long DeviceID/location is shown after button press while idle | Not related to seconds; cannot cause NACKs. |
| unsolicitedNonce | Static callback setting | Correlation value used in nonce for unsolicited button callbacks while the device is idle | Applies to call, call_up, andcall_down; command callbacks still use the command's own nonce. |
These are the sneaky ones: they're accepted in both worlds, and might or might not persist.
| Field(s) | Classification | If sent with command… | If sent without command… |
|---|---|---|---|
| quantity / Quantity | Convenience/decoration | Rendered as a command display element | Becomes a static decoration (stored and shown when idle) |
| barcode / Barcode | Convenience/decoration | Rendered as a command display element | Becomes a static decoration (stored and shown when idle) |
| qrcode / QRcode | Convenience/decoration | Rendered as a command display element | Becomes a static decoration (stored and shown when idle) |
| arrow / Arrow | Convenience/decoration | Rendered as a command display element | Becomes a static decoration (stored and shown when idle) |
| icon / Icon | Convenience/decoration | Rendered as a command display element | Becomes a static decoration (stored and shown when idle) |
Practical takeaway: these "convenience" fields behave like extra lines in a command, but like persistent statics in a static update.
| Field(s) | Classification | Why it's suppressed |
|---|---|---|
| brightness | Setting | Settings and actions are kept separate for predictable behavior and performance. |
| locationoverride | Setting | Commands don't set persistent context. |
| statica–statice | Setting/display | Statics are not allowed inside commands. |
| displaytimeout (and similar) | Setting | Commands should not change static UI configuration. |
command + seconds).statica…statice, locationoverride, brightness).line1…line5, you're in command land whether you meant to be or not.Below is a Put Wall / Pack Wall worked example mapped end-to-end, using commands for short-lived actions and statics for long-lived state.
Do this once when installing / mapping devices.
{
"locationoverride": "PutWall 1 | Cubby 34",
"displaytimeout": 15,
"brightness": 100
}What it means: Device always knows its putwall/cubby identity when idle. When someone taps the button while idle, it will briefly show DeviceID/location for 15s, then revert.
Goal: Light the Put Side device briefly while the sorter drops units.
{
"command": "flash",
"line1": "PUT: Order 1959690",
"line2": "Qty: 2",
"color": "blue",
"seconds": 60,
"nonce": "1959690"
}What happens on the device:
On button press → ACK → command clears:
If nobody taps in 60 seconds → NACK → command clears:
Info
seconds short (30–120s) so NACKs are meaningful.Goal: If items are sitting in cubby waiting for packing, the device should keep showing state without draining batteries or generating NACK noise.
{
"locationoverride": "PutWall 1 | Cubby 34",
"statica": "READY TO PACK",
"staticb": "Order 1959690",
"staticc": "Units: 2",
"arrow": "up"
}What happens:
When packing actually begins (or when you want to actively draw attention), use a command on Pack Side.
{
"command": "display",
"line1": "PACK NOW",
"line2": "Order 1959690",
"line3": "Units: 2",
"color": "green",
"seconds": 900,
"nonce": "1959690-pack"
}Behavior:
When you get ACK for the pack command, you typically want to change the idle state.
{
"statica": "",
"staticb": "",
"staticc": "",
"staticd": "",
"statice": ""
}{
"statica": "PACK COMPLETE",
"staticb": "Order 1959690",
"staticc": "Good to ship"
}This is where Pack Side differs from Put Side. If the pack command times out (NACK), don't keep reissuing a long-running command. Instead:
{
"statica": "WAITING FOR PACK",
"staticb": "Order 1959690",
"staticc": "Units: 2"
}Now:
If you want the packer to explicitly say "I'm here, re-light it":
{
"statica": "HOLD BUTTON 4s",
"staticb": "to re-light pack",
"staticc": "Order 1959690",
"unsolicitedNonce": "reissueID-122298393"
}When worker holds the button:
call and places theunsolicitedNonce value into the callbacknonceThis is elegant because it avoids blind retries.
On multi-button devices, unsolicited plus and minus presses sendcall_up and call_down only when no command is being displayed. During an active command, those same buttons are treated as quantity adjustments instead of unsolicited callbacks.
Warning