# Domain Search API

URL: https://www.deepinfo.com/data-api/apis/domain-search/

## Query the Whole Domain Index by Any Field.

Send one JSON body to the Domain Search API. Filter on names, WHOIS, DNS, certificates and web data, and get back full domain records, a page at a time or as an export.

Use it when the question crosses fields. The finder APIs start from one indicator; Domain Search describes a set of domains by everything you know about them.

[Talk to us about access](https://www.deepinfo.com/contact/?topic=data-api) [Domain Search reference](https://docs.deepinfo.com/reference/discovery/domain-search/)

### Put All Conditions in One Body.

One question across three layers: every domain whose mail goes to one server, registered since the start of 2026, that answers on the web. Newest registrations first.

POST `https://api.deepinfo.com/v1/discovery/domain-search` [Reference](https://docs.deepinfo.com/reference/discovery/domain-search/)

| Parameter | Type |  | Description |
| --- | --- | --- | --- |
| `filters` | object | Optional | In the body. Arrays of conditions under `must`, `should` and `must_not`, each `{name, type, value}`. |
| `sort` | array | Optional | In the body. One or more `{field, order}` pairs, `order` is `asc` or `desc`. |
| `page` | integer | Optional | Page number, from 1. |
| `page_size` | integer | Optional | Results per page. |
| `export` | boolean | Optional | Return the matches as an export instead of a page. Default `false`. |
| `export_format` | string | Optional | `json` or `csv`. |
| `export_scope` | string | Optional | How much of each record to include: `basic`, `default` or `extended`. |

Request

curl:

```bash
curl -X POST "https://api.deepinfo.com/v1/discovery/domain-search?page_size=25" \
  -H "apikey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": {
      "must": [
        { "name": "dns.mx.mail_servers", "type": "eq", "value": "mail.hosting.example" },
        { "name": "domain.whois.create_date", "type": "gte", "value": "2026-01-01T00:00:00Z" },
        { "name": "webdata.connection_status", "type": "eq", "value": "success" }
      ]
    },
    "sort": [ { "field": "domain.whois.create_date", "order": "desc" } ]
  }'
```

Python:

```python
import requests

body = {
    "filters": {
        "must": [
            {"name": "dns.mx.mail_servers", "type": "eq", "value": "mail.hosting.example"},
            {"name": "domain.whois.create_date", "type": "gte", "value": "2026-01-01T00:00:00Z"},
            {"name": "webdata.connection_status", "type": "eq", "value": "success"},
        ],
    },
    "sort": [{"field": "domain.whois.create_date", "order": "desc"}],
}
r = requests.post(
    "https://api.deepinfo.com/v1/discovery/domain-search",
    params={"page_size": 25},
    json=body,
    headers={"apikey": "YOUR_API_KEY"},
)
data = r.json()
print(data["result_count"])
for d in data["results"]:
    print(d["punycode"], d["domain"]["whois"]["create_date"])
```

JavaScript:

```javascript
const r = await fetch('https://api.deepinfo.com/v1/discovery/domain-search?page_size=25', {
  method: 'POST',
  headers: { apikey: 'YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    filters: {
      must: [
        { name: 'dns.mx.mail_servers', type: 'eq', value: 'mail.hosting.example' },
        { name: 'domain.whois.create_date', type: 'gte', value: '2026-01-01T00:00:00Z' },
        { name: 'webdata.connection_status', type: 'eq', value: 'success' },
      ],
    },
    sort: [{ field: 'domain.whois.create_date', order: 'desc' }],
  }),
})
const { result_count, results } = await r.json()
console.log(result_count, results.map((d) => d.punycode))
```

Response

200 OK · application/json

```json
{
  "page": 1,
  "page_size": 25,
  "result_count": 2,
  "results": [
    {
      "punycode": "harbor-cafe.example",
      "unicode": "harbor-cafe.example",
      "is_idn": false,
      "domain": {
        "name": { "punycode": "harbor-cafe", "length": 11 },
        "whois": {
          "create_date": "2026-09-14T08:12:40Z",
          "registrar": "…",
          "name_servers": ["ns1.hosting.example"]
        }
      },
      "dns": {
        "a": { "ip_addresses": ["198.51.100.23"] },
        "mx": { "mail_servers": ["mail.hosting.example"] }
      },
      "webdata": { "connection_status": "success", "…": "…" }
    },
    {
      "punycode": "oak-studio.example",
      "unicode": "oak-studio.example",
      "is_idn": false,
      "domain": {
        "whois": { "create_date": "2026-08-30T17:41:02Z" }
      },
      "dns": {
        "mx": { "mail_servers": ["mail.hosting.example"] }
      },
      "webdata": { "connection_status": "success", "…": "…" }
    }
  ]
}
```

### Operators That Share One Filter Shape.

Each condition is `{name, type, value}`: a field, an operator and a value. The operator decides what kind of value it expects.

| Operator | Matches when the field | Example condition |
| --- | --- | --- |
| `eq` | Equals the value | `domain.extension` · `"com"` |
| `in` | Equals any value in an array | `domain.whois.registrant.country` · `["tr", "fr"]` |
| `startswith` | Starts with the string | `fqdn` · `"login."` |
| `endswith` | Ends with the string | `fqdn` · `".acme.example"` |
| `wildcard` | Matches a pattern, `?` for one character and `*` for any run | `dns.mx.mail_servers` · `"mx?.acme.example"` |
| `fuzzy` | Approximately matches the string, a few characters apart | `domain.name` · `"acme"` |
| `contains_any` | Is an array holding at least one of the values | `domain.name.keywords` · `["login", "verify"]` |
| `contains_all` | Is an array holding every one of the values | `domain.name.keywords` · `["acme", "pay"]` |
| `gte` | Is greater than or equal to a number or date | `domain.whois.create_date` · `"2025-01-01T00:00:00Z"` |
| `lte` | Is less than or equal to a number or date | `domain.whois.expiry_date` · `"2026-12-31T23:59:59Z"` |
| `exists` | Has a value (`true`) or has none (`false`) | `dns.mx.mail_servers` · `true` |

Operators are defined once for the whole API, in the [search and filters guide](https://docs.deepinfo.com/getting-started/search-and-filters/).

### Where a Condition Sits Decides How It Combines.

All conditions under `must` have to match. At least one under `should` has to match. Nothing under `must_not` may match.

The example on the right takes every domain on one name server, keeps the ones already in use, those that accept mail or answer on the web, and leaves out the domains you own.

[Filtering in the reference](https://docs.deepinfo.com/reference/discovery/domain-search/#ref-filtering)

must + should + must_not

```json
{
  "filters": {
    "must": [
      { "name": "dns.ns.name_servers", "type": "eq", "value": "ns1.hosting.example" }
    ],
    "should": [
      { "name": "dns.mx.mail_servers", "type": "exists", "value": true },
      { "name": "webdata.connection_status", "type": "eq", "value": "success" }
    ],
    "must_not": [
      { "name": "domain", "type": "in", "value": ["acme.example", "acme-group.example"] }
    ]
  }
}
```

1. Every one has to match
2. At least one has to match
3. None may match

### Workflows That Start With a Filter.

#### [Threat Hunting](https://www.deepinfo.com/solutions/use-cases/threat-hunting/)

Describe an actor’s habits as filters, such as a registrar, a name-server pattern and a registration window, and see what else matches.

#### [Internet Research](https://www.deepinfo.com/solutions/use-cases/domain-intelligence-and-research/)

Measure a slice of the internet by its configuration: live sites without HSTS, self-signed certificates, domains expiring with WHOIS privacy on.

#### [Phishing Detection](https://www.deepinfo.com/solutions/use-cases/phishing-detection-and-prevention/)

Run a look-alike body on a schedule, `fuzzy` on `domain.name` with your own domain in `must_not`, and triage what appeared since the last run, newest registration first.

#### [Brand Impersonation](https://www.deepinfo.com/solutions/use-cases/brand-impersonation-protection/)

Sweep names that carry your brand keyword next to words like login, verify or secure, across all extensions.

### Before You Send a Query.

- **Searchable fields**: Grouped by family: name and extension, subdomain, WHOIS, DNS, IP history, SSL, and web data with HTTP headers. The full list is in the [reference](https://docs.deepinfo.com/reference/discovery/domain-search/#ref-filtering).
- **Totals**: `result_count` is the total number of matches across all pages. See [pagination](https://docs.deepinfo.com/getting-started/pagination/).
- **Empty body**: An empty body `{}` matches all records in the dataset. Send at least one condition.
- **Export**: `export=true` returns the matches as JSON or CSV instead of a page. Large exports can time out, so filter first.
- **In the Deepinfo Platform**: EASM custom discovery rules are written in this filter language over Deepinfo’s domain data. A query you test here can become a rule that proposes new assets. See [Asset Discovery](https://www.deepinfo.com/platform/easm/smart-asset-discovery/).
- **Rate limits**: Plan-dependent. The default is one request per second per key and endpoint. See [rate limits](https://docs.deepinfo.com/getting-started/rate-limits/).

### From a Result to the Next Pivot.

- [Domain Detail](https://www.deepinfo.com/data-api/apis/domain-detail/) (Discovery): The full record for one domain, in the shape Domain Search returns.
- [Associated Domain Finder](https://www.deepinfo.com/data-api/apis/associated-domain-finder/) (Discovery): Domains that share a registrant, name servers, IP, mail servers or SSL organization.
- [Deep Search & Insights](https://www.deepinfo.com/platform/dsi/domain-search/) (DSI): Domain Search and the finders, as one module of the Deepinfo Platform.

### Questions About Domain Search API

**Are subdomains in the results as well?**

Yes. Each record is a host name, filtered as `fqdn`, and a filter on `domain` matches a registered domain together with its subdomains. `subdomain_root` and `subdomain_last` filter on the subdomain labels themselves.

**Which fields can results be sorted on?**

The name and extension (`punycode`, `domain.extension.punycode`), the WHOIS create, expiry, update and last-change dates, and `dns_last_change_date` and `ssl_last_change_date`. Pass them in `sort` as `{field, order}` pairs.

**Can we find every host that serves one certificate?**

Yes. Filter `ssl.fingerprint.sha256` on the certificate’s SHA-256 fingerprint. A fingerprint identifies one certificate, so the result is each host in the index that serves it.

**Can we find domains that pointed to an IP in the past?**

Yes. `ip_history` and `domain.ip_history` keep each address a host or domain has resolved to over time, so a filter on them also matches names that have moved since.

**How is the Domain Search API priced?**

As part of an API services plan, priced by volume and frequency, separately from the platform. See [Data & API pricing](https://www.deepinfo.com/pricing/#data-pricing), or [talk to us](https://www.deepinfo.com/contact/?topic=data-api) about the queries you plan to run.

**Does the filter syntax work on other Deepinfo endpoints?**

Yes, with two exceptions. The EASM, CTI and BRP searches and their bulk actions take this `filters` body and these operators, each with its own list of searchable fields. Darkweb Search and Report Search use their own formats.

**What happens if a field name is wrong?**

The request fails with a 400 application error, and its `parameters` list points to what was rejected. See [errors](https://docs.deepinfo.com/getting-started/errors/).

### Bring the Question. We’ll Write the Filter With You.

Tell us what you want to find in the dataset. We set up access and walk through the fields with your team on a short call.

[Talk to us about access](https://www.deepinfo.com/contact/?topic=data-api) [All API services](https://www.deepinfo.com/data-api/apis/)
