Skip to main content

DataForSEO Integration

Complete guide to DataForSEO API integration, rate limits, and usage patterns.


Overview

DataForSEO provides keyword research, SERP tracking, and competitive intelligence data. RankFabric uses several DataForSEO APIs:

  • Instant Pages - Fetch HTML snapshots of websites
  • Keyword Suggestions - Related keywords with search volume
  • Keyword Overview - Full keyword metrics (volume, CPC, intent, history)
  • Categories for Keywords - Category classification
  • Keywords for Keywords - Related keyword discovery
  • SERP API - Search ranking positions
  • Domain Metrics - Top domains per category

Configuration

Environment Variables

Set in wrangler.toml:

[vars]
DATAFORSEO_LABS_LIMIT = "100"
DATAFORSEO_LABS_MAX_REQUESTS = "1"
DATAFORSEO_DAILY_BUDGET = "50"

Secrets

Store credentials securely:

echo "your-login" | wrangler secret put DATAFORSEO_LOGIN
echo "your-password" | wrangler secret put DATAFORSEO_PASSWORD

Get credentials: Sign up at dataforseo.com


APIs Used

1. Instant Pages

Fetch HTML snapshots of websites for analysis.

Endpoint: POST https://api.dataforseo.com/v3/on_page/instant_pages

Used In: src/lib/dataforseo.jsfetchInstantPage()

Request:

[{
"target": "example.com",
"check_spell": false,
"disable_cookie_popup": true,
"load_resources": false,
"enable_javascript": false
}]

Response:

{
"tasks": [{
"result": [{
"items": [{
"url": "https://example.com",
"content": "<!DOCTYPE html>...",
"meta": {...}
}]
}],
"cost": 0.01
}]
}

Cost: ~$0.01 per page

Rate Limit: 2000 requests/minute

Usage:

  • Keyword research flow (analyze site HTML)
  • Content extraction for LLM analysis

2. Keyword Suggestions

Get related keywords with search volume.

Endpoint: POST https://api.dataforseo.com/v3/dataforseo_labs/google/keyword_suggestions/live

Used In: src/lib/dataforseo.jsfetchKeywordSuggestions()

Request:

[{
"keyword": "seo tools",
"location_code": 2840,
"language_code": "en",
"limit": 100
}]

Response:

{
"tasks": [{
"result": [{
"items": [
{
"keyword": "best seo tools",
"search_volume": 8100,
"competition": 0.75,
"cpc": 12.50
}
]
}]
}]
}

Cost: ~$0.004 per 100 keywords

Batch Limit: 100 keywords per request

Usage:

  • Generate related keywords
  • Expand keyword lists

3. Keyword Overview

Full keyword data including 72-month history.

Endpoint: POST https://api.dataforseo.com/v3/dataforseo_labs/google/keyword_overview/live

Used In: src/endpoints/keyword-overview.js

Request:

[{
"keywords": ["seo tools", "keyword research"],
"location_code": 2840,
"language_code": "en"
}]

Response:

{
"tasks": [{
"result": [{
"items": [
{
"keyword": "seo tools",
"search_volume": 27100,
"difficulty": 75,
"cpc": 15.30,
"competition": 0.85,
"monthly_searches": [
{"month": 11, "year": 2025, "search_volume": 27100}
],
"keyword_properties": {
"intent": "commercial"
}
}
]
}]
}]
}

Cost: ~$0.004 per keyword

Batch Limit: 100 keywords per request

Usage:

  • Get comprehensive keyword metrics
  • Historical trend analysis

4. Categories for Keywords

Get DataForSEO category IDs for keywords.

Endpoint: POST https://api.dataforseo.com/v3/dataforseo_labs/google/categories_for_keywords/live

Used In: src/endpoints/categories-for-keywords.js

Request:

[{
"keywords": ["seo tools", "keyword research"],
"location_code": 2840,
"language_code": "en"
}]

Response:

{
"tasks": [{
"result": [{
"items": [
{
"keyword": "seo tools",
"categories": [12045, 12046]
}
]
}]
}]
}

Cost: ~$0.004 per 100 keywords

Usage:

  • Auto-categorize keywords
  • Map to DataForSEO category taxonomy

5. Keywords for Keywords

Get related keywords ranked by relevance.

Endpoint: POST https://api.dataforseo.com/v3/keywords_data/google_ads/keywords_for_keywords/live

Used In: src/endpoints/keywords-for-keywords.js

Request:

[{
"keywords": ["seo tools"],
"location_code": 2840,
"language_code": "en",
"sort_by": "relevance"
}]

Response:

{
"tasks": [{
"result": [{
"keywords": [
{
"keyword": "best seo tools",
"competition": "HIGH",
"search_volume": 8100
}
]
}]
}]
}

Cost: ~$0.05 per request

Usage:

  • Keyword expansion
  • AI prompt enrichment

6. SERP API

Get search engine ranking positions.

Endpoint: POST https://api.dataforseo.com/v3/serp/google/organic/live/advanced

Used In: src/lib/dataforseo.jsfetchSerpResults()

Request:

[{
"keyword": "seo tools",
"location_code": 2840,
"language_code": "en",
"device": "desktop",
"depth": 100
}]

Response:

{
"tasks": [{
"result": [{
"items": [
{
"type": "organic",
"rank_group": 1,
"rank_absolute": 1,
"url": "https://example.com/seo-tools",
"title": "Best SEO Tools",
"description": "..."
}
]
}]
}]
}

Cost: ~$0.003 per keyword

Usage:

  • SERP tracking
  • Competitive analysis

Rate Limits & Quotas

Account Limits

Default limits (varies by plan):

  • Requests per minute: 2000
  • Requests per day: Unlimited (cost-based)
  • Concurrent requests: 100

Budget Management

RankFabric tracks daily budget in KV:

Budget Key: budget:daily

Check budget:

const spent = await env.DFS_BUDGETS.get('budget:daily');
const limit = env.DATAFORSEO_DAILY_BUDGET || 50;

Budget enforcement:

if (parseFloat(spent) >= parseFloat(limit)) {
throw new Error('Daily budget exceeded');
}

Reset: Automatic at midnight UTC


Caching Strategy

KV Cache

DataForSEO responses are cached in KV to reduce costs.

Cache Keys:

dfs:categories:{keyword}
dfs:suggestions:{keyword}:{location}
dfs:serp:{keyword}:{location}:{device}

TTL:

  • Category data: 30 days
  • Keyword suggestions: 7 days
  • SERP data: 1 day

Example:

const cacheKey = `dfs:suggestions:${keyword}:${location}`;
const cached = await env.DFS_RUNS.get(cacheKey);
if (cached) return JSON.parse(cached);

// Fetch from DataForSEO
const result = await fetchFromDataForSEO(...);

// Cache result
await env.DFS_RUNS.put(cacheKey, JSON.stringify(result), {
expirationTtl: 86400 * 7
});

Category Taxonomy

DataForSEO provides 3,182 categories stored in KV.

KV Key: dataforseo-categories.json

Structure:

{
"12045": {
"id": 12045,
"name": "Internet & Telecom > Web Services > SEO & SEM",
"path": ["Internet & Telecom", "Web Services", "SEO & SEM"]
}
}

Usage:

// Get all categories
const categoriesJson = await env.DFS_RUNS.get('dataforseo-categories.json');
const categories = JSON.parse(categoriesJson);

// Map category ID to name
const categoryName = categories[12045]?.name;

Error Handling

Common Errors

401 Unauthorized:

{
"status_code": 20103,
"status_message": "Incorrect login or password"
}

Fix: Verify DATAFORSEO_LOGIN and DATAFORSEO_PASSWORD secrets

429 Rate Limit:

{
"status_code": 40901,
"status_message": "Rate limit exceeded"
}

Fix: Implement backoff/retry or reduce request rate

402 Insufficient Funds:

{
"status_code": 40204,
"status_message": "Insufficient account balance"
}

Fix: Add credits to DataForSEO account

Retry Logic

Automatic retry with exponential backoff:

async function retryWithBackoff(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (err) {
if (i === maxRetries - 1) throw err;
const delay = Math.pow(2, i) * 1000;
await new Promise(res => setTimeout(res, delay));
}
}
}

Retry on:

  • Network errors
  • 5xx server errors
  • Rate limit errors (with longer delay)

Don't retry on:

  • 401 authentication errors
  • 400 bad request errors
  • 402 insufficient funds

Cost Optimization

Best Practices

  1. Use batch endpoints:

    // Good: 100 keywords in 1 request ($0.004)
    fetchKeywordOverview(keywords: [...100])

    // Bad: 100 requests ($0.40)
    for (const kw of keywords) {
    fetchKeywordOverview([kw])
    }
  2. Cache aggressively:

    • Category data rarely changes → 30 day TTL
    • Search volume changes monthly → 7 day TTL
  3. Use cheaper APIs when possible:

    • Keyword Suggestions ($0.004) vs Keywords for Keywords ($0.05)
  4. Set daily budgets:

    [vars]
    DATAFORSEO_DAILY_BUDGET = "25"
  5. Monitor costs:

    -- Track daily spending in ClickHouse
    SELECT
    toDate(created_at) as date,
    SUM(cost) as total_cost
    FROM dataforseo_requests
    GROUP BY date
    ORDER BY date DESC;

Implementation Details

Authentication

HTTP Basic Auth with Base64 encoding:

function getAuthHeader(env) {
const login = env.DATAFORSEO_LOGIN;
const password = env.DATAFORSEO_PASSWORD;
const credentials = `${login}:${password}`;
const encoded = btoa(unescape(encodeURIComponent(credentials)));
return `Basic ${encoded}`;
}

Request Format

All DataForSEO endpoints expect POST with JSON array:

const payload = [{
keyword: "seo tools",
location_code: 2840,
language_code: "en"
}];

const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': getAuthHeader(env)
},
body: JSON.stringify(payload)
});

Response Parsing

Standard response structure:

const data = await response.json();
const tasks = data.tasks || [];
const results = [];

for (const task of tasks) {
const taskResults = task.result || [];
for (const result of taskResults) {
const items = result.items || [];
results.push(...items);
}
}

Cost tracking:

const cost = tasks[0]?.cost || 0;
await trackDataForSEOCost(cost);

Location Codes

Common location codes:

CodeLocation
2840United States
2826United Kingdom
2124Canada
2036Australia
2276Germany

Full list: DataForSEO Location Codes


Language Codes

Common language codes:

CodeLanguage
enEnglish
esSpanish
frFrench
deGerman
jaJapanese

Full list: DataForSEO Language Codes


File Locations

  • Main library: src/lib/dataforseo.js
  • Adapters: src/adapters/dataforseo-instant-pages-adapter.js
  • Endpoints: src/endpoints/*
  • Category mapping: src/lib/dataforseo-categories.js

See Also