At a glance
| Item | Detail |
|---|---|
| Address | https://[download hostname]/pdns/dwl/v1 |
| Access | HTTPS requests (GET) |
| Authentication | API token, sent as Authorization: Bearer <token> |
| Record types | A, AAAA, CNAME, MX, NS, TXT |
| File format | Compressed (gzip) newline-delimited JSON: one record per line |
| Each file covers | Four hours of observations for one record type, in UTC |
| Files change after publishing? | Never |
| Interrupted downloads | Can be resumed from where they stopped |
Authentication
Daily Downloads uses API tokens. Create one in the Spamhaus Customer Portal and send it in the Authorization header with every request:
Authorization: Bearer <your API token>
Daily Downloads accepts API tokens only, not single sign-on. Your account also needs Daily Downloads enabled. Every request needs a token: nothing is available without one.
What you can request
| Request | What you get |
|---|---|
GET /pdns/dwl/v1/list/{date} |
The files available for one day. Use this for routine checks. |
GET /pdns/dwl/v1/list |
Every day available, with its files. It covers the whole history, so use it for a first full download rather than routine checks. |
GET /pdns/dwl/v1/file/{date}/{name} |
The file itself. |
Dates are always written as YYYY-MM-DD in UTC, with leading zeros: 2026-09-01, not 2026-9-1.
Each file in a listing comes with its name, record type, the start of the four hours it covers, its size, when it was published and a ready-made download path. Use that path rather than building your own.
What's in a file
File names
Every file name follows the same pattern: pdns_<record type>_<date>_<start time>.json.gz.
For example, pdns_A_20260916_0800.json.gz holds A records for the four hours starting 08:00
UTC on 16 September 2026.
Occasionally a second file is produced for the same four hours. It has a number added before
the extension, such as pdns_NS_20260916_1600_2.json.gz. It holds additional records, not a
replacement, so download both.
What a record looks like
{"rrname":"example.com","rrtype":1,"rdata":"192.0.2.10"}
| Field | Meaning |
|---|---|
rrname |
The DNS name observed. |
rrtype |
The record type as a number: 1 = A, 28 = AAAA, 5 = CNAME, 15 = MX, 2 = NS, 16 = TXT. File names use the letters; records use the number. |
rdata |
The record's value, such as an IP address or host name. |
Files can be large, so read them a line at a time rather than loading a whole file into memory.
Keep your copy up to date
- Create an API token in the Spamhaus Customer Portal.
- Check today's and yesterday's listings more often than every four hours, so you see each new file soon after it's published.
- Compare each file's name and size with what you already hold. Because files never change, a name you already have is a file you already have.
- Download any new file using the path from the listing.
- If a download is interrupted, resume it from where it stopped rather than starting again.
Most download tools can do this; for example, curl's
-C -option. - Check the downloaded size against the size in the listing.
- Read each file a line at a time and load the records into your own systems.
Good to know
- Everything is in UTC. Dates and four-hour periods follow UTC and don't change with daylight saving.
- Files arrive after their four hours end. A file is published a few minutes after the period it covers.
- Keep checking yesterday after midnight. Yesterday's last file arrives shortly after midnight UTC, so don't stop checking a date as soon as it changes.
- A day with nothing published yet is not an error. Its listing returns an empty list of files. Check the file count, not the response code.
- Files never change. You can keep them for as long as you need and never download the same file twice.
- The same record can appear in more than one file. That means it was seen again in a later period. Records are unique within a file; if you want unique records across files, remove repeats yourself.
- Don't ask for extra compression. Files are already compressed.
- Each download has a time limit. A very slow download can be closed before it finishes. Resume it rather than starting again.
- Older files may contain blank lines between records. Most tools skip them automatically. If yours doesn't, skip empty lines when reading.
Troubleshooting
| What you see | What to do |
|---|---|
| HTTP 401 | The token is missing, wrongly formatted, invalid or expired. Check the Authorization header and use a current API token. |
| HTTP 403 | The token is valid, but the account doesn't have Daily Downloads. Signing in again won't help; contact us to add it to your account. |
| HTTP 400 | The date or file name is wrongly formatted. Dates must be YYYY-MM-DD with leading zeros. |
| HTTP 404 | That file doesn't exist. Use the path from the listing. |
| HTTP 503 | A temporary problem on our side. Wait and try again, leaving longer gaps between attempts. Nothing is wrong with the data. |
| A download stops part-way | Resume it from where it stopped. See step 5 in Keep your copy up to date. |
| A listing shows no files | Nothing has been published for that day yet. Check again later. |
Learn more
- Daily Downloads technical reference
- Real Time Streaming: new observations as they're seen
- API Reference
Want Daily Downloads for your team? Talk to us about access.