Content Optimizer API
Analyze existing URLs, fetch optimization suggestions, and apply them.
The Content Optimizer scrapes an existing URL, analyzes SEO + GEO signals against the target keyword, and returns 15–25 concrete improvement suggestions — from headline rewrites to FAQ schema recommendations. Via apply you can materialize accepted suggestions directly into an optimized article.
Module context: Content Optimizer · walkthrough: Optimize Content.
Endpoints
| Method | Endpoint | Description | Credits |
|---|---|---|---|
| GET | /v1/content-optimizer |
All optimizer runs in the team (paginated) | — |
| GET | /v1/content-optimizer/{id} |
Detail with scraped content, score, suggestions | — |
| POST | /v1/content-optimizer/analyze |
New run — body: {url, keyword, project_id?, language?} → 202 |
5 |
| POST | /v1/content-optimizer/{id}/apply |
Materialize accepted suggestions into an optimized article — body: {suggestion_ids[], create_article?:bool} |
5 |
Start an analysis
TOKEN="$RANKION_API_TOKEN"
BASE="https://rankion.ai/api/v1"
curl -X POST "$BASE/content-optimizer/analyze" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{
"url":"https://example.com/blog/ai-coding",
"keyword":"ai coding tools",
"project_id":12,
"language":"en"
}'
Response 202 Accepted:
{
"id": 47,
"status": "pending",
"message": "Analysis dispatched"
}
The job runs 10–20 seconds: ScraperAPI fetches the HTML, Claude Sonnet 4.5 compares it against the top-10 SERP for the keyword and against the GEO heuristics (entity coverage, citation worthiness, AI-snippet suitability).
Fetch detail
curl "$BASE/content-optimizer/$ID" \
-H "Authorization: Bearer $TOKEN"
Response shape:
{
"id": 47,
"status": "completed",
"url": "https://example.com/blog/ai-coding",
"keyword": "ai coding tools",
"scraped_word_count": 1240,
"current_score": 62,
"potential_score": 84,
"suggestions": [
{
"id": 311,
"category": "headline",
"priority": "high",
"title": "H1 does not feature the keyword prominently",
"before": "Coding with AI: an overview",
"after": "The Best AI Coding Tools 2026 (with Benchmarks)",
"rationale": "Top-3 SERP results have the keyword in the first 3 words."
}
]
}
suggestions[] is sorted by priority (high → low) and groupable by category (headline, meta, intro, faq, internal_links, entities, schema, structure, cta).
Apply suggestions
Instead of feeding each suggestion back into the source CMS by hand, you can materialize them into an optimized article in Rankion — the resulting article lands in the AI Content Editor and can be published from there via the Articles API.
curl -X POST "$BASE/content-optimizer/$ID/apply" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{
"suggestion_ids":[311, 312, 315, 318],
"create_article":true
}'
Response:
{
"article_id": 92,
"applied_count": 4,
"score_before": 62,
"score_after": 81
}
Complete example: analyze → top suggestions → apply
PID=12
# 1) Dispatch analysis
ID=$(curl -s -X POST "$BASE/content-optimizer/analyze" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"url":"https://example.com/blog/ai-coding","keyword":"ai coding tools","project_id":'$PID'}' \
| jq -r .id)
# 2) Poll until completed
while [ "$(curl -s "$BASE/content-optimizer/$ID" \
-H "Authorization: Bearer $TOKEN" | jq -r .status)" != "completed" ]; do
sleep 3
done
# 3) Extract top-5 high-priority suggestions
TOP=$(curl -s "$BASE/content-optimizer/$ID" \
-H "Authorization: Bearer $TOKEN" \
| jq -c '[.suggestions[] | select(.priority=="high")][:5] | map(.id)')
# 4) Apply
curl -X POST "$BASE/content-optimizer/$ID/apply" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d "{\"suggestion_ids\":$TOP,\"create_article\":true}"
Notes & pitfalls
- Analyze is async. Even when the endpoint returns
200/202— suggestions only arrive once the job completes. Polling interval: 3–5 s. urlmust be publicly reachable. Behind a login? → ScraperAPI fails →status="failed"with detail inerror_message.- Apply is not idempotent. Applying the same suggestion IDs multiple times creates multiple articles. Check whether
article_idis already set first. keywordis required. Withoutkeywordthere is no SERP comparison basis → validation error.
Related: Articles API · Credits · Content Optimizer · Optimize Content.