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_ridsarray of stringAt most 100 items.
Response: BatchGetDataConnectorsResponse
data_connectorsarray ofDataConnector
Fields of
DataConnectordata_connector_ridstring
namestring
descriptionstring
connection_detailsDataConnectorDetailsSecrets
Fields of
DataConnectorDetailsSecretsopc_uaOpcUaConnectorDetailsSecret
Fields of
OpcUaConnectorDetailsSecreturistring
authentication_configOpcAuthenticationConfigSecret
Fields of
OpcAuthenticationConfigSecret- one of
anonymous,username_password,token
anonymousobject
username_passwordOpcUsernamePasswordAuthenticationSecret
Fields of
OpcUsernamePasswordAuthenticationSecretusernamestring
passwordstring
tokenOpcTokenAuthenticationSecret
Fields of
OpcTokenAuthenticationSecrettokenstring
- one of
scraping_configOpcUaScrapingConfig
Fields of
OpcUaScrapingConfignode_exploration_configOpcUaNodeExplorationConfig
Fields of
OpcUaNodeExplorationConfig- one of
opc_ua_traversal_config,opc_ua_direct_node_subscription
opc_ua_traversal_configOpcUaTraversalConfig
Fields of
OpcUaTraversalConfigroot_nodesarray ofOpcNodeRoot 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
OpcNodenamespaceinteger (int64)
identifierOpcIdentifierValue
Fields of
OpcIdentifierValue- one of
numeric,string
- one of
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/CreateDataConnectorCreates a new data connector configuration
Request:
CreateDataConnectorRequestnamestring required
descriptionstring
connection_detailsDataConnectorDetailsrequired
Fields of
DataConnectorDetailsopc_uaOpcUaConnectorDetails
Fields of
OpcUaConnectorDetailsuristring required
authentication_configOpcAuthenticationConfigrequired
Fields of
OpcAuthenticationConfig- one of
anonymous,username_password,tokenrequired
anonymousobject
username_passwordOpcUsernamePasswordAuthentication
Fields of
OpcUsernamePasswordAuthenticationusernamestring required
passwordstring required
tokenOpcTokenAuthentication
Fields of
OpcTokenAuthenticationtokenstring required
- one of
scraping_configOpcUaScrapingConfigrequired
Fields of
OpcUaScrapingConfignode_exploration_configOpcUaNodeExplorationConfigrequired
Fields of
OpcUaNodeExplorationConfig- one of
opc_ua_traversal_config,opc_ua_direct_node_subscriptionrequired
opc_ua_traversal_configOpcUaTraversalConfig
Fields of
OpcUaTraversalConfigroot_nodesarray ofOpcNodeRoot 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
OpcNodenamespaceinteger (int64)
identifierOpcIdentifierValuerequired
Fields of
OpcIdentifierValue- one of
numeric,stringrequired
numericinteger
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/DeleteDataConnectorDeletes a data connector. This operation is idempotent.
Request:
DeleteDataConnectorRequestdata_connector_ridstring required
Response:
DeleteDataConnectorResponseA 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/GetDataConnectorGets the settings for a data connector
Request:
GetDataConnectorRequestdata_connector_ridstring
Response:
GetDataConnectorResponsedata_connectorDataConnector
Fields of
DataConnectordata_connector_ridstring
namestring
descriptionstring
connection_detailsDataConnectorDetailsSecrets
Fields of
DataConnectorDetailsSecretsopc_uaOpcUaConnectorDetailsSecret
Fields of
OpcUaConnectorDetailsSecreturistring
authentication_configOpcAuthenticationConfigSecret
Fields of
OpcAuthenticationConfigSecret- one of
anonymous,username_password,token
anonymousobject
username_passwordOpcUsernamePasswordAuthenticationSecret
Fields of
OpcUsernamePasswordAuthenticationSecretusernamestring
passwordstring
tokenOpcTokenAuthenticationSecret
Fields of
OpcTokenAuthenticationSecrettokenstring
- one of
scraping_configOpcUaScrapingConfig
Fields of
OpcUaScrapingConfignode_exploration_configOpcUaNodeExplorationConfig
Fields of
OpcUaNodeExplorationConfig- one of
opc_ua_traversal_config,opc_ua_direct_node_subscription
opc_ua_traversal_configOpcUaTraversalConfig
Fields of
OpcUaTraversalConfigroot_nodesarray ofOpcNodeRoot 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
OpcNodenamespaceinteger (int64)
identifierOpcIdentifierValue
Fields of
OpcIdentifierValue- one of
numeric,string
- one of
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/GetSessionStatusGets the session status for a connection
Request:
GetSessionStatusRequestdata_connector_ridstring required
Response:
GetSessionStatusResponse- one of
none,active
noneobject
activeActiveSessionStatus
Fields of
ActiveSessionStatusreplica_statusarray ofReplicaStatus
Values of
ReplicaStatusREPLICA_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": {} }
Search#
gRPC
/nominal.data_connector.v1.DataConnectorService/SearchList the data connectors matching the search criteria. The JSON transcoder ranks literal path segments above
/{...}template captures, so the literal/searchroute wins over the/{data_connector_rid}template regardless of declaration order.Request:
SearchRequestworkspace_ridstring required
filterSearchFilterrequired
Fields of
SearchFilter- one of
name,description,target_dataset,andrequired
nameNameFilter
Fields of
NameFilternamestring required
descriptionDescriptionFilter
Fields of
DescriptionFilterdescriptionstring required
target_datasetTargetDatasetFilter
Fields of
TargetDatasetFiltertarget_dataset_ridstring required
andAndFilter
Fields of
AndFilterclausesarray ofSearchFilter
- one of
page_sizeintegerIf unspecified, defaults to 100
page_tokenstring
sort_bySortByrequired
Response:
SearchResponsedata_connectorsarray ofDataConnector
Fields of
DataConnectordata_connector_ridstring
namestring
descriptionstring
connection_detailsDataConnectorDetailsSecrets
Fields of
DataConnectorDetailsSecretsopc_uaOpcUaConnectorDetailsSecret
Fields of
OpcUaConnectorDetailsSecreturistring
authentication_configOpcAuthenticationConfigSecret
Fields of
OpcAuthenticationConfigSecret- one of
anonymous,username_password,token
anonymousobject
username_passwordOpcUsernamePasswordAuthenticationSecret
Fields of
OpcUsernamePasswordAuthenticationSecretusernamestring
passwordstring
tokenOpcTokenAuthenticationSecret
Fields of
OpcTokenAuthenticationSecrettokenstring
- one of
scraping_configOpcUaScrapingConfig
Fields of
OpcUaScrapingConfignode_exploration_configOpcUaNodeExplorationConfig
Fields of
OpcUaNodeExplorationConfig- one of
opc_ua_traversal_config,opc_ua_direct_node_subscription
opc_ua_traversal_configOpcUaTraversalConfig
Fields of
OpcUaTraversalConfigroot_nodesarray ofOpcNodeRoot 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
OpcNodenamespaceinteger (int64)
identifierOpcIdentifierValue
Fields of
OpcIdentifierValue- one of
numeric,string
- one of
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.SearchRequest( workspace_rid="<workspace rid>", filter={"name": {"name": "<name>"}}, sort_by={"field": "SORT_FIELD_UPDATED_AT", "order": "SORT_ORDER_ASC"}, ) response = data_connector_service.Search(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.SearchRequest{ WorkspaceRid: "<workspace rid>", Filter: &data_connectorv1.SearchFilter{ Filter: &data_connectorv1.SearchFilter_Name{Name: &data_connectorv1.NameFilter{ Name: "<name>", }}, }, SortBy: &data_connectorv1.SortBy{ Field: data_connectorv1.SortField_SORT_FIELD_UPDATED_AT, Order: data_connectorv1.SortOrder_SORT_ORDER_ASC, }, } response, err := dataConnectorService.Search(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" } ], "page_token": "<page token>" }
Start session#
gRPC
/nominal.data_connector.v1.DataConnectorService/StartSessionStarts a session for a connection
Request:
StartSessionRequestdata_connector_ridstring required
Response:
StartSessionResponseA 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/StopSessionStops a session for a connection
Request:
StopSessionRequestdata_connector_ridstring required
Response:
StopSessionResponseA 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/UpdateDataConnectorUpdates 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 placeconnection_detailscan travel — and it keeps connector credentials out of URLs, which proxy and CDN access logs retain.Request:
UpdateDataConnectorRequestdata_connector_ridstring required
namestring
descriptionstring
connection_detailsDataConnectorDetailsUpdates
Fields of
DataConnectorDetailsUpdatesopc_uaOpcUaConnectorDetailsUpdates
Fields of
OpcUaConnectorDetailsUpdatesuristring
authentication_configOpcAuthenticationConfig
Fields of
OpcAuthenticationConfig- one of
anonymous,username_password,tokenrequired
anonymousobject
username_passwordOpcUsernamePasswordAuthentication
Fields of
OpcUsernamePasswordAuthenticationusernamestring required
passwordstring required
tokenOpcTokenAuthentication
Fields of
OpcTokenAuthenticationtokenstring required
- one of
scraping_configOpcUaScrapingConfigUpdates
Fields of
OpcUaScrapingConfigUpdatesnode_exploration_configOpcUaNodeExplorationConfig
Fields of
OpcUaNodeExplorationConfig- one of
opc_ua_traversal_config,opc_ua_direct_node_subscriptionrequired
opc_ua_traversal_configOpcUaTraversalConfig
Fields of
OpcUaTraversalConfigroot_nodesarray ofOpcNodeRoot 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
OpcNodenamespaceinteger (int64)
identifierOpcIdentifierValuerequired
Fields of
OpcIdentifierValue- one of
numeric,stringrequired
numericinteger
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_ARGUMENTDATA_CONNECTOR_ERROR_TYPE_TARGET_DATASET_NOT_IN_WORKSPACEData connector not found
NOT_FOUNDDATA_CONNECTOR_ERROR_TYPE_CONNECTOR_NOT_FOUNDData connector not found
PERMISSION_DENIEDDATA_CONNECTOR_ERROR_TYPE_CONNECTOR_NOT_AUTHORIZEDData connector not found
Types#
ActiveSessionStatus#
replica_statusarray ofReplicaStatus
AndFilter#
clausesarray ofSearchFilter
DataConnector#
A configured data connector
data_connector_ridstring
namestring
descriptionstring
connection_detailsDataConnectorDetailsSecrets
workspace_ridstring
target_dataset_ridstring
created_atstring (date-time)
DataConnectorDetails#
Union type for different data connector types
opc_uaOpcUaConnectorDetails
DataConnectorDetailsSecrets#
Union type for different data connector types with secrets
opc_uaOpcUaConnectorDetailsSecret
DataConnectorDetailsUpdates#
opc_uaOpcUaConnectorDetailsUpdates
DescriptionFilter#
descriptionstring required
NameFilter#
namestring required
OpcAuthenticationConfig#
Authentication configuration for OPC-UA server connection
Set exactly one of the fields below.
- one of
anonymous,username_password,tokenrequired
anonymousobject
username_passwordOpcUsernamePasswordAuthentication
tokenOpcTokenAuthentication
OpcAuthenticationConfigSecret#
Authentication configuration for OPC-UA server connection with secrets
Set exactly one of the fields below.
- one of
anonymous,username_password,tokenrequired
anonymousobject
username_passwordOpcUsernamePasswordAuthenticationSecret
tokenOpcTokenAuthenticationSecret
OpcIdentifierValue#
The identifier field for an OPC-UA node
Set exactly one of the fields below.
- one of
numeric,stringrequired
numericinteger
stringstring
OpcNode#
An OPC-UA node
namespaceinteger (int64)
identifierOpcIdentifierValuerequired
OpcTokenAuthentication#
tokenstring required
OpcTokenAuthenticationSecret#
tokenstring
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_pathrequired
node_idOpcUaNodeIdFor example, “NodeId{ns=3;i=1010}”
browse_nameOpcUaBrowseNameThe “name” field under the “BrowseName” attribute
display_nameOpcUaDisplayNameThe “text” field under the “DisplayName” attribute
full_pathOpcUaFullPathThe 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
uristring required
authentication_configOpcAuthenticationConfigrequired
scraping_configOpcUaScrapingConfigrequired
OpcUaConnectorDetailsSecret#
Configuration for connecting to an OPC-UA server with secrets
uristring
authentication_configOpcAuthenticationConfigSecret
scraping_configOpcUaScrapingConfig
OpcUaConnectorDetailsUpdates#
Updated configuration for connecting to an OPC-UA server
uristring
authentication_configOpcAuthenticationConfig
scraping_configOpcUaScrapingConfigUpdates
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
subscriptionOpcUaSubscriptionConfigUse OPC-UA subscriptions to receive data changes pushed from the server
pollingOpcUaPollingConfigPeriodically poll the server for current node values
OpcUaDataChangeFilter#
triggerOpcUaDataChangeTriggerThe trigger for the data change filter.
deadband_typeOpcUaDeadbandType
deadband_valuenumber
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#
nodesarray ofOpcNodeAt 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_nodesarray ofOpcNodeWe will build path up to any of these nodes, or the Objects folder.
delimiterstringCustom delimiter for path separation. Defaults to “/” if not specified.
array_tag_namesarray of stringArray 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_subscriptionrequired
opc_ua_traversal_configOpcUaTraversalConfig
opc_ua_direct_node_subscriptionOpcUaDirectNodeSubscription
OpcUaNodeId#
A message with no fields.
OpcUaPollingConfig#
Configuration for polling-based data acquisition
polling_interval_msinteger (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.
offsetstring (date-time)
OpcUaScrapingConfig#
Configuration for determining how data is discovered and handled
Polling mode can only be used with server time.
node_exploration_configOpcUaNodeExplorationConfigrequired
unit_node_namestring requiredThe browse name of the node under which the unit is stored for the nodes we scrape.
channel_naming_conventionOpcUaChannelNamingConventionrequired
override_hostboolean requiredIf 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_handlingOpcUaUnknownDataTypeHandlingrequiredHow we will handle unknown data types when we read them from the server
failed_monitor_handlingOpcUaFailedMonitorHandlingdeprecatedDeprecated: Use data_acquisition_config.subscription.failed_monitor_handling instead.
timestamp_handlingOpcUaTimestampHandlingrequiredWhat timestamps should we write for the channels?
data_change_filterOpcUaDataChangeFilterdeprecatedDeprecated: Use data_acquisition_config.subscription.data_change_filter instead.
data_acquisition_configOpcUaDataAcquisitionConfigConfiguration 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_configOpcUaNodeExplorationConfig
unit_node_namestringThe browse name of the node under which the unit is stored for the nodes we scrape.
channel_naming_conventionOpcUaChannelNamingConvention
override_hostbooleanIf 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_handlingOpcUaUnknownDataTypeHandlingHow we will handle unknown data types when we read them from the server
failed_monitor_handlingOpcUaFailedMonitorHandlingdeprecatedDeprecated: Use data_acquisition_config.subscription.failed_monitor_handling instead.
timestamp_handlingOpcUaTimestampHandlingWhat timestamps should we write for the channels?
data_change_filterOpcUaDataChangeFilterdeprecatedDeprecated: Use data_acquisition_config.subscription.data_change_filter instead.
data_acquisition_configOpcUaDataAcquisitionConfigConfiguration 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_handlingOpcUaFailedMonitorHandlingrequiredHow to handle situations where there are failed monitors.
data_change_filterOpcUaDataChangeFilterrequiredThe 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,relativerequired
OpcUaTraversalConfig#
root_nodesarray ofOpcNodeRoot 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_nodesarray ofOpcNodeWe will not subscribe to any of these nodes.
reference_exploration_typeOpcUaReferenceExplorationTyperequiredThe 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_ERRORIf we encounter an unknown data type, we will error out
OPC_UA_UNKNOWN_DATA_TYPE_HANDLING_TREAT_AS_DOUBLEIf we encounter an unknown data type, we will assume it is a double
OPC_UA_UNKNOWN_DATA_TYPE_HANDLING_TREAT_AS_STRINGIf we encounter an unknown data type, we will assume it is a string
OpcUsernamePasswordAuthentication#
usernamestring required
passwordstring required
OpcUsernamePasswordAuthenticationSecret#
usernamestring required
passwordstring
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,andrequired
SortBy#
SortField#
SORT_FIELD_UNSPECIFIED
SORT_FIELD_UPDATED_AT
SortOrder#
SORT_ORDER_UNSPECIFIED
SORT_ORDER_ASC
SORT_ORDER_DESC
TargetDatasetFilter#
target_dataset_ridstring required
Page design based on Scalar, MIT License.
- one of
- one of
- one of
- one of
- one of
- one of
- one of