# Source: https://docs.perplexity.ai/guides/search-domain-filter-guide.md

# Search Domain Filter

<Note>
  The `search_domain_filter` parameter allows you to limit search results to specific domains or URLs, enabling focused research from trusted sources.
</Note>

<Info>
  Domain filters allow you to specify which domains to include in search results. You can filter by specific domains, top-level domains (TLDs), or domain parts. You can specify up to 20 filters per request. Domains should be provided without the protocol (e.g., "nature.com" not "[https://nature.com](https://nature.com)").
</Info>

## Overview

The domain filter for the Search API allows you to control which sources appear in your search results by limiting them to specific domains. This is particularly useful when you need to:

* Focus research on authoritative or trusted sources
* Search within specific publication networks or organizations
* Build domain-specific search applications
* Conduct competitive research within specific industry domains

The `search_domain_filter` parameter accepts an array of domain strings that restricts results to only the specified domains. This is useful when you want to search exclusively within trusted or relevant sources.

```bash  theme={null}
"search_domain_filter": ["nature.com", "science.org", "cell.com"]
```

## Filtering Capabilities

Domain filters support flexible matching across different domain components:

### Root Domain Filtering

Specify a root domain to match all content from that domain and its subdomains:

```bash  theme={null}
"search_domain_filter": ["wikipedia.org"]
```

This will match:

* `en.wikipedia.org`
* `fr.wikipedia.org`
* `de.wikipedia.org`
* Any other Wikipedia language subdomain

### Top-Level Domain (TLD) Filtering

Filter by top-level domain to target specific categories of sites:

```bash  theme={null}
"search_domain_filter": [".gov"]
```

This will match all government domains:

* `nasa.gov`
* `cdc.gov`
* `irs.gov`
* Any other `.gov` domain

<Tip>
  TLD filtering is particularly useful for targeting specific types of organizations, such as `.gov` for government sites, `.edu` for educational institutions, or country-specific TLDs like `.uk` or `.ca`.
</Tip>

### Domain Part Filtering

Any part of a domain can be used as a filter. The system will match domains containing that component.

<Note>
  Path-based filtering (e.g., `domain.com/specific-path`) is not currently supported but is under development.
</Note>

## Examples

**1. Academic Sources**

This example limits search results to authoritative academic publishers:

**Request Example**

<CodeGroup>
  ```python Python theme={null}
  from perplexity import Perplexity

  client = Perplexity()

  response = client.search.create(
      query="climate change research",
      max_results=10,
      search_domain_filter=[
          "nature.com",
          "science.org",
          "cell.com"
      ]
  )

  for result in response.results:
      print(f"{result.title}: {result.url}")
  ```

  ```typescript TypeScript theme={null}
  import Perplexity from '@perplexity-ai/perplexity_ai';

  const client = new Perplexity();

  const response = await client.search.create({
    query: "climate change research",
    maxResults: 10,
    searchDomainFilter: [
      "nature.com",
      "science.org",
      "cell.com"
    ]
  });

  for (const result of response.results) {
    console.log(`${result.title}: ${result.url}`);
  }
  ```

  ```bash cURL theme={null}
  curl -X POST 'https://api.perplexity.ai/search' \
    -H 'Authorization: Bearer $PERPLEXITY_API_KEY' \
    -H 'Content-Type: application/json' \
    -d '{
      "query": "climate change research",
      "max_results": 10,
      "search_domain_filter": [
        "nature.com",
        "science.org",
        "cell.com"
      ]
    }' | jq
  ```
</CodeGroup>

**2. Tech News Sources**

Search across major technology news websites:

<CodeGroup>
  ```python Python theme={null}
  from perplexity import Perplexity

  client = Perplexity()

  response = client.search.create(
      query="latest tech trends 2025",
      max_results=10,
      search_domain_filter=[
          "techcrunch.com",
          "theverge.com",
          "arstechnica.com",
          "wired.com"
      ]
  )

  for result in response.results:
      print(f"{result.title}")
      print(f"Source: {result.url}")
      print(f"Date: {result.date}")
      print("---")
  ```

  ```typescript TypeScript theme={null}
  import Perplexity from '@perplexity-ai/perplexity_ai';

  const client = new Perplexity();

  const response = await client.search.create({
    query: "latest tech trends 2025",
    maxResults: 10,
    searchDomainFilter: [
      "techcrunch.com",
      "theverge.com",
      "arstechnica.com",
      "wired.com"
    ]
  });

  for (const result of response.results) {
    console.log(`${result.title}`);
    console.log(`Source: ${result.url}`);
    console.log(`Date: ${result.date}`);
    console.log("---");
  }
  ```

  ```bash cURL theme={null}
  curl -X POST 'https://api.perplexity.ai/search' \
    -H 'Authorization: Bearer $PERPLEXITY_API_KEY' \
    -H 'Content-Type: application/json' \
    -d '{
      "query": "latest tech trends 2025",
      "max_results": 10,
      "search_domain_filter": [
        "techcrunch.com",
        "theverge.com",
        "arstechnica.com",
        "wired.com"
      ]
    }' | jq
  ```
</CodeGroup>

**3. Government and Educational Sources (TLD Filtering)**

Use top-level domain filtering to search across all government or educational institutions:

<CodeGroup>
  ```python Python theme={null}
  from perplexity import Perplexity

  client = Perplexity()

  # Search all .gov and .edu domains
  response = client.search.create(
      query="climate change policy research",
      max_results=15,
      search_domain_filter=[
          ".gov",
          ".edu"
      ]
  )

  for result in response.results:
      print(f"{result.title}")
      print(f"Source: {result.url}")
      print("---")
  ```

  ```typescript TypeScript theme={null}
  import Perplexity from '@perplexity-ai/perplexity_ai';

  const client = new Perplexity();

  // Search all .gov and .edu domains
  const response = await client.search.create({
    query: "climate change policy research",
    maxResults: 15,
    searchDomainFilter: [
      ".gov",
      ".edu"
    ]
  });

  for (const result of response.results) {
    console.log(`${result.title}`);
    console.log(`Source: ${result.url}`);
    console.log("---");
  }
  ```

  ```bash cURL theme={null}
  curl -X POST 'https://api.perplexity.ai/search' \
    -H 'Authorization: Bearer $PERPLEXITY_API_KEY' \
    -H 'Content-Type: application/json' \
    -d '{
      "query": "climate change policy research",
      "max_results": 15,
      "search_domain_filter": [
        ".gov",
        ".edu"
      ]
    }' | jq
  ```
</CodeGroup>

**4. Wikipedia Across Languages (Subdomain Matching)**

Search across all Wikipedia language editions by specifying the root domain:

<CodeGroup>
  ```python Python theme={null}
  from perplexity import Perplexity

  client = Perplexity()

  # Matches en.wikipedia.org, fr.wikipedia.org, de.wikipedia.org, etc.
  response = client.search.create(
      query="quantum mechanics",
      max_results=10,
      search_domain_filter=["wikipedia.org"]
  )

  for result in response.results:
      print(f"{result.title}")
      print(f"URL: {result.url}")
      print("---")
  ```

  ```typescript TypeScript theme={null}
  import Perplexity from '@perplexity-ai/perplexity_ai';

  const client = new Perplexity();

  // Matches en.wikipedia.org, fr.wikipedia.org, de.wikipedia.org, etc.
  const response = await client.search.create({
    query: "quantum mechanics",
    maxResults: 10,
    searchDomainFilter: ["wikipedia.org"]
  });

  for (const result of response.results) {
    console.log(`${result.title}`);
    console.log(`URL: ${result.url}`);
    console.log("---");
  }
  ```

  ```bash cURL theme={null}
  curl -X POST 'https://api.perplexity.ai/search' \
    -H 'Authorization: Bearer $PERPLEXITY_API_KEY' \
    -H 'Content-Type: application/json' \
    -d '{
      "query": "quantum mechanics",
      "max_results": 10,
      "search_domain_filter": ["wikipedia.org"]
    }' | jq
  ```
</CodeGroup>

**5. Combining Domain Filter with Other Filters**

Domain filters work seamlessly with other search parameters for precise control:

<CodeGroup>
  ```python Python theme={null}
  from perplexity import Perplexity

  client = Perplexity()

  # Combine domain filter with date and language filters
  response = client.search.create(
      query="quantum computing breakthroughs",
      max_results=20,
      search_domain_filter=[
          "nature.com",
          "science.org",
          "arxiv.org"
      ],
      search_recency_filter="month",
      search_language_filter=["en"]
  )

  for result in response.results:
      print(f"{result.title}")
      print(f"URL: {result.url}")
      print(f"Date: {result.date}")
      print("---")
  ```

  ```typescript TypeScript theme={null}
  import Perplexity from '@perplexity-ai/perplexity_ai';

  const client = new Perplexity();

  // Combine domain filter with date and language filters
  const response = await client.search.create({
    query: "quantum computing breakthroughs",
    maxResults: 20,
    searchDomainFilter: [
      "nature.com",
      "science.org",
      "arxiv.org"
    ],
    searchRecencyFilter: "month",
    searchLanguageFilter: ["en"]
  });

  for (const result of response.results) {
    console.log(`${result.title}`);
    console.log(`URL: ${result.url}`);
    console.log(`Date: ${result.date}`);
    console.log("---");
  }
  ```

  ```bash cURL theme={null}
  curl -X POST 'https://api.perplexity.ai/search' \
    -H 'Authorization: Bearer $PERPLEXITY_API_KEY' \
    -H 'Content-Type: application/json' \
    -d '{
      "query": "quantum computing breakthroughs",
      "max_results": 20,
      "search_domain_filter": [
        "nature.com",
        "science.org",
        "arxiv.org"
      ],
      "search_recency_filter": "month",
      "search_language_filter": ["en"]
    }' | jq
  ```
</CodeGroup>

## Parameter Reference

### `search_domain_filter`

* **Type**: Array of strings
* **Format**: Domain names without protocol (e.g., "example.com")
* **Description**: Filters search results to only include content from specified domains
* **Optional**: Yes
* **Maximum**: 20 domains per request
* **Example**: `"search_domain_filter": ["nature.com", "science.org"]`

## Domain Format Guidelines

**Correct Domain Formats:**

* `"nature.com"` - Root domain (matches nature.com and all subdomains)
* `"blog.example.com"` - Specific subdomain
* `"arxiv.org"` - Root domain (matches all subdomains)
* `".gov"` - Top-level domain (matches all .gov sites)
* `".edu"` - Top-level domain (matches all .edu sites)
* `".uk"` - Country-code TLD (matches all .uk sites)
* `"wikipedia.org"` - Matches en.wikipedia.org, fr.wikipedia.org, etc.

**Incorrect Domain Formats:**

* ❌ `"https://nature.com"` - Don't include protocol
* ❌ `"nature.com/"` - Don't include trailing slash
* ❌ `"nature.com/articles"` - Don't include path (path filtering coming soon)
* ❌ `"www.nature.com"` - Avoid www prefix (use root domain)

## Best Practices

### Domain Selection Strategy

* **Use Root Domains for Broad Coverage**: Specify root domains (e.g., "wikipedia.org") to match all subdomains automatically, including different language versions and regional sites.
* **Use TLDs for Categorical Filtering**: Target specific organization types with TLD filters like `.gov` for government, `.edu` for education, or `.org` for non-profits.
* **Be Specific When Needed**: Choose specific domains that are directly relevant to your search query to ensure high-quality results.
* **Quality Over Quantity**: Using fewer, highly relevant domains often produces better results than maximizing the 20-domain limit.
* **Consider Domain Authority**: Prioritize authoritative sources in your field for more reliable information.

### Locale and Regional Targeting

While domain filters don't directly filter by user location, you can target specific locales using:

* **Country-code TLDs**: Use filters like `.uk`, `.ca`, `.de`, `.jp` to target country-specific domains
* **Subdomain matching**: Specify regional subdomains when available (e.g., "uk.domain.com")
* **Combined approach**: Mix country TLDs with specific trusted domains for precise regional filtering

<Tip>
  For international research, combine TLD filtering with the `search_language_filter` parameter to refine results by both location and language.
</Tip>

### Domain Selection

* **Use Trusted Sources**: Select a specific set of trusted sources you want to search within (e.g., academic research, official documentation).
* **Leverage TLD Filtering**: When researching topics that span many sites of the same type, use TLD filters to cast a wider net (e.g., `.gov` for policy research).
* **Focus on Quality**: Choose authoritative domains that consistently provide reliable information relevant to your queries.

### Client-Side Validation

Validate domain formats on the client side before sending requests:

<CodeGroup>
  ```python Python theme={null}
  import re

  def validate_domain(domain):
      """Validate domain format including TLD filters."""
      # TLD filter (e.g., .gov, .edu)
      if domain.startswith('.'):
          tld_pattern = r'^\.[a-zA-Z]{2,}$'
          return bool(re.match(tld_pattern, domain))
      
      # Standard domain validation pattern
      pattern = r'^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$'
      return bool(re.match(pattern, domain))

  def validate_domain_filter(domains):
      """Validate domain filter array."""
      if len(domains) > 20:
          raise ValueError("Maximum 20 domains allowed")

      for domain in domains:
          if not validate_domain(domain):
              raise ValueError(f"Invalid domain format: {domain}")

      return True

  # Usage examples
  try:
      # Mix of regular domains and TLD filters
      domains = ["nature.com", "science.org", ".gov", ".edu"]
      validate_domain_filter(domains)

      response = client.search.create(
          query="research topic",
          search_domain_filter=domains
      )
  except ValueError as e:
      print(f"Validation error: {e}")
  ```

  ```typescript TypeScript theme={null}
  function validateDomain(domain: string): boolean {
    // TLD filter (e.g., .gov, .edu)
    if (domain.startsWith('.')) {
      const tldPattern = /^\.[a-zA-Z]{2,}$/;
      return tldPattern.test(domain);
    }
    
    // Standard domain validation pattern
    const pattern = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
    return pattern.test(domain);
  }

  function validateDomainFilter(domains: string[]): void {
    if (domains.length > 20) {
      throw new Error("Maximum 20 domains allowed");
    }

    for (const domain of domains) {
      if (!validateDomain(domain)) {
        throw new Error(`Invalid domain format: ${domain}`);
      }
    }
  }

  // Usage examples
  try {
    // Mix of regular domains and TLD filters
    const domains = ["nature.com", "science.org", ".gov", ".edu"];
    validateDomainFilter(domains);

    const response = await client.search.create({
      query: "research topic",
      searchDomainFilter: domains
    });
  } catch (error) {
    console.error("Validation error:", error.message);
  }
  ```
</CodeGroup>

### Performance Considerations

* **Result Availability**: Narrowing to specific domains may reduce the number of available results. Be prepared to handle cases where fewer results are returned than requested.
* **Domain Coverage**: Ensure the domains you specify actually contain content relevant to your query. Overly restrictive filters may return zero results.
* **Combination Effects**: Domain filters combined with other restrictive filters (date, language) can significantly reduce result counts.

<Tip>
  For best results, combine domain filtering with other filters like `search_recency_filter` or `search_language_filter` to narrow down your search to highly relevant, timely content from your target sources. Use TLD filters like `.gov` or `.edu` when you need broad coverage across an entire category of authoritative sites.
</Tip>