DirectivSys.Sdk
1.1.0
See the version list below for details.
dotnet add package DirectivSys.Sdk --version 1.1.0
NuGet\Install-Package DirectivSys.Sdk -Version 1.1.0
<PackageReference Include="DirectivSys.Sdk" Version="1.1.0" />
<PackageVersion Include="DirectivSys.Sdk" Version="1.1.0" />
<PackageReference Include="DirectivSys.Sdk" />
paket add DirectivSys.Sdk --version 1.1.0
#r "nuget: DirectivSys.Sdk, 1.1.0"
#:package DirectivSys.Sdk@1.1.0
#addin nuget:?package=DirectivSys.Sdk&version=1.1.0
#tool nuget:?package=DirectivSys.Sdk&version=1.1.0
DirectivSys.Sdk
Official .NET SDK for DirectivSys Analytics Platform. Enables seamless integration with DirectivSys to receive AI-powered business intelligence directives and submit analytics payloads.
Features
✨ Zero Boilerplate - Automatic webhook endpoint creation
🔒 Secure by Default - Built-in authentication and validation
📦 Strongly Typed - Complete DTOs for all analytics types
🚀 Easy Submission - Fluent API for submitting analytics payloads
⚡ Async/Await - Modern async patterns throughout
Installation
dotnet add package DirectivSys.Sdk
Or via Package Manager Console:
Install-Package DirectivSys.Sdk
Quick Start
1. Configure Services (Program.cs or Startup.cs)
using DirectivSys.Sdk.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Add DirectivSys SDK
builder.Services.AddDirectivSys(options =>
{
options.ApiKey = "your-directivsys-api-key";
options.BaseUrl = "https://api.directivsys.com";
// ClientId is automatically extracted from the API Key
});
var app = builder.Build();
// Map the webhook endpoint
app.MapDirectivWebhook();
// Set up your callback to handle incoming directives
var directivSys = app.GetDirectivSys();
directivSys.OnDirectiveReceived = HandleDirective;
app.Run();
void HandleDirective(GlobalRecord record)
{
Console.WriteLine($"Received {record.Directives.Count} directives for {record.AnalyticsType}");
foreach (var directive in record.Directives.OrderBy(d => d.Priority))
{
Console.WriteLine($"[Priority {directive.Priority}] {directive.Action}");
Console.WriteLine($" Rationale: {directive.Rationale}");
// Execute your business logic based on the directive
switch (directive.Action)
{
case "reorderSupplier":
var sku = directive.Parameters["sku"].ToString();
var quantity = Convert.ToInt32(directive.Parameters["quantity"]);
// Your reorder logic here
break;
case "launchPromotion":
var targets = directive.Targets;
// Your promotion logic here
break;
}
}
}
2. Submit Analytics Data
using DirectivSys.Sdk.Models.Payloads;
using DirectivSys.Sdk.Services;
public class InventoryService
{
private readonly DirectivSysClient _client;
public InventoryService(DirectivSysClient client)
{
_client = client;
}
public async Task AnalyzeInventoryAsync()
{
var payload = new InventoryHealthPayload
{
Sku = "SKU123",
StockLevel = 20,
ReorderPoint = 50,
SafetyStock = 30,
ForecastedDemandNext30Days = 200,
AverageLeadTimeDays = 5
};
// Submit the payload for async processing
// Instructions are pre-configured in AnalyticsConfig on the backend
var response = await _client.SubmitInventoryHealthAsync(payload);
Console.WriteLine($"Payload submitted: {response.PayloadId}, Status: {response.Status}");
// Option 1: Poll for results
var result = await PollForResultAsync(response.PayloadId);
// Option 2: Process immediately (synchronous)
// var result = await _client.ProcessLatestAsync("InventoryHealth");
}
private async Task<AnalyticsResult?> PollForResultAsync(Guid payloadId, int maxAttempts = 30)
{
for (int i = 0; i < maxAttempts; i++)
{
var response = await _client.GetResultByPayloadIdAsync(payloadId);
if (response.IsComplete && response.Result != null)
{
return response.Result;
}
if (response.Status == "failed")
{
throw new Exception($"Processing failed: {response.Error}");
}
await Task.Delay(1000); // Wait 1 second before next poll
}
throw new TimeoutException("Polling timed out");
}
}
Supported Analytics Types
The SDK includes strongly-typed payload classes for all DirectivSys analytics types:
Important: Instructions for each analytics type are configured once in the AnalyticsConfig on the backend, not sent with each payload submission. Payloads contain only data - this reduces payload size and allows updating instructions without changing client code.
Supply Chain Analytics
- InventoryHealth - Stock level monitoring and reorder recommendations
- SupplierReliability - Supplier performance evaluation
- DemandForecast - Future demand prediction
- CostOptimization - Order quantity and cost optimization
E-Commerce Analytics
- CustomerSegmentation - Customer grouping by behavior and value
- CartAbandonment - Abandoned cart detection and recovery
- SalesFunnelConversion - Conversion rate tracking and optimization
- ProductPerformance - Bestseller and slow-mover identification
- CustomerLifetimeValue - Long-term customer value estimation
- MarketingROI - Campaign effectiveness measurement
API Reference
Configuration
DirectivSysOptions
public class DirectivSysOptions
{
public string ApiKey { get; set; } // Required: Your DirectivSys API Key (X-API-Key header)
public string BaseUrl { get; set; } // Default: "https://api.directivsys.com"
public Guid? ClientId { get; set; } // Optional: Extracted from API Key if not provided
public int TimeoutSeconds { get; set; } // Default: 30
}
Core Models
GlobalRecord
The main container for analytics results received via webhook:
public class GlobalRecord
{
public Guid RecordId { get; set; }
public Guid ClientId { get; set; }
public string AnalyticsType { get; set; }
public List<Directive> Directives { get; set; }
public List<Metric> Metrics { get; set; }
public List<Observation> Observations { get; set; }
public Provenance Provenance { get; set; }
public DateTime CreatedAt { get; set; }
}
Directive
Actionable recommendations from the AI agent:
public class Directive
{
public Guid DirectiveId { get; set; }
public int Priority { get; set; } // 1 = highest priority
public string Action { get; set; } // e.g., "reorderSupplier"
public Dictionary<string, object> Parameters { get; set; }
public List<string> Targets { get; set; }
public string Rationale { get; set; }
public string Status { get; set; }
}
Metric
Calculated business metrics:
public class Metric
{
public string Name { get; set; }
public double Value { get; set; }
public string Unit { get; set; }
public string Status { get; set; } // "healthy", "warning", "critical"
public string Explanation { get; set; }
}
Observation
Human-readable explanations and context:
public class Observation
{
public string Text { get; set; }
public string Severity { get; set; } // "info", "warning", "critical"
public string Scope { get; set; } // "global", "product", "supplier"
}
DirectivSysClient Methods
Submit Analytics Payloads
// Specific analytics types - Submit for async processing
Task<IngestResponse> SubmitInventoryHealthAsync(InventoryHealthPayload payload, CancellationToken cancellationToken = default)
Task<IngestResponse> SubmitCustomerSegmentationAsync(CustomerSegmentationPayload payload, CancellationToken cancellationToken = default)
Task<IngestResponse> SubmitCartAbandonmentAsync(CartAbandonmentPayload payload, CancellationToken cancellationToken = default)
Task<IngestResponse> SubmitProductPerformanceAsync(ProductPerformancePayload payload, CancellationToken cancellationToken = default)
// Generic submission for any analytics type
Task<IngestResponse> SubmitAnalyticsAsync<T>(string analyticsType, T payload, CancellationToken cancellationToken = default)
where T : AnalyticsPayloadBase
Process and Retrieve Results
// Process the latest pending payload synchronously
Task<AnalyticsResult> ProcessLatestAsync(string analyticsType, CancellationToken cancellationToken = default)
// Get result for a specific payload (for polling after async submission)
Task<PayloadResultResponse> GetResultByPayloadIdAsync(Guid payloadId, CancellationToken cancellationToken = default)
Response Models
// Response from ingestion
public class IngestResponse
{
public Guid PayloadId { get; set; }
public string Status { get; set; } // "pending"
}
// Complete analytics result
public class AnalyticsResult
{
public Guid ResultId { get; set; }
public Guid PayloadId { get; set; }
public string AnalyticsType { get; set; }
public DateTime CreatedAt { get; set; }
public string InputsSummary { get; set; }
public string InstructionSet { get; set; }
public string Provenance { get; set; }
public List<MetricResult> Metrics { get; set; }
public List<DirectiveResult> Directives { get; set; }
public List<ObservationResult> Observations { get; set; }
}
// Polling response (can be complete or status)
public class PayloadResultResponse
{
public bool IsComplete { get; set; }
public AnalyticsResult? Result { get; set; } // Available when IsComplete = true
public string? Status { get; set; } // "pending", "processing", "failed"
public string? Error { get; set; } // Available when Status = "failed"
}
Advanced Usage
Processing Patterns
The SDK supports three different processing patterns:
Pattern 1: Fire-and-Forget Ingestion
Submit payloads for async processing without waiting for results:
var response = await client.SubmitInventoryHealthAsync(payload);
// Store response.PayloadId for later retrieval if needed
Console.WriteLine($"Submitted: {response.PayloadId}");
Pattern 2: Synchronous Processing
Process immediately and get results:
// First ingest the payload
var ingestResponse = await client.SubmitInventoryHealthAsync(payload);
// Then immediately process the latest one
var result = await client.ProcessLatestAsync("InventoryHealth");
// Work with the result
foreach (var directive in result.Directives)
{
Console.WriteLine($"{directive.Action}: {directive.Rationale}");
}
Pattern 3: Async with Polling
Submit for async processing and poll until complete:
var ingestResponse = await client.SubmitInventoryHealthAsync(payload);
// Poll for results
AnalyticsResult? result = null;
int attempts = 0;
while (result == null && attempts < 30)
{
await Task.Delay(1000); // Wait 1 second
var response = await client.GetResultByPayloadIdAsync(ingestResponse.PayloadId);
if (response.IsComplete)
{
result = response.Result;
}
else if (response.Status == "failed")
{
throw new Exception($"Processing failed: {response.Error}");
}
attempts++;
}
Custom Analytics Types
For analytics types not included in the SDK, use the generic submission method:
public class CustomAnalyticsPayload : AnalyticsPayloadBase
{
public string CustomField1 { get; set; }
public int CustomField2 { get; set; }
}
var payload = new CustomAnalyticsPayload
{
CustomField1 = "value",
CustomField2 = 42
};
await client.SubmitAnalyticsAsync("CustomAnalyticsType", payload);
Accessing Services Directly
// In a controller or service
public class MyController : ControllerBase
{
private readonly DirectivSysClient _client;
private readonly IDirectivSysService _service;
public MyController(DirectivSysClient client, IDirectivSysService service)
{
_client = client;
_service = service;
// Set callback dynamically
_service.OnDirectiveReceived = HandleDirective;
}
}
Error Handling
try
{
var response = await client.SubmitInventoryHealthAsync(payload);
}
catch (DirectivSysException ex)
{
// Handle DirectivSys-specific errors
Console.WriteLine($"DirectivSys error: {ex.Message}");
}
catch (HttpRequestException ex)
{
// Handle network errors
Console.WriteLine($"Network error: {ex.Message}");
}
Configuration Best Practices
Using Configuration Files
appsettings.json:
{
"DirectivSys": {
"ApiKey": "your-api-key",
"BaseUrl": "https://api.directivsys.com",
"TimeoutSeconds": 30
}
}
Program.cs:
builder.Services.AddDirectivSys(options =>
{
builder.Configuration.GetSection("DirectivSys").Bind(options);
});
Using Environment Variables
builder.Services.AddDirectivSys(options =>
{
options.ApiKey = Environment.GetEnvironmentVariable("DIRECTIVSYS_API_KEY")
?? throw new InvalidOperationException("DIRECTIVSYS_API_KEY not set");
options.BaseUrl = Environment.GetEnvironmentVariable("DIRECTIVSYS_BASE_URL")
?? "https://api.directivsys.com";
});
Webhook Security
The webhook endpoint (/directiv/webhook) validates incoming requests using the API key. DirectivSys includes the X-API-Key header automatically when sending webhook notifications.
The validation ensures:
- Request includes
X-API-Key: {your-api-key}header - The provided key matches your configured API key
- Payload can be deserialized to
GlobalRecord
Example: Complete Integration
using DirectivSys.Sdk.Extensions;
using DirectivSys.Sdk.Models;
using DirectivSys.Sdk.Models.Payloads;
using DirectivSys.Sdk.Services;
var builder = WebApplication.CreateBuilder(args);
// Configure DirectivSys
builder.Services.AddDirectivSys(options =>
{
options.ApiKey = builder.Configuration["DirectivSys:ApiKey"]!;
options.BaseUrl = builder.Configuration["DirectivSys:BaseUrl"] ?? "https://api.directivsys.com";
});
// Add your services
builder.Services.AddControllers();
builder.Services.AddHostedService<InventoryAnalysisWorker>();
var app = builder.Build();
app.UseRouting();
app.MapControllers();
app.MapDirectivWebhook();
// Configure directive callback
var directivSys = app.GetDirectivSys();
directivSys.OnDirectiveReceived = record =>
{
var logger = app.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Received analytics: {Type} with {Count} directives",
record.AnalyticsType, record.Directives.Count);
foreach (var directive in record.Directives)
{
// Process each directive
ProcessDirective(directive, app.Services);
}
};
app.Run();
void ProcessDirective(Directive directive, IServiceProvider services)
{
var scope = services.CreateScope();
switch (directive.Action)
{
case "reorderSupplier":
var inventoryService = scope.ServiceProvider.GetRequiredService<IInventoryService>();
inventoryService.Reorder(directive.Parameters["sku"].ToString()!);
break;
case "launchPromotion":
var marketingService = scope.ServiceProvider.GetRequiredService<IMarketingService>();
marketingService.LaunchCampaign(directive.Targets);
break;
}
}
// Background worker to periodically submit analytics
public class InventoryAnalysisWorker : BackgroundService
{
private readonly DirectivSysClient _client;
private readonly ILogger<InventoryAnalysisWorker> _logger;
public InventoryAnalysisWorker(DirectivSysClient client, ILogger<InventoryAnalysisWorker> logger)
{
_client = client;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
// Aggregate your data
var inventoryData = await GetCurrentInventoryAsync();
// Submit to DirectivSys
await _client.SubmitInventoryHealthAsync(inventoryData, stoppingToken);
_logger.LogInformation("Inventory analysis submitted successfully");
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to submit inventory analysis");
}
// Run daily
await Task.Delay(TimeSpan.FromHours(24), stoppingToken);
}
}
private async Task<InventoryHealthPayload> GetCurrentInventoryAsync()
{
// Your logic to aggregate inventory data
return new InventoryHealthPayload
{
Sku = "SKU123",
StockLevel = 45,
ReorderPoint = 50,
SafetyStock = 30,
ForecastedDemandNext30Days = 200
};
}
}
Requirements
- .NET 6.0 or higher
- ASP.NET Core application (for webhook endpoint)
Support
For issues, questions, or feature requests, please visit:
- GitHub Issues: https://github.com/directivsys/directivsys-sdk-dotnet/issues
- Documentation: https://docs.directivsys.com
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Made with ❤️ by DirectivSys Inc
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Microsoft.Extensions.Http (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.2.9 | 144 | 4/21/2026 |
| 1.2.8 | 147 | 4/10/2026 |
| 1.2.7 | 129 | 3/14/2026 |
| 1.2.6 | 131 | 3/9/2026 |
| 1.2.5 | 118 | 3/9/2026 |
| 1.2.4 | 108 | 3/8/2026 |
| 1.2.3 | 116 | 3/7/2026 |
| 1.2.1 | 318 | 2/4/2026 |
| 1.2.0 | 161 | 2/2/2026 |
| 1.1.9 | 136 | 2/1/2026 |
| 1.1.8 | 134 | 2/1/2026 |
| 1.1.7 | 137 | 2/1/2026 |
| 1.1.6 | 142 | 1/31/2026 |
| 1.1.5 | 150 | 1/20/2026 |
| 1.1.4 | 129 | 1/20/2026 |
| 1.1.3 | 126 | 1/19/2026 |
| 1.1.2 | 137 | 1/19/2026 |
| 1.1.1 | 135 | 1/18/2026 |
| 1.1.0 | 134 | 1/10/2026 |
| 1.0.1 | 138 | 1/9/2026 |