Schema · sensors/ingest
Sensor ingest request
The body a producer posts to Ingest (POST /v1/atlas/signals, proto iohr.sensors.v1.IngestRequest): readings from one sensor, at most 500, each accepted or refused on its own (send an Idempotency-Key header to make a retry safe). A reading is a produced_at, exactly one of a number (value) or a state word (state), labels from the sensor's label_keys, and optionally the digest of evidence the producer keeps. It carries no content: no text, prompt, document or credential, and every object is closed so a field outside these is refused. Only the sensor's producer may write, a paused or revoked sensor refuses, and a built-in sensor is read only: the service decides those, the schema cannot. Draft line: it may still be corrected.
https://schemas.inorbit.hr/sensors/ingest/v0.jsonEach version is a file at its own address. The raw file is plain JSON, served without a sign-in.
- v0draftMay still be corrected; kept for five minutes.schemas.inorbit.hr/sensors/ingest/v0.json ↗
Fields of v0, the newest version, by path. A name ending in [] is each item of a list. Every field not listed is refused.
sensor_idstringrequiredThe sensor to write to: sen_ and a ULID (the id Register answered). Never a bare UUID.
pattern ^sen_[0-9A-HJKMNP-TV-Z]{26}$at most 30 charactersschema_versionintegeroptionalThe schema version the producer speaks, 1 to 1000. It must equal the sensor's own schema_version (Register set it; 1 today); leave it out to send under the sensor's.
1 to 1000account_idstringoptionalThe account to write into, a UUID. Leave it out for the caller's own; only a service names another account.
pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$at most 36 charactersreadingslist of anyrequiredThe batch: 1 to 500 readings, in the order sent (the answer's outcomes follow it).
at most 500 items
Valid documents with made-up values, as the repository's tests check them.
{
"sensor_id": "sen_01JC3Z8Q4M7T2V9XK5R6B1N0HA",
"readings": [
{
"produced_at": "2026-10-23T14:09:26.123Z",
"value": 182.5,
"labels": {
"volume": "/"
}
},
{
"produced_at": "2026-10-23T14:10:26Z",
"value": 181.9
}
],
"schema_version": 1
}The repository's tests also check 45 documents that this schema must refuse.
Replace the file name with yours.
"json.schemas": [
{ "fileMatch": ["my-file.json"], "url": "https://schemas.inorbit.hr/sensors/ingest/v0.json" }
]check-jsonschema --schemafile https://schemas.inorbit.hr/sensors/ingest/v0.json my-file.jsonajv validate --spec=draft2020 -s <(curl -s https://schemas.inorbit.hr/sensors/ingest/v0.json) -d my-file.jsoncurl -s https://schemas.inorbit.hr/sensors/ingest/v0.jsonThe raw file of v0, as published.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://schemas.inorbit.hr/sensors/ingest/v0.json",
"title": "Sensor ingest request",
"description": "The body a producer posts to Ingest (POST /v1/atlas/signals, proto iohr.sensors.v1.IngestRequest): readings from one sensor, at most 500, each accepted or refused on its own (send an Idempotency-Key header to make a retry safe). A reading is a produced_at, exactly one of a number (value) or a state word (state), labels from the sensor's label_keys, and optionally the digest of evidence the producer keeps. It carries no content: no text, prompt, document or credential, and every object is closed so a field outside these is refused. Only the sensor's producer may write, a paused or revoked sensor refuses, and a built-in sensor is read only: the service decides those, the schema cannot. Draft line: it may still be corrected.",
"type": "object",
"additionalProperties": false,
"required": [
"sensor_id",
"readings"
],
"properties": {
"sensor_id": {
"description": "The sensor to write to: sen_ and a ULID (the id Register answered). Never a bare UUID.",
"type": "string",
"maxLength": 30,
"pattern": "^sen_[0-9A-HJKMNP-TV-Z]{26}$"
},
"schema_version": {
"description": "The schema version the producer speaks, 1 to 1000. It must equal the sensor's own schema_version (Register set it; 1 today); leave it out to send under the sensor's.",
"type": "integer",
"minimum": 1,
"maximum": 1000
},
"account_id": {
"description": "The account to write into, a UUID. Leave it out for the caller's own; only a service names another account.",
"type": "string",
"maxLength": 36,
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"readings": {
"description": "The batch: 1 to 500 readings, in the order sent (the answer's outcomes follow it).",
"type": "array",
"minItems": 1,
"maxItems": 500,
"items": {
"$ref": "#/$defs/reading"
}
}
},
"$defs": {
"reading": {
"description": "One reading as the producer sends it (proto iohr.sensors.v1.SignalReading). A gauge sends a value, a counter a value of zero or more, a state sensor a state: the service checks the kind. The producer's time may not be more than a day ahead or 7 days old (the service refuses with future or too_old).",
"type": "object",
"additionalProperties": false,
"required": [
"produced_at"
],
"properties": {
"produced_at": {
"description": "RFC 3339, the producer's clock.",
"$ref": "https://schemas.inorbit.hr/sensors/reading/v0.json#/$defs/timestamp"
},
"value": {
"description": "A gauge's or counter's value: a finite number.",
"type": "number"
},
"state": {
"description": "A state sensor's value: 1 to 32 of a-z, 0-9 and underscore.",
"$ref": "https://schemas.inorbit.hr/sensors/reading/v0.json#/$defs/state_word"
},
"labels": {
"description": "At most 8, keys from the sensor's label_keys, each value 1 to 64 characters.",
"$ref": "https://schemas.inorbit.hr/sensors/reading/v0.json#/$defs/labels"
},
"evidence_digest": {
"description": "Optional: sha256: and 64 lowercase hex characters, of evidence the producer keeps. Leave it out when there is none.",
"$ref": "https://schemas.inorbit.hr/sensors/reading/v0.json#/$defs/evidence_digest"
}
},
"oneOf": [
{
"required": [
"value"
]
},
{
"required": [
"state"
]
}
]
}
}
}