Go-live checklist for your address integration
Go through keys, limits, error handling, caching, data and monitoring before your Danadresse integration goes into production.
Most of what goes wrong in production is not the calls themselves but everything around them: a test key that made it into production, a key sitting in a public page without a domain lock, or an address field that goes blank when a limit is hit.
This list collects the points worth checking before you go live. Each point links to a guide with the details.
Keys
- Use a live key. Test keys (
dawa_test_…) are counted per IP address at the free plan's level, and they cannot call/api/v1/enrich/…. See Test keys and sandbox. - One key per environment and service. Then you can rotate or revoke one without hitting the others, and the dashboard shows which one is in use.
- The key lives in a secret store, not in the code and not in Git. See Rotate API keys.
- Keys in web pages are locked to your domains under Tilladte domæner (allowed domains). Remember both
firma.dkandwww.firma.dk. See Browser keys and allowed domains. - Server code sends the key in the header
X-Api-Key, not asapi_keyin the URL.
Limits
- You know your expected usage per month and per minute and have picked a plan that fits. See the plans on the front page.
- On Hobby the quota is a ceiling. After 2,000 calls you are served from a grace buffer up to 2,400 calls (header
X-Quota-Grace: true). After that the API answers429 quota_exceededfor the rest of the month. - On a paid plan you have set a budget cap, if overage must not run freely. It is set under Billing. Without a cap, calls beyond the quota are billed as overage.
- Batch jobs keep their pace below the per-minute limit (360 on Hobby, 1,700 on Basis, 7,000 on Pro). See Monitor usage.
- The full dataset is fetched with replication, not with thousands of single calls. See First extract.
Error handling
- Every call has a timeout, e.g. 10 seconds.
- You only retry what can succeed:
429on the per-minute limit,503,502,504and network errors, with backoff andRetry-After. Never401,403,400orquota_exceeded. See Retries and backoff. - You branch on
code, not on the error text. See The error format. - The user can carry on if the API does not answer. An address field in a checkout must accept manual input, and the order must go through.
Performance
- Autocomplete has a debounce of 150 to 250 ms and cancels stale calls. See Hand-built DAWA autocomplete.
- Lookups that do not change are cached, e.g. postcodes and municipalities. Error responses are never cached. See Caching address lookups.
- List calls are paginated with
sideandper_side. See Pagination.
Data
- You store the address id, not just the text. See Store the address id.
- You have a plan for addresses that get retired. See status, darstatus and retired addresses.
- The attribution is on your pages: "Contains data from Klimadatastyrelsen (CC BY 4.0)". See Data licence, attribution and personal data.
- Only the address is sent to the API, never names, emails or phone numbers.
Monitoring
- You log
X-RateLimit-Remainingand get an alert at 80 percent of the monthly quota. On Hobby you also alert whenX-Quota-Grace: trueshows up: the quota is then used and the grace buffer has started. - You react to
X-Danadresse-Key-Status. If it is set, the key is flagged as possibly leaked. - You know where to find service status: the status page. Changes to the API are in the changelog. Questions and bug reports go through support.
Migrated from DAWA?
- No DAWA URLs are left in code or configuration, and CI fails if they come back. See Find DAWA calls with migrate-cli.
- You have checked the list of known differences against the endpoints and fields you use. See Move from DAWA.
- JSONP has the key in the URL, if your frontend uses
callback. A<script>tag cannot sendX-Api-Key, so useapi_keywith a domain-locked browser key, or switch tofetch.
Run a final check
The script runs with the key you are going live with. It warns if it is a test key, makes one call and shows how much room there is:
import os import requests key = os.environ["DANADRESSE_API_KEY"] if key.startswith("dawa_test_"): print("WARNING: this is a test key. Use a live key in production.") r = requests.get( "https://api.danadresse.dk/autocomplete", params={"q": "Rådhuspladsen 1", "per_side": 1}, headers={"X-Api-Key": key}, timeout=10, ) print(f"autocomplete: {r.status_code}") print("monthly quota:", r.headers.get("X-RateLimit-Limit"), "- left:", r.headers.get("X-RateLimit-Remaining")) print("per minute: ", r.headers.get("X-RateLimit-Minute-Limit")) status = r.headers.get("X-Danadresse-Key-Status") if status: print(f"WARNING: the key is flagged as {status}") if r.status_code != 200: print(r.text) raise SystemExit(1)
When everything is green, run the smoke test from Move from DAWA with the endpoints your code uses.
Related guides
Markdown source Spotted an error? Tell us API-reference (Swagger)