Keyword analysis Beta
Scores a page against the keywords you actually care about and tells you exactly which placements are missing. Dozens of placement checks per keyword across metadata, headings, body copy, the URL slug, images and Open Graph, returned as a 0–100 score with every check labelled pass, warn or fail.
Authentication
Send your API key as an X-API-Key header, or as a key query parameter. Available on every plan, including Free — plans differ only in requests per day. This call costs one request against your daily quota, which is shared across every key on the account. See Authentication.
Query parameters
| Name | Type | Description |
|---|---|---|
url required | string | The page to analyse. |
keywords required | string | Comma-separated target keywords, maximum 5 (anything beyond the fifth is dropped). Alias: keyword. |
key optional | string | Your API key, if not sent as the X-API-Key header. |
Request
Response
- {
- "url": "https://example.com", "host": "example.com", "statusCode": 200,
- "title": "Example Domain", "metaDescription": null,
- "keywords": ["coffee beans", "arabica"],
- "results": [{
- "keyword": "coffee beans", "score": 68, "issues": 8,
- "categories": [
- { "key": "meta", "label": "Meta data", "score": 60, "checks": 5 },
- { "key": "html", "label": "HTML optimization", "score": 75, "checks": 9 },
- { "key": "other", "label": "Other", "score": 50, "checks": 4 }
- ],
- "checks": [{ "cat": "meta", "imp": "high", "label": "Keyword in the title tag",
- "status": "pass", "detail": "“coffee beans” is in the title" }],
- "stats": { "occurrences": 14, "density": 3.4, "position": 12, "totalWords": 412 }
- }],
- "elements": {
- "headings": [{ "level": 1, "text": "Best Coffee Beans", "dup": false }],
- "blocks": [{ "text": "…", "len": 240, "repeated": false }],
- "topKeywords": [{ "word": "coffee", "count": 22, "density": 5.3, "score": 85 }],
- "media": [{ "url": "/a.png", "alt": "a", "title": "" }]
- }
- }
Response fields
| Field | Type | Description |
|---|---|---|
results[] | array | One entry per keyword, in the order you supplied them. |
results[].score | integer | 0–100 optimisation score for that keyword on that page. |
results[].categories | array | Per-category roll-up — meta data, HTML optimisation and other — with a score and the number of checks in each. |
results[].checks | array | Every individual check: cat, importance (imp), label, status (pass/warn/fail) and a human-readable detail. |
results[].stats | object | Occurrences, density (%), first-occurrence position and the page's total word count. |
elements | object | The raw page material the checks were run against — headings, text blocks, the page's own top keywords and its images. |
Errors
keywords parameter check both run before the API key is verified, so a request with a missing or invalid key does not reliably return 401 — a call with no keywords returns 400, and a call made while the engine is unavailable returns 503, regardless of the key. Send a valid keywords value if you want to test your authentication against this endpoint.| Status | When |
|---|---|
400 | keywords (or keyword) is missing or empty: { "error": "Missing keywords parameter (comma-separated, max 5)" }. Returned before the key is checked. |
503 | The keyword engine is unavailable on this server. Also returned before the key is checked. |
401 | Missing or invalid API key — only once keywords is present and the engine is available. |
403 | The URL is a private, loopback or cloud-metadata address and was blocked by SSRF protection. |
429 | Burst rate limit (60 req/10s per IP, 30 req/10s per key) or your daily quota. See Rate limits. |
502 | The target URL could not be fetched. |
Errors return { "error": "…" }; see Errors.