# Cleanse addresses in n8n with the HTTP Request node

> Set up the HTTP Request node in n8n with Header Auth, batching and retries, map the fields from datavask, and import a ready-made workflow.
>
> https://danadresse.dk/en/guides/n8n · verified 2026-11-02
n8n does not need a dedicated Danadresse node. The **HTTP Request** node calls the API, and the JSON response comes out as fields you can use in the next nodes. The short recipe is at [/en/integrationer/n8n](/en/integrationer/n8n). This guide adds field mapping, batching against the per-minute limit, error handling and a workflow you can import.

## 1. Store the key as a credential

Go to **Credentials → Add credential → Header Auth**. Set *Name* to `X-Api-Key` and *Value* to your key, and call the credential `Danadresse`. The key is then stored encrypted in n8n rather than in plain text in the workflow.

## 2. Set up the HTTP Request node

| Setting | Value |
|---|---|
| Method | `GET` |
| URL | `https://api.danadresse.dk/datavask/adgangsadresser` |
| Authentication | Generic Credential Type → Header Auth → `Danadresse` |
| Send Query Parameters | On, Name `betegnelse`, Value `{{ $json.adresse }}` |
| Options → Batching | Items per Batch `1`, Batch Interval `1000` ms |
| Options → Response | *Include Response Headers and Status* on |

Batching makes n8n send one call per second instead of all at once. Without it, a long list can hit the per-minute limit within seconds. On the free plan the limit is 360 calls per minute, so set the interval to match your plan.

With *Include Response Headers and Status* the response sits under `body`, and you also get `statusCode` and `headers`.

`/datavask/adgangsadresser` matches the entrance (street, house number, postcode). To hit a specific flat, use `/datavask/adresser`: it reads floor and door straight from `betegnelse` (`Strandvejen 100, 2. tv, 2900 Hellerup`), and `adresse` then also has `etage`, `dør` and `adgangsadresseid`. Separate query parameters (`vejnavn`, `husnr`, `etage`, `dør`, `postnr`) work too.

## 3. Map the fields

n8n expressions are JavaScript, and lists count from 0. `?.` makes the expression return empty instead of failing when there is no candidate.

| You need | Expression |
|---|---|
| Category | `{{ $json.body.kategori }}` |
| Access address id | `{{ $json.body.resultater[0]?.adresse.id }}` |
| Street and number | `{{ $json.body.resultater[0]?.adresse.vejnavn }} {{ $json.body.resultater[0]?.adresse.husnr }}` |
| Postcode and city | `{{ $json.body.resultater[0]?.adresse.postnr }} {{ $json.body.resultater[0]?.adresse.postnrnavn }}` |
| HTTP status | `{{ $json.statusCode }}` |

Use an **IF** or **Switch** node on the category. A is an exact match. B is one safe match with small spelling differences: continue, and store the official text from `adresse`. C (several candidates or larger differences) goes to manual review and is never accepted automatically.

The cleanse answer has no municipality or coordinates. If you need them, add a second HTTP Request node with the URL `https://api.danadresse.dk/adgangsadresser/{{ $json.body.resultater[0].adresse.id }}` and the same credential. Read `kommune.kode`, `kommune.navn` and `adgangspunkt.koordinater[0]` / `[1]` (longitude, latitude) from its response. That is one extra call per row.

## 4. Errors and 429

Open the node's **Settings**:

- **Retry On Fail**: on, *Max Tries* `3`, *Wait Between Tries* `5000` ms (the most n8n allows). At the per-minute limit (`rate_limit_per_minute`) the API sends `Retry-After` with the seconds until the minute window resets (1-60), so a retry after 5 seconds can come too early. With batching as above that is rare.
- **On Error**: *Continue (using error output)*. The node then gets an extra output for rows that still fail after the retries. Connect it to a node that logs the address and the error.

Retries do not help when the code is `quota_exceeded`. That means the free plan's monthly quota and its 20 % grace are used up. The response has no `Retry-After`, and the quota resets on the 1st of next month. Error responses on the DAWA paths have a `code` field, so you can tell them apart in the error branch. For `quota_exceeded`, `title` explains it in plain language and `details` has `resets_at` and `upgrade_url`. Refused calls are not counted.

If you would rather control it all yourself, turn on *Never Error* under *Options → Response*. Every response then leaves through the normal output, and you can send `statusCode` 429 with `body.code` = `rate_limit_per_minute` to a **Wait** node that waits `{{ $json.headers['retry-after'] }}` seconds, and back.

## 5. Import a ready-made workflow

Copy the JSON and paste it onto an empty canvas in n8n with Ctrl+V or Cmd+V. Then pick your `Danadresse` credential in the HTTP Request node and run the workflow.

```json id=n8n-workflow run=syntax
{
  "name": "Danadresse datavask",
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [0, 0]
    },
    {
      "parameters": {
        "jsCode": "return [\n  { json: { adresse: 'Strandvejen 100, 2900 Hellerup' } },\n  { json: { adresse: 'Rådhuspladsen 1, 1550 København V' } }\n];"
      },
      "name": "Testadresser",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [220, 0]
    },
    {
      "parameters": {
        "url": "https://api.danadresse.dk/datavask/adgangsadresser",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [{ "name": "betegnelse", "value": "={{ $json.adresse }}" }]
        },
        "options": {
          "batching": { "batch": { "batchSize": 1, "batchInterval": 1000 } },
          "response": { "response": { "fullResponse": true } }
        }
      },
      "name": "Datavask",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [440, 0],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000,
      "onError": "continueErrorOutput"
    }
  ],
  "connections": {
    "Start": { "main": [[{ "node": "Testadresser", "type": "main", "index": 0 }]] },
    "Testadresser": { "main": [[{ "node": "Datavask", "type": "main", "index": 0 }]] }
  }
}
```

## Test the call

The same call the node makes, from a terminal:

```bash id=test-call run=live expect="kategori"
curl -s "https://api.danadresse.dk/datavask/adgangsadresser?betegnelse=Strandvejen%20100%2C%202900%20Hellerup" \
  -H "X-Api-Key: $DANADRESSE_API_KEY"
```

## Next steps

- [Make](/en/guides/make) and [Zapier](/en/guides/zapier)
- [Limits, quotas and 429](/en/guides/graenser-og-429)
- Short recipe: [/en/integrationer/n8n](/en/integrationer/n8n)
