# Vask adresser i Power Automate med HTTP-handlingen

> Kald datavask fra et Power Automate-flow med HTTP-handlingen, parse svaret med et færdigt JSON-skema og håndter 429 og tomme resultater.
>
> https://danadresse.dk/guides/power-automate · verified 2026-11-02
Et Power Automate-flow kan vaske en adresse, hver gang der kommer en ny række i SharePoint, Dataverse, Excel Online eller et Microsoft Forms-svar. Du bruger den indbyggede **HTTP**-handling, et **Parse JSON**-trin og en betingelse på kategorien.

> [!NOTE]
> HTTP-handlingen er en premium-connector. Den kræver en Power Automate Premium-licens (eller en licens pr. flow). Det samme gælder brugerdefinerede connectors, så der er ingen vej uden om premium for at kalde et eksternt API.

## 1. Tilføj HTTP-handlingen

Efter din trigger: **Nyt trin → HTTP**. Udfyld:

| Felt | Værdi |
|---|---|
| Method | `GET` |
| URI | `https://api.danadresse.dk/datavask/adgangsadresser` |
| Headers | `X-Api-Key` = din nøgle |
| Queries | `betegnelse` = adressefeltet fra triggeren (dynamisk indhold) |

Brug **Queries** i stedet for at sætte adressen ind i URI'en. Så koder Power Automate selv mellemrum, komma og æøå.

Åbn handlingens **Indstillinger** og slå **Sikre input** til. Ellers står nøglen i klar tekst i kørselshistorikken. I en løsning (solution) kan du lægge nøglen i en miljøvariabel af typen *Hemmelighed* i stedet for at skrive den i handlingen.

## 2. Parse svaret

Tilføj **Data Operation → Parse JSON**. Indhold: `Body` fra HTTP-handlingen. Skema:

```json id=parse-schema run=syntax
{
  "type": "object",
  "properties": {
    "kategori": { "type": "string" },
    "resultater": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "adresse": {
            "type": "object",
            "properties": {
              "id": { "type": "string" },
              "href": { "type": "string" },
              "status": { "type": "integer" },
              "vejnavn": { "type": ["string", "null"] },
              "adresseringsvejnavn": { "type": ["string", "null"] },
              "husnr": { "type": ["string", "null"] },
              "supplerendebynavn": { "type": ["string", "null"] },
              "postnr": { "type": ["string", "null"] },
              "postnrnavn": { "type": ["string", "null"] },
              "virkningstart": { "type": ["string", "null"] },
              "virkningslut": { "type": ["string", "null"] }
            }
          },
          "vaskeresultat": {
            "type": "object",
            "properties": {
              "afstand": { "type": "integer" },
              "ukendtetokens": { "type": "array" }
            }
          }
        }
      }
    }
  },
  "required": ["kategori", "resultater"]
}
```

Felter som `supplerendebynavn` er ofte `null`. Står typen kun som `"string"`, fejler Parse JSON på de adresser. Derfor `["string", "null"]`. Genererer du skemaet fra et eksempel, hvor feltet har en tekst, bliver typen kun `string`, og flowet fejler senere på en adresse, hvor feltet er `null`.

## 3. Brug felterne

`resultater` er en liste med det bedste match først. Hent felterne med udtryk:

```text id=expressions run=no
first(body('Parse_JSON')?['resultater'])?['adresse']?['id']
first(body('Parse_JSON')?['resultater'])?['adresse']?['postnr']
first(body('Parse_JSON')?['resultater'])?['adresse']?['postnrnavn']
first(body('Parse_JSON')?['resultater'])?['adresse']?['vejnavn']
```

`?['…']` gør, at udtrykket giver `null` i stedet for en fejl, når `resultater` er tom.

Vaskesvaret har den officielle vej, husnummer, postnummer og by, men ikke kommune eller koordinater. Skal du bruge dem, så tilføj en HTTP-handling mere med `GET https://api.danadresse.dk/adgangsadresser/{id}` (`id` fra ovenfor), og læs `kommune.kode`, `kommune.navn` og `adgangspunkt.koordinater` (længde, bredde) fra dens body.

Tilføj en **Betingelse** på `kategori`. A er et præcist match. B er ét sikkert match med små stavefejl: skriv det tilbage med den officielle tekst fra `adresse`. C er usikkert (flere kandidater eller større afvigelser): send det til manuel kontrol, fx som en opgave i Planner eller en mail, og godkend det aldrig automatisk. Kategori C med en tom `resultater` betyder, at der ikke blev fundet nogen kandidat.

`/datavask/adgangsadresser` matcher opgangen (vej, husnummer, postnummer). Skal du have den præcise lejlighed, så brug `/datavask/adresser`: den læser etage og dør direkte fra `betegnelse` (`Strandvejen 100, 2. tv, 2900 Hellerup`), og `adresse` har så også `etage`, `dør` og `adgangsadresseid`. Har du delene i separate felter, kan du i stedet sende `vejnavn`, `husnr`, `etage`, `dør` og `postnr` som hver sin query-parameter.

## 4. Fejl og 429

HTTP-handlingen fejler ved alle svar på 400 eller derover. Standardpolitikken for genforsøg prøver igen ved 408, 429 og 5xx. To slags 429 kan forekomme:

- `rate_limit_per_minute` med `Retry-After` (1-60 sekunder): for mange kald i minuttet. Et genforsøg hjælper.
- `quota_exceeded` uden `Retry-After`: gratisplanens månedskvote og dens buffer på 20 % er brugt. Genforsøg hjælper ikke før den 1. i næste måned. Svaret siger det i klar tekst, og `details` har `resets_at` (hvornår det ophører) og `upgrade_url`.

Afviste kald tæller ikke, så genforsøgene koster ingenting.

Sæt **Genforsøgspolitik** til *Fast interval*, 2 forsøg, interval `PT10S`. Tilføj derefter en handling, fx en mail til dig selv, og sæt dens **Konfigurer kør efter** til *mislykkedes* og *fik timeout*. Så opdager du, hvis nøglen er spærret (401/403) eller kvoten er brugt.

Kører flowet på mange rækker på én gang, så sæt **Samtidighedskontrol** på din *Apply to each* til en lav værdi. Ellers rammer du minutgrænsen.

## Test kaldet

Samme kald som HTTP-handlingen, fra en terminal:

```bash id=test-call run=live expect="kategori"
curl -s "https://api.danadresse.dk/datavask/adgangsadresser?betegnelse=R%C3%A5dhuspladsen%201%2C%201550%20K%C3%B8benhavn%20V" \
  -H "X-Api-Key: $DANADRESSE_API_KEY"
```

## Næste skridt

- [Make](/guides/make), [Zapier](/guides/zapier) og [n8n](/guides/n8n) — samme opsætning i andre værktøjer.
- [Grænser, kvoter og 429](/guides/graenser-og-429)
