Newfoundcodes.Okatana
1.0.2
dotnet add package Newfoundcodes.Okatana --version 1.0.2
NuGet\Install-Package Newfoundcodes.Okatana -Version 1.0.2
<PackageReference Include="Newfoundcodes.Okatana" Version="1.0.2" />
<PackageVersion Include="Newfoundcodes.Okatana" Version="1.0.2" />
<PackageReference Include="Newfoundcodes.Okatana" />
paket add Newfoundcodes.Okatana --version 1.0.2
#r "nuget: Newfoundcodes.Okatana, 1.0.2"
#:package Newfoundcodes.Okatana@1.0.2
#addin nuget:?package=Newfoundcodes.Okatana&version=1.0.2
#tool nuget:?package=Newfoundcodes.Okatana&version=1.0.2
<div align="center"> <img src="https://raw.githubusercontent.com/newfoundcodes/okatana/refs/heads/main/public/logo.png" width="128" /> <h1>Okatana .NET SDK</h1> <p> <a href="https://github.com/newfoundcodes/okatana-csharp-sdk/actions"><img src="https://github.com/newfoundcodes/okatana-csharp-sdk/actions/workflows/ci.yml/badge.svg" alt="Build Status"></a> </p> </div>
.NET 8 SDK for the Okatana External API v1. Provides request objects, response helpers, pagination support, typed models, explicit exception mapping, safe read retries, custom HttpClient injection, xUnit tests, and Material for MkDocs documentation.
API URL configuration
https://okatana.newfoundcodes.com is documentation. This SDK does not use it as a default API host.
Every client must receive the URL of the user's own Okatana deployment:
using Newfoundcodes.Okatana;
var client = new OkatanaClient(new OkatanaClientOptions
{
BaseUrl = "https://project-management.example.com",
ApiKey = "oka_public.secret"
});
The client accepts either a deployment origin (https://project-management.example.com) or a full v1 base (https://project-management.example.com/api/v1). Origin URLs append /api/v1 automatically.
Quick Start
Install the package via NuGet:
dotnet add package Newfoundcodes.Okatana
Then, initialize the client and make your first request:
using Newfoundcodes.Okatana;
var client = new OkatanaClient(new OkatanaClientOptions
{
BaseUrl = Environment.GetEnvironmentVariable("OKATANA_URL"),
ApiKey = Environment.GetEnvironmentVariable("OKATANA_API_KEY")
});
var organization = await client.Organizations.GetAsync(Environment.GetEnvironmentVariable("OKATANA_ORG"));
Console.WriteLine(organization.Name);
Typed request example
using Newfoundcodes.Okatana.Requests;
using Newfoundcodes.Okatana.Models;
var response = await client.Tickets.CreateAsync(
projectId,
new CreateTicketRequest
{
Title = "Validate production deployment",
BoardSlug = "open",
DescriptionHtml = "<p>Run deployment checks.</p>",
Priority = TicketPriority.High,
AssigneeIds = [operatorId],
LabelIds = [releaseLabelId]
}
);
To preserve explicit null values in PATCH operations, use OkatanaOptional:
using Newfoundcodes.Okatana.Requests;
await client.Tickets.UpdateAsync(
ticketId,
new UpdateTicketRequest
{
DescriptionHtml = null, // send JSON null
Archived = false
}
);
API services
Organizations— read organization.Projects— list/create/read/update/delete projects; members; labels; tags; analytics.Boards— list/create/update/reorder/delete boards.Tickets— list/create/reorder/read/update/delete/move/comment tickets.Documents— list/create/read/update/delete/comment documents.
Response helpers
C# async enumeration natively handles pagination metadata behind the scenes:
await foreach (var ticket in client.Projects.EnumerateTicketsAsync(projectId))
{
Console.WriteLine(ticket.Title);
}
Models retain the source object in JsonExtensionData dictionaries to preserve unknown fields.
Errors
Common Okatana statuses map to specific exceptions:
using Newfoundcodes.Okatana.Exceptions;
try
{
await client.Tickets.CreateAsync(projectId, new CreateTicketRequest { Title = "Deploy" });
}
catch (OkatanaRequestValidationException e)
{
Console.WriteLine(string.Join(", ", e.Errors.Select(err => err.Message)));
}
catch (OkatanaRateLimitException e)
{
Console.WriteLine(e.RetryAfter);
}
Retry behavior
The default policy retries safe read methods (GET, HEAD) on transport failures and transient statuses. Write requests are not retried automatically as the Okatana API lacks idempotency keys.
using Newfoundcodes.Okatana;
var client = new OkatanaClient(new OkatanaClientOptions
{
BaseUrl = Environment.GetEnvironmentVariable("OKATANA_URL"),
ApiKey = Environment.GetEnvironmentVariable("OKATANA_API_KEY"),
SafeReadRetries = 0 // Disable retries
});
Dependency Injection and HttpClient
You can provide your own HttpClient instances to control timeouts, proxies, and connection pooling, or use the ASP.NET Core DI extensions:
// Manual
var client = new OkatanaClient(myHttpClient, options);
// Dependency Injection
builder.Services.AddOkatanaClient(options);
Development
dotnet restore
dotnet test
dotnet build
Build the documentation:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
mkdocs serve
See docs/ for the complete manual and examples/ for executable scenarios.
| 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.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Http (>= 8.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.