The webatla API
Pull the domain database straight into your own stack. Authenticate with a Bearer key, download a whole dataset or one slice as compressed JSONL, and filter it locally. No per-row metering.
How the API works
The API serves whole files, not a live query endpoint. You download a full dataset or a single slice, then slice and filter it on your own machine. That keeps downloads fast and puts no cap on how you query.
1. Create a key
Generate a Bearer API key in your account, optionally locked to an IP allowlist. Send it as an Authorization header.
2. Download files
Fetch the full export, or one slice by TLD, TLD suffix, country or technology. Resume interrupted downloads with a Range request.
3. Filter locally
Decompress with zstd and query with jq, a warehouse or your own code. One dimension per slice, intersect the rest yourself.
Authentication
Most endpoints require a Bearer API key. The public catalogue, preview and sample endpoints need no auth.
- Create and manage keys in your account. The full key is shown once at creation, so store it safely.
- Send it as
Authorization: Bearer wbtl_…on every authenticated request. - Optionally restrict a key to an IP allowlist. Requests from other addresses get
401. - Keys are rate limited per key. Rotate or revoke a key at any time.
Endpoints
The full, machine-readable contract lives at /api/v1/openapi.json (OpenAPI 3.1).
| Method | Endpoint | Auth | Rate limit | Purpose |
|---|---|---|---|---|
| GET | /api/v1/datasets | Public | 60/min | List published datasets with price and row counts |
| GET | /api/v1/preview/{scope}/{key} | Public | 60/min | Free preview rows for a scope |
| GET | /api/v1/sample/{scope}/{key} | Public | 60/min | Free sample export for a scope |
| GET | /api/v1/me | Bearer | 200/min | The current key's user and scopes |
| GET | /api/v1/me/orders | Bearer | 200/min | Your orders and their status |
| GET | /api/v1/me/downloads | Bearer | 200/min | Your download history (?limit= up to 500) |
| GET | /api/download/{slug} | Bearer | 240/min | Full dataset export as .jsonl.zst |
| GET | /api/download/{slug}/{scope}/{key} | Bearer | 240/min | One per-scope slice of a dataset |
scope is one of tld, tld_suffix, country or technology. Download endpoints require paid, unexpired access to that dataset.
Quickstart
Every download is one file. Pull the whole dataset, or narrow to a single dimension first.
Download the full export
Download a single slice
curl, resume and local filter
List past downloads with GET https://webatla.com/api/v1/me/downloads. Try a free preview with no key: GET https://webatla.com/api/v1/preview/tld/com?dataset=all-data.
Data format
Files are JSON Lines (one JSON object per line), zstd-compressed. The schema is shared across datasets, so signals line up on the same domain key.
- Each line is one domain. Decompress with
zstd -dor stream withzstdcat. - Column names can contain spaces, so read them with bracket keys in jq, for example
.["Country by IP"]. - Fields may be missing or null. Default them, for example
.Registrar // "". - Dates are ISO 8601 strings, for example
"2026-11-18T04:47:13.573"or"2026-04-22".
Column reference
| Column | Type | Example | Datasets |
|---|---|---|---|
| Domain | string | "arriva.com.hr" | d1–d7 |
| TLD suffix | string | "com.hr" | d1–d7 |
| TLD | string | "hr" | d1–d7 |
| Domain type | string: "ICANN" | "PRIVATE" | "ICANN" | d1–d4, d6, d7 |
| HTTP status | integer | null | 200 | d3, d6, d7 |
| IP address | string | null | "31.13.236.27" | d3, d6, d7 |
| Country by IP | string (ISO-2) | null | "DE" | d2, d3, d6, d7 |
| Social networks | object | null | {"facebook": ["https://…"]} | d3, d6, d7 |
| Technologies last data checked | string (date) | null | "2026-04-22" | d3, d6, d7 |
| Technologies | array | object | null | ["WordPress"] / {"PHP": "4.4.9"} | d3, d6, d7 |
| DNS last data checked | string (date) | "2026-06-03" | d4, d6, d7 |
| DNS Status | string: "TRUE" | "FALSE" | "TRUE" | d4, d6, d7 |
| DNS records | object | null | {"A": ["31.13.236.27"], "MX": [{"host": "…", "priority": 0}]} | d4, d6, d7 |
| PR value | number | 4.808574e-9 / 0 | d2, d3, d6, d7 |
| Harmonic value | number | 10305265 / 0 | d2, d3, d6, d7 |
| RDAP/WHOIS last date checked | string (date) | "2026-01-04" | d5, d7, d6* |
| RDAP/WHOIS method | string: "rdap" | "whois" | "whois" | d5, d7, d6* |
| Domain creation date | string (ISO 8601) | null | "2024-12-12T14:04:04" | d2, d3, d5, d6, d7 |
| Domain expiration date | string (ISO 8601) | null | "2026-12-12T14:04:04" | d2, d3, d5, d6, d7 |
| Domain last changed | string (ISO 8601) | null | "2026-01-04T04:43:01" | d5, d7, d6* |
| Registrar | string | null | "REGRU-RU" | d5, d6, d7 |
| RDAP/WHOIS Record | object | null | {"raw_response": "% TCI Whois…"} | d5, d6* |
| Response Status RDAP/WHOIS | string | "Domain is active" | d5, d6* |
Datasets: d1 All active domains · d2 Websites + Ranking · d3 Technologies · d4 DNS · d5 RDAP & WHOIS · d6 All data · d7 Domain Investor.
* In All data (d6) the RDAP/WHOIS fields are present only for the domains that carry a registration record.
Nested field shapes
Technologiesis either an array of names or an object of name to version.DNS Statusis the string"TRUE"or"FALSE", not a boolean.DNS recordsmaps a record type to its values:A, AAAA, NS, SOA, TXT, MX, CNAME, CAA, HTTPS, DNSKEY, DS, SRV, PTR….MXis[{"host", "priority"}].Social networksmaps a platform to profile links:facebook, instagram, x-twitter, linkedin, youtube, whatsapp, telegram, tiktok, github…. These are the site's own public links, not a person's contact.RDAP/WHOIS Recordholds the raw registration record, redacted of personal fields per ICANN rules.
Recipes
Verified against real export files. Everything runs locally after you download a file.
Count, extract and export to CSV
Filter by technology
DNS and expiry
Python
Response codes and limits
Errors return a JSON body of the shape {"error": "…"}. Rate-limit headers are returned on every request.
| Code | Meaning |
|---|---|
| 200 / 206 | Success. 206 is a partial (resumed) download. |
| 302 | A browser session is missing on a download route. API keys get 401 instead. |
| 401 | Missing, invalid or IP-blocked API key. |
| 403 | No active paid access to this dataset. |
| 404 | Unknown dataset or entity, or the file is not uploaded yet. |
| 416 | Malformed or multipart Range request. |
| 429 | Rate limit exceeded. Back off and retry. |
Public endpoints are limited per IP. Authenticated endpoints are limited per key or per user, as listed above.
Start building
Create a key in your account, or browse the datasets and pull a free sample first. Questions about a custom slice? Email support@webatla.com.