Documentation
SEO Content Scoring API — AI-powered quality analysis for any URL or article. Get a score, grade, readability breakdown, keyword analysis, and actionable suggestions in a single API call.
Quick Start
Get up and running in 3 steps:
Step 1 — Get a free trial API key
curl -X POST https://ss-seo-api.duckdns.org/v1/trial \
-H "Content-Type: application/json" \
-d '{"name": "my-app", "email": "you@example.com"}'
Response: {"api_key": "seo_xxxx...", "tier": "free", "monthly_limit": 50}
Step 2 — Score a URL
curl -X POST https://ss-seo-api.duckdns.org/v1/score \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{"url": "https://yourblog.com/post", "focus_keywords": ["seo", "content"]}'
Step 3 — Read the result
{
"overall_score": 72,
"grade": "B",
"readability": {
"score": 78,
"grade_level": "9th grade",
"assessment": "Appropriate for most audiences"
},
"keyword_density": {
"risk": "low",
"top_keywords": [
{"keyword": "seo", "count": 8, "density": "2.1%"},
{"keyword": "content", "count": 6, "density": "1.6%"}
]
},
"suggestions": [
"Add more internal links to related posts",
"Expand the introduction to hook readers faster",
"Increase word count — aim for 1,200+ words",
"Add alt text to images for better accessibility",
"Use more subheadings (H2/H3) to improve scannability"
],
"strengths": ["Good keyword placement", "Clear structure", "Appropriate reading level"],
"meta": {
"input_type": "url",
"char_count": 3840,
"word_count": 620,
"heading_count": 4,
"link_count": 3,
"tier": "free",
"requests_remaining": 47
}
}
Authentication
All scoring endpoints require an API key. Pass it as a header:
| Header | Example | Notes |
|---|---|---|
x-api-key | seo_xxxxxxxxxxxx | Preferred |
Authorization | Bearer seo_xxxx | Also accepted |
Get a Free Trial Key
Call POST /v1/trial — no credit card, no account required. Gives you 50 requests/month on the free tier. Rate-limited to 3 keys per IP per hour to prevent abuse.
POST /v1/score
Analyze a URL or raw text block for SEO quality. Returns an overall score, grade, readability, keyword analysis, and specific improvement suggestions powered by Claude AI.
Request body application/json
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Public URL to fetch and score | |
text | string | Raw text content to score (max 50,000 chars) | |
focus_keywords | string[] | Target keywords to check density for |
Provide either url or text — not both. If both provided, url takes precedence.
Example — score raw text
curl -X POST https://ss-seo-api.duckdns.org/v1/score \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"text": "SEO best practices include researching the right keywords...",
"focus_keywords": ["seo", "keywords", "content"]
}'
POST /v1/trial
Create a free-tier API key. No authentication required. The key is shown once — store it securely.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | required | Your name or app identifier (2–80 chars) |
email | string | Optional — for upgrade notifications |
GET /v1/usage
Check how many requests you've made this calendar month and how many remain.
curl https://ss-seo-api.duckdns.org/v1/usage \ -H "x-api-key: YOUR_API_KEY"
{
"tier": "free",
"requests_this_month": 12,
"monthly_limit": 50,
"requests_remaining": 38,
"overage_rate": null
}
Response Schema
| Field | Type | Description |
|---|---|---|
overall_score | number (0–100) | Composite SEO quality score |
grade | string (A–F) | Letter grade: A ≥90, B ≥75, C ≥60, D ≥45, F <45 |
readability.score | number (0–100) | Flesch Reading Ease score |
readability.grade_level | string | Flesch-Kincaid grade level |
readability.assessment | string | Plain-English readability summary |
keyword_density.risk | string | low / medium / high (stuffing risk) |
keyword_density.top_keywords | array | Top keywords with count and density % |
suggestions | string[] | 5+ actionable improvement recommendations |
strengths | string[] | Things the content does well |
meta.input_type | string | url or text |
meta.word_count | number | Detected word count |
meta.requests_remaining | number | Remaining quota for current month |
Error Codes
| HTTP | Code / Message | Cause |
|---|---|---|
| 400 | Missing input | Neither url nor text provided |
| 400 | Text too long | Text exceeds 50,000 characters |
| 401 | API key required | Missing x-api-key header |
| 401 | Invalid API key | Key not found or revoked |
| 422 | Could not fetch URL | URL unreachable, blocked, or not HTML |
| 429 | Monthly limit reached | Upgrade your plan to continue |
| 429 | Too many requests | Global rate limit: 200 req/min per IP |
| 500 | Internal server error | Scoring service error — retry or contact support |
Rate Limits
Two layers of rate limiting apply:
| Limit | Value | Scope |
|---|---|---|
| Monthly quota | Tier-dependent (50–20,000) | Per API key, resets on the 1st of each month |
| Burst limit | 200 requests/minute | Per IP address (global DDoS protection) |
| Trial creation | 3 keys/hour | Per IP address |
Enterprise accounts receive 20,000 req/mo included, then $0.01 per additional request.
Pricing
Subscribe at RapidAPI.
cURL Examples
Score a URL
curl -X POST https://ss-seo-api.duckdns.org/v1/score \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{"url": "https://example.com/blog-post"}'
Score raw text with focus keywords
curl -X POST https://ss-seo-api.duckdns.org/v1/score \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"text": "Your article content here...",
"focus_keywords": ["target keyword", "secondary term"]
}'
Check usage
curl https://ss-seo-api.duckdns.org/v1/usage \ -H "x-api-key: YOUR_API_KEY"
Python Example
import requests
API_KEY = "YOUR_API_KEY"
BASE = "https://ss-seo-api.duckdns.org"
# Score a URL
resp = requests.post(
f"{BASE}/v1/score",
headers={"x-api-key": API_KEY, "Content-Type": "application/json"},
json={"url": "https://yourblog.com/article", "focus_keywords": ["seo"]}
)
data = resp.json()
print(f"Score: {data['overall_score']}/100 Grade: {data['grade']}")
print("Suggestions:")
for s in data["suggestions"]:
print(f" - {s}")
JavaScript / Node.js Example
const API_KEY = "YOUR_API_KEY";
const BASE = "https://ss-seo-api.duckdns.org";
async function scoreUrl(url) {
const res = await fetch(`${BASE}/v1/score`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": API_KEY,
},
body: JSON.stringify({ url, focus_keywords: ["seo", "content"] }),
});
const data = await res.json();
console.log(`Score: ${data.overall_score} (${data.grade})`);
console.log("Top suggestion:", data.suggestions[0]);
return data;
}
scoreUrl("https://yourblog.com/post");
PHP Example
<?php
$apiKey = "YOUR_API_KEY";
$base = "https://ss-seo-api.duckdns.org";
$ch = curl_init("$base/v1/score");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: $apiKey",
],
CURLOPT_POSTFIELDS => json_encode([
"url" => "https://yourblog.com/post",
"focus_keywords" => ["seo", "content"],
]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
echo "Score: {$response['overall_score']} Grade: {$response['grade']}\n";
foreach ($response["suggestions"] as $tip) {
echo " - $tip\n";
}