C# API Documentation & Wrapper

Updated .NET usage, endpoint coverage, and error handling

Unshared.shop / Blog / C# API Documentation & Wrapper
Cyanokit March 31, 2026 12 min read API Documentation

Updated C# / .NET API docs (2026)

This is the current C# reference for the UNSHARED API. It matches current endpoints and ZIP/KV handling.

Base URL: https://api.unshared.shop/api/
Token: Get from profile.

Endpoints you should use

  • POST ?action=validate (multipart file)
  • POST ?action=validate_url (url form field)
  • GET ?action=info&id={serial} (serial check)
  • GET ?action=rarity&date={MM-DD-YY} (rarity lookup)

Minimal .NET 6+ client

using System.Net.Http.Headers;
using System.Text.Json;

public sealed class UnsharedApiClient : IDisposable
{
    private readonly HttpClient _http;
    private readonly string _base;

    public UnsharedApiClient(string token, string baseUrl = "https://api.unshared.shop/api/")
    {
        _base = baseUrl.TrimEnd('/') + "/";
        _http = new HttpClient();
        _http.DefaultRequestHeaders.Add("X-API-Token", token);
    }

    public async Task<JsonElement> ValidateFileAsync(string filePath)
    {
        using var form = new MultipartFormDataContent();
        await using var fs = File.OpenRead(filePath);
        using var sc = new StreamContent(fs);
        sc.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        form.Add(sc, "file", Path.GetFileName(filePath));
        using var res = await _http.PostAsync(_base + "?action=validate", form);
        var raw = await res.Content.ReadAsStringAsync();
        res.EnsureSuccessStatusCode();
        return JsonDocument.Parse(raw).RootElement;
    }

    public async Task<JsonElement> ValidateUrlAsync(string url)
    {
        using var form = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("url", url) });
        using var res = await _http.PostAsync(_base + "?action=validate_url", form);
        var raw = await res.Content.ReadAsStringAsync();
        res.EnsureSuccessStatusCode();
        return JsonDocument.Parse(raw).RootElement;
    }

    public async Task<JsonElement> CheckSerialAsync(string serial)
    {
        var raw = await _http.GetStringAsync(_base + "?action=info&id=" + Uri.EscapeDataString(serial));
        return JsonDocument.Parse(raw).RootElement;
    }

    public void Dispose() => _http.Dispose();
}

Example usage

using var api = new UnsharedApiClient("YOUR_TOKEN");
var validate = await api.ValidateFileAsync("kv.bin");

if (validate.TryGetProperty("success", out var ok) && ok.GetBoolean())
{
    var serial = validate.GetProperty("serial").GetString();
    Console.WriteLine($"Serial: {serial}");
    Console.WriteLine($"Status: {validate.GetProperty("status").GetString()}");

    if (!string.IsNullOrWhiteSpace(serial))
    {
        var info = await api.CheckSerialAsync(serial);
        Console.WriteLine("Shared: " + info.GetProperty("shared").ToString());
    }
}
else
{
    Console.WriteLine("Validation failed.");
}

ZIP support notes

  • ZIP URLs/files are supported in validation endpoints.
  • The archive must contain exactly one valid 16KB KV candidate.
  • Multiple KV candidates in one ZIP are rejected.

Best practices

  • Use EnsureSuccessStatusCode() and parse JSON only after HTTP success.
  • Handle transient HTTP failures with retries/backoff.
  • Treat token as a secret (don't embed in client apps).
  • If you validate ZIPs, surface clear errors to users.
Wrapper download: UnsharedApiWrapper.cs

For API help, open a support ticket.