Partner APIs
Component health
Heartbeat a kiosk, KDS station or POS sends to report it is alive. Fire infers the outage from the missing heartbeat.
POST
A device can only report that it is alive. Nobody announces their own death: an outage is inferred
from the absence of a heartbeat. That is why this contract is a periodic beat and not an alert —
you POST here every cycle (the fleet runs at 600 s), and Fire’s availability dashboard reads the
silence.
The account and vendor are derived from the key, never from the body. Do not send
1. A stable
It has to survive reboots, updates and reinstalls. A changing id makes the fleet look like it renews
itself and keeps uptime from ever stabilizing.
3. Obey
Every 4. Send
The device’s emission time, not the arrival time. See the field above for why it changes what
gets counted as downtime.
5. Agree on
There is nothing to register first. A component unknown to Fire is created on its first
heartbeat and enters a trial period — it is not watched until it has reported in 2 distinct
hours. That is where typos die: a mistyped
componentId reports once, never returns, and never
raises an alert.Authentication
This endpoint requires a vendor-scoped API key with thecomponent-health:write scope (account +
vendor binding). Keys without the scope, or without a vendor binding, are rejected with 403.
string
required
Your Fire vendor-scoped API key with scope
component-health:write. Generate one from
Developers → API Management.accountId.
Request body
string
required
What kind of device is beating. One of
kiosk, kds_station or pos.string
required
Your id for this device, 1–120 characters. It must be stable — it has to survive reboots,
updates and reinstalls. If it changes, Fire sees a different component: the old one stops beating
and is retired after 7 days, the new one starts with no history and re-enters the trial period. Use
the hardware serial, an install id persisted to disk, or the terminal id. Never a user-editable
name (
Kitchen 1) or an id regenerated per boot.string
required
UUID of the store this component belongs to. Validated against your stores — it must exist and
belong to the API key’s account. Required: a component with no store falls out of the store-level
availability calculation, and a store with 3 kiosks where one is misconfigured would be scored over
2 — reporting “2 of 2, all good” while one is down.
string
required
online or degraded. There is no down — a device cannot declare itself dead; Fire infers
that from the missing heartbeat. degraded means the device is alive but something it needs is
not: the device itself decides that, not Fire.string
ISO 8601 timestamp with offset of when the device emitted the beat — not when it arrived.
Without it, everything is dated at the moment the request touched the server, so a beat delayed by
the network that lands after the outage was already declared stretches that outage artificially. It
also drops out-of-order beats: a
sentAt older than the last one processed is ignored. Optional,
but send it.integer
The cadence the device believes it has, 60–86400. Informational — the cadence in force is the one
Fire returns in
X-Heartbeat-Interval.string | null
ISO 8601 timestamp with offset of when the device lost connectivity, reported when it recovers.
This dates the outage when it actually happened rather than when Fire found out — a kiosk with no
network keeps selling from its offline queue, and without this field it would be charged downtime
it never had.
string
Why the device is not
online, as a normalized code (1–60 chars, snake_case, no spaces). This
is what makes a deliberately free-form detail analyzable — see the shared vocabulary below.string
The device’s app version, 1–40 characters. It has its own field — rather than living inside
details — because it is the only datum universal to all three types, and “this version fails
more” is the most common correlation across a fleet.object
Free-form context. Stored as-is: Fire does not interpret any key, deliberately, so a release on
your side never breaks ingestion. Keys are per component type — a KDS screen has no printer or
pinpad, a POS does. See the key contract below.
Response
On success the endpoint returns204 No Content — no body. A heartbeat creates no resource you
would later fetch, and an acknowledgement with a body would only add bytes to a request every device
makes every cycle.
integer
Response header carrying the cadence in force, in seconds. If it differs from the one you are
using, adopt it on the next cycle. The interval is configurable per device on Fire’s side; if
devices ignore the header, that control is ours only on paper — we would change the number in the
database and the fleet would keep its old rhythm until your next release.
What we need from each device
Five things. None is optional in practice: without them the system still works, but with worse data — and in two cases it lies towards optimism, which is the worst direction for a monitor.1. A stable componentId
It has to survive reboots, updates and reinstalls. A changing id makes the fleet look like it renews
itself and keeps uptime from ever stabilizing.
2. Jitter on startup
Do not beat on the same second as everyone else. Add a random offset of up to one full interval before the first heartbeat, and keep it. Ten thousand devices with the same cadence, all rebooted after a regional power cut, stay synchronized forever — the problem is not the average load, it is that exact second.3. Obey X-Heartbeat-Interval
Every 204 carries the cadence in force. Adopt it on the next cycle. The dashboard’s bar granularity
is derived from that value, so a device that ignores it makes the screen claim a precision the data
does not have.
4. Send sentAt
The device’s emission time, not the arrival time. See the field above for why it changes what
gets counted as downtime.
5. Agree on degradedReason — and on what a KDS reports
details is free-form on purpose: the device knows what hardware it has, Fire does not. But to
answer “what fails most?” the reasons need a shared vocabulary.
details keys by component type:
kiosk→printer,pinpad,queuedOrderspos→printer,pinpadkds_station→ still to be agreed with the KDS team. A screen has no sales peripherals; the candidates are its connection to its own backend and the orders left undispatched in queue. Until that is settled, do not assume any key here.
How Fire reads it
- Automatic enrollment and trial period. The first heartbeat creates the component. It is not watched until it has reported in 2 distinct hours. A mistyped id and a device that was installed and died instantly look identical — neither alerts. The one-off reports stay listed for someone to look at, without polluting the dashboard.
- Outage declared after 2 missed intervals, not after the first one. A single beat lost to the network is not an outage.
- Retired after 7 days without a beat: the component leaves the dashboard on its own. If it comes back, it reappears with its whole history.
- Outside store hours nothing counts. Intervals are clipped to that store’s real operating day — when it actually opened and closed, not its declared schedule. A kiosk switched off overnight adds no downtime.
Errors
A store that is not yours comes back as
400, not 404: from the contract’s point of view it is
an invalid body, and a 404 would confirm to a key that the uuid exists in someone else’s account.
On retrying: a lost heartbeat is not recoverable. Resending the one from ten minutes ago adds
nothing, and with a correct sentAt it is dropped as out of order. On a 5xx, wait for the next
cycle — never accumulate stale beats.
Related
KDS order status
The other endpoint your kitchen devices call — order lifecycle instead of availability.
Introduction
Base URLs, API keys, scopes and error format.

