How OpenSEO Handles Backlink Data Retrieval and Presentation

OpenSEO retrieves backlink data through a layered architecture that validates requests with Zod schemas, fetches from the Data-for-SEO API via a dedicated service layer with caching, and presents filtered results through both a React-based UI and an MCP tool for AI agents.

OpenSEO, an open-source SEO platform maintained in the every-app/open-seo repository, implements a robust pipeline for backlink analysis. The system separates concerns across multiple layers—from API validation to business logic—ensuring type-safe backlink data retrieval and flexible presentation. Understanding how OpenSEO handles backlink data retrieval and presentation reveals a pattern that balances external API dependencies with efficient caching and multi-interface support.

Architecture Overview

OpenSEO organizes its backlink functionality into five distinct layers:

Layer Responsibility Key File
API Layer Validates input and exposes server-side entry points src/serverFunctions/backlinks.ts
Business Layer Communicates with Data-for-SEO API, handles caching and pagination src/server/features/backlinks/services/BacklinksService.ts
Schema Layer Defines Zod schemas for request validation and response shaping src/types/schemas/backlinks.ts
MCP Layer Provides AI-agent tools for programmatic access src/server/mcp/tools/get-backlinks-overview.ts
UI Layer Renders tables, filters, and export functionality web/src/lib/feature-pages.ts

This separation ensures that the core backlink retrieval logic remains isolated from presentation concerns, allowing the same service to power both the web interface and AI integrations.

The Retrieval Flow

The backlink data retrieval process follows a strict validation pipeline before reaching external APIs.

Request Validation

Every incoming request first passes through Zod schema validation. In src/serverFunctions/backlinks.ts, the server functions use backlinksOverviewInputSchema and backlinksRowsPageRequestSchema to validate parameters:

// src/serverFunctions/backlinks.ts
import { BacklinksService } from "@/server/features/backlinks/services/BacklinksService";
import { backlinksRowsPageRequestSchema } from "@/types/schemas/backlinks";

export const getBacklinks = createServerFunction()
  .inputValidator((data) => backlinksRowsPageRequestSchema.parse(data))
  .handler(async (req, ctx) => {
    // req contains: target, tab, page, pageSize, sortField, sortOrder, filters, mode
    return BacklinksService.profileBacklinksPage(req, ctx, /* options */);
  });

The validation wrapper ensures that all inputs conform to the expected shape before processing continues.

Service Layer Execution

Once validated, requests forward to BacklinksService, which orchestrates four main operations:

  • profileOverview: Gathers summary statistics (total backlinks, referring domains, top pages)
  • profileBacklinksPage: Retrieves paginated backlink rows
  • profileReferringDomainsPage: Fetches domain-level aggregates
  • profileTopPagesPage: Returns the most linked-to pages

The service maintains a default cache in backlinksServiceData.ts to minimize external API calls and respects pagination parameters (page, pageSize) to handle large datasets efficiently.

External API Communication

BacklinksService communicates directly with the Data-for-SEO API. The service implements caching layers to store results and reduce latency for repeated queries. All pagination, filtering, and sorting logic occurs after retrieval but before the response returns to the client.

Data Processing and Filtering

After retrieving raw data from the external API, OpenSEO applies business logic to refine results.

Filtering Logic

The system supports complex filtering through backlinksApiFilters.ts, which processes boolean flags for:

  • Spam: Identifies low-quality links
  • Broken: Detects non-responsive backlinks
  • Lost: Flags removed backlinks
  • Nofollow: Identifies non-passing links

Sorting Capabilities

Results sort according to backlinksRowsSortFieldSchema, supporting fields like rank DESC to prioritize high-authority domains. The service constructs the final payload to match the Zod output schema defined in src/types/schemas/backlinks.ts, ensuring type consistency between server and client.

Presentation Layer

The backlink data presentation layer transforms JSON payloads into interactive tables. The Backlink Checker page, registered in web/src/routeTree.gen.ts and configured in web/src/lib/feature-pages.ts (lines 184-214), renders:

Column Data Source
Backlink URL of the linking page
Rank Domain authority estimate
Signal Flags Boolean values for spam, broken, lost, nofollow
Referring Domain Grouped view when mode = "one_per_domain"

UI Features

The interface includes pagination controls driven by the page and pageSize values returned by the service. Users can toggle dynamic filters through checkboxes that modify the backlinksRowsFiltersSchema values, triggering instant re-requests. An export function serializes current rows—including all filter flags—to CSV format for offline analysis.

// Front-end usage (React hook)
import { useQuery } from "@tanstack/react-query";

function useBacklinkRows(domain: string, page = 1) {
  return useQuery(
    ["backlinks", domain, page],
    async () => {
      const res = await fetch(`/api/backlinks/rows?target=${domain}&page=${page}`);
      if (!res.ok) throw new Error("Failed to load backlinks");
      return res.json(); // matches the Zod output schema
    },
    { keepPreviousData: true }
  );
}

MCP Integration for AI Agents

OpenSEO exposes backlink functionality to AI agents through the Model Context Protocol (MCP). The tool defined in src/server/mcp/tools/get-backlinks-overview.ts provides a concise interface:

// src/server/mcp/tools/get-backlinks-overview.ts
import { BacklinksService } from "@/server/features/backlinks/services/BacklinksService";

export async function get_backlinks_overview(input: { target: string }) {
  // Returns: { backlinks: number | null, referringDomains: number | null, topPages: number | null }
  return BacklinksService.profileOverview(input, { billing: /* current user billing */ });
}

This allows AI agents to fetch backlink overviews without rendering the full UI, returning only essential metrics for automated analysis.

Summary

  • OpenSEO implements a five-layer architecture separating validation, business logic, and presentation concerns for backlink data.
  • The BacklinksService in src/server/features/backlinks/services/BacklinksService.ts handles all Data-for-SEO API communication with built-in caching.
  • Zod schemas in src/types/schemas/backlinks.ts enforce type safety across API boundaries.
  • The system supports multi-modal presentation through both a React-based web interface and an MCP tool for AI agents.
  • Advanced filtering (spam, broken, lost, nofollow) and sorting occur at the service layer before data reaches the client.

Frequently Asked Questions

OpenSEO uses Zod schemas defined in src/types/schemas/backlinks.ts to validate all incoming requests. The server functions in src/serverFunctions/backlinks.ts wrap validation through an .inputValidator() method that parses inputs against schemas like backlinksRowsPageRequestSchema before passing them to the business layer.

The platform integrates with the Data-for-SEO API through the BacklinksService class. This service handles authentication, request construction, caching of results in backlinksServiceData.ts, and error handling for all external backlink queries.

Yes. OpenSEO exposes a dedicated MCP tool in src/server/mcp/tools/get-backlinks-overview.ts that allows AI agents to call BacklinksService.profileOverview() directly. This returns a concise JSON object containing backlink counts, referring domains, and top pages without requiring HTML rendering.

The presentation layer implements server-side pagination controlled by page and pageSize parameters. The service returns paginated subsets of data, and the React frontend maintains state through TanStack Query with keepPreviousData enabled to prevent UI flickering during navigation.

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 →