# Æ, ø og å: tegnsæt og URL-kodning

> Send æøå korrekt URL-kodet, læs UTF-8-svar uden ødelagte tegn, åbn CSV i Excel med de rigtige bogstaver, og forstå oe/aa/ae-foldningen i autocomplete.
>
> https://danadresse.dk/guides/aeoeaa-tegnsaet · verified 2026-11-02
Danske adresser er fulde af æ, ø og å. API'et bruger UTF-8 hele vejen: i URL'en, i JSON og i CSV. Problemer opstår, når et led i kæden bruger et andet tegnsæt, typisk Windows-1252 (også kaldet Latin-1 eller ANSI). Resultatet er enten tomme svar eller tekst som `RÃ¥dhuspladsen`.

## Genkend fejlen

| Du ser | Det skulle være | Årsag |
|---|---|---|
| `Ã¦`, `Ã¸`, `Ã¥` | æ, ø, å | UTF-8 læst som Windows-1252 |
| `Ã†`, `Ã˜`, `Ã…` | Æ, Ø, Å | Det samme med store bogstaver |
| `�` eller `?` | æ, ø eller å | Windows-1252 læst som UTF-8, eller tegnet tabt ved en konvertering |
| `R%E5dhuspladsen` i URL'en | `R%C3%A5dhuspladsen` | Teksten er URL-kodet som Latin-1 |
| `å` i JSON | å | Ikke en fejl. JSON-parseren laver det om til å |

## Send æøå i URL'en

I en URL skal æ, ø og å sendes som UTF-8-bytes, procentkodet:

| Tegn | URL-kodet |
|---|---|
| æ / Æ | `%C3%A6` / `%C3%86` |
| ø / Ø | `%C3%B8` / `%C3%98` |
| å / Å | `%C3%A5` / `%C3%85` |
| mellemrum | `%20` (eller `+` i query-strengen) |

Byg aldrig URL'en ved at sætte tekst sammen. Lad dit bibliotek kode parametrene. Med curl gør `-G` og `--data-urlencode` det for dig:

```bash id=curl-urlencode run=live expect="Rådhuspladsen"
curl -s -G "https://api.danadresse.dk/autocomplete" \
  --data-urlencode "q=Rådhuspladsen 1" \
  --data-urlencode "per_side=3" \
  -H "X-Api-Key: $DANADRESSE_API_KEY"
```

I Python koder `requests` alt, du giver det i `params`:

```python id=python-params run=live expect="%C3%A5"
import os
import requests

r = requests.get(
    "https://api.danadresse.dk/autocomplete",
    params={"q": "Rådhuspladsen 1", "per_side": 1},
    headers={"X-Api-Key": os.environ["DANADRESSE_API_KEY"]},
    timeout=10,
)
r.raise_for_status()
print(r.url)                              # ...?q=R%C3%A5dhuspladsen+1&per_side=1
print(r.json()[0]["forslagstekst"])       # r.json() læser altid UTF-8
```

I PHP bruger du `http_build_query`, som koder UTF-8-strenge korrekt. Brug ikke `utf8_decode` eller `mb_convert_encoding` til Latin-1 før kaldet:

```php id=php-build-query run=live expect="Rådhuspladsen"
<?php
$query = http_build_query(["q" => "Rådhuspladsen 1", "per_side" => 3]);
$ctx = stream_context_create(["http" => [
    "header" => "X-Api-Key: " . getenv("DANADRESSE_API_KEY"),
    "timeout" => 10,
]]);
$body = file_get_contents("https://api.danadresse.dk/autocomplete?$query", false, $ctx);
foreach (json_decode($body, true) as $forslag) {
    echo $forslag["forslagstekst"], "\n";
}
```

I JavaScript bruger du `URL` og `searchParams.set()`, som i [Dit første API-kald](/guides/kom-i-gang).

Kommer din tekst fra et gammelt system, en fil eller en database i Windows-1252, så konverter den til UTF-8, før du sender den. I Python: `tekst = rå_bytes.decode("cp1252")`. På kommandolinjen: `iconv -f WINDOWS-1252 -t UTF-8 ind.csv > ud.csv`.

## Læs svaret som UTF-8

JSON-svar har `Content-Type: application/json` uden en `charset`-parameter. JSON er altid UTF-8, og de fleste klienter ved det: `r.json()` i Python, `res.json()` i JavaScript og `json_decode()` i PHP giver de rigtige tegn.

Problemerne kommer, når en klient gætter tegnsættet ud fra headeren:

- **Windows PowerShell 5.1** (`Invoke-RestMethod`, `Invoke-WebRequest`) læser et svar uden `charset` som Latin-1. Brug PowerShell 7, eller læs bytes og dekod dem selv:

```powershell id=powershell-utf8 run=no
$headers = @{ "X-Api-Key" = $env:DANADRESSE_API_KEY }
$res = Invoke-WebRequest -Uri "https://api.danadresse.dk/postnumre/2900" -Headers $headers -UseBasicParsing
$json = [System.Text.Encoding]::UTF8.GetString($res.RawContentStream.ToArray()) | ConvertFrom-Json
$json.navn
```

- **Ældre HTTP-biblioteker** i fx Java, .NET eller VBA bruger systemets standardtegnsæt, når de laver bytes om til tekst. Angiv UTF-8 eksplicit.
- **Databasen** skal også kunne gemme tegnene. I MySQL og MariaDB skal kolonnen og forbindelsen være `utf8mb4`.

## CSV i Excel

`format=csv` giver UTF-8 uden BOM (byte order mark). Dobbeltklikker du på filen i Excel på Windows, gætter Excel på Windows-1252, og så står der `RÃ¥dhuspladsen`. Der er tre løsninger:

1. **Importér i stedet for at åbne.** I Excel: *Data → Fra tekst/CSV*, vælg filen, og sæt *Filoprindelse* til *65001: Unicode (UTF-8)*.
2. **Power Query.** Angiv tegnsættet direkte:

```m id=power-query-csv run=no
let
    Kilde = Web.Contents(
        "https://api.danadresse.dk/adresser",
        [Query = [postnr = "4200", per_side = "100", format = "csv"],
         Headers = [#"X-Api-Key" = "DIN_API_NØGLE"]]),
    Csv = Csv.Document(Kilde, [Delimiter = ",", Encoding = 65001, QuoteStyle = QuoteStyle.Csv]),
    Tabel = Table.PromoteHeaders(Csv, [PromoteAllScalars = true])
in
    Tabel
```

3. **Gem filen med BOM.** Henter du CSV'en med et script, så skriv den med en BOM foran. Så åbner Excel den rigtigt ved dobbeltklik:

```python id=csv-with-bom run=syntax
import os

import requests

r = requests.get(
    "https://api.danadresse.dk/adresser",
    params={"postnr": "4200", "per_side": 1000, "format": "csv"},
    headers={"X-Api-Key": os.environ["DANADRESSE_API_KEY"]},
    timeout=30,
)
r.raise_for_status()
with open("adresser.csv", "w", encoding="utf-8-sig", newline="") as f:  # utf-8-sig = UTF-8 med BOM
    f.write(r.content.decode("utf-8"))
print("Gemte adresser.csv")
```

Excel med dansk opsætning forventer semikolon som skilletegn. API'ets CSV bruger komma, så vælg komma i importdialogen, eller brug Power Query som ovenfor. Se også [Excel og Power Query](/guides/excel-power-query).

## oe, aa og ae i autocomplete

Brugere skriver ofte uden danske tegn: `raadhuspladsen`, `kobenhavn`, `Soendergade`. `/autocomplete` prøver derfor varianter af det, brugeren har skrevet:

- `aa` → å, `oe` → ø, `ae` → æ (også med stort begyndelsesbogstav)
- et `o` i starten af et ord → ø, så `oster` finder `Øster`
- derudover en stavefejlstolerance, der kan rette et eller to forkerte bogstaver i længere ord

```python id=folding-demo run=live expect="Rådhuspladsen"
import os
import requests

r = requests.get(
    "https://api.danadresse.dk/autocomplete",
    params={"q": "raadhuspladsen 1", "per_side": 3},
    headers={"X-Api-Key": os.environ["DANADRESSE_API_KEY"]},
    timeout=10,
)
r.raise_for_status()
for forslag in r.json():
    print(forslag["forslagstekst"])
```

Foldningen findes i `/autocomplete`. Filtrene på `/adresser` og `/adgangsadresser` (`vejnavn=`, `husnr=`, `postnr=`) laver ikke den samme foldning. Skriv navnene med æ, ø og å. Kommer dine data uden æøå, så kør dem gennem `/autocomplete` eller `/datavask/adresser` først. Datavaskens parser læser stavemåder som `Aabenraa`, `Åbenrå` og `Kobenhavn` og matcher dem med det officielle navn. Se [Ingen resultater?](/guides/ingen-resultater)

## Næste skridt

- [Ingen resultater?](/guides/ingen-resultater)
- [Formater: JSON, CSV, GeoJSON og NDJSON](/guides/formater-json-csv-geojson)
- [Excel og Power Query](/guides/excel-power-query)
