HTML to PDF in C# / .NET

The .NET ecosystem's PDF options are commercial licenses that cost more than a year of any API plan (IronPDF, Aspose) or bundling Chromium yourself with PuppeteerSharp. For most teams the pragmatic answer is ten lines of HttpClient:

1. Convert HTML to PDF

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

var client = new HttpClient { Timeout = TimeSpan.FromSeconds(60) };
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("INKPDF_KEY"));

var response = await client.PostAsJsonAsync("https://inkpdf.dev/v1/pdf", new
{
    html = "<h1>Hello from C#</h1><p>Rendered by real Chromium.</p>",
    options = new { format = "Letter" },
});

response.EnsureSuccessStatusCode();
await File.WriteAllBytesAsync("hello.pdf", await response.Content.ReadAsByteArrayAsync());

2. Invoice from an object (no HTML)

var invoice = new
{
    template = "invoice",
    data = new
    {
        brand = new { name = "Acme Studio", color = "#0f766e" },
        invoiceNumber = "INV-2043",
        issueDate = "2026-07-01",
        dueDate = "2026-07-31",
        currency = "USD",
        to = new { name = "Northwind Traders", address = "1 Market St, SF" },
        items = new[]
        {
            new { description = "Design work", quantity = 10, unitPrice = 95m },
        },
        taxRate = 8.5,
    },
};
var response = await client.PostAsJsonAsync("https://inkpdf.dev/v1/pdf", invoice);

Line totals, subtotal, tax, and grand total are computed server-side. Receipt, quote, report, and certificate templates are in the gallery.

3. ASP.NET Core minimal API endpoint

app.MapGet("/invoices/{id}/pdf", async (string id, InvoiceService invoices, HttpClient inkpdf) =>
{
    var data = await invoices.GetTemplateDataAsync(id);
    var res = await inkpdf.PostAsJsonAsync("https://inkpdf.dev/v1/pdf",
        new { template = "invoice", data });

    if (!res.IsSuccessStatusCode)
        return Results.Problem("PDF generation failed", statusCode: 502);

    var pdf = await res.Content.ReadAsByteArrayAsync();
    return Results.File(pdf, "application/pdf", $"{id}.pdf");
});

Register the client with builder.Services.AddHttpClient and keep the API key in user-secrets or your key vault.

Quota visibility

Every successful render returns x-inkpdf-used and x-inkpdf-quota headers, and GET /v1/usage reports your month at any time. Failed renders never count. Details in the API docs.

Try it without writing code

The playground renders live against the real pipeline — 20 free renders a day, no signup.