Schema · sensors/sensor
Sensor
One sensor as Get (GET /v1/atlas/sensors/{sensor_id}, under "sensor"), List (GET /v1/atlas/sensors, inside each of "groups"[]."sensors"), Register and the pause, resume and revoke calls return it (proto iohr.sensors.v1.Sensor, JSON field names as the API writes them). A sensor is a named source of readings: what it is, who produces it, how often it reports and whether it is healthy. It carries no content: no text, prompt, document or credential, and the object is closed so a field outside these is refused. Every id carries its prefix (sen_ for a registered sensor, mon_ for a monitor, builtin. for a derived count); a bare UUID is never a sensor id. Fields the API leaves at their default (an empty string, 0, false) are present. Draft line: it may still be corrected.
https://schemas.inorbit.hr/sensors/sensor/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/sensor/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_idanyrequiredsen_ and a ULID, mon_ and a ULID for a monitor, or builtin.<name> for a derived count.
account_idstringrequiredThe account's id, a UUID (an account is not a prefixed resource).
pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$ownerstringoptionalThe verified subject that registered it (a person, or a key's own id): a subject id, no spaces; empty for a built-in sensor.
pattern ^[^\s\u0000-\u001f\u007f-\u009f]*$at most 128 charactersproducer_kindenumrequiredWho produces it: agent, device or connection for a registered sensor; builtin for a derived one.
One of
"agent""device""connection""builtin"producer_refstringoptionalThe agent, device or connection id the producer said it is: 1 to 64 of A-Z, a-z, 0-9 and _.:- ; empty for a built-in sensor.
pattern ^([A-Za-z0-9_.:-]{1,64})?$kindenumrequiredWhat a reading holds: gauge (a number that goes up and down), counter (a number that only grows) or state (a word).
One of
"gauge""counter""state"namestringrequiredA short name, unique per producer and kind: 1 to 64 of a-z, 0-9, underscore, dot and hyphen for a registered sensor; a built-in sensor's display name (at most 128 characters, no control characters).
pattern ^[^\u0000-\u001f\u007f-\u009f]*$at least 1 charactersat most 128 charactersunitstringoptionalThe unit of a number, at most 16 bytes; empty for a state.
pattern ^[^\u0000-\u001f\u007f-\u009f]*$at most 16 characterssourceenumrequiredWhere it comes from, for grouping: mac, server, agent, connection or phone for a registered sensor; monitors, incidents, coordinator or asks for a built-in one.
One of
"mac""server""agent""connection""phone""monitors""incidents""coordinator""asks"schema_versionintegerrequiredThe schema version the producer speaks (1 today); an ingest must send the same.
1 to 1000stateenumrequiredactive, paused or revoked.
One of
"active""paused""revoked"interval_secondsintegeroptionalHow often the producer said it reports: 0 (not periodic) or 10 to 86400.
healthenumrequiredok, stale (3 intervals missed) or silent (nothing yet) for a registered sensor; for a built-in one also up, down, unknown or paused.
One of
"ok""stale""silent""up""down""unknown""paused"rate_per_minutenumberoptionalReadings per minute over the last 10 minutes.
at least 0last_seen_atstringoptionalRFC 3339; empty when nothing came yet.
pattern ^$|^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]{1,9})?(Z|[+-][0-9]{2}:[0-9]{2})$label_keyslist of anyoptionalThe label keys this sensor may send: at most 8, each 1 to 32 of a-z, 0-9 and underscore, none that names a credential.
at most 8 itemsno repeatsbuiltinbooleanrequiredTrue for a built-in sensor: read only, derived.
created_atstringrequiredRFC 3339. Empty only for a derived count (builtin.), which has no creation time.
pattern ^$|^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]{1,9})?(Z|[+-][0-9]{2}:[0-9]{2})$revoked_atstringoptionalRFC 3339; empty unless the sensor is revoked.
pattern ^$|^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]{1,9})?(Z|[+-][0-9]{2}:[0-9]{2})$
Valid documents with made-up values, as the repository's tests check them.
{
"sensor_id": "builtin.incidents.open",
"account_id": "3e4f5a6b-8c9d-4e0f-9a1b-4c5d6e7f8091",
"owner": "",
"producer_kind": "builtin",
"producer_ref": "",
"kind": "gauge",
"name": "Open incidents",
"unit": "count",
"source": "incidents",
"schema_version": 1,
"state": "active",
"interval_seconds": 0,
"health": "ok",
"rate_per_minute": 0,
"last_seen_at": "2026-10-23T14:09:26.123Z",
"label_keys": [],
"builtin": true,
"created_at": "2026-10-01T00:00:00.000Z",
"revoked_at": ""
}The repository's tests also check 30 documents that this schema must refuse.
Replace the file name with yours.
"json.schemas": [
{ "fileMatch": ["my-file.json"], "url": "https://schemas.inorbit.hr/sensors/sensor/v0.json" }
]check-jsonschema --schemafile https://schemas.inorbit.hr/sensors/sensor/v0.json my-file.jsonajv validate --spec=draft2020 -s <(curl -s https://schemas.inorbit.hr/sensors/sensor/v0.json) -d my-file.jsoncurl -s https://schemas.inorbit.hr/sensors/sensor/v0.jsonThe raw file of v0, as published.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://schemas.inorbit.hr/sensors/sensor/v0.json",
"title": "Sensor",
"description": "One sensor as Get (GET /v1/atlas/sensors/{sensor_id}, under \"sensor\"), List (GET /v1/atlas/sensors, inside each of \"groups\"[].\"sensors\"), Register and the pause, resume and revoke calls return it (proto iohr.sensors.v1.Sensor, JSON field names as the API writes them). A sensor is a named source of readings: what it is, who produces it, how often it reports and whether it is healthy. It carries no content: no text, prompt, document or credential, and the object is closed so a field outside these is refused. Every id carries its prefix (sen_ for a registered sensor, mon_ for a monitor, builtin. for a derived count); a bare UUID is never a sensor id. Fields the API leaves at their default (an empty string, 0, false) are present. Draft line: it may still be corrected.",
"type": "object",
"additionalProperties": false,
"required": [
"sensor_id",
"account_id",
"producer_kind",
"kind",
"name",
"source",
"schema_version",
"state",
"health",
"builtin",
"created_at"
],
"properties": {
"sensor_id": {
"description": "sen_ and a ULID, mon_ and a ULID for a monitor, or builtin.<name> for a derived count.",
"$ref": "https://schemas.inorbit.hr/sensors/reading/v0.json#/$defs/sensor_id"
},
"account_id": {
"description": "The account's id, a UUID (an account is not a prefixed resource).",
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"owner": {
"description": "The verified subject that registered it (a person, or a key's own id): a subject id, no spaces; empty for a built-in sensor.",
"type": "string",
"maxLength": 128,
"pattern": "^[^\\s\\u0000-\\u001f\\u007f-\\u009f]*$"
},
"producer_kind": {
"description": "Who produces it: agent, device or connection for a registered sensor; builtin for a derived one.",
"enum": [
"agent",
"device",
"connection",
"builtin"
]
},
"producer_ref": {
"description": "The agent, device or connection id the producer said it is: 1 to 64 of A-Z, a-z, 0-9 and _.:- ; empty for a built-in sensor.",
"type": "string",
"pattern": "^([A-Za-z0-9_.:-]{1,64})?$"
},
"kind": {
"description": "What a reading holds: gauge (a number that goes up and down), counter (a number that only grows) or state (a word).",
"enum": [
"gauge",
"counter",
"state"
]
},
"name": {
"description": "A short name, unique per producer and kind: 1 to 64 of a-z, 0-9, underscore, dot and hyphen for a registered sensor; a built-in sensor's display name (at most 128 characters, no control characters).",
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[^\\u0000-\\u001f\\u007f-\\u009f]*$"
},
"unit": {
"description": "The unit of a number, at most 16 bytes; empty for a state.",
"type": "string",
"maxLength": 16,
"pattern": "^[^\\u0000-\\u001f\\u007f-\\u009f]*$"
},
"source": {
"description": "Where it comes from, for grouping: mac, server, agent, connection or phone for a registered sensor; monitors, incidents, coordinator or asks for a built-in one.",
"enum": [
"mac",
"server",
"agent",
"connection",
"phone",
"monitors",
"incidents",
"coordinator",
"asks"
]
},
"schema_version": {
"description": "The schema version the producer speaks (1 today); an ingest must send the same.",
"type": "integer",
"minimum": 1,
"maximum": 1000
},
"state": {
"description": "active, paused or revoked.",
"enum": [
"active",
"paused",
"revoked"
]
},
"interval_seconds": {
"description": "How often the producer said it reports: 0 (not periodic) or 10 to 86400.",
"type": "integer",
"oneOf": [
{
"const": 0
},
{
"minimum": 10,
"maximum": 86400
}
]
},
"health": {
"description": "ok, stale (3 intervals missed) or silent (nothing yet) for a registered sensor; for a built-in one also up, down, unknown or paused.",
"enum": [
"ok",
"stale",
"silent",
"up",
"down",
"unknown",
"paused"
]
},
"rate_per_minute": {
"description": "Readings per minute over the last 10 minutes.",
"type": "number",
"minimum": 0
},
"last_seen_at": {
"description": "RFC 3339; empty when nothing came yet.",
"type": "string",
"pattern": "^$|^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?(Z|[+-][0-9]{2}:[0-9]{2})$"
},
"label_keys": {
"description": "The label keys this sensor may send: at most 8, each 1 to 32 of a-z, 0-9 and underscore, none that names a credential.",
"type": "array",
"maxItems": 8,
"uniqueItems": true,
"items": {
"$ref": "https://schemas.inorbit.hr/sensors/reading/v0.json#/$defs/label_key"
}
},
"builtin": {
"description": "True for a built-in sensor: read only, derived.",
"type": "boolean"
},
"created_at": {
"description": "RFC 3339. Empty only for a derived count (builtin.), which has no creation time.",
"type": "string",
"pattern": "^$|^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?(Z|[+-][0-9]{2}:[0-9]{2})$"
},
"revoked_at": {
"description": "RFC 3339; empty unless the sensor is revoked.",
"type": "string",
"pattern": "^$|^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?(Z|[+-][0-9]{2}:[0-9]{2})$"
}
},
"allOf": [
{
"if": {
"properties": {
"builtin": {
"const": true
}
},
"required": [
"builtin"
]
},
"then": {
"properties": {
"producer_kind": {
"const": "builtin"
},
"source": {
"enum": [
"monitors",
"incidents",
"coordinator",
"asks"
]
},
"label_keys": {
"maxItems": 0
}
}
},
"else": {
"properties": {
"sensor_id": {
"pattern": "^sen_"
},
"producer_kind": {
"enum": [
"agent",
"device",
"connection"
]
},
"producer_ref": {
"minLength": 1
},
"name": {
"pattern": "^[a-z0-9_.-]{1,64}$"
},
"source": {
"enum": [
"mac",
"server",
"agent",
"connection",
"phone"
]
},
"created_at": {
"minLength": 20
}
},
"required": [
"producer_ref"
]
}
},
{
"if": {
"properties": {
"state": {
"const": "revoked"
}
},
"required": [
"state"
]
},
"then": {
"required": [
"revoked_at"
],
"properties": {
"revoked_at": {
"minLength": 20
}
}
}
}
]
}