Skip to content

Functions

A function graph is a template of nodes and edges whose dynamic settings are the parameters it leaves open. An instance binds them — to devices, groups or fixed values — and is the thing that runs. Every trigger re-evaluates the whole graph in one pass, a sweep, so counters, latches and timers are explicit runtime state, kept per evaluation context.

Sweeps are triggered by OBJECT_UPDATED from flake, by META_SET from meta and by timer deadlines; group membership decides which per-device contexts exist. A result leaves the graph as a virtual property beside the device's own, as a mail through the email module, or as FUNCTIONS_STATE on the websocket.

GETList node types/api/v1/function/nodes
POSTCreate a function graph/api/v1/function
GETList function graphs/api/v1/function
GETRead a function graph/api/v1/function/:functionId
PATCHUpdate a function graph/api/v1/function/:functionId
DELETEDelete a function graph/api/v1/function/:functionId
POSTCreate an instance/api/v1/function/:functionId/instance
GETList instances/api/v1/function/:functionId/instance
GETRead an instance with its state/api/v1/function/:functionId/instance/:instanceId
PATCHUpdate an instance/api/v1/function/:functionId/instance/:instanceId
DELETEDelete an instance/api/v1/function/:functionId/instance/:instanceId
POSTReset the runtime state/api/v1/function/:functionId/instance/:instanceId/reset

List node types

The registry a graph editor builds its palette from: every node type with its ports, its settings and the family it belongs to. inputs is a map of ports, or the string dynamic-number/dynamic-bool for types that take any number of same-typed inputs.

GET/api/v1/function/nodes

Response

NameDescription
typeenumThe type string a config puts in nodes[].typePROP, ADD, TON, EMAIL_NOTIFY and the rest.
Possible values: PROP, META, NUM, STR, BOOL, TIME, DUR, ADD, MULT, SUB, DIV, INT_DIV, MOD, BIT_AND, BIT_OR, BIT_XOR, ABS, EXP, CEIL, FLOOR, POW, LIMIT, LN, LOG, GRT, EQL_RT, LSR, EQL_LSR, EQL, UNEQL, STRICT_EQL, STRICT_UNEQL, AND, NAND, OR, NOR, XOR, NXOR, SR, RS, R_TRIG, F_TRIG, INCR, CTU, CTD, CTUD, TON, TOF, TP, STPW, GATE, SNAP, MUX, MIN, MAX, VRT_PROP, EMAIL_NOTIFY, RES
familystringWhich group of the palette the type belongs to: input, arithmetic, compare, logic, processing, selection, effect or result.
inputsThe input ports the type declares, keyed by port name — or the string dynamic-number/dynamic-bool for types that take any number of same-typed inputs.
Alternative 1dictionaryThe input ports the type declares, keyed by port name — or the string dynamic-number/dynamic-bool for types that take any number of same-typed inputs.
typeenumThe value type every setting of the family takes.
Possible values: number, bool, string, time, duration
unitoptionalenumPresentation only — ms or s for how a client should show the value; stored values are milliseconds either way.
Possible values: ms, s
optionalbooleanoptionalWhether a node may omit the port; every port that is not optional has to be declared on the node.
descriptionstringoptionalWhat the port stands for, as the node type declares it.
Alternative 2stringThe input ports the type declares, keyed by port name — or the string dynamic-number/dynamic-bool for types that take any number of same-typed inputs.
outputsdictionaryThe output ports the type declares, keyed by port name; never dynamic.
typeenumThe value type every setting of the family takes.
Possible values: number, bool, string, time, duration
unitoptionalenumPresentation only — ms or s for how a client should show the value; stored values are milliseconds either way.
Possible values: ms, s
optionalbooleanoptionalWhether a node may omit the port; every port that is not optional has to be declared on the node.
descriptionstringoptionalWhat the port stands for, as the node type declares it.
settingsdictionaryThe settings the type accepts, keyed by name — deviceIdentifier, propIdentifier, template and the like.
typeenumThe value type every setting of the family takes.
Possible values: number, bool, string, time, duration
requiredbooleanWhether a config has to supply the setting; a missing one fails validation.
extraInputsbooleanoptionalSet when the type also accepts input ports the config author names — EMAIL_NOTIFY takes one per template parameter the graph feeds.
extraSettingsobjectoptionalSet when the type accepts a whole family of settings sharing a prefix. Their names come from whatever the node points at rather than from the type, so an editor has to look them up there.
prefixstringThe prefix those settings share — param. on EMAIL_NOTIFY, one per template parameter.
typeenumThe value type every setting of the family takes.
Possible values: number, bool, string, time, duration
descriptionstringoptionalWhat the node type does, as the registry declares it.

Errors

StatusDescriptionBody
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Create a function graph

Stores a graph as a template — it computes nothing until an instance binds it. The open parameters are derived from the dynamic settings, and every device a node names outright has to be one the caller may read, or update in the case of VRT_PROP.

POST/api/v1/function

Body

NameDescription
namestringDisplay name of the graph, 1 to 64 characters.
min length 1 · max length 64
descriptionstringoptionalWhat the graph does, for whoever reads it later; free text.
nodesarrayThe nodes of the graph, each with a ref unique within it. What a node may carry follows from its type, so GET /function/nodes is the contract.
refstringThe node's name inside this graph — unique, 1 to 64 characters of letters, digits, - and _. Edges address ports as <ref>.<port>.
Pattern: ^[0-9a-zA-Z\-_]{1,64}$
typeenumWhich node type computes here; one of those GET /function/nodes lists, and it decides which settings and ports are allowed.
Possible values: PROP, META, NUM, STR, BOOL, TIME, DUR, ADD, MULT, SUB, DIV, INT_DIV, MOD, BIT_AND, BIT_OR, BIT_XOR, ABS, EXP, CEIL, FLOOR, POW, LIMIT, LN, LOG, GRT, EQL_RT, LSR, EQL_LSR, EQL, UNEQL, STRICT_EQL, STRICT_UNEQL, AND, NAND, OR, NOR, XOR, NXOR, SR, RS, R_TRIG, F_TRIG, INCR, CTU, CTD, CTUD, TON, TOF, TP, STPW, GATE, SNAP, MUX, MIN, MAX, VRT_PROP, EMAIL_NOTIFY, RES
settingsdictionaryoptionalThe node's settings, keyed by name. Each is either fixed in the graph or left open, and every open one becomes a parameter the instance binds.
inputsdictionaryoptionalThe input ports of this node, named with one to three upper-case letters or digits. A fixed-arity type has to be given its required ports; a dynamic one — ADD, AND — gets as many as the graph names.
typeenumThe value the port carries; declaring it sharpens a generic port — a PROP output to bool, say — and both ends of an edge have to agree.
Possible values: number, bool, string, time, duration
unitoptionalenumPresentation only — ms or s for how a client should show the value; stored values are milliseconds either way.
Possible values: ms, s
optionalbooleanoptionalWhether the port may be left out. Which ports a type actually requires is fixed by the type; GET /function/nodes is the authority.
descriptionstringoptionalWhat the port stands for; free text, not interpreted.
outputsdictionaryoptionalThe output ports of this node, in the same shape as inputs; only ports the type has.
typeenumThe value the port carries; declaring it sharpens a generic port — a PROP output to bool, say — and both ends of an edge have to agree.
Possible values: number, bool, string, time, duration
unitoptionalenumPresentation only — ms or s for how a client should show the value; stored values are milliseconds either way.
Possible values: ms, s
optionalbooleanoptionalWhether the port may be left out. Which ports a type actually requires is fixed by the type; GET /function/nodes is the authority.
descriptionstringoptionalWhat the port stands for; free text, not interpreted.
edgesarrayThe connections between node ports. A graph may not contain a cycle — the sweep walks it in one pass, in topological order.
fromstringSource, as <ref>.<port>, naming an output of a node in this graph.
tostringTarget, as <ref>.<port>, naming an input; one input takes exactly one edge, a second into it is rejected.
tenantIdstringoptionalWhich tenant the graph belongs to. Only needed when the caller's access spans several tenants; otherwise it follows from the access rules.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Response

NameDescription
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource

Errors

StatusDescriptionBody
403You do not have permission to perform this action
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The graph or its bindings do not hold together — a dangling edge, a port the node type does not have, a type mismatch across an edge, a cycle, or a parameter left unbound. sections names the failing area and lists one message per problem; fix those and repeat the call.
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

List function graphs

Lists the graphs of the tenant; depth=1 adds the full config. A graph naming a device the caller may not read is left out rather than refused.

GET/api/v1/function?depth=0

Query Parameters

NameDescription
depthintegeroptionalHow many levels of nested resources the response includes; 0 returns only the top level.
Default: 0
min 0

Response

NameDescription
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
configobjectoptionaldepth ≥ 1The stored graph; included from depth=1.
namestringDisplay name of the graph, 1 to 64 characters.
min length 1 · max length 64
descriptionstringoptionalWhat the graph does, for whoever reads it later; free text.
nodesarrayThe nodes of the graph, each with a ref unique within it. What a node may carry follows from its type, so GET /function/nodes is the contract.
refstringThe node's name inside this graph — unique, 1 to 64 characters of letters, digits, - and _. Edges address ports as <ref>.<port>.
Pattern: ^[0-9a-zA-Z\-_]{1,64}$
typeenumWhich node type computes here; one of those GET /function/nodes lists, and it decides which settings and ports are allowed.
Possible values: PROP, META, NUM, STR, BOOL, TIME, DUR, ADD, MULT, SUB, DIV, INT_DIV, MOD, BIT_AND, BIT_OR, BIT_XOR, ABS, EXP, CEIL, FLOOR, POW, LIMIT, LN, LOG, GRT, EQL_RT, LSR, EQL_LSR, EQL, UNEQL, STRICT_EQL, STRICT_UNEQL, AND, NAND, OR, NOR, XOR, NXOR, SR, RS, R_TRIG, F_TRIG, INCR, CTU, CTD, CTUD, TON, TOF, TP, STPW, GATE, SNAP, MUX, MIN, MAX, VRT_PROP, EMAIL_NOTIFY, RES
settingsdictionaryoptionalThe node's settings, keyed by name. Each is either fixed in the graph or left open, and every open one becomes a parameter the instance binds.
inputsdictionaryoptionalThe input ports of this node, named with one to three upper-case letters or digits. A fixed-arity type has to be given its required ports; a dynamic one — ADD, AND — gets as many as the graph names.
typeenumThe value type the binding has to carry.
Possible values: number, bool, string, time, duration
unitoptionalenumPresentation only — ms or s for how a client should show the value; stored values are milliseconds either way.
Possible values: ms, s
optionalbooleanoptionalWhether the port may be left out. Which ports a type actually requires is fixed by the type; GET /function/nodes is the authority.
descriptionstringoptionalWhat the port stands for; free text, not interpreted.
outputsdictionaryoptionalThe output ports of this node, in the same shape as inputs; only ports the type has.
typeenumThe value type the binding has to carry.
Possible values: number, bool, string, time, duration
unitoptionalenumPresentation only — ms or s for how a client should show the value; stored values are milliseconds either way.
Possible values: ms, s
optionalbooleanoptionalWhether the port may be left out. Which ports a type actually requires is fixed by the type; GET /function/nodes is the authority.
descriptionstringoptionalWhat the port stands for; free text, not interpreted.
edgesarrayThe connections between node ports. A graph may not contain a cycle — the sweep walks it in one pass, in topological order.
fromstringSource, as <ref>.<port>, naming an output of a node in this graph.
tostringTarget, as <ref>.<port>, naming an input; one input takes exactly one edge, a second into it is rejected.
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
parametersarrayThe settings the graph leaves open, sorted by key; dynamic settings that share a ref become one parameter rather than several. An instance has to bind every one of them.
keystringHow a binding addresses the parameter: the setting's own ref, or <node>.<setting> when it has none.
typeenumThe value type the binding has to carry.
Possible values: number, bool, string, time, duration
kindoptionalenumdevice when the parameter names a device — a binding for it has to be a device or a group; value for everything else.
Default: value
Possible values: value, device
orderarraystringThe node refs in evaluation order, computed when the graph was written; every sweep walks the graph exactly this way.
createdBystringResource identifier of the entity that created this resource

Errors

StatusDescriptionBody
403You do not have permission to perform this action
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The request did not match the schema for this endpoint. The details field carries the specific failures.error: Validation Error
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Read a function graph

The stored graph with what the server derived from it: parameters, which an instance has to bind, and order, the sequence every sweep walks. A graph naming a device the caller may not read answers 404, so the response does not confirm that it exists.

GET/api/v1/function/Yk3pL7rWq2

Path Parameters

NameDescription
functionIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Response

NameDescription
namestringDisplay name of the graph, 1 to 64 characters.
min length 1 · max length 64
descriptionstringoptionalWhat the graph does, for whoever reads it later; free text.
nodesarrayThe nodes of the graph, each with a ref unique within it. What a node may carry follows from its type, so GET /function/nodes is the contract.
refstringThe node's name inside this graph — unique, 1 to 64 characters of letters, digits, - and _. Edges address ports as <ref>.<port>.
Pattern: ^[0-9a-zA-Z\-_]{1,64}$
typeenumWhich node type computes here; one of those GET /function/nodes lists, and it decides which settings and ports are allowed.
Possible values: PROP, META, NUM, STR, BOOL, TIME, DUR, ADD, MULT, SUB, DIV, INT_DIV, MOD, BIT_AND, BIT_OR, BIT_XOR, ABS, EXP, CEIL, FLOOR, POW, LIMIT, LN, LOG, GRT, EQL_RT, LSR, EQL_LSR, EQL, UNEQL, STRICT_EQL, STRICT_UNEQL, AND, NAND, OR, NOR, XOR, NXOR, SR, RS, R_TRIG, F_TRIG, INCR, CTU, CTD, CTUD, TON, TOF, TP, STPW, GATE, SNAP, MUX, MIN, MAX, VRT_PROP, EMAIL_NOTIFY, RES
settingsdictionaryoptionalThe node's settings, keyed by name. Each is either fixed in the graph or left open, and every open one becomes a parameter the instance binds.
inputsdictionaryoptionalThe input ports of this node, named with one to three upper-case letters or digits. A fixed-arity type has to be given its required ports; a dynamic one — ADD, AND — gets as many as the graph names.
typeenumThe value type the binding has to carry.
Possible values: number, bool, string, time, duration
unitoptionalenumPresentation only — ms or s for how a client should show the value; stored values are milliseconds either way.
Possible values: ms, s
optionalbooleanoptionalWhether the port may be left out. Which ports a type actually requires is fixed by the type; GET /function/nodes is the authority.
descriptionstringoptionalWhat the port stands for; free text, not interpreted.
outputsdictionaryoptionalThe output ports of this node, in the same shape as inputs; only ports the type has.
typeenumThe value type the binding has to carry.
Possible values: number, bool, string, time, duration
unitoptionalenumPresentation only — ms or s for how a client should show the value; stored values are milliseconds either way.
Possible values: ms, s
optionalbooleanoptionalWhether the port may be left out. Which ports a type actually requires is fixed by the type; GET /function/nodes is the authority.
descriptionstringoptionalWhat the port stands for; free text, not interpreted.
edgesarrayThe connections between node ports. A graph may not contain a cycle — the sweep walks it in one pass, in topological order.
fromstringSource, as <ref>.<port>, naming an output of a node in this graph.
tostringTarget, as <ref>.<port>, naming an input; one input takes exactly one edge, a second into it is rejected.
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
parametersarrayThe settings the graph leaves open, sorted by key; dynamic settings that share a ref become one parameter rather than several. An instance has to bind every one of them.
keystringHow a binding addresses the parameter: the setting's own ref, or <node>.<setting> when it has none.
typeenumThe value type the binding has to carry.
Possible values: number, bool, string, time, duration
kindoptionalenumdevice when the parameter names a device — a binding for it has to be a device or a group; value for everything else.
Default: value
Possible values: value, device
orderarraystringThe node refs in evaluation order, computed when the graph was written; every sweep walks the graph exactly this way.
createdBystringResource identifier of the entity that created this resource

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404No graph with this {functionId} in the tenant — and the same answer when the graph names a device the caller may not read, so a 404 here is not proof of absence. Check the id against GET /function.
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The request did not match the schema for this endpoint. The details field carries the specific failures.error: Validation Error
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Update a function graph

nodes and edges are replaced whole rather than merged, and the result is validated again. A change that opens a new parameter is refused with 409 — every existing instance would be left unbound — and each instance is re-linked to its triggers and its runtime state cleared.

PATCH/api/v1/function/Yk3pL7rWq2

Path Parameters

NameDescription
functionIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Body

NameDescription
namestringoptionalDisplay name of the graph, 1 to 64 characters.
min length 1 · max length 64
descriptionstringoptionalWhat the graph does, for whoever reads it later; free text.
nodesarrayoptionalThe nodes of the graph, each with a ref unique within it. What a node may carry follows from its type, so GET /function/nodes is the contract.
refstringThe node's name inside this graph — unique, 1 to 64 characters of letters, digits, - and _. Edges address ports as <ref>.<port>.
Pattern: ^[0-9a-zA-Z\-_]{1,64}$
typeenumWhich node type computes here; one of those GET /function/nodes lists, and it decides which settings and ports are allowed.
Possible values: PROP, META, NUM, STR, BOOL, TIME, DUR, ADD, MULT, SUB, DIV, INT_DIV, MOD, BIT_AND, BIT_OR, BIT_XOR, ABS, EXP, CEIL, FLOOR, POW, LIMIT, LN, LOG, GRT, EQL_RT, LSR, EQL_LSR, EQL, UNEQL, STRICT_EQL, STRICT_UNEQL, AND, NAND, OR, NOR, XOR, NXOR, SR, RS, R_TRIG, F_TRIG, INCR, CTU, CTD, CTUD, TON, TOF, TP, STPW, GATE, SNAP, MUX, MIN, MAX, VRT_PROP, EMAIL_NOTIFY, RES
settingsdictionaryoptionalThe node's settings, keyed by name. Each is either fixed in the graph or left open, and every open one becomes a parameter the instance binds.
inputsdictionaryoptionalThe input ports of this node, named with one to three upper-case letters or digits. A fixed-arity type has to be given its required ports; a dynamic one — ADD, AND — gets as many as the graph names.
typeenumThe value the port carries; declaring it sharpens a generic port — a PROP output to bool, say — and both ends of an edge have to agree.
Possible values: number, bool, string, time, duration
unitoptionalenumPresentation only — ms or s for how a client should show the value; stored values are milliseconds either way.
Possible values: ms, s
optionalbooleanoptionalWhether the port may be left out. Which ports a type actually requires is fixed by the type; GET /function/nodes is the authority.
descriptionstringoptionalWhat the port stands for; free text, not interpreted.
outputsdictionaryoptionalThe output ports of this node, in the same shape as inputs; only ports the type has.
typeenumThe value the port carries; declaring it sharpens a generic port — a PROP output to bool, say — and both ends of an edge have to agree.
Possible values: number, bool, string, time, duration
unitoptionalenumPresentation only — ms or s for how a client should show the value; stored values are milliseconds either way.
Possible values: ms, s
optionalbooleanoptionalWhether the port may be left out. Which ports a type actually requires is fixed by the type; GET /function/nodes is the authority.
descriptionstringoptionalWhat the port stands for; free text, not interpreted.
edgesarrayoptionalThe connections between node ports. A graph may not contain a cycle — the sweep walks it in one pass, in topological order.
fromstringSource, as <ref>.<port>, naming an output of a node in this graph.
tostringTarget, as <ref>.<port>, naming an input; one input takes exactly one edge, a second into it is rejected.

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404No graph with this {functionId} in the tenant — and the same answer when the graph names a device the caller may not read, so a 404 here is not proof of absence. Check the id against GET /function.
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The graph or its bindings do not hold together — a dangling edge, a port the node type does not have, a type mismatch across an edge, a cycle, or a parameter left unbound. sections names the failing area and lists one message per problem; fix those and repeat the call.
409The updated graph would open a parameter the stored one does not have, which would leave every existing instance unbound. Fix the new setting to a value instead of leaving it dynamic, or store it as a second graph.
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Delete a function graph

Deletes the graph and, in cascade, every instance of it — runtime state, trigger links and per-device contexts included. Nothing is kept; a graph still in use has to be created and bound again.

DELETE/api/v1/function/Yk3pL7rWq2

Path Parameters

NameDescription
functionIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404No graph with this {functionId} in the tenant — and the same answer when the graph names a device the caller may not read, so a 404 here is not proof of absence. Check the id against GET /function.
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The request did not match the schema for this endpoint. The details field carries the specific failures.error: Validation Error
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Create an instance

Binds every parameter of the graph and starts it: the first sweep runs on creation, seeded with what the bound devices last reported, rather than waiting for the next device message. A device parameter takes a group instead — at most one per instance — which fans the instance out into one evaluation context per member device.

POST/api/v1/function/string/instance

Path Parameters

NameDescription
functionIdstringId of the function definition whose instances the route addresses — the graph, not a running instance of it.

Body

NameDescription
namestringoptionalDisplay name of the instance, 1 to 64 characters; optional.
min length 1 · max length 64
bindingsdictionaryOne entry per parameter of the graph, keyed by the parameter's key. Every parameter has to appear — a partial object is refused as unbound.
enabledbooleanoptionalWhether the instance evaluates; defaults to true. A disabled instance keeps its bindings and its state, but no trigger sweeps it.
Default: true

Response

NameDescription
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404No graph with this {functionId} in the tenant — and the same answer when the graph names a device the caller may not read, so a 404 here is not proof of absence. Check the id against GET /function.
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The graph or its bindings do not hold together — a dangling edge, a port the node type does not have, a type mismatch across an edge, a cycle, or a parameter left unbound. sections names the failing area and lists one message per problem; fix those and repeat the call.
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

List instances

Lists the instances of one graph; depth=1 adds their bindings. Instances bound to a device or group the caller may not read are left out rather than refused.

GET/api/v1/function/string/instance?depth=0

Path Parameters

NameDescription
functionIdstringId of the function definition whose instances the route addresses — the graph, not a running instance of it.

Query Parameters

NameDescription
depthintegeroptionalHow many levels of nested resources the response includes; 0 returns only the top level.
Default: 0
min 0

Response

NameDescription
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
instanceobjectoptionalThe stored instance; included from depth=1.
namestringoptionalDisplay name of the instance; absent when none was given.
min length 1 · max length 64
bindingsdictionaryWhat each open parameter of the graph is bound to, keyed by the parameter's key.
enabledbooleanoptionalWhether the instance evaluates. Deleting a bound device switches a directly bound instance off rather than removing it, so the breakage stays visible; a derived context goes with its device.
Default: true
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
configIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
deviceIdentifierstringoptionalOnly on a derived context: the CRN of the device this copy of a group-bound instance runs for.
createdBystringResource identifier of the entity that created this resource

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404No graph with this {functionId} in the tenant — and the same answer when the graph names a device the caller may not read, so a 404 here is not proof of absence. Check the id against GET /function.
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The request did not match the schema for this endpoint. The details field carries the specific failures.error: Validation Error
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Read an instance with its state

The instance plus the current ports of every node, inputs and outputs merged per ref. updatedAt is null while nothing has been swept; a group-bound instance holds no state of its own and names its per-device contexts in contexts.

GET/api/v1/function/Yk3pL7rWq2/instance/Yk3pL7rWq2

Path Parameters

NameDescription
functionIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$
instanceIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Response

NameDescription
instanceobjectThe instance, as stored.
namestringoptionalDisplay name of the instance; absent when none was given.
min length 1 · max length 64
bindingsdictionaryWhat each open parameter of the graph is bound to, keyed by the parameter's key.
enabledbooleanoptionalWhether the instance evaluates. Deleting a bound device switches a directly bound instance off rather than removing it, so the breakage stays visible; a derived context goes with its device.
Default: true
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
configIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
deviceIdentifierstringoptionalOnly on a derived context: the CRN of the device this copy of a group-bound instance runs for.
createdBystringResource identifier of the entity that created this resource
nodesdictionaryEvery node's ports keyed by ref, inputs and outputs merged into one object; empty until the graph has swept for the first time.
contextsarraystringoptionalThe per-device evaluation contexts a group-bound instance fans out into; absent when there are none. Each carries its own state, which is why the parent's nodes stays empty.
updatedAtintegeroptionalWhen the last sweep finished, UTC epoch milliseconds; null while nothing has been swept.

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404No instance with this {instanceId} under this graph — also the answer when the graph behind it is gone. GET /function/{functionId}/instance shows what is left.
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The request did not match the schema for this endpoint. The details field carries the specific failures.error: Validation Error
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Update an instance

bindings is replaced whole and has to name every parameter of the graph again — a partial object is rejected as unbound. Any update clears the runtime state, so counters, latches and running timers start over.

PATCH/api/v1/function/Yk3pL7rWq2/instance/Yk3pL7rWq2

Path Parameters

NameDescription
functionIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$
instanceIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Body

NameDescription
namestringoptionalDisplay name of the instance, 1 to 64 characters.
min length 1 · max length 64
bindingsdictionaryoptionalReplaces the bindings as a whole: every parameter of the graph has to appear again, not only the ones that change.
enabledbooleanoptionalWhether the instance evaluates; nothing sweeps a disabled one. Switching it off clears the runtime state like any other change — counters, latches and timers start over when it is switched back on.
Default: true

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404No instance with this {instanceId} under this graph — also the answer when the graph behind it is gone. GET /function/{functionId}/instance shows what is left.
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The graph or its bindings do not hold together — a dangling edge, a port the node type does not have, a type mismatch across an edge, a cycle, or a parameter left unbound. sections names the failing area and lists one message per problem; fix those and repeat the call.
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Delete an instance

Stops the instance and drops its runtime state, its trigger links and any per-device contexts. The graph itself stays and can be bound again.

DELETE/api/v1/function/Yk3pL7rWq2/instance/Yk3pL7rWq2

Path Parameters

NameDescription
functionIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$
instanceIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404No instance with this {instanceId} under this graph — also the answer when the graph behind it is gone. GET /function/{functionId}/instance shows what is left.
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The request did not match the schema for this endpoint. The details field carries the specific failures.error: Validation Error
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Reset the runtime state

Clears counters, latches and timer starts of the instance and of every per-device context, leaving the bindings alone. Nothing is recomputed and no input is re-primed — a PROP node stays empty until its device reports again.

POST/api/v1/function/Yk3pL7rWq2/instance/Yk3pL7rWq2/reset

Path Parameters

NameDescription
functionIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$
instanceIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404No instance with this {instanceId} under this graph — also the answer when the graph behind it is gone. GET /function/{functionId}/instance shows what is left.
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The request did not match the schema for this endpoint. The details field carries the specific failures.error: Validation Error
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Events

Published on the tenant's event stream and delivered over the websocket to every subscriber holding read on the resource the message names. resourceIdentifier is the resource the action changed; the payload is the shape below.

EventDescription
FUNCTIONS_CONFIG_CREATEA graph was stored, together with the parameters and the evaluation order derived from it.
FUNCTIONS_CONFIG_DELETEA graph was removed; every instance of it goes with it, each as an event of its own.
FUNCTIONS_CONFIG_UPDATEA graph was rewritten — the payload is the whole config, not the patch — and every instance re-linked and reset.
FUNCTIONS_EMAIL_NOTIFICATIONAn EMAIL_NOTIFY node fired and handed the email module a template plus the parameters the graph filled — never a recipient, and never over a websocket.
FUNCTIONS_INSTANCE_CREATEA graph was bound to devices and values, and swept once from what those devices had already reported.
FUNCTIONS_INSTANCE_DELETEAn instance was removed, with its runtime state, its trigger links and its per-device contexts.
FUNCTIONS_INSTANCE_UPDATEAn instance was rewritten — bindings, name or the enabled flag — and its runtime state cleared.
FUNCTIONS_STATEA sweep finished: nodes carries only the ports whose value changed and at when it ran — the update that keeps a graph view live without a subscription of its own.

Function graph created

A graph was stored, together with the parameters and the evaluation order derived from it.

EVENTFUNCTIONS_CONFIG_CREATE

Payload

NameDescription
namestringDisplay name of the graph, 1 to 64 characters.
min length 1 · max length 64
descriptionstringoptionalWhat the graph does, for whoever reads it later; free text.
nodesarrayThe nodes of the graph, each with a ref unique within it. What a node may carry follows from its type, so GET /function/nodes is the contract.
refstringThe node's name inside this graph — unique, 1 to 64 characters of letters, digits, - and _. Edges address ports as <ref>.<port>.
Pattern: ^[0-9a-zA-Z\-_]{1,64}$
typeenumWhich node type computes here; one of those GET /function/nodes lists, and it decides which settings and ports are allowed.
Possible values: PROP, META, NUM, STR, BOOL, TIME, DUR, ADD, MULT, SUB, DIV, INT_DIV, MOD, BIT_AND, BIT_OR, BIT_XOR, ABS, EXP, CEIL, FLOOR, POW, LIMIT, LN, LOG, GRT, EQL_RT, LSR, EQL_LSR, EQL, UNEQL, STRICT_EQL, STRICT_UNEQL, AND, NAND, OR, NOR, XOR, NXOR, SR, RS, R_TRIG, F_TRIG, INCR, CTU, CTD, CTUD, TON, TOF, TP, STPW, GATE, SNAP, MUX, MIN, MAX, VRT_PROP, EMAIL_NOTIFY, RES
settingsdictionaryoptionalThe node's settings, keyed by name. Each is either fixed in the graph or left open, and every open one becomes a parameter the instance binds.
inputsdictionaryoptionalThe input ports of this node, named with one to three upper-case letters or digits. A fixed-arity type has to be given its required ports; a dynamic one — ADD, AND — gets as many as the graph names.
typeenumThe value type the binding has to carry.
Possible values: number, bool, string, time, duration
unitoptionalenumPresentation only — ms or s for how a client should show the value; stored values are milliseconds either way.
Possible values: ms, s
optionalbooleanoptionalWhether the port may be left out. Which ports a type actually requires is fixed by the type; GET /function/nodes is the authority.
descriptionstringoptionalWhat the port stands for; free text, not interpreted.
outputsdictionaryoptionalThe output ports of this node, in the same shape as inputs; only ports the type has.
typeenumThe value type the binding has to carry.
Possible values: number, bool, string, time, duration
unitoptionalenumPresentation only — ms or s for how a client should show the value; stored values are milliseconds either way.
Possible values: ms, s
optionalbooleanoptionalWhether the port may be left out. Which ports a type actually requires is fixed by the type; GET /function/nodes is the authority.
descriptionstringoptionalWhat the port stands for; free text, not interpreted.
edgesarrayThe connections between node ports. A graph may not contain a cycle — the sweep walks it in one pass, in topological order.
fromstringSource, as <ref>.<port>, naming an output of a node in this graph.
tostringTarget, as <ref>.<port>, naming an input; one input takes exactly one edge, a second into it is rejected.
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
parametersarrayThe settings the graph leaves open, sorted by key; dynamic settings that share a ref become one parameter rather than several. An instance has to bind every one of them.
keystringHow a binding addresses the parameter: the setting's own ref, or <node>.<setting> when it has none.
typeenumThe value type the binding has to carry.
Possible values: number, bool, string, time, duration
kindoptionalenumdevice when the parameter names a device — a binding for it has to be a device or a group; value for everything else.
Default: value
Possible values: value, device
orderarraystringThe node refs in evaluation order, computed when the graph was written; every sweep walks the graph exactly this way.
createdBystringResource identifier of the entity that created this resource

Function graph deleted

A graph was removed; every instance of it goes with it, each as an event of its own.

EVENTFUNCTIONS_CONFIG_DELETE

Payload

NameDescription

Function graph updated

A graph was rewritten — the payload is the whole config, not the patch — and every instance re-linked and reset.

EVENTFUNCTIONS_CONFIG_UPDATE

Payload

NameDescription
namestringDisplay name of the graph, 1 to 64 characters.
min length 1 · max length 64
descriptionstringoptionalWhat the graph does, for whoever reads it later; free text.
nodesarrayThe nodes of the graph, each with a ref unique within it. What a node may carry follows from its type, so GET /function/nodes is the contract.
refstringThe node's name inside this graph — unique, 1 to 64 characters of letters, digits, - and _. Edges address ports as <ref>.<port>.
Pattern: ^[0-9a-zA-Z\-_]{1,64}$
typeenumWhich node type computes here; one of those GET /function/nodes lists, and it decides which settings and ports are allowed.
Possible values: PROP, META, NUM, STR, BOOL, TIME, DUR, ADD, MULT, SUB, DIV, INT_DIV, MOD, BIT_AND, BIT_OR, BIT_XOR, ABS, EXP, CEIL, FLOOR, POW, LIMIT, LN, LOG, GRT, EQL_RT, LSR, EQL_LSR, EQL, UNEQL, STRICT_EQL, STRICT_UNEQL, AND, NAND, OR, NOR, XOR, NXOR, SR, RS, R_TRIG, F_TRIG, INCR, CTU, CTD, CTUD, TON, TOF, TP, STPW, GATE, SNAP, MUX, MIN, MAX, VRT_PROP, EMAIL_NOTIFY, RES
settingsdictionaryoptionalThe node's settings, keyed by name. Each is either fixed in the graph or left open, and every open one becomes a parameter the instance binds.
inputsdictionaryoptionalThe input ports of this node, named with one to three upper-case letters or digits. A fixed-arity type has to be given its required ports; a dynamic one — ADD, AND — gets as many as the graph names.
typeenumThe value type the binding has to carry.
Possible values: number, bool, string, time, duration
unitoptionalenumPresentation only — ms or s for how a client should show the value; stored values are milliseconds either way.
Possible values: ms, s
optionalbooleanoptionalWhether the port may be left out. Which ports a type actually requires is fixed by the type; GET /function/nodes is the authority.
descriptionstringoptionalWhat the port stands for; free text, not interpreted.
outputsdictionaryoptionalThe output ports of this node, in the same shape as inputs; only ports the type has.
typeenumThe value type the binding has to carry.
Possible values: number, bool, string, time, duration
unitoptionalenumPresentation only — ms or s for how a client should show the value; stored values are milliseconds either way.
Possible values: ms, s
optionalbooleanoptionalWhether the port may be left out. Which ports a type actually requires is fixed by the type; GET /function/nodes is the authority.
descriptionstringoptionalWhat the port stands for; free text, not interpreted.
edgesarrayThe connections between node ports. A graph may not contain a cycle — the sweep walks it in one pass, in topological order.
fromstringSource, as <ref>.<port>, naming an output of a node in this graph.
tostringTarget, as <ref>.<port>, naming an input; one input takes exactly one edge, a second into it is rejected.
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
parametersarrayThe settings the graph leaves open, sorted by key; dynamic settings that share a ref become one parameter rather than several. An instance has to bind every one of them.
keystringHow a binding addresses the parameter: the setting's own ref, or <node>.<setting> when it has none.
typeenumThe value type the binding has to carry.
Possible values: number, bool, string, time, duration
kindoptionalenumdevice when the parameter names a device — a binding for it has to be a device or a group; value for everything else.
Default: value
Possible values: value, device
orderarraystringThe node refs in evaluation order, computed when the graph was written; every sweep walks the graph exactly this way.
createdBystringResource identifier of the entity that created this resource

Email notification requested

An EMAIL_NOTIFY node fired and handed the email module a template plus the parameters the graph filled — never a recipient, and never over a websocket.

EVENTFUNCTIONS_EMAIL_NOTIFICATION

Payload

NameDescription
intentIdstringIdentifies one firing of the graph, and is derived rather than random: a replayed sweep produces the same id and the receiver drops the repeat, so no mail goes out twice.
topicstringUnique Coldwave resource name (CRN) that identifies a resource
sourcesarraystringCRNs of the devices the firing graph read from. A subscriber's access to them is re-checked on every delivery — a subscription outlives the role that justified it.
templateIdstringId of the template. On a send it is the alternative to templateType — exactly one of the two, since a type resolves to a template through the tenant's mapping.
paramsdictionaryParameters of the call: a device method takes one entry per parameter, each stating its own type; a mail template takes its parameter values keyed by name.

Instance created

A graph was bound to devices and values, and swept once from what those devices had already reported.

EVENTFUNCTIONS_INSTANCE_CREATE

Payload

NameDescription
namestringoptionalDisplay name of the instance; absent when none was given.
min length 1 · max length 64
bindingsdictionaryWhat each open parameter of the graph is bound to, keyed by the parameter's key.
enabledbooleanoptionalWhether the instance evaluates. Deleting a bound device switches a directly bound instance off rather than removing it, so the breakage stays visible; a derived context goes with its device.
Default: true
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
configIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
deviceIdentifierstringoptionalOnly on a derived context: the CRN of the device this copy of a group-bound instance runs for.
createdBystringResource identifier of the entity that created this resource

Instance deleted

An instance was removed, with its runtime state, its trigger links and its per-device contexts.

EVENTFUNCTIONS_INSTANCE_DELETE

Payload

NameDescription

Instance updated

An instance was rewritten — bindings, name or the enabled flag — and its runtime state cleared.

EVENTFUNCTIONS_INSTANCE_UPDATE

Payload

NameDescription
namestringoptionalDisplay name of the instance; absent when none was given.
min length 1 · max length 64
bindingsdictionaryWhat each open parameter of the graph is bound to, keyed by the parameter's key.
enabledbooleanoptionalWhether the instance evaluates. Deleting a bound device switches a directly bound instance off rather than removing it, so the breakage stays visible; a derived context goes with its device.
Default: true
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
configIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
deviceIdentifierstringoptionalOnly on a derived context: the CRN of the device this copy of a group-bound instance runs for.
createdBystringResource identifier of the entity that created this resource

Node state changed

A sweep finished: nodes carries only the ports whose value changed and at when it ran — the update that keeps a graph view live without a subscription of its own.

EVENTFUNCTIONS_STATE

Payload

NameDescription
nodesdictionaryThe ports that changed in this sweep, keyed by node reference. Only the changes travel, so a client merges them into the state it already holds.
atintegerWhen the sweep produced this state, UTC epoch milliseconds.