Loading...
Sign in to see the examples with your own API key.

.NET SDK

A .NET client for every endpoint, with DAWA's records, field names and errors. Targets .NET Standard 2.0 and .NET 8, and uses no reflection, so it works in trimmed, native AOT and file-based apps. The current version is 1.0.0.

Install

dotnet add package getAddress.Dk.Sdk

Set it up

Register it as a typed HttpClient:

services.AddSingleton(new GetAddressDk.ApiKeys("{your-api-key}", "{your-admin-key}"));
services.AddHttpClient<GetAddressDk.Api>();

Or construct it yourself:

var api = new GetAddressDk.Api(httpClient, new GetAddressDk.ApiKeys("{your-api-key}"));

The API key goes in the api-key query parameter of every request. The admin key is only needed for usage. Keep both on your server: an API key sent from a web page is refused with 401. When the HttpClient has no BaseAddress, https://api.getaddress.dk/ is used.

Code that runs in your visitors' browsers (Blazor WebAssembly) uses a domain token instead:

var api = new GetAddressDk.Api(httpClient, GetAddressDk.ApiKeys.DomainToken("{your-domain-token}"));

Names

Records keep DAWA's Danish field names, in PascalCase with æ, ø and å written ae, oe and aa: dør is Doer, højde is Hoejde, ændret is Aendret. The JSON names are exactly DAWA's. Each record comes in DAWA's three shapes, picked by the method name: GetAdresse (struktur=nestet), GetAdresseFlad and GetAdresseMini. Coordinates are WGS84 unless you pass Srid.Etrs89Utm32 (EPSG:25832).

Autocomplete

DAWA's combined /autocomplete: street names, then access addresses, then addresses as the user types.

var result = await api.Autocomplete("Amagerbrogade 217A");

if (result.IsSuccess)
{
    foreach (var suggestion in result.Success)
    {
        var text = suggestion.Forslagstekst;                            // what to show in the list
        if (suggestion.IsAdresse)
        {
            var adresse = await api.GetAdresse(suggestion.Data.Id!);   // one look-up
        }
    }
}

DAWA's parameters are on AutocompleteQuery:

await api.Autocomplete(new GetAddressDk.AutocompleteQuery
{
    Q = "Amagerbrogade 217A",
    Type = GetAddressDk.AutocompleteLevel.Adresse,
    Postnr = "2300|2400",                                 // several separated by |, as in DAWA
    Fuzzy = true,
    PerSide = 10,
});

AdresserAutocomplete, AdgangsadresserAutocomplete, VejnavneAutocomplete and PostnumreAutocomplete call DAWA's per-resource autocompletes.

Adresser and adgangsadresser

One record by id is one look-up; a search costs one look-up per record returned. See Adresser and Adgangsadresser.

var adresse = await api.GetAdresse("3bba05d4-c8c4-4c90-8a64-a4dff11b9d1b");
var line = adresse.Success!.Adressebetegnelse;        // "Amagerbrogade 217A, kl. 5, 2300 København S"
var floor = adresse.Success.Etage;                    // "kl"
var door = adresse.Success.Doer;                      // "5"

var found = await api.SearchAdresser(new GetAddressDk.AdresseQuery
{
    Postnr = "2300",
    Vejnavn = "Amagerbrogade",
    Husnr = "217A",
    PerSide = 100,                                    // at most 100; Side pages on
});

var adgangsadresse = await api.GetAdgangsadresseMini("099f3e28-4fb8-4c61-86a1-edff5df52409");

Etage = "" or Doer = "" means "has none", as in DAWA.

Reverse geocoding

The access address nearest a point. One look-up.

var nearest = await api.Reverse(12.6137425, 55.6490036);                                // WGS84
var utm = await api.ReverseMini(724524.37, 6172102.97, GetAddressDk.Srid.Etrs89Utm32);

GeoJSON

var feature = await api.GetAdresseGeoJson("3bba05d4-c8c4-4c90-8a64-a4dff11b9d1b");
var json = feature.Success!.Json;                     // exactly as sent, for a map library

SearchAdresserGeoJson, SearchAdgangsadresserGeoJson, GetAdgangsadresseGeoJson and ReverseGeoJson do the same.

Vejnavne and postnumre

Free, and rate limited. See Vejnavne and Postnumre.

var streets = await api.Vejnavne(new GetAddressDk.VejnavnQuery { Postnr = "2300" });   // every street in 2300
var street = await api.GetVejnavn("Amagerbrogade");
var postcodes = await api.Postnumre();                                                  // all of them
var postcode = await api.GetPostnummer("2300");

Usage

Needs the admin key. See Usage.

var today = await api.Usage();
var oneDay = await api.Usage(29, 9, 2026);
var range = await api.Usage(new DateTime(2026, 9, 1), new DateTime(2026, 9, 29));

Result and Failure

Every call returns a Result<T>. When IsSuccess is true, Success holds the response; otherwise Failed is a Failure. Errors are results, not exceptions. Failure.Status is the HTTP status (0 when no response arrived) and Failure.Message says what went wrong. There are two kinds:

var result = await api.GetAdresse(id);

if (!result.IsSuccess)
{
    if (result.Failed.IsNotFound) { /* no such address; costs nothing */ }
    else if (result.Failed.IsQueryParameterFormatError) { var what = result.Failed.Details[0].Name; }
    else if (result.Failed.IsRateLimited) { await Task.Delay(TimeSpan.FromSeconds(result.Failed.RetryAfterSeconds ?? 60)); }
    else if (result.Failed.IsUnauthorized) { /* key missing or unknown */ }
    else { var message = result.Failed.Message; }
}
Top