Skip to main content

The HTTP API

Anything that can make an HTTP request can send readings to a General crate. Find your crate ID, API key and both URLs under Send data in the crate.


Send one reading​

POST https://data.carroted.com/api/v2/ingest/{crate_id}

Headers:

  • X-API-Key: your_api_key
  • Content-Type: application/json

Body:

{
"device": "greenhouse-1",
"metric": "temperature",
"value": 22.5
}

Reply:

{ "status": "Data received and queued", "device": "greenhouse-1", "count": 1 }

count is the number of readings stored from your request.


Send several metrics at once​

Instead of metric and value, you can put each metric in as its own key. Every numeric key becomes a reading with that key as the metric:

{
"device": "greenhouse-1",
"temperature": 22.5,
"humidity": 61,
"battery": 3.92
}

This stores three readings and replies with "count": 3. You can mix both styles in one body.


Send a batch​

POST https://data.carroted.com/api/v2/ingest/{crate_id}/batch

The body is a JSON array. Each item is one reading, or one device with several metrics, as above:

[
{ "device": "greenhouse-1", "metric": "temperature", "value": 22.5 },
{ "device": "greenhouse-2", "temperature": 19.8, "humidity": 70 }
]

A batch can hold up to 100 readings on Free and 250 on Maker, counted after the metrics are split out. Bigger batches are refused with 400 Batch size limit exceeded. Batches have their own rate limit, see Limits and errors.


The fields​

FieldRequiredWhat it is
deviceYesThe device. Any text, 1 to 100 characters: a serial number, a hostname, kitchen-sensor.
metricWith valueThe metric. Any text, 1 to 100 characters: temperature, cpu_usage.
valueWith metricA number. Numbers sent as text ("22.5") work too.
timeNoWhen the reading was taken, as an RFC 3339 timestamp in UTC.

Older scripts and Lighthouse send ship_id and cargo_id instead of device and metric. Both spellings are accepted.

Values must be numbers. Text and true/false are ignored. If nothing in a request is a number, you get 400 No valid data found.


Timestamps​

Leave time out and the reading is stamped with the time it arrives, in UTC.

To send readings you took earlier (from a logger, or after a device was offline), add time:

{ "device": "logger-3", "metric": "temperature", "value": 18.2, "time": "2026-10-21T06:00:00Z" }

Use the full RFC 3339 form with a time zone: 2026-10-21T06:00:00Z or 2026-10-21T08:00:00+02:00.

caution

A time that can't be read is not an error: the reading is stored with the time it arrived instead. If old readings show up as "now", check the format.

Readings older than your plan keeps (1 day on Free, 90 days on Maker) are removed by the retention policy.


Location data​

Send latitude and longitude as two metrics named latitude and longitude, in the same request so they share one timestamp. The dashboard made for you puts devices with these metrics on a map.

{ "device": "van-05", "latitude": 52.3702, "longitude": 4.8952, "speed_kmh": 45.2 }

Duplicates​

A reading with the same device, metric and time as one already stored is dropped. Sending the same batch twice doesn't double your data.


Next steps​