API reference
Keyword research
AI-estimated keyword ideas and metrics (search volume, competition, difficulty and cost per click) to help you choose topics. The numbers are model estimates, not Google Ads data: use them to compare and prioritize.
1 endpointBase URL https://autoranko.com/api/public/v1Every request needs a bearer token
Research keywords
https://autoranko.com/api/public/v1/sites/{id}/keywordsRuns AI keyword research for the site. In ideas mode (the default) it expands your seed keywords into related long-tail keywords, a mix of informational and commercial searches. In metrics mode it estimates metrics for exactly the keywords you send. Each keyword comes with estimated monthly volume, competition, difficulty and cost per click.
All numbers are AI estimates (the response always has estimated: true): good for comparing and prioritizing keywords, not exact traffic data. Occasionally the list comes back empty or a metric is missing; retry if you need it. The request is synchronous and can take up to 2 minutes. Each request counts as one AI call in the site's monthly usage (ai_calls_used).
Request
idintegerRequiredSite ID, from GET /sites.
application/jsonkeywordsarray of stringsRequiredSeed keywords (ideas) or the exact keywords to evaluate (metrics), as a JSON array of strings. Empty strings are dropped and only the first 20 are used; extra items are ignored, not rejected.- Max items
20- Example
["emergency plumber"]
modestringOptionalideasexpands the seeds into related keywords;metricsestimates metrics for exactly the keywords sent. Any other value runsideas. The legacy nameactionis accepted as an alias.One of
ideasmetrics- Default
ideas- Example
ideas
curl -X POST https://autoranko.com/api/public/v1/sites/1/keywords \
-H "Authorization: Bearer $AUTORANKO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"mode": "ideas",
"keywords": [
"emergency plumber"
]
}'const res = await fetch("https://autoranko.com/api/public/v1/sites/1/keywords", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.AUTORANKO_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
mode: "ideas",
keywords: ["emergency plumber"],
}),
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
for (const k of data.keywords) {
console.log(`${k.keyword}: volume ${k.volume}, difficulty ${k.difficulty}, CPC ${k.cpc} USD`);
}import os
import requests
res = requests.post(
"https://autoranko.com/api/public/v1/sites/1/keywords",
headers={"Authorization": f"Bearer {os.environ['AUTORANKO_TOKEN']}"},
json={
"mode": "ideas",
"keywords": ["emergency plumber"],
},
timeout=130,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
for k in data["keywords"]:
print(f"{k['keyword']}: volume {k.get('volume')}, difficulty {k.get('difficulty')}, CPC {k.get('cpc')} USD")<?php
$ch = curl_init('https://autoranko.com/api/public/v1/sites/1/keywords');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 130,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('AUTORANKO_TOKEN'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'mode' => 'ideas',
'keywords' => ['emergency plumber'],
]),
]);
$data = json_decode(curl_exec($ch), true);
if (isset($data['error'])) throw new RuntimeException($data['error']['message']);
foreach ($data['keywords'] as $k) {
printf("%s: volume %d, difficulty %d\n", $k['keyword'], $k['volume'] ?? 0, $k['difficulty'] ?? 0);
}Response
200OKKeywords with AI-estimated metrics.
application/jsonkeywordsarray of objectsKeywords with estimated metrics.keywordsitems(6)KeywordkeywordstringThe keyword.volumeintegerOptionalEstimated monthly searches.competitionstringOptionalEstimated advertiser competition.One of
LOWMEDIUMHIGHcompetition_indexintegerOptionalCompetition on a 0–100 scale.difficultyintegerOptionalEstimated difficulty of ranking on page one, 0–100.cpcnumberOptionalEstimated cost per click, in USD.
estimatedbooleanAlwaystrue: every metric is an AI estimate.
Examples
POST/sites/1/keywords
{
"mode": "ideas",
"keywords": [
"emergency plumber"
]
}{
"keywords": [
{
"keyword": "emergency plumber near me",
"volume": 14800,
"competition": "HIGH",
"competition_index": 92,
"difficulty": 78,
"cpc": 38.45
},
{
"keyword": "24 hour emergency plumber",
"volume": 5400,
"competition": "HIGH",
"competition_index": 89,
"difficulty": 74,
"cpc": 42.18
},
{
"keyword": "emergency plumber cost",
"volume": 1900,
"competition": "MEDIUM",
"competition_index": 67,
"difficulty": 61,
"cpc": 18.72
},
{
"keyword": "emergency plumber for burst pipe",
"volume": 880,
"competition": "MEDIUM",
"competition_index": 63,
"difficulty": 55,
"cpc": 29.64
}
],
"estimated": true
}POST/sites/1/keywords
{
"mode": "metrics",
"keywords": []
}{
"error": {
"code": "invalid_body",
"message": "keywords array is required."
}
}Errors
| Error | When |
|---|---|
| 400invalid_body | The body isn't valid JSON (Invalid JSON body.). |
| 400invalid_body | keywords is missing, empty or contains only empty strings (keywords array is required.). |
| 401missing_token | The Authorization: Bearer … header is missing. |
| 401invalid_token | The token is malformed, unknown or revoked. |
| 404not_found | No site with this id belongs to your account (Site not found.). |
| 429rate_limited | The token made more than 120 requests in the last 60 seconds. |
| 502upstream_error | The AI provider returned an error or timed out (Keyword research failed, please retry.). |
API version v1. Every path on this page is relative to https://autoranko.com/api/public/v1.