Open standard · wire-level check

Watch your data arrive.

What this is
A live test bin for oat-ods messages
Box
demo
Keeps
the last 50 messages

This is step one of watching a reading travel from a sensor to a screen: prove the device is talking. Point it at the endpoint URL on the right and every message it sends shows up here within seconds, checked against the oat-ods standard, raw and unpolished on purpose. Once readings arrive clean here, step two is seeing them as a real dashboard on the live demonstration, the same pipeline with the polish on.

How to use it.

  1. Copy the endpoint URL from the panel on the right.
  2. On an Open Agriculture Technology device's setup page, choose Webhook delivery and paste it. (Pick a unique box name so your readings stay separate from everyone else's.)
  3. Watch them land below. A conformant badge means the message matches the standard; check lists what's missing.
  4. When your messages come through conformant, point the device at a real endpoint and watch the same readings as charts and zones on the live demonstration dashboard.

This page runs a friendly check. For the authoritative, machine-readable validation builders run scripts/oat/ods_validate.py against the published JSON Schema.

Live messages box: demo · auto-refresh 10s

check 2026-06-26T14:59:12Z

(no stream.id) · ? ?

via ?

missing or malformed "schema" (expected oat-ods/<major>.<minor>); missing "source" with a gateway_id or physical_id; missing "observed_at"; missing "stream.id" (the logical primary key); missing "measurement"; missing "value"

raw message
{
    "oat_recipe_export": "1.1",
    "$schema": "https://openagriculturetechnology.com/standard/oat-recipe-0.1.schema.json",
    "exported_at": "2026-06-25T14:30:00Z",
    "bundle": {
        "slug": "oat-ks-lettuce",
        "name": "Lettuce, Master Grow Recipe",
        "cultivar": "Lettuce",
        "target_use": "leafy / continuous harvest",
        "license": "CC-BY-4.0",
        "weeks": 5,
        "forked_from": null
    },
    "stages": [
        {
            "label": "Seedling",
            "start": 0,
            "end": 1,
            "params": {
                "detail": "germination"
            }
        },
        {
            "label": "Production",
            "start": 2,
            "end": 4,
            "params": null
        }
    ],
    "designs": {
        "light": {
            "all": {
                "fixture": "broad-spectrum LED bar",
                "count": 4,
                "photoperiod": 16,
                "dli": 14
            }
        }
    },
    "charts": {
        "light": {
            "dli_canopy": {
                "0": {
                    "target": 10,
                    "lower_warning": 8,
                    "upper_warning": 14,
                    "unit": "mol/m²/d"
                },
                "2": {
                    "target": 14,
                    "lower_warning": 12,
                    "upper_warning": 17,
                    "unit": "mol/m²/d"
                }
            },
            "photoperiod_hours": [
                {
                    "target": 16,
                    "unit": "h"
                }
            ],
            "far_red_fraction": [
                {
                    "target": 0.08,
                    "lower_warning": 0.04,
                    "upper_warning": 0.14,
                    "unit": "fraction"
                }
            ]
        },
        "environment": {
            "air_temperature_day": [
                {
                    "target": 20,
                    "lower_warning": 17,
                    "upper_warning": 24,
                    "lower_alert": 12,
                    "upper_alert": 30,
                    "unit": "Cel"
                }
            ],
            "vpd_air": [
                {
                    "target": 0.8,
                    "lower_warning": 0.6,
                    "upper_warning": 1.1,
                    "unit": "kPa"
                }
            ],
            "cwsi": {
                "2": {
                    "target": 0.2,
                    "upper_warning": 0.4,
                    "upper_alert": 0.6,
                    "unit": "index"
                }
            },
            "leaf_wetness_hours": [
                {
                    "upper_warning": 6,
                    "upper_alert": 10,
                    "unit": "h"
                }
            ]
        },
        "substrate": {
            "soil_water_tension": [
                {
                    "target": 15,
                    "upper_warning": 30,
                    "upper_alert": 50,
                    "unit": "cbar"
                }
            ],
            "pore_water_ec": [
                {
                    "target": 1.8,
                    "lower_warning": 1.2,
                    "upper_warning": 2.6,
                    "unit": "mS/cm"
                }
            ],
            "substrate_oxygen": [
                {
                    "target": 18,
                    "lower_warning": 12,
                    "lower_alert": 8,
                    "unit": "%"
                }
            ]
        }
    }
}

Frequently asked questions.

How do I test that my sensor is sending data correctly?

Point your device's webhook at the endpoint URL on this page and watch the readings arrive. Each one gets a badge: conformant means it matches the oat-ods standard, check lists what's missing. It's the fastest way to confirm a sensor or gateway is actually talking before you wire it into anything.

How do I see what my IoT device or Home Assistant is actually sending?

Send the device's output to a receiving endpoint that logs incoming messages, such as a test webhook or an MQTT viewer. It shows each message with its parsed fields, the stream, the reading, and the source device, alongside the full raw JSON, so you can see exactly what left the device rather than guessing from the sensor's own display.

How do I check whether my sensor data is valid?

Validate the data against a schema that defines the required fields and their types. A quick check can flag missing or malformed fields as messages arrive. For authoritative, repeatable validation in a script or continuous-integration pipeline, run the messages through a JSON Schema validator, which confirms each message conforms to the published format.