How OpenSEO Handles Keyword Research Using DataForSEO

OpenSEO performs keyword research by orchestrating requests to the DataForSEO Labs Keywords Data API through a layered architecture that handles authentication, location normalization, credit-based billing, and granular error recovery.

OpenSEO is an open-source SEO platform that integrates deeply with DataForSEO to deliver comprehensive keyword research capabilities. The implementation spans multiple TypeScript modules in the every-app/open-seo repository that transform user inputs into valid API requests while automatically tracking usage costs. This article examines the exact mechanisms used to fetch, validate, and bill for keyword data.

The DataForSEO Integration Architecture

OpenSEO’s keyword research capability is built on five logical layers that process a request from the UI to the external API and back. The flow begins when a user selects a research scope—such as domain, subdomains, subfolder, or exact URL—and submits a seed keyword.

The architecture relies on src/server/lib/dataforseo/client.ts to construct authenticated requests, src/shared/billing-credit-features.ts to map API endpoints to internal credit features, and src/shared/keyword-locations.ts to normalize locale settings. Execution is managed by src/server/workflows/RankCheckWorkflow.ts, which also handles credit deduction and error telemetry.

Constructing Authenticated Requests

The createDataforseoClient function in src/server/lib/dataforseo/client.ts handles the core communication with DataForSEO. It constructs the JSON payload required by the API, including the keyword, language, and location parameters.

Authentication uses base-64 encoding of the email:password combination, which is added to the HTTP headers alongside the required content-type specifications. The client supports multiple DataForSEO Labs endpoints, including v3/dataforseo_labs/google/related_keywords/live and the keyword suggestions endpoint, each accepting a payload with keyword, language_code, and location_code fields.

Mapping Endpoints to Billing Credits

Before any HTTP request executes, OpenSEO determines the cost implications. The file src/shared/billing-credit-features.ts maps each DataForSEO API path to an internal credit feature—specifically keyword_research for keyword-related endpoints.

This mapping enables automatic per-user usage tracking. When the workflow triggers a request, the system debits the appropriate number of credits from the user's balance based on the mapped feature, ensuring costs are recorded regardless of whether the request succeeds or fails.

Validating Locations and Languages

Keyword research accuracy depends on correct geographic and linguistic targeting. The src/shared/keyword-locations.ts module validates that the supplied domain and locale are supported by DataForSEO Labs.

This layer rejects malformed hosts or IP addresses before a request is transmitted. It translates the UI-friendly location name into the standard DataForSEO location_code and language_code parameters (for example, converting "United States" to location_code: "us" and language_code: "en"), preventing invalid API calls that would consume credits without returning data.

Workflow Execution and Scope Filtering

The src/server/workflows/RankCheckWorkflow.ts orchestrates the end-to-end execution of keyword research tasks. It manages the interaction between the DataForSEO client and the billing system.

For advanced filtering, src/shared/researchScope.ts defines RESEARCH_SCOPE_FILTER_SLOTS, which determines how many of DataForSEO’s eight available filter slots are consumed based on the chosen research scope. A subfolder scope consumes more filter slots than a domain-level scope, allowing the platform to enforce scope-based filtering constraints before sending the request.

Handling Charged Errors and Telemetry

DataForSEO bills for certain errors—such as "Invalid Field" responses—meaning the user pays even if no data returns. OpenSEO handles this through DataforseoChargedTaskError, implemented in the client logic and tested in src/server/lib/dataforseo/client.test.ts.

When a charged error occurs, the workflow still records the exact USD cost against the user’s credit balance and propagates a useful error message to the front-end. This prevents hidden over-usage while maintaining transparent billing records for both successful and failed API interactions.

Practical Implementation Example

The following TypeScript example demonstrates fetching related keywords using the OpenSEO DataForSEO client, including error handling for billed failures:

import { createDataforseoClient } from "@/server/lib/dataforseo/client";
import { billingCustomer } from "@/server/lib/billing";

async function fetchRelatedKeywords(seed: string) {
  const client = createDataforseoClient(billingCustomer);

  const payload = {
    keyword: seed,
    language_code: "en",
    location_code: "us",
  };

  const result = await client.keywords.relatedKeywords(payload);
  return result;
}

try {
  const data = await fetchRelatedKeywords("open source seo");
  console.log("Related keywords:", data);
} catch (e) {
  if (e instanceof DataforseoChargedTaskError) {
    console.warn("DataForSEO error (billed):", e.message);
  } else {
    console.error("Unexpected error:", e);
  }
}

This implementation hits the v3/dataforseo_labs/google/related_keywords/live endpoint and returns an array of keyword objects containing search volume, difficulty, and intent data.

Summary

  • Request Building: The createDataforseoClient function in client.ts constructs authenticated payloads using base-64 encoded credentials and standard DataForSEO parameters.
  • Credit Mapping: billing-credit-features.ts automatically maps API endpoints to the keyword_research credit feature for granular usage tracking.
  • Locale Validation: keyword-locations.ts ensures only valid location_code and language_code combinations are transmitted to DataForSEO.
  • Scope Management: researchScope.ts enforces filter slot limits based on whether the user searches across domains, subdomains, subfolders, or exact URLs.
  • Error Accountability: DataforseoChargedTaskError captures billed errors to ensure credit balances are accurately maintained even when API calls fail.

Frequently Asked Questions

How does OpenSEO authenticate with the DataForSEO API?

OpenSEO authenticates using base-64 encoding of the user's email and password combination, which is added to the HTTP headers in src/server/lib/dataforseo/client.ts. This header is included with every request to the DataForSEO Labs endpoints, ensuring secure access to the keyword data.

What happens if a keyword research request fails?

If the failure is a "charged error"—such as an invalid field or malformed parameter—OpenSEO throws a DataforseoChargedTaskError. The system still debits the user's credit balance for the cost of the call and logs the exact USD amount, then surfaces a friendly error message to the UI. Uncharged errors are handled as standard exceptions without billing.

How does OpenSEO handle different geographic markets?

The platform uses src/shared/keyword-locations.ts to validate and translate user-selected locations into DataForSEO's standard location_code and language_code identifiers. This prevents invalid requests and ensures search volume and difficulty metrics reflect the intended geographic market.

Can users filter keyword research by specific URL paths?

Yes. OpenSEO supports scope-based filtering (domain, subdomains, subfolder, or exact URL) through src/shared/researchScope.ts. The system calculates required filter slots using RESEARCH_SCOPE_FILTER_SLOTS and constructs the appropriate DataForSEO payload, enabling targeted keyword discovery for specific site sections.

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 →