Skip to main content

Domain data, ready to download.

A small REST API for daily domain snapshots, new domains, expired domains, and historical files. Responses are JSON; bulk data is streamed as gzip or zip.

Base URL https://primitive.host/api/v1
Authentication Authorization: Bearer ph_…

Overview

  • Daily snapshots refreshed once per day at 02:00 UTC.
  • Zone files contain one sorted, deduplicated domain per line — only domains first indexed during the snapshot's UTC day (the previous day relative to the run), not the full zone.
  • A snapshot dated {date} covers {date} 00:00 → 24:00 UTC; new/ and expired/ use the same window.
  • Latest downloads use /dl/; historical downloads use /dl/{date}/.
  • Historical snapshots are retained for a configurable period, defaulting to 30 days.
  • Storage: dated keys snapshots/{date}/zones/{zone}.txt.gz; flat keys zones/… are aliases to latest.

Authentication

Create an API token in Account Settings → API Tokens. Tokens are shown once and use the ph_… format.

curl -H "Authorization: Bearer ph_YOUR_TOKEN" \ https://primitive.host/api/v1/zones/
●Keep tokens private. Missing, invalid, or revoked tokens return 401. A valid token still needs an active Data Access subscription — without one every endpoint returns 402.

Zones

GET /zones/ List zones and counts ▶

Returns all zones with suffix_type, domains (total size of the zone), domains_24h (domains in the latest snapshot, i.e. added on the previous UTC day; null when no snapshot metadata is available yet), last_run, and last_date. Query parameters are not accepted.

curl -H "Authorization: Bearer ph_…" \ https://primitive.host/api/v1/zones/
GET /zones/{zone}/ Zone details ▶

Returns details for one zone: domains (total) and domains_24h (previous UTC day snapshot count). Unknown zones return 404.

GET /zones/{zone}/dl/ stream Latest zone file ▶

Streams the latest zone file as gzip-compressed text: the domains first indexed on the previous UTC day. The flat storage key is zones/{zone}.txt.gz. A zone with no domains indexed that day returns a valid but empty gzip (0 lines) — check rows in /zones/{zone}/meta/ or domains_24h first. Response headers X-Snapshot-Date and X-Domains-Count carry the same values.

curl -H "Authorization: Bearer ph_…" \ https://primitive.host/api/v1/zones/com/dl/ \ -o com.txt.gz
GET /zones/{zone}/dl/{date}/ stream Dated zone file ▶

Streams a specific snapshot using YYYY-MM-DD: domains first indexed on that UTC day. The dated key is snapshots/{date}/zones/{zone}.txt.gz. Also returns X-Snapshot-Date and X-Domains-Count headers; unknown dates return 404.

curl -H "Authorization: Bearer ph_…" \ https://primitive.host/api/v1/zones/com/dl/2026-08-30/ \ -o com-2026-08-30.txt.gz
GET /zones/{zone}/meta/ Latest zone metadata ▶

Returns metadata for the latest zone file without downloading it: key, size (compressed bytes), last_modified, exists, plus zone, suffix_type, domains (zone total), snapshot_date, rows (line count in the file) and domains_24h (same value while snapshot_date is the latest snapshot). rows is 0 for zones with no domains indexed that day, and null when no snapshot metadata exists yet.

curl -H "Authorization: Bearer ph_…" \ https://primitive.host/api/v1/zones/sh/meta/
GET /zones/{zone}/meta/{date}/ Dated zone metadata ▶

Same fields for one snapshot date (YYYY-MM-DD) — snapshot_date is the requested date and rows is that snapshot's line count. Missing snapshot files return 404.

curl -H "Authorization: Bearer ph_…" \ https://primitive.host/api/v1/zones/com/meta/2026-10-05/

New domains

GET /new/ Latest metadata ▶

Returns metadata such as size and last_modified for new/domains.txt.gz.

GET /new/dl/ stream Latest download ▶

Streams the latest new-domain file as gzip-compressed text.

GET /new/{date}/ Dated metadata ▶

Returns metadata for new domains on the requested date.

GET /new/dl/{date}/ stream Dated download ▶

Streams snapshots/{date}/new/domains.txt.gz.

curl -H "Authorization: Bearer ph_…" \ https://primitive.host/api/v1/new/dl/2026-08-30/ \ -o new-2026-08-30.txt.gz

Expired domains

GET /expired/ Latest metadata ▶

Returns metadata such as size and last_modified for expired/domains.txt.gz.

GET /expired/dl/ stream Latest download ▶

Streams the latest expired-domain file as gzip-compressed text.

GET /expired/{date}/ Dated metadata ▶

Returns metadata for expired domains on the requested date.

GET /expired/dl/{date}/ stream Dated download ▶

Streams snapshots/{date}/expired/domains.txt.gz.

All zones bundle

ZIP stream
GET /all/dl/ Download every zone ▶

Streams a latest-only ZIP containing one .txt.gz file per zone (same previous-UTC-day window as the zone files). There is no dated history for this bundle.

curl -H "Authorization: Bearer ph_…" \ https://primitive.host/api/v1/all/dl/ \ -o all.zip

History & dates

GET /snapshot-dates/ auth Available dates ▶

Returns available dates in ascending YYYY-MM-DD order. Retention defaults to 30 days and is configurable by the service.

curl -H "Authorization: Bearer ph_…" \ https://primitive.host/api/v1/snapshot-dates/

Dated objects use snapshots/{date}/zones/, snapshots/{date}/new/, and snapshots/{date}/expired/. Flat zones/, new/, and expired/ paths point to the latest promoted snapshot.

Errors & limits

400Bad date format or unsupported query parameters.
401Missing, invalid, or revoked token.
402Valid token, but no active Data Access subscription on the account.
404Unknown zone, missing object, or date outside retention.
409No zone snapshot has been generated yet.

There is no pagination for bulk data. Use the download endpoints for complete files.

Examples

List a zone, then download it

TOKEN=ph_xxx curl -H "Authorization: Bearer $TOKEN" \ https://primitive.host/api/v1/zones/ | jq '.zones[0]' curl -H "Authorization: Bearer $TOKEN" \ https://primitive.host/api/v1/zones/ru.com/dl/ \ -o ru.com.txt.gz gunzip -c ru.com.txt.gz | head

Check a token

curl -i -H "Authorization: Bearer $TOKEN" \ https://primitive.host/api/v1/zones/ | head -1 # HTTP/1.1 200 or 409 → valid; 401 → invalid