Octavia.CmsSDK 0.3.0

dotnet add package Octavia.CmsSDK --version 0.3.0
                    
NuGet\Install-Package Octavia.CmsSDK -Version 0.3.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="Octavia.CmsSDK" Version="0.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Octavia.CmsSDK" Version="0.3.0" />
                    
Directory.Packages.props
<PackageReference Include="Octavia.CmsSDK" />
                    
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 Octavia.CmsSDK --version 0.3.0
                    
#r "nuget: Octavia.CmsSDK, 0.3.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 Octavia.CmsSDK@0.3.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=Octavia.CmsSDK&version=0.3.0
                    
Install as a Cake Addin
#tool nuget:?package=Octavia.CmsSDK&version=0.3.0
                    
Install as a Cake Tool

Octavia.CmsSDK

Typed .NET client for the Octavia AI CMS API — articles, categories, tags, forms, submissions, AI automation, social publishing and analytics, behind one client and one response shape.

  • Generated from the OpenAPI spec, so it covers every public operation.
  • Zero third-party dependencies — System.Text.Json only.
  • .NET 8+, nullable reference types enabled.

Install

dotnet add package Octavia.CmsSDK

Quick start

using Octavia.CmsSDK;

var cms = CMS.Init("your-api-key");

var res = await cms.Article.CreateAsync(new
{
    mainTitle = new { en = "Hello" },
    body = new { en = "Content" },
    category = new[] { "CATEGORY_ID" },
    author = "AUTHOR_ID",
});

if (!res.Ok)
{
    throw new Exception(res.Error?.Message ?? "Request failed");
}

Console.WriteLine(res.Data?.Article?.Slug);

Authentication

The API key is the only credential, and it is required. There is no OAuth, no refresh token and no header option — the key is sent as the x-api-key header on every request, and that is the entire authentication story.

The base URL is fixed to https://api.octaviatech.app/cms (exposed as CMSConstants.BaseUrl), so there is nothing to configure. Your tenant and the service status are resolved by the gateway from your key; you never send them.

Get a key:

  1. Sign up at octaviatech.app
  2. Dashboard → your service → API Keys → Create key

Keep the key server-side. Read it from configuration, never hard-code it.

var apiKey = Environment.GetEnvironmentVariable("OCTAVIA_API_KEY")
    ?? throw new InvalidOperationException("OCTAVIA_API_KEY is not set");

var cms = CMS.Init(apiKey);

Initialize

var cms = CMS.Init("your-api-key", new CMSOptions
{
    Timeout = TimeSpan.FromSeconds(30),
    ThrowOnError = false,
});
Option Type Default Notes
Timeout TimeSpan 30 seconds Per-request timeout.
ThrowOnError bool false false returns Ok = false; true throws an ApiError.

CMS.Init returns a facade. cms.Raw is the underlying Client if you need an endpoint the generated resources do not cover yet.


Response shape

Every method returns CMSResponse<T>, with T bound to the endpoint's model:

public sealed record CMSResponse<T>(
    bool Ok,
    T? Data,
    CMSError? Error = null,
    CMSMeta? Meta = null);
var res = await cms.Article.GetAllAsync(new Dictionary<string, string?>
{
    ["page"] = "1",
    ["limit"] = "10",
});

if (!res.Ok)
{
    Console.Error.WriteLine($"{res.Error?.StatusCode}: {res.Error?.Message}");
    return;
}

foreach (var item in res.Data?.ArticleListItem ?? [])
{
    Console.WriteLine(item.Slug);
}

Errors

With the default ThrowOnError = false you check res.Ok. Set it to true and the call throws an ApiError:

try
{
    await cms.Article.GetByIdAsync("6810f2c3a1b2c3d4e5f60718");
}
catch (ApiError err)
{
    Console.Error.WriteLine($"{err.Status}: {err.Message}");
    Console.Error.WriteLine(err.Payload);
}
Status Meaning Retry?
400 Invalid request or missing field No — fix the request
401 Missing or invalid API key No
403 Key valid, role not permitted No
404 Record not found No
426 Plan quota exhausted No — upgrade, wait for the period to roll over, or free up quota
429 Transient rate limit Yes, after the interval in retry-after

Query parameters

Filters go in the query dictionary, passed as the first argument to read methods:

var res = await cms.Article.GetAllAsync(new Dictionary<string, string?>
{
    ["page"] = "1",
    ["limit"] = "10",
    ["category"] = "CATEGORY_ID",
});

var hits = await cms.Article.SearchAsync(new Dictionary<string, string?>
{
    ["keyword"] = "typescript",
    ["limit"] = "5",
});

Write methods take the body as an anonymous object:

await cms.Article.UpdateAsync(new
{
    id = "ARTICLE_ID",
    mainTitle = new { en = "Updated" },
});

Resources

Property Covers
cms.Article Articles, comments, reactions, engagement settings
cms.Author Authors
cms.Category Categories
cms.Subcategory Subcategories
cms.Tag Tags
cms.Form Forms and captcha configuration
cms.FormSubmission Submissions and their article relations
cms.Language Languages
cms.AI Summarize, translate, SEO, repurpose, social publishing
cms.AIConversation Multi-turn article drafting
cms.Report Statistics, charts, dashboard configuration
cms.Raw The unwrapped client

Method names follow the route segments as generated, including the ones that read as a verb and a method together — IdReactionPOSTAsync, EngagementSettingsPUTAsync. The API reference lists every operation under its route.


Common tasks

Paginate

var first = await cms.Article.GetAllAsync(new Dictionary<string, string?>
{
    ["page"] = "1",
    ["limit"] = "20",
});

Console.WriteLine(first.Data?.Pagination?.Total);

Create multilingual content

category and subCategory take arrays of IDs, even when you have one. Text fields are maps from language code to string.

await cms.Article.CreateAsync(new
{
    mainTitle = new { en = "Hello", es = "Hola" },
    body = new { en = "Content", es = "Contenido" },
    category = new[] { "6810f2c3a1b2c3d4e5f60718" },
    subCategory = new[] { "6810f2c3a1b2c3d4e5f60719" },
    author = "6810f2c3a1b2c3d4e5f60720",
});

Only languages registered through cms.Language.CreateAsync can be written.

Summarize text

var res = await cms.AI.SummarizeAsync(new Dictionary<string, string?>
{
    ["text"] = "Long article body…",
});

Console.WriteLine(res.Data);

Dependency injection

Client takes a ClientConfig, so you can register it and build the facade yourself:

services.AddSingleton(_ =>
{
    var client = new Client(new ClientConfig(CMSConstants.BaseUrl, apiKey));
    return new CMS(client);
});

Cancellation

Pass a CancellationToken through HttpClient's timeout, or call the low-level client when you need per-call cancellation:

var raw = await cms.Raw.RequestAsync(HttpMethod.Get, "/articles/getAll",
    query: new Dictionary<string, string?> { ["page"] = "1" });

Documentation


License

ISC

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

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
0.3.0 69 9/29/2026
0.2.0 124 2/23/2026