API
Read the same data programmatically. Anonymous use is rate-limited per IP. A free API key raises the limits.
Quick start
Domains with an invalid SPF record that appeared in the last 24 hours. Leave out the key header to try it anonymously.
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/domains?q=spf:invalid%20added:%3C24h&limit=50"
Machine-readable: OpenAPI schema (JSON) for code generators, Postman or Insomnia.
Limits
Counted per IP or per key. Responses carry X-RateLimit-* headers; 429 includes Retry-After.
| Anonymous | Free key | |
|---|---|---|
| Requests per minute | 5 | 60 |
| Requests per day | 100 | 5'000 |
| Results per page | 25 | 200 |
| Cursor paging | no | yes |
Expensive calls count more: /domains/count, /domains/{name}/related, /stats/overview and /insights/* count as 2, /facets as 5. Clients that keep exceeding the limit are blocked for an hour.
All under /api/v1, JSON, GET. Open one for an example request, its response, the parameters and every response field.
GET /domains Search domains
One page of domains matching q. Follow next_cursor for more (cursor paging needs an API key).
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/domains?q=spf:invalid%20added:%3C24h&limit=25"
Example response SearchPage
{
"items": [
{
"domain": "xn--brgli-kva.ch",
"domain_unicode": "bürgli.ch",
"first_seen": "2026-10-08T06:00:00",
"status": "active",
"removed_at": null,
"dnssec": 1,
"mx_provider": "infomaniak",
"mx_hosted_by": "",
"ns_hosted_by": "",
"ns_provider": "hostpoint",
"spf": "valid",
"dmarc": "reject",
"ipv6": 0,
"web_country": "CH",
"n_issues": 2,
"checked_at": "2026-10-10T09:24:14",
"exact": false
}
],
"next_cursor": "2026-10-08 06:00:00|garage.ch",
"sort": "new"
} Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| q | string | Search query in the same language as the search field, e.g. spf:invalid provider:cyon garage. Empty = all active domains. | |
| limit | integer | 25 | Page size. Capped at 25 anonymous, 100 web, 200 with an API key. |
| cursor | string | next_cursor of the previous page (API key required). | |
| sort | string | auto | relevance (exact and prefix matches first), new (newest in the zone first), az (by name), checked (most recently analysed by the DNS harvester first; not yet analysed last); auto = relevance if q contains a name, else new. |
Response fields (SearchPage, DomainHit)
SearchPage
| items | DomainHit[] | Matching domains, one page |
| next_cursor | string | Pass as cursor for the next page; empty on the last page (cursor paging needs an API key) |
| sort | "relevance" | "new" | "az" | "checked" | Sort order actually used (auto resolves to relevance or new) |
DomainHit
| domain | string | Domain name in ASCII (punycode for IDNs) |
| domain_unicode | string | Domain name in Unicode |
| first_seen | datetime | First seen in the zone (UTC). 1970-01-02 means: present before tracking started |
| status | "active" | "removed" | Whether the domain is currently in the zone |
| removed_at | datetime| null | When it left the zone (UTC), null while active |
| dnssec | integer | 1 if the registry has a DS record for it (DNSSEC signed), else 0 |
| mx_provider | string | Mail provider derived from the MX records; 'none' without MX, '' before the first DNS check |
| mx_hosted_by | string | For self-named mail servers (a host under the domain's own name, e.g. mail.<domain>): who actually runs them, '' if unknown |
| ns_hosted_by | string | For self-named name servers (hosts under the domain's own name, e.g. ns1., ns., dns.<domain>): who runs them, from their addresses in the zone file; '' if unknown |
| ns_provider | string | DNS provider derived from the name servers |
| spf | string | SPF status: valid, none, permissive (+all), multiple, invalid_syntax, too_many_lookups; '' if not analysed |
| dmarc | string | DMARC status: none, monitor (p=none), quarantine, reject, invalid, multiple; '' if not analysed |
| ipv6 | integer | 1 if the domain (or www) has an AAAA record, else 0 |
| web_country | string | Country of the first web server address (ISO code), '' if unknown |
| n_issues | integer | Number of findings (see /issues) |
| checked_at | datetime| null | Last DNS check (UTC), null if not analysed yet |
| exact | boolean | True when this is the exact domain searched for (relevance sort only) |
GET /domains/count Count matches
Number of domains matching q. Counts as 2 requests.
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/domains/count?q=provider:cyon%20dmarc:none"
Example response Count
{
"count": 189891
} Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| q | string | Search query in the same language as the search field, e.g. spf:invalid provider:cyon garage. Empty = all active domains. |
Response fields (Count)
Count
| count | integer | Number of matching domains |
GET /facets Counts per filter value
For each filter, the most frequent values among the domains matching q (that filter itself ignored). Keys: provider, spf, dmarc, ns, issue, tag, spfinclude, rua, caa, dnssecstate, delegation, hostedby, nshostedby, dnssec, ipv6. dnssec and ipv6 hold one entry, value "true". Counts as 5 requests.
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/facets?q=treuhand"
Example response { [key]: ValueCount[] }
{
"key": [
{
"value": "hostpoint",
"count": 430049
}
]
} Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| q | string | Search query in the same language as the search field, e.g. spf:invalid provider:cyon garage. Empty = all active domains. |
Response fields (ValueCount)
ValueCount
| value | string | The value (provider, status, issue code, ...) |
| count | integer | Number of domains with this value |
GET /domains/{name} Domain details
Zone data, DNS records, analysis and the last 100 record changes of one domain. 404 if never in the zone.
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/domains/garage.ch"
Example response DomainDetail
{
"domain": "garage.ch",
"domain_unicode": "garage.ch",
"first_seen": "1970-01-02T00:00:00",
"status": "active",
"removed_at": null,
"zone_ns": [
"ns1.hostpoint.ch",
"ns2.hostpoint.ch"
],
"dnssec": 1,
"a": [
"217.26.48.101"
],
"aaaa": [],
"ns": [
"ns1.hostpoint.ch",
"ns2.hostpoint.ch"
],
"mx": [
{
"prio": 10,
"host": "mx1.mail.hostpoint.ch"
}
],
"txt": [
"v=spf1 include:spf.protection.outlook.com -all"
],
"caa": [
"0 issue \"letsencrypt.org\""
],
"dmarc_txt": [
"v=DMARC1; p=reject; rua=mailto:dmarc@example.ch"
],
"mx_provider": "hostpoint",
"ns_provider": "hostpoint",
"spf_status": "valid",
"dmarc_status": "reject",
"txt_tags": [
"google",
"microsoft-365"
],
"issues": [
"dmarc_no_rua"
],
"dnssec_state": "ok",
"nsec_mode": "nsec3",
"nsec3_iterations": 0,
"caa_issuers": [
"letsencrypt.org"
],
"soa_rname": "hostmaster.hostpoint.ch",
"soa_mname": "ns1.hostpoint.ch",
"soa_serial": 2026100901,
"soa_expire": 1209600,
"spf_includes": [
"spf.protection.outlook.com"
],
"dmarc_rua": [
"example.ch"
],
"www_state": "a",
"dkim_selectors": [
"selector1"
],
"mx_hosted_by": "",
"mx_hosted_source": "",
"ns_hosted_by": "",
"ns_ips": [
"111.90.159.157"
],
"bimi": [
"v=BIMI1; l=https://example.ch/logo.svg"
],
"mta_sts": [
"v=STSv1; id=20261001"
],
"tls_rpt": [
"v=TLSRPTv1; rua=mailto:tls@example.ch"
],
"lookup_state": "",
"lookup_detail": "94.126.19.210:53 returned REFUSED for example.ch SOA",
"lookup_since": null,
"checked_at": "2026-10-10T09:24:14",
"delegation": "ok",
"history": [
{
"changed_at": "2026-10-09T14:02:11",
"rrtype": "MX",
"old": [
"10 mx1.example.net"
],
"new": [
"10 mx1.mail.hostpoint.ch"
]
}
]
} Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| name*(path) | string | Domain name, ASCII (punycode) form, e.g. garage.ch |
Response fields (DomainDetail, MxRecord, HistoryEntry)
DomainDetail
| domain | string | Domain name in ASCII |
| domain_unicode | string | Domain name in Unicode |
| first_seen | datetime | First seen in the zone (UTC); 1970-01-02 = before tracking started |
| status | "active" | "removed" | Whether the domain is currently in the zone |
| removed_at | datetime| null | When it left the zone (UTC), null while active |
| zone_ns | string[] | Name servers listed by the registry (delegation) |
| dnssec | integer | 1 if the registry has a DS record, else 0 |
| a | string[] | IPv4 addresses of the domain |
| aaaa | string[] | IPv6 addresses of the domain |
| ns | string[] | Name servers the domain itself publishes |
| mx | MxRecord[] | MX records |
| txt | string[] | TXT records |
| caa | string[] | CAA records |
| dmarc_txt | string[] | TXT records at _dmarc.<domain> |
| mx_provider | string | Mail provider derived from MX ('none' without MX, '' if not analysed) |
| ns_provider | string | DNS provider derived from the name servers |
| spf_status | string | SPF status (see DomainHit.spf) |
| dmarc_status | string | DMARC status (see DomainHit.dmarc) |
| txt_tags | string[] | Services recognised from TXT verification records |
| issues | string[] | Finding codes; /issues has a description of each |
| dnssec_state | string | DNSSEC state: ok, none (unsigned), ds_mismatch, ds_no_dnskey, dnskey_no_ds; '' if not analysed |
| nsec_mode | string | Authenticated denial: nsec, nsec3 or '' |
| nsec3_iterations | integer | NSEC3 hash iterations, -1 if not applicable |
| caa_issuers | string[] | Certificate authorities allowed by CAA |
| soa_rname | string | SOA contact mailbox (as a name) |
| soa_mname | string | SOA primary name server |
| soa_serial | integer | SOA serial |
| soa_expire | integer | SOA expire (seconds) |
| spf_includes | string[] | Domains included by SPF (who may send mail) |
| dmarc_rua | string[] | Domains receiving DMARC aggregate reports |
| www_state | string | www.<domain>: a (has an address), cname, none; '' if not analysed |
| dkim_selectors | string[] | DKIM selectors found |
| mx_hosted_by | string | For self-named mail servers: who runs them |
| mx_hosted_source | string | How mx_hosted_by was derived: mx-ip (address of the MX host, exact), spf-ip, spf-a, spf (SPF include, a hint); '' if unknown |
| ns_hosted_by | string | For self-named name servers (hosts under the domain's own name, e.g. ns1., ns., dns.<domain>): who runs them, from the network of their glue addresses |
| ns_ips | string[] | Glue addresses of self-named name servers, from the zone file |
| bimi | string[] | TXT at default._bimi.<domain> (BIMI) |
| mta_sts | string[] | TXT at _mta-sts.<domain> (MTA-STS) |
| tls_rpt | string[] | TXT at _smtp._tls.<domain> (TLS-RPT) |
| lookup_state | string | '' = resolved; public = only public resolvers (1.1.1.1, 8.8.8.8) answered; otherwise why the domain cannot be resolved, also not through public resolvers: lame, not_loaded, dnssec, unreachable, nxdomain, other. The records shown are then those of the last successful resolution, if any |
| lookup_detail | string | For a domain that cannot be resolved: the public resolver's explanation (Extended DNS Error) |
| lookup_since | datetime| null | For a domain that cannot be resolved: since when (UTC) |
| checked_at | datetime| null | Last DNS check (UTC), null if not analysed yet |
| delegation | string| null | Registry vs. zone name servers: ok, differs, disjoint, parent_extra, child_extra, child_no_ns. Only present once analysed |
| history | HistoryEntry[] | Last 100 record changes, newest first |
MxRecord
| prio | integer | MX preference (lower is preferred) |
| host | string | Mail server host name |
HistoryEntry
| changed_at | datetime | When the change was observed (UTC) |
| rrtype | string | Record type that changed (A, AAAA, NS, MX, TXT, CAA, ...) |
| old | string[] | Previous values |
| new | string[] | New values |
GET /changes Added or removed domains
Domains that entered or left the zone within a time window, newest first. Page with offset.
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/changes?kind=removed&since=3d&limit=50&offset=100"
Example response ChangeList
{
"kind": "added",
"since_hours": 24,
"total": 812,
"items": [
{
"domain": "neue-firma.ch",
"ts": "2026-10-10T06:00:00"
}
]
} Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| kind | string | added | added or removed |
| since | string | 24h | Time window: hours or days, e.g. 12h, 3d (max 9999). |
| limit | integer | 200 | Maximum number of items |
| offset | integer | 0 | Skip this many items (paging) |
Response fields (ChangeList, ChangeItem)
ChangeList
| kind | "added" | "removed" | Requested kind |
| since_hours | integer | Time window in hours |
| total | integer | All changes of this kind in the window (items may be fewer) |
| items | ChangeItem[] | Newest first, up to limit, after skipping offset |
ChangeItem
| domain | string | Domain name in ASCII |
| ts | datetime | Snapshot in which the change was seen (UTC) |
GET /changes/providers Added and removed domains per DNS provider
Which DNS providers (name servers in the zone delegation) gained and lost the most domains within a time window.
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/changes/providers?since=30d&top=10"
Example response ProviderChanges
{
"since_hours": 168,
"added": 3100,
"removed": 2900,
"top_added": [
{
"provider": "hostpoint",
"added": 120,
"removed": 95
}
],
"top_removed": [
{
"provider": "hostpoint",
"added": 120,
"removed": 95
}
],
"net": [
{
"provider": "hostpoint",
"added": 120,
"removed": 95
}
]
} Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| since | string | 7d | Time window: hours or days, e.g. 24h, 30d (max 9999). |
| top | integer | 15 | Providers per list |
Response fields (ProviderChanges, ProviderChange)
ProviderChanges
| since_hours | integer | Time window in hours |
| added | integer | All added domains in the window |
| removed | integer | All removed domains in the window |
| top_added | ProviderChange[] | Providers with the most added domains |
| top_removed | ProviderChange[] | Providers with the most removed domains |
| net | ProviderChange[] | Providers with the largest net change (added minus removed, either way) |
ProviderChange
| provider | string | DNS provider (as in ns_provider) |
| added | integer | Domains with this provider that entered the zone |
| removed | integer | Domains with this provider that left the zone |
GET /changes/summary Change totals
Added and removed domains in the last 12 hours, 24 hours, 3, 7, 30 and 90 days. The zone is imported once a day.
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/changes/summary"
Example response ChangeSummary
{
"added_12h": 310,
"added_24h": 812,
"added_3d": 2304,
"added_7d": 5120,
"added_30d": 21900,
"added_90d": 64000,
"removed_12h": 280,
"removed_24h": 701,
"removed_3d": 2010,
"removed_7d": 4630,
"removed_30d": 19800,
"removed_90d": 58800
} Response fields (ChangeSummary)
ChangeSummary
| added_12h | integer | Domains added in the last 12 hours |
| added_24h | integer | ... 24 hours |
| added_3d | integer | ... 3 days |
| added_7d | integer | ... 7 days |
| added_30d | integer | ... 30 days |
| added_90d | integer | ... 90 days |
| removed_12h | integer | Domains removed in the last 12 hours |
| removed_24h | integer | ... 24 hours |
| removed_3d | integer | ... 3 days |
| removed_7d | integer | ... 7 days |
| removed_30d | integer | ... 30 days |
| removed_90d | integer | ... 90 days |
GET /changes/daily Changes per day
Added and removed domains per day (UTC), oldest first. Days without changes are omitted.
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/changes/daily?days=7"
Example response DailyChange[]
[
{
"day": "2026-10-09",
"added": 790,
"removed": 655
}
] Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| days | integer | 30 | Number of days back |
Response fields (DailyChange)
DailyChange
| day | date | Day (UTC) |
| added | integer | Domains added that day |
| removed | integer | Domains removed that day |
GET /stats/overview Zone statistics
Totals and provider, SPF, DMARC and finding distributions. Lists except ns_provider cover analysed domains only. Counts as 2 requests.
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/stats/overview"
Example response Overview
{
"active_domains": 2639107,
"resolved_domains": 2633,
"mail_domains": 1938,
"dnssec_domains": 1409721,
"ipv6_domains": 1032,
"distinct_mx_providers": 185,
"distinct_ns_providers": 18064,
"ns_provider": [
{
"value": "hostpoint",
"count": 430049
}
],
"mx_provider": [
{
"value": "hostpoint",
"count": 430049
}
],
"spf": [
{
"value": "hostpoint",
"count": 430049
}
],
"dmarc": [
{
"value": "hostpoint",
"count": 430049
}
],
"issues": [
{
"value": "hostpoint",
"count": 430049
}
],
"tags": [
{
"value": "hostpoint",
"count": 430049
}
],
"spf_includes": [
{
"value": "hostpoint",
"count": 430049
}
],
"dmarc_rua": [
{
"value": "hostpoint",
"count": 430049
}
],
"caa_issuers": [
{
"value": "hostpoint",
"count": 430049
}
],
"dnssec_state": [
{
"value": "hostpoint",
"count": 430049
}
],
"delegation": [
{
"value": "hostpoint",
"count": 430049
}
],
"mail_hosted_by": [
{
"value": "hostpoint",
"count": 430049
}
],
"mail_hosted_source": [
{
"value": "hostpoint",
"count": 430049
}
],
"self_named": [
444,
310
],
"ns_hosted_by": [
{
"value": "hostpoint",
"count": 430049
}
],
"ns_self_named": [
4287,
4100
],
"unresolvable_domains": 148000,
"lookup_state": [
{
"value": "hostpoint",
"count": 430049
}
]
} Response fields (Overview, ValueCount)
Overview
| active_domains | integer | Domains currently in the zone |
| resolved_domains | integer | Of those, analysed (DNS resolved) so far |
| mail_domains | integer | Analysed domains that receive mail (have MX) |
| dnssec_domains | integer | Domains with a DS record |
| ipv6_domains | integer | Domains with IPv6 |
| distinct_mx_providers | integer | Distinct mail providers |
| distinct_ns_providers | integer | Distinct DNS providers |
| ns_provider | ValueCount[] | Top 25 DNS providers (all active domains) |
| mx_provider | ValueCount[] | Top 25 mail providers (analysed domains, as all lists below) |
| spf | ValueCount[] | SPF status distribution |
| dmarc | ValueCount[] | DMARC status distribution |
| issues | ValueCount[] | Most frequent findings |
| tags | ValueCount[] | Most frequent TXT services |
| spf_includes | ValueCount[] | Most included SPF domains |
| dmarc_rua | ValueCount[] | Most frequent DMARC report receivers |
| caa_issuers | ValueCount[] | Most allowed certificate authorities |
| dnssec_state | ValueCount[] | DNSSEC validation states |
| delegation | ValueCount[] | Delegation consistency states |
| mail_hosted_by | ValueCount[] | Who runs self-named mail servers |
| mail_hosted_source | ValueCount[] | How that was derived |
| self_named | integer[] | [domains with a self-named mail server, of which the operator is known] |
| ns_hosted_by | ValueCount[] | Who runs self-named name servers (all active domains) |
| ns_self_named | integer[] | [domains with self-named name servers, of which the operator is known] |
| unresolvable_domains | integer | Analysed domains that cannot be resolved, also not through public resolvers (counted in resolved_domains; left out of the lists above) |
| lookup_state | ValueCount[] | Why those domains cannot be resolved: lame, not_loaded, dnssec, unreachable, nxdomain, other |
ValueCount
| value | string | The value (provider, status, issue code, ...) |
| count | integer | Number of domains with this value |
GET /fields Filter names
Filter names the query language understands (name:value).
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/fields"
Example response string[]
[ "" ]
GET /issues Finding codes
Every finding code (as in issues and issue:) with a human-readable description.
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/issues"
Example response { [key]: string }
{
"key": ""
} GET /limits Rate limits
Current limits per access tier (anonymous, web UI, API key).
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/limits"
Example response Limits
{
"anon": {
"per_minute": 5,
"per_day": 100,
"max_page_size": 25,
"cursor_paging": false
},
"key": {
"per_minute": 5,
"per_day": 100,
"max_page_size": 25,
"cursor_paging": false
},
"web": {
"per_minute": 5,
"per_day": 100,
"max_page_size": 25,
"cursor_paging": false
}
} Response fields (Limits, TierLimits)
Limits
| anon | TierLimits | Anonymous use, per IP address |
| key | TierLimits | With a free API key, per key |
| web | TierLimits | The searchzone.ch website, per visitor IP (one search counts once) |
TierLimits
| per_minute | integer | Requests per minute |
| per_day | integer | Requests per day (UTC) |
| max_page_size | integer | Largest limit for /domains |
| cursor_paging | boolean | Whether cursor paging is allowed |
GET /insights/zone Zone insights
DNSSEC, name server and naming facts from the delegation data of all active domains. Counts as 2 requests.
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/insights/zone"
Example response ZoneInsights
{
"total": 2639107,
"signed": 1409721,
"ds_algorithms": [
{
"value": "hostpoint",
"count": 430049
}
],
"ds_digests": [
{
"value": "hostpoint",
"count": 430049
}
],
"ns_count": [
{
"value": "hostpoint",
"count": 430049
}
],
"ns_provider_count": [
{
"value": "hostpoint",
"count": 430049
}
],
"top_ns_hosts": [
{
"value": "hostpoint",
"count": 430049
}
],
"shared_ns_sets": [
{
"ns": [
"ns.hostpoint.ch",
"ns2.hostpoint.ch",
"ns3.hostpoint.ch"
],
"count": 416998
}
],
"names": {
"idn": 64404,
"digits_only": 3358,
"short": 29,
"with_hyphen": 913398,
"long": 11551
}
} Response fields (ZoneInsights, ValueCount, SharedNsSet, NameStats)
ZoneInsights
| total | integer | Active domains |
| signed | integer | With a DS record |
| ds_algorithms | ValueCount[] | DNSSEC algorithm numbers in DS records |
| ds_digests | ValueCount[] | DS digest types |
| ns_count | ValueCount[] | Domains by number of name servers |
| ns_provider_count | ValueCount[] | Domains by number of distinct DNS providers |
| top_ns_hosts | ValueCount[] | Most used name server hosts |
| shared_ns_sets | SharedNsSet[] | Most used complete name server sets |
| names | NameStats | Naming patterns |
ValueCount
| value | string | The value (provider, status, issue code, ...) |
| count | integer | Number of domains with this value |
SharedNsSet
| ns | string[] | The name server set |
| count | integer | Domains delegated to exactly this set |
NameStats
| idn | integer | Internationalised names (xn--) |
| digits_only | integer | Names made of digits only |
| short | integer | Names of at most 2 characters (+ .ch) |
| with_hyphen | integer | Names containing a hyphen |
| long | integer | Names longer than 30 characters |
GET /insights/fun Fun facts about names
Records and oddities among the names of all active domains (longest, accents, palindromes, ...). Counts as 2 requests.
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/insights/fun"
Example response FunFacts
{
"total": 2639107,
"median_length": 11,
"longest": {
"count": 15,
"examples": [
{
"domain": "xn--brgli-kva.ch",
"domain_unicode": "bürgli.ch"
}
]
},
"shortest": {
"count": 15,
"examples": [
{
"domain": "xn--brgli-kva.ch",
"domain_unicode": "bürgli.ch"
}
]
},
"most_accents": {
"count": 15,
"examples": [
{
"domain": "xn--brgli-kva.ch",
"domain_unicode": "bürgli.ch"
}
]
},
"accents_only": {
"count": 15,
"examples": [
{
"domain": "xn--brgli-kva.ch",
"domain_unicode": "bürgli.ch"
}
]
},
"accent_letters": [
{
"value": "hostpoint",
"count": 430049
}
],
"emoji": 0,
"most_hyphens": {
"count": 15,
"examples": [
{
"domain": "xn--brgli-kva.ch",
"domain_unicode": "bürgli.ch"
}
]
},
"longest_digits": {
"count": 15,
"examples": [
{
"domain": "xn--brgli-kva.ch",
"domain_unicode": "bürgli.ch"
}
]
},
"palindromes": {
"count": 15,
"examples": [
{
"domain": "xn--brgli-kva.ch",
"domain_unicode": "bürgli.ch"
}
]
},
"one_letter": {
"count": 15,
"examples": [
{
"domain": "xn--brgli-kva.ch",
"domain_unicode": "bürgli.ch"
}
]
},
"doubled": {
"count": 15,
"examples": [
{
"domain": "xn--brgli-kva.ch",
"domain_unicode": "bürgli.ch"
}
]
},
"switzerland": [
{
"value": "hostpoint",
"count": 430049
}
],
"classics": [
{
"value": "hostpoint",
"count": 430049
}
],
"three_letters": {
"taken": 15866,
"total": 17576,
"missing": [
"1989"
]
},
"years": {
"taken": 15866,
"total": 17576,
"missing": [
"1989"
]
}
} Response fields (FunFacts, FunFact, ValueCount, NameGap, FunExample)
FunFacts
| total | integer | Active domains |
| median_length | integer | Median name length in characters, without .ch |
| longest | FunFact | Longest names (63 characters is the DNS maximum) |
| shortest | FunFact | All names of 2 characters |
| most_accents | FunFact | Names with the most non-ASCII letters; count = all internationalised names |
| accents_only | FunFact | Names made only of non-ASCII letters, such as äää.ch |
| accent_letters | ValueCount[] | How often each non-ASCII letter occurs in names |
| emoji | integer | Names with characters outside the Latin script (the .ch registry does not allow them) |
| most_hyphens | FunFact | Names with the most hyphens; count = names with at least 5 |
| longest_digits | FunFact | Longest names made of digits only; count = all digits-only names |
| palindromes | FunFact | Names longer than 5 characters that read the same backwards |
| one_letter | FunFact | Names of one character repeated (at least 3 times), such as aaa.ch |
| doubled | FunFact | Names that are one word said twice, such as beobachterbeobachter.ch |
| switzerland | ValueCount[] | Names containing the country's name, per language |
| classics | ValueCount[] | Names containing Swiss classics (fondue, velo, ...) |
| three_letters | NameGap | Three-letter names a-z in the zone |
| years | NameGap | Years 1900-2030 as names (1999.ch) in the zone |
FunFact
| count | integer | Number of active domains with this property |
| examples | FunExample[] | Up to 5 of them, the most extreme first |
ValueCount
| value | string | The value (provider, status, issue code, ...) |
| count | integer | Number of domains with this value |
NameGap
| taken | integer | How many of the candidate names are in the zone |
| total | integer | Number of candidate names |
| missing | string[] | Candidates not in the zone (first ones alphabetically); not in the zone does not mean free to register |
FunExample
| domain | string | Domain name in ASCII (punycode for IDNs) |
| domain_unicode | string | Domain name in Unicode |
GET /insights/resolved DNS insights
Aggregations over analysed domains: shared addresses, mail x DNS providers, IPv6, hosting. Counts as 2 requests.
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/insights/resolved"
Example response ResolvedInsights
{
"resolved": 2633,
"top_ips": [
{
"value": "hostpoint",
"count": 430049
}
],
"top_mx_hosts": [
{
"value": "hostpoint",
"count": 430049
}
],
"owner_clusters": [
{
"value": "hostpoint",
"count": 430049
}
],
"soa_contacts": [
{
"value": "hostpoint",
"count": 430049
}
],
"mail_by_dns": {
"mail": [
"hostpoint",
"google"
],
"dns": [
"hostpoint",
"cloudflare"
],
"cells": [
{
"mail": "hostpoint",
"dns": "hostpoint",
"count": 436
}
]
},
"ipv6_by_dns": [
{
"provider": "hostpoint",
"domains": 1200,
"ipv6": 310
}
],
"hosting": {
"enabled": true,
"asns": [
{
"value": "hostpoint",
"count": 430049,
"name": "HOSTPOINT-AS"
}
],
"countries": [
{
"value": "hostpoint",
"count": 430049
}
]
},
"dnssec_state": [
{
"value": "hostpoint",
"count": 430049
}
],
"nsec_mode": [
{
"value": "hostpoint",
"count": 430049
}
]
} Response fields (ResolvedInsights, ValueCount, MailByDns, Ipv6ByDns, Hosting, MailDnsCell, AsnCount)
ResolvedInsights
| resolved | integer | Analysed domains (the sample all lists refer to) |
| top_ips | ValueCount[] | Most shared web server addresses |
| top_mx_hosts | ValueCount[] | Most used mail server hosts |
| owner_clusters | ValueCount[] | Verification tokens shared by several domains (same owner) |
| soa_contacts | ValueCount[] | Most frequent SOA contacts |
| mail_by_dns | MailByDns | Mail provider x DNS provider matrix |
| ipv6_by_dns | Ipv6ByDns[] | IPv6 adoption per DNS provider (at least 5 domains) |
| hosting | Hosting | Web hosting networks and countries |
| dnssec_state | ValueCount[] | DNSSEC validation states |
| nsec_mode | ValueCount[] | NSEC vs NSEC3 |
ValueCount
| value | string | The value (provider, status, issue code, ...) |
| count | integer | Number of domains with this value |
MailByDns
| string[] | Top mail providers (rows) | |
| dns | string[] | Top DNS providers (columns) |
| cells | MailDnsCell[] | Counts per combination (missing = 0) |
Ipv6ByDns
| provider | string | DNS provider |
| domains | integer | Analysed domains at this provider |
| ipv6 | integer | Of those, with IPv6 |
Hosting
| enabled | boolean | False when no ASN database is configured (lists are then empty) |
| asns | AsnCount[] | Most frequent web hosting networks (AS numbers) |
| countries | ValueCount[] | Most frequent web hosting countries |
MailDnsCell
| string | Mail provider | |
| dns | string | DNS provider |
| count | integer | Domains with this combination |
AsnCount
| value | string | The value (provider, status, issue code, ...) |
| count | integer | Number of domains with this value |
| name | string | Network name of the AS |
GET /cache/status Cache status
When the cached statistics (overview, insights, fun facts, trends) were computed and when they are refreshed. They are recomputed in the background every 6 hours and after each daily zone import.
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/cache/status"
Example response { [key]: CacheInfo }
{
"key": {
"computed_at": "2026-10-15T09:34:36Z",
"next_refresh": "2026-10-15T15:24:36Z"
}
} Response fields (CacheInfo)
CacheInfo
| computed_at | datetime| null | When the cached answer was computed (UTC); null while it is not cached yet |
| next_refresh | datetime| null | When it will be recomputed in the background (UTC); also right after each zone import |
GET /stats/trends Trends
Daily snapshots of the zone's distributions (DNSSEC, DNS and mail providers, SPF, DMARC, IPv6), oldest first. Recorded since the installation; one point per day. Counts as 2 requests.
Example request
curl -H "Authorization: Bearer sz_..." "https://searchzone.ch/api/v1/stats/trends?days=90"
Example response TrendPoint[]
[
{
"day": "2026-10-15",
"metric": "ns_provider",
"key": "cyon",
"count": 120034,
"total": 2639107
}
] Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| days | integer | 365 | Number of days back |
Response fields (TrendPoint)
TrendPoint
| day | date | Day of the snapshot (UTC) |
| metric | string | zone, ns_provider, mx_provider, spf, dmarc or ipv6 |
| key | string | Value within the metric (provider, status; for zone: active, dnssec, resolved) |
| count | integer | Domains with this value that day |
| total | integer | Base for a share: active domains (zone, ns_provider) or analysed domains (the others) |
Query syntax
The same language as the search field on the website (the q parameter). Open a group for its filters.
Domain name
| blick.ch | Name contains the text. The exact name and names starting with it come first. |
| ^blick | Name starts with |
| blick.ch$ | Name ends with |
| ^blick.ch$ | Exactly this name |
| idn:true | Internationalised names (umlauts) |
Combining
| treuhand garage | Space = AND: both must match |
| provider:cyon,hostpoint | Comma inside one filter = OR |
| spf:invalid OR dmarc:none | The word OR splits the whole query (AND binds tighter) |
| -issue:spf_no_all | Leading minus excludes |
Addresses
Every address filter also takes a range (1.2.3.0/24) or a prefix (1.2.*).
| a:217.26.48.1 | A record (IPv4 address of the domain) |
| aaaa:2a00:d70::1 | AAAA record (IPv6 address of the domain) |
| ip:217.26.48.0/24 | A or AAAA |
| mx:217.26.48.1 | Address of one of the domain's mail servers (collected by newer harvests) |
| spf:217.26.48.1 | SPF lists this address directly in ip4:/ip6: (includes are not followed) |
| asn:13030 | Website hosted in this network (IPv4) |
| country:ch | Website hosted in this country (IPv4) |
| provider:cyon | Mail provider, or part of the MX host name (mx: works the same) |
| provider:self-named | Mail server under the domain's own name (mail., mx.<domain>…) |
| hostedby:hostpoint | Who runs a self-named mail server (inferred) |
| spf:invalid | Faulty SPF (syntax, several records, >10 lookups, +all); or one status: valid, none, permissive, multiple, too_many_lookups |
| dmarc:invalid | Faulty DMARC (malformed, several records, or the lookup fails); or: none, monitor, quarantine, reject, temperror |
| spfinclude:google.com | SPF authorises this sender (include/redirect) |
| rua:dmarcian.com | DMARC reports go to |
| dkim:selector1 | DKIM selector found |
TXT records
| txt:sendgrid | TXT contains the text (matches from the start of a word, fast) |
| txt:"v=spf1 mx" | Phrase in quotes |
| txtraw:endgri | Any substring anywhere (slower) |
| tag:google | Verification or policy record of a service |
| owner:google:… | Same verification token as another domain |
DNS and zone
| ns:cloudflare | Name server provider or part of the name |
| ns:self-named | Name servers under the domain's own name (ns1., ns., dns.<domain>…) |
| nshostedby:hostpoint | Who runs self-named name servers (from their addresses in the zone file) |
| dnssec:true | Signed (DS record in the zone) |
| dsalg:13 | DNSSEC algorithm |
| dsdigest:4 | DS digest type |
| dnssecstate:ds_mismatch | DS does not match DNSKEY (extended profile) |
| nsec:nsec3 | Denial of existence |
| nscount:1 | Number of name servers (also >3, <2) |
| redundancy:single | Only one DNS provider |
| delegation:disjoint | Registry and zone list different name servers |
| caa:letsencrypt.org | CAA allows this issuer |
| soarname:hostmaster.example.ch | SOA contact |
| www:none | www: a, cname or none |
| ipv6:true | Has an AAAA record |
Findings and lifecycle
| issue:no_spf_but_mail | A finding (see the Findings filter for all names) |
| analysed:true | Resolved by a harvester |
| lookup:broken | Cannot be resolved, also not through public resolvers; or a reason: lame, not_loaded, dnssec, unreachable, nxdomain; public: only public resolvers answered |
| added:<24h | Entered the zone (h or d) |
| removed:<7d | Left the zone |