Sign in

← All schemas

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.

Canonical $id, draft
https://schemas.inorbit.hr/sensors/sensor/v0.json
01Versions

Each version is a file at its own address. The raw file is plain JSON, served without a sign-in.

02Fields

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_idanyrequired

    sen_ and a ULID, mon_ and a ULID for a monitor, or builtin.<name> for a derived count.

  • account_idstringrequired

    The 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}$

  • ownerstringoptional

    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.

    pattern ^[^\s\u0000-\u001f\u007f-\u009f]*$at most 128 characters

  • producer_kindenumrequired

    Who produces it: agent, device or connection for a registered sensor; builtin for a derived one.

    One of"agent""device""connection""builtin"

  • producer_refstringoptional

    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.

    pattern ^([A-Za-z0-9_.:-]{1,64})?$

  • kindenumrequired

    What 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"

  • namestringrequired

    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).

    pattern ^[^\u0000-\u001f\u007f-\u009f]*$at least 1 charactersat most 128 characters

  • unitstringoptional

    The unit of a number, at most 16 bytes; empty for a state.

    pattern ^[^\u0000-\u001f\u007f-\u009f]*$at most 16 characters

  • sourceenumrequired

    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.

    One of"mac""server""agent""connection""phone""monitors""incidents""coordinator""asks"

  • schema_versionintegerrequired

    The schema version the producer speaks (1 today); an ingest must send the same.

    1 to 1000

  • stateenumrequired

    active, paused or revoked.

    One of"active""paused""revoked"

  • interval_secondsintegeroptional

    How often the producer said it reports: 0 (not periodic) or 10 to 86400.

  • healthenumrequired

    ok, 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_minutenumberoptional

    Readings per minute over the last 10 minutes.

    at least 0

  • last_seen_atstringoptional

    RFC 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 anyoptional

    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.

    at most 8 itemsno repeats

  • builtinbooleanrequired

    True for a built-in sensor: read only, derived.

  • created_atstringrequired

    RFC 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_atstringoptional

    RFC 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})$

03Examples

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.

04Check a file against it

Replace the file name with yours.

VS Code, JetBrains: settings
"json.schemas": [
  { "fileMatch": ["my-file.json"], "url": "https://schemas.inorbit.hr/sensors/sensor/v0.json" }
]
check-jsonschema
check-jsonschema --schemafile https://schemas.inorbit.hr/sensors/sensor/v0.json my-file.json
ajv-cli
ajv validate --spec=draft2020 -s <(curl -s https://schemas.inorbit.hr/sensors/sensor/v0.json) -d my-file.json
curl
curl -s https://schemas.inorbit.hr/sensors/sensor/v0.json
05The schema itself

The raw file of v0, as published.

schemas.inorbit.hr/sensors/sensor/v0.json
{
  "$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
          }
        }
      }
    }
  ]
}