CivitaiSharp.Tools
0.9.0
dotnet add package CivitaiSharp.Tools --version 0.9.0
NuGet\Install-Package CivitaiSharp.Tools -Version 0.9.0
<PackageReference Include="CivitaiSharp.Tools" Version="0.9.0" />
<PackageVersion Include="CivitaiSharp.Tools" Version="0.9.0" />
<PackageReference Include="CivitaiSharp.Tools" />
paket add CivitaiSharp.Tools --version 0.9.0
#r "nuget: CivitaiSharp.Tools, 0.9.0"
#:package CivitaiSharp.Tools@0.9.0
#addin nuget:?package=CivitaiSharp.Tools&version=0.9.0
#tool nuget:?package=CivitaiSharp.Tools&version=0.9.0
CivitaiSharp

A modern, lightweight, and AOT-ready .NET 10 client library for all things Civitai.com.
Note: CivitaiSharp is currently in Alpha. APIs, features, and stability are subject to change.
Table of Contents
- Packages and Release Schedule
- Installation
- Quick Start
- Configuration
- API Examples
- Features
- Documentation
- Known API Quirks
- Versioning
- License
- Contributing
1. Packages and Release Schedule
| Package | Status | Description |
|---|---|---|
| CivitaiSharp.Core | Alpha | Public API client for models, images, tags, and creators |
| CivitaiSharp.Sdk | Alpha | Generator/Orchestration API client for image generation jobs |
| CivitaiSharp.Tools | Alpha | Utilities for downloads, file hashing, and HTML parsing |
Note: All packages are currently in Alpha. APIs may change between minor versions.
Warning: CivitaiSharp.Sdk is not fully tested and should not be used in production environments. Use at your own risk.
2. Installation
Install via NuGet:
# Core library - API client for models, images, tags, and creators
dotnet add package CivitaiSharp.Core --prerelease
# SDK - Image generation and job management (requires API token)
dotnet add package CivitaiSharp.Sdk --prerelease
# Tools - File hashing, downloads, and HTML parsing
dotnet add package CivitaiSharp.Tools --prerelease
3. Quick Start
Minimal Example
The simplest way to get started with CivitaiSharp.Core:
using CivitaiSharp.Core;
using CivitaiSharp.Core.Extensions;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddCivitaiApi();
await using var provider = services.BuildServiceProvider();
var client = provider.GetRequiredService<IApiClient>();
var result = await client.Models.ExecuteAsync();
if (result.IsSuccess)
{
foreach (var model in result.Value.Items)
Console.WriteLine(model.Name);
}
Full Example with Configuration
using CivitaiSharp.Core;
using CivitaiSharp.Core.Extensions;
using CivitaiSharp.Core.Models;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddCivitaiApi(options =>
{
options.TimeoutSeconds = 120;
options.StrictJsonParsing = true;
});
await using var provider = services.BuildServiceProvider();
var client = provider.GetRequiredService<IApiClient>();
var result = await client.Models
.WhereType(ModelType.Checkpoint)
.WhereNsfw(false)
.OrderBy(ModelSort.MostDownloaded)
.ExecuteAsync(resultsLimit: 10);
if (result.IsSuccess)
{
foreach (var model in result.Value.Items)
Console.WriteLine($"{model.Name} by {model.Creator?.Username}");
}
else
{
Console.WriteLine($"Error: {result.ErrorInfo.Message}");
}
4. Configuration
Using appsettings.json
CivitaiSharp.Core reads configuration from the CivitaiApi section by default.
Minimal Configuration (appsettings.json)
{
"CivitaiApi": {
}
}
All settings have sensible defaults, so an empty section is valid.
Full Configuration (appsettings.json)
{
"CivitaiApi": {
"BaseUrl": "https://civitai.com",
"ApiVersion": "v1",
"ApiKey": null,
"TimeoutSeconds": 30,
"StrictJsonParsing": false
}
}
| Property | Type | Default | Description |
|---|---|---|---|
BaseUrl |
string |
https://civitai.com |
Base URL for the Civitai API |
ApiVersion |
string |
v1 |
API version path segment |
ApiKey |
string? |
null |
Optional API key for authenticated requests |
TimeoutSeconds |
int |
30 |
HTTP request timeout (1-300 seconds) |
StrictJsonParsing |
bool |
false |
Throw on unmapped JSON properties |
Authentication Note: The Core library can query public endpoints (models, images, tags, creators) without an API key. An API key is only required for authenticated features like favorites, hidden models, and higher rate limits. NSFW Content: Setting
WhereNsfw(true)on models or using certainImageNsfwLevelvalues (Mature, X) requires authentication. This is different from CivitaiSharp.Sdk which always requires an API token for all operations.
Configuration with IConfiguration
using CivitaiSharp.Core.Extensions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var services = new ServiceCollection();
services.AddCivitaiApi(configuration);
// Or with a custom section name:
// services.AddCivitaiApi(configuration, "MyCustomSection");
await using var provider = services.BuildServiceProvider();
5. API Examples
CivitaiSharp.Core provides fluent builders for each endpoint. Each builder is immutable and thread-safe.
Models Endpoint
// Get all models (default query)
var result = await client.Models.ExecuteAsync();
// Get a specific model by ID
var result = await client.Models.GetByIdAsync(12345);
if (result.IsSuccess)
Console.WriteLine($"Model: {result.Value.Name}");
// Get the first matching model (efficient single-item retrieval)
var result = await client.Models
.WhereName("SDXL")
.FirstOrDefaultAsync();
if (result is { IsSuccess: true, Value: not null })
Console.WriteLine($"Found: {result.Value.Name}");
// Search by name
var result = await client.Models
.WhereName("SDXL")
.ExecuteAsync();
// Filter by type and sort
var result = await client.Models
.WhereType(ModelType.Checkpoint)
.OrderBy(ModelSort.MostDownloaded)
.ExecuteAsync(resultsLimit: 25);
// Filter by tag
var result = await client.Models
.WhereTag("anime")
.WhereNsfw(false)
.ExecuteAsync();
// Filter by creator
var result = await client.Models
.WhereUsername("Mewyk")
.OrderBy(ModelSort.Newest)
.ExecuteAsync();
// Filter by base model (string value, e.g., "SDXL 1.0", "SD 1.5", "Flux.1 D")
var result = await client.Models
.WhereBaseModel("SDXL 1.0")
.WhereType(ModelType.Lora)
.ExecuteAsync();
// Filter by multiple base models
var result = await client.Models
.WhereBaseModels("SDXL 1.0", "Pony")
.ExecuteAsync();
// Filter by specific model IDs (ignored if query is also provided)
var result = await client.Models
.WhereIds(12345, 67890, 11111)
.ExecuteAsync();
// Get a specific model version by version ID
var versionResult = await client.Models.GetByVersionIdAsync(130072);
if (versionResult.IsSuccess)
{
Console.WriteLine($"Version: {versionResult.Value.Name}");
Console.WriteLine($"AIR: {versionResult.Value.AirIdentifier}");
}
// Get a model version by file hash (SHA256, AutoV2, CRC32, etc.)
var hashResult = await client.Models.GetByVersionHashAsync("ABC123DEF456");
if (hashResult.IsSuccess)
{
Console.WriteLine($"Found: {hashResult.Value.Model?.Name}");
Console.WriteLine($"AIR: {hashResult.Value.AirIdentifier}");
}
Images Endpoint
// Get all images (default query)
var result = await client.Images.ExecuteAsync();
// Get the first matching image
var result = await client.Images
.WhereModelId(12345)
.FirstOrDefaultAsync();
if (result is { IsSuccess: true, Value: not null })
Console.WriteLine($"Image URL: {result.Value.Url}");
// Filter by model ID
var result = await client.Images
.WhereModelId(12345)
.ExecuteAsync();
// Filter by model version ID
var result = await client.Images
.WhereModelVersionId(67890)
.OrderBy(ImageSort.Newest)
.ExecuteAsync();
// Filter by username
var result = await client.Images
.WhereUsername("Mewyk")
.WhereNsfwLevel(ImageNsfwLevel.None)
.ExecuteAsync(resultsLimit: 50);
// Filter by post ID
var result = await client.Images
.WherePostId(11111)
.ExecuteAsync();
Tags Endpoint
// Get all tags (default query)
var result = await client.Tags.ExecuteAsync();
// Search tags by name
var result = await client.Tags
.WhereName("portrait")
.ExecuteAsync(resultsLimit: 100);
Creators Endpoint
// Get all creators (default query)
var result = await client.Creators.ExecuteAsync();
// Search creators by name
var result = await client.Creators
.WhereName("Mewyk")
.ExecuteAsync(resultsLimit: 20);
// Page-based pagination (Models, Tags, and Creators use pages, not cursors)
var result = await client.Creators
.WithPageIndex(2)
.ExecuteAsync(resultsLimit: 50);
Pagination
// Cursor-based pagination (Images only)
string? cursor = null;
var allImages = new List<Image>();
do
{
result = await client.Images
.WhereModelId(12345)
.ExecuteAsync(resultsLimit: 100, cursor: cursor);
if (!result.IsSuccess)
break;
allImages.AddRange(result.Value.Items);
cursor = result.Value.Metadata?.NextCursor;
} while (cursor is not null);
// Page-based pagination (Models, Tags, Creators)
var page1 = await client.Models.WithPageIndex(1).ExecuteAsync();
var page2 = await client.Tags.WithPageIndex(2).ExecuteAsync();
var page3 = await client.Creators.WithPageIndex(3).ExecuteAsync();
Tools - File Hashing
using CivitaiSharp.Tools.Hashing;
using CivitaiSharp.Tools.Extensions;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddCivitaiDownloads();
await using var provider = services.BuildServiceProvider();
var hashingService = provider.GetRequiredService<IFileHashingService>();
// Compute SHA256 hash
var result = await hashingService.ComputeHashAsync(
@"C:\Models\model.safetensors",
HashAlgorithm.Sha256);
if (result.IsSuccess)
{
Console.WriteLine($"Hash: {result.Value.Hash}");
Console.WriteLine($"Size: {result.Value.FileSize:N0} bytes");
}
// Supported algorithms: Sha256, Sha512, Blake3, Crc32
var blake3Result = await hashingService.ComputeHashAsync(filePath, HashAlgorithm.Blake3);
Tools - Downloading Files
using CivitaiSharp.Core;
using CivitaiSharp.Core.Extensions;
using CivitaiSharp.Tools.Downloads;
using CivitaiSharp.Tools.Extensions;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddCivitaiApi();
services.AddCivitaiDownloads(options =>
{
options.Images.BaseDirectory = @"C:\Downloads\Images";
options.Images.PathPattern = "{Username}/{Id}.{Extension}";
options.Models.BaseDirectory = @"C:\Models";
options.Models.PathPattern = "{ModelType}/{ModelName}/{FileName}";
options.Models.VerifyHash = true;
});
await using var provider = services.BuildServiceProvider();
var apiClient = provider.GetRequiredService<IApiClient>();
var downloadService = provider.GetRequiredService<IDownloadService>();
// Download a model file with hash verification
var modelResult = await apiClient.Models.GetByIdAsync(4201);
if (modelResult.IsSuccess)
{
var version = modelResult.Value.ModelVersions?.FirstOrDefault();
var file = version?.Files?.FirstOrDefault(f => f.Primary == true);
if (file is not null && version is not null)
{
var downloadResult = await downloadService.DownloadAsync(file, version);
if (downloadResult.IsSuccess)
{
Console.WriteLine($"Downloaded: {downloadResult.Value.FilePath}");
Console.WriteLine($"Verified: {downloadResult.Value.IsVerified}");
}
}
}
Tools - HTML Parsing
using CivitaiSharp.Tools.Parsing;
// Convert HTML description to Markdown
var markdown = HtmlParser.ToMarkdown(model.Description);
// Convert to plain text
var plainText = HtmlParser.ToPlainText(model.Description);
// Or use extension methods on Model/ModelVersion
var markdown = model.GetDescriptionAsMarkdown();
var plainText = modelVersion.GetDescriptionAsPlainText();
Error Handling
var result = await client.Models.ExecuteAsync();
// Pattern matching
var message = result switch
{
{ IsSuccess: true, Value: var page } => $"Found {page.Items.Count} models",
{ IsSuccess: false, ErrorInfo: var error } => error.Code switch
{
ErrorCode.RateLimited => "Too many requests, please slow down",
ErrorCode.Unauthorized => "Invalid or missing API key",
ErrorCode.NotFound => "Resource not found",
_ => $"Error: {error.Code} - {error.Message}"
}
};
// Traditional approach
if (result.IsSuccess)
{
foreach (var model in result.Value.Items)
Console.WriteLine(model.Name);
}
else
{
Console.WriteLine($"Failed: {result.ErrorInfo.Message}");
}
6. Features
- Modern .NET 10 - Built with nullable reference types, records, and primary constructors
- Fluent Query Builders - Type-safe, immutable builders for constructing API requests
- Result Pattern - Explicit success/failure handling with discriminated union
- Built-in Resilience - Retry policies, circuit breakers, rate limiting, and timeouts
- Dependency Injection - First-class support for
IHttpClientFactoryand Microsoft DI - Streaming Downloads - Memory-efficient response handling with
ResponseHeadersRead - Explicit JSON Contract - All model properties use
[JsonPropertyName]for type safety
7. Documentation
8. Known API Quirks
CivitaiSharp interacts with the Civitai.com API, which has several known quirks. Some are mitigated automatically; others are documented and under investigation.
| Issue | Description |
|---|---|
| Tags endpoint model count | Documented feature, but responses never include this field |
limit=0 parameter |
Documented to return all results for various endpoints, but returns an error |
| Semantic errors with HTTP 200 | Errors, Not Found, and others, all return HTTP 200 |
| Endpoint inconsistencies | Intermittent throttling, unreported outages, undocumented rate limits |
| Variable metadata structures | Metadata format varies widely between responses |
| User existence issues | During partial outages, existing users may appear nonexistent |
| Creator endpoint unreliability | See details below |
Creator Endpoint Reliability Issues
The /api/v1/creators endpoint is known to experience intermittent reliability issues:
- HTTP 500 errors: The endpoint frequently returns server errors, especially under load
- Slow response times: Requests may take significantly longer than other endpoints (10-30+ seconds)
- Timeout failures: Long response times can exceed client timeout thresholds
Recommendations:
- Implement generous timeouts: Set timeouts of 60-120 seconds for Creator endpoint requests
- Use retry logic: The built-in resilience handler will retry on 500 errors, but success is not guaranteed
- Handle failures gracefully: Your application should degrade gracefully when Creator data is unavailable
- Cache results aggressively: When requests succeed, cache the results to reduce API load
// Example: Handling Creator endpoint unreliability
var result = await client.Creators.ExecuteAsync(resultsLimit: 10);
if (!result.IsSuccess)
{
// Log the error but continue with degraded functionality
logger.LogWarning("Creator data unavailable: {Error}", result.ErrorInfo.Message);
return GetCachedCreators(); // Fallback to cached data
}
Additional quirks are being tracked and will be addressed in future releases.
9. Versioning
CivitaiSharp follows MAJOR.MINOR.PATCH semantic versioning:
| Component | Description |
|---|---|
| MAJOR | Significant, breaking API changes |
| MINOR | New features; may include limited breaking changes unlikely to affect most users |
| PATCH | Backwards-compatible bug fixes and improvements |
Pre-release versions use the format: MAJOR.MINOR.PATCH-alpha.N
Note: While in Alpha (0.x.x), APIs may change between minor versions. Stability is guaranteed from v1.0.0 onwards.
10. License
This repository is released under the MIT License.
11. Contributing
Contributions are welcome. Please read CONTRIBUTING.md for guidelines.
Legal Notice
CivitaiSharp is an independent open-source project and is not affiliated with, sponsored by, endorsed by, or officially associated with Civitai.com or Civitai, Inc. The Civitai name and any related trademarks are the property of their respective owners. Use of these names is for identification purposes only and does not imply any endorsement or partnership.
| Product | Versions 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. |
-
net10.0
- Blake3 (>= 2.0.0)
- CivitaiSharp.Core (>= 0.9.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Http (>= 10.0.0)
- Microsoft.Extensions.Options (>= 10.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.0)
- Microsoft.Extensions.Options.DataAnnotations (>= 10.0.0)
- System.IO.Hashing (>= 10.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 |
|---|---|---|
| 0.9.0 | 637 | 12/3/2025 |