Data connector service (gRPC)#

Service for managing data connectors to external data sources.

Endpoints#

Batch get data connectors#

gRPC /nominal.data_connector.v1.DataConnectorService/BatchGetDataConnectors

Gets the settings for a batch of data connectors. Connectors in workspaces the caller lacks workspace:view on are omitted rather than failing the call.

Request: BatchGetDataConnectorsRequest

data_connector_rids array of string

At most 100 items.

Response: BatchGetDataConnectorsResponse

data_connectors array of DataConnector

​

Fields of DataConnector
data_connector_rid string

​

name string

​

description string

​

connection_details DataConnectorDetailsSecrets

​

Fields of DataConnectorDetailsSecrets
opc_ua OpcUaConnectorDetailsSecret

​

Fields of OpcUaConnectorDetailsSecret
uri string

​

authentication_config OpcAuthenticationConfigSecret

​

Fields of OpcAuthenticationConfigSecret
one of anonymous, username_password, token

​

anonymous object

​

username_password OpcUsernamePasswordAuthenticationSecret

​

Fields of OpcUsernamePasswordAuthenticationSecret
username string

​

password string

​

token OpcTokenAuthenticationSecret

​

Fields of OpcTokenAuthenticationSecret
token string

​

scraping_config OpcUaScrapingConfig

​

Fields of OpcUaScrapingConfig
node_exploration_config OpcUaNodeExplorationConfig

​

Fields of OpcUaNodeExplorationConfig
one of opc_ua_traversal_config, opc_ua_direct_node_subscription

​

opc_ua_traversal_config OpcUaTraversalConfig

​

Fields of OpcUaTraversalConfig
root_nodes array of OpcNode

Root nodes to start traversing for variable nodes. For each node specified here, we will recursively traverse child nodes until there are none left. If empty, defaults to starting from the objects folder node NodeId{ns=0;i=85}

Fields of OpcNode
namespace integer (int64)

​

identifier OpcIdentifierValue

​

Fields of OpcIdentifierValue
one of numeric, string

Request

import grpc
from nominal.protos.data_connector.v1 import data_connector_pb2, data_connector_pb2_grpc

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

request = data_connector_pb2.BatchGetDataConnectorsRequest(
    data_connector_rids=["<data connector rids>"],
)
response = data_connector_service.BatchGetDataConnectors(request, metadata=auth)
print(response)
package main

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

	data_connectorv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/data_connector/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()
	dataConnectorService := data_connectorv1.NewDataConnectorServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &data_connectorv1.BatchGetDataConnectorsRequest{
		DataConnectorRids: []string{
			"<data connector rids>",
		},
	}
	response, err := dataConnectorService.BatchGetDataConnectors(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "data_connectors": [
    {
      "data_connector_rid": "<data connector rid>",
      "name": "<name>",
      "description": "<description>",
      "connection_details": {
        "opc_ua": {
          "uri": "<uri>",
          "authentication_config": {
            "anonymous": {}
          },
          "scraping_config": {
            "node_exploration_config": {
              "opc_ua_traversal_config": {
                "root_nodes": [
                  {
                    "namespace": 1,
                    "identifier": {
                      "numeric": 1
                    }
                  }
                ],
                "skip_nodes": [
                  {
                    "namespace": 1,
                    "identifier": {
                      "numeric": 1
                    }
                  }
                ],
                "reference_exploration_type": "OPC_UA_REFERENCE_EXPLORATION_TYPE_ORGANIZES"
              }
            },
            "unit_node_name": "<unit node name>",
            "channel_naming_convention": {
              "node_id": {}
            },
            "override_host": true,
            "unknown_data_type_handling": "OPC_UA_UNKNOWN_DATA_TYPE_HANDLING_ERROR",
            "failed_monitor_handling": "OPC_UA_FAILED_MONITOR_HANDLING_ERROR",
            "timestamp_handling": {
              "server": {}
            },
            "data_change_filter": {
              "trigger": "OPC_UA_DATA_CHANGE_TRIGGER_STATUS_ONLY",
              "deadband_type": "OPC_UA_DEADBAND_TYPE_NONE",
              "deadband_value": 1
            },
            "data_acquisition_config": {
              "subscription": {
                "failed_monitor_handling": "OPC_UA_FAILED_MONITOR_HANDLING_ERROR",
                "data_change_filter": {
                  "trigger": "OPC_UA_DATA_CHANGE_TRIGGER_STATUS_ONLY",
                  "deadband_type": "OPC_UA_DEADBAND_TYPE_NONE",
                  "deadband_value": 1
                }
              }
            }
          }
        }
      },
      "workspace_rid": "<workspace rid>",
      "target_dataset_rid": "<target dataset rid>",
      "created_at": "2026-01-01T00:00:00Z"
    }
  ]
}

Create data connector#

gRPC /nominal.data_connector.v1.DataConnectorService/CreateDataConnector

Creates a new data connector configuration

Request: CreateDataConnectorRequest

name string required

​

description string

​

connection_details DataConnectorDetails required

​

Fields of DataConnectorDetails
opc_ua OpcUaConnectorDetails

​

Fields of OpcUaConnectorDetails
uri string required

​

authentication_config OpcAuthenticationConfig required

​

Fields of OpcAuthenticationConfig
one of anonymous, username_password, token required

​

anonymous object

​

username_password OpcUsernamePasswordAuthentication

​

Fields of OpcUsernamePasswordAuthentication
username string required

​

password string required

​

token OpcTokenAuthentication

​

Fields of OpcTokenAuthentication
token string required

​

scraping_config OpcUaScrapingConfig required

​

Fields of OpcUaScrapingConfig
node_exploration_config OpcUaNodeExplorationConfig required

​

Fields of OpcUaNodeExplorationConfig
one of opc_ua_traversal_config, opc_ua_direct_node_subscription required

​

opc_ua_traversal_config OpcUaTraversalConfig

​

Fields of OpcUaTraversalConfig
root_nodes array of OpcNode

Root nodes to start traversing for variable nodes. For each node specified here, we will recursively traverse child nodes until there are none left. If empty, defaults to starting from the objects folder node NodeId{ns=0;i=85}

Fields of OpcNode
namespace integer (int64)

​

identifier OpcIdentifierValue required

​

Fields of OpcIdentifierValue
one of numeric, string required

​

numeric integer

Request

import grpc
from nominal.protos.data_connector.v1 import data_connector_pb2, data_connector_pb2_grpc

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

request = data_connector_pb2.CreateDataConnectorRequest(
    name="<name>",
    connection_details={
        "opc_ua": {
            "uri": "<uri>",
            "authentication_config": {"anonymous": {}},
            "scraping_config": {
                "node_exploration_config": {
                    "opc_ua_traversal_config": {
                        "reference_exploration_type": "OPC_UA_REFERENCE_EXPLORATION_TYPE_ORGANIZES",
                    },
                },
                "unit_node_name": "<unit node name>",
                "channel_naming_convention": {"node_id": {}},
                "override_host": True,
                "unknown_data_type_handling": "OPC_UA_UNKNOWN_DATA_TYPE_HANDLING_ERROR",
                "timestamp_handling": {"server": {}},
            },
        },
    },
    workspace_rid="<workspace rid>",
    target_dataset_rid="<target dataset rid>",
)
response = data_connector_service.CreateDataConnector(request, metadata=auth)
print(response)
package main

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

	data_connectorv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/data_connector/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
	"google.golang.org/protobuf/types/known/emptypb"
)

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()
	dataConnectorService := data_connectorv1.NewDataConnectorServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &data_connectorv1.CreateDataConnectorRequest{
		Name: "<name>",
		ConnectionDetails: &data_connectorv1.DataConnectorDetails{
			DataConnectorDetails: &data_connectorv1.DataConnectorDetails_OpcUa{OpcUa: &data_connectorv1.OpcUaConnectorDetails{
				Uri: "<uri>",
				AuthenticationConfig: &data_connectorv1.OpcAuthenticationConfig{
					OpcAuthenticationConfig: &data_connectorv1.OpcAuthenticationConfig_Anonymous{Anonymous: &emptypb.Empty{}},
				},
				ScrapingConfig: &data_connectorv1.OpcUaScrapingConfig{
					NodeExplorationConfig: &data_connectorv1.OpcUaNodeExplorationConfig{
						OpcUaNodeExplorationConfig: &data_connectorv1.OpcUaNodeExplorationConfig_OpcUaTraversalConfig{OpcUaTraversalConfig: &data_connectorv1.OpcUaTraversalConfig{
							ReferenceExplorationType: data_connectorv1.OpcUaReferenceExplorationType_OPC_UA_REFERENCE_EXPLORATION_TYPE_ORGANIZES,
						}},
					},
					UnitNodeName: "<unit node name>",
					ChannelNamingConvention: &data_connectorv1.OpcUaChannelNamingConvention{
						NamingConvention: &data_connectorv1.OpcUaChannelNamingConvention_NodeId{NodeId: &data_connectorv1.OpcUaChannelNamingConvention_OpcUaNodeId{}},
					},
					OverrideHost:            true,
					UnknownDataTypeHandling: data_connectorv1.OpcUaUnknownDataTypeHandling_OPC_UA_UNKNOWN_DATA_TYPE_HANDLING_ERROR,
					TimestampHandling: &data_connectorv1.OpcUaTimestampHandling{
						TimestampType: &data_connectorv1.OpcUaTimestampHandling_Server{Server: &data_connectorv1.OpcUaTimestampHandling_OpcUaServerTime{}},
					},
				},
			}},
		},
		WorkspaceRid:     "<workspace rid>",
		TargetDatasetRid: "<target dataset rid>",
	}
	response, err := dataConnectorService.CreateDataConnector(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "data_connector": {
    "data_connector_rid": "<data connector rid>",
    "name": "<name>",
    "description": "<description>",
    "connection_details": {
      "opc_ua": {
        "uri": "<uri>",
        "authentication_config": {
          "anonymous": {}
        },
        "scraping_config": {
          "node_exploration_config": {
            "opc_ua_traversal_config": {
              "root_nodes": [
                {
                  "namespace": 1,
                  "identifier": {
                    "numeric": 1
                  }
                }
              ],
              "skip_nodes": [
                {
                  "namespace": 1,
                  "identifier": {
                    "numeric": 1
                  }
                }
              ],
              "reference_exploration_type": "OPC_UA_REFERENCE_EXPLORATION_TYPE_ORGANIZES"
            }
          },
          "unit_node_name": "<unit node name>",
          "channel_naming_convention": {
            "node_id": {}
          },
          "override_host": true,
          "unknown_data_type_handling": "OPC_UA_UNKNOWN_DATA_TYPE_HANDLING_ERROR",
          "failed_monitor_handling": "OPC_UA_FAILED_MONITOR_HANDLING_ERROR",
          "timestamp_handling": {
            "server": {}
          },
          "data_change_filter": {
            "trigger": "OPC_UA_DATA_CHANGE_TRIGGER_STATUS_ONLY",
            "deadband_type": "OPC_UA_DEADBAND_TYPE_NONE",
            "deadband_value": 1
          },
          "data_acquisition_config": {
            "subscription": {
              "failed_monitor_handling": "OPC_UA_FAILED_MONITOR_HANDLING_ERROR",
              "data_change_filter": {
                "trigger": "OPC_UA_DATA_CHANGE_TRIGGER_STATUS_ONLY",
                "deadband_type": "OPC_UA_DEADBAND_TYPE_NONE",
                "deadband_value": 1
              }
            }
          }
        }
      }
    },
    "workspace_rid": "<workspace rid>",
    "target_dataset_rid": "<target dataset rid>",
    "created_at": "2026-01-01T00:00:00Z"
  }
}

Delete data connector#

gRPC /nominal.data_connector.v1.DataConnectorService/DeleteDataConnector

Deletes a data connector. This operation is idempotent.

Request: DeleteDataConnectorRequest

data_connector_rid string required

​

Response: DeleteDataConnectorResponse

A message with no fields.

Request

import grpc
from nominal.protos.data_connector.v1 import data_connector_pb2, data_connector_pb2_grpc

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

request = data_connector_pb2.DeleteDataConnectorRequest(
    data_connector_rid="<data connector rid>",
)
response = data_connector_service.DeleteDataConnector(request, metadata=auth)
print(response)
package main

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

	data_connectorv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/data_connector/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()
	dataConnectorService := data_connectorv1.NewDataConnectorServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &data_connectorv1.DeleteDataConnectorRequest{
		DataConnectorRid: "<data connector rid>",
	}
	response, err := dataConnectorService.DeleteDataConnector(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{}

Get data connector#

gRPC /nominal.data_connector.v1.DataConnectorService/GetDataConnector

Gets the settings for a data connector

Request: GetDataConnectorRequest

data_connector_rid string

​

Response: GetDataConnectorResponse

data_connector DataConnector

​

Fields of DataConnector
data_connector_rid string

​

name string

​

description string

​

connection_details DataConnectorDetailsSecrets

​

Fields of DataConnectorDetailsSecrets
opc_ua OpcUaConnectorDetailsSecret

​

Fields of OpcUaConnectorDetailsSecret
uri string

​

authentication_config OpcAuthenticationConfigSecret

​

Fields of OpcAuthenticationConfigSecret
one of anonymous, username_password, token

​

anonymous object

​

username_password OpcUsernamePasswordAuthenticationSecret

​

Fields of OpcUsernamePasswordAuthenticationSecret
username string

​

password string

​

token OpcTokenAuthenticationSecret

​

Fields of OpcTokenAuthenticationSecret
token string

​

scraping_config OpcUaScrapingConfig

​

Fields of OpcUaScrapingConfig
node_exploration_config OpcUaNodeExplorationConfig

​

Fields of OpcUaNodeExplorationConfig
one of opc_ua_traversal_config, opc_ua_direct_node_subscription

​

opc_ua_traversal_config OpcUaTraversalConfig

​

Fields of OpcUaTraversalConfig
root_nodes array of OpcNode

Root nodes to start traversing for variable nodes. For each node specified here, we will recursively traverse child nodes until there are none left. If empty, defaults to starting from the objects folder node NodeId{ns=0;i=85}

Fields of OpcNode
namespace integer (int64)

​

identifier OpcIdentifierValue

​

Fields of OpcIdentifierValue
one of numeric, string

Request

import grpc
from nominal.protos.data_connector.v1 import data_connector_pb2, data_connector_pb2_grpc

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

request = data_connector_pb2.GetDataConnectorRequest(
    data_connector_rid="<data connector rid>",
)
response = data_connector_service.GetDataConnector(request, metadata=auth)
print(response)
package main

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

	data_connectorv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/data_connector/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()
	dataConnectorService := data_connectorv1.NewDataConnectorServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &data_connectorv1.GetDataConnectorRequest{
		DataConnectorRid: "<data connector rid>",
	}
	response, err := dataConnectorService.GetDataConnector(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "data_connector": {
    "data_connector_rid": "<data connector rid>",
    "name": "<name>",
    "description": "<description>",
    "connection_details": {
      "opc_ua": {
        "uri": "<uri>",
        "authentication_config": {
          "anonymous": {}
        },
        "scraping_config": {
          "node_exploration_config": {
            "opc_ua_traversal_config": {
              "root_nodes": [
                {
                  "namespace": 1,
                  "identifier": {
                    "numeric": 1
                  }
                }
              ],
              "skip_nodes": [
                {
                  "namespace": 1,
                  "identifier": {
                    "numeric": 1
                  }
                }
              ],
              "reference_exploration_type": "OPC_UA_REFERENCE_EXPLORATION_TYPE_ORGANIZES"
            }
          },
          "unit_node_name": "<unit node name>",
          "channel_naming_convention": {
            "node_id": {}
          },
          "override_host": true,
          "unknown_data_type_handling": "OPC_UA_UNKNOWN_DATA_TYPE_HANDLING_ERROR",
          "failed_monitor_handling": "OPC_UA_FAILED_MONITOR_HANDLING_ERROR",
          "timestamp_handling": {
            "server": {}
          },
          "data_change_filter": {
            "trigger": "OPC_UA_DATA_CHANGE_TRIGGER_STATUS_ONLY",
            "deadband_type": "OPC_UA_DEADBAND_TYPE_NONE",
            "deadband_value": 1
          },
          "data_acquisition_config": {
            "subscription": {
              "failed_monitor_handling": "OPC_UA_FAILED_MONITOR_HANDLING_ERROR",
              "data_change_filter": {
                "trigger": "OPC_UA_DATA_CHANGE_TRIGGER_STATUS_ONLY",
                "deadband_type": "OPC_UA_DEADBAND_TYPE_NONE",
                "deadband_value": 1
              }
            }
          }
        }
      }
    },
    "workspace_rid": "<workspace rid>",
    "target_dataset_rid": "<target dataset rid>",
    "created_at": "2026-01-01T00:00:00Z"
  }
}

Get session status#

gRPC /nominal.data_connector.v1.DataConnectorService/GetSessionStatus

Gets the session status for a connection

Request: GetSessionStatusRequest

data_connector_rid string required

​

Response: GetSessionStatusResponse

one of none, active

​

none object

​

active ActiveSessionStatus

​

Fields of ActiveSessionStatus
replica_status array of ReplicaStatus

​

Values of ReplicaStatus
REPLICA_STATUS_UNSPECIFIED

​

REPLICA_STATUS_STARTING

​

REPLICA_STATUS_SUBSCRIBING

​

REPLICA_STATUS_RUNNING

​

REPLICA_STATUS_STOPPING

​

REPLICA_STATUS_STOPPED

​

Request

import grpc
from nominal.protos.data_connector.v1 import data_connector_pb2, data_connector_pb2_grpc

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

request = data_connector_pb2.GetSessionStatusRequest(
    data_connector_rid="<data connector rid>",
)
response = data_connector_service.GetSessionStatus(request, metadata=auth)
print(response)
package main

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

	data_connectorv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/data_connector/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()
	dataConnectorService := data_connectorv1.NewDataConnectorServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &data_connectorv1.GetSessionStatusRequest{
		DataConnectorRid: "<data connector rid>",
	}
	response, err := dataConnectorService.GetSessionStatus(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "none": {}
}

Start session#

gRPC /nominal.data_connector.v1.DataConnectorService/StartSession

Starts a session for a connection

Request: StartSessionRequest

data_connector_rid string required

​

Response: StartSessionResponse

A message with no fields.

Request

import grpc
from nominal.protos.data_connector.v1 import data_connector_pb2, data_connector_pb2_grpc

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

request = data_connector_pb2.StartSessionRequest(
    data_connector_rid="<data connector rid>",
)
response = data_connector_service.StartSession(request, metadata=auth)
print(response)
package main

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

	data_connectorv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/data_connector/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()
	dataConnectorService := data_connectorv1.NewDataConnectorServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &data_connectorv1.StartSessionRequest{
		DataConnectorRid: "<data connector rid>",
	}
	response, err := dataConnectorService.StartSession(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{}

Stop session#

gRPC /nominal.data_connector.v1.DataConnectorService/StopSession

Stops a session for a connection

Request: StopSessionRequest

data_connector_rid string required

​

Response: StopSessionResponse

A message with no fields.

Request

import grpc
from nominal.protos.data_connector.v1 import data_connector_pb2, data_connector_pb2_grpc

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

request = data_connector_pb2.StopSessionRequest(
    data_connector_rid="<data connector rid>",
)
response = data_connector_service.StopSession(request, metadata=auth)
print(response)
package main

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

	data_connectorv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/data_connector/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()
	dataConnectorService := data_connectorv1.NewDataConnectorServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &data_connectorv1.StopSessionRequest{
		DataConnectorRid: "<data connector rid>",
	}
	response, err := dataConnectorService.StopSession(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{}

Update data connector#

gRPC /nominal.data_connector.v1.DataConnectorService/UpdateDataConnector

Updates the settings for a data connector. body: "*" is required here. google.api.http routes fields outside the path and body to the query string, which has no spelling for a message field, so the body is the only place connection_details can travel — and it keeps connector credentials out of URLs, which proxy and CDN access logs retain.

Request: UpdateDataConnectorRequest

data_connector_rid string required

​

name string

​

description string

​

connection_details DataConnectorDetailsUpdates

​

Fields of DataConnectorDetailsUpdates
opc_ua OpcUaConnectorDetailsUpdates

​

Fields of OpcUaConnectorDetailsUpdates
uri string

​

authentication_config OpcAuthenticationConfig

​

Fields of OpcAuthenticationConfig
one of anonymous, username_password, token required

​

anonymous object

​

username_password OpcUsernamePasswordAuthentication

​

Fields of OpcUsernamePasswordAuthentication
username string required

​

password string required

​

token OpcTokenAuthentication

​

Fields of OpcTokenAuthentication
token string required

​

scraping_config OpcUaScrapingConfigUpdates

​

Fields of OpcUaScrapingConfigUpdates
node_exploration_config OpcUaNodeExplorationConfig

​

Fields of OpcUaNodeExplorationConfig
one of opc_ua_traversal_config, opc_ua_direct_node_subscription required

​

opc_ua_traversal_config OpcUaTraversalConfig

​

Fields of OpcUaTraversalConfig
root_nodes array of OpcNode

Root nodes to start traversing for variable nodes. For each node specified here, we will recursively traverse child nodes until there are none left. If empty, defaults to starting from the objects folder node NodeId{ns=0;i=85}

Fields of OpcNode
namespace integer (int64)

​

identifier OpcIdentifierValue required

​

Fields of OpcIdentifierValue
one of numeric, string required

​

numeric integer

Request

import grpc
from nominal.protos.data_connector.v1 import data_connector_pb2, data_connector_pb2_grpc

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

request = data_connector_pb2.UpdateDataConnectorRequest(
    data_connector_rid="<data connector rid>",
)
response = data_connector_service.UpdateDataConnector(request, metadata=auth)
print(response)
package main

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

	data_connectorv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/data_connector/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()
	dataConnectorService := data_connectorv1.NewDataConnectorServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &data_connectorv1.UpdateDataConnectorRequest{
		DataConnectorRid: "<data connector rid>",
	}
	response, err := dataConnectorService.UpdateDataConnector(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "data_connector": {
    "data_connector_rid": "<data connector rid>",
    "name": "<name>",
    "description": "<description>",
    "connection_details": {
      "opc_ua": {
        "uri": "<uri>",
        "authentication_config": {
          "anonymous": {}
        },
        "scraping_config": {
          "node_exploration_config": {
            "opc_ua_traversal_config": {
              "root_nodes": [
                {
                  "namespace": 1,
                  "identifier": {
                    "numeric": 1
                  }
                }
              ],
              "skip_nodes": [
                {
                  "namespace": 1,
                  "identifier": {
                    "numeric": 1
                  }
                }
              ],
              "reference_exploration_type": "OPC_UA_REFERENCE_EXPLORATION_TYPE_ORGANIZES"
            }
          },
          "unit_node_name": "<unit node name>",
          "channel_naming_convention": {
            "node_id": {}
          },
          "override_host": true,
          "unknown_data_type_handling": "OPC_UA_UNKNOWN_DATA_TYPE_HANDLING_ERROR",
          "failed_monitor_handling": "OPC_UA_FAILED_MONITOR_HANDLING_ERROR",
          "timestamp_handling": {
            "server": {}
          },
          "data_change_filter": {
            "trigger": "OPC_UA_DATA_CHANGE_TRIGGER_STATUS_ONLY",
            "deadband_type": "OPC_UA_DEADBAND_TYPE_NONE",
            "deadband_value": 1
          },
          "data_acquisition_config": {
            "subscription": {
              "failed_monitor_handling": "OPC_UA_FAILED_MONITOR_HANDLING_ERROR",
              "data_change_filter": {
                "trigger": "OPC_UA_DATA_CHANGE_TRIGGER_STATUS_ONLY",
                "deadband_type": "OPC_UA_DEADBAND_TYPE_NONE",
                "deadband_value": 1
              }
            }
          }
        }
      }
    },
    "workspace_rid": "<workspace rid>",
    "target_dataset_rid": "<target dataset rid>",
    "created_at": "2026-01-01T00:00:00Z"
  }
}

Errors#

Errors shows how these errors are sent.

Code

Reason

Message

INVALID_ARGUMENT

DATA_CONNECTOR_ERROR_TYPE_TARGET_DATASET_NOT_IN_WORKSPACE

Data connector not found

NOT_FOUND

DATA_CONNECTOR_ERROR_TYPE_CONNECTOR_NOT_FOUND

Data connector not found

PERMISSION_DENIED

DATA_CONNECTOR_ERROR_TYPE_CONNECTOR_NOT_AUTHORIZED

Data connector not found

Types#

ActiveSessionStatus#

replica_status array of ReplicaStatus

​

AndFilter#

clauses array of SearchFilter

​

DataConnector#

A configured data connector

data_connector_rid string

​

name string

​

description string

​

connection_details DataConnectorDetailsSecrets

​

workspace_rid string

​

target_dataset_rid string

​

created_at string (date-time)

​

DataConnectorDetails#

Union type for different data connector types

opc_ua OpcUaConnectorDetails

​

DataConnectorDetailsSecrets#

Union type for different data connector types with secrets

opc_ua OpcUaConnectorDetailsSecret

​

DataConnectorDetailsUpdates#

opc_ua OpcUaConnectorDetailsUpdates

​

DescriptionFilter#

description string required

​

NameFilter#

name string required

​

OpcAuthenticationConfig#

Authentication configuration for OPC-UA server connection

Set exactly one of the fields below.

one of anonymous, username_password, token required

​

anonymous object

​

username_password OpcUsernamePasswordAuthentication

​

OpcAuthenticationConfigSecret#

Authentication configuration for OPC-UA server connection with secrets

Set exactly one of the fields below.

one of anonymous, username_password, token required

​

anonymous object

​

OpcIdentifierValue#

The identifier field for an OPC-UA node

Set exactly one of the fields below.

one of numeric, string required

​

numeric integer

​

string string

​

OpcNode#

An OPC-UA node

namespace integer (int64)

​

identifier OpcIdentifierValue required

​

OpcTokenAuthentication#

token string required

​

OpcTokenAuthenticationSecret#

token string

​

OpcUaBrowseName#

A message with no fields.

OpcUaChannelNamingConvention#

How do you want to map the names of OPC-UA nodes to Nominal channels?

Set exactly one of the fields below.

one of node_id, browse_name, display_name, full_path required

​

node_id OpcUaNodeId

For example, “NodeId{ns=3;i=1010}”

browse_name OpcUaBrowseName

The “name” field under the “BrowseName” attribute

display_name OpcUaDisplayName

The “text” field under the “DisplayName” attribute

full_path OpcUaFullPath

The full path of the node, separated by a delimiter. Use this setting for creating the hierarchical prefix tree.

OpcUaConnectorDetails#

Configuration for connecting to an OPC-UA server

uri string required

​

authentication_config OpcAuthenticationConfig required

​

scraping_config OpcUaScrapingConfig required

​

OpcUaConnectorDetailsSecret#

Configuration for connecting to an OPC-UA server with secrets

uri string

​

authentication_config OpcAuthenticationConfigSecret

​

scraping_config OpcUaScrapingConfig

​

OpcUaConnectorDetailsUpdates#

Updated configuration for connecting to an OPC-UA server

uri string

​

authentication_config OpcAuthenticationConfig

​

scraping_config OpcUaScrapingConfigUpdates

​

OpcUaDataAcquisitionConfig#

Configuration for how data should be acquired from the OPC-UA server

Set at most one of the fields below.

one of subscription, polling

​

subscription OpcUaSubscriptionConfig

Use OPC-UA subscriptions to receive data changes pushed from the server

polling OpcUaPollingConfig

Periodically poll the server for current node values

OpcUaDataChangeFilter#

trigger OpcUaDataChangeTrigger

The trigger for the data change filter.

deadband_type OpcUaDeadbandType

​

deadband_value number

​

OpcUaDataChangeTrigger#

OPC_UA_DATA_CHANGE_TRIGGER_UNSPECIFIED

​

OPC_UA_DATA_CHANGE_TRIGGER_STATUS_ONLY

​

OPC_UA_DATA_CHANGE_TRIGGER_STATUS_VALUE

​

OPC_UA_DATA_CHANGE_TRIGGER_STATUS_VALUE_TIMESTAMP

​

OpcUaDeadbandType#

OPC_UA_DEADBAND_TYPE_UNSPECIFIED

​

OPC_UA_DEADBAND_TYPE_NONE

​

OPC_UA_DEADBAND_TYPE_ABSOLUTE

​

OPC_UA_DEADBAND_TYPE_PERCENT

​

OpcUaDirectNodeSubscription#

nodes array of OpcNode

At least 1 item.

OpcUaDisplayName#

A message with no fields.

OpcUaFailedMonitorHandling#

OPC_UA_FAILED_MONITOR_HANDLING_UNSPECIFIED

​

OPC_UA_FAILED_MONITOR_HANDLING_ERROR

​

OPC_UA_FAILED_MONITOR_HANDLING_IGNORE

​

OpcUaFullPath#

Configuration for full path naming convention

root_nodes array of OpcNode

We will build path up to any of these nodes, or the Objects folder.

delimiter string

Custom delimiter for path separation. Defaults to “/” if not specified.

array_tag_names array of string

Array TagNames to extract out of the path. For example, if the path is “/airplane/wing[1]/drag”, specifying the TagName “wing” would represent this with the channel “/airplane/drag” with “wing”:”1” as a tag.

OpcUaNodeExplorationConfig#

Set exactly one of the fields below.

one of opc_ua_traversal_config, opc_ua_direct_node_subscription required

​

opc_ua_traversal_config OpcUaTraversalConfig

​

opc_ua_direct_node_subscription OpcUaDirectNodeSubscription

​

OpcUaNodeId#

A message with no fields.

OpcUaPollingConfig#

Configuration for polling-based data acquisition

polling_interval_ms integer (uint64)

The interval between polls in milliseconds. Defaults to 1000ms if not specified.

OpcUaReferenceExplorationType#

OPC_UA_REFERENCE_EXPLORATION_TYPE_UNSPECIFIED

​

OPC_UA_REFERENCE_EXPLORATION_TYPE_ORGANIZES

​

OPC_UA_REFERENCE_EXPLORATION_TYPE_HIERARCHICAL_REFERENCES

​

OpcUaRelativeTimestamp#

Use the server timestamp, but add an optional offset. By default, the offset will be the time now. This is useful for when the server starts at an epoch time of 0.

offset string (date-time)

​

OpcUaScrapingConfig#

Configuration for determining how data is discovered and handled

Polling mode can only be used with server time.

node_exploration_config OpcUaNodeExplorationConfig required

​

unit_node_name string required

The browse name of the node under which the unit is stored for the nodes we scrape.

channel_naming_convention OpcUaChannelNamingConvention required

​

override_host boolean required

If true, we will override the host and port of the OPC UA server with the host and port of the original server URL.

unknown_data_type_handling OpcUaUnknownDataTypeHandling required

How we will handle unknown data types when we read them from the server

failed_monitor_handling OpcUaFailedMonitorHandling deprecated

Deprecated: Use data_acquisition_config.subscription.failed_monitor_handling instead.

timestamp_handling OpcUaTimestampHandling required

What timestamps should we write for the channels?

data_change_filter OpcUaDataChangeFilter deprecated

Deprecated: Use data_acquisition_config.subscription.data_change_filter instead.

data_acquisition_config OpcUaDataAcquisitionConfig

Configuration for how data should be acquired from the server. If not specified, defaults to subscription mode using the deprecated fields above.

OpcUaScrapingConfigUpdates#

Updated configuration for determining how data is discovered and handled

Polling mode can only be used with server time.

node_exploration_config OpcUaNodeExplorationConfig

​

unit_node_name string

The browse name of the node under which the unit is stored for the nodes we scrape.

channel_naming_convention OpcUaChannelNamingConvention

​

override_host boolean

If true, we will override the host and port of the OPC UA server with the host and port of the original server URL.

unknown_data_type_handling OpcUaUnknownDataTypeHandling

How we will handle unknown data types when we read them from the server

failed_monitor_handling OpcUaFailedMonitorHandling deprecated

Deprecated: Use data_acquisition_config.subscription.failed_monitor_handling instead.

timestamp_handling OpcUaTimestampHandling

What timestamps should we write for the channels?

data_change_filter OpcUaDataChangeFilter deprecated

Deprecated: Use data_acquisition_config.subscription.data_change_filter instead.

data_acquisition_config OpcUaDataAcquisitionConfig

Configuration for how data should be acquired from the server.

OpcUaServerTime#

Use the server timestamp https://reference.opcfoundation.org/Core/Part4/v104/docs/7.7.4

A message with no fields.

OpcUaSourceTime#

Use the source timestamp https://reference.opcfoundation.org/Core/Part4/v104/docs/7.7.3

A message with no fields.

OpcUaSubscriptionConfig#

Configuration for subscription-based data acquisition

failed_monitor_handling OpcUaFailedMonitorHandling required

How to handle situations where there are failed monitors.

data_change_filter OpcUaDataChangeFilter required

The data change filter to be applied for the monitored items in the subscription.

OpcUaTimestampHandling#

Set exactly one of the fields below.

one of server, source, relative required

​

server OpcUaServerTime

​

source OpcUaSourceTime

​

OpcUaTraversalConfig#

root_nodes array of OpcNode

Root nodes to start traversing for variable nodes. For each node specified here, we will recursively traverse child nodes until there are none left. If empty, defaults to starting from the objects folder node NodeId{ns=0;i=85}

skip_nodes array of OpcNode

We will not subscribe to any of these nodes.

reference_exploration_type OpcUaReferenceExplorationType required

The type of references that we will follow when traversing the root nodes in the OPC UA server.

OpcUaUnknownDataTypeHandling#

OPC_UA_UNKNOWN_DATA_TYPE_HANDLING_UNSPECIFIED

​

OPC_UA_UNKNOWN_DATA_TYPE_HANDLING_ERROR

If we encounter an unknown data type, we will error out

OPC_UA_UNKNOWN_DATA_TYPE_HANDLING_TREAT_AS_DOUBLE

If we encounter an unknown data type, we will assume it is a double

OPC_UA_UNKNOWN_DATA_TYPE_HANDLING_TREAT_AS_STRING

If we encounter an unknown data type, we will assume it is a string

OpcUsernamePasswordAuthentication#

username string required

​

password string required

​

OpcUsernamePasswordAuthenticationSecret#

username string required

​

password string

​

ReplicaStatus#

REPLICA_STATUS_UNSPECIFIED

​

REPLICA_STATUS_STARTING

​

REPLICA_STATUS_SUBSCRIBING

​

REPLICA_STATUS_RUNNING

​

REPLICA_STATUS_STOPPING

​

REPLICA_STATUS_STOPPED

​

SearchFilter#

Set exactly one of the fields below.

one of name, description, target_dataset, and required

​

name NameFilter

​

description DescriptionFilter

​

target_dataset TargetDatasetFilter

​

and AndFilter

​

SortBy#

field SortField

If unspecified, defaults to SORT_FIELD_UPDATE_AT

order SortOrder

If unspecified, defaults to SORT_ORDER_DESC

SortField#

SORT_FIELD_UNSPECIFIED

​

SORT_FIELD_UPDATED_AT

​

SortOrder#

SORT_ORDER_UNSPECIFIED

​

SORT_ORDER_ASC

​

SORT_ORDER_DESC

​

TargetDatasetFilter#

target_dataset_rid string required

​

Page design based on Scalar, MIT License.