Go-live checklist for your address integration

Go through keys, limits, error handling, caching, data and monitoring before your Danadresse integration goes into production.

4 min Level: Beginner ✓ Code tested

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.dk and www.firma.dk. See Browser keys and allowed domains.
  • Server code sends the key in the header X-Api-Key, not as api_key in 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 answers 429 quota_exceeded for 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: 429 on the per-minute limit, 503, 502, 504 and network errors, with backoff and Retry-After. Never 401, 403, 400 or quota_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

Data

Monitoring

  • You log X-RateLimit-Remaining and get an alert at 80 percent of the monthly quota. On Hobby you also alert when X-Quota-Grace: true shows 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 send X-Api-Key, so use api_key with a domain-locked browser key, or switch to fetch.

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:

Python#preflight
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)

Try it with a free key

2,000 calls/month on the free plan. No credit card.

Create account →