Served.SDK 1.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Served.SDK --version 1.2.0
                    
NuGet\Install-Package Served.SDK -Version 1.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Served.SDK" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Served.SDK" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Served.SDK" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Served.SDK --version 1.2.0
                    
#r "nuget: Served.SDK, 1.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Served.SDK@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Served.SDK&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Served.SDK&version=1.2.0
                    
Install as a Cake Tool

Served.SDK

NuGet

The official .NET SDK for the Served API. This library provides a strongly-typed, modern fluent client for interacting with the Served platform, covering Project Management, Task Tracking, Time Registration, Finance, DevOps, and more.

Features

  • Module-Based API: Organized access through domain modules (e.g., client.ProjectManagement.Projects).
  • Generic & Abstract: Built on reusable base classes for consistent CRUD operations.
  • Strongly Typed: Full type safety for all Served entities (Projects, Tasks, Invoices, etc.).
  • Modern Async: Built from the ground up with async/await.
  • Bulk Operations: Support for batch create, update, and delete operations.
  • Error Handling: Custom ServedApiException provides detailed error context.
  • Backwards Compatible: Legacy client access patterns still supported.
  • Tracing & Observability: Built-in OpenTelemetry support with Forge platform integration.

Installation

dotnet add package Served.SDK

Getting Started

Initialization

Initialize the ServedClient with your API URL, Token, and optional Tenant context.

using Served.SDK.Client;

var client = new ServedClient(
    baseUrl: "https://app.served.dk",
    token: "YOUR_API_TOKEN",
    tenant: "YOUR_TENANT_SLUG" // Optional header context
);

Dependency Injection

For ASP.NET Core applications:

services.AddHttpClient<IServedClient, ServedClient>(client =>
{
    client.BaseAddress = new Uri("https://app.served.dk");
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "TOKEN");
});

API Structure

The SDK organizes APIs into domain modules for better discoverability:

Module Resources Description
ProjectManagement Projects, Tasks Project and task management
DevOpsModule Repositories, PullRequests, Pipelines DevOps integration
FinanceModule Invoices Invoice management
SalesModule Pipelines, Deals Sales pipeline and deals
Registration TimeRegistrations Time tracking
Companies Customers Customer management
Identity Employees, ApiKeys User and API key management
Calendar Agreements Appointments and agreements
Board Boards, Sheets Kanban boards
Reporting Dashboards, Datasources Reports and dashboards
Tenant Tenants, Workspaces Multi-tenant management
Bootstrap - Application initialization

Usage Examples

// Project Management
var projects = await client.ProjectManagement.Projects.GetAllAsync();
var tasks = await client.ProjectManagement.Tasks.GetByProjectAsync(123);

// Time Registration
var registrations = await client.Registration.TimeRegistrations.GetByDateRangeAsync(
    "2024-01-01", "2024-01-31");

// Calendar
var agreements = await client.Calendar.Agreements.GetByCustomerAsync(456);

// DevOps
var repos = await client.DevOpsModule.Repositories.GetAllAsync();
var pipelines = await client.DevOpsModule.Pipelines.GetByRepositoryAsync(789);

Projects

Manage projects with the client.ProjectManagement.Projects resource.

using Served.SDK.Models.Projects;

// 1. List Projects (with filtering)
var projects = await client.ProjectManagement.Projects.GetAllAsync(new ProjectQueryParams
{
    CustomerId = 123,
    IsActive = true,
    Take = 50
});

// 2. Get Project Details
var project = await client.ProjectManagement.Projects.GetAsync(projectId: 1);
Console.WriteLine($"Project: {project.Name} (#{project.ProjectNo})");

// 3. Create a Project
var newProject = await client.ProjectManagement.Projects.CreateAsync(new CreateProjectRequest
{
    Name = "New Website Launch",
    StartDate = DateTime.UtcNow,
    EndDate = DateTime.UtcNow.AddMonths(3),
    CustomerId = 123
});

// 4. Update Project
await client.ProjectManagement.Projects.UpdateAsync(newProject.Id, new UpdateProjectRequest
{
    Description = "Updated description",
    Progress = 50
});

// 5. Delete Project
await client.ProjectManagement.Projects.DeleteAsync(projectId: 1);

// 6. Bulk Operations
var bulkResult = await client.ProjectManagement.Projects.CreateBulkAsync(new BulkCreateProjectsRequest
{
    Projects = new List<CreateProjectRequest>
    {
        new() { Name = "Project A", CustomerId = 1 },
        new() { Name = "Project B", CustomerId = 1 }
    }
});

Tasks

Manage tasks with client.ProjectManagement.Tasks.

using Served.SDK.Models.Tasks;

// 1. List Tasks (with filtering)
var tasks = await client.ProjectManagement.Tasks.GetAllAsync(new TaskQueryParams
{
    ProjectId = project.Id,
    IncludeCompleted = false,
    Take = 50
});

// 2. Get Task Details
var task = await client.ProjectManagement.Tasks.GetAsync(taskId: 1);

// 3. Create a Task
var newTask = await client.ProjectManagement.Tasks.CreateAsync(new CreateTaskRequest
{
    Name = "Design Homepage",
    ProjectId = project.Id,
    DueDate = DateTime.UtcNow.AddDays(7),
    Priority = TaskPriority.High
});

// 4. Update Task
await client.ProjectManagement.Tasks.UpdateAsync(newTask.Id, new UpdateTaskRequest
{
    Description = "Create mockups for homepage",
    Status = TaskStatus.InProgress
});

// 5. Update Task Status
await client.ProjectManagement.Tasks.UpdateStatusAsync(newTask.Id, new UpdateTaskStatusRequest
{
    Status = TaskStatus.Completed
});

// 6. Get Tasks by Project
var projectTasks = await client.ProjectManagement.Tasks.GetByProjectAsync(project.Id);

// 7. Bulk Status Update
await client.ProjectManagement.Tasks.UpdateStatusBulkAsync(new BulkUpdateTaskStatusRequest
{
    Ids = new List<int> { 1, 2, 3 },
    Status = TaskStatus.Completed
});

Time Registration

Log hours using client.Registration.TimeRegistrations.

using Served.SDK.Models.TimeRegistration;

// 1. Create Time Registration
var registration = await client.Registration.TimeRegistrations.CreateAsync(new CreateTimeRegistrationRequest
{
    TaskId = task.Id,
    ProjectId = project.Id,
    Start = DateTime.UtcNow.AddHours(-2),
    End = DateTime.UtcNow,
    Minutes = 120,
    Description = "Worked on design mockups",
    Billable = true
});

// 2. Get Time Registrations by Project
var registrations = await client.Registration.TimeRegistrations.GetByProjectAsync(project.Id);

// 3. Get Time Registrations by Date Range
var weekRegistrations = await client.Registration.TimeRegistrations.GetByDateRangeAsync(
    "2024-01-01", "2024-01-07");

// 4. Get Time Registrations by Employee
var myRegistrations = await client.Registration.TimeRegistrations.GetByEmployeeAsync(employeeId: 123);

// 5. Bulk Create
await client.Registration.TimeRegistrations.CreateBulkAsync(new BulkCreateTimeRegistrationsRequest
{
    Items = new List<CreateTimeRegistrationRequest>
    {
        new() { ProjectId = 1, Minutes = 60, Description = "Meeting" },
        new() { ProjectId = 1, Minutes = 120, Description = "Development" }
    }
});

Customers

Manage customers with client.Companies.Customers.

using Served.SDK.Models.Customers;

// 1. List Customers
var customers = await client.Companies.Customers.GetAllAsync(new CustomerQueryParams
{
    IsActive = true,
    CustomerType = CustomerType.Company
});

// 2. Create Customer
var customer = await client.Companies.Customers.CreateAsync(new CreateCustomerRequest
{
    Name = "Acme Corporation",
    Email = "contact@acme.com",
    CustomerType = CustomerType.Company
});

// 3. Search Customers
var results = await client.Companies.Customers.SearchAsync("Acme");

Calendar (Agreements)

Manage appointments with client.Calendar.Agreements.

using Served.SDK.Models.Agreements;

// 1. Get Agreements by Date Range
var appointments = await client.Calendar.Agreements.GetByDateRangeAsync(
    DateTime.Today, DateTime.Today.AddDays(7));

// 2. Create Agreement
var agreement = await client.Calendar.Agreements.CreateAsync(new CreateAgreementRequest
{
    Title = "Project Kickoff Meeting",
    StartDate = DateTime.UtcNow.AddDays(1),
    EndDate = DateTime.UtcNow.AddDays(1).AddHours(2),
    CustomerId = customer.Id
});

// 3. Get Agreements by Customer
var customerMeetings = await client.Calendar.Agreements.GetByCustomerAsync(customer.Id);

DevOps

Access DevOps integrations with client.DevOpsModule.

using Served.SDK.Models.DevOps;

// 1. List Repositories
var repos = await client.DevOpsModule.Repositories.GetAllAsync();

// 2. Get Pull Requests
var pullRequests = await client.DevOpsModule.PullRequests.GetByRepositoryAsync(repoId: 1);

// 3. Get Pipelines
var pipelines = await client.DevOpsModule.Pipelines.GetByRepositoryAsync(repoId: 1);

Finance (Invoices)

Access invoice data with client.FinanceModule.

using Served.SDK.Models.Finance;

// Get invoice keys and fetch details
var invoiceKeys = await client.FinanceModule.Invoices.GetKeysAsync(new InvoiceQueryParams
{
    Take = 10
});
var invoices = await client.FinanceModule.Invoices.GetRangeAsync(invoiceKeys);

foreach (var invoice in invoices)
{
    Console.WriteLine($"Invoice #{invoice.InvoiceNo}: {invoice.Amount:C} ({invoice.StatusName})");
}

Identity (Employees & API Keys)

Manage users and API keys with client.Identity.

using Served.SDK.Models.Users;
using Served.SDK.Models.ApiKeys;

// Get Employees
var employees = await client.Identity.Employees.GetAllAsync();

// Manage API Keys
var apiKeys = await client.Identity.ApiKeys.GetAllAsync();
var newKey = await client.Identity.ApiKeys.CreateAsync(new CreateApiKeyRequest
{
    Name = "CI/CD Integration",
    Scopes = new List<string> { "projects:read", "tasks:write" }
});

Legacy Access (Backwards Compatible)

The original flat client access is still supported:

// Legacy access pattern (still works)
var projects = await client.Projects.GetAllAsync();
var tasks = await client.Tasks.GetAllAsync();
var customers = await client.Customers.GetAllAsync();

Error Handling

The SDK throws ServedApiException for non-success HTTP status codes.

try
{
    await client.ProjectManagement.Projects.GetAsync(99999);
}
catch (ServedApiException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
    Console.WriteLine("Project not found.");
}
catch (ServedApiException ex)
{
    Console.WriteLine($"API Error: {ex.StatusCode} - {ex.Content}");
}

Tracing & Observability

The SDK includes built-in tracing with OpenTelemetry support and Forge platform integration.

Quick Start

// Enable tracing with environment auto-detection
var client = new ServedClient("https://api.served.dk", token)
    .EnableTracing();

// Or use the builder pattern for full control
var client = new ServedClientBuilder()
    .WithBaseUrl("https://api.served.dk")
    .WithToken(token)
    .WithTenant("my-workspace")
    .WithTracing(options =>
    {
        options.ServiceName = "my-application";
        options.EnableForge = true;
        options.SamplingRate = 0.1; // Sample 10% of requests
    })
    .Build();

Environment Variables

Variable Description Default
SERVED_TRACING_ENABLED Enable/disable tracing false
SERVED_SERVICE_NAME Service identifier served-sdk-client
SERVED_SERVICE_VERSION Service version SDK version
SERVED_ENVIRONMENT Environment name development
FORGE_API_KEY Forge platform API key -
OTEL_EXPORTER_OTLP_ENDPOINT OTLP collector endpoint -
SERVED_SAMPLING_RATE Request sampling rate (0.0-1.0) 1.0

Custom Events

// Record custom telemetry events
client.Tracer?.RecordEvent(new TelemetryEvent
{
    Type = TelemetryEventType.Custom,
    Name = "invoice.generated",
    Attributes = new Dictionary<string, object>
    {
        ["invoice.id"] = invoiceId,
        ["invoice.amount"] = amount
    }
});

Manual Spans

// Create custom spans for complex operations
using var span = client.Tracer?.StartSpan("batch-import");
span?.SetAttribute("batch.size", items.Count);

foreach (var item in items)
{
    await ProcessItemAsync(item);
}

Architecture

Core Components

  • IHttpClient: Interface for HTTP operations used by all API clients.
  • ApiClientBase<TEntity, TDetail, TCreate, TUpdate, TQuery>: Generic base class for CRUD operations.
  • BulkApiClientBase: Extended base class with bulk operation support.
  • ApiModuleBase: Base class for organizing related resources into modules.

Project Structure

Served.SDK/
├── Client/
│   ├── Core/
│   │   ├── IHttpClient.cs          # HTTP operations interface
│   │   ├── IApiClient.cs           # Generic API client interfaces
│   │   ├── ApiClientBase.cs        # Abstract CRUD implementation
│   │   └── ApiModuleBase.cs        # Module grouping base class
│   ├── Apis/
│   │   ├── ProjectManagementApi.cs # Projects & Tasks
│   │   ├── DevOpsApi.cs            # Repositories, PRs, Pipelines
│   │   ├── FinanceApi.cs           # Invoices
│   │   ├── SalesApi.cs             # Sales Pipelines & Deals
│   │   ├── RegistrationApi.cs      # Time Registration
│   │   ├── CompaniesApi.cs         # Customers
│   │   ├── IdentityApi.cs          # Employees & API Keys
│   │   ├── CalendarApi.cs          # Agreements
│   │   ├── BoardApi.cs             # Boards & Sheets
│   │   ├── ReportingApi.cs         # Dashboards & Datasources
│   │   ├── TenantApi.cs            # Tenants & Workspaces
│   │   └── BootstrapApi.cs         # Initialization
│   ├── Resources/                   # Legacy resource clients
│   ├── ServedClient.cs             # Main client implementation
│   └── IServedClient.cs            # Client interface
└── Models/
    ├── Projects/
    ├── Tasks/
    ├── TimeRegistration/
    ├── Customers/
    ├── Agreements/
    ├── Finance/
    ├── DevOps/
    └── Common/

Support

For issues, please open a ticket on the GitHub Repository.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.4.0 132 1/29/2026
1.2.0 119 1/17/2026
1.1.0 118 1/13/2026
1.0.0 235 12/21/2025

v1.2.0: Added MCP utilities (ToolArgs, ResponseFormatter, DocumentParser, DictToolArgs) for consistent parameter parsing and markdown response formatting. Reduces token usage in AI interactions.