Sovereign Platform is in pre-launch alpha.
Not yet available to purchase. Sign up for our mailing list for upcoming launch dates.
Sovereign Platform is in pre-launch alpha.
Not yet available to purchase. Sign up for our mailing list for upcoming launch dates.
If the built-in connectors do not cover a service you need, you can build your own using the Sovereign Connector SDK. A connector is a .NET project that defines actions — operations your workflows can perform against an external service.
This Page Is for Developers
This is the one documentation page that includes code. Building a connector requires .NET development experience. If you are not a developer, check whether ConnectorGen can auto-generate a connector from your service's OpenAPI specification instead.
A connector is a standalone .NET web application that:
The SDK handles registration, schema generation, and request routing. You focus on implementing the business logic for each action.
Start by creating a .NET 8 web application and adding the SDK package:
dotnet new web -n MyConnector
cd MyConnector
dotnet add reference path/to/DataWorkflows.Sdk.csproj
Create a class with the [Connector] attribute to identify your connector:
using DataWorkflows.Sdk.Attributes;
[Connector(Id = "my-service", Name = "My Service",
Description = "Connect to My Service API")]
public class MyServiceConnector { }
The Id must be unique across all connectors in your deployment. The Name and Description are displayed in the Studio's Node Palette.
Actions are the individual operations your connector provides. Each action is a class that extends WorkflowAction<T> where T is your parameters model:
using DataWorkflows.Contracts.Actions;
using DataWorkflows.Sdk.Actions;
using DataWorkflows.Sdk.Attributes;
[Action(
Type = "my-service.get-item",
DisplayName = "Get Item",
Description = "Retrieve an item by ID from My Service")]
public class GetItemAction : WorkflowAction<GetItemParameters>
{
public override string Type => "my-service.get-item";
protected override async Task<ActionExecutionResult> ExecuteAsync(
ActionExecutionContext<GetItemParameters> context,
CancellationToken ct)
{
var itemId = context.TypedParameters.ItemId;
// Call your external service here
var httpClient = context.Services.GetRequiredService<HttpClient>();
var response = await httpClient.GetAsync(
$"https://api.myservice.com/items/{itemId}", ct);
var content = await response.Content.ReadAsStringAsync(ct);
return ActionExecutionResult.Success(new Dictionary<string, object?>
{
["result"] = new { item = content }
});
}
}
public class GetItemParameters
{
[ActionField(DisplayName = "Item ID",
Description = "The unique identifier of the item to retrieve",
Required = true)]
public string ItemId { get; set; } = "";
}
Key points:
[Action] attribute defines the action type, display name, and description shown in the StudioType property must match the [Action] attribute's Type value[ActionField] attributes — the SDK generates the input schema automaticallyresult property: new { item = ... } becomes { "result": { "item": ... } }The [ActionField] attribute controls how the field appears in the Studio's Properties Panel:
public class SearchParameters
{
[ActionField(
DisplayName = "Search Query",
Description = "The text to search for",
Required = true)]
public string Query { get; set; } = "";
[ActionField(
DisplayName = "Max Results",
Description = "Maximum number of results to return",
Required = false)]
public int MaxResults { get; set; } = 10;
[ActionField(
DisplayName = "Include Archived",
Description = "Whether to include archived items in results",
Required = false)]
public bool IncludeArchived { get; set; } = false;
}
The SDK infers the field type from the C# type: string becomes a text field, int becomes a number field, bool becomes a toggle.
If your service requires authentication, your action can receive credentials through the execution context. Credentials are resolved by the Auth Service based on the user's connections (see Connecting to Services).
For services using API keys:
var apiKey = context.Parameters.TryGetValue("apiKey", out var key)
? key?.ToString() : null;
For OAuth-based services, tokens are injected automatically when the user has an active connection.
Your connector's Program.cs configures registration with the Engine and starts listening for execution requests:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddConnectorHost(builder.Configuration);
var app = builder.Build();
app.MapConnectorEndpoints();
app.Run();
Configure the registration settings in appsettings.json:
{
"ConnectorRegistration": {
"EngineUrl": "http://engine:80",
"BaseUrl": "http://my-connector:80",
"ConnectorId": "my-service"
}
}
When the connector starts, it registers its actions with the Engine. The actions then appear in the Studio's Node Palette.
Create a Dockerfile for your connector and add it to the Docker Compose configuration. The connector needs network access to the Engine (for registration) and to whatever external service it connects to.
If the service you want to connect to has an OpenAPI specification, ConnectorGen can automatically generate a connector for you. ConnectorGen analyzes the API specification and produces a complete connector project with:
This is significantly faster than building a connector from scratch and works well for standard REST APIs.
Start with ConnectorGen
If your target service publishes an OpenAPI spec, try ConnectorGen first. You can always customize the generated connector afterward if you need special behavior.
The Enterprise SDK adds additional capabilities for advanced connector scenarios, including enhanced credential resolution, license validation, and premium connector features. Connectors using Enterprise SDK extensions require corresponding capabilities enabled in your license.