API reference
Sites
A site is a WordPress website connected to Autoranko through the Autoranko WordPress plugin. Articles, jobs and keyword research all belong to a site, and plan limits are tracked per site, so most integrations start by listing sites to get a site ID.
2 endpointsBase URL https://autoranko.com/api/public/v1Every request needs a bearer token
List sites
https://autoranko.com/api/public/v1/sitesReturns every site your account owns, newest first. A site is a WordPress install connected through the Autoranko plugin; its id is what the articles, jobs and keyword endpoints take. The list isn't paginated.
Check wp_connected before relying on publishing: it's true once the site owner has authorized Autoranko to publish to WordPress. Without it, jobs still produce drafts, but publishing them fails.
Request
No parameters. Send the request with your token, nothing else.
curl https://autoranko.com/api/public/v1/sites \
-H "Authorization: Bearer $AUTORANKO_TOKEN"const res = await fetch("https://autoranko.com/api/public/v1/sites", {
headers: { Authorization: `Bearer ${process.env.AUTORANKO_TOKEN}` },
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
for (const site of data.sites) {
console.log(site.id, site.domain, site.wp_connected ? "can publish" : "WordPress not connected");
}import os
import requests
res = requests.get(
"https://autoranko.com/api/public/v1/sites",
headers={"Authorization": f"Bearer {os.environ['AUTORANKO_TOKEN']}"},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
for site in data["sites"]:
print(site["id"], site["domain"], "can publish" if site["wp_connected"] else "WordPress not connected")<?php
$ch = curl_init('https://autoranko.com/api/public/v1/sites');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AUTORANKO_TOKEN')],
]);
$data = json_decode(curl_exec($ch), true);
if (isset($data['error'])) throw new RuntimeException($data['error']['message']);
foreach ($data['sites'] as $site) {
$state = $site['wp_connected'] ? 'can publish' : 'WordPress not connected';
echo "{$site['id']} {$site['domain']} $state\n";
}Response
200OKAll sites the account owns, newest first.
application/jsonsitesarray of objectsThe account's sites, newest first.sitesitems(8)SiteidstringSite ID: a 64-bit integer serialized as a string. Use it as{id}in/sites/{id}/…paths.site_urlstring (uri)The site's home URL.site_namestringThe site title from WordPress (can be empty).domainstringThe site's hostname. A domain can be registered only once across Autoranko.planstringThe plan this site's limits are enforced against. It mirrors the owner's subscription.One of
freestarterprois_activebooleanfalseonce the Autoranko plugin has been deleted from the WordPress site;trueagain if the plugin registers the site again.wp_connectedbooleantruewhen Autoranko is authorized to publish to the site's WordPress. Publishing (POST /jobs/{id}/publish orauto_publish) needs it.created_atstring (date-time)When the site was first registered.
Example
Account with one site
GET/sites
{
"sites": [
{
"id": "1",
"site_url": "https://demo.autoranko.com",
"site_name": "Autoranko Demo Site",
"domain": "demo.autoranko.com",
"plan": "pro",
"is_active": true,
"wp_connected": false,
"created_at": "2026-10-25T19:57:53.200Z"
}
]
}Errors
| Error | When |
|---|---|
| 401missing_token | The Authorization: Bearer … header is missing. |
| 401invalid_token | The token is malformed, unknown or revoked. |
| 429rate_limited | The token made more than 120 requests in the last 60 seconds. |
Get a site with usage
https://autoranko.com/api/public/v1/sites/{id}Returns one site and its usage against the plan's limits. usage.ai_calls_used counts every AI call the site made this calendar month (UTC), against usage.ai_calls_limit: each completed article job uses two (outline and draft), each keyword research request one, and the WordPress plugin's own AI features count too.
usage.articles_limit is how many article jobs the plan allows: per calendar month on paid plans, or once in total on Free (articles_period says which). The response has no articles-used counter. To compute one, count the site's jobs that didn't fail, created this month on a paid plan or ever on Free.
Request
idintegerRequiredSite ID, from GET /sites.
curl https://autoranko.com/api/public/v1/sites/1 \
-H "Authorization: Bearer $AUTORANKO_TOKEN"const res = await fetch("https://autoranko.com/api/public/v1/sites/1", {
headers: { Authorization: `Bearer ${process.env.AUTORANKO_TOKEN}` },
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
const { site, usage } = data;
console.log(`${site.domain}: ${usage.ai_calls_used}/${usage.ai_calls_limit} AI calls this month`);
console.log(`Article allowance: ${usage.articles_limit} (${usage.articles_period})`);import os
import requests
res = requests.get(
"https://autoranko.com/api/public/v1/sites/1",
headers={"Authorization": f"Bearer {os.environ['AUTORANKO_TOKEN']}"},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
usage = data["usage"]
print(f"{data['site']['domain']}: {usage['ai_calls_used']}/{usage['ai_calls_limit']} AI calls this month")
print(f"Article allowance: {usage['articles_limit']} ({usage['articles_period']})")<?php
$ch = curl_init('https://autoranko.com/api/public/v1/sites/1');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AUTORANKO_TOKEN')],
]);
$data = json_decode(curl_exec($ch), true);
if (isset($data['error'])) throw new RuntimeException($data['error']['message']);
['site' => $site, 'usage' => $usage] = $data;
printf("%s: %d/%d AI calls this month\n", $site['domain'], $usage['ai_calls_used'], $usage['ai_calls_limit']);
printf("Article allowance: %d (%s)\n", $usage['articles_limit'], $usage['articles_period']);Response
200OKThe site and its usage in the current period.
application/jsonsiteobjectThe site.sitekeys(8)SiteidstringSite ID: a 64-bit integer serialized as a string. Use it as{id}in/sites/{id}/…paths.site_urlstring (uri)The site's home URL.site_namestringThe site title from WordPress (can be empty).domainstringThe site's hostname. A domain can be registered only once across Autoranko.planstringThe plan this site's limits are enforced against. It mirrors the owner's subscription.One of
freestarterprois_activebooleanfalseonce the Autoranko plugin has been deleted from the WordPress site;trueagain if the plugin registers the site again.wp_connectedbooleantruewhen Autoranko is authorized to publish to the site's WordPress. Publishing (POST /jobs/{id}/publish orauto_publish) needs it.created_atstring (date-time)When the site was first registered.
usageobjectUsage against the site plan's limits.usagekeys(4)SiteUsageai_calls_usedintegerAI calls the site has made this calendar month (UTC), from every source: each completed article job uses two (outline and draft), each keyword research request one, and the WordPress plugin's AI features count too. SEO toolkit calls (/seo/…) don't: they count against the account's own allowance.ai_calls_limitintegerMonthly AI-call allowance of the site's plan (Free 300, Starter 1,500, Pro 6,000).articles_limitintegerArticle jobs the plan allows perarticles_period(Free 3, Starter 8, Pro 30). Jobs that end infaileddon't count.articles_periodstringlifetimeon Free (a one-time allowance), ormonth(calendar month, UTC) on paid plans.One of
lifetimemonth
Examples
GET/sites/1
{
"site": {
"id": "1",
"site_url": "https://demo.autoranko.com",
"site_name": "Autoranko Demo Site",
"domain": "demo.autoranko.com",
"plan": "pro",
"is_active": true,
"wp_connected": false,
"created_at": "2026-10-25T19:57:53.200Z"
},
"usage": {
"ai_calls_used": 2,
"ai_calls_limit": 6000,
"articles_limit": 30,
"articles_period": "month"
}
}GET/sites/999
{
"error": {
"code": "not_found",
"message": "Site not found."
}
}Errors
| Error | When |
|---|---|
| 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. |
API version v1. Every path on this page is relative to https://autoranko.com/api/public/v1.