🔑 Semrush - Keyword Research
Overview​
Analyze organic keyword rankings for any domain including search volumes, positions, traffic estimates, and keyword difficulty.
Organic Keywords​
Get Organic Keywords​
GET /keyword/organic/:domain​
Purpose: Retrieve top organic keywords ranking for a domain
Request:
GET /v1/integrations/semrush/keyword/organic/example.com?new=false
Authorization: Bearer {jwt_token}
Semrush API:
GET https://api.semrush.com/?type=domain_organic&key={API_KEY}&database={COUNTRY}&domain={DOMAIN}&display_limit=10&display_sort=nq_desc
API Parameters:
type:domain_organicdisplay_limit: 10 (top keywords)display_sort:nq_desc(by search volume descending)
CSV Response Columns:
Domain;Keyword;Position;Previous Position;Search Volume;Number of Results;CPC;URL;Traffic (%);Traffic Cost;Competition;Number of Ads;Trends;Timestamp
JSON Response:
{
"success": true,
"message": "SUCCESS",
"data": {
"data": [
{
"Domain": "example.com",
"Keyword": "quality products",
"Position": "3",
"Previous Position": "5",
"Search Volume": "18000",
"Number of Results": "2500000",
"CPC": "2.50",
"URL": "https://example.com/products",
"Traffic (%)": "12.5",
"Traffic Cost": "1850",
"Competition": "0.78",
"Number of Ads": "15",
"Trends": "0.9,1.0,1.2,1.1,0.95,0.88,1.05,1.15,1.3,1.25,1.1,1.0"
}
],
"createdAt": "2025-10-10T08:00:00Z",
"lastUpdate": "2025-10-10T08:00:00Z",
"nextUpdate": "2025-10-17T08:00:00Z",
"daysSinceUpdate": 0,
"daysUntilUpdate": 7,
"isStale": false
}
}
Keyword Metrics​
Key Fields​
| Field | Description | Format |
|---|---|---|
| Keyword | Search query | String |
| Position | Current SERP position | Integer (1-100) |
| Previous Position | Position in previous update | Integer |
| Search Volume | Monthly searches | Integer |
| CPC | Cost per click | Decimal (USD) |
| URL | Ranking page | URL |
| Traffic (%) | Est. traffic share | Percentage |
| Traffic Cost | PPC equivalent value | USD |
| Competition | Keyword difficulty | 0.0-1.0 |
| Number of Ads | Paid ads count | Integer |
| Trends | 12-month trend | Comma-separated decimals |
Understanding Trends​
Trends show 12-month search volume relative to average:
"0.9,1.0,1.2,1.1,0.95,0.88,1.05,1.15,1.3,1.25,1.1,1.0"
1.0= Average volume> 1.0= Above average (e.g.,1.2= 20% above)< 1.0= Below average (e.g.,0.9= 10% below)
Use Case: Identify seasonal patterns
Caching​
Cache Configuration:
- Cache Type:
domain_organic - TTL: 7 days
- Force Refresh:
?new=true
Business Logic:
if (isNew) {
jsonData = await SemrushModel.findToday(accountID, userID, domain, 'domain_organic');
if (!jsonData) {
const csvStr = await semrushProvider.getOrganicKeyword(domain, accountCountry);
jsonData = await csvtojson({ delimiter: ';' }).fromString(csvStr);
await SemrushModel.add(accountID, userID, domain, 'domain_organic', jsonData);
}
} else {
jsonData = await SemrushModel.findLast(accountID, userID, domain, 'domain_organic');
}
Use Cases​
1. Keyword Opportunity Analysis​
Identify high-value keywords:
// Filter for high volume, low competition
const opportunities = keywords.filter(
k => parseInt(k['Search Volume']) > 5000 && parseFloat(k.Competition) < 0.5,
);
2. Content Gap Analysis​
Find keywords competitors rank for:
# Get your keywords
GET /keyword/organic/yourclient.com
# Get competitor keywords
GET /competitor/organic/competitor.com
# Compare to find gaps
3. Traffic Value Calculation​
Calculate total organic traffic value:
const totalValue = keywords.reduce((sum, k) => sum + parseFloat(k['Traffic Cost'] || 0), 0);
4. Position Tracking​
Monitor ranking changes:
keywords.forEach(k => {
const current = parseInt(k.Position);
const previous = parseInt(k['Previous Position']);
const change = previous - current; // Positive = improvement
console.log(`${k.Keyword}: ${change > 0 ? '↑' : '↓'} ${Math.abs(change)}`);
});
Sorting Options​
Default sort: nq_desc (search volume descending)
Other available sorts:
po_asc- Position ascending (best rankings first)po_desc- Position descendingnq_asc- Search volume ascendingtr_desc- Traffic descendingtc_desc- Traffic cost descending