CVR lookups in C# and .NET

In .NET you can fetch CVR data with HttpClient and deserialize the response straight into your own records. You don't need any NuGet packages beyond what ships with .NET.

Look up a company by CVR number

This is a top-level program for .NET 6 and later. The records only include the fields you need. The rest is ignored.

csharp
using System.Net;
using System.Net.Http.Json;
using System.Text.Json.Serialization;

var http = new HttpClient { BaseAddress = new Uri("https://apicvr.dk/") };

async Task<Company?> GetCompany(int cvr)
{
    var res = await http.GetAsync($"api/v1/{cvr}");
    if (res.StatusCode == HttpStatusCode.NotFound) return null;
    res.EnsureSuccessStatusCode(); // 422 or 502 throws
    return await res.Content.ReadFromJsonAsync<Company>();
}

var company = await GetCompany(24256790);
Console.WriteLine($"{company!.Name}, {company.Zipcode} {company.City}");

foreach (var owner in company.Ejere)
    Console.WriteLine($"{owner.Name} {owner.OwnershipRange}");

record Company(
    [property: JsonPropertyName("vat")] int Vat,
    [property: JsonPropertyName("name")] string Name,
    [property: JsonPropertyName("zipcode")] int? Zipcode,
    [property: JsonPropertyName("city")] string? City,
    [property: JsonPropertyName("protected")] bool? Protected,
    [property: JsonPropertyName("ejere")] List<Owner> Ejere);

record Owner(
    [property: JsonPropertyName("name")] string? Name,
    [property: JsonPropertyName("ownership_range")] string? OwnershipRange);

Search by company name

csharp
var hits = await http.GetFromJsonAsync<List<Hit>>(
    "api/v1/search/fuzzy/" + Uri.EscapeDataString("novo nordisk"));

foreach (var hit in hits!.Take(5))
    Console.WriteLine($"{hit.CvrNumber} {hit.Name}");

record Hit(
    [property: JsonPropertyName("name")] string Name,
    [property: JsonPropertyName("cvr_number")] int CvrNumber,
    [property: JsonPropertyName("industrytext")] string? IndustryText);

Handle errors

StatusMeaning
200The company was found. The body is JSON.
404No company has that CVR number. Body: {"detail": {"error": "NOT_FOUND"}}
422The CVR number isn't a number.
502The CVR register didn't answer. Try again shortly.

EnsureSuccessStatusCode() throws an HttpRequestException on 422 and 502. Catch it if you want to retry.

Always check protected before using the data for marketing. When it's true, the company has opted out of direct marketing.

Frequently asked questions

How do I use HttpClient in ASP.NET Core?

Register a typed client with builder.Services.AddHttpClient<CvrClient>() instead of creating a new HttpClient per request.

Why are some field names Danish?

Fields like ejere (owners) and direktion (management) follow the CVR register's own terms. With JsonPropertyName you can give them English names in your code.