Skip to content

Commands Reference

Every command a module declares (RFC-040), rendered from the same pass that generates schema/command/, one operation document per command in OpenAPI's vocabulary. A command is addressed by an attribute ref, <moduleId>.<componentName>.<componentId>.<verb>; its identity is the component name plus the verb, and the endpoints listed under it are the filters that serve it, with the component id free. The field descriptions are the request struct's doc comments; the documents are the published contract. A command not listed here is not declared in this build, which algol command sends all the same and nothing validates.

A refusal travels as a micro error: the code and a description in the headers, the cause in the body. A signed command takes its body inside the RFC-035 D14 envelope; what is described is the inner request. A field whose type is a name links to the shared definition it references, described once under Shared definitions.

app.dump

Captures the next N raw bytes off the serial link into a file under the module's dump directory, N given as the body; answers at once with the file's path, or with why the request was declined.

Served by: retx.app.*.dump

Request: text, text/plain.

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
message string Message is the path of the capture file after ok, the reason otherwise.
status string Status is ok, ignored or error. One of ok, ignored, error.

app.status

Answers the module's health status on demand - the code its app.main status carries - as the status name; served by the nats app and the configurer.

Served by: *.app.*.status

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component.
500 The handler failed; the body carries the error.

auth.enrol

Enrols exactly one of a user key - with its label and a role the caller may grant - and a module name bound to a key; re-enrolling a key with another role drops its live connections, which the reply counts.

Served by: *.auth.*.enrol

Request: a JSON object. Signed.

Field Type Required Meaning
issued string Issued is when the caller signed the request. The service refuses a request issued outside ReplayWindow of its own clock.
module object Module is the module argument of enrol and revoke.
userKey object UserKey is the person's-key argument of enrol and revoke. Exactly one of UserKey and Module is set on those verbs; neither on ls.
verb string Verb is the operation; it must match the subject the request is sent on, so a signed revoke cannot be replayed as an enrol.

Example:

{
  "issued": "2026-09-07T12:00:00Z",
  "userKey": {
    "key": "UAEXAMPLEKEY",
    "label": "lukas",
    "role": "superuser"
  },
  "verb": "enrol"
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
401 The signing key is not an enrolled user key, the signature does not verify, the request was issued outside the replay window, or it was already answered.
403 The caller's role may not change the registry, or may not grant the role named.
404 No such key or module name in the registry.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
disconnected integer

auth.ls

Lists the identity registry: every module name, expected or bound to a key, and every enrolled user key with its label and role.

Served by: *.auth.*.ls

Request: a JSON object. Signed.

Field Type Required Meaning
issued string Issued is when the caller signed the request. The service refuses a request issued outside ReplayWindow of its own clock.
module object Module is the module argument of enrol and revoke.
userKey object UserKey is the person's-key argument of enrol and revoke. Exactly one of UserKey and Module is set on those verbs; neither on ls.
verb string Verb is the operation; it must match the subject the request is sent on, so a signed revoke cannot be replayed as an enrol.

Example:

{
  "issued": "2026-09-07T12:00:00Z",
  "verb": "ls"
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
401 The signing key is not an enrolled user key, the signature does not verify, the request was issued outside the replay window, or it was already answered.
403 The caller's role may not change the registry, or may not grant the role named.
404 No such key or module name in the registry.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
modules array
userKeys array

auth.revoke

Revokes exactly one of a user key and a module name; live connections of the key are dropped, and the reply counts them.

Served by: *.auth.*.revoke

Request: a JSON object. Signed.

Field Type Required Meaning
issued string Issued is when the caller signed the request. The service refuses a request issued outside ReplayWindow of its own clock.
module object Module is the module argument of enrol and revoke.
userKey object UserKey is the person's-key argument of enrol and revoke. Exactly one of UserKey and Module is set on those verbs; neither on ls.
verb string Verb is the operation; it must match the subject the request is sent on, so a signed revoke cannot be replayed as an enrol.

Example:

{
  "issued": "2026-09-07T12:00:00Z",
  "module": {
    "name": "flower"
  },
  "verb": "revoke"
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
401 The signing key is not an enrolled user key, the signature does not verify, the request was issued outside the replay window, or it was already answered.
403 The caller's role may not change the registry, or may not grant the role named.
404 No such key or module name in the registry.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
disconnected integer

bundle.activate

Applies one installed variant to the running store: every member is placed and stamped with the bundle, and every config carrying that bundle which the variant does not list is withdrawn. An omitted variant resolves only where exactly one is installed. Persisted by a bundle commit.

Served by: cfg.bundle.*.activate

Request: a JSON object. Signed.

Field Type Required Meaning
adopt boolean Adopt lets the activation claim refs that run unattributed - no bundle placed them. Without it those refs are a rejection naming them, because taking ownership silently is what makes a bundle teardown months later delete a config nobody meant to hand over. A ref held by ANOTHER bundle is refused either way: that is an overlap between bundles, not an unclaimed config.
id string
variant string Variant selects which variant of the bundle to activate. Empty resolves only when exactly one is installed, and is refused naming them when several are: the convenience is a property of the device's current set, not of the model, so it can never be answered by guessing.

Example:

{
  "adopt": true,
  "id": "site",
  "variant": "v2"
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
401 The body is not a signed write, or the envelope is refused: a bad signature, another verb's, a stale issue time, or one already answered.
403 The signing key's role does not reach what the write addresses, or the key is in neither identity table.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
bundle string Bundle is the bundle its members were stamped with.
id string ID is the address of the variant that was activated, &lt;bundle>@&lt;variant>.
members array of bundleMemberResult Members carries one entry per config the activation touched, in ref order.

bundle.delete

Deletes one installed variant's file, or every variant of the bundle when none is named, refused while a file still describes running state held by its own bundle unless forced. Running configs are never touched by it.

Served by: cfg.bundle.*.delete

Request: a JSON object. Signed.

Field Type Required Meaning
force boolean Force deletes the file anyway. The members keep running and keep their bundle stamps, so a teardown afterwards still works - it needs the stamps, not the file. Deliberate un-bundling is the case it exists for.
id string
variant string Variant selects which variant's file to delete. Empty deletes EVERY variant of the bundle, and is refused whole if any one of them is held: it is one request about one bundle, so a partial outcome would leave an operator to work out which half ran.

Example:

{
  "force": true,
  "id": "site",
  "variant": "v2"
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
401 The body is not a signed write, or the envelope is refused: a bad signature, another verb's, a stale issue time, or one already answered.
403 The signing key's role does not reach what the write addresses, or the key is in neither identity table.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
bundle string Bundle is the bundle it belonged to, reported because it is the operator's handle on the members that outlive the file - and the file that carried it is now gone.
forced boolean Forced echoes the request, so a caller reading only the result can tell a delete that was allowed from one that overrode the guard.
id string ID is the address of the variant that was deleted, &lt;bundle>@&lt;variant>.
removed array Removed lists the addresses a bare-bundle delete removed, empty when one variant was named: a request about a bundle answers with what it took off, and a request about one file already says so in ID.
stillRunning array of componentRef StillRunning are the members whose running config still equalled a removed variant's body under its bundle when the file was deleted. Only a forced delete can report any: an unforced one is refused when this would be non-empty.

bundle.update

Creates or edits one variant of a bundle from running configs: members added from their running intent or removed, and the description set. The variant is required - update creates what it names. Every invocation writes a whole new artifact. With adopt the running configs follow the edit at once - refs added are stamped with the bundle, refs removed lose their stamp - persisted by a commit.

Served by: cfg.bundle.*.update

Request: a JSON object. Signed.

Field Type Required Meaning
add array of componentRef Add captures each ref's current running intent as a member, replacing whatever the bundle held for that ref. Re-adding a listed ref is how a member is refreshed after the config was tweaked - the same explicit act, not a separate flag. The ref has to be running; its attribution does not matter.
adopt boolean Adopt makes the running configs follow the edit now rather than at the next activation: every ref added is stamped with the document's bundle, every ref removed loses its stamp and runs unattributed from then on. Nothing is published and no module is asked - attribution is the configurer's bookkeeping, and config commit is what persists it. A ref added that another bundle holds is refused unless Force; a ref removed that another bundle holds is left alone. Requires at least one of Add and Remove.
description string Description sets the free-form author note; nil leaves it, empty clears it.
force boolean Force lets Adopt take an added ref over from the bundle holding it, which is the one way a running config moves between bundles without being deleted and created again. Refused without Adopt; unused when no added ref is held, the way an activation's adopt is unused when nothing runs unattributed.
id string ID is the bundle: the key the members are stamped with, and the component id of cfg.bundleinfo.&lt;id>.
remove array of componentRef Remove drops members from the FILE and is an error for a ref the bundle does not list. Without Adopt the running config is untouched: what a bundle lists and what runs under its bundle are different questions, and the next activation's stale sweep is what settles the second one.
variant string Variant is which variant of that bundle to author, and is REQUIRED here where the other verbs may take a bare bundle: update creates what it names, and a defaulted variant would be a second spelling of an identity the file name carries.

Example:

{
  "add": [
    "sys.ethernet.eth0"
  ],
  "adopt": true,
  "description": "The site's network profile.",
  "id": "site",
  "remove": [
    "sys.wlan.wlan0"
  ],
  "variant": "v2"
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
401 The body is not a signed write, or the envelope is refused: a bad signature, another verb's, a stale issue time, or one already answered.
403 The signing key's role does not reach what the write addresses, or the key is in neither identity table.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
adopted array of bundleAdoption Adopted is one entry per ref added or removed by a request with Adopt set, saying what the ref's attribution was and what it is now. Empty without Adopt.
bundle string Bundle is the bundle it belongs to - the left half of that address, repeated because it is what a config commit --bundle afterwards takes.
createdAt string
description string
digest string Digest is algorithm:hex over the file's bytes, and InstalledAt its modification time.
id string ID is the address of the variant that was written, &lt;bundle>@&lt;variant>.
installedAt string
members array of componentRef

flow.measurement_event_publish

Hands the flow a measurement event: without a measurementRef it starts a new measurement, with one it extends or stops the running one, and an event nothing is running for is ignored. The reply says which, and names the measurement running now.

Served by: flower.flow.*.measurement_event_publish

Request: a JSON object.

Field Type Required Meaning
event object

Example:

{
  "event": {
    "dataTimestamp": "2026-09-07T11:59:59Z",
    "deadline": "2026-09-07T12:02:00Z",
    "reason": "vibration above threshold",
    "ref": "trigger.trigger.vibration",
    "start": "2026-09-07T12:00:00Z",
    "timestamp": "2026-09-07T12:00:00Z"
  }
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no flow component, the body is not the request, or the flow refused the event: an unknown measurement, a deadline before the start.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
result object

gsm.reset

Resets the modem of this gsm connection.

Served by: sys.gsm.*.reset

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component.
500 The handler failed; the body carries the error.

gsm.send_sms

Sends an SMS over the modem of this gsm connection. Refused with 429 while the send queue is full.

Served by: sys.gsm.*.send_sms

Request: a JSON object.

Field Type Required Meaning
number string yes Number is the recipient, in international form (+41790000000).
text string yes Text is the message text.

Example:

{
  "number": "+41790000000",
  "text": "pump 2 stopped"
}

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
500 The handler failed; the body carries the error.

led.set

Sets this indicator: one pattern per element, keyed by element name; an element not named is set off. The element names and the patterns are the indicator's config's.

Served by: sys.led.*.set

Request: a JSON object.

Field Type Required Meaning

Example:

{
  "green": "blink",
  "red": "on"
}

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
500 The handler failed; the body carries the error.

main.cmd

Executes one board-controller command - a register read or write by ref, or a direct read or write by unit and register id - and answers its result; the body is the command object, discriminated by its type field.

Served by: bc.main.*.cmd

Request: a JSON object.

Field Type Required Meaning

Example:

{
  "registerRef": "bc.bcapp.reg.fw_version_uint",
  "type": "readValue"
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, the body is not a command, or the board refused it; the body is then {status, message, value}.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
message string
status string
value any

main.cmds

Executes a batch of board-controller commands in order, with one default timeout, and answers every command's result; with continueOnError a failed command does not end the batch, and its error is in the result.

Served by: bc.main.*.cmds

Request: a JSON object.

Field Type Required Meaning
commands array of boardCommand Commands are the batch, in the order they run.
continueOnError boolean ContinueOnError runs the remaining commands after one failed, reporting every outcome in the result rather than refusing the batch at the first failure.
timeout number Timeout is the default timeout per call, in seconds; a command's own options override it. Zero means the connector's default.

Example:

{
  "commands": [
    {
      "registerRef": "bc.bcapp.reg.scratch_pad",
      "type": "writeValue",
      "value": 7
    },
    {
      "options": {
        "timeout": 0.5
      },
      "registerRef": "bc.bcapp.reg.scratch_pad",
      "type": "readValue"
    }
  ],
  "continueOnError": true,
  "timeout": 2
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, the body is not a batch, or a command failed and the batch does not continue on error; the body is then {status, message, value} with the results so far.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
message string
status string
value any

manifest.check

Says what importing the manifest would do, by the validation the import runs, writing nothing: the bundles installed, the activations, the configs applied, and with the replace header the running configs and bundle files converging to it would take off the device.

Served by: cfg.manifest.*.check

Request: bytes, application/octet-stream.

Headers:

  • X-Algol-Manifest-Adopt: true lets every activation claim refs that run unattributed.
  • X-Algol-Manifest-Replace: true converges the whole device to the manifest: what it does not describe is taken off. Subsumes adopt.

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The manifest would be refused as a whole, with the same reason an import would give.
403 The requester's role does not reach what the manifest would write.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
activate array Activate is the manifest's activation list, in the order it would run.
bundles array Bundles is one entry per bundle the manifest carries, in id order.
configs array of componentRef Configs are the config section's refs, in ref order - which is the manifest's own order, not the order the apply addresses them in. The apply sorts by config type first (ConfigObjectFactory registration), so the two differ whenever the section spans more than one type; a caller reading this as a sequence would show the wrong one. It is a set, and the useful reading of it is membership.
removedBundles array RemovedBundles are the installed bundle files a --replace does not name.
removedConfigs array of componentRef RemovedConfigs is the absent set of a --replace check: the operator-managed configs running on this device that the manifest does not describe, which converging to it withdraws. Empty on a delta check, which removes nothing.
replace boolean Replace echoes the mode the check ran in, so a caller reading only the result can tell an empty removal set from a check that never looked for one.

manifest.export

Answers a manifest describing this device, gzipped: with no body or an empty request the backup - every installed bundle plus the whole startup set - and with bundles named a rollout of those bundles, activated in the order given. A named bundle whose variant is omitted resolves only where exactly one is installed, and the manifest names the full address either way.

Served by: cfg.manifest.*.export

Request: a JSON object, or none for the default.

Field Type Required Meaning
bundles array Bundles selects the rollout form and names exactly what it carries, in the order to activate them. It is required for a rollout rather than derived from what is "active": active is a per-member statement about hash pairs and is never stored, so a bundle with three of four members matching has no honest answer - and drift would silently change what a rollout contains. An entry is &lt;bundle>@&lt;variant>, or a bare &lt;bundle> where the device holds exactly one variant of it - the same resolution bundle activate does, and refused the same way for none or for several. The manifest that comes back always names the full address, so which variant a rollout carries is decided at export time.
noActivate boolean NoActivate ships the named bundles without the activation list: install now, activate later. Meaningless without Bundles, since a backup activates nothing.

Example:

{
  "bundles": [
    "site"
  ],
  "noActivate": true
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is bytes, application/gzip.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
403 The requester's role does not reach the export.
500 The handler failed; the body carries the error.

Reply headers:

  • X-Algol-Manifest-Omitted: What the requester's role left out of the export, as JSON {bundles, configs}; absent when nothing was.

manifest.import

Installs a manifest: its bundles, the activations it lists, and its config section, then persists them; the body is the manifest, plain JSON or gzipped. Validation is all-or-nothing before anything is written; a failure after it comes back inside the result, on the item it belongs to.

Served by: cfg.manifest.*.import

Request: bytes, application/octet-stream. Signed.

Headers:

  • X-Algol-Manifest-Adopt: true lets every activation claim refs that run unattributed.
  • X-Algol-Manifest-Replace: true converges the whole device to the manifest: what it does not describe is taken off. Subsumes adopt.

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The manifest is refused as a whole - the document, a body this build cannot use, an activation precondition - and nothing was written.
401 The body is not a signed write, or the envelope is refused: a bad signature, another verb's, a stale issue time, or one already answered.
403 The signing key's role does not reach what the write addresses, or the key is in neither identity table.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
activations array Activations follow the manifest's own order.
bundles array Bundles is one entry per bundle the manifest carried, in id order - installed whether or not it was activated.
configs array Configs is the config section's outcome, in the order the set was applied in - by config type first (ConfigObjectFactory registration), ref second - not in ref order.
removedBundles array
removedConfigs array RemovedConfigs and RemovedBundles are the absent set of a --replace import: the running configs the manifest does not describe, withdrawn in reverse ConfigObjectFactory order, and the installed bundle files it does not name. Both are empty on a delta import, which removes nothing.

player.play

Plays the WAV file the body names, out of the module's audio directory; the reply comes once playback ended, and a second request waits for the first.

Served by: audio.player.*.play

Request: text, text/plain.

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component, or the body is not a bare file name with the .wav suffix.
404 The audio directory holds no file of that name.
500 Playback failed; the body carries the player's error.

recstorage.recording_get

One catalogued Recording by its own ref - the ref column of a recording_list page - with its measurement, channel, size, digest and context.

Served by: recorder.recstorage.*.recording_get

Request: a JSON object.

Field Type Required Meaning
ref componentRef A component reference, moduleId.componentName.componentId.

Example:

{
  "ref": "recorder.rec.MFRGGZDF"
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
404 No catalogued Recording has this ref.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
recording recording

recstorage.recording_list

Lists one page of the recorder's catalog: the Recordings a measurement and a channel filter match, in path order, with the page's place in the whole set - the effective offset and the total the filter matches.

Served by: recorder.recstorage.*.recording_list

Request: a JSON object.

Field Type Required Meaning
filter recordingFilter Narrows a listing by measurement and by channel; a filter left out, or "*", matches everything on that dimension.
order string One of asc, desc.
page object

Example:

{
  "filter": {
    "channel": "*",
    "measurement": "flower.measurement.*"
  },
  "order": "asc",
  "page": {
    "limit": 50
  }
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
offset integer
recordings array of recording
total integer

s3upload.start

Opens an export run on this S3 upload profile; a start during a run is dropped.

Served by: recorder.s3upload.*.start

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component.
404 No export profile has this ref.
409 The profile is not running: its config is disabled or in error.
500 The handler failed; the body carries the error.

s3upload.stop

Ends the export run on this S3 upload profile once the Recording in hand is finished; a stop while idle is dropped.

Served by: recorder.s3upload.*.stop

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component.
404 No export profile has this ref.
409 The profile is not running: its config is disabled or in error.
500 The handler failed; the body carries the error.

secret.get

Reads a secret's value, answered only into the requester's own inbox and only to a requester a dispatched config admits to it.

Served by: cfg.secret.*.get

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component.
401 The reply subject is not a confined inbox.
403 No config dispatched to the requester references the secret from a type its declaration admits.
404 The secret is not declared.
409 The secret is declared and has no value yet.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
changed string
kind string One of string, bytes, bcrypt, awsCredentials.
value string

secret.set

Stores a declared secret's value, answered only into the requester's own inbox; the reply says when and how many bytes, never the value.

Served by: cfg.secret.*.set

Request: a JSON object. Signed.

Field Type Required Meaning
value string

Example:

{
  "value": "Y29ycmVjdCBob3JzZSBiYXR0ZXJ5IHN0YXBsZQ=="
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
401 The reply subject is not a confined inbox, or the write is not signed, or its envelope is refused.
403 The signing key is not in the identity tables.
404 The secret is not declared.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
changed string
size integer

store.commit

Persists the latest intent of the configs a filter matches to their startup files, so it survives a restart, whether or not the module has answered it yet; with a bundle, the members of that bundle only. The reply names what the requester's role left out.

Served by: cfg.store.*.commit

Request: a JSON object. Signed.

Field Type Required Meaning
bundle string Bundle narrows the commit to the configs carrying this bundle (RFC-014), on top of Filter. A bundle commit is what persists an activation: it writes every current member's startup file and removes the startup files of the members the activation deleted, in one pass.
filter componentFilter A wildcard component filter, moduleId.componentName.componentId with * for a free segment.

Example:

{
  "bundle": "site",
  "filter": "sys.ethernet.*"
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
401 The body is not a signed write, or the envelope is refused: a bad signature, another verb's, a stale issue time, or one already answered.
403 The signing key's role does not reach what the write addresses, or the key is in neither identity table.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
notInEffect array NotInEffect names the refs a commit persisted whose committed intent the module is not running: the resolution is still WAIT or failed ERROR (nothing was dispatched), the module has not answered this generation, or it answered WAIT or ERROR. A report, never a refusal - the file holds the intent either way and the next boot republishes it. It is what the operator would otherwise read off config ls after every commit. Empty on a revert.
skipped array

store.delete_bundle

Tears down a bundle: a delete for every running config carrying it, in reverse module order, best-effort, with each member's outcome in the reply. It needs no bundle file.

Served by: cfg.store.*.delete_bundle

Request: a JSON object. Signed.

Field Type Required Meaning
bundle string Bundle is required. An empty bundle would mean "delete every unattributed config", i.e. the whole device, so it is rejected rather than interpreted.

Example:

{
  "bundle": "site"
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
401 The body is not a signed write, or the envelope is refused: a bad signature, another verb's, a stale issue time, or one already answered.
403 The signing key's role does not reach what the write addresses, or the key is in neither identity table.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
result array

store.list_config_status

Lists the configs a filter matches as records of the stages a config travels - startup, intent published and its status, effective published and its status - each stage included on request. Records outside the requester's read set are left out silently.

Served by: cfg.store.*.list_config_status

Request: a JSON object.

Field Type Required Meaning
filter componentFilter A wildcard component filter, moduleId.componentName.componentId with * for a free segment.
include object

Example:

{
  "filter": "sys.*",
  "include": {
    "effectiveConfigStatus": true,
    "effectivePublishedConfig": true,
    "intentConfigStatus": true,
    "intentPublishedConfig": true,
    "startupConfig": true
  }
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
403 The requester's role does not reach the listing.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
result array of configRecord

store.patch

Changes the enabled state, the property values or both of one running config, atomically; a field left out is left as it is. Properties can be set, never added, removed or retyped.

Served by: cfg.store.*.patch

Request: a JSON object. Signed.

Field Type Required Meaning
enabled boolean
force boolean
properties array Properties carries the tag of its wire spelling so a schema reflected from the struct sees it (RFC-012); the codec below still writes and reads it itself, since a property list decodes by each entry's type.
ref componentRef A component reference, moduleId.componentName.componentId.
requestId string
version integer

Example:

{
  "enabled": true,
  "force": true,
  "properties": [
    {
      "name": "strength",
      "value": 3
    }
  ],
  "ref": "sys.teapot.pot0",
  "requestId": "req-7",
  "version": 4
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
401 The body is not a signed write, or the envelope is refused: a bad signature, another verb's, a stale issue time, or one already answered.
403 The signing key's role does not reach what the write addresses, or the key is in neither identity table.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
changedAt string ChangedAt is when this status content last changed (version, status code, or message). Independent of CreatedAt on the corresponding ConfigurationUpdate. Modules stamp it on every publish; the configurer retains the previous value when a republish carries the same version and status, so observers see last change, not last heartbeat.
config configBody Current configuration of the component. Should be a super set from the Configuration in the corresponding ConfigUpdate. Should be a pointer to the actual configuration object. It's not of type ConfigObject, to be able to put anything in it (especially useful in error conditions)
ref componentRef Reference to the component the configuration update is for.
requestId string RequestID for tracking. Might be empty. RequestID is not used for any internal logic, but is passed through from ConfigUpdate and is used to differentiate the result of concurrent requests to the same component with the same Version.
status configStatus Status of the configuration update.
version integer Version of the configuration update.

store.revert

Returns the running configs a filter matches to the body persisted on disk - the inverse of a commit; with a bundle, the members of that bundle only. A config already at its committed body is left alone.

Served by: cfg.store.*.revert

Request: a JSON object. Signed.

Field Type Required Meaning
bundle string
filter componentFilter A wildcard component filter, moduleId.componentName.componentId with * for a free segment.

Example:

{
  "bundle": "site",
  "filter": "sys.ethernet.*"
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
401 The body is not a signed write, or the envelope is refused: a bad signature, another verb's, a stale issue time, or one already answered.
403 The signing key's role does not reach what the write addresses, or the key is in neither identity table.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
notInEffect array NotInEffect names the refs a commit persisted whose committed intent the module is not running: the resolution is still WAIT or failed ERROR (nothing was dispatched), the module has not answered this generation, or it answered WAIT or ERROR. A report, never a refusal - the file holds the intent either way and the next boot republishes it. It is what the operator would otherwise read off config ls after every commit. Empty on a revert.
skipped array

store.update

Creates, edits or deletes one running config: the update envelope names the ref, the operation and the config body of the addressed type. The reply is the configurer's answer for the intent; the module's own answer follows on the config status subject.

Served by: cfg.store.*.update

Request: a JSON object. Signed.

Field Type Required Meaning
bundle string Bundle is the bundle attribution this update stamps on the target's config record (RFC-014). Modules ignore it, exactly like ManagedBy: it is the configurer's bookkeeping, carried on the wire so that a configurer restart can rebuild the attribution from the CONFIG stream replay. Empty means "leave the attribution as it is", never "clear it": an ordinary operator update to a member must not detach it, or the member silently drops out of config commit --bundle and out of bundle teardown. Only the bundle verbs set a bundle - an activation on this field, bundle update --adopt on the record without a publish - and only bundle update --remove --adopt clears one. The configurer's update endpoint refuses an external update that names a bundle for the same reason: a claim without the conflict table is not a claim a bundle made. It is a component ref part, because it is one: a document whose id becomes cfg.bundleinfo.&lt;id> claims the key of the same name by default, so the two namespaces are one namespace, and a key that could not be an id would be a key nothing could ever own.
config configBody Configuration update. Might be empty in case of a CONFIG_DELETE operation. It's always a pointer type!
createdAt string Creation timestamp of this update. Optional.
force boolean If Force is true, the config handler skips the equality check and always pushes the update through, even when the incoming config is structurally identical to the stored one.
op string Operation to perform on the configuration. If omitted, CONFIG_UPDATE is assumed. Configuration will be ignored for a CONFIG_DELETE operation. One of UPDATE, DELETE.
ref componentRef yes The component to update (independent of other updates).
requestId string RequestID for tracking. Might be empty. RequestID is not used for any internal logic, but is passed through to subsequent ConfigUpdateStatus.
version integer Version for optimistic locking. If Version is omitted, it's default of 0 comes into play which means last update wins.

Example:

{
  "bundle": "site",
  "config": {
    "enabled": true,
    "id": "pot0",
    "label": "Kitchen pot",
    "schemaVersion": 6,
    "type": "teapot"
  },
  "op": "UPDATE",
  "ref": "sys.teapot.pot0",
  "requestId": "req-7",
  "version": 4
}

Responses:

Code Meaning
200 Done; the body is the answer. The body is a JSON object.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
401 The body is not a signed write, or the envelope is refused: a bad signature, another verb's, a stale issue time, or one already answered.
403 The signing key's role does not reach what the write addresses, or the key is in neither identity table.
500 The handler failed; the body carries the error.

Reply fields:

Field Type Required Meaning
changedAt string ChangedAt is when this status content last changed (version, status code, or message). Independent of CreatedAt on the corresponding ConfigurationUpdate. Modules stamp it on every publish; the configurer retains the previous value when a republish carries the same version and status, so observers see last change, not last heartbeat.
config configBody Current configuration of the component. Should be a super set from the Configuration in the corresponding ConfigUpdate. Should be a pointer to the actual configuration object. It's not of type ConfigObject, to be able to put anything in it (especially useful in error conditions)
ref componentRef Reference to the component the configuration update is for.
requestId string RequestID for tracking. Might be empty. RequestID is not used for any internal logic, but is passed through from ConfigUpdate and is used to differentiate the result of concurrent requests to the same component with the same Version.
status configStatus Status of the configuration update.
version integer Version of the configuration update.

systemd.restart

Restarts the host unit named in the body, whatever it is. Never grantable to a configured role: the target is in the body, where no permission reaches.

Served by: sys.systemd.*.restart

Request: text, text/plain.

Responses:

Code Meaning
200 Done; the body is the answer. The body is text.
400 The subject names no component.
500 The handler failed; the body carries the error.

systemdapp.restart

Restarts this app.

Served by: sys.systemdapp.*.restart

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component.
500 The handler failed; the body carries the error.

systemdapp.start

Runs this listen-mode app now: mounts its rootfs and starts it.

Served by: sys.systemdapp.*.start

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component.
500 The handler failed; the body carries the error.

systemdmount.release

Unmounts the medium in this slot and leaves the slot enabled, so the next medium mounts on its own; the unmount runs in the background and reports through the slot's status.

Served by: sys.systemdmount.*.release

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component.
500 The handler failed; the body carries the error.

systemdscript.restart

Restarts this script: a start-mode script is run again, a running one is bounced.

Served by: sys.systemdscript.*.restart

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component.
500 The handler failed; the body carries the error.

systemdscript.start

Runs this listen-mode script now.

Served by: sys.systemdscript.*.start

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component.
500 The handler failed; the body carries the error.

systemdunit.restart

Restarts this host unit. Refused with 409 while the unit's config is disabled or systemd does not have the unit.

Served by: sys.systemdunit.*.restart

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component.
500 The handler failed; the body carries the error.

systemdunit.start

Starts this host unit. Refused with 409 while the unit's config is disabled or systemd does not have the unit.

Served by: sys.systemdunit.*.start

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component.
500 The handler failed; the body carries the error.

systemdunit.stop

Stops this host unit. Refused with 409 while the unit's config is disabled or systemd does not have the unit.

Served by: sys.systemdunit.*.stop

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component.
500 The handler failed; the body carries the error.

teapot.brew

Starts a brew on this teapot at the given strength.

Served by: sys.teapot.*.brew

Request: a JSON object.

Field Type Required Meaning
label string Label names the brew, for the pot's log; optional.
strength integer yes Strength is the brew strength, 1 (weak) to 5 (strong). Between 1 and 5.

Example:

{
  "label": "afternoon",
  "strength": 3
}

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component, or the body is not a JSON object, or a declared field is missing or of the wrong kind.
409 The pot is already brewing; the same request succeeds once it is done.
500 The handler failed; the body carries the error.

usbexport.start

Opens an export run on this USB export profile; a start during a run is dropped.

Served by: recorder.usbexport.*.start

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component.
404 No export profile has this ref.
409 The profile is not running: its config is disabled or in error.
500 The handler failed; the body carries the error.

usbexport.stop

Ends the export run on this USB export profile once the Recording in hand is finished; a stop while idle is dropped.

Served by: recorder.usbexport.*.stop

Request: none, the verb is the whole request.

Responses:

Code Meaning
200 Done. The body is the text ok.
400 The subject names no component.
404 No export profile has this ref.
409 The profile is not running: its config is disabled or in error.
500 The handler failed; the body carries the error.

Shared definitions

The models the documents share, published once in schema/common/v1.schema.json and referenced from every tree (RFC-012, "Shared definitions").

attributeRef

An attribute reference, a component reference plus an attribute name.

A string matching ^[a-zA-Z_][0-9a-zA-Z_]*\.[a-zA-Z_][0-9a-zA-Z_]*\.[a-zA-Z_][0-9a-zA-Z_]*\.[a-zA-Z_][0-9a-zA-Z_]*$.

boardCommand

One board-controller command, discriminated by its type field: a register read or write by ref, or a direct read or write by unit and register id.

One of: boardWriteValue, boardReadValue, boardReadValues, boardDirectReadValue, boardDirectReadValues, boardDirectWriteValue, boardDirectWriteValues, boardDirectWriteBytes.

boardDirectReadValue

DirectReadValueCmd reads one register by unit and register id, whether or not a register is configured for it.

Field Type Required Meaning
options object
registerId integer
type string yes The command's type, which selects the fields beside it.
unitId integer

boardDirectReadValues

DirectReadValuesCmd reads Length consecutive registers from a unit and register id.

Field Type Required Meaning
length integer
options object
registerId integer
type string yes The command's type, which selects the fields beside it.
unitId integer

boardDirectWriteBytes

DirectWriteBytesCmd writes a byte string from a unit and register id, in pages, and has the unit verify it against the digest.

Field Type Required Meaning
chunkSize integer ChunkSize is the write page size in bytes, a positive multiple of 2; zero means 2.
content string Content is the byte string, base64 on the wire.
md5sum string MD5Sum is the hex MD5 of Content, which the unit verifies after the last page.
options object
registerId integer
type string yes The command's type, which selects the fields beside it.
unitId integer

boardDirectWriteValue

DirectWriteValueCmd writes one value by unit and register id.

Field Type Required Meaning
options object
registerId integer
type string yes The command's type, which selects the fields beside it.
unitId integer
value integer

boardDirectWriteValues

DirectWriteValuesCmd writes consecutive values from a unit and register id.

Field Type Required Meaning
options object
registerId integer
type string yes The command's type, which selects the fields beside it.
unitId integer
values array

boardReadValue

ReadValueCmd reads one register named by its ref.

Field Type Required Meaning
options object
registerRef string RegisterRef names the register, bc.<connector>.reg.<name>.
type string yes The command's type, which selects the fields beside it.

boardReadValues

ReadValuesCmd reads a set of registers in one range read.

Field Type Required Meaning
options object
registerRefs array RegisterRefs name the registers, bc.<connector>.reg.<name> each.
type string yes The command's type, which selects the fields beside it.

boardWriteValue

WriteValueCmd writes one value to a register named by its ref.

Field Type Required Meaning
options object
registerRef string RegisterRef names the register, bc.<connector>.reg.<name>.
type string yes The command's type, which selects the fields beside it.
value integer Value is the 16-bit value to write.

bundleAdoption

BundleAdoption is one ref's attribution around a bundle update --adopt: From is the bundle it carried before the edit and Bundle the one it carries after - the bundle's for a ref added, none for a ref removed.

Field Type Required Meaning
bundle string
from string
ref componentRef A component reference, moduleId.componentName.componentId.

bundleMemberResult

BundleActivateMemberResult is one config's outcome.

Field Type Required Meaning
adopted boolean Adopted marks a member that was claimed without being published: what runs under the ref was already the bundle's content, so only the attribution changed. There is no status because no module was asked - and deliberately so, since migrating a device onto bundles must not churn every module with updates that change nothing.
error string Error is the configurer's own refusal, or the reason no answer arrived.
ref componentRef A component reference, moduleId.componentName.componentId.
status configUpdateStatus Holds information about the status of a configuration update.

componentFilter

A wildcard component filter, moduleId.componentName.componentId with * for a free segment.

A string matching ^(?:[a-zA-Z_][0-9a-zA-Z_]*|\*)(?:\.(?:[a-zA-Z_][0-9a-zA-Z_]*|\*)){0,3}(?:\.\*)?$.

componentRef

A component reference, moduleId.componentName.componentId.

A string matching ^[a-zA-Z_][0-9a-zA-Z_]*\.[a-zA-Z_][0-9a-zA-Z_]*\.[a-zA-Z_][0-9a-zA-Z_]*$.

componentStatus

A component status by name, as it travels in JSON.

A string, one of DELETED, DISABLED, ERROR, UNKNOWN, OK, WAIT.

componentStatusIndex

A component status as a status field publishes it (RFC-029 D5): the integer index, named by x-enum-varnames.

An integer: -3=DELETED, -2=DISABLED, -1=ERROR, 0=UNKNOWN, 1=OK, 2=WAIT.

configBody

A config body of a registered type, its type field included; that type's document under schema/config describes it.

An open object.

configRecord

ConfigRecord is a single entry in the list_config_status response: one config in every stage it travels, which is what algol config info / ls print.

Field Type Required Meaning
bundle string Bundle is the bundle attribution of this config (RFC-014): the exclusivity key config commit --bundle and config delete --bundle select on, set by a bundle activation and defaulting to the placing bundle's id. Empty means unattributed - the state of every config no bundle placed, which is every config before bundles are used at all.
effectiveConfigStatus configUpdateStatus EffectiveConfigStatus is what the module reported back for that config - the apply axis, and the body it is actually running. Nil when the module has not answered, and when a config was deleted but not yet committed (its status is mapped to nil externally).
effectivePublishedConfig configUpdate EffectivePublishedConfig is the update last published on the component's own config subject - the bound config for a resolution-managed target, the config itself otherwise. It is the only record of what the module was given: the intent may never have resolved, and the module may never have answered.
intentConfigStatus configUpdateStatus IntentConfigStatus is how the configurer answered that intent: the resolution axis (WAIT while sources are missing, ERROR when resolution or materialization failed, OK once a bound config was dispatched).
intentPublishedConfig configUpdate IntentPublishedConfig is the operator intent as published: since RFC-022 its Configuration is the resolution envelope, not the bound config the module receives. Nil for module-sourced components, which nobody authored.
managedBy string ManagedBy names who owns this config: ManagedByModule for a config the module publishes itself, otherwise the source of the last update ("cli", "remote", ...). Always set.
ref componentRef Component is always set; it identifies the config object this entry describes.
startupConfig configBody StartupConfig is the configuration currently persisted on disk. Nil if the component has no persisted startup config. The tag is its wire spelling for a schema reflected from the struct (RFC-012); the codec below writes and reads it itself, by the body's type.
summary object Summary is every stage as a listing reads it, without the bodies: a content digest per stage plus the handful of facts a row is rendered from. Populated by the Summary include flag, which is the one a listing asks for.

configStatus

Field Type Required Meaning
msg string Optional message, may be used for additional information (e.g. error message, operational hints, ...)
statusCode componentStatus Status code for the specific configuration update. Includes the deletion case (for handling of deletions downstream) One of DELETED, DISABLED, ERROR, UNKNOWN, OK, WAIT.

configUpdate

A ConfigurationUpdate is used to update a component's configuration.

Field Type Required Meaning
bundle string Bundle is the bundle attribution this update stamps on the target's config record (RFC-014). Modules ignore it, exactly like ManagedBy: it is the configurer's bookkeeping, carried on the wire so that a configurer restart can rebuild the attribution from the CONFIG stream replay. Empty means "leave the attribution as it is", never "clear it": an ordinary operator update to a member must not detach it, or the member silently drops out of config commit --bundle and out of bundle teardown. Only the bundle verbs set a bundle - an activation on this field, bundle update --adopt on the record without a publish - and only bundle update --remove --adopt clears one. The configurer's update endpoint refuses an external update that names a bundle for the same reason: a claim without the conflict table is not a claim a bundle made. It is a component ref part, because it is one: a document whose id becomes cfg.bundleinfo.&lt;id> claims the key of the same name by default, so the two namespaces are one namespace, and a key that could not be an id would be a key nothing could ever own.
config configBody Configuration update. Might be empty in case of a CONFIG_DELETE operation. It's always a pointer type!
createdAt string Creation timestamp of this update. Optional.
force boolean If Force is true, the config handler skips the equality check and always pushes the update through, even when the incoming config is structurally identical to the stored one.
op string Operation to perform on the configuration. If omitted, CONFIG_UPDATE is assumed. Configuration will be ignored for a CONFIG_DELETE operation. One of UPDATE, DELETE.
ref componentRef yes The component to update (independent of other updates).
requestId string RequestID for tracking. Might be empty. RequestID is not used for any internal logic, but is passed through to subsequent ConfigUpdateStatus.
version integer Version for optimistic locking. If Version is omitted, it's default of 0 comes into play which means last update wins.

configUpdateStatus

Holds information about the status of a configuration update.

Field Type Required Meaning
changedAt string ChangedAt is when this status content last changed (version, status code, or message). Independent of CreatedAt on the corresponding ConfigurationUpdate. Modules stamp it on every publish; the configurer retains the previous value when a republish carries the same version and status, so observers see last change, not last heartbeat.
config configBody Current configuration of the component. Should be a super set from the Configuration in the corresponding ConfigUpdate. Should be a pointer to the actual configuration object. It's not of type ConfigObject, to be able to put anything in it (especially useful in error conditions)
ref componentRef Reference to the component the configuration update is for.
requestId string RequestID for tracking. Might be empty. RequestID is not used for any internal logic, but is passed through from ConfigUpdate and is used to differentiate the result of concurrent requests to the same component with the same Version.
status configStatus Status of the configuration update.
version integer Version of the configuration update.

recording

Field Type Required Meaning
archiveIdx integer Index of recording for a channel in archive (0-based)
archiveLen integer Amount of total recordings for a channel in archive. If 0, the length is unknown.
archiveRef componentRef A component reference, moduleId.componentName.componentId.
channelRef componentRef A component reference, moduleId.componentName.componentId.
channelType string One of Scalar, GeographicCoordinate, CartesianCoordinate, GPSVelocity, MonoPCMAudio16.
context object
deleted boolean
digest string Digest is the algorithm:hex content digest of the complete Parquet file bytes (today md5:<lowercase-hex>), computed at completion and held in the catalog (never in the Parquet footer). Empty when unknown.
freq number
last string
measurementRef componentRef A component reference, moduleId.componentName.componentId.
recRef componentRef A component reference, moduleId.componentName.componentId.
ref componentRef A component reference, moduleId.componentName.componentId.
size integer Size of the recording in bytes (if available)
start string
url string

recordingFilter

Narrows a listing by measurement and by channel; a filter left out, or "*", matches everything on that dimension.

Field Type Required Meaning
channel componentFilter A wildcard component filter, moduleId.componentName.componentId with * for a free segment.
measurement componentFilter A wildcard component filter, moduleId.componentName.componentId with * for a free segment.