API reference
Generation jobs
A job is one article generation: you send a topic, Autoranko builds an SEO outline and writes the full article, then holds it for your review or publishes it to WordPress. Jobs run in the background; follow them by polling or with webhooks.
4 endpointsBase URL https://autoranko.com/api/public/v1Every request needs a bearer token
Job lifecycle
A job moves through these statuses by itself. Your calls only start it (POST /sites/{id}/jobs) and approve it (POST /jobs/{id}/publish). Follow it by polling GET /jobs/{id}, or let the job.review, job.published and job.failed webhooks tell you.
Review first
auto_publishoff (the default). The draft waits inreviewuntil you call POST /jobs/{id}/publish.- pending
- generating
- reviewfires job.review
- publishing
- publishedfires job.published
Autopilot
auto_publishon and WordPress connected (wp_connected: true). Without the connection the job stops inreview.- pending
- generating
- publishing
- publishedfires job.published
Generation fails
errorsays why. Failed jobs don't count toward the allowance; create a new job to try again.- pending
- generating
- failedfires job.failed
WordPress rejects the post
The job returns to
reviewwitherrorset (Publishing failed: …). Fix the cause, then publish again.- publishing
- reviewfires job.review
- publishing
Stuck job recovered
Still
generatingafter an hour (a server restart, say): reset topendingand retried automatically.- generating
- pending
- generating
| Status | Meaning | Moves to |
|---|---|---|
| pending | Created and waiting to start. Immediate jobs start within seconds; scheduled jobs start once scheduled_for has passed (the scheduler runs every minute). | generating |
| generating | Autoranko is writing the outline, then the full article. This usually takes a few minutes. A job stuck here for over an hour (after a server restart, for example) is reset to pending and retried automatically. | reviewpublishingfailedpending |
| reviewjob.review | The draft is ready and waiting for approval: auto_publish was off, the site has no WordPress connection, or a publish attempt failed (then error says why). Publish it with POST /jobs/{id}/publish. | publishing |
| publishing | The article is being sent to WordPress. If WordPress rejects it, the job goes back to review. | publishedreview |
| publishedjob.published | The article is live on WordPress, and wp_post_id holds the post ID. | Final |
| failedjob.failed | Generation failed, and error says why. Failed jobs don't count toward the plan's allowance; create a new job to try again. | Final |
List jobs
https://autoranko.com/api/public/v1/sites/{id}/jobsLists the site's generation jobs, newest first, including jobs created in the dashboard. The list leaves out the heavy fields (outline and article_html); fetch a single job with GET /jobs/{id} for those.
Filter with status to build a review queue (review) or catch failures (failed). The endpoint returns the newest limit jobs (up to 200) and has no offset.
Request
idintegerRequiredSite ID, from GET /sites.
statusstringOptionalOnly return jobs in this status. An unknown value returns an empty list, not an error.One of
pendinggeneratingreviewpublishingpublishedfailed- Example
review
limitintegerOptionalHow many of the newest jobs to return. Values outside 1–200 are clamped to that range.- Default
50- Range
1–200- Example
20
curl "https://autoranko.com/api/public/v1/sites/1/jobs?status=review&limit=20" \
-H "Authorization: Bearer $AUTORANKO_TOKEN"const res = await fetch("https://autoranko.com/api/public/v1/sites/1/jobs?status=review&limit=20", {
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 job of data.jobs) {
console.log(job.id, job.status, job.article_title ?? job.topic);
}import os
import requests
res = requests.get(
"https://autoranko.com/api/public/v1/sites/1/jobs",
headers={"Authorization": f"Bearer {os.environ['AUTORANKO_TOKEN']}"},
params={"status": "review", "limit": 20},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
for job in data["jobs"]:
print(job["id"], job["status"], job["article_title"] or job["topic"])<?php
$ch = curl_init('https://autoranko.com/api/public/v1/sites/1/jobs?status=review&limit=20');
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['jobs'] as $job) {
echo $job['id'], ' ', $job['status'], ' ', $job['article_title'] ?? $job['topic'], "\n";
}Response
200OKThe newest jobs, optionally filtered by status.
application/jsonjobsarray of objectsJobs, newest first.jobsitems(13)JobidstringJob ID: a 64-bit integer serialized as a string.site_idstringID of the site the article is for.topicstringThe topic the article was requested for.target_keywordstring or nullThe keyword the article targets, ornull.statusstringWhere the job is in its lifecycle:pending→generating→revieworpublishing→published, orfailed.One of
pendinggeneratingreviewpublishingpublishedfailedarticle_titlestring or nullTitle chosen in the outline step;nulluntil the draft is ready.meta_descriptionstring or nullSEO meta description (aimed at under 160 characters), also used as the WordPress excerpt;nulluntil the draft is ready.wp_post_idstring or nullID of the WordPress post once published (a 64-bit integer serialized as a string), otherwisenull.auto_publishbooleanWhether the job publishes to WordPress by itself when the draft is ready.scheduled_forstring (date-time) or nullWhen a scheduled job is due to start, ornullfor a job that started immediately.errorstring or nullWhy the job failed, or why the last publish attempt failed (it then starts withPublishing failed:);nullotherwise.created_atstring (date-time)When the job was created.updated_atstring (date-time)When the job last changed.
Example
Recent jobs
GET/sites/1/jobs
{
"jobs": [
{
"id": "3",
"site_id": "1",
"topic": "How to winterize a sprinkler system before the first freeze",
"target_keyword": "winterize sprinkler system",
"status": "review",
"article_title": "How to Winterize a Sprinkler System Before the First Freeze",
"meta_description": "Learn how to winterize a sprinkler system before the first freeze, with steps for shutting off water, draining lines and protecting equipment.",
"wp_post_id": null,
"auto_publish": false,
"scheduled_for": null,
"error": "Publishing failed: WordPress publishing is not authorized for this site.",
"created_at": "2026-10-25T20:10:51.035Z",
"updated_at": "2026-10-25T20:42:05.140Z"
}
]
}Captured from the live API, with a seeded sample job left out. The error comes from a publish attempt on a site without a WordPress connection.
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. |
Create a job
https://autoranko.com/api/public/v1/sites/{id}/jobsStarts writing a new article for the site. Autoranko builds an SEO outline for your topic (title, meta description, sections and FAQs, planned at about 1,800 words), then writes the full article as HTML. The call returns 201 right away with the job in pending; generation runs in the background and usually takes a few minutes.
What happens when the draft is ready depends on auto_publish. Off (the default): the job stops in review and fires job.review, so you can read it and then call POST /jobs/{id}/publish. On, with WordPress connected (wp_connected: true): it continues to publishing and published by itself. On, without a WordPress connection: it stops in review.
Pass scheduled_for to queue the job for later instead of starting now. A scheduler checks every minute and starts due jobs, oldest first, up to 5 per run.
Every job counts toward the site's article allowance as soon as it's created (Free: 3 in total; Starter: 8 per calendar month; Pro: 30 per calendar month). Jobs that end in failed don't count. Once the allowance is used up, this endpoint returns 429 plan_limit.
Request
idintegerRequiredSite ID, from GET /sites.
application/jsontopicstringRequiredWhat the article should be about: a working title, a question or a short brief. Surrounding whitespace is trimmed; 1–300 characters remain.- Length
1–300 characters- Example
How to winterize a sprinkler system before the first freeze
target_keywordstringOptionalThe search query the article should rank for. It steers the outline, headings and on-page SEO. Omit it, or send an empty string, for none.- Example
winterize sprinkler system
auto_publishbooleanOptionalPublish to WordPress as soon as the draft is ready instead of stopping inreview. Needs the site's WordPress connection (wp_connected: true); without it the job stops inreview. Send a JSON boolean: any truthy value, even the string"false", turns it on.- Default
false- Example
false
scheduled_forstring (date-time)OptionalStart generating at this time instead of now: an ISO 8601 date-time such as2026-11-02T09:00:00Z. IncludeZor an offset; times without one are treated as UTC. A time in the past starts the job on the scheduler's next run, within about a minute.- Example
2026-11-02T09:00:00Z
curl -X POST https://autoranko.com/api/public/v1/sites/1/jobs \
-H "Authorization: Bearer $AUTORANKO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"topic": "How to winterize a sprinkler system before the first freeze",
"target_keyword": "winterize sprinkler system",
"auto_publish": false
}'const res = await fetch("https://autoranko.com/api/public/v1/sites/1/jobs", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.AUTORANKO_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
topic: "How to winterize a sprinkler system before the first freeze",
target_keyword: "winterize sprinkler system",
auto_publish: false,
}),
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
const { job } = data;
console.log(`Job ${job.id} created (${job.status}); poll GET /jobs/${job.id} for the draft`);import os
import requests
res = requests.post(
"https://autoranko.com/api/public/v1/sites/1/jobs",
headers={"Authorization": f"Bearer {os.environ['AUTORANKO_TOKEN']}"},
json={
"topic": "How to winterize a sprinkler system before the first freeze",
"target_keyword": "winterize sprinkler system",
"auto_publish": False,
},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
job = data["job"]
print(f"Job {job['id']} created ({job['status']}); poll GET /jobs/{job['id']} for the draft")<?php
$ch = curl_init('https://autoranko.com/api/public/v1/sites/1/jobs');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('AUTORANKO_TOKEN'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'topic' => 'How to winterize a sprinkler system before the first freeze',
'target_keyword' => 'winterize sprinkler system',
'auto_publish' => false,
]),
]);
$data = json_decode(curl_exec($ch), true);
if (isset($data['error'])) throw new RuntimeException($data['error']['message']);
$job = $data['job'];
echo "Job {$job['id']} created ({$job['status']}); poll GET /jobs/{$job['id']} for the draft\n";Response
201CreatedThe job was created in pending.
application/jsonjobobjectThe new job.jobkeys(11)NewJobidstringJob ID: a 64-bit integer serialized as a string.site_idstringID of the site the article is for.topicstringThe topic the article was requested for.target_keywordstring or nullThe keyword the article targets, ornull.statusstringWhere the job is in its lifecycle:pending→generating→revieworpublishing→published, orfailed.One of
pendinggeneratingreviewpublishingpublishedfailedarticle_titlestring or nullTitle chosen in the outline step;nulluntil the draft is ready.meta_descriptionstring or nullSEO meta description (aimed at under 160 characters), also used as the WordPress excerpt;nulluntil the draft is ready.wp_post_idstring or nullID of the WordPress post once published (a 64-bit integer serialized as a string), otherwisenull.auto_publishbooleanWhether the job publishes to WordPress by itself when the draft is ready.scheduled_forstring (date-time) or nullWhen a scheduled job is due to start, ornullfor a job that started immediately.created_atstring (date-time)When the job was created.
Examples
POST/sites/1/jobsIllustrative
{
"topic": "How to winterize a sprinkler system before the first freeze",
"target_keyword": "winterize sprinkler system",
"auto_publish": false
}{
"job": {
"id": "3",
"site_id": "1",
"topic": "How to winterize a sprinkler system before the first freeze",
"target_keyword": "winterize sprinkler system",
"status": "pending",
"article_title": null,
"meta_description": null,
"wp_post_id": null,
"auto_publish": false,
"scheduled_for": null,
"created_at": "2026-10-25T20:10:51.035Z"
}
}Reconstructed from the live job 3 as the API returned it at creation.
POST/sites/1/jobsIllustrative
{
"topic": "Drip irrigation vs. sprinklers: which saves more water?",
"target_keyword": "drip irrigation vs sprinklers",
"auto_publish": true,
"scheduled_for": "2026-11-02T09:00:00Z"
}{
"job": {
"id": "4",
"site_id": "1",
"topic": "Drip irrigation vs. sprinklers: which saves more water?",
"target_keyword": "drip irrigation vs sprinklers",
"status": "pending",
"article_title": null,
"meta_description": null,
"wp_post_id": null,
"auto_publish": true,
"scheduled_for": "2026-11-02T09:00:00.000Z",
"created_at": "2026-10-26T08:30:12.481Z"
}
}scheduled_for comes back normalized to UTC with milliseconds.
POST/sites/1/jobs
{
"target_keyword": "winterize sprinkler system"
}{
"error": {
"code": "invalid_body",
"message": "topic is required."
}
}POST/sites/1/jobs
{
"topic": "How to winterize a sprinkler system before the first freeze",
"target_keyword": "winterize sprinkler system",
"auto_publish": false
}{
"error": {
"code": "plan_limit",
"message": "Free plan article allowance used — upgrade to keep publishing."
}
}Errors
| Error | When |
|---|---|
| 400invalid_body | The body isn't valid JSON (Invalid JSON body.). |
| 400invalid_body | topic is missing or blank (topic is required.). |
| 400invalid_body | topic is longer than 300 characters (topic is too long (max 300 chars).). |
| 400invalid_body | scheduled_for can't be parsed as a date-time (scheduled_for must be an ISO 8601 datetime.). |
| 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. |
| 429plan_limit | The site has used its article allowance (Free: 3 in total; Starter: 8 per calendar month; Pro: 30 per calendar month). |
Get a job
https://autoranko.com/api/public/v1/jobs/{id}Returns one job with everything generated so far. outline and article_html are null until the draft is finished; then they hold the structured outline and the full article HTML that will be published.
To follow a job, poll this endpoint every 15–30 seconds until status is review, published or failed, or subscribe to webhooks and skip polling. error explains a failed job. On a job back in review, it holds the reason the last publish attempt failed (starting with Publishing failed:) and is cleared when a later publish succeeds.
Request
idintegerRequiredJob ID, from POST /sites/{id}/jobs or GET /sites/{id}/jobs.
curl https://autoranko.com/api/public/v1/jobs/3 \
-H "Authorization: Bearer $AUTORANKO_TOKEN"const res = await fetch("https://autoranko.com/api/public/v1/jobs/3", {
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 { job } = data;
console.log(job.status, job.article_title);
if (job.status === "review") console.log(job.article_html.slice(0, 300));
if (job.error) console.error(job.error);import os
import requests
res = requests.get(
"https://autoranko.com/api/public/v1/jobs/3",
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']}")
job = data["job"]
print(job["status"], job["article_title"])
if job["status"] == "review":
print(job["article_html"][:300])
if job["error"]:
print("Error:", job["error"])<?php
$ch = curl_init('https://autoranko.com/api/public/v1/jobs/3');
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']);
$job = $data['job'];
echo $job['status'], ' ', $job['article_title'], "\n";
if ($job['status'] === 'review') echo substr($job['article_html'], 0, 300), "\n";
if ($job['error']) echo 'Error: ', $job['error'], "\n";Response
200OKThe job, with its outline and article HTML once generated.
application/jsonjobobjectThe job.jobkeys(15)JobDetailidstringJob ID: a 64-bit integer serialized as a string.site_idstringID of the site the article is for.topicstringThe topic the article was requested for.target_keywordstring or nullThe keyword the article targets, ornull.statusstringWhere the job is in its lifecycle:pending→generating→revieworpublishing→published, orfailed.One of
pendinggeneratingreviewpublishingpublishedfailedarticle_titlestring or nullTitle chosen in the outline step;nulluntil the draft is ready.meta_descriptionstring or nullSEO meta description (aimed at under 160 characters), also used as the WordPress excerpt;nulluntil the draft is ready.wp_post_idstring or nullID of the WordPress post once published (a 64-bit integer serialized as a string), otherwisenull.auto_publishbooleanWhether the job publishes to WordPress by itself when the draft is ready.scheduled_forstring (date-time) or nullWhen a scheduled job is due to start, ornullfor a job that started immediately.errorstring or nullWhy the job failed, or why the last publish attempt failed (it then starts withPublishing failed:);nullotherwise.outlineobject or nullThe structured outline the article was written from;nulluntil the draft is ready. It's AI-generated JSON: the keys below are requested from the model but not guaranteed.outlinekeys(10)JobOutlinetitlestringOptionalArticle title.meta_descriptionstringOptionalSEO meta description.slugstringOptionalSuggested URL slug.target_keywordstringOptionalPrimary keyword.secondary_keywordsarray of stringsOptionalRelated keywords to work into the article.sectionsarray of objectsOptionalThe article structure, in order.sectionsitems(4)levelstringHeading level.One of
h2h3headingstringSection heading.descriptionstringWhat the section covers.word_countintegerPlanned length of the section in words.
faqsarray of objectsOptionalQuestions for the FAQ section.faqsitems(2)questionstringThe question.answer_briefstringThe gist of the answer.
image_suggestionsarray of objectsOptionalImage ideas. The first one is meant as the featured image.image_suggestionsitems(2)descriptionstringWhat the image shows.alt_textstringSuggested alt text.
google_image_queriesarray of stringsOptionalSearch queries for finding matching images.video_querystringOptionalSearch query for a related video.
article_htmlstring or nullThe full article as HTML: headings start at<h2>(the title is separate) and there are no images.nulluntil the draft is ready. This is exactly what gets published.created_atstring (date-time)When the job was created.updated_atstring (date-time)When the job last changed.
Examples
GET/jobs/3
{
"job": {
"id": "3",
"site_id": "1",
"topic": "How to winterize a sprinkler system before the first freeze",
"target_keyword": "winterize sprinkler system",
"status": "review",
"article_title": "How to Winterize a Sprinkler System Before the First Freeze",
"meta_description": "Learn how to winterize a sprinkler system before the first freeze, with steps for shutting off water, draining lines and protecting equipment.",
"wp_post_id": null,
"auto_publish": false,
"scheduled_for": null,
"error": "Publishing failed: WordPress publishing is not authorized for this site.",
"outline": {
"title": "How to Winterize a Sprinkler System Before the First Freeze",
"meta_description": "Learn how to winterize a sprinkler system before the first freeze, with steps for shutting off water, draining lines and protecting equipment.",
"slug": "winterize-sprinkler-system",
"target_keyword": "winterize sprinkler system",
"secondary_keywords": [
"sprinkler blowout",
"drain irrigation lines",
"insulate backflow preventer"
],
"sections": [
{
"level": "h2",
"heading": "Why winterizing your sprinkler system matters",
"description": "How trapped water freezes, expands and cracks pipes, fittings and valves.",
"word_count": 220
},
{
"level": "h2",
"heading": "Step 1: Shut off the water supply",
"description": "Find the main shut-off valve and protect it from freezing.",
"word_count": 180
}
],
"faqs": [
{
"question": "When should I winterize my sprinkler system?",
"answer_brief": "Before the first hard freeze, once nights approach 32 °F (0 °C)."
}
],
"image_suggestions": [
{
"description": "Homeowner blowing out sprinkler lines with an air compressor in autumn",
"alt_text": "Blowing out sprinkler lines with an air compressor"
}
],
"google_image_queries": [
"sprinkler system blowout"
],
"video_query": "how to winterize a sprinkler system"
},
"article_html": "<h2>Why winterizing your sprinkler system matters</h2>\n<p>Water left inside an irrigation system can freeze and expand, cracking pipes, splitting fittings, or damaging valves. Exposed backflow preventers are especially vulnerable because they lack the protection that soil provides to buried components.</p>\n<!-- … shortened for the docs … -->",
"created_at": "2026-10-25T20:10:51.035Z",
"updated_at": "2026-10-25T20:42:05.140Z"
}
}Captured from the live API. article_html is shortened, and outline is abbreviated to show its structure.
GET/jobs/9999
{
"error": {
"code": "not_found",
"message": "Job 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 job with this id exists (Job not found.), or it belongs to another account's site (Site not found.). |
| 429rate_limited | The token made more than 120 requests in the last 60 seconds. |
Publish a job
https://autoranko.com/api/public/v1/jobs/{id}/publishApproves a job that's waiting in review and publishes it to the site's WordPress as a live post: article_title becomes the post title, article_html the content and meta_description the excerpt. The call returns at once with status set to publishing; the WordPress request runs in the background. No request body is needed.
When it succeeds, the job becomes published, wp_post_id holds the new post's ID and job.published fires with the post URL in wp_link. If WordPress rejects the post, or the site isn't connected (wp_connected: false), the job returns to review with error set (for example Publishing failed: WordPress publishing is not authorized for this site.) and job.review fires with publish_error: true. Fix the cause and call this endpoint again.
Request
idintegerRequiredJob ID, from POST /sites/{id}/jobs or GET /sites/{id}/jobs.
curl -X POST https://autoranko.com/api/public/v1/jobs/3/publish \
-H "Authorization: Bearer $AUTORANKO_TOKEN"const res = await fetch("https://autoranko.com/api/public/v1/jobs/3/publish", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.AUTORANKO_TOKEN}` },
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
console.log(data.status); // "publishing"; job.published fires once the post is liveimport os
import requests
res = requests.post(
"https://autoranko.com/api/public/v1/jobs/3/publish",
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']}")
print(data["status"]) # "publishing"; job.published fires once the post is live<?php
$ch = curl_init('https://autoranko.com/api/public/v1/jobs/3/publish');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AUTORANKO_TOKEN')],
CURLOPT_POSTFIELDS => '',
]);
$data = json_decode(curl_exec($ch), true);
if (isset($data['error'])) throw new RuntimeException($data['error']['message']);
echo $data['status'], "\n"; // "publishing"; job.published fires once the post is liveResponse
200OKPublishing started.
application/jsonokbooleanAlwaystrue.statusstringThe job's new status.One of
publishing
Examples
POST/jobs/3/publish
{
"ok": true,
"status": "publishing"
}POST/jobs/3/publish
{
"error": {
"code": "invalid_state",
"message": "Only jobs in 'review' with generated content can be published."
}
}Errors
| Error | When |
|---|---|
| 401missing_token | The Authorization: Bearer … header is missing. |
| 401invalid_token | The token is malformed, unknown or revoked. |
| 404not_found | No job with this id exists (Job not found.), or it belongs to another account's site (Site not found.). |
| 409invalid_state | The job isn't in review or has no generated article: it's still generating, already publishing or published, or failed. |
| 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.