Anchor Text Diversity Checker
Enter your target keyword and the anchors pointing to one page: for email marketing software, six sample anchors split into 1 exact match, 2 partial, 2 generic like learn more and 1 other, so the profile reads as diverse. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Target keyword
- email marketing software
- Total
- 6
- Assessment
- diverse
Anchor text can help search engines understand a destination, but a backlink profile dominated by one commercial phrase may look manufactured rather than earned. This anchor text diversity checker groups links to the same page into exact-match, partial-match, generic, and other categories. It reports counts and percentages, then applies a transparent warning rule so you can review a pattern without treating a heuristic as a search-engine verdict. The analysis is deterministic, quick, and suitable for repeatable audits.
Prepare one destination and its primary keyword
Start with anchor texts that all point to the same destination. Mixing links to a homepage, a product page, and a guide would make the percentages misleading because each page can reasonably target a different phrase. Enter the primary keyword that best describes the destination, then provide every observed anchor exactly as it appears in your backlink export.
The checker normalizes capitalization, accents, punctuation, apostrophes, and repeated whitespace before comparing phrases. That means small formatting differences do not create false variety. An anchor is exact-match when its normalized form equals the normalized target keyword.
It is partial-match when it is not exact but shares at least one normalized keyword token. Familiar calls to action such as “click here” and “learn more,” along with bare URLs, are generic. Names, unrelated phrases, and other anchors with no keyword overlap remain in the other category.
Keeping that fourth category visible makes the result auditable: every input belongs to exactly one group, and all counts always add up to the submitted total.
Interpret the warning as a review signal
The over-optimization flag uses a simple, published heuristic rather than pretending to reproduce a search engine’s private systems. A sample is flagged when it contains at least five anchors and exact matches represent 50 percent or more, or when exact and partial matches together represent 80 percent or more. Samples below five anchors receive an insufficient-sample assessment because one link would move their percentages too dramatically.
A flag does not prove a penalty, manipulation, or poor performance. It tells you that the distribution deserves human review alongside link quality, referring-domain diversity, relevance, placement, and acquisition history. Editorially earned links can naturally repeat a descriptive phrase, especially in a narrow field.
Conversely, a varied list can still be risky if the links come from low-quality or coordinated sites. Use the reported reasons to see exactly which threshold fired, compare similar pages consistently, and preserve the raw export. The best conclusion is contextual: this checker measures concentration in wording, not the authority, intent, or legitimacy of the links themselves.
Use repeatable samples to monitor change
For meaningful comparisons, collect anchor texts from the same data source, with the same filters, and over comparable dates. A monthly snapshot can show whether outreach, digital public relations, partnerships, or organic mentions are moving the profile toward or away from a concentrated commercial phrase. Keep duplicates when they represent separate links: the tool measures the observed link distribution, so ten links using one phrase should contribute ten observations.
Do not rewrite brand names or combine similar anchors before analysis, because that erases the variation you are trying to measure. When a warning appears, investigate the referring pages before changing anything. You might pause campaigns that prescribe exact wording, encourage partners to use natural descriptions, or earn links to useful supporting resources that attract varied citations.
Avoid manufacturing generic anchors merely to improve the percentages; cosmetic diversity is not the same as editorial quality.
What you can do with it
Review an outreach campaign
Check whether partner and guest-post links repeat a prescribed commercial keyword too often.
Compare competing pages
Apply the same categories and thresholds to anchor exports for pages serving a similar search intent.
Monitor backlink changes
Run consistent monthly samples and record whether exact and partial match concentration is rising.
FAQ
What is an exact-match anchor?
It is an anchor whose normalized wording equals the normalized target keyword, ignoring case, accents, punctuation, apostrophes, and repeated whitespace.
What is a partial-match anchor?
It is a non-exact, non-generic anchor that shares at least one normalized word with the target keyword.
Does a warning mean the page has a penalty?
No. The warning is a concentration heuristic for review, not evidence of a search-engine action or a prediction of rankings.
Why are fewer than five anchors not assessed?
Very small samples change sharply with each link, so the tool reports the categories but labels the optimization assessment as insufficient.
When is an anchor profile flagged as over-optimized?
When there are at least five anchors and exact matches make up 50 percent or more, or exact and partial matches together reach 80 percent or more. The reasons show which threshold fired; it is a prompt for review, not proof of a penalty.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/seo/anchor-text-diversity \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"target_keyword":"email marketing software","anchor_texts":["Email marketing software","best email marketing software","learn more","Acme Mail","https://example.com/email"]}'const res = await fetch("https://api.kit.forhosting.com/seo/anchor-text-diversity", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"target_keyword": "email marketing software",
"anchor_texts": [
"Email marketing software",
"best email marketing software",
"learn more",
"Acme Mail",
"https://example.com/email"
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/seo/anchor-text-diversity",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"target_keyword": "email marketing software",
"anchor_texts": [
"Email marketing software",
"best email marketing software",
"learn more",
"Acme Mail",
"https://example.com/email"
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/seo/anchor-text-diversity", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"target_keyword":"email marketing software","anchor_texts":["Email marketing software","best email marketing software","learn more","Acme Mail","https://example.com/email"]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"target_keyword":"email marketing software","anchor_texts":["Email marketing software","best email marketing software","learn more","Acme Mail","https://example.com/email"]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/seo/anchor-text-diversity", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"target_keyword": "email marketing software",
"anchor_texts": [
"Email marketing software",
"best email marketing software",
"learn more",
"Acme Mail",
"https://example.com/email"
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "seo.anchor_text_diversity",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical questions
Which anchors count as generic?
Common calls to action such as click here, read more, and learn more count as generic, as do bare HTTP, HTTPS, or www URLs.
How much does the API cost?
Each API request costs $0.002. The same deterministic classification is suitable for repeatable automated reports.