How the DataForSEO Integration is Structured in OpenSEO: Location Mapping and API Routing

The DataForSEO integration in OpenSEO is built around a type-safe mapping layer in src/shared/keyword-locations.ts that validates location codes, resolves language preferences, and routes requests to the correct API provider (Labs or Google Ads) before any external calls are initiated.

The OpenSEO repository implements a deterministic façade over the DataForSEO API to prevent expensive billing errors and ensure accurate SERP data retrieval. Every request flows through a centralized validation system that maps internal market representations to DataForSEO's specific location_code and language_code requirements. This architectural approach isolates provider-specific logic into discrete utilities that are consumed by rank tracking workflows, MCP research tools, and backlink analysis functions.

Core Architectural Components

Location and Language Catalogs

At the heart of the integration sits src/shared/keyword-locations.ts, which exports two definitive data tables. The LOCATION_OPTIONS array contains every country supported by DataForSEO, including the canonical location_code (e.g., 2840 for United States, 2214 for Germany), human-readable labels, and a googleAdsOnly boolean flag indicating markets only available through the Google Ads API. Complementing this is SERP_LANGUAGE_OPTIONS, a master list of all language codes accepted by DataForSEO's SERP API.

The utility function getLanguageOptions(locationCode) performs runtime filtering against MULTI_LANGUAGE_LOCATIONS to return only the subset of languages actually supported for a specific country. This prevents the "Invalid Field: language_code" errors that would otherwise consume API credits.

Provider Selection Logic

DataForSEO maintains two distinct data endpoints: the Labs API (default) and the Google Ads API (for limited markets). The function getKeywordDataProvider(locationCode) inspects the LOCATION_OPTIONS entry for the requested code and returns either 'labs' or 'google_ads'. This deterministic routing ensures that requests for countries like Japan (Labs) and certain Google Ads-only regions hit the correct endpoint without manual configuration.

Market Resolution Utilities

OpenSEO handles ambiguous market inputs through a family of resolver functions. resolveMarket(args, project) reconciles user-provided locationCode and languageCode against project defaults, applying DataForSEO-specific fallbacks such as defaulting to United States (2840) when a Labs-only market is unsupported. For keyword data specifically, resolveLabsMarket() enforces Labs API constraints, while resolveKeywordDataLanguage() selects the appropriate language code based on the resolved market and available options.

Validation and Error Prevention

Pre-flight Validation Checks

Before any HTTP request leaves the server, OpenSEO runs cheap validation functions to avoid charged errors. isSupportedLocationCode(code) verifies existence in LOCATION_OPTIONS, while isLabsLocationCode(code) specifically checks Labs API availability. For language validation, isSupportedLanguageCode() and isLanguageServedForLocation() ensure the requested language is actually served for the target location. These guards are invoked in MCP tools and server functions to fail fast without consuming DataForSEO credits.

Integration Points Across the Codebase

MCP Research Tools

The file src/server/mcp/tools/dataforseo-research-tools.ts consumes the resolution utilities to construct safe API payloads. When processing keyword volume or CPC requests, these tools call resolveLabsMarket() and resolveKeywordDataLanguage() to guarantee that outgoing requests contain valid location_code and language_code combinations.

Rank Tracking Workflows

In src/server/workflows/RankCheckWorkflow.ts, the integration uses resolveMarket() to build DFSEO SERP tasks. This ensures that rank checks respect both project defaults and DataForSEO's location limitations, routing requests through the correct provider based on the resolved market.

The server functions in src/serverFunctions/backlinks.ts and src/serverFunctions/ai-search.ts leverage the same location/language logic to choose DataForSEO endpoints. These modules enforce credit-usage limits while utilizing the validation layer to prevent malformed requests to the backlink and AI-search APIs.

Practical Implementation Examples

Resolving Markets for Rank Tracking

import {
  resolveMarket,
  getKeywordDataProvider,
  getLanguageOptions,
} from '@/shared/keyword-locations';

// Project configuration from database
const project = { locationCode: 2840, languageCode: 'en' }; // United States

// User requests data for Germany (location code 2214)
const args = { locationCode: 2214 };

const { locationCode, languageCode } = resolveMarket(args, project);
// Returns: { locationCode: 2214, languageCode: 'de' }

const provider = getKeywordDataProvider(locationCode);
// Returns: 'labs' (Germany is serviced by Labs API)

const languages = getLanguageOptions(locationCode);
// Returns: [{ code: 'de', label: 'German' }]

Building Validated Keyword Data Requests

import {
  resolveLabsMarket,
  resolveKeywordDataLanguage,
} from '@/shared/keyword-locations';

function buildKeywordRequest(project, userArgs) {
  // Constrain to Labs-compatible markets only
  const { locationCode, languageCode } = resolveLabsMarket(userArgs, project);
  
  // Select language code accepted by DFSEO keyword endpoints
  const keywordLang = resolveKeywordDataLanguage(locationCode, languageCode);
  
  return {
    location_code: locationCode,
    language_code: keywordLang,
    // Additional DFSEO payload fields...
  };
}

Summary

  • The DataForSEO integration centers on src/shared/keyword-locations.ts, which maintains authoritative mappings of location codes, language codes, and API providers.
  • Provider routing is handled deterministically by getKeywordDataProvider(), automatically selecting between Labs and Google Ads APIs based on market availability.
  • Market resolution utilities like resolveMarket() and resolveLabsMarket() reconcile user inputs with project defaults while enforcing DataForSEO constraints.
  • Pre-flight validation through isSupportedLocationCode() and related functions prevents charged API errors by validating inputs before transmission.
  • The integration is consumed across MCP tools, rank tracking workflows, and backlink functions, providing a consistent, type-safe interface to the DataForSEO API.

Frequently Asked Questions

How does OpenSEO handle unsupported locations in DataForSEO?

OpenSEO maintains a comprehensive whitelist in LOCATION_OPTIONS located in src/shared/keyword-locations.ts. When a user requests an unsupported location, the validation functions isSupportedLocationCode() and isLabsLocationCode() return false before any API call is attempted, preventing charged errors and allowing the application to fallback to project defaults or return clear validation messages.

What is the difference between the Labs and Google Ads API providers in the OpenSEO integration?

According to the source code in src/shared/keyword-locations.ts, the Labs API is the default provider for most markets and offers broad SERP data coverage, while the Google Ads API is reserved for specific locations marked with googleAdsOnly: true. The function getKeywordDataProvider() automatically routes requests to the correct endpoint based on the target location code's configuration.

How does OpenSEO validate language codes before sending requests to DataForSEO?

The integration validates languages through isSupportedLanguageCode() and isLanguageServedForLocation(), which cross-reference the requested language against SERP_LANGUAGE_OPTIONS and location-specific subsets. Additionally, resolveKeywordDataLanguage() ensures that the final language code sent to DataForSEO is actually supported for the specific location, avoiding the "Invalid Field: language_code" error that would otherwise consume API credits.

Where is the DataForSEO client configuration and routing logic located?

The core mapping and routing logic resides in src/shared/keyword-locations.ts, while high-level consumption occurs in src/server/mcp/tools/dataforseo-research-tools.ts, src/server/workflows/RankCheckWorkflow.ts, and various server functions like src/serverFunctions/backlinks.ts. This separation keeps provider-specific logic isolated in the shared utilities while business logic remains in the respective tools and workflows.

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 →