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:

HeaderExampleNotes
x-api-keyseo_xxxxxxxxxxxxPreferred
AuthorizationBearer seo_xxxxAlso accepted
Keep your API key secret — never expose it in client-side code or public repos.

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

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

FieldTypeRequiredDescription
urlstringPublic URL to fetch and score
textstringRaw text content to score (max 50,000 chars)
focus_keywordsstring[]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

POST/v1/trial

Create a free-tier API key. No authentication required. The key is shown once — store it securely.

FieldTypeRequiredDescription
namestringrequiredYour name or app identifier (2–80 chars)
emailstringOptional — for upgrade notifications

GET /v1/usage

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

FieldTypeDescription
overall_scorenumber (0–100)Composite SEO quality score
gradestring (A–F)Letter grade: A ≥90, B ≥75, C ≥60, D ≥45, F <45
readability.scorenumber (0–100)Flesch Reading Ease score
readability.grade_levelstringFlesch-Kincaid grade level
readability.assessmentstringPlain-English readability summary
keyword_density.riskstringlow / medium / high (stuffing risk)
keyword_density.top_keywordsarrayTop keywords with count and density %
suggestionsstring[]5+ actionable improvement recommendations
strengthsstring[]Things the content does well
meta.input_typestringurl or text
meta.word_countnumberDetected word count
meta.requests_remainingnumberRemaining quota for current month

Error Codes

HTTPCode / MessageCause
400Missing inputNeither url nor text provided
400Text too longText exceeds 50,000 characters
401API key requiredMissing x-api-key header
401Invalid API keyKey not found or revoked
422Could not fetch URLURL unreachable, blocked, or not HTML
429Monthly limit reachedUpgrade your plan to continue
429Too many requestsGlobal rate limit: 200 req/min per IP
500Internal server errorScoring service error — retry or contact support

Rate Limits

Two layers of rate limiting apply:

LimitValueScope
Monthly quotaTier-dependent (50–20,000)Per API key, resets on the 1st of each month
Burst limit200 requests/minutePer IP address (global DDoS protection)
Trial creation3 keys/hourPer IP address

Enterprise accounts receive 20,000 req/mo included, then $0.01 per additional request.

Pricing

Free
$0
50 req/mo
Basic
$9.99
300 req/mo
Pro ★
$29
1,500 req/mo
Ultra
$79
6,000 req/mo
Enterprise
$199
20k + $0.01

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";
}