Procedure executions service (gRPC)#

Service for creating and managing procedure executions.

Endpoints#

Batch archive procedure executions#

gRPC /nominal.procedures.executions.v1.ProcedureExecutionsService/BatchArchiveProcedureExecutions

Archive procedure executions

Request: BatchArchiveProcedureExecutionsRequest

procedure_execution_rids array of string

​

Response: BatchArchiveProcedureExecutionsResponse

procedure_execution_rids array of string

​

Request

import grpc
from nominal.protos.procedures.executions.v1 import procedure_executions_pb2, procedure_executions_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
procedure_executions_service = procedure_executions_pb2_grpc.ProcedureExecutionsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = procedure_executions_pb2.BatchArchiveProcedureExecutionsRequest(
    procedure_execution_rids=["<procedure execution rids>"],
)
response = procedure_executions_service.BatchArchiveProcedureExecutions(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	executionsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/executions/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	procedureExecutionsService := executionsv1.NewProcedureExecutionsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &executionsv1.BatchArchiveProcedureExecutionsRequest{
		ProcedureExecutionRids: []string{
			"<procedure execution rids>",
		},
	}
	response, err := procedureExecutionsService.BatchArchiveProcedureExecutions(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "procedure_execution_rids": [
    "<procedure execution rids>"
  ]
}

Batch get procedure execution metadata#

gRPC /nominal.procedures.executions.v1.ProcedureExecutionsService/BatchGetProcedureExecutionMetadata

Batch get procedure execution metadata

Request: BatchGetProcedureExecutionMetadataRequest

procedure_execution_rids array of string

​

Response: BatchGetProcedureExecutionMetadataResponse

procedure_executions array of ProcedureExecutionMetadata

​

Fields of ProcedureExecutionMetadata
rid string

​

procedure_rid string

The procedure template rid this execution is based on.

procedure_commit_id string

The commit ID of the procedure template this execution is based on. This can be overridden at the node level for individual nodes.

title string

At least 1 character.

description string

​

labels array of string

​

properties map of string to string

​

created_by string

​

created_at string (date-time)

​

updated_by string

​

updated_at string (date-time)

​

started_at string (date-time)

Will be unset until the execution transitions from NOT_STARTED to IN_PROGRESS.

started_by string

​

finished_at string (date-time)

Will be unset until the execution transitions from IN_PROGRESS to a terminal state.

finished_by string

​

aborted_at string (date-time)

Will be true/set if the execution is the ABORTED terminal state.

aborted_by string

​

failed_at string (date-time)

Will be set if the execution is in the ERRORED terminal state.

failed_by string

​

failed_reason string

​

asset_rids array of string

Assets which this execution has acted on in completed steps (e.g. through an event creation action).

is_archived boolean

​

Request

import grpc
from nominal.protos.procedures.executions.v1 import procedure_executions_pb2, procedure_executions_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
procedure_executions_service = procedure_executions_pb2_grpc.ProcedureExecutionsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = procedure_executions_pb2.BatchGetProcedureExecutionMetadataRequest(
    procedure_execution_rids=["<procedure execution rids>"],
)
response = procedure_executions_service.BatchGetProcedureExecutionMetadata(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	executionsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/executions/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	procedureExecutionsService := executionsv1.NewProcedureExecutionsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &executionsv1.BatchGetProcedureExecutionMetadataRequest{
		ProcedureExecutionRids: []string{
			"<procedure execution rids>",
		},
	}
	response, err := procedureExecutionsService.BatchGetProcedureExecutionMetadata(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "procedure_executions": [
    {
      "rid": "<rid>",
      "procedure_rid": "<procedure rid>",
      "procedure_commit_id": "<procedure commit id>",
      "title": "<title>",
      "description": "<description>",
      "labels": [
        "<labels>"
      ],
      "properties": {
        "<key>": "<value>"
      },
      "created_by": "<created by>",
      "created_at": "2026-01-01T00:00:00Z",
      "updated_by": "<updated by>",
      "updated_at": "2026-01-01T00:00:00Z",
      "started_at": "2026-01-01T00:00:00Z",
      "started_by": "<started by>",
      "finished_at": "2026-01-01T00:00:00Z",
      "finished_by": "<finished by>",
      "aborted_at": "2026-01-01T00:00:00Z",
      "aborted_by": "<aborted by>",
      "failed_at": "2026-01-01T00:00:00Z",
      "failed_by": "<failed by>",
      "failed_reason": "<failed reason>",
      "asset_rids": [
        "<asset rids>"
      ],
      "is_archived": true
    }
  ]
}

Batch unarchive procedure executions#

gRPC /nominal.procedures.executions.v1.ProcedureExecutionsService/BatchUnarchiveProcedureExecutions

Unarchive procedure executions

Request: BatchUnarchiveProcedureExecutionsRequest

procedure_execution_rids array of string

​

Response: BatchUnarchiveProcedureExecutionsResponse

procedure_execution_rids array of string

​

Request

import grpc
from nominal.protos.procedures.executions.v1 import procedure_executions_pb2, procedure_executions_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
procedure_executions_service = procedure_executions_pb2_grpc.ProcedureExecutionsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = procedure_executions_pb2.BatchUnarchiveProcedureExecutionsRequest(
    procedure_execution_rids=["<procedure execution rids>"],
)
response = procedure_executions_service.BatchUnarchiveProcedureExecutions(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	executionsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/executions/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	procedureExecutionsService := executionsv1.NewProcedureExecutionsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &executionsv1.BatchUnarchiveProcedureExecutionsRequest{
		ProcedureExecutionRids: []string{
			"<procedure execution rids>",
		},
	}
	response, err := procedureExecutionsService.BatchUnarchiveProcedureExecutions(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "procedure_execution_rids": [
    "<procedure execution rids>"
  ]
}

Create procedure execution#

gRPC /nominal.procedures.executions.v1.ProcedureExecutionsService/CreateProcedureExecution

Create a new procedure execution from a procedure

Request: CreateProcedureExecutionRequest

procedure_rid string

​

procedure_commit_id string

​

title string

At least 1 character.

description string

​

start_immediately boolean

​

Response: CreateProcedureExecutionResponse

procedure_execution ProcedureExecution

​

Fields of ProcedureExecution
rid string

​

metadata ProcedureExecutionMetadata

​

Fields of ProcedureExecutionMetadata
rid string

​

procedure_rid string

The procedure template rid this execution is based on.

procedure_commit_id string

The commit ID of the procedure template this execution is based on. This can be overridden at the node level for individual nodes.

title string

At least 1 character.

description string

​

labels array of string

​

properties map of string to string

​

created_by string

​

created_at string (date-time)

​

updated_by string

​

updated_at string (date-time)

​

started_at string (date-time)

Will be unset until the execution transitions from NOT_STARTED to IN_PROGRESS.

started_by string

​

finished_at string (date-time)

Will be unset until the execution transitions from IN_PROGRESS to a terminal state.

finished_by string

​

aborted_at string (date-time)

Will be true/set if the execution is the ABORTED terminal state.

aborted_by string

​

failed_at string (date-time)

Will be set if the execution is in the ERRORED terminal state.

failed_by string

​

failed_reason string

​

asset_rids array of string

Assets which this execution has acted on in completed steps (e.g. through an event creation action).

is_archived boolean

​

state ProcedureExecutionState

​

Fields of ProcedureExecutionState
global_fields map of string to FieldOutput

The current values for the global fields in the procedure.

Fields of FieldOutput
one of 10 fields

​

asset_rid string

If a global field is not yet defined, I think it’s just not present in the global_fields map option (buf.validate.oneof) = {required: true};

string_value string

​

double_value number

​

boolean_value boolean

​

int_value integer (int64)

​

strings_value Strings

​

Fields of Strings
values array of string

​

ingest_job_rid string

​

run_rid string

​

file_upload_value FileUploadFieldValue

​

Fields of FileUploadFieldValue
s3_upload S3UploadFileValue

​

Fields of S3UploadFileValue
s3_path string

The S3 path where the uploaded file is stored At least 1 character.

file_name string

The original filename of the uploaded file At least 1 character.

file_type string

The MIME type of the uploaded file Following the convention of https://developer.mozilla.org/en-US/docs/Web/API/Blob/type (from which the File api inherits, we will accept an empty string)

multi_file_upload_value MultiFileUploadFieldValue

​

Fields of MultiFileUploadFieldValue
uploads array of FileUploadFieldValue

The list of uploads

nodes map of string to ProcedureExecutionNode

A map from execution node ID to the execution node.

Fields of ProcedureExecutionNode
one of section, step

​

section ProcedureExecutionSectionNode

A section node is a visual grouping of other sections and steps. Execution sections are static and do not have execution state.

Fields of ProcedureExecutionSectionNode
id string

Unique identifier of this execution node. At least 1 character.

template_node_id string

Unique identifier of the template node this execution node is based on. At least 1 character.

title string

Title of this section. Uses the template section’s title and cannot be changed in execution. At least 1 character.

description string

Description of this section. Uses the template section’s description and cannot be changed in execution.

template_commit_id string

If set, the commit ID of the procedure template this section is based on. Otherwise, the section is based on the template commit specified at the top level of the execution.

step ProcedureExecutionStepNode

Execution steps are the interactive steps in a procedure.

Fields of ProcedureExecutionStepNode
id string

Unique identifier of this execution node. At least 1 character.

template_node_id string

Unique identifier of the template node this execution node is based on. At least 1 character.

is_outdated boolean

Execution steps become “outdated” once any upstream steps are re-run An outdated execution step should not be further modified.

state ExecutionStepState

The current status of the step along with metadata about the status transitions.

Fields of ExecutionStepState
one of 6 fields

​

not_started ExecutionStepNotStarted

​

in_progress ExecutionStepInProgress

​

Fields of ExecutionStepInProgress
started_at string (date-time)

​

started_by string

​

submitted ExecutionStepSubmitted

​

Fields of ExecutionStepSubmitted
started_at string (date-time)

​

started_by string

​

submitted_at string (date-time)

​

submitted_by string

​

skipped ExecutionStepSkipped

Terminal states below

Fields of ExecutionStepSkipped
skipped_at string (date-time)

​

skipped_by string

​

skip_reason string

​

started_at string (date-time)

Optional because a step can be skipped from the NOT_STARTED state before these are set

started_by string

​

submitted_at string (date-time)

Optional because a step can be skipped from the IN_PROGRESS state before these are set

submitted_by string

​

succeeded ExecutionStepSucceeded

​

Fields of ExecutionStepSucceeded
started_at string (date-time)

​

started_by string

​

submitted_at string (date-time)

​

submitted_by string

​

succeeded_at string (date-time)

​

succeeded_by string

​

errored ExecutionStepErrored

​

Fields of ExecutionStepErrored
started_at string (date-time)

Optional because a step can reach ERRORED without having been started

started_by string

​

submitted_at string (date-time)

Optional because a step can be errored before being submitted

submitted_by string

​

errored_at string (date-time)

​

errored_by string

​

error string

​

skipped_at string (date-time)

Optional because a step could be skipped but then error while running completion actions

skipped_by string

​

skip_reason string

​

succeeded_at string (date-time)

Optional because a step can succeed but then error while running completion actions

succeeded_by string

​

value StepContentValue

The current value for the content of the step.

Fields of StepContentValue
one of form, start_ingest, select_or_create_asset, wait

​

form FormStepValue

​

Fields of FormStepValue
fields array of FormFieldValue

​

Fields of FormFieldValue
one of 9 fields

Request

import grpc
from nominal.protos.procedures.executions.v1 import procedure_executions_pb2, procedure_executions_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
procedure_executions_service = procedure_executions_pb2_grpc.ProcedureExecutionsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = procedure_executions_pb2.CreateProcedureExecutionRequest(
    procedure_rid="<procedure rid>",
    procedure_commit_id="<procedure commit id>",
    title="<title>",
    description="<description>",
    start_immediately=True,
)
response = procedure_executions_service.CreateProcedureExecution(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	executionsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/executions/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
	"google.golang.org/protobuf/proto"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	procedureExecutionsService := executionsv1.NewProcedureExecutionsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &executionsv1.CreateProcedureExecutionRequest{
		ProcedureRid:      "<procedure rid>",
		ProcedureCommitId: "<procedure commit id>",
		Title:             "<title>",
		Description:       proto.String("<description>"),
		StartImmediately:  proto.Bool(true),
	}
	response, err := procedureExecutionsService.CreateProcedureExecution(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "procedure_execution": {
    "rid": "<rid>",
    "metadata": {
      "rid": "<rid>",
      "procedure_rid": "<procedure rid>",
      "procedure_commit_id": "<procedure commit id>",
      "title": "<title>",
      "description": "<description>",
      "labels": [
        "<labels>"
      ],
      "properties": {
        "<key>": "<value>"
      },
      "created_by": "<created by>",
      "created_at": "2026-01-01T00:00:00Z",
      "updated_by": "<updated by>",
      "updated_at": "2026-01-01T00:00:00Z",
      "started_at": "2026-01-01T00:00:00Z",
      "started_by": "<started by>",
      "finished_at": "2026-01-01T00:00:00Z",
      "finished_by": "<finished by>",
      "aborted_at": "2026-01-01T00:00:00Z",
      "aborted_by": "<aborted by>",
      "failed_at": "2026-01-01T00:00:00Z",
      "failed_by": "<failed by>",
      "failed_reason": "<failed reason>",
      "asset_rids": [
        "<asset rids>"
      ],
      "is_archived": true
    },
    "state": {
      "global_fields": {
        "<key>": {
          "asset_rid": "<asset rid>"
        }
      },
      "nodes": {
        "<key>": {
          "section": {
            "id": "<id>",
            "template_node_id": "<template node id>",
            "title": "<title>",
            "description": "<description>",
            "template_commit_id": "<template commit id>"
          }
        }
      },
      "section_edges": {
        "<key>": {
          "node_ids": [
            "<node ids>"
          ]
        }
      },
      "step_edges": {
        "<key>": {
          "node_ids": [
            "<node ids>"
          ]
        }
      }
    }
  }
}

Get procedure execution#

gRPC /nominal.procedures.executions.v1.ProcedureExecutionsService/GetProcedureExecution

Get a procedure execution by its RID

Request: GetProcedureExecutionRequest

procedure_execution_rid string

​

include_display_graph boolean

If true, the display graph will be included in the response. Default is false.

Response: GetProcedureExecutionResponse

procedure_execution ProcedureExecution

​

Fields of ProcedureExecution
rid string

​

metadata ProcedureExecutionMetadata

​

Fields of ProcedureExecutionMetadata
rid string

​

procedure_rid string

The procedure template rid this execution is based on.

procedure_commit_id string

The commit ID of the procedure template this execution is based on. This can be overridden at the node level for individual nodes.

title string

At least 1 character.

description string

​

labels array of string

​

properties map of string to string

​

created_by string

​

created_at string (date-time)

​

updated_by string

​

updated_at string (date-time)

​

started_at string (date-time)

Will be unset until the execution transitions from NOT_STARTED to IN_PROGRESS.

started_by string

​

finished_at string (date-time)

Will be unset until the execution transitions from IN_PROGRESS to a terminal state.

finished_by string

​

aborted_at string (date-time)

Will be true/set if the execution is the ABORTED terminal state.

aborted_by string

​

failed_at string (date-time)

Will be set if the execution is in the ERRORED terminal state.

failed_by string

​

failed_reason string

​

asset_rids array of string

Assets which this execution has acted on in completed steps (e.g. through an event creation action).

is_archived boolean

​

state ProcedureExecutionState

​

Fields of ProcedureExecutionState
global_fields map of string to FieldOutput

The current values for the global fields in the procedure.

Fields of FieldOutput
one of 10 fields

​

asset_rid string

If a global field is not yet defined, I think it’s just not present in the global_fields map option (buf.validate.oneof) = {required: true};

string_value string

​

double_value number

​

boolean_value boolean

​

int_value integer (int64)

​

strings_value Strings

​

Fields of Strings
values array of string

​

ingest_job_rid string

​

run_rid string

​

file_upload_value FileUploadFieldValue

​

Fields of FileUploadFieldValue
s3_upload S3UploadFileValue

​

Fields of S3UploadFileValue
s3_path string

The S3 path where the uploaded file is stored At least 1 character.

file_name string

The original filename of the uploaded file At least 1 character.

file_type string

The MIME type of the uploaded file Following the convention of https://developer.mozilla.org/en-US/docs/Web/API/Blob/type (from which the File api inherits, we will accept an empty string)

multi_file_upload_value MultiFileUploadFieldValue

​

Fields of MultiFileUploadFieldValue
uploads array of FileUploadFieldValue

The list of uploads

nodes map of string to ProcedureExecutionNode

A map from execution node ID to the execution node.

Fields of ProcedureExecutionNode
one of section, step

​

section ProcedureExecutionSectionNode

A section node is a visual grouping of other sections and steps. Execution sections are static and do not have execution state.

Fields of ProcedureExecutionSectionNode
id string

Unique identifier of this execution node. At least 1 character.

template_node_id string

Unique identifier of the template node this execution node is based on. At least 1 character.

title string

Title of this section. Uses the template section’s title and cannot be changed in execution. At least 1 character.

description string

Description of this section. Uses the template section’s description and cannot be changed in execution.

template_commit_id string

If set, the commit ID of the procedure template this section is based on. Otherwise, the section is based on the template commit specified at the top level of the execution.

step ProcedureExecutionStepNode

Execution steps are the interactive steps in a procedure.

Fields of ProcedureExecutionStepNode
id string

Unique identifier of this execution node. At least 1 character.

template_node_id string

Unique identifier of the template node this execution node is based on. At least 1 character.

is_outdated boolean

Execution steps become “outdated” once any upstream steps are re-run An outdated execution step should not be further modified.

state ExecutionStepState

The current status of the step along with metadata about the status transitions.

Fields of ExecutionStepState
one of 6 fields

​

not_started ExecutionStepNotStarted

​

in_progress ExecutionStepInProgress

​

Fields of ExecutionStepInProgress
started_at string (date-time)

​

started_by string

​

submitted ExecutionStepSubmitted

​

Fields of ExecutionStepSubmitted
started_at string (date-time)

​

started_by string

​

submitted_at string (date-time)

​

submitted_by string

​

skipped ExecutionStepSkipped

Terminal states below

Fields of ExecutionStepSkipped
skipped_at string (date-time)

​

skipped_by string

​

skip_reason string

​

started_at string (date-time)

Optional because a step can be skipped from the NOT_STARTED state before these are set

started_by string

​

submitted_at string (date-time)

Optional because a step can be skipped from the IN_PROGRESS state before these are set

submitted_by string

​

succeeded ExecutionStepSucceeded

​

Fields of ExecutionStepSucceeded
started_at string (date-time)

​

started_by string

​

submitted_at string (date-time)

​

submitted_by string

​

succeeded_at string (date-time)

​

succeeded_by string

​

errored ExecutionStepErrored

​

Fields of ExecutionStepErrored
started_at string (date-time)

Optional because a step can reach ERRORED without having been started

started_by string

​

submitted_at string (date-time)

Optional because a step can be errored before being submitted

submitted_by string

​

errored_at string (date-time)

​

errored_by string

​

error string

​

skipped_at string (date-time)

Optional because a step could be skipped but then error while running completion actions

skipped_by string

​

skip_reason string

​

succeeded_at string (date-time)

Optional because a step can succeed but then error while running completion actions

succeeded_by string

​

value StepContentValue

The current value for the content of the step.

Fields of StepContentValue
one of form, start_ingest, select_or_create_asset, wait

​

form FormStepValue

​

Fields of FormStepValue
fields array of FormFieldValue

​

Fields of FormFieldValue
one of 9 fields

Request

import grpc
from nominal.protos.procedures.executions.v1 import procedure_executions_pb2, procedure_executions_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
procedure_executions_service = procedure_executions_pb2_grpc.ProcedureExecutionsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = procedure_executions_pb2.GetProcedureExecutionRequest(
    procedure_execution_rid="<procedure execution rid>",
    include_display_graph=True,
)
response = procedure_executions_service.GetProcedureExecution(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	executionsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/executions/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	procedureExecutionsService := executionsv1.NewProcedureExecutionsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &executionsv1.GetProcedureExecutionRequest{
		ProcedureExecutionRid: "<procedure execution rid>",
		IncludeDisplayGraph:   true,
	}
	response, err := procedureExecutionsService.GetProcedureExecution(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "procedure_execution": {
    "rid": "<rid>",
    "metadata": {
      "rid": "<rid>",
      "procedure_rid": "<procedure rid>",
      "procedure_commit_id": "<procedure commit id>",
      "title": "<title>",
      "description": "<description>",
      "labels": [
        "<labels>"
      ],
      "properties": {
        "<key>": "<value>"
      },
      "created_by": "<created by>",
      "created_at": "2026-01-01T00:00:00Z",
      "updated_by": "<updated by>",
      "updated_at": "2026-01-01T00:00:00Z",
      "started_at": "2026-01-01T00:00:00Z",
      "started_by": "<started by>",
      "finished_at": "2026-01-01T00:00:00Z",
      "finished_by": "<finished by>",
      "aborted_at": "2026-01-01T00:00:00Z",
      "aborted_by": "<aborted by>",
      "failed_at": "2026-01-01T00:00:00Z",
      "failed_by": "<failed by>",
      "failed_reason": "<failed reason>",
      "asset_rids": [
        "<asset rids>"
      ],
      "is_archived": true
    },
    "state": {
      "global_fields": {
        "<key>": {
          "asset_rid": "<asset rid>"
        }
      },
      "nodes": {
        "<key>": {
          "section": {
            "id": "<id>",
            "template_node_id": "<template node id>",
            "title": "<title>",
            "description": "<description>",
            "template_commit_id": "<template commit id>"
          }
        }
      },
      "section_edges": {
        "<key>": {
          "node_ids": [
            "<node ids>"
          ]
        }
      },
      "step_edges": {
        "<key>": {
          "node_ids": [
            "<node ids>"
          ]
        }
      }
    }
  },
  "display_graph": {
    "top_level_nodes": [
      "<top level nodes>"
    ],
    "section_to_sorted_children": {
      "<key>": {
        "node_ids": [
          "<node ids>"
        ]
      }
    }
  }
}

Repeat step#

gRPC /nominal.procedures.executions.v1.ProcedureExecutionsService/RepeatStep

Repeat a previously finished step in a procedure execution. This can only be done if the given step is in state SUCCEEDED, SKIPPED or ERRORED. Other state transitions are managed by the backend.

Request: RepeatStepRequest

procedure_execution_rid string

​

step_id string

The unique identifier of the execution step to repeat/duplicate. At least 1 character.

behavior RepeatStepBehavior

Behavior for how repeating the step will affect dependants.

Values of RepeatStepBehavior
REPEAT_STEP_BEHAVIOR_UNSPECIFIED

​

REPEAT_STEP_BEHAVIOR_ISOLATED

The targeted step will be repeated, but the original graph will be preserved and only direct children will be checked for state updates

value StepContentValue

Setting the value of the step’s content.

Fields of StepContentValue
one of form, start_ingest, select_or_create_asset, wait required

​

form FormStepValue

​

Fields of FormStepValue
fields array of FormFieldValue

​

Fields of FormFieldValue
one of 9 fields required

​

asset AssetFieldValue

​

Fields of AssetFieldValue
asset_reference AssetReference

​

Fields of AssetReference
one of rid, field_id required

​

rid string

a constant AssetRid

field_id string

The field reference that will contain an AssetRid value. The execution will fail if the field is not set but the value is accessed.

checkbox CheckboxFieldValue

​

Fields of CheckboxFieldValue
value boolean

Default to false if not set

text TextFieldValue

​

Fields of TextFieldValue
value string

Default to empty string if not set

int IntFieldValue

​

Fields of IntFieldValue
value integer (int64)

​

double DoubleFieldValue

​

Fields of DoubleFieldValue
value number

​

single_enum SingleEnumFieldValue

​

Fields of SingleEnumFieldValue
value string

Default to empty string if not set

multi_enum MultiEnumFieldValue

​

Fields of MultiEnumFieldValue
value array of string

Default to empty list if not set

file_upload FileUploadFieldValue

​

Fields of FileUploadFieldValue
s3_upload S3UploadFileValue

​

Fields of S3UploadFileValue
s3_path string

The S3 path where the uploaded file is stored At least 1 character.

file_name string

The original filename of the uploaded file At least 1 character.

file_type string

The MIME type of the uploaded file Following the convention of https://developer.mozilla.org/en-US/docs/Web/API/Blob/type (from which the File api inherits, we will accept an empty string)

multi_file_upload MultiFileUploadFieldValue

​

Fields of MultiFileUploadFieldValue
uploads array of FileUploadFieldValue

The list of uploads

start_ingest StartIngestStepValue

​

Fields of StartIngestStepValue
ingest_job_rid string

The RID of the ingest job that was started by the client. This must be populated for the step to be submitted.

select_or_create_asset SelectOrCreateAssetStepValue

​

Fields of SelectOrCreateAssetStepValue
asset_reference AssetReference

The asset that was selected / created by the client. This must be populated for the step to be submitted.

wait WaitStepValue

…

auto_proceed_config AutoProceedConfig

Set whether the step has auto-proceed enabled.

Fields of AutoProceedConfig
one of disabled, enabled required

​

disabled Disabled

The step will not be automatically completed

enabled Enabled

The step will automatically submit the step contents once the requirements are met and begin the transition to either PASSED or ERRORED.

target_state TargetStepStateRequest

Setting the state of the step. This will occur after the other updates in this request.

Fields of TargetStepStateRequest
one of in_progress, submitted, skipped, errored required

​

in_progress StepInProgressRequest

​

submitted StepSubmittedRequest

​

skipped StepSkippedRequest

​

Fields of StepSkippedRequest
skip_reason string

​

errored StepErroredRequest

​

Fields of StepErroredRequest
error_reason string

​

Response: RepeatStepResponse

procedure_execution ProcedureExecution

​

Fields of ProcedureExecution
rid string

​

metadata ProcedureExecutionMetadata

​

Fields of ProcedureExecutionMetadata
rid string

​

procedure_rid string

The procedure template rid this execution is based on.

procedure_commit_id string

The commit ID of the procedure template this execution is based on. This can be overridden at the node level for individual nodes.

title string

At least 1 character.

description string

​

labels array of string

​

properties map of string to string

​

created_by string

​

created_at string (date-time)

​

updated_by string

​

updated_at string (date-time)

​

started_at string (date-time)

Will be unset until the execution transitions from NOT_STARTED to IN_PROGRESS.

started_by string

​

finished_at string (date-time)

Will be unset until the execution transitions from IN_PROGRESS to a terminal state.

finished_by string

​

aborted_at string (date-time)

Will be true/set if the execution is the ABORTED terminal state.

aborted_by string

​

failed_at string (date-time)

Will be set if the execution is in the ERRORED terminal state.

failed_by string

​

failed_reason string

​

asset_rids array of string

Assets which this execution has acted on in completed steps (e.g. through an event creation action).

is_archived boolean

​

state ProcedureExecutionState

​

Fields of ProcedureExecutionState
global_fields map of string to FieldOutput

The current values for the global fields in the procedure.

Fields of FieldOutput
one of 10 fields

​

asset_rid string

If a global field is not yet defined, I think it’s just not present in the global_fields map option (buf.validate.oneof) = {required: true};

string_value string

​

double_value number

​

boolean_value boolean

​

int_value integer (int64)

​

strings_value Strings

​

Fields of Strings
values array of string

​

ingest_job_rid string

​

run_rid string

​

file_upload_value FileUploadFieldValue

​

Fields of FileUploadFieldValue
s3_upload S3UploadFileValue

​

Fields of S3UploadFileValue
s3_path string

The S3 path where the uploaded file is stored At least 1 character.

file_name string

The original filename of the uploaded file At least 1 character.

file_type string

The MIME type of the uploaded file Following the convention of https://developer.mozilla.org/en-US/docs/Web/API/Blob/type (from which the File api inherits, we will accept an empty string)

multi_file_upload_value MultiFileUploadFieldValue

​

Fields of MultiFileUploadFieldValue
uploads array of FileUploadFieldValue

The list of uploads

nodes map of string to ProcedureExecutionNode

A map from execution node ID to the execution node.

Fields of ProcedureExecutionNode
one of section, step

​

section ProcedureExecutionSectionNode

A section node is a visual grouping of other sections and steps. Execution sections are static and do not have execution state.

Fields of ProcedureExecutionSectionNode
id string

Unique identifier of this execution node. At least 1 character.

template_node_id string

Unique identifier of the template node this execution node is based on. At least 1 character.

title string

Title of this section. Uses the template section’s title and cannot be changed in execution. At least 1 character.

description string

Description of this section. Uses the template section’s description and cannot be changed in execution.

template_commit_id string

If set, the commit ID of the procedure template this section is based on. Otherwise, the section is based on the template commit specified at the top level of the execution.

step ProcedureExecutionStepNode

Execution steps are the interactive steps in a procedure.

Fields of ProcedureExecutionStepNode
id string

Unique identifier of this execution node. At least 1 character.

template_node_id string

Unique identifier of the template node this execution node is based on. At least 1 character.

is_outdated boolean

Execution steps become “outdated” once any upstream steps are re-run An outdated execution step should not be further modified.

state ExecutionStepState

The current status of the step along with metadata about the status transitions.

Fields of ExecutionStepState
one of 6 fields

​

not_started ExecutionStepNotStarted

​

in_progress ExecutionStepInProgress

​

Fields of ExecutionStepInProgress
started_at string (date-time)

​

started_by string

​

submitted ExecutionStepSubmitted

​

Fields of ExecutionStepSubmitted
started_at string (date-time)

​

started_by string

​

submitted_at string (date-time)

​

submitted_by string

​

skipped ExecutionStepSkipped

Terminal states below

Fields of ExecutionStepSkipped
skipped_at string (date-time)

​

skipped_by string

​

skip_reason string

​

started_at string (date-time)

Optional because a step can be skipped from the NOT_STARTED state before these are set

started_by string

​

submitted_at string (date-time)

Optional because a step can be skipped from the IN_PROGRESS state before these are set

submitted_by string

​

succeeded ExecutionStepSucceeded

​

Fields of ExecutionStepSucceeded
started_at string (date-time)

​

started_by string

​

submitted_at string (date-time)

​

submitted_by string

​

succeeded_at string (date-time)

​

succeeded_by string

​

errored ExecutionStepErrored

​

Fields of ExecutionStepErrored
started_at string (date-time)

Optional because a step can reach ERRORED without having been started

started_by string

​

submitted_at string (date-time)

Optional because a step can be errored before being submitted

submitted_by string

​

errored_at string (date-time)

​

errored_by string

​

error string

​

skipped_at string (date-time)

Optional because a step could be skipped but then error while running completion actions

skipped_by string

​

skip_reason string

​

succeeded_at string (date-time)

Optional because a step can succeed but then error while running completion actions

succeeded_by string

​

value StepContentValue

The current value for the content of the step.

Fields of StepContentValue
one of form, start_ingest, select_or_create_asset, wait

​

form FormStepValue

​

Fields of FormStepValue
fields array of FormFieldValue

​

Fields of FormFieldValue
one of 9 fields

Request

import grpc
from nominal.protos.procedures.executions.v1 import procedure_executions_pb2, procedure_executions_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
procedure_executions_service = procedure_executions_pb2_grpc.ProcedureExecutionsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = procedure_executions_pb2.RepeatStepRequest(
    procedure_execution_rid="<procedure execution rid>",
    step_id="<step id>",
    behavior="REPEAT_STEP_BEHAVIOR_ISOLATED",
    value={"form": {"fields": [{"asset": {"asset_reference": {"rid": "<rid>"}}}]}},
    auto_proceed_config={"disabled": {}},
    target_state={"in_progress": {}},
)
response = procedure_executions_service.RepeatStep(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	executionsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/executions/v1"
	proceduresv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	procedureExecutionsService := executionsv1.NewProcedureExecutionsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &executionsv1.RepeatStepRequest{
		ProcedureExecutionRid: "<procedure execution rid>",
		StepId:                "<step id>",
		Behavior:              executionsv1.RepeatStepBehavior_REPEAT_STEP_BEHAVIOR_ISOLATED,
		Value: &executionsv1.StepContentValue{
			Value: &executionsv1.StepContentValue_Form{Form: &executionsv1.FormStepValue{
				Fields: []*executionsv1.FormFieldValue{
					{
						Field: &executionsv1.FormFieldValue_Asset{Asset: &executionsv1.AssetFieldValue{
							Asset: &executionsv1.AssetFieldValue_AssetReference{AssetReference: &proceduresv1.AssetReference{
								Option: &proceduresv1.AssetReference_Rid{Rid: "<rid>"},
							}},
						}},
					},
				},
			}},
		},
		AutoProceedConfig: &proceduresv1.AutoProceedConfig{
			Config: &proceduresv1.AutoProceedConfig_Disabled_{Disabled: &proceduresv1.AutoProceedConfig_Disabled{}},
		},
		TargetState: &executionsv1.TargetStepStateRequest{
			TargetState: &executionsv1.TargetStepStateRequest_InProgress{InProgress: &executionsv1.StepInProgressRequest{}},
		},
	}
	response, err := procedureExecutionsService.RepeatStep(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "procedure_execution": {
    "rid": "<rid>",
    "metadata": {
      "rid": "<rid>",
      "procedure_rid": "<procedure rid>",
      "procedure_commit_id": "<procedure commit id>",
      "title": "<title>",
      "description": "<description>",
      "labels": [
        "<labels>"
      ],
      "properties": {
        "<key>": "<value>"
      },
      "created_by": "<created by>",
      "created_at": "2026-01-01T00:00:00Z",
      "updated_by": "<updated by>",
      "updated_at": "2026-01-01T00:00:00Z",
      "started_at": "2026-01-01T00:00:00Z",
      "started_by": "<started by>",
      "finished_at": "2026-01-01T00:00:00Z",
      "finished_by": "<finished by>",
      "aborted_at": "2026-01-01T00:00:00Z",
      "aborted_by": "<aborted by>",
      "failed_at": "2026-01-01T00:00:00Z",
      "failed_by": "<failed by>",
      "failed_reason": "<failed reason>",
      "asset_rids": [
        "<asset rids>"
      ],
      "is_archived": true
    },
    "state": {
      "global_fields": {
        "<key>": {
          "asset_rid": "<asset rid>"
        }
      },
      "nodes": {
        "<key>": {
          "section": {
            "id": "<id>",
            "template_node_id": "<template node id>",
            "title": "<title>",
            "description": "<description>",
            "template_commit_id": "<template commit id>"
          }
        }
      },
      "section_edges": {
        "<key>": {
          "node_ids": [
            "<node ids>"
          ]
        }
      },
      "step_edges": {
        "<key>": {
          "node_ids": [
            "<node ids>"
          ]
        }
      }
    }
  }
}

Search procedure executions#

gRPC /nominal.procedures.executions.v1.ProcedureExecutionsService/SearchProcedureExecutions

Search for procedure executions. The JSON transcoder ranks literal path segments above /{...} template captures, so the literal /search route wins over the /{procedure_execution_rid} template regardless of declaration order.

Request: SearchProcedureExecutionsRequest

query ProcedureExecutionSearchQuery

​

Fields of ProcedureExecutionSearchQuery
one of 12 fields required

​

search_text string

​

label string

​

property Property

​

Fields of Property
name string

​

value string

​

and ProcedureExecutionSearchAndQuery

​

Fields of ProcedureExecutionSearchAndQuery
queries array of ProcedureExecutionSearchQuery

​

or ProcedureExecutionSearchOrQuery

​

Fields of ProcedureExecutionSearchOrQuery
queries array of ProcedureExecutionSearchQuery

​

workspace string

​

procedure_rid string

​

commit_id string

​

created_by string

​

progress_status ProcedureExecutionProgressStatus

​

Values of ProcedureExecutionProgressStatus
PROCEDURE_EXECUTION_PROGRESS_STATUS_UNSPECIFIED

​

PROCEDURE_EXECUTION_PROGRESS_STATUS_NOT_STARTED

​

PROCEDURE_EXECUTION_PROGRESS_STATUS_IN_PROGRESS

​

PROCEDURE_EXECUTION_PROGRESS_STATUS_FINISHED

​

PROCEDURE_EXECUTION_PROGRESS_STATUS_ABORTED

​

assets_filter AssetsFilter

​

Fields of AssetsFilter
asset_rids array of string

​

operator Operator

​

Values of Operator
OPERATOR_UNSPECIFIED

​

OPERATOR_OR

​

OPERATOR_AND

​

is_archived boolean

​

sort_options ProcedureExecutionSortOptions

​

Fields of ProcedureExecutionSortOptions
is_descending boolean

Defaults to descending

sort_field SearchProcedureExecutionsSortField required

​

Values of SearchProcedureExecutionsSortField
SEARCH_PROCEDURE_EXECUTIONS_SORT_FIELD_UNSPECIFIED

​

SEARCH_PROCEDURE_EXECUTIONS_SORT_FIELD_CREATED_AT

​

SEARCH_PROCEDURE_EXECUTIONS_SORT_FIELD_STARTED_AT

​

SEARCH_PROCEDURE_EXECUTIONS_SORT_FIELD_FINISHED_AT

​

SEARCH_PROCEDURE_EXECUTIONS_SORT_FIELD_UPDATED_AT

​

page_size integer

Page sizes greater than 1_000 will be rejected. Default pageSize is 100. From 1 to 1,000.

next_page_token string

​

Response: SearchProcedureExecutionsResponse

procedure_executions array of ProcedureExecutionMetadata

​

Fields of ProcedureExecutionMetadata
rid string

​

procedure_rid string

The procedure template rid this execution is based on.

procedure_commit_id string

The commit ID of the procedure template this execution is based on. This can be overridden at the node level for individual nodes.

title string

At least 1 character.

description string

​

labels array of string

​

properties map of string to string

​

created_by string

​

created_at string (date-time)

​

updated_by string

​

updated_at string (date-time)

​

started_at string (date-time)

Will be unset until the execution transitions from NOT_STARTED to IN_PROGRESS.

started_by string

​

finished_at string (date-time)

Will be unset until the execution transitions from IN_PROGRESS to a terminal state.

finished_by string

​

aborted_at string (date-time)

Will be true/set if the execution is the ABORTED terminal state.

aborted_by string

​

failed_at string (date-time)

Will be set if the execution is in the ERRORED terminal state.

failed_by string

​

failed_reason string

​

asset_rids array of string

Assets which this execution has acted on in completed steps (e.g. through an event creation action).

is_archived boolean

​

next_page_token string

​

Request

import grpc
from nominal.protos.procedures.executions.v1 import procedure_executions_pb2, procedure_executions_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
procedure_executions_service = procedure_executions_pb2_grpc.ProcedureExecutionsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = procedure_executions_pb2.SearchProcedureExecutionsRequest(
    query={"search_text": "<search text>"},
    sort_options={"sort_field": "SEARCH_PROCEDURE_EXECUTIONS_SORT_FIELD_CREATED_AT"},
    page_size=1,
    next_page_token="<next page token>",
)
response = procedure_executions_service.SearchProcedureExecutions(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	executionsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/executions/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
	"google.golang.org/protobuf/proto"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	procedureExecutionsService := executionsv1.NewProcedureExecutionsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &executionsv1.SearchProcedureExecutionsRequest{
		Query: &executionsv1.ProcedureExecutionSearchQuery{
			Query: &executionsv1.ProcedureExecutionSearchQuery_SearchText{SearchText: "<search text>"},
		},
		SortOptions: &executionsv1.ProcedureExecutionSortOptions{
			SortField: executionsv1.SearchProcedureExecutionsSortField_SEARCH_PROCEDURE_EXECUTIONS_SORT_FIELD_CREATED_AT,
		},
		PageSize:      proto.Int32(1),
		NextPageToken: proto.String("<next page token>"),
	}
	response, err := procedureExecutionsService.SearchProcedureExecutions(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "procedure_executions": [
    {
      "rid": "<rid>",
      "procedure_rid": "<procedure rid>",
      "procedure_commit_id": "<procedure commit id>",
      "title": "<title>",
      "description": "<description>",
      "labels": [
        "<labels>"
      ],
      "properties": {
        "<key>": "<value>"
      },
      "created_by": "<created by>",
      "created_at": "2026-01-01T00:00:00Z",
      "updated_by": "<updated by>",
      "updated_at": "2026-01-01T00:00:00Z",
      "started_at": "2026-01-01T00:00:00Z",
      "started_by": "<started by>",
      "finished_at": "2026-01-01T00:00:00Z",
      "finished_by": "<finished by>",
      "aborted_at": "2026-01-01T00:00:00Z",
      "aborted_by": "<aborted by>",
      "failed_at": "2026-01-01T00:00:00Z",
      "failed_by": "<failed by>",
      "failed_reason": "<failed reason>",
      "asset_rids": [
        "<asset rids>"
      ],
      "is_archived": true
    }
  ],
  "next_page_token": "<next page token>"
}

Update procedure execution#

gRPC /nominal.procedures.executions.v1.ProcedureExecutionsService/UpdateProcedureExecution

Heavy-handed update method for procedure execution.

Request: UpdateProcedureExecutionRequest

procedure_execution_rid string

​

title string

​

description string

​

commit_id string

​

labels LabelUpdateWrapper

​

Fields of LabelUpdateWrapper
labels array of string

​

properties PropertyUpdateWrapper

​

Fields of PropertyUpdateWrapper
properties map of string to string

​

state ProcedureExecutionState

​

Fields of ProcedureExecutionState
global_fields map of string to FieldOutput

The current values for the global fields in the procedure.

Fields of FieldOutput
one of 10 fields

​

asset_rid string

If a global field is not yet defined, I think it’s just not present in the global_fields map option (buf.validate.oneof) = {required: true};

string_value string

​

double_value number

​

boolean_value boolean

​

int_value integer (int64)

​

strings_value Strings

​

Fields of Strings
values array of string

​

ingest_job_rid string

​

run_rid string

​

file_upload_value FileUploadFieldValue

​

Fields of FileUploadFieldValue
s3_upload S3UploadFileValue

​

Fields of S3UploadFileValue
s3_path string

The S3 path where the uploaded file is stored At least 1 character.

file_name string

The original filename of the uploaded file At least 1 character.

file_type string

The MIME type of the uploaded file Following the convention of https://developer.mozilla.org/en-US/docs/Web/API/Blob/type (from which the File api inherits, we will accept an empty string)

multi_file_upload_value MultiFileUploadFieldValue

​

Fields of MultiFileUploadFieldValue
uploads array of FileUploadFieldValue

The list of uploads

nodes map of string to ProcedureExecutionNode

A map from execution node ID to the execution node.

Fields of ProcedureExecutionNode
one of section, step required

​

section ProcedureExecutionSectionNode

A section node is a visual grouping of other sections and steps. Execution sections are static and do not have execution state.

Fields of ProcedureExecutionSectionNode
id string

Unique identifier of this execution node. At least 1 character.

template_node_id string

Unique identifier of the template node this execution node is based on. At least 1 character.

title string

Title of this section. Uses the template section’s title and cannot be changed in execution. At least 1 character.

description string

Description of this section. Uses the template section’s description and cannot be changed in execution.

template_commit_id string

If set, the commit ID of the procedure template this section is based on. Otherwise, the section is based on the template commit specified at the top level of the execution.

step ProcedureExecutionStepNode

Execution steps are the interactive steps in a procedure.

Fields of ProcedureExecutionStepNode
id string

Unique identifier of this execution node. At least 1 character.

template_node_id string

Unique identifier of the template node this execution node is based on. At least 1 character.

is_outdated boolean

Execution steps become “outdated” once any upstream steps are re-run An outdated execution step should not be further modified.

state ExecutionStepState

The current status of the step along with metadata about the status transitions.

Fields of ExecutionStepState
one of 6 fields required

​

not_started ExecutionStepNotStarted

​

in_progress ExecutionStepInProgress

​

Fields of ExecutionStepInProgress
started_at string (date-time)

​

started_by string

​

submitted ExecutionStepSubmitted

​

Fields of ExecutionStepSubmitted
started_at string (date-time)

​

started_by string

​

submitted_at string (date-time)

​

submitted_by string

​

skipped ExecutionStepSkipped

Terminal states below

Fields of ExecutionStepSkipped
skipped_at string (date-time)

​

skipped_by string

​

skip_reason string

​

started_at string (date-time)

Optional because a step can be skipped from the NOT_STARTED state before these are set

started_by string

​

submitted_at string (date-time)

Optional because a step can be skipped from the IN_PROGRESS state before these are set

submitted_by string

​

succeeded ExecutionStepSucceeded

​

Fields of ExecutionStepSucceeded
started_at string (date-time)

​

started_by string

​

submitted_at string (date-time)

​

submitted_by string

​

succeeded_at string (date-time)

​

succeeded_by string

​

errored ExecutionStepErrored

​

Fields of ExecutionStepErrored
started_at string (date-time)

Optional because a step can reach ERRORED without having been started

started_by string

​

submitted_at string (date-time)

Optional because a step can be errored before being submitted

submitted_by string

​

errored_at string (date-time)

​

errored_by string

​

error string

​

skipped_at string (date-time)

Optional because a step could be skipped but then error while running completion actions

skipped_by string

​

skip_reason string

​

succeeded_at string (date-time)

Optional because a step can succeed but then error while running completion actions

succeeded_by string

​

value StepContentValue

The current value for the content of the step.

Fields of StepContentValue
one of form, start_ingest, select_or_create_asset, wait required

​

form FormStepValue

​

Fields of FormStepValue
fields array of FormFieldValue

​

Fields of FormFieldValue
one of 9 fields required

​

Request

from datetime import datetime, timezone

import grpc
from nominal.protos.procedures.executions.v1 import procedure_executions_pb2, procedure_executions_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
procedure_executions_service = procedure_executions_pb2_grpc.ProcedureExecutionsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = procedure_executions_pb2.UpdateProcedureExecutionRequest(
    procedure_execution_rid="<procedure execution rid>",
    title="<title>",
    description="<description>",
    commit_id="<commit id>",
    labels={"labels": ["<labels>"]},
    properties={"properties": {"<key>": "<value>"}},
    state={
        "global_fields": {"<key>": {"asset_rid": "<asset rid>"}},
        "nodes": {
            "<key>": {
                "section": {
                    "id": "<id>",
                    "template_node_id": "<template node id>",
                    "title": "<title>",
                    "description": "<description>",
                    "template_commit_id": "<template commit id>",
                },
            },
        },
        "section_edges": {"<key>": {"node_ids": ["<node ids>"]}},
        "step_edges": {"<key>": {"node_ids": ["<node ids>"]}},
    },
    is_aborted=True,
    started_at=datetime(2026, 1, 1, tzinfo=timezone.utc),
    finished_at=datetime(2026, 1, 1, tzinfo=timezone.utc),
)
response = procedure_executions_service.UpdateProcedureExecution(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"
	"time"

	executionsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/executions/v1"
	proceduresv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/v1"
	"github.com/nominal-io/nominal-api-protos-go/nominal/protos/types"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/types/known/timestamppb"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	procedureExecutionsService := executionsv1.NewProcedureExecutionsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &executionsv1.UpdateProcedureExecutionRequest{
		ProcedureExecutionRid: "<procedure execution rid>",
		Title:                 proto.String("<title>"),
		Description:           proto.String("<description>"),
		CommitId:              proto.String("<commit id>"),
		Labels: &types.LabelUpdateWrapper{
			Labels: []string{
				"<labels>",
			},
		},
		Properties: &types.PropertyUpdateWrapper{
			Properties: map[string]string{
				"<key>": "<value>",
			},
		},
		State: &executionsv1.ProcedureExecutionState{
			GlobalFields: map[string]*executionsv1.FieldOutput{
				"<key>": {
					Output: &executionsv1.FieldOutput_AssetRid{AssetRid: "<asset rid>"},
				},
			},
			Nodes: map[string]*executionsv1.ProcedureExecutionNode{
				"<key>": {
					Node: &executionsv1.ProcedureExecutionNode_Section{Section: &executionsv1.ProcedureExecutionSectionNode{
						Id:               "<id>",
						TemplateNodeId:   "<template node id>",
						Title:            "<title>",
						Description:      proto.String("<description>"),
						TemplateCommitId: proto.String("<template commit id>"),
					}},
				},
			},
			SectionEdges: map[string]*proceduresv1.NodeList{
				"<key>": {
					NodeIds: []string{
						"<node ids>",
					},
				},
			},
			StepEdges: map[string]*proceduresv1.NodeList{
				"<key>": {
					NodeIds: []string{
						"<node ids>",
					},
				},
			},
		},
		IsAborted:  proto.Bool(true),
		StartedAt:  timestamppb.New(time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)),
		FinishedAt: timestamppb.New(time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)),
	}
	response, err := procedureExecutionsService.UpdateProcedureExecution(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "procedure_execution": {
    "rid": "<rid>",
    "metadata": {
      "rid": "<rid>",
      "procedure_rid": "<procedure rid>",
      "procedure_commit_id": "<procedure commit id>",
      "title": "<title>",
      "description": "<description>",
      "labels": [
        "<labels>"
      ],
      "properties": {
        "<key>": "<value>"
      },
      "created_by": "<created by>",
      "created_at": "2026-01-01T00:00:00Z",
      "updated_by": "<updated by>",
      "updated_at": "2026-01-01T00:00:00Z",
      "started_at": "2026-01-01T00:00:00Z",
      "started_by": "<started by>",
      "finished_at": "2026-01-01T00:00:00Z",
      "finished_by": "<finished by>",
      "aborted_at": "2026-01-01T00:00:00Z",
      "aborted_by": "<aborted by>",
      "failed_at": "2026-01-01T00:00:00Z",
      "failed_by": "<failed by>",
      "failed_reason": "<failed reason>",
      "asset_rids": [
        "<asset rids>"
      ],
      "is_archived": true
    },
    "state": {
      "global_fields": {
        "<key>": {
          "asset_rid": "<asset rid>"
        }
      },
      "nodes": {
        "<key>": {
          "section": {
            "id": "<id>",
            "template_node_id": "<template node id>",
            "title": "<title>",
            "description": "<description>",
            "template_commit_id": "<template commit id>"
          }
        }
      },
      "section_edges": {
        "<key>": {
          "node_ids": [
            "<node ids>"
          ]
        }
      },
      "step_edges": {
        "<key>": {
          "node_ids": [
            "<node ids>"
          ]
        }
      }
    }
  }
}

Update procedure execution metadata#

gRPC /nominal.procedures.executions.v1.ProcedureExecutionsService/UpdateProcedureExecutionMetadata

Update the metadata of a procedure execution

Request: UpdateProcedureExecutionMetadataRequest

procedure_execution_rid string

​

title string

​

description string

​

commit_id string

​

labels LabelUpdateWrapper

​

Fields of LabelUpdateWrapper
labels array of string

​

properties PropertyUpdateWrapper

​

Fields of PropertyUpdateWrapper
properties map of string to string

​

Response: UpdateProcedureExecutionMetadataResponse

metadata ProcedureExecutionMetadata

​

Fields of ProcedureExecutionMetadata
rid string

​

procedure_rid string

The procedure template rid this execution is based on.

procedure_commit_id string

The commit ID of the procedure template this execution is based on. This can be overridden at the node level for individual nodes.

title string

At least 1 character.

description string

​

labels array of string

​

properties map of string to string

​

created_by string

​

created_at string (date-time)

​

updated_by string

​

updated_at string (date-time)

​

started_at string (date-time)

Will be unset until the execution transitions from NOT_STARTED to IN_PROGRESS.

started_by string

​

finished_at string (date-time)

Will be unset until the execution transitions from IN_PROGRESS to a terminal state.

finished_by string

​

aborted_at string (date-time)

Will be true/set if the execution is the ABORTED terminal state.

aborted_by string

​

failed_at string (date-time)

Will be set if the execution is in the ERRORED terminal state.

failed_by string

​

failed_reason string

​

asset_rids array of string

Assets which this execution has acted on in completed steps (e.g. through an event creation action).

is_archived boolean

​

Request

import grpc
from nominal.protos.procedures.executions.v1 import procedure_executions_pb2, procedure_executions_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
procedure_executions_service = procedure_executions_pb2_grpc.ProcedureExecutionsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = procedure_executions_pb2.UpdateProcedureExecutionMetadataRequest(
    procedure_execution_rid="<procedure execution rid>",
    title="<title>",
    description="<description>",
    commit_id="<commit id>",
    labels={"labels": ["<labels>"]},
    properties={"properties": {"<key>": "<value>"}},
)
response = procedure_executions_service.UpdateProcedureExecutionMetadata(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	executionsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/executions/v1"
	"github.com/nominal-io/nominal-api-protos-go/nominal/protos/types"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
	"google.golang.org/protobuf/proto"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	procedureExecutionsService := executionsv1.NewProcedureExecutionsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &executionsv1.UpdateProcedureExecutionMetadataRequest{
		ProcedureExecutionRid: "<procedure execution rid>",
		Title:                 proto.String("<title>"),
		Description:           proto.String("<description>"),
		CommitId:              proto.String("<commit id>"),
		Labels: &types.LabelUpdateWrapper{
			Labels: []string{
				"<labels>",
			},
		},
		Properties: &types.PropertyUpdateWrapper{
			Properties: map[string]string{
				"<key>": "<value>",
			},
		},
	}
	response, err := procedureExecutionsService.UpdateProcedureExecutionMetadata(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "metadata": {
    "rid": "<rid>",
    "procedure_rid": "<procedure rid>",
    "procedure_commit_id": "<procedure commit id>",
    "title": "<title>",
    "description": "<description>",
    "labels": [
      "<labels>"
    ],
    "properties": {
      "<key>": "<value>"
    },
    "created_by": "<created by>",
    "created_at": "2026-01-01T00:00:00Z",
    "updated_by": "<updated by>",
    "updated_at": "2026-01-01T00:00:00Z",
    "started_at": "2026-01-01T00:00:00Z",
    "started_by": "<started by>",
    "finished_at": "2026-01-01T00:00:00Z",
    "finished_by": "<finished by>",
    "aborted_at": "2026-01-01T00:00:00Z",
    "aborted_by": "<aborted by>",
    "failed_at": "2026-01-01T00:00:00Z",
    "failed_by": "<failed by>",
    "failed_reason": "<failed reason>",
    "asset_rids": [
      "<asset rids>"
    ],
    "is_archived": true
  }
}

Update step#

gRPC /nominal.procedures.executions.v1.ProcedureExecutionsService/UpdateStep

Update the status of a step in a procedure execution. This can only be done if the step is NOT_STARTED, IN_PROGRESS, or SUBMITTED. Other state transitions are managed by the backend.

Request: UpdateStepRequest

procedure_execution_rid string

​

step_id string

The unique identifier of the execution step to update. At least 1 character.

value StepContentValue

Setting the value of the step’s content. This is only allowed if the step is NOT_STARTED or IN_PROGRESS.

Fields of StepContentValue
one of form, start_ingest, select_or_create_asset, wait required

​

form FormStepValue

​

Fields of FormStepValue
fields array of FormFieldValue

​

Fields of FormFieldValue
one of 9 fields required

​

asset AssetFieldValue

​

Fields of AssetFieldValue
asset_reference AssetReference

​

Fields of AssetReference
one of rid, field_id required

​

rid string

a constant AssetRid

field_id string

The field reference that will contain an AssetRid value. The execution will fail if the field is not set but the value is accessed.

checkbox CheckboxFieldValue

​

Fields of CheckboxFieldValue
value boolean

Default to false if not set

text TextFieldValue

​

Fields of TextFieldValue
value string

Default to empty string if not set

int IntFieldValue

​

Fields of IntFieldValue
value integer (int64)

​

double DoubleFieldValue

​

Fields of DoubleFieldValue
value number

​

single_enum SingleEnumFieldValue

​

Fields of SingleEnumFieldValue
value string

Default to empty string if not set

multi_enum MultiEnumFieldValue

​

Fields of MultiEnumFieldValue
value array of string

Default to empty list if not set

file_upload FileUploadFieldValue

​

Fields of FileUploadFieldValue
s3_upload S3UploadFileValue

​

Fields of S3UploadFileValue
s3_path string

The S3 path where the uploaded file is stored At least 1 character.

file_name string

The original filename of the uploaded file At least 1 character.

file_type string

The MIME type of the uploaded file Following the convention of https://developer.mozilla.org/en-US/docs/Web/API/Blob/type (from which the File api inherits, we will accept an empty string)

multi_file_upload MultiFileUploadFieldValue

​

Fields of MultiFileUploadFieldValue
uploads array of FileUploadFieldValue

The list of uploads

start_ingest StartIngestStepValue

​

Fields of StartIngestStepValue
ingest_job_rid string

The RID of the ingest job that was started by the client. This must be populated for the step to be submitted.

select_or_create_asset SelectOrCreateAssetStepValue

​

Fields of SelectOrCreateAssetStepValue
asset_reference AssetReference

The asset that was selected / created by the client. This must be populated for the step to be submitted.

wait WaitStepValue

…

auto_proceed_config AutoProceedConfig

Set whether the step has auto-proceed enabled. This is only allowed if the step is NOT_STARTED. or IN_PROGRESS.

Fields of AutoProceedConfig
one of disabled, enabled required

​

disabled Disabled

The step will not be automatically completed

enabled Enabled

The step will automatically submit the step contents once the requirements are met and begin the transition to either PASSED or ERRORED.

target_state TargetStepStateRequest

Setting the state of the step. This will occur after the other updates in this request.

Fields of TargetStepStateRequest
one of in_progress, submitted, skipped, errored required

​

in_progress StepInProgressRequest

​

submitted StepSubmittedRequest

​

skipped StepSkippedRequest

​

Fields of StepSkippedRequest
skip_reason string

​

errored StepErroredRequest

​

Fields of StepErroredRequest
error_reason string

​

Response: UpdateStepResponse

procedure_execution ProcedureExecution

​

Fields of ProcedureExecution
rid string

​

metadata ProcedureExecutionMetadata

​

Fields of ProcedureExecutionMetadata
rid string

​

procedure_rid string

The procedure template rid this execution is based on.

procedure_commit_id string

The commit ID of the procedure template this execution is based on. This can be overridden at the node level for individual nodes.

title string

At least 1 character.

description string

​

labels array of string

​

properties map of string to string

​

created_by string

​

created_at string (date-time)

​

updated_by string

​

updated_at string (date-time)

​

started_at string (date-time)

Will be unset until the execution transitions from NOT_STARTED to IN_PROGRESS.

started_by string

​

finished_at string (date-time)

Will be unset until the execution transitions from IN_PROGRESS to a terminal state.

finished_by string

​

aborted_at string (date-time)

Will be true/set if the execution is the ABORTED terminal state.

aborted_by string

​

failed_at string (date-time)

Will be set if the execution is in the ERRORED terminal state.

failed_by string

​

failed_reason string

​

asset_rids array of string

Assets which this execution has acted on in completed steps (e.g. through an event creation action).

is_archived boolean

​

state ProcedureExecutionState

​

Fields of ProcedureExecutionState
global_fields map of string to FieldOutput

The current values for the global fields in the procedure.

Fields of FieldOutput
one of 10 fields

​

asset_rid string

If a global field is not yet defined, I think it’s just not present in the global_fields map option (buf.validate.oneof) = {required: true};

string_value string

​

double_value number

​

boolean_value boolean

​

int_value integer (int64)

​

strings_value Strings

​

Fields of Strings
values array of string

​

ingest_job_rid string

​

run_rid string

​

file_upload_value FileUploadFieldValue

​

Fields of FileUploadFieldValue
s3_upload S3UploadFileValue

​

Fields of S3UploadFileValue
s3_path string

The S3 path where the uploaded file is stored At least 1 character.

file_name string

The original filename of the uploaded file At least 1 character.

file_type string

The MIME type of the uploaded file Following the convention of https://developer.mozilla.org/en-US/docs/Web/API/Blob/type (from which the File api inherits, we will accept an empty string)

multi_file_upload_value MultiFileUploadFieldValue

​

Fields of MultiFileUploadFieldValue
uploads array of FileUploadFieldValue

The list of uploads

nodes map of string to ProcedureExecutionNode

A map from execution node ID to the execution node.

Fields of ProcedureExecutionNode
one of section, step

​

section ProcedureExecutionSectionNode

A section node is a visual grouping of other sections and steps. Execution sections are static and do not have execution state.

Fields of ProcedureExecutionSectionNode
id string

Unique identifier of this execution node. At least 1 character.

template_node_id string

Unique identifier of the template node this execution node is based on. At least 1 character.

title string

Title of this section. Uses the template section’s title and cannot be changed in execution. At least 1 character.

description string

Description of this section. Uses the template section’s description and cannot be changed in execution.

template_commit_id string

If set, the commit ID of the procedure template this section is based on. Otherwise, the section is based on the template commit specified at the top level of the execution.

step ProcedureExecutionStepNode

Execution steps are the interactive steps in a procedure.

Fields of ProcedureExecutionStepNode
id string

Unique identifier of this execution node. At least 1 character.

template_node_id string

Unique identifier of the template node this execution node is based on. At least 1 character.

is_outdated boolean

Execution steps become “outdated” once any upstream steps are re-run An outdated execution step should not be further modified.

state ExecutionStepState

The current status of the step along with metadata about the status transitions.

Fields of ExecutionStepState
one of 6 fields

​

not_started ExecutionStepNotStarted

​

in_progress ExecutionStepInProgress

​

Fields of ExecutionStepInProgress
started_at string (date-time)

​

started_by string

​

submitted ExecutionStepSubmitted

​

Fields of ExecutionStepSubmitted
started_at string (date-time)

​

started_by string

​

submitted_at string (date-time)

​

submitted_by string

​

skipped ExecutionStepSkipped

Terminal states below

Fields of ExecutionStepSkipped
skipped_at string (date-time)

​

skipped_by string

​

skip_reason string

​

started_at string (date-time)

Optional because a step can be skipped from the NOT_STARTED state before these are set

started_by string

​

submitted_at string (date-time)

Optional because a step can be skipped from the IN_PROGRESS state before these are set

submitted_by string

​

succeeded ExecutionStepSucceeded

​

Fields of ExecutionStepSucceeded
started_at string (date-time)

​

started_by string

​

submitted_at string (date-time)

​

submitted_by string

​

succeeded_at string (date-time)

​

succeeded_by string

​

errored ExecutionStepErrored

​

Fields of ExecutionStepErrored
started_at string (date-time)

Optional because a step can reach ERRORED without having been started

started_by string

​

submitted_at string (date-time)

Optional because a step can be errored before being submitted

submitted_by string

​

errored_at string (date-time)

​

errored_by string

​

error string

​

skipped_at string (date-time)

Optional because a step could be skipped but then error while running completion actions

skipped_by string

​

skip_reason string

​

succeeded_at string (date-time)

Optional because a step can succeed but then error while running completion actions

succeeded_by string

​

value StepContentValue

The current value for the content of the step.

Fields of StepContentValue
one of form, start_ingest, select_or_create_asset, wait

​

form FormStepValue

​

Fields of FormStepValue
fields array of FormFieldValue

​

Fields of FormFieldValue
one of 9 fields

Request

import grpc
from nominal.protos.procedures.executions.v1 import procedure_executions_pb2, procedure_executions_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
procedure_executions_service = procedure_executions_pb2_grpc.ProcedureExecutionsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = procedure_executions_pb2.UpdateStepRequest(
    procedure_execution_rid="<procedure execution rid>",
    step_id="<step id>",
    value={"form": {"fields": [{"asset": {"asset_reference": {"rid": "<rid>"}}}]}},
    auto_proceed_config={"disabled": {}},
    target_state={"in_progress": {}},
)
response = procedure_executions_service.UpdateStep(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	executionsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/executions/v1"
	proceduresv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	procedureExecutionsService := executionsv1.NewProcedureExecutionsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &executionsv1.UpdateStepRequest{
		ProcedureExecutionRid: "<procedure execution rid>",
		StepId:                "<step id>",
		Value: &executionsv1.StepContentValue{
			Value: &executionsv1.StepContentValue_Form{Form: &executionsv1.FormStepValue{
				Fields: []*executionsv1.FormFieldValue{
					{
						Field: &executionsv1.FormFieldValue_Asset{Asset: &executionsv1.AssetFieldValue{
							Asset: &executionsv1.AssetFieldValue_AssetReference{AssetReference: &proceduresv1.AssetReference{
								Option: &proceduresv1.AssetReference_Rid{Rid: "<rid>"},
							}},
						}},
					},
				},
			}},
		},
		AutoProceedConfig: &proceduresv1.AutoProceedConfig{
			Config: &proceduresv1.AutoProceedConfig_Disabled_{Disabled: &proceduresv1.AutoProceedConfig_Disabled{}},
		},
		TargetState: &executionsv1.TargetStepStateRequest{
			TargetState: &executionsv1.TargetStepStateRequest_InProgress{InProgress: &executionsv1.StepInProgressRequest{}},
		},
	}
	response, err := procedureExecutionsService.UpdateStep(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "procedure_execution": {
    "rid": "<rid>",
    "metadata": {
      "rid": "<rid>",
      "procedure_rid": "<procedure rid>",
      "procedure_commit_id": "<procedure commit id>",
      "title": "<title>",
      "description": "<description>",
      "labels": [
        "<labels>"
      ],
      "properties": {
        "<key>": "<value>"
      },
      "created_by": "<created by>",
      "created_at": "2026-01-01T00:00:00Z",
      "updated_by": "<updated by>",
      "updated_at": "2026-01-01T00:00:00Z",
      "started_at": "2026-01-01T00:00:00Z",
      "started_by": "<started by>",
      "finished_at": "2026-01-01T00:00:00Z",
      "finished_by": "<finished by>",
      "aborted_at": "2026-01-01T00:00:00Z",
      "aborted_by": "<aborted by>",
      "failed_at": "2026-01-01T00:00:00Z",
      "failed_by": "<failed by>",
      "failed_reason": "<failed reason>",
      "asset_rids": [
        "<asset rids>"
      ],
      "is_archived": true
    },
    "state": {
      "global_fields": {
        "<key>": {
          "asset_rid": "<asset rid>"
        }
      },
      "nodes": {
        "<key>": {
          "section": {
            "id": "<id>",
            "template_node_id": "<template node id>",
            "title": "<title>",
            "description": "<description>",
            "template_commit_id": "<template commit id>"
          }
        }
      },
      "section_edges": {
        "<key>": {
          "node_ids": [
            "<node ids>"
          ]
        }
      },
      "step_edges": {
        "<key>": {
          "node_ids": [
            "<node ids>"
          ]
        }
      }
    }
  }
}

Update step channel capture status#

gRPC /nominal.procedures.executions.v1.ProcedureExecutionsService/UpdateStepChannelCaptureStatus

Called by the backend (channel capture executor) to merge a single channel-capture status into a step’s channel_capture_statuses. Identity is (output_field_id, capture_moment); existing entries for that identity are replaced. Statuses are written incrementally as captures progress (in_progress -> terminal), so this RPC is expected to be called multiple times per capture.

Request: UpdateStepChannelCaptureStatusRequest

procedure_execution_rid string

​

step_id string

The unique identifier of the execution step to update. At least 1 character.

channel_capture_status ChannelCaptureStatus

The status to merge into the step’s channel_capture_statuses, identified by (output_field_id, capture_moment). Replaces any previously written entry with the same identity.

Fields of ChannelCaptureStatus
output_field_id string

The output_field_id of the capture. Used together with capture_moment to identify which capture this status refers to. At least 1 character.

capture_moment CaptureMoment

Which step lifecycle moment this capture corresponds to. A given output_field_id may be captured at both step start and step completion, in which case there will be one ChannelCaptureStatus entry per moment. Must be a defined, non-UNSPECIFIED CaptureMoment — capture_moment is half of the identity key used for merging, so accepting the zero value would produce a bogus key.

Values of CaptureMoment
CAPTURE_MOMENT_UNSPECIFIED

Required zero-value enum sentinel. Do not include this in capture_moments.

CAPTURE_MOMENT_STEP_START

​

CAPTURE_MOMENT_STEP_COMPLETION

​

one of in_progress, succeeded, failed, skipped required

​

in_progress ChannelCaptureInProgress

​

Fields of ChannelCaptureInProgress
started_at string (date-time)

​

succeeded ChannelCaptureSucceeded

​

Fields of ChannelCaptureSucceeded
started_at string (date-time)

​

captured_at string (date-time)

​

value CapturedValue required

​

Fields of CapturedValue
one of double_value, int_value, bool_value, string_value required

​

double_value number

​

int_value integer (int64)

​

bool_value boolean

​

string_value string

​

failed ChannelCaptureFailed

​

Fields of ChannelCaptureFailed
started_at string (date-time)

​

failed_at string (date-time)

​

reason ChannelCaptureFailureReason

​

Values of ChannelCaptureFailureReason
CHANNEL_CAPTURE_FAILURE_REASON_UNSPECIFIED

​

CHANNEL_CAPTURE_FAILURE_REASON_DATA_SOURCE_NOT_FOUND

The channel’s data_source_ref could not be resolved to a concrete data source at execution time (e.g. the named ref is not present in the execution’s data scopes or run data sources).

CHANNEL_CAPTURE_FAILURE_REASON_CHANNEL_NOT_FOUND

The data source was resolved but the named channel (with the configured tags, if any) does not exist on it, or its metadata could not be fetched.

CHANNEL_CAPTURE_FAILURE_REASON_UNSUPPORTED_CHANNEL_TYPE

The channel’s data type cannot be represented by CapturedValue, or the channel’s data type is unset. Permanent for this channel — re-running will not help.

CHANNEL_CAPTURE_FAILURE_REASON_TIMEOUT_NO_DATA

No data point arrived within the capture timeout window (subscription opened but yielded no value before the deadline).

CHANNEL_CAPTURE_FAILURE_REASON_INTERNAL_ERROR

Catch-all for backend / infrastructure failures that prevented capture — e.g. websocket connect/subscribe/stream failure, missing websocket configuration, downstream event creation failure, interrupt, or any other unexpected failure. See error_message for the specific cause.

error_message string

Free-text detail. Must not contain unsafe content — same conventions as other user-visible error_message fields on procedure executions. Capped to bound payload size; truncate at the producer if a longer detail is available. At most 4,096 characters.

skipped ChannelCaptureSkipped

​

Fields of ChannelCaptureSkipped
skipped_at string (date-time)

​

reason ChannelCaptureSkipReason

​

Values of ChannelCaptureSkipReason
CHANNEL_CAPTURE_SKIP_REASON_UNSPECIFIED

​

CHANNEL_CAPTURE_SKIP_REASON_RUN_SCOPED_UNSUPPORTED

The capture targets a run-scoped channel locator, which is not yet supported.

Response: UpdateStepChannelCaptureStatusResponse

procedure_execution ProcedureExecution

​

Fields of ProcedureExecution
rid string

​

metadata ProcedureExecutionMetadata

​

Fields of ProcedureExecutionMetadata
rid string

​

procedure_rid string

The procedure template rid this execution is based on.

procedure_commit_id string

The commit ID of the procedure template this execution is based on. This can be overridden at the node level for individual nodes.

title string

At least 1 character.

description string

​

labels array of string

​

properties map of string to string

​

created_by string

​

created_at string (date-time)

​

updated_by string

​

updated_at string (date-time)

​

started_at string (date-time)

Will be unset until the execution transitions from NOT_STARTED to IN_PROGRESS.

started_by string

​

finished_at string (date-time)

Will be unset until the execution transitions from IN_PROGRESS to a terminal state.

finished_by string

​

aborted_at string (date-time)

Will be true/set if the execution is the ABORTED terminal state.

aborted_by string

​

failed_at string (date-time)

Will be set if the execution is in the ERRORED terminal state.

failed_by string

​

failed_reason string

​

asset_rids array of string

Assets which this execution has acted on in completed steps (e.g. through an event creation action).

is_archived boolean

​

state ProcedureExecutionState

​

Fields of ProcedureExecutionState
global_fields map of string to FieldOutput

The current values for the global fields in the procedure.

Fields of FieldOutput
one of 10 fields

​

asset_rid string

If a global field is not yet defined, I think it’s just not present in the global_fields map option (buf.validate.oneof) = {required: true};

string_value string

​

double_value number

​

boolean_value boolean

​

int_value integer (int64)

​

strings_value Strings

​

Fields of Strings
values array of string

​

ingest_job_rid string

​

run_rid string

​

file_upload_value FileUploadFieldValue

​

Fields of FileUploadFieldValue
s3_upload S3UploadFileValue

​

Fields of S3UploadFileValue
s3_path string

The S3 path where the uploaded file is stored At least 1 character.

file_name string

The original filename of the uploaded file At least 1 character.

file_type string

The MIME type of the uploaded file Following the convention of https://developer.mozilla.org/en-US/docs/Web/API/Blob/type (from which the File api inherits, we will accept an empty string)

multi_file_upload_value MultiFileUploadFieldValue

​

Fields of MultiFileUploadFieldValue
uploads array of FileUploadFieldValue

The list of uploads

nodes map of string to ProcedureExecutionNode

A map from execution node ID to the execution node.

Fields of ProcedureExecutionNode
one of section, step

​

section ProcedureExecutionSectionNode

A section node is a visual grouping of other sections and steps. Execution sections are static and do not have execution state.

Fields of ProcedureExecutionSectionNode
id string

Unique identifier of this execution node. At least 1 character.

template_node_id string

Unique identifier of the template node this execution node is based on. At least 1 character.

title string

Title of this section. Uses the template section’s title and cannot be changed in execution. At least 1 character.

description string

Description of this section. Uses the template section’s description and cannot be changed in execution.

template_commit_id string

If set, the commit ID of the procedure template this section is based on. Otherwise, the section is based on the template commit specified at the top level of the execution.

step ProcedureExecutionStepNode

Execution steps are the interactive steps in a procedure.

Fields of ProcedureExecutionStepNode
id string

Unique identifier of this execution node. At least 1 character.

template_node_id string

Unique identifier of the template node this execution node is based on. At least 1 character.

is_outdated boolean

Execution steps become “outdated” once any upstream steps are re-run An outdated execution step should not be further modified.

state ExecutionStepState

The current status of the step along with metadata about the status transitions.

Fields of ExecutionStepState
one of 6 fields

​

not_started ExecutionStepNotStarted

​

in_progress ExecutionStepInProgress

​

Fields of ExecutionStepInProgress
started_at string (date-time)

​

started_by string

​

submitted ExecutionStepSubmitted

​

Fields of ExecutionStepSubmitted
started_at string (date-time)

​

started_by string

​

submitted_at string (date-time)

​

submitted_by string

​

skipped ExecutionStepSkipped

Terminal states below

Fields of ExecutionStepSkipped
skipped_at string (date-time)

​

skipped_by string

​

skip_reason string

​

started_at string (date-time)

Optional because a step can be skipped from the NOT_STARTED state before these are set

started_by string

​

submitted_at string (date-time)

Optional because a step can be skipped from the IN_PROGRESS state before these are set

submitted_by string

​

succeeded ExecutionStepSucceeded

​

Fields of ExecutionStepSucceeded
started_at string (date-time)

​

started_by string

​

submitted_at string (date-time)

​

submitted_by string

​

succeeded_at string (date-time)

​

succeeded_by string

​

errored ExecutionStepErrored

​

Fields of ExecutionStepErrored
started_at string (date-time)

Optional because a step can reach ERRORED without having been started

started_by string

​

submitted_at string (date-time)

Optional because a step can be errored before being submitted

submitted_by string

​

errored_at string (date-time)

​

errored_by string

​

error string

​

skipped_at string (date-time)

Optional because a step could be skipped but then error while running completion actions

skipped_by string

​

skip_reason string

​

succeeded_at string (date-time)

Optional because a step can succeed but then error while running completion actions

succeeded_by string

​

value StepContentValue

The current value for the content of the step.

Fields of StepContentValue
one of form, start_ingest, select_or_create_asset, wait

​

form FormStepValue

​

Fields of FormStepValue
fields array of FormFieldValue

​

Fields of FormFieldValue
one of 9 fields

Request

from datetime import datetime, timezone

import grpc
from nominal.protos.procedures.executions.v1 import procedure_executions_pb2, procedure_executions_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
procedure_executions_service = procedure_executions_pb2_grpc.ProcedureExecutionsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = procedure_executions_pb2.UpdateStepChannelCaptureStatusRequest(
    procedure_execution_rid="<procedure execution rid>",
    step_id="<step id>",
    channel_capture_status={
        "output_field_id": "<output field id>",
        "capture_moment": "CAPTURE_MOMENT_STEP_START",
        "in_progress": {"started_at": datetime(2026, 1, 1, tzinfo=timezone.utc)},
    },
)
response = procedure_executions_service.UpdateStepChannelCaptureStatus(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"
	"time"

	executionsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/executions/v1"
	proceduresv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/procedures/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
	"google.golang.org/protobuf/types/known/timestamppb"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	procedureExecutionsService := executionsv1.NewProcedureExecutionsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &executionsv1.UpdateStepChannelCaptureStatusRequest{
		ProcedureExecutionRid: "<procedure execution rid>",
		StepId:                "<step id>",
		ChannelCaptureStatus: &executionsv1.ChannelCaptureStatus{
			OutputFieldId: "<output field id>",
			CaptureMoment: proceduresv1.CaptureMoment_CAPTURE_MOMENT_STEP_START,
			Status: &executionsv1.ChannelCaptureStatus_InProgress{InProgress: &executionsv1.ChannelCaptureInProgress{
				StartedAt: timestamppb.New(time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)),
			}},
		},
	}
	response, err := procedureExecutionsService.UpdateStepChannelCaptureStatus(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "procedure_execution": {
    "rid": "<rid>",
    "metadata": {
      "rid": "<rid>",
      "procedure_rid": "<procedure rid>",
      "procedure_commit_id": "<procedure commit id>",
      "title": "<title>",
      "description": "<description>",
      "labels": [
        "<labels>"
      ],
      "properties": {
        "<key>": "<value>"
      },
      "created_by": "<created by>",
      "created_at": "2026-01-01T00:00:00Z",
      "updated_by": "<updated by>",
      "updated_at": "2026-01-01T00:00:00Z",
      "started_at": "2026-01-01T00:00:00Z",
      "started_by": "<started by>",
      "finished_at": "2026-01-01T00:00:00Z",
      "finished_by": "<finished by>",
      "aborted_at": "2026-01-01T00:00:00Z",
      "aborted_by": "<aborted by>",
      "failed_at": "2026-01-01T00:00:00Z",
      "failed_by": "<failed by>",
      "failed_reason": "<failed reason>",
      "asset_rids": [
        "<asset rids>"
      ],
      "is_archived": true
    },
    "state": {
      "global_fields": {
        "<key>": {
          "asset_rid": "<asset rid>"
        }
      },
      "nodes": {
        "<key>": {
          "section": {
            "id": "<id>",
            "template_node_id": "<template node id>",
            "title": "<title>",
            "description": "<description>",
            "template_commit_id": "<template commit id>"
          }
        }
      },
      "section_edges": {
        "<key>": {
          "node_ids": [
            "<node ids>"
          ]
        }
      },
      "step_edges": {
        "<key>": {
          "node_ids": [
            "<node ids>"
          ]
        }
      }
    }
  }
}

Errors#

Errors shows how these errors are sent.

Code

Reason

Message

INVALID_ARGUMENT

PROCEDURE_EXECUTIONS_SERVICE_ERROR_INVALID_GRAPH

Invalid procedure graph

INVALID_ARGUMENT

PROCEDURE_EXECUTIONS_SERVICE_ERROR_INVALID_SEARCH_TOKEN

Invalid search token

INVALID_ARGUMENT

PROCEDURE_EXECUTIONS_SERVICE_ERROR_INVALID_STEP_TRANSITION

Invalid step transition

INVALID_ARGUMENT

PROCEDURE_EXECUTIONS_SERVICE_ERROR_INVALID_STEP_UPDATE

Invalid step update

NOT_FOUND

PROCEDURE_EXECUTIONS_SERVICE_ERROR_INVALID_NODE

Invalid node

NOT_FOUND

PROCEDURE_EXECUTIONS_SERVICE_ERROR_NODE_NOT_FOUND

Node not found

NOT_FOUND

PROCEDURE_EXECUTIONS_SERVICE_ERROR_NOT_FOUND

Procedure execution not found

NOT_FOUND

PROCEDURE_EXECUTIONS_SERVICE_ERROR_PROC_NOT_FOUND

Procedure not found

Types#

AndSuccessCondition#

conditions array of SuccessConditionStatus

​

ApplyChecklistsResult#

An ApplyChecklists action results in a list of DataReviewRids if successful.

data_review_rids array of string

​

ApplyWorkbookTemplatesResult#

An ApplyWorkbookTemplates action results in a list of workbook RIDs if successful.

workbook_rids array of string

​

AssetFieldValue#

asset_reference AssetReference

​

AssetReference#

A reference to a single asset

Set exactly one of the fields below.

one of rid, field_id required

​

rid string

a constant AssetRid

field_id string

The field reference that will contain an AssetRid value. The execution will fail if the field is not set but the value is accessed.

AssetsFilter#

asset_rids array of string

​

operator Operator

​

AutoProceedConfig#

AutoProceedConfig is a configuration that determines whether a step should automatically proceed (submit the contents and check success_conditions) when some set of criteria are met. By default this will be disabled.

Set exactly one of the fields below.

one of disabled, enabled required

​

disabled Disabled

The step will not be automatically completed

enabled Enabled

The step will automatically submit the step contents once the requirements are met and begin the transition to either PASSED or ERRORED.

CapturedValue#

Set exactly one of the fields below.

one of double_value, int_value, bool_value, string_value required

​

double_value number

​

int_value integer (int64)

​

bool_value boolean

​

string_value string

​

CaptureMoment#

When in the step lifecycle to capture a channel value.

CAPTURE_MOMENT_UNSPECIFIED

Required zero-value enum sentinel. Do not include this in capture_moments.

CAPTURE_MOMENT_STEP_START

​

CAPTURE_MOMENT_STEP_COMPLETION

​

ChannelCaptureConfig#

Shared configuration for capturing a single channel value where the source channel is supplied by the parent config.

At execution time, the backend reads the channel’s value at the configured moment(s) and writes it into event metadata under dotted keys derived from output_field_id.

output_field_id string

Base field ID used to namespace event property keys (and downstream procedure outputs).

capture_moments array of CaptureMoment

When to capture relative to the step lifecycle. Empty means no capture occurs — at least one moment must be specified. No duplicates.

ChannelCaptureFailed#

The capture terminated with a failure. The structured reason enum drives UI grouping and downstream alerting; error_message provides a free-text detail for operator debugging. Whether a failed capture transitions the containing step to ERRORED is a backend policy decision outside this message — do not assume failure always implies step ERRORED.

started_at string (date-time)

​

failed_at string (date-time)

​

reason ChannelCaptureFailureReason

​

error_message string

Free-text detail. Must not contain unsafe content — same conventions as other user-visible error_message fields on procedure executions. Capped to bound payload size; truncate at the producer if a longer detail is available. At most 4,096 characters.

ChannelCaptureFailureReason#

Categorizes why a channel capture failed. New reasons should be added here as additional failure modes are recognized.

CHANNEL_CAPTURE_FAILURE_REASON_UNSPECIFIED

​

CHANNEL_CAPTURE_FAILURE_REASON_DATA_SOURCE_NOT_FOUND

The channel’s data_source_ref could not be resolved to a concrete data source at execution time (e.g. the named ref is not present in the execution’s data scopes or run data sources).

CHANNEL_CAPTURE_FAILURE_REASON_CHANNEL_NOT_FOUND

The data source was resolved but the named channel (with the configured tags, if any) does not exist on it, or its metadata could not be fetched.

CHANNEL_CAPTURE_FAILURE_REASON_UNSUPPORTED_CHANNEL_TYPE

The channel’s data type cannot be represented by CapturedValue, or the channel’s data type is unset. Permanent for this channel — re-running will not help.

CHANNEL_CAPTURE_FAILURE_REASON_TIMEOUT_NO_DATA

No data point arrived within the capture timeout window (subscription opened but yielded no value before the deadline).

CHANNEL_CAPTURE_FAILURE_REASON_INTERNAL_ERROR

Catch-all for backend / infrastructure failures that prevented capture — e.g. websocket connect/subscribe/stream failure, missing websocket configuration, downstream event creation failure, interrupt, or any other unexpected failure. See error_message for the specific cause.

ChannelCaptureInProgress#

The capture has been initiated (the value read / WebSocket subscription opened) but no terminal outcome has been written yet. The frontend can render a “capturing…” affordance from this state.

started_at string (date-time)

​

ChannelCaptureSkipped#

The capture was intentionally not attempted because the system does not currently support this capture configuration and purposefully skips rather than fails.

skipped_at string (date-time)

​

reason ChannelCaptureSkipReason

​

ChannelCaptureSkipReason#

Categorizes why a channel capture was skipped without being attempted. Skipped statuses are soft outcomes and do not transition the step to ERRORED.

CHANNEL_CAPTURE_SKIP_REASON_UNSPECIFIED

​

CHANNEL_CAPTURE_SKIP_REASON_RUN_SCOPED_UNSUPPORTED

The capture targets a run-scoped channel locator, which is not yet supported.

ChannelCaptureStatus#

The status of a single channel capture attempt for a specific (output_field_id, capture_moment) pair on a step. Mirrors the lifecycle-oneof shape used by SuccessConditionStatus so that the frontend can render an in-progress “capturing…” affordance, a terminal value/error, or a soft skip (e.g. system limitation), all from a single self-describing message.

Identity within a step = (output_field_id, capture_moment). The backend merges incoming statuses by this key, replacing any previously written entry for that identity. The channel locator is not echoed here — consumers resolve it by looking up output_field_id in the step’s capture config.

Set exactly one of in_progress, succeeded, failed, skipped.

output_field_id string

The output_field_id of the capture. Used together with capture_moment to identify which capture this status refers to. At least 1 character.

capture_moment CaptureMoment

Which step lifecycle moment this capture corresponds to. A given output_field_id may be captured at both step start and step completion, in which case there will be one ChannelCaptureStatus entry per moment. Must be a defined, non-UNSPECIFIED CaptureMoment — capture_moment is half of the identity key used for merging, so accepting the zero value would produce a bogus key.

one of in_progress, succeeded, failed, skipped required

​

in_progress ChannelCaptureInProgress

​

ChannelCaptureSucceeded#

The capture terminated successfully with a value.

started_at string (date-time)

​

captured_at string (date-time)

​

value CapturedValue required

​

ChannelLocator#

Locates a specific channel within a data source for validation. Uses symbolic reference names that are resolved to concrete resources at execution time, allowing procedure templates to be defined before the actual data sources exist.

Set exactly one of asset, run.

data_source_ref string

Symbolic name for the data source (e.g., “main”, “test_data”). This name is resolved to a concrete DataSourceRid at execution time by looking up the name in the data scopes (for assets) or data sources (for runs) specified by asset_or_run. This is NOT a field reference - it’s a literal string that must match a data source ref name. At least 1 character.

channel_name string

The name of the channel within the data source to validate. At least 1 character.

tags map of string to string

Optional series tags to filter the channel data. Used to select specific series when multiple series exist for the same channel name.

one of asset, run required

​

asset AssetReference

​

run RunReference

​

ChannelValidationSuccessCondition#

Defines a success condition that compares channel data against a threshold value. The step succeeds when the comparison (channel_value COMPARATOR threshold) evaluates to true within the timeout period. For example, checking if a channel value is greater than 100. Use COMPARATOR_EXISTS for capture-only conditions that succeed as soon as any channel value is observed.

channel ChannelLocator required

The channel to validate against the threshold. If the data_source_ref or channel_name cannot be resolved at execution time, the step will transition to ERRORED state immediately.

comparator COMPARATOR required

The comparison operator to use. COMPARATOR_UNSPECIFIED should never be used and will be rejected at runtime.

threshold number

The threshold value to compare the channel data against. The comparison is: channel_value COMPARATOR threshold Using double for better precision. Note: When using COMPARATOR_EQUAL or COMPARATOR_NOT_EQUAL with floating-point channel data, be aware of potential precision issues inherent to IEEE 754. Ignored when comparator is COMPARATOR_EXISTS.

timeout_millis integer

Maximum time in milliseconds to wait for the condition to be satisfied. If the timeout expires before the comparison evaluates to true, the step moves to ERRORED. Must be greater than zero and at most one hour (3,600,000 milliseconds). Greater than 0 and at most 3,600,000.

point_persistence integer (int64)

optionally specify a persistence of individual points Greater than 0.

time_persistence integer (int64)

optionally specify a persistence duration in milliseconds (max 5 minutes) for which the condition must hold true Greater than 0 and at most 300,000.

channel_captures array of ChannelCaptureConfig

Channel values to capture while evaluating this success condition. These captures use the condition’s channel field as their source. Each config produces dot-namespaced event-metadata properties keyed by output_field_id.

ChannelValidationSuccessConditionStatus#

condition ChannelValidationSuccessCondition

​

consecutive_matches integer

Persistence tracking state for channel validation conditions. Tracks consecutive successful evaluations for point_persistence.

first_satisfied_at string (date-time)

Timestamp when the condition first became satisfied. Used for time_persistence to track how long the condition has held true.

CheckboxFieldValue#

value boolean

Default to false if not set

COMPARATOR#

Comparison operator to evaluate channel value against threshold. The condition is satisfied when: channel_value COMPARATOR threshold Example: COMPARATOR_GREATER_THAN with threshold 100.0 means channel_value > 100.0

Evaluation semantics: The most recent channel value within the timeout period is used for comparison. If the channel has no data, the condition will continuously retry until timeout_millis expires.

COMPARATOR_UNSPECIFIED

Unspecified comparator. This is an invalid state and should never be used. Required by proto3 convention as the zero value. Will be rejected at runtime.

COMPARATOR_GREATER_THAN

​

COMPARATOR_GREATER_THAN_OR_EQUAL

​

COMPARATOR_LESS_THAN

​

COMPARATOR_LESS_THAN_OR_EQUAL

​

COMPARATOR_EQUAL

​

COMPARATOR_NOT_EQUAL

​

COMPARATOR_EXISTS

Succeeds when any channel value exists. The threshold field is ignored.

CompletionActionState#

Set exactly one of the fields below.

one of not_run, succeeded, error, in_progress required

​

not_run NotRun

The action was not run

succeeded Succeeded

The action was run and succeeded. The result is available in CompletionActionStatus.result

error string

The action was run and errored. This field contains the error message.

in_progress InProgress

The action execution is in progress

CompletionActionStatus#

The status of a completion action and its result (if any).

Set at most one of create_event, create_run, apply_workbook_templates, apply_checklists, update_run.

state CompletionActionState

​

one of 5 fields

​

create_event CreateEventResult

​

create_run CreateRunResult

​

apply_workbook_templates ApplyWorkbookTemplatesResult

​

apply_checklists ApplyChecklistsResult

​

update_run UpdateRunResult

…

CreateEventResult#

A CreateEvent action results in an EventRid if successful.

event_rid string

​

CreateRunResult#

A CreateRun action results in a RunRid if successful.

run_rid string

​

Disabled#

A message with no fields.

DoubleFieldValue#

value number

​

Enabled#

A message with no fields.

ExecutionStepErrored#

An execution step reaches the ERRORED state if something went wrong while trying to complete the step. This could be due to a badly configured procedure, an error/timeout in the completion condition, or an error/timeout in one of the completion actions. This is a terminal state, the step’s values cannot be modified by the user.

started_at string (date-time)

Optional because a step can reach ERRORED without having been started

started_by string

​

submitted_at string (date-time)

Optional because a step can be errored before being submitted

submitted_by string

​

errored_at string (date-time)

​

errored_by string

​

error string

​

skipped_at string (date-time)

Optional because a step could be skipped but then error while running completion actions

skipped_by string

​

skip_reason string

​

succeeded_at string (date-time)

Optional because a step can succeed but then error while running completion actions

succeeded_by string

​

ExecutionStepInProgress#

An execution step is in the IN_PROGRESS state once it has been started from NOT_STARTED, either manually or automatically. In this state, the step’s values can be modified by the user.

started_at string (date-time)

​

started_by string

​

ExecutionStepNotStarted#

All execution steps start in the NOT_STARTED state. In this state, the step’s values can be modified by the user.

A message with no fields.

ExecutionStepSkipped#

An execution step is in the SKIPPED state if it was skipped by a user. An execution step cannot be skipped if it is in a terminal state (SUCCEEDED or ERRORED). This is a terminal state, the step’s values cannot be modified by the user.

skipped_at string (date-time)

​

skipped_by string

​

skip_reason string

​

started_at string (date-time)

Optional because a step can be skipped from the NOT_STARTED state before these are set

started_by string

​

submitted_at string (date-time)

Optional because a step can be skipped from the IN_PROGRESS state before these are set

submitted_by string

​

ExecutionStepState#

The read-side state for an execution step. Here is the state machine: All steps start in the NOT_STARTED state. From NOT_STARTED, a step can transition to IN_PROGRESS or SKIPPED. - Transitioning to IN_PROGRESS can be done manually by a user or automatically if auto-start is enabled. This transition can only happen if the step’s dependencies are in a completed state (SUCCEEDED or SKIPPED) From IN_PROGRESS, a step can transition to SUBMITTED or SKIPPED. - Transitioning to SUBMITTED can be done manually by a user or automatically if auto-proceed is enabled. This transition can only happen if the step’s content has its required values set. - Transitioning to SKIPPED can be done manually by a user. From SUBMITTED, a step can transition to SUCCEEDED, ERRORED, or SKIPPED. - Transitioning to SUCCEEDED or ERRORED is done by the backend after monitoring the completion condition (if any) and executing the completion actions (if any). - Transitioning to SKIPPED can be done manually by a user.

Set exactly one of the fields below.

one of 6 fields required

​

not_started ExecutionStepNotStarted

​

in_progress ExecutionStepInProgress

​

submitted ExecutionStepSubmitted

​

skipped ExecutionStepSkipped

Terminal states below

succeeded ExecutionStepSucceeded

​

ExecutionStepSubmitted#

An execution step is in the SUBMITTED state once it has been submitted from the IN_PROGRESS state, either manually or automatically. In this state, the step’s values are considered submitted and cannot be modified by the user. In this state, the backend will monitor the completion condition (if any) and execute the completion actions (if any) once the condition is satisfied.

started_at string (date-time)

​

started_by string

​

submitted_at string (date-time)

​

submitted_by string

​

ExecutionStepSucceeded#

An execution step reaches the SUCCEEDED state if all conditions were met and all actions successfully ran. This is a terminal state, the step’s values cannot be modified by the user.

started_at string (date-time)

​

started_by string

​

submitted_at string (date-time)

​

submitted_by string

​

succeeded_at string (date-time)

​

succeeded_by string

​

FieldOutput#

This is different from FormFieldValue in that this represents the resolved value after the step has been completed. Eg, this would contain an AssetRid while the FormFieldValue could contain an AssetReference

Set at most one of the fields below.

one of 10 fields

​

asset_rid string

If a global field is not yet defined, I think it’s just not present in the global_fields map option (buf.validate.oneof) = {required: true};

string_value string

​

double_value number

​

boolean_value boolean

​

int_value integer (int64)

​

strings_value Strings

​

ingest_job_rid string

​

run_rid string

​

file_upload_value FileUploadFieldValue

​

multi_file_upload_value MultiFileUploadFieldValue

​

FileUploadFieldValue#

Corresponds to usage of the upload api

s3_upload S3UploadFileValue

​

FormFieldValue#

The value chosen for a form field. This differs from FieldOutput in that this should map 1:1 with FormField types, while FieldOutput contains the resolved values after the execution step is complete.

Set exactly one of the fields below.

one of 9 fields required

​

asset AssetFieldValue

​

checkbox CheckboxFieldValue

​

text TextFieldValue

​

int IntFieldValue

​

double DoubleFieldValue

​

single_enum SingleEnumFieldValue

​

multi_enum MultiEnumFieldValue

​

file_upload FileUploadFieldValue

​

multi_file_upload MultiFileUploadFieldValue

​

FormStepValue#

fields array of FormFieldValue

​

IngestJobSuccessCondition#

The step will succeed when the associated ingest job succeeds. If the ingest job fails, the step will move to ERRORED.

field_id string

The field ID that contains the IngestJobRid of the ingest job to monitor.

InProgress#

A message with no fields.

IntFieldValue#

value integer (int64)

​

LabelUpdateWrapper#

Wrapper classes to allow for optional fields on update requests

labels array of string

​

MultiEnumFieldValue#

value array of string

Default to empty list if not set

MultiFileUploadFieldValue#

uploads array of FileUploadFieldValue

The list of uploads

NodeList#

A list of node IDs.

node_ids array of string

​

NotRun#

A message with no fields.

Operator#

OPERATOR_UNSPECIFIED

​

OPERATOR_OR

​

OPERATOR_AND

​

ProcedureDisplayGraph#

A simpler representation of the procedure graph that is used for display in a UI.

top_level_nodes array of string

Sections or steps that do not belong to any parent sections. This is ordered in a topological ordering of steps.

section_to_sorted_children map of string to NodeList

Map of section node IDs to their topologically sorted children

ProcedureExecution#

rid string

​

metadata ProcedureExecutionMetadata

​

state ProcedureExecutionState

​

ProcedureExecutionMetadata#

rid string

​

procedure_rid string

The procedure template rid this execution is based on.

procedure_commit_id string

The commit ID of the procedure template this execution is based on. This can be overridden at the node level for individual nodes.

title string

At least 1 character.

description string

​

labels array of string

​

properties map of string to string

​

created_by string

​

created_at string (date-time)

​

updated_by string

​

updated_at string (date-time)

​

started_at string (date-time)

Will be unset until the execution transitions from NOT_STARTED to IN_PROGRESS.

started_by string

​

finished_at string (date-time)

Will be unset until the execution transitions from IN_PROGRESS to a terminal state.

finished_by string

​

aborted_at string (date-time)

Will be true/set if the execution is the ABORTED terminal state.

aborted_by string

​

failed_at string (date-time)

Will be set if the execution is in the ERRORED terminal state.

failed_by string

​

failed_reason string

​

asset_rids array of string

Assets which this execution has acted on in completed steps (e.g. through an event creation action).

is_archived boolean

​

ProcedureExecutionNode#

A procedure execution node is either a section or a step.

Set exactly one of the fields below.

one of section, step required

​

section ProcedureExecutionSectionNode

A section node is a visual grouping of other sections and steps. Execution sections are static and do not have execution state.

step ProcedureExecutionStepNode

Execution steps are the interactive steps in a procedure.

ProcedureExecutionProgressStatus#

PROCEDURE_EXECUTION_PROGRESS_STATUS_UNSPECIFIED

​

PROCEDURE_EXECUTION_PROGRESS_STATUS_NOT_STARTED

​

PROCEDURE_EXECUTION_PROGRESS_STATUS_IN_PROGRESS

​

PROCEDURE_EXECUTION_PROGRESS_STATUS_FINISHED

​

PROCEDURE_EXECUTION_PROGRESS_STATUS_ABORTED

​

ProcedureExecutionSearchAndQuery#

queries array of ProcedureExecutionSearchQuery

​

ProcedureExecutionSearchOrQuery#

queries array of ProcedureExecutionSearchQuery

​

ProcedureExecutionSearchQuery#

Set exactly one of the fields below.

one of 12 fields required

​

search_text string

​

label string

​

property Property

​

workspace string

​

procedure_rid string

​

commit_id string

​

created_by string

​

assets_filter AssetsFilter

​

is_archived boolean

​

ProcedureExecutionSectionNode#

A section node is a visual grouping of other sections and steps.

id string

Unique identifier of this execution node. At least 1 character.

template_node_id string

Unique identifier of the template node this execution node is based on. At least 1 character.

title string

Title of this section. Uses the template section’s title and cannot be changed in execution. At least 1 character.

description string

Description of this section. Uses the template section’s description and cannot be changed in execution.

template_commit_id string

If set, the commit ID of the procedure template this section is based on. Otherwise, the section is based on the template commit specified at the top level of the execution.

ProcedureExecutionSortOptions#

is_descending boolean

Defaults to descending

sort_field SearchProcedureExecutionsSortField required

​

ProcedureExecutionState#

ProcedureExecutionState is the state of an executing procedure.

global_fields map of string to FieldOutput

The current values for the global fields in the procedure.

nodes map of string to ProcedureExecutionNode

A map from execution node ID to the execution node.

section_edges map of string to NodeList

Section edges represent the visual grouping of sections and steps. All keys are IDs for section nodes, and all values are lists of IDs for section or step nodes. { A, [B, C] } means that section A visually groups nodes B and C together.

step_edges map of string to NodeList

Step edges represent the dependencies between steps. All keys and values are IDs for step nodes. { A, [B, C] } means that steps B and C depend on step A to complete to be started

ProcedureExecutionStepNode#

Execution steps are the interactive steps in a procedure.

id string

Unique identifier of this execution node. At least 1 character.

template_node_id string

Unique identifier of the template node this execution node is based on. At least 1 character.

is_outdated boolean

Execution steps become “outdated” once any upstream steps are re-run An outdated execution step should not be further modified.

state ExecutionStepState

The current status of the step along with metadata about the status transitions.

value StepContentValue

The current value for the content of the step.

auto_proceed_config AutoProceedConfig

Whether the step has auto-proceed enabled.

success_condition_status SuccessConditionStatus

Completion_condition_status is the status of the completion condition for the step The backend manages this property and will update it while it monitors the completion_condition if set. This property will be unset if no completion_condition is set on the step or if the execution step’s contents has not been submitted yet.

completion_action_statuses array of CompletionActionStatus

Completion_action_statuses are the status of the completion actions for the step The backend manages this property and will update it after performing completion_actions.

outputs map of string to FieldOutput

Outputs are the values of the fields within this step, set by the backend after the step has reached the SUCCEEDED state. The backend will know how to introspect the node and determine these values, for example looking for form fields with ids in a FormStep. These outputs can be consumed by other steps later in the procedure by referencing {output_id}:{field_id}

template_commit_id string

If set, the commit ID of the procedure template this step is based on. Otherwise, the step is based on the template commit specified at the top level of the execution.

channel_capture_statuses array of ChannelCaptureStatus

Channel capture statuses are the per-(output_field_id, capture_moment) statuses of the channel captures configured for this step. The backend manages this property and writes entries incrementally as captures progress through their lifecycle.

Property#

name string

​

value string

​

PropertyUpdateWrapper#

properties map of string to string

​

RepeatStepBehavior#

REPEAT_STEP_BEHAVIOR_UNSPECIFIED

​

REPEAT_STEP_BEHAVIOR_ISOLATED

The targeted step will be repeated, but the original graph will be preserved and only direct children will be checked for state updates

RunReference#

A reference to a single run

field_id string

The field id that will contain a RunRid value. The execution will fail if the field is not set properly.

S3UploadFileValue#

s3_path string

The S3 path where the uploaded file is stored At least 1 character.

file_name string

The original filename of the uploaded file At least 1 character.

file_type string

The MIME type of the uploaded file Following the convention of https://developer.mozilla.org/en-US/docs/Web/API/Blob/type (from which the File api inherits, we will accept an empty string)

SearchProcedureExecutionsSortField#

SEARCH_PROCEDURE_EXECUTIONS_SORT_FIELD_UNSPECIFIED

​

SEARCH_PROCEDURE_EXECUTIONS_SORT_FIELD_CREATED_AT

​

SEARCH_PROCEDURE_EXECUTIONS_SORT_FIELD_STARTED_AT

​

SEARCH_PROCEDURE_EXECUTIONS_SORT_FIELD_FINISHED_AT

​

SEARCH_PROCEDURE_EXECUTIONS_SORT_FIELD_UPDATED_AT

​

SelectOrCreateAssetStepValue#

asset_reference AssetReference

The asset that was selected / created by the client. This must be populated for the step to be submitted.

SingleEnumFieldValue#

value string

Default to empty string if not set

StartIngestStepValue#

ingest_job_rid string

The RID of the ingest job that was started by the client. This must be populated for the step to be submitted.

StepContentValue#

The value for a step’s content. Should match the ProcedureStepNode type.

Set exactly one of the fields below.

one of form, start_ingest, select_or_create_asset, wait required

​

form FormStepValue

​

start_ingest StartIngestStepValue

​

select_or_create_asset SelectOrCreateAssetStepValue

​

wait WaitStepValue

…

StepErroredRequest#

error_reason string

​

StepInProgressRequest#

A message with no fields.

StepSkippedRequest#

skip_reason string

​

StepSubmittedRequest#

A message with no fields.

Strings#

values array of string

​

Succeeded#

A message with no fields.

SuccessConditionCanceled#

started_at string (date-time)

​

canceled_at string (date-time)

​

SuccessConditionFailed#

started_at string (date-time)

​

failed_at string (date-time)

​

failure_reason string

​

SuccessConditionInProgress#

started_at string (date-time)

​

SuccessConditionSatisfied#

started_at string (date-time)

​

satisfied_at string (date-time)

​

SuccessConditionStatus#

Represents the current status of one or more nested completion conditions. Mirrors the recursive SuccessCondition in nominal.procedures.v1

Set exactly one of and, timer, ingest_job, channel_validation, webhook. Set exactly one of in_progress, satisfied, failed, canceled, submitted.

one of 5 fields required

​

webhook WebhookConditionStatus

OrSuccessConditionOrStatus or = 5;

one of 5 fields required

​

SuccessConditionSubmitted#

submitted_at string (date-time)

​

TargetStepStateRequest#

A request to update the state of an execution step.

Set exactly one of the fields below.

one of in_progress, submitted, skipped, errored required

​

in_progress StepInProgressRequest

​

submitted StepSubmittedRequest

​

skipped StepSkippedRequest

​

errored StepErroredRequest

​

TextFieldValue#

value string

Default to empty string if not set

TimerSuccessCondition#

A timer condition that will succeed the step after a specified duration.

duration_seconds integer

Duration in seconds to wait before succeeding the step. This value must be non-negative. This duration is a minimum bound; the actual duration may be longer. At least 0.

UpdateRunResult#

An UpdateRun action results in the list of RunRids that were updated.

run_rids array of string

​

WaitStepValue#

A message with no fields.

WebhookConditionStatus#

Status tracking for webhook success conditions. Tracks delivery attempts, retry timing, and the last response from the external system. Note: Secret management for retries is handled internally in workflow state, not exposed in this public API message.

condition WebhookSuccessCondition

The original webhook condition configuration being monitored

delivery_attempts integer

Number of delivery attempts made so far At least 0.

last_attempt_time string (date-time)

Timestamp of the last delivery attempt

next_retry_time string (date-time)

Timestamp when the next retry should be attempted (null if no retry scheduled)

last_delivery_id string

Unique ID of the last delivery attempt (unset if no attempts made yet) Generated per-attempt to correlate webhook deliveries with external system logs

last_http_status integer

HTTP status code from the last delivery attempt From 100 to 599.

last_error_message string

Error message from the last delivery attempt (if failed)

started_at string (date-time)

Timestamp when webhook condition evaluation started

terminal_failure_reason WebhookFailureReason

Terminal failure reason for this webhook condition. Only set when the condition transitions to FAILED status. Remains unset during retries (use last_error_message for intermediate failures).

WebhookDeliveryConfig#

Configuration for webhook delivery retry logic and timeouts.

max_retries integer

Maximum delivery attempts (default: 3, max: 10) From 0 to 10.

retry_interval_seconds integer (int64)

Initial retry interval seconds (default: 15, min: 5, max: 300) From 5 to 300.

exponential_backoff boolean

Use exponential backoff (default: true)

max_retry_interval_seconds integer (int64)

Max retry interval seconds (default: 300, max: 3600) From 5 to 3,600.

timeout_seconds integer (int64)

Overall timeout seconds (default: 600, max: 86400) From 1 to 86,400.

WebhookFailureReason#

Categorizes why a webhook success condition failed. This enum represents terminal failure states - failures that caused the condition to permanently fail.

WEBHOOK_FAILURE_REASON_UNSPECIFIED

Unspecified/unknown failure reason. Should not be used in normal operation.

WEBHOOK_FAILURE_REASON_CLIENT_ERROR

External system returned 4XX client error (permanent failure, no retry attempted). Indicates misconfiguration or invalid request that won’t succeed on retry. Common causes: 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found.

WEBHOOK_FAILURE_REASON_SERVER_ERROR_MAX_RETRIES_EXCEEDED

External system returned 5XX server error and max retries were exhausted. Server errors are typically transient and retries were attempted. Common causes: 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable.

WEBHOOK_FAILURE_REASON_TIMEOUT_MAX_RETRIES_EXCEEDED

Individual HTTP request timed out and max retries were exhausted. The external system didn’t respond within the per-request timeout window.

WEBHOOK_FAILURE_REASON_OVERALL_TIMEOUT_EXCEEDED

Overall condition timeout exceeded before receiving successful 2xx response. The webhook delivery config’s timeout_seconds was reached. This can occur even if individual requests completed (returned responses) but took too long cumulatively between retry delays, without receiving 2xx.

WEBHOOK_FAILURE_REASON_NETWORK_ERROR_MAX_RETRIES_EXCEEDED

Network-level failure prevented request delivery and max retries were exhausted. Common causes: DNS resolution failure, connection refused, TLS handshake failure.

WEBHOOK_FAILURE_REASON_PAYLOAD_ERROR

Template rendering or payload serialization failed (permanent failure). The payload_template could not be rendered to valid JSON. Common causes: Invalid Handlebars syntax, circular references, invalid JSON after rendering.

WEBHOOK_FAILURE_REASON_REDIRECT_LOOP

Too many redirects encountered (typically indicates redirect loop). Follows HTTP standard - most clients limit to 20 redirects.

WEBHOOK_FAILURE_REASON_INTEGRATION_CONFIG_ERROR

Integration configuration is invalid or missing required fields. Common causes: Integration RID not found, missing URL, invalid HMAC config.

WebhookSuccessCondition#

A webhook success condition that waits for external system approval via HTTP webhook. The step succeeds when the external system responds with 2xx status code.

Failure behavior: - 4xx responses: Permanent failure, no retry (CLIENT_ERROR) - 5xx responses: Retry with exponential backoff until max_retries (SERVER_ERROR_MAX_RETRIES_EXCEEDED) - Network errors: Retry until max_retries (NETWORK_ERROR_MAX_RETRIES_EXCEEDED) - Timeout: Retry until timeout_seconds exceeded (OVERALL_TIMEOUT_EXCEEDED) - Redirects: Followed automatically, fails if redirect loop detected (REDIRECT_LOOP)

integration_rid string

RID reference to a WebhookIntegration (the advanced integration type with HMAC signing) At least 1 character.

delivery_config WebhookDeliveryConfig

Webhook delivery configuration. If not provided, server uses documented defaults.

event_type string

Event type to send (e.g., “procedure.step_waiting”) At least 1 character.

payload_template string

JSON payload template using Handlebars syntax (https://handlebarsjs.com/) Supports variable references using {{variable_name}} syntax: - {{execution_rid}} - Procedure execution RID - {{step_id}} - Current step ID - {{step_name}} - Current step name/title - {{procedure_name}} - Procedure name - {{field_id}} - Any global form field value (e.g., {{environment}}, {{approval_level}}) - {{asset_rid}} - Asset RID if step has asset context - {{asset_name}} - Asset name if step has asset context Advanced features: - Conditionals: {{#if environment}}production mode{{/if}} - Loops: {{#each tags}}{{this}}{{/each}} - Comparisons: {{#if (eq priority “HIGH”)}}urgent{{/if}} - Default values: {{default environment “unknown”}} Example template: { “event”: “approval_required”, “execution_id”: “{{execution_rid}}”, “step”: “{{step_name}}”, “environment”: “{{environment}}”, {{#if asset_name}} “asset”: “{{asset_name}}”, {{/if}} “is_production”: {{#if (eq environment “production”)}}true{{else}}false{{/if}} } Variables that cannot be resolved will be replaced with empty string. Invalid JSON after template evaluation will cause the condition to fail with PAYLOAD_ERROR reason. At least 1 character.

Page design based on Scalar, MIT License.