Home
Home/Developers/SDKs/dotnet
Ed25519 signaturesSHA-256 hashes8 SDKs
Status
Sign inStart free
Home
Start here
Overview
Authentication
Errors
FAQ
API
Events
Canonical JSON and hashes
Documents
Anchoring a file
AI attestations
Attestation schema
Verifying attestations
Traces
Sealing a trace
Audit logs
Organizations
Streams
Portal
Public proof
Event schema
Exporting events
Integrations
Clerk
Auth0
Embeddable viewer
All endpoints
Reference
SDKs
Node.js
Python
Go
Java
Ruby
Rust
.NET
PHP
REST
Verification
Docs · SDKs

.NET SDK

Install the .NET SDK, build a client, see every method with a .NET sample, and verify records offline.

sha-256 · 3a352297…2592
sha-256 · 971e439d…e24c
RESTNode.jsPythonGoJavaRubyRust.NETPHP
Install

.NET

Invoance on NuGet.

.NET 8.0. Every network method ends in Async, returns a Task and takes an optional CancellationToken.

Terminal
dotnet add package Invoance
Client
ApiKeyThe API key. Falls back to INVOANCE_API_KEY; ArgumentException when neither is set.
BaseUrlAPI host. Falls back to INVOANCE_BASE_URL, then https://api.invoance.com. Trailing slashes are removed.
ApiVersionPath prefix put before every request path. Default v1.
TimeoutPer-request timeout as a TimeSpan. Default 30 seconds; past it the call throws TimeoutException.
IdempotencyKeyDefault Idempotency-Key header for every mutating request; a per-call key wins.
ExtraHeadersHeaders merged into every request.
RetriesNone. Each request is sent once; on TimeoutException or NetworkException, retry it yourself with the same Idempotency-Key.
.NET
using Invoance;

// Reads INVOANCE_API_KEY and INVOANCE_BASE_URL from the environment.
using var client = new InvoanceClient();

// Or pass options.
using var configured = new InvoanceClient(new InvoanceClientOptions
{
    ApiKey = "invoance_live_...",
    BaseUrl = "https://api.invoance.com",
    Timeout = TimeSpan.FromSeconds(60),
});

// Never throws.
var (valid, reason, baseUrl) = await client.ValidateAsync();
Console.WriteLine($"{valid} {reason} {baseUrl}");
Methods

Every endpoint with a .NET sample, by resource. Open a row for the sample; the link opens the endpoint card with its fields, response and errors.

EventsReference
POST/v1/eventsIngest an event
.NET
using Invoance;
using Invoance.Models;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var result = await client.Events.IngestAsync(new IngestEventParams
{
    EventType = "policy.approval",
    EventTime = "2026-09-22T08:14:07Z",
    Payload = new Dictionary<string, object?>
    {
        ["policy_id"] = "pol_8472",
        ["approved_by"] = "risk_committee",
        ["decision"] = "approved",
    },
    IdempotencyKey = "policy-approval-pol_8472",
});
Console.WriteLine(result.EventId + " " + result.IngestedAt);
Ingest an event: fields, response and errors
GET/v1/eventsList events
.NET
using Invoance;
using Invoance.Models;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var page = await client.Events.ListAsync(new ListEventsParams
{
    Page = 1,
    Limit = 50,
    EventType = "policy.approval",
});
Console.WriteLine(page.Total + " " + page.HasMore);
foreach (var item in page.Events)
{
    Console.WriteLine(item.EventId + " " + item.IngestedAt + " " + item.PayloadHash);
}
List events: fields, response and errors
GET/v1/events/{event_id}Get an event
.NET
using Invoance;
using Invoance.Models;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

ComplianceEvent ev = await client.Events.GetAsync("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4");
Console.WriteLine(ev.EventType + " " + ev.IngestedAt);
Console.WriteLine(ev.PayloadHash + " " + ev.EventHash + " " + ev.RequestHash);
foreach (var pair in ev.Payload)
{
    Console.WriteLine(pair.Key + "=" + pair.Value);
}
Get an event: fields, response and errors
POST/v1/events/{event_id}/verifyVerify an event
.NET
using Invoance;
using Invoance.Models;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var result = await client.Events.VerifyAsync("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4", new VerifyEventParams
{
    Payload = new Dictionary<string, object?>
    {
        ["policy_id"] = "pol_8472",
        ["approved_by"] = "risk_committee",
        ["decision"] = "approved",
    },
});
Console.WriteLine(result.MatchResult + " " + result.MatchedField);
Console.WriteLine(result.AnchoredHash + " " + result.SubmittedHash + " " + result.AnchoredAt);
Verify an event: fields, response and errors
DocumentsReference
POST/v1/document/anchorAnchor a document
.NET
using System.Security.Cryptography;
using Invoance;
using Invoance.Models;

var file = await File.ReadAllBytesAsync("./INV-2026-0917.pdf");
var documentHash = Convert.ToHexString(SHA256.HashData(file)).ToLowerInvariant();

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var result = await client.Documents.AnchorAsync(new AnchorDocumentParams
{
    DocumentHash = documentHash,
    DocumentRef = "INV-2026-0917.pdf",
    EventType = "invoice.issued",
    Metadata = new Dictionary<string, object?>
    {
        ["invoice_number"] = "INV-2026-0917",
        ["amount"] = 5230,
        ["currency"] = "USD",
    },
    IdempotencyKey = "anchor-" + documentHash,
});
Console.WriteLine(result.EventId + " " + result.Status);
Anchor a document: fields, response and errors
GET/v1/documentList documents
.NET
using Invoance;
using Invoance.Models;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var page = await client.Documents.ListAsync(new ListDocumentsParams
{
    Limit = 25,
    DateFrom = "2026-09-01T00:00:00Z",
});
Console.WriteLine(page.Total + " " + page.HasMore);
foreach (var d in page.Documents)
{
    Console.WriteLine(d.EventId + " " + d.DocumentRef + " " + d.HasOriginal);
}
List documents: fields, response and errors
GET/v1/document/{event_id}Get a document
.NET
using Invoance;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var doc = await client.Documents.GetAsync("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4");
Console.WriteLine(doc.DocumentHash + " " + doc.HasOriginal + " " + doc.CreatedAt);
if (doc.Organization != null)
{
    Console.WriteLine(doc.Organization.IssuerName + " " + doc.Organization.DomainVerified);
}
Get a document: fields, response and errors
GET/v1/document/{event_id}/originalDownload the original
.NET
using Invoance;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var data = await client.Documents.GetOriginalAsync("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4");
await File.WriteAllBytesAsync("./INV-2026-0917.pdf", data);
Console.WriteLine(data.Length);
Download the original: fields, response and errors
POST/v1/document/{event_id}/verifyVerify a document hash
.NET
using System.Security.Cryptography;
using Invoance;
using Invoance.Models;

var file = await File.ReadAllBytesAsync("./INV-2026-0917.pdf");
var documentHash = Convert.ToHexString(SHA256.HashData(file)).ToLowerInvariant();

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var result = await client.Documents.VerifyAsync("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4", new VerifyDocumentParams
{
    DocumentHash = documentHash,
});
Console.WriteLine(result.MatchResult + " " + result.AnchoredHash + " " + result.AnchoredAt);
Verify a document hash: fields, response and errors
AI AttestationsReference
POST/v1/ai/attestationsIngest an attestation
.NET
using Invoance;
using Invoance.Models;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var result = await client.Attestations.IngestAsync(new IngestAttestationParams
{
    Type = "output",
    Input = "Summarize the termination clause in contract CT-8472.",
    Output = "Either party may terminate with 30 days written notice. Early termination fees do not apply after month 12.",
    ModelProvider = "openai",
    ModelName = "gpt-4.1",
    ModelVersion = "2026-04-14",
    Subject = new AttestationSubject
    {
        UserId = "u_4821",
        SessionId = "sess_9f3a",
        Extra = new Dictionary<string, object?> { ["department"] = "legal" },
    },
    IdempotencyKey = "ct-8472-summary-1",
});
Console.WriteLine($"{result.AttestationId} {result.PayloadHash}");
Ingest an attestation: fields, response and errors
GET/v1/ai/attestationsList attestations
.NET
using Invoance;
using Invoance.Models;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var page = await client.Attestations.ListAsync(new ListAttestationsParams
{
    Limit = 50,
    AttestationType = "output",
    ModelProvider = "openai",
});
Console.WriteLine($"{page.Total} {page.HasMore} {page.Attestations.Count}");
List attestations: fields, response and errors
GET/v1/ai/attestations/{attestation_id}Get an attestation
.NET
using Invoance;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var att = await client.Attestations.GetAsync("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4");
Console.WriteLine($"{att.AttestationHash} {att.SignatureAlg} {att.PublicKey}");
Get an attestation: fields, response and errors
GET/v1/ai/attestations/{attestation_id}/rawGet the raw payload
.NET
using Invoance;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var raw = await client.Attestations.GetRawAsync("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4");
Console.WriteLine(raw?["type"]?.ToString());
Console.WriteLine(raw?["context"]?["model_name"]?.ToString());
Get the raw payload: fields, response and errors
POST/v1/ai/attestations/{attestation_id}/verifyVerify a hash
.NET
using Invoance;
using Invoance.Models;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var result = await client.Attestations.VerifyAsync("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4", new VerifyAttestationParams
{
    ContentHash = "c4efe15781214a84046ad7e0592977c634a5cf45f4c1e06160daf760a295a8df",
});
Console.WriteLine($"{result.MatchResult} {result.MatchedField}");
Verify a hash: fields, response and errors
TracesReference
POST/v1/tracesCreate a trace
.NET
using Invoance;
using Invoance.Models;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var trace = await client.Traces.CreateAsync(new CreateTraceParams
{
    Label = "Invoice batch 2026-09",
    Metadata = new Dictionary<string, object?>
    {
        ["batch_id"] = "b_4471",
        ["region"] = "eu-west",
    },
});
Console.WriteLine($"{trace.TraceId} {trace.Status}");
Create a trace: fields, response and errors
POST/v1/traces/{trace_id}/sealSeal a trace
.NET
using Invoance;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var sealed = await client.Traces.SealAsync("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4");
Console.WriteLine($"{sealed.Status} {sealed.Message}");
Seal a trace: fields, response and errors
Audit LogsReference
POST/v1/audit/eventsIngest an audit event
.NET
using Invoance;
using Invoance.Models;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var result = await client.Audit.Events.IngestAsync(new IngestAuditEventParams
{
    OrganizationId = "org_8472",
    Action = "user.signed_in",
    OccurredAt = "2026-09-22T08:14:07Z",
    Actor = new Dictionary<string, object?>
    {
        ["type"] = "user",
        ["id"] = "u_4821",
        ["name"] = "Ada Lovelace",
    },
    Targets = new List<IDictionary<string, object?>>
    {
        new Dictionary<string, object?> { ["type"] = "workspace", ["id"] = "ws_17" },
    },
    Context = new Dictionary<string, object?>
    {
        ["location"] = "203.0.113.10",
        ["user_agent"] = "Mozilla/5.0",
    },
    Metadata = new Dictionary<string, object?> { ["method"] = "sso", ["mfa"] = true },
    IdempotencyKey = "signin-u_4821-2026-09-22T08:14:07Z",
});
Console.WriteLine(result?["event_id"] + " " + result?["ingested_at"]);
Ingest an audit event: fields, response and errors
POST/v1/audit/orgsCreate an audit org
.NET
using Invoance;
using Invoance.Models;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var org = await client.Audit.Orgs.CreateAsync(new CreateAuditOrgParams
{
    OrganizationId = "org_8472",
    Name = "Acme Robotics",
});
Console.WriteLine(org?["id"] + " " + org?["retention_days"]);
Create an audit org: fields, response and errors
PlatformReference
GET/v1/meIntrospect the API key
.NET
using Invoance;

// Reads INVOANCE_API_KEY from the environment.
using var client = new InvoanceClient();

var me = await client.MeAsync();
Console.WriteLine(me?["organization"]?["primary_domain"]);
Console.WriteLine(me?["limits"]?["rate_limit_per_sec"]);
Introspect the API key: fields, response and errors
Verify offlineHow verification works

Two checks run without trusting the server: Attestations.VerifySignatureAsync fetches the record and checks its Ed25519 signature over signed_payload; AuditVerify.VerifyAuditEvent (namespace Invoance.Internal) rebuilds the invoance.audit/1 bytes of an audit event, given as a dictionary of its wire fields, and checks its signature. Pass the hex key from GET /keys/{domain} as the second argument to pin it instead of the key on the row.

.NET
using Invoance;
using Invoance.Internal;

using var client = new InvoanceClient();

// AI attestation: Ed25519 over signed_payload, checked locally.
var sig = await client.Attestations.VerifySignatureAsync("a1d4f8c2-7b3e-4e9a-b5c6-0d2e8f4a7c19");
Console.WriteLine($"{sig.Valid} {sig.Reason}");

// Audit event: canonical bytes rebuilt locally, signature checked
// against a pinned key (the public_key from GET /keys/{domain}, base64url decoded to hex).
var pinnedHexKey = "d4443bd9d30ef4c2e0e5db03467e3c5c740358482c1a1e30cdb27a2e02a38176";
var evt = await client.Audit.Events.GetAsync("aevt_01J8F3KQ2R7VWX9YB4ND6MCZAH");
var map = new Dictionary<string, object?>
{
    ["id"] = evt.Id,
    ["org_id"] = evt.OrgId,
    ["seq"] = evt.Seq,
    ["occurred_at"] = evt.OccurredAt,
    ["ingested_at"] = evt.IngestedAt,
    ["action"] = evt.Action,
    ["actor"] = evt.Actor,
    ["targets"] = evt.Targets,
    ["context"] = evt.Context,
    ["metadata"] = evt.Metadata,
    ["payload_hash"] = evt.PayloadHash,
    ["signature"] = evt.Signature,
    ["signing_public_key"] = evt.SigningPublicKey,
};
var result = AuditVerify.VerifyAuditEvent(map, pinnedHexKey);
Console.WriteLine($"{result.Valid} {result.Reason} {result.KeySource}"); // pinned

Proof infrastructure. Records are hashed, signed with your organization's Ed25519 key, and stored append-only, so anyone can check them later.

Products

  • Audit Logs
  • Event Ledger
  • AI Attestation
  • Document Anchoring
  • Traces

Developers

  • Documentation
  • API reference
  • SDKs
  • How it works
  • How traces seal
  • System status

Verify

  • Audit Log
  • Event
  • AI Attestation
  • Document
  • Trace

Company

  • Why Invoance
  • Pricing
  • Security
  • Compliance teams
  • Finance teams
  • Partners
  • Resources
  • Help center
  • Contact
© 2026 Invoance
PrivacyLegal noticeLegal FAQGitHubLinkedInX