How Backlink Analysis Endpoints Filter and Return Domain Data in Open SEO

The Open SEO repository processes backlink analysis requests through a pipeline that validates inputs with Zod schemas, translates user filters into DataForSEO API clauses via BacklinksService, and returns cached, normalized domain records with a six-hour retention policy.

The Open SEO project provides server-side endpoints for analyzing backlink profiles, specifically handling the filtering and retrieval of referring domain data. Understanding how these backlink analysis endpoints filter and return domain data requires examining the interaction between server functions, service-layer business logic, and external API integration. The architecture emphasizes type safety through schema validation, efficient caching, and precise filter construction to minimize external API costs while delivering accurate SEO metrics.

Server Function Entry Points and Validation

HTTP POST endpoints in src/serverFunctions/backlinks.ts serve as the primary interface for backlink analysis requests. The getBacklinksReferringDomains function handles requests specifically for the referring-domains tab, validating incoming payloads against the referringDomainsPageRequestSchema Zod schema before processing.

This validation layer ensures that parameters such as target, scope, filters, and pagination settings meet strict type requirements. Only after successful validation does the endpoint delegate execution to the service layer, preventing malformed requests from reaching the external DataForSEO API.

Service Layer Orchestration

The BacklinksService class in src/server/features/backlinks/services/BacklinksService.ts centralizes all backlink data operations. For referring domain requests, the method profileReferringDomainsPage manages the complete data retrieval workflow.

This service method first normalizes the target using normalizeBacklinksTarget to standardize domain or page formats. It then generates a cache key based on the normalized parameters and checks for existing cached results with a six-hour TTL (time-to-live). When cache misses occur, the service instantiates a DataForSEO client and prepares to fetch fresh data.

Constructing DataForSEO Filters

The filtering logic resides in src/server/features/backlinks/services/backlinksApiFilters.ts, specifically within the buildReferringDomainsApiFilters function. This module translates the user-supplied ReferringDomainsFilters object into an array of DataForSEO-compatible filter clauses.

The construction process involves several specialized helpers:

  • collectExcludeConditions – Handles exclusion patterns such as domain suffixes or substrings
  • collectNumericRange – Processes minimum and maximum thresholds for metrics like backlinks, referringPages, and spamScore
  • finishFilters – Assembles include/exclude conditions, enforces filter budget constraints, and joins clauses with AND operators

These functions support complex filtering scenarios including string pattern matching (e.g., including domains containing "blog" while excluding ".ru" domains), numeric range constraints, and boolean flags like hideLost.

Response Mapping and Caching

After receiving raw data from the DataForSEO API via dataforseo.backlinks.referringDomains, the service transforms the response through mapReferringDomainsRows. This mapping function trims the API payload to essential fields including domain, backlinks, referringPages, and spamScore.

The service then stores the processed result in the cache and returns a standardized paginated payload containing:

  • rows – The filtered array of domain records
  • totalCount – The total number of matching records (when available)
  • hasMore – Boolean indicating additional pages exist
  • page, pageSize, and fetchedAt – Metadata for client-side state management

Practical Implementation Examples

The following example demonstrates requesting filtered referring domains for a specific target:

// Request referring domains with complex filters
fetch('/api/backlinks/referring-domains', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    target: 'example.com',
    scope: 'domain',
    page: 1,
    pageSize: 20,
    sortField: 'backlinks',
    sortOrder: 'desc',
    filters: {
      include: 'blog',
      exclude: '.ru',
      minBacklinks: 10,
      maxBacklinks: 500,
      minSpamScore: 0,
      maxSpamScore: 20,
      hideLost: true,
    },
  }),
})
  .then(r => r.json())
  .then(data => {
    console.log('Referring domains:', data.rows);
    // Output: [{ domain: 'myblog.com', backlinks: 123, ... }, ...]
  });

For server-side or testing scenarios, invoke the service directly:

import { BacklinksService } from '@/server/features/backlinks/services/BacklinksService';
import { createMockBillingContext } from '@/test/helpers';

const ctx = createMockBillingContext();

BacklinksService.profileReferringDomainsPage(
  {
    target: 'example.com',
    scope: 'domain',
    page: 1,
    pageSize: 20,
    sortField: 'backlinks',
    sortOrder: 'desc',
    filters: {
      include: 'blog',
      exclude: '.ru',
      minBacklinks: 10,
    },
  },
  ctx,
  { hideSpam: false }
).then(result => console.log(result.rows));

Summary

  • Validation Layer: Zod schemas in src/serverFunctions/backlinks.ts enforce type safety before processing begins.
  • Filter Translation: The buildReferringDomainsApiFilters function converts user parameters into DataForSEO query syntax using helpers like collectNumericRange and collectExcludeConditions.
  • Caching Strategy: Results are cached for six hours via BacklinksService, reducing redundant external API calls.
  • Data Normalization: normalizeBacklinksTarget standardizes inputs while mapReferringDomainsRows trims API responses to essential domain metrics.
  • Architecture: The separation between server functions, service logic, and filter construction maintains clean separation of concerns while supporting complex filtering scenarios.

Frequently Asked Questions

Open SEO uses Zod schemas defined in src/types/schemas/backlinks.ts to validate all incoming payloads. The referringDomainsPageRequestSchema specifically ensures that filter parameters, pagination settings, and target specifications meet strict TypeScript types before the BacklinksService processes the request.

What filtering capabilities are supported for referring domains?

The system supports string pattern filtering (include/exclude substrings), numeric range filtering for metrics like backlinks and spam score, and boolean flags such as hideLost. These filters are assembled in src/server/features/backlinks/services/backlinksApiFilters.ts using buildReferringDomainsApiFilters and joined with AND operators to create precise DataForSEO API queries.

Results are cached for six hours (TTL = 6 hours) by the BacklinksService in src/server/features/backlinks/services/BacklinksService.ts. The service generates unique cache keys based on normalized target parameters and filter combinations to ensure cache hits only return relevant, context-specific data.

Yes, you can import BacklinksService directly from @/server/features/backlinks/services/BacklinksService and call profileReferringDomainsPage with a valid context object. This approach is particularly useful for unit testing or internal server-side processing where HTTP overhead is unnecessary.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →