Skip to main content

RankDisco API Reference

Complete API endpoint documentation for RankDisco (RankFabric Edge Worker).

API Overview

Base URL

Production: https://api.rankdisco.com
Development: https://rankdisco-api.your-subdomain.workers.dev

Authentication

All API endpoints (except webhooks and public endpoints) require authentication via API key.

Header Authentication (Recommended)

Authorization: Bearer YOUR_API_KEY

Query Parameter Authentication

GET /api/endpoint?api_key=YOUR_API_KEY

Rate Limits

TierRequests/minuteBurst
Free60100
Pro300500
EnterpriseUnlimitedUnlimited

Response Format

All responses are JSON with consistent structure:

Success Response

{
"success": true,
"data": { ... },
"count": 100,
"pagination": {
"limit": 50,
"offset": 0,
"has_more": true
}
}

Error Response

{
"error": "Error message",
"details": "Additional context",
"status": 400
}

Common HTTP Status Codes

CodeDescription
200Success
201Created
400Bad Request - Invalid parameters
401Unauthorized - Invalid or missing API key
404Not Found
429Rate Limited
500Internal Server Error

Endpoint Categories

  • Projects - Project management
  • Assets - Asset management (websites, apps, local businesses)
  • Keywords - Keyword research and tracking
  • Rankings - SERP and App Store rankings
  • Apps - App Store intelligence
  • Domains - Domain management and metrics
  • Admin - Administrative operations
  • Webhooks - External callback handlers

Projects

Create Project

Creates a new project for organizing tracking subscriptions.

POST /api/projects

Request Body

{
"organization_id": "org_abc123",
"name": "My Project",
"description": "Optional description",
"settings": {
"default_location_code": 2840,
"default_language_code": "en"
}
}

Response

{
"success": true,
"project": {
"id": "proj_xyz789",
"organization_id": "org_abc123",
"name": "My Project",
"description": "Optional description",
"status": "active",
"settings": { ... },
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
}

Error Codes

CodeDescription
400Missing required fields (organization_id, name)
500Database error

List Projects

GET /api/projects?organization_id={org_id}&status={status}&limit={limit}&offset={offset}

Query Parameters

ParameterTypeRequiredDefaultDescription
organization_idstringYes-Organization ID
statusstringNoactiveFilter: active, paused, archived, all
limitintegerNo100Max results (max: 500)
offsetintegerNo0Pagination offset

Response

{
"success": true,
"projects": [
{
"id": "proj_xyz789",
"name": "My Project",
"status": "active",
...
}
],
"count": 10,
"total": 25,
"pagination": {
"limit": 100,
"offset": 0,
"has_more": false
}
}

Get Project

GET /api/projects/{project_id}

Response

{
"success": true,
"project": {
"id": "proj_xyz789",
"name": "My Project",
"status": "active",
"stats": {
"total_keywords": 150,
"total_apps": 5,
"total_assets": 12
},
...
}
}

Update Project

PUT /api/projects/{project_id}

Request Body

{
"name": "Updated Name",
"description": "Updated description",
"status": "paused",
"settings": { ... }
}

Delete Project

Soft-deletes a project by setting status to archived.

DELETE /api/projects/{project_id}

Assets

Assets represent your owned properties: websites, apps, and local businesses.

Create Asset

POST /api/assets

Request Body (Website)

{
"project_id": "proj_xyz789",
"type": "website",
"value": "example.com",
"name": "My Website",
"skip_onboarding": false,
"backlinks_limit": 100,
"keywords_limit": 100
}

Request Body (iOS App)

{
"project_id": "proj_xyz789",
"type": "app_ios",
"value": "123456789",
"name": "My App",
"platform": "apple",
"icon_url": "https://...",
"app_id": "123456789",
"bundle_id": "com.example.app"
}

Request Body (Local Business)

{
"project_id": "proj_xyz789",
"type": "local",
"value": "ChIJ...",
"name": "My Business",
"place_id": "ChIJ...",
"cid": "12345678901234567890",
"location_id": 1026201,
"lat": 30.2672,
"lng": -97.7431,
"address": "123 Main St, Austin, TX",
"phone": "+1-512-555-1234"
}

Response

{
"success": true,
"id": "asset_abc123",
"message": "Asset saved",
"domain_id": 456,
"onboarding": {
"started": true,
"orchestration": "workflow",
"workflow_id": "wf_xyz",
"status_url": "/api/admin/workflow/asset-onboard/wf_xyz"
}
}

List Assets

GET /api/assets?project_id={project_id}

Response

{
"assets": [
{
"id": "asset_abc123",
"project_id": "proj_xyz789",
"type": "website",
"value": "example.com",
"name": "My Website",
"platform": null,
"icon_url": null,
"meta_json": "{}",
"created_at": 1705315800000,
"updated_at": 1705315800000
}
]
}

Get Asset

GET /api/assets/{asset_id}

Update Asset

PUT /api/assets/{asset_id}

Request Body

{
"name": "Updated Name",
"icon_url": "https://...",
"meta": { "key": "value" }
}

Delete Asset

DELETE /api/assets/{asset_id}

Keywords

Track Keywords

Start tracking keywords for SERP rankings.

POST /api/keywords/track

Request Body (Single Keyword)

{
"project_id": "proj_xyz789",
"keyword_text": "best seo tools",
"location_code": 2840,
"language_code": "en",
"device": "desktop",
"target_domain": "example.com"
}

Request Body (Batch)

{
"keywords": [
{
"project_id": "proj_xyz789",
"keyword_text": "best seo tools",
"location_code": 2840,
"language_code": "en",
"device": "desktop"
},
{
"project_id": "proj_xyz789",
"keyword_text": "seo software",
"location_code": 2840,
"language_code": "en",
"device": "mobile"
}
]
}

Response

{
"success": true,
"message": "Keywords successfully added to tracking",
"keywords_tracked": 2,
"keywords": [
{
"keyword_id": "kw_abc123",
"keyword_text": "best seo tools",
"status": "tracking",
"serp_queued": true
}
],
"serp_tracking": {
"orchestration": "workflow",
"keywords_queued": 2
},
"estimated_completion": "2024-01-15T10:35:00Z"
}

Keyword Suggestions

Get related keywords with search volume data.

POST /api/keywords/suggestions

Request Body

{
"keyword": "seo tools",
"location_code": 2840,
"language_code": "en",
"limit": 100,
"include_seed_keyword": true,
"include_serp_info": false
}

Response

{
"success": true,
"count": 100,
"data": {
"seed_keyword": "seo tools",
"total_count": 5432,
"items_count": 100,
"keywords": [
{
"keyword": "free seo tools",
"keyword_info": {
"search_volume": 12100,
"competition": 0.45,
"competition_level": "MEDIUM",
"cpc": 5.23,
"categories": [10003, 10004]
},
"category_names": ["Software", "Internet & Telecom"]
}
]
}
}

Keyword Overview

Get comprehensive keyword data including 84-month history.

POST /api/keywords/overview

Request Body

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

Response

{
"success": true,
"keywords": [
{
"keyword": "seo tools",
"search_volume": 33100,
"competition": 0.67,
"cpc": 8.45,
"search_intent": "commercial",
"monthly_searches": [
{ "year": 2024, "month": 1, "search_volume": 33100 }
],
"categories": [10003]
}
]
}

AI Search Volume

Get AI search volume for keywords (ChatGPT, Gemini, etc.).

POST /api/keywords/ai-search-volume

Request Body

{
"keywords": ["best crm software", "project management tools"],
"location_code": 2840,
"language_code": "en"
}

Keywords for Keywords

Get related keywords sorted by relevance.

POST /api/keywords/for-keywords

Request Body

{
"keywords": ["seo", "content marketing"],
"location_code": 2840,
"language_code": "en",
"limit": 50
}

Categories for Keywords

Get DataForSEO category IDs for keywords.

POST /api/keywords/categories

Request Body

{
"keywords": ["seo tools", "marketing software"],
"location_code": 2840,
"language_code": "en"
}

Rankings

Track Rankings

Check SERP rankings for keywords (on-demand).

POST /api/rankings/track

Request Body

{
"keywords": [
{
"project_id": "proj_xyz789",
"keyword_text": "best seo tools",
"location_code": 2840,
"language_code": "en",
"device": "desktop",
"target_domain": "example.com",
"depth": 100
}
]
}

Response

{
"success": true,
"results": [
{
"keyword_id": "kw_abc123",
"keyword": "best seo tools",
"success": true,
"run_id": "run_xyz",
"results_count": 100,
"position": 7,
"matched_domain": "example.com",
"top_domains": [
{ "position": 1, "domain": "ahrefs.com", "url": "..." }
],
"cost": 0.0035
}
],
"total_keywords": 1,
"total_cost": 0.0035
}

Get Rankings

Retrieve stored rankings for a project.

GET /api/rankings?project_id={project_id}&keyword={keyword}&channel={channel}&limit={limit}

Query Parameters

ParameterTypeRequiredDescription
project_idstringYesProject ID
keywordstringNoFilter by keyword (prefix match)
asset_idstringNoFilter by asset
channelstringNoseo, local, local_pack, app_store, apple_app_store, google_play_store
relationshipstringNoMINE, COMPETITOR, OTHER
limitintegerNoMax results (default: 50, max: 200)

Response

{
"rankings": [
{
"id": "serp_run123_7",
"keyword": "best seo tools",
"position": 7,
"previous_position": 9,
"change": 2,
"url": "https://example.com/seo-tools",
"domain": "example.com",
"title": "Best SEO Tools in 2024",
"platform": "google",
"channel": "seo",
"check_date": "2024-01-15",
"check_ts": "2024-01-15T10:30:00Z",
"asset_name": "My Website",
"relationship": "MINE",
"status": "ranked"
}
],
"count": 50,
"project_id": "proj_xyz789"
}

Apps

Search for apps to add as assets.

POST /api/apps/search

Request Body

{
"query": "spotify",
"platform": "apple",
"limit": 10
}

Response

{
"query": "spotify",
"platform": "apple",
"results": [
{
"app_id": "324684580",
"title": "Spotify - Music and Podcasts",
"platform": "apple",
"url": "https://apps.apple.com/app/id324684580",
"icon": "https://...",
"developer": "Spotify AB",
"rating": 4.8,
"reviews_count": 12500000,
"is_free": true,
"category": "Music"
}
],
"cost": 0.00144
}

Track App

Start tracking an app for rankings.

POST /api/apps/track

Request Body

{
"project_id": "proj_xyz789",
"app_id": "324684580",
"platform": "apple",
"name": "Spotify",
"icon_url": "https://...",
"url": "https://apps.apple.com/app/id324684580",
"frequency": "daily"
}

Response

{
"success": true,
"subscription": {
"id": "sub_abc123",
"project_id": "proj_xyz789",
"app_id": "324684580",
"platform": "apple",
"name": "Spotify",
"status": "active",
"frequency": "daily",
"next_run_at": "2024-01-16T10:30:00Z",
"tracking_enabled": true
},
"asset": {
"id": "asset_xyz",
"type": "app_ios",
"value": "324684580",
"name": "Spotify",
"role": "primary"
},
"orchestration": {
"type": "workflow",
"workflow_id": "wf_123",
"status_url": "/api/admin/workflow/app-details/wf_123"
}
}

Untrack App

DELETE /api/apps/untrack

Request Body

{
"project_id": "proj_xyz789",
"app_id": "324684580",
"platform": "apple"
}

List Apps

GET /api/apps?limit={limit}&offset={offset}

Get App Details

GET /api/apps/{app_id}

Response

{
"id": "324684580",
"platform": "apple",
"title": "Spotify - Music and Podcasts",
"subtitle": "Music and podcasts for everyone",
"developer_name": "Spotify AB",
"description": "With Spotify, you can...",
"rating": 4.8,
"rating_count": 12500000,
"price": 0,
"is_free": true,
"primary_category": "Music",
"icon_url": "https://...",
"screenshot_urls": ["https://..."],
"version": "8.9.10",
"size_bytes": 125829120,
"release_date": "2011-07-14",
"website_url": "https://spotify.com",
"created_at": 1705315800000,
"updated_at": 1705315800000
}

App Stats

GET /api/apps/{app_id}/stats

App Rankings

GET /api/apps/{app_id}/rankings

App Recommendations

GET /api/apps/{app_id}/recommendations

App All Rankings

Get combined category and recommendation rankings.

GET /api/app-store/apps/{app_id}/all-rankings

Domains

Top Domains

Get top-ranking domains.

GET /api/top-domains?limit={limit}

Domain Metrics

Get domain metrics from ClickHouse.

GET /api/domain-metrics?category_id={category_id}&limit={limit}

Admin Endpoints

Administrative endpoints for system management. Require additional admin permissions.

Domain Onboarding

Onboard Domain

Full domain onboarding with backlinks, keywords, and summary fetching.

POST /api/admin/domains/onboard

Request Body

{
"domain": "example.com",
"project_id": "proj_xyz789",
"asset_name": "Example Site",
"backlinks_limit": 1000,
"keywords_limit": 1000,
"skip_backlinks": false,
"skip_keywords": false,
"skip_referring_domains": false,
"location_code": 2840,
"language_code": "en"
}

Response

{
"success": true,
"domain": "example.com",
"domain_id": 123,
"orchestration": "workflow",
"workflow_id": "wf_abc123",
"status_url": "/api/admin/workflow/domain-onboard/wf_abc123",
"asset_id": "asset_xyz",
"project_id": "proj_xyz789",
"message": "Domain onboarding started via workflow orchestration."
}

Domain Status

GET /api/admin/domains/status?domain={domain}

Response

{
"domain": "example.com",
"domain_id": 123,
"data_tier": "customer",
"onboard_status": "completed",
"onboard_started_at": 1705315800000,
"onboard_completed_at": 1705315965000,
"fetch_timestamps": {
"backlinks_fetched_at": 1705315850000,
"keywords_fetched_at": 1705315900000,
"summary_fetched_at": 1705315920000
},
"stats": {
"backlinks": 5432,
"urls_total": 1200,
"urls_classified": 1150,
"keywords": 890,
"has_summary": true
},
"classification": {
"domain_type": "business",
"channel_bucket": "owned_media",
"classification_source": "llm",
"classification_confidence": 85
}
}

Classification Stats

URL Classification Stats

GET /api/admin/classification-stats?source={source}&domain_id={domain_id}

Response

{
"summary": {
"urls": {
"total": 125000,
"classified": 118500,
"crawled": 95000,
"avg_confidence": 78,
"low_confidence": 5200,
"high_confidence": 89000,
"coverage_pct": 95
},
"domains": {
"total": 45000,
"classified": 42000,
"typed": 38000,
"avg_confidence": 82,
"coverage_pct": 93
}
},
"distributions": {
"url_sources": [
{ "classification_source": "rules", "count": 85000 },
{ "classification_source": "llm", "count": 25000 }
],
"page_types": [
{ "page_type": "article", "count": 45000 },
{ "page_type": "product", "count": 22000 }
],
"confidence": [
{ "bucket": "90-100", "count": 65000 },
{ "bucket": "80-89", "count": 24000 }
]
}
}

Browse URLs

GET /api/admin/urls/browse?dimension={dimension}&value={value}&limit={limit}&offset={offset}

Query Parameters

ParameterTypeDescription
dimensionstringpage_type, quality_tier, domain_type, spam_tier, structural_type
valuestringFilter value (use "unknown" for unclassified)
searchstringURL search pattern
sortstringrecent, confidence, url
orderstringasc, desc
domain_idintegerFilter by domain

URL Feedback

Submit corrections for URL classifications.

POST /api/admin/urls/feedback

Request Body

{
"url_id": 12345,
"is_correct": false,
"corrected_page_type": "article",
"corrected_quality_tier": "high",
"corrected_structural_type": "blog_post",
"notes": "This is clearly a blog article"
}

Cost Tracking

Get Cost Summary

GET /api/admin/costs?since={since}&until={until}&minutes={minutes}

Daily Costs

GET /api/admin/costs/daily?days={days}&granularity={granularity}

Query Parameters

ParameterTypeDefaultDescription
daysinteger30Number of days
granularitystringdayminute, hour, day
project_idstring-Filter by project
servicestring-Filter by service

Run Costs

GET /api/admin/costs/run/{run_id}

Project Costs

GET /api/admin/costs/project/{project_id}

Comprehensive Summary

GET /api/admin/costs/summary

Queue Management

Queue Status

GET /api/admin/queues/status

Response

{
"summary": {
"active_queues": 4,
"total_queues": 5,
"total_messages": 1250,
"processing": 45,
"failed": 12,
"processed_today": 8500,
"rate_per_min": 142
},
"queues": [
{
"name": "domain-onboard",
"description": "Domain onboarding & enrichment",
"messages": 250,
"pending": 250,
"processing": 10,
"failed": 2,
"status": "processing",
"consumers": 3
}
]
}

Workflow Management

List Workflows

GET /api/admin/workflows

Running Workflows

GET /api/admin/workflows/running

Workflow History

GET /api/admin/workflows/history

Workflow Failures

GET /api/admin/workflows/failures

Get Workflow Status

GET /api/admin/workflow/{type}/{id}

Trigger Workflow

POST /api/admin/workflow/{type}

Pause Workflow

POST /api/admin/workflow/{type}/{id}/pause

Resume Workflow

POST /api/admin/workflow/{type}/{id}/resume

Terminate Workflow

DELETE /api/admin/workflow/{type}/{id}

Trigger Classification

POST /api/admin/classifier/classify

Browse Classified URLs

GET /api/admin/classifier/browse

Brand Management

Populate Brands

POST /api/admin/populate-brands

Lock Brand

POST /api/admin/brands/{brand_id}/lock

Lock App Brand

POST /api/admin/apps/{app_id}/lock-brand

Assign Brand

POST /api/admin/apps/{app_id}/assign-brand

Cleanup Operations

Admin Cleanup

POST /api/admin/cleanup

Fix Primary Categories

POST /api/admin/fix-primary-categories

Fix Category IDs

POST /api/admin/fix-category-ids

Fix Games Categories

POST /api/admin/fix-games-categories

Data Migration

Migrate to ClickHouse

POST /api/admin/migrate-to-clickhouse

Webhook Endpoints

External callback handlers for third-party services.

DataForSEO App Info Webhook

Receives app details when DataForSEO tasks complete.

POST /api/dataforseo/app-info-webhook

Note: Called by DataForSEO service. Payload is gzip-compressed JSON.


DataForSEO App List Webhook

Receives app list results from DataForSEO.

POST /api/dataforseo/app-list-webhook

Pipeline Monitoring

Pipeline Activity

Get real-time pipeline activity stats.

GET /api/pipeline-activity?range={range}

Query Parameters

ParameterTypeDefaultDescription
rangestring5mTime range: 5m, 15m, 1h, 6h, 24h

Response

{
"success": true,
"nodes": {
"classify-backlinks": {
"active": 5,
"currentQueued": 120,
"queuePending": 250,
"started": 1500,
"completed": 1450,
"failed": 15,
"successRate": 99,
"avgLatencyMs": 850
}
},
"uniqueItems": {
"urlsQueued": 5000,
"urlsClassified": 4850,
"keywordsQueued": 2000,
"keywordsClassified": 1920,
"domainsActive": 25
},
"timeRange": "5m",
"timestamp": "2024-01-15T10:30:00Z"
}

DAG Session Activation

Activate/deactivate DAG monitoring for real-time updates.

POST /api/dag-session/activate
DELETE /api/dag-session/activate

Internal Endpoints

Service-to-service APIs for internal operations.

Fetch Content

Fetch and parse webpage content.

POST /api/fetch-content

Request Body

{
"url": "https://example.com/page",
"extract_meta": true,
"max_text": 50000
}

Resolve Domain

Resolve www vs non-www domain before adding.

POST /api/util/resolve-domain

Request Body

{
"domain": "example.com"
}

Response

{
"input": "example.com",
"resolved": "www.example.com",
"redirected": true
}

Search for DataForSEO location codes.

GET /api/locations/search?q={query}

Resolve Location

Resolve location name to location code.

POST /api/locations/resolve

Test Endpoints

Development and testing endpoints (require authentication).

Debug Auth

GET /test/debug-auth

Classifier Evaluation

GET /api/test/classifier-eval
POST /api/test/classifier-eval

Test DataForSEO

GET /api/test-dataforseo

Error Codes Reference

CodeEndpoint GroupDescription
400AllMissing required parameters
401AllInvalid or missing API key
404Projects, AssetsResource not found
409AssetsDuplicate asset
429AllRate limit exceeded
500AllInternal server error
502DataForSEOUpstream API error

DataForSEO Response Structure

All DataForSEO proxy endpoints return this structure:

{
"tasks": [{
"result": [{
"items": [
{ /* actual data */ }
],
"total_count": 12345
}],
"cost": 0.01
}]
}

Standard parsing: data.tasks[0].result[0].items


Cost Reference

ServiceEndpointCost
DataForSEO SERP/serp/google/organic/live/advanced$0.0035/request
DataForSEO Backlinks/backlinks/summary/live$0.02/request
DataForSEO Keywords/dataforseo_labs/google/keyword_suggestions$0.04/100 keywords
DataForSEO App List/app_data/apple/app_listings/search/live$0.00144/request
DataForSEO App Info/app_data/apple/app_info/task_post$0.015/app
Workers AIClassification$0.011/1K neurons
ZenRowsWeb scrapingPlan-based

SDK Examples

JavaScript/TypeScript

const response = await fetch('https://api.rankdisco.com/api/keywords/track', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
project_id: 'proj_xyz789',
keyword_text: 'best seo tools',
location_code: 2840,
language_code: 'en'
})
});

const data = await response.json();
console.log(data.keywords);

Python

import requests

response = requests.post(
'https://api.rankdisco.com/api/keywords/track',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'project_id': 'proj_xyz789',
'keyword_text': 'best seo tools',
'location_code': 2840,
'language_code': 'en'
}
)

data = response.json()
print(data['keywords'])

cURL

curl -X POST https://api.rankdisco.com/api/keywords/track \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"project_id": "proj_xyz789",
"keyword_text": "best seo tools",
"location_code": 2840,
"language_code": "en"
}'