Device Ingest API#
Self Hosted Cloud Hosted
This page covers the public device-ingest endpoints only — the ones a device firmware author or integrator needs. The full internal API (batches, taps, vessels, devices, auth, admin, etc.) is not repeated here.
On the hosted service, devices post to ingest.brewgraph.com. Use the URL the app shows
when you add a device (for example https://ingest.brewgraph.com/ingest/ispindel); the
/api/ingest/... paths below work there too. HTTPS is the default; plain http:// is
accepted for firmware that cannot do TLS.
Authentication#
Each device is issued its own token at registration time. The token is included in the request payload (field name varies slightly per endpoint — see below), not as a bearer header — this lets devices authenticate without implementing OAuth/JWT in constrained firmware.
Ingest endpoints#
Endpoint |
Device |
Notes |
|---|---|---|
|
iSpindel, Tilt Hydrometer (via TiltBridge) |
Native iSpindel JSON payload |
|
GravityMon |
GravityMon-native payload format |
|
PressureMon |
Pressure, temperature, battery, RSSI. Coming soon to Cloud Hosted; not available in the beta |
|
KegMon |
Pour detection pulses. Coming soon to Cloud Hosted; not available in the beta |
|
KegMon |
Beer-assignment and pour-report payloads. Coming soon to Cloud Hosted; not available in the beta |
|
Any supported ingest device |
Detects the compatible payload shape and routes it to the appropriate handler |
Request examples#
These are the three gravity device paths that work in the Cloud Hosted beta. Replace
YOUR-DEVICE-TOKEN with the token shown when you registered the device, and
use the exact URL the app shows for that device. On the hosted service the URL
starts with https://ingest.brewgraph.com. Every request returns 200 with
no body on success. An unknown token returns 401, a request sent too soon
after the device’s plan interval returns 429, and a value that cannot be
stored returns 422.
Measurements are stored as sent: numeric values are not range-checked or clamped, so negative
pressure is accepted. A request returns 422 when its body cannot be parsed, a required value
is missing, a number is not finite, or a unit is unsupported. Unit names are case-insensitive.
An omitted optional field is shown as empty, not as zero. Negative volume is rejected with the
field name in the ingestion log. On Self Hosted, a KegMon volume above vessel capacity is stored
and raises the vessel capacity to match.
Battery voltage and percentage are stored independently and shown independently when present;
neither is calculated from the other. Reading responses expose them as batteryVoltage and
batteryPercent. On the hosted service, a native RAPT Pill reports gravity as specific gravity
(SG) and battery as a percentage.
The token always goes in the JSON body as token. The examples use a
placeholder, never a real token. The device ID is
accepted but can never authenticate a request on the hosted service. Fields not
listed as stored are ignored.
GravityMon#
curl -X POST https://ingest.brewgraph.com/ingest/gravitymon \
-H "Content-Type: application/json" \
-d '{
"name": "Gravitymon_01",
"ID": "12345678",
"token": "YOUR-DEVICE-TOKEN",
"angle": 42.15,
"temperature": 19.5,
"temp_units": "C",
"battery": 4.12,
"gravity": 1.045,
"corr-gravity": 1.044,
"gravity-unit": "G",
"velocity": -1.5,
"interval": 900,
"RSSI": -65,
"run-time": 2.14
}'
gravity-unitmust beG(specific gravity).P(Plato) is rejected with422.temp_unitsmust beCorF; any other value is rejected with422. Fahrenheit is converted to Celsius. If you leave it out, Celsius is assumed.corr-gravityis deliberately ignored: BrewGraph records the raw gravity value.nameandintervalare accepted but not stored.
iSpindel#
curl -X POST https://ingest.brewgraph.com/ingest/ispindel \
-H "Content-Type: application/json" \
-d '{
"name": "[SG] iSpindel",
"ID": 13065051,
"token": "YOUR-DEVICE-TOKEN",
"angle": 66.79,
"temperature": 20.56,
"temp_units": "C",
"battery": 4.13,
"gravity": 1.045,
"interval": 900,
"RSSI": -77
}'
In the iSpindel firmware, set the device name to start with the exact prefix
[SG]. The iSpindel’s calibration must output specific gravity. BrewGraph does not guess the scale from the number.temp_unitsfollows the same rule as for GravityMon.nameandintervalare accepted but not stored.
Tilt Hydrometer (via TiltBridge)#
TiltBridge posts to the same route as the iSpindel, using the iSpindel HTTP
format. TiltBridge can send a color field (for example "blue") in
place of ID. Use the token for the Tilt device you added in BrewGraph.
curl -X POST https://ingest.brewgraph.com/ingest/ispindel \
-H "Content-Type: application/json" \
-d '{
"name": "[SG] Tilt",
"color": "blue",
"token": "YOUR-DEVICE-TOKEN",
"temperature": 20.5,
"temp_units": "C",
"gravity": 1.045
}'
The [SG] name prefix and the temp_units rule above apply here as well.
See Devices for the full per-device setup guide (colour matching for Tilt, calibration for gravity sensors, etc.) — this page is just the wire protocol reference.