← Back to tracks
System Integrator Integration
Build bespoke compliance solutions for your clients. Set up OAuth apps, onboard legal entities, configure processing routes, and monitor everything via webhooks.
1
Register an OAuth 2.0 app
Create an OAuth application for server-to-server or user-facing integrations.
using Semansys.CompliancePlatform.Client;
var client = new CompliancePlatformClient("https://api.semansys.com", apiKey);
var app = await client.OAuth.RegisterAppAsync(new RegisterOAuthAppRequest
{
AppName = "Acme Integration Hub",
RedirectUris = new[] { "https://integration.acme.com/callback" },
GrantTypes = new[] { "authorization_code", "client_credentials" },
Scopes = new[] { "documents:write", "entities:manage", "routes:manage" }
});
Console.WriteLine($"Client ID: {app.ClientId}");
Console.WriteLine($"Client Secret: {app.ClientSecret}");2
Onboard a legal entity
Register your client with their business identifiers and jurisdiction defaults.
var entity = await client.LegalEntities.CreateAsync(new CreateLegalEntityRequest
{
Name = "Client Corp B.V.",
Jurisdiction = "NL",
Identifiers = new[]
{
new IdentifierRequest { Type = "kvk", Value = "12345678" },
new IdentifierRequest { Type = "vat", Value = "NL123456789B01" },
new IdentifierRequest { Type = "peppol", Value = "0106:12345678" }
},
Defaults = new EntityDefaults
{
PreferredDeliveryChannel = "peppol",
PreferredValidationProfile = "si-ubl-2.0"
}
});
Console.WriteLine($"Legal Entity ID: {entity.LegalEntityId}");3
Configure a processing route
Define how documents are validated, converted, and delivered.
var route = await client.Routes.CreateAsync(new CreateRouteRequest
{
LegalEntityId = entity.LegalEntityId,
Name = "Standard NL Invoice Route",
Trigger = "ApiSubmit",
Stages = new[]
{
new StageRequest { Steps = new[] { new StepRequest { Type = "Validate", Config = new { Profile = "si-ubl-2.0" } } } },
new StageRequest { Steps = new[] { new StepRequest { Type = "Convert", Config = new { TargetFormat = "ubl" } }, new StepRequest { Type = "Convert", Config = new { TargetFormat = "pdf" } } } },
new StageRequest { Steps = new[] { new StepRequest { Type = "Deliver", Config = new { Channel = "peppol" } } } }
}
});
Console.WriteLine($"Route ID: {route.RouteId}");4
Submit a document through the configured route
Send a document on behalf of your client through the configured pipeline.
var result = await client.Documents.CreateAsync(new CreateDocumentRequest
{
SenderLegalEntityId = entity.LegalEntityId,
Receiver = new ReceiverRef { Identifier = "0106:87654321" },
Content = new SsmContent { Kind = "ssm", Ssm = new SsmInvoice { InvoiceNumber = "SI-2026-001", IssueDate = "2026-03-16", CurrencyCode = "EUR" } }
});
Console.WriteLine($"Document ID: {result.DocumentId}");5
Monitor via webhooks
Subscribe to lifecycle events and verify webhook signatures.
var webhook = await client.Webhooks.RegisterAsync(new RegisterWebhookRequest
{
Url = "https://integration.acme.com/webhooks/semansys",
EventTypes = new[] { "document.created.v1", "document.validated.v1", "document.sent.v1", "document.delivery.failed.v1", "route.completed.v1", "route.failed.v1" }
});
app.MapPost("/einvoicing/webhooks/semansys", async (HttpContext ctx) =>
{
var isValid = WebhookVerifier.Verify(
ctx.Request.Headers["X-Semansys-Signature"],
await new StreamReader(ctx.Request.Body).ReadToEndAsync(),
webhook.SigningSecret);
if (!isValid) return Results.Unauthorized();
return Results.Ok();
});