Error 401: missing or invalid API key
Find the cause of 401 missing_api_key and invalid_api_key with a checklist and a small diagnostic script, and fix the key or the way you send it.
Status 401 means the API does not know who you are. Either no key came with the call (missing_api_key), or the key is not recognised (invalid_api_key). Every call needs a key, the DAWA-compatible ones included, so this is the error people meet most often right after switching from DAWA.
What you see
On the DAWA paths (/adresser, /autocomplete and so on):
{
"type": "UnauthorizedError",
"title": "This API requires an X-Api-Key header. Get a free key in 30 seconds at https://danadresse.dk/dashboard/signup — then add 'X-Api-Key: <your key>' to every request.",
"details": null,
"code": "missing_api_key"
}{
"type": "UnauthorizedError",
"title": "The provided API key is invalid or revoked.",
"details": null,
"code": "invalid_api_key"
}On /api/v1 the same code is in error.code. See The error format.
Run the diagnostic script first
The script checks the usual mistakes in the key itself and then makes one call:
import os import re import requests raw = os.environ.get("DANADRESSE_API_KEY") if raw is None: raise SystemExit("DANADRESSE_API_KEY is not set in this environment") key = raw.strip().strip('"').strip("'") if key != raw: print("Warning: the key had whitespace, a line break or quotes around it") if not re.fullmatch(r"dawa_(live|test)_[0-9a-f]{64}", key): print(f"Warning: the key does not have the expected format (length {len(key)})") r = requests.get( "https://api.danadresse.dk/postnumre/8000", headers={"X-Api-Key": key}, timeout=10, ) try: code = r.json().get("code") except ValueError: code = None print(r.status_code, code or "OK")
If you get 200 OK, the key is fine and the problem is in how your application sends it. Go through the checklist.
missing_api_key: the key did not arrive
The header has the wrong name.
- Cause: The key was sent as
Authorization: Bearer …,Api-Key,apikeyor in the JSON body. The API only reads theX-Api-Keyheader and theapi_keyquery parameter. Only the remote MCP server at/mcpalso acceptsAuthorization: Bearer <key>. - Fix: Use
X-Api-Key: <key>. Upper and lower case in the header name do not matter.
The environment variable is empty where the code runs.
- Cause: The key is set in your terminal, but not in systemd, Docker, cron, CI or the hosting panel. The header goes out as
X-Api-Key:with no value, and an empty header counts as missing. - Fix: Log the length of the key (never the key itself) at startup, and stop the program if it is 0.
A proxy or framework strips the header.
- Cause: Some reverse proxies, API gateways and serverless platforms only forward known headers.
- Fix: Test with curl directly against
https://api.danadresse.dkfrom the same machine. If that works, allowX-Api-Keyin the proxy, or send the key asapi_keyin the URL.
The call goes to http://.
- Cause:
http://api.danadresse.dkanswers with a redirect (301) tohttps://. curl without-Ljust shows an HTML page, and some HTTP clients drop headers or the body when they follow a redirect. - Fix: Always use
https://.
The key sits in a widget setting that is not used.
- Cause: DAWA's old widget reads the key from the script URL (
?key=…), fromdata-api-keyon the script tag, or from theapiKeyandparams.api_keyoptions. Anywhere else, the widget sends no key. - Fix: See From dawa-autocomplete2.
invalid_api_key: the key was not recognised
The key is mistyped or truncated.
- Cause: Copied without the last characters, or with an extra one. A key is
dawa_live_ordawa_test_followed by 64 characters from 0-9 and a-f. - Fix: Run the diagnostic script. If the format is wrong, create a new key under Keys. The key is shown only once, so it cannot be retrieved again.
Quotes or a line break in the key.
- Cause:
.envfiles withKEY="…"read by a tool that does not strip the quotes, or a key with a line break from a file. Whitespace around a key in the header is stripped. Inapi_key=in the URL it is not. - Fix: Strip quotes and whitespace when you read the key.
The key was deleted or rotated.
- Cause: Someone deleted the key in the dashboard, or it was replaced and the old one is still in an environment.
- Fix: Check under Keys which keys are active (the last four characters are shown), and update the configuration.
Both header and URL hold a key.
- Cause: The header wins. An old key in the header gives
invalid_api_keyeven if the URL holds the new one. - Fix: Send only one of them.
A key from another product.
- Cause: A Datafordeler key or a key from another service in the same variable.
- Fix: Use a key from danadresse.dk/dashboard/keys.
401 on the dashboard API
Endpoints such as /api/v1/keys and /api/v1/webhooks use a login token (JWT) in Authorization: Bearer …, not an API key. Without a token you get error.code unauthorized. With an expired or wrong token you get invalid_token. Get a new token with POST /api/v1/auth/login.
Next steps
- Header or api_key in the URL
- Error 403: access denied, if the key is recognised but refused.
- Test keys and the sandbox
Related guides
Markdown source Spotted an error? Tell us API-reference (Swagger)