Keyword Research
Discover new keyword opportunities, generate content ideas, and analyze search trends using the SerpWatch Keyword Research API.
Overview
The Keyword Research API helps you expand your keyword universe by generating related keyword ideas, providing autocomplete suggestions, and revealing trending search topics. These endpoints deliver real-time data directly from search engines.
Available Endpoints
| Endpoint | Purpose | Response |
|---|---|---|
/api/v1/keyword-research/ideas |
Generate keyword ideas from seed keywords | Async (task-based) |
/api/v1/keyword-research/suggest/live |
Get autocomplete suggestions | Synchronous |
/api/v1/keyword-research/trends/live |
Get trending searches | Synchronous |
Use Cases
- Content Planning - Find new topics to write about based on search demand
- SEO Strategy - Discover long-tail variations of your target keywords
- PPC Campaigns - Expand your keyword lists for paid search
- Market Research - Understand what people are searching for in your industry
- Trend Analysis - Identify emerging topics and seasonal patterns
Autocomplete Suggestions
The /suggest/live endpoint returns Google autocomplete suggestions for any seed keyword.
This is a synchronous endpoint that returns results immediately.
curl -X POST "https://engine.v2.serpwatch.io/api/v1/keyword-research/suggest/live" \
-H "Authorization: Bearer $SERPWATCH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"keyword": "project management",
"location_code": 2840,
"language_code": "en"
}'
import requests
import os
API_KEY = os.environ.get("SERPWATCH_API_KEY")
BASE_URL = "https://engine.v2.serpwatch.io"
response = requests.post(
f"{BASE_URL}/api/v1/keyword-research/suggest/live",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"keyword": "project management",
"location_code": 2840, # United States
"language_code": "en"
}
)
suggestions = response.json()
for suggestion in suggestions.get("result", []):
print(f" - {suggestion['keyword']}")
const API_KEY = process.env.SERPWATCH_API_KEY;
const BASE_URL = "https://engine.v2.serpwatch.io";
const response = await fetch(
`${BASE_URL}/api/v1/keyword-research/suggest/live`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
keyword: "project management",
location_code: 2840, // United States
language_code: "en"
})
}
);
const suggestions = await response.json();
for (const suggestion of suggestions.result || []) {
console.log(` - ${suggestion.keyword}`);
}
Response Example
{
"status": "success",
"result": [
{ "keyword": "project management software" },
{ "keyword": "project management tools" },
{ "keyword": "project management certification" },
{ "keyword": "project management jobs" },
{ "keyword": "project management app" },
{ "keyword": "project management methodologies" },
{ "keyword": "project management courses" },
{ "keyword": "project management skills" }
]
}
Generating Keyword Ideas
The /ideas endpoint generates a comprehensive list of related keywords
from your seed keywords. This is an async endpoint that returns a task ID.
Submit Seed Keywords
Send one or more seed keywords to generate ideas from.
Receive Task ID
The API returns a task ID for tracking the request.
Poll or Webhook
Wait for results via polling or receive them via webhook.
Submit Ideas Request
curl -X POST "https://engine.v2.serpwatch.io/api/v1/keyword-research/ideas" \
-H "Authorization: Bearer $SERPWATCH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"keywords": ["project management", "task tracking"],
"location_code": 2840,
"language_code": "en",
"include_seed_keyword": true,
"postback_url": "https://yourapp.com/webhook/keywords"
}'
import requests
import os
API_KEY = os.environ.get("SERPWATCH_API_KEY")
BASE_URL = "https://engine.v2.serpwatch.io"
# Submit keyword ideas request
response = requests.post(
f"{BASE_URL}/api/v1/keyword-research/ideas",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"keywords": ["project management", "task tracking"],
"location_code": 2840, # United States
"language_code": "en",
"include_seed_keyword": True
}
)
task = response.json()
task_id = task["id"]
print(f"Task submitted: {task_id}")
const API_KEY = process.env.SERPWATCH_API_KEY;
const BASE_URL = "https://engine.v2.serpwatch.io";
// Submit keyword ideas request
const response = await fetch(
`${BASE_URL}/api/v1/keyword-research/ideas`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
keywords: ["project management", "task tracking"],
location_code: 2840, // United States
language_code: "en",
include_seed_keyword: true
})
}
);
const task = await response.json();
const taskId = task.id;
console.log(`Task submitted: ${taskId}`);
Retrieve Results
import time
def get_keyword_ideas(task_id, max_wait=120):
"""Poll for keyword ideas results."""
start_time = time.time()
while time.time() - start_time < max_wait:
response = requests.get(
f"{BASE_URL}/api/v1/keyword-research/ideas/{task_id}",
headers={"Authorization": f"Bearer {API_KEY}"}
)
result = response.json()
if result["status"] in ["success", "completed"]:
return result
elif result["status"] == "error":
raise Exception(f"Task failed: {result.get('error_message')}")
time.sleep(3)
raise TimeoutError("Request timed out")
# Get results
result = get_keyword_ideas(task_id)
# Process keyword ideas
for idea in result.get("result", {}).get("keywords", []):
keyword = idea["keyword"]
volume = idea.get("search_volume", "N/A")
print(f"{keyword}: {volume} monthly searches")
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
async function getKeywordIdeas(taskId, maxWait = 120000) {
const startTime = Date.now();
while (Date.now() - startTime < maxWait) {
const response = await fetch(
`${BASE_URL}/api/v1/keyword-research/ideas/${taskId}`,
{ headers: { "Authorization": `Bearer ${API_KEY}` } }
);
const result = await response.json();
if (result.status === "success" || result.status === "completed") {
return result;
} else if (result.status === "error") {
throw new Error(`Task failed: ${result.error_message}`);
}
await sleep(3000);
}
throw new Error("Request timed out");
}
// Get results
const result = await getKeywordIdeas(taskId);
// Process keyword ideas
for (const idea of result.result?.keywords || []) {
const { keyword, search_volume: volume = "N/A" } = idea;
console.log(`${keyword}: ${volume} monthly searches`);
}
Trending Searches
The /trends/live endpoint returns currently trending searches for a specific
location. Use this to discover emerging topics and capitalize on rising search interest.
curl -X POST "https://engine.v2.serpwatch.io/api/v1/keyword-research/trends/live" \
-H "Authorization: Bearer $SERPWATCH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"location_code": 2840,
"language_code": "en"
}'
response = requests.post(
f"{BASE_URL}/api/v1/keyword-research/trends/live",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"location_code": 2840, # United States
"language_code": "en"
}
)
trends = response.json()
print("Trending Searches:")
for trend in trends.get("result", []):
title = trend.get("title", "")
traffic = trend.get("traffic", "")
print(f" {title} - {traffic} searches")
const response = await fetch(
`${BASE_URL}/api/v1/keyword-research/trends/live`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
location_code: 2840, // United States
language_code: "en"
})
}
);
const trends = await response.json();
console.log("Trending Searches:");
for (const trend of trends.result || []) {
const { title = "", traffic = "" } = trend;
console.log(` ${title} - ${traffic} searches`);
}
Complete Workflow Example
Here's a complete example that combines autocomplete suggestions with keyword ideas to build a comprehensive keyword list for a topic.
#!/usr/bin/env python3
"""
SerpWatch Keyword Research Workflow
Generates a comprehensive keyword list from a seed topic
"""
import os
import time
import requests
API_KEY = os.environ.get("SERPWATCH_API_KEY")
BASE_URL = "https://engine.v2.serpwatch.io"
def get_suggestions(keyword, location_code=2840):
"""Get autocomplete suggestions for a keyword."""
response = requests.post(
f"{BASE_URL}/api/v1/keyword-research/suggest/live",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"keyword": keyword,
"location_code": location_code,
"language_code": "en"
}
)
response.raise_for_status()
return [s["keyword"] for s in response.json().get("result", [])]
def get_keyword_ideas(keywords, location_code=2840):
"""Get keyword ideas (async workflow)."""
# Submit request
response = requests.post(
f"{BASE_URL}/api/v1/keyword-research/ideas",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"keywords": keywords,
"location_code": location_code,
"language_code": "en",
"include_seed_keyword": True
}
)
response.raise_for_status()
task_id = response.json()["id"]
# Poll for results
for _ in range(40): # Max 2 minutes
result = requests.get(
f"{BASE_URL}/api/v1/keyword-research/ideas/{task_id}",
headers={"Authorization": f"Bearer {API_KEY}"}
).json()
if result["status"] in ["success", "completed"]:
return result.get("result", {}).get("keywords", [])
elif result["status"] == "error":
raise Exception(f"Task failed: {result.get('error_message')}")
time.sleep(3)
raise TimeoutError("Request timed out")
def research_topic(seed_keyword):
"""Complete keyword research workflow for a topic."""
print(f"\nResearching: {seed_keyword}")
print("=" * 50)
all_keywords = set()
# Step 1: Get autocomplete suggestions
print("\n1. Getting autocomplete suggestions...")
suggestions = get_suggestions(seed_keyword)
all_keywords.update(suggestions)
print(f" Found {len(suggestions)} suggestions")
# Step 2: Get keyword ideas for seed + top suggestions
print("\n2. Generating keyword ideas...")
seed_list = [seed_keyword] + suggestions[:3] # Use top 3 suggestions
ideas = get_keyword_ideas(seed_list)
print(f" Found {len(ideas)} keyword ideas")
# Step 3: Compile and sort results
print("\n3. Compiling results...")
keywords_with_data = []
for idea in ideas:
kw = idea.get("keyword", "")
volume = idea.get("search_volume", 0)
all_keywords.add(kw)
keywords_with_data.append({
"keyword": kw,
"volume": volume
})
# Sort by volume
keywords_with_data.sort(key=lambda x: x["volume"] or 0, reverse=True)
# Display top 20
print(f"\nTop Keywords by Volume:")
print("-" * 50)
for kw in keywords_with_data[:20]:
vol = kw["volume"] if kw["volume"] else "N/A"
print(f" {kw['keyword']}: {vol}")
print(f"\nTotal unique keywords found: {len(all_keywords)}")
return keywords_with_data
if __name__ == "__main__":
results = research_topic("project management software")
# Export to CSV, database, etc.
Best Practices
Start Broad, Then Narrow
Begin with broad seed keywords to maximize idea generation, then filter results based on search volume, competition, and relevance to your goals.
Maximize Your Results
- Use multiple seeds - Submit 3-5 related seed keywords to get more diverse ideas
- Try question modifiers - Add "how to", "what is", "best" to your seeds for different angles
- Check multiple locations - Search behavior varies by country
- Combine endpoints - Use suggestions first, then expand top results with ideas
Filter Strategically
- Volume thresholds - Filter out keywords below your minimum traffic threshold
- Intent matching - Group keywords by search intent (informational, commercial, etc.)
- Remove duplicates - Deduplicate across multiple research sessions
- Brand filtering - Exclude competitor brand terms if not relevant
Rate Limits
The /suggest/live and /trends/live endpoints are synchronous
and count toward your rate limits. For large-scale research, use the async /ideas
endpoint which is optimized for batch processing.