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

> Discover how the DataForSEO integration in OpenSEO structures location mapping and API routing for efficient data retrieval. Learn about type-safe validation and provider selection.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: architecture
- Published: 2026-09-02

---

**The DataForSEO integration in OpenSEO is built around a type-safe mapping layer in [`src/shared/keyword-locations.ts`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/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.

### Backlink and AI Search Functions

The server functions in [`src/serverFunctions/backlinks.ts`](https://github.com/every-app/open-seo/blob/main/src/serverFunctions/backlinks.ts) and [`src/serverFunctions/ai-search.ts`](https://github.com/every-app/open-seo/blob/main/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

```typescript
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

```typescript
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`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/src/shared/keyword-locations.ts), while high-level consumption occurs in [`src/server/mcp/tools/dataforseo-research-tools.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/tools/dataforseo-research-tools.ts), [`src/server/workflows/RankCheckWorkflow.ts`](https://github.com/every-app/open-seo/blob/main/src/server/workflows/RankCheckWorkflow.ts), and various server functions like [`src/serverFunctions/backlinks.ts`](https://github.com/every-app/open-seo/blob/main/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.