ForHosting KIT · SEO

Check hreflang tag consistency and reciprocal links

Hreflang clusters only work reliably when every participating page declares the same complete set of alternatives, including a self-reference.

● BetaFree · in your browser
Use it from WebAPIEmailTelegramApp soon

This checker compares mappings collected from multiple pages and exposes incomplete clusters without fetching any URLs. It builds the expected page set from all source and target URLs, checks every source against that set, and returns the precise links missing from each page. The result is deterministic, suitable for release checks, migrations, and repeatable SEO quality-control workflows.

Why complete reciprocal clusters matter

An hreflang annotation is not merely a one-way recommendation from one page to another. It describes membership in a group of equivalent language or regional pages, and every page in that group should publish the same set of destinations. That includes a link to itself. When an English page names French and German alternatives but the French page only names English, the cluster is incomplete even though several individual tags look correct. Search engines may ignore unsupported relationships, leaving the wrong language version eligible for a query or weakening the intended regional signal. Manual review becomes unreliable as clusters grow because the number of relationships increases quickly. A four-page cluster needs each of its four pages to declare all four destinations, which means sixteen source-to-target relationships must be present. This checker turns that visual comparison into an exact set test. It reports consistency only when every page represented by the submitted mappings declares every page in the cluster, making omissions and missing self-references explicit rather than hiding them behind a summary count.

How to prepare and interpret the mappings

Submit one record for each hreflang declaration you observed. The page_url identifies the page containing the tag, language records the tag value, and target_url identifies its destination. Include records from every page that is intended to belong to the cluster. The checker derives the expected cluster from the union of source and target URLs. This detail catches an especially useful failure: if one page is referenced by its siblings but contributes no declarations of its own, it still enters the expected set and is reported as missing every destination. URLs are compared as exact strings after surrounding whitespace is removed, so your collection process should use the canonical absolute form emitted by the pages. The output contains a page summary and a conflicts list. A complete page has declared every URL in the derived cluster. An incomplete page includes missing_urls, which lists the precise destinations that must be added. The consistent field is true only when the conflicts list is empty; duplicate declarations do not manufacture completeness because destinations are compared as a set.

Use it in launches, migrations, and recurring audits

The most valuable time to run a reciprocity check is before a multilingual release reaches crawlers. Export the generated hreflang declarations from the rendered pages, convert them into mapping records, and fail the release when consistent is false. This catches template branches that omit the current page, regional rollouts that update only the new market, and migrations where one locale still emits URLs from the old structure. The same check also fits a scheduled audit after editors add or retire locales. Because the algorithm performs no network requests, it does not prove that a destination responds successfully, is canonical, or contains useful equivalent content; those are separate crawling and editorial checks. Its narrow promise is stronger: for the exact mapping set supplied, it determines whether every represented page lists every other represented page and itself. API requests use the published base price of $0.002, while the browser implementation can run the same pure comparison locally. Store the returned conflicts beside deployment evidence so corrections can be traced to a specific source page and missing target rather than a vague cluster-level warning.

Validate a multilingual launch

Check that every newly launched locale and every existing sibling page publish the complete shared alternate set before release.

Audit a platform migration

Compare mappings emitted by new templates and identify pages that lost self-references or return links during URL migration.

Guard an SEO deployment pipeline

Turn an inconsistent cluster into a deterministic failed quality check with exact missing source-to-target relationships.

What makes an hreflang cluster consistent?

Every URL represented in the cluster must declare every represented URL, including itself. The checker reports true only when all those relationships exist.

Does the checker fetch the pages?

No. It only compares the mappings you provide, so it is deterministic and does not verify HTTP status, canonical tags, or page content.

How are missing source pages detected?

The expected cluster is built from both source and target URLs. A URL that appears only as a target is therefore reported as a page with missing declarations.

Are duplicate declarations treated as conflicts?

Duplicate source-to-target declarations do not affect completeness. Destinations are compared as a set, while the mapping count still reflects all submitted records.

Are URL variants normalized?

No. URLs are compared exactly after trimming surrounding whitespace. Normalize scheme, host, path, and trailing-slash conventions before submitting mappings.

What does an API request cost?

Each request uses the published base price of $0.002. The comparison does not make network or model calls.

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.

POSThttps://api.kit.forhosting.com/seo/hreflang-conflict-check

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.

curl -X POST https://api.kit.forhosting.com/seo/hreflang-conflict-check \
  -H "Authorization: Bearer $KIT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mappings":[{"page_url":"https://example.com/en","language":"en","target_url":"https://example.com/en"},{"page_url":"https://example.com/en","language":"fr","target_url":"https://example.com/fr"},{"page_url":"https://example.com/fr","language":"en","target_url":"https://example.com/en"},{"page_url":"https://example.com/fr","language":"fr","target_url":"https://example.com/fr"}]}'
{
  "mappings": [
    {
      "page_url": "https://example.com/en",
      "language": "en",
      "target_url": "https://example.com/en"
    },
    {
      "page_url": "https://example.com/en",
      "language": "fr",
      "target_url": "https://example.com/fr"
    },
    {
      "page_url": "https://example.com/fr",
      "language": "en",
      "target_url": "https://example.com/en"
    },
    {
      "page_url": "https://example.com/fr",
      "language": "fr",
      "target_url": "https://example.com/fr"
    }
  ]
}
{
  "task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
  "type": "seo.hreflang_conflict_check",
  "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.

Per request$0.002

Published price — no tokens, no invented credits. A failed task is never charged.

HTTPCodeMeaning
401unauthorizedMissing or invalid API key.
402insufficient_balanceYour balance doesn't cover the task price.
404unknown_typeThat task type doesn't exist.
429rate_limitedToo many requests. Use the webhook instead of polling.

Read the full KIT documentation →