DEV Community

Cover image for How to Do an Internal Linking Audit That Produces Useful Fixes
AgentSEO-dev
AgentSEO-dev

Posted on

How to Do an Internal Linking Audit That Produces Useful Fixes

An internal linking audit can produce a clean spreadsheet and still fail to improve the site.

The usual report counts links, flags orphan pages, and lists crawl depth. That is necessary diagnostic work. It does not answer the harder editorial question:

Which page should link to this URL, in which section, with what anchor, and why would the link help the reader?

You need both layers. First, audit the site graph to find structural problems. Then review the page context before adding any link.

This tutorial gives you a repeatable workflow for doing that. It includes a spreadsheet-ready decision model and a copy-paste AgentSEO request for ranking supplied target pages against a source article.

The short answer

To audit internal links:

  1. Build an inventory of canonical, indexable URLs.
  2. Crawl the site and join the crawl with sitemap, analytics, and Search Console exports.
  3. Find orphan candidates, broken destinations, redirects, excessive depth, and important pages with weak relevant support.
  4. Prioritize pages by business value and search role, not raw inlink count.
  5. Choose contextually relevant source pages for each target.
  6. Write concise, descriptive anchors inside useful body copy.
  7. Verify the rendered HTML contains normal crawlable <a href> links.
  8. Release a controlled batch and measure page-level outcomes.

Google's current link guidance supports the fundamentals behind this workflow: links help Google discover pages and understand relevance, crawlable links generally use an <a> element with an href, and anchor text should be descriptive, concise, and relevant. Google also says every page you care about should have a link from at least one other page on your site. Read Google's link best practices.

That guidance does not mean every page needs more links. The audit should improve routes through the site, not maximize a count.

Start with a page inventory, not an anchor-text brainstorm

Your crawler sees URLs it can reach. Your XML sitemap may contain URLs the crawler cannot reach. Search Console and analytics may contain historical URLs absent from both.

Combine at least these sources:

Source What it can reveal What it cannot prove alone
Site crawl Current link paths, status codes, depth, inlinks, outlinks Whether an uncrawled URL exists elsewhere
XML sitemap URLs you intend search engines to discover Whether each URL has internal support or deserves indexation
Search Console Pages with Google Search impressions or clicks A complete site architecture
Analytics Pages people visit and paths they take Search-engine crawlability
CMS export Published pages and ownership metadata What production actually renders

Normalize the URLs before comparing them. Remove fragments, handle trailing slashes consistently, and separate tracking parameters from canonical URLs. Keep the original values in another column so the cleanup stays reversible.

Your working inventory should include:

url
canonical_url
status_code
indexability
page_type
primary_topic
business_priority
inlinks
unique_linking_pages
crawl_depth
sitemap_present
search_impressions_90d
organic_clicks_90d
conversion_role
Enter fullscreen mode Exit fullscreen mode

Do not call a page an orphan merely because one crawler missed it. A crawl limit, blocked resource, JavaScript rendering problem, or incomplete starting set can create false positives. Treat orphan status as a candidate finding until you reconcile the crawl with the sitemap, CMS, Search Console, and analytics.

Separate technical defects from editorial opportunities

One queue should not mix broken links with optional content improvements. The fixes have different risk and ownership.

Technical defects

These normally deserve the first pass:

  • internal links that resolve to 4xx or 5xx pages
  • links that pass through avoidable redirect chains
  • important URLs that have no confirmed crawlable internal link
  • links implemented as click handlers without a resolvable href
  • links to non-canonical, duplicate, or unintended noindex URLs
  • important pages buried behind pagination or excessive crawl depth

Editorial opportunities

These require judgment:

  • a strong source page mentions a concept but does not link to the best next resource
  • an important product or documentation page is supported only by navigation links
  • anchors such as “click here” or “read more” hide the destination's meaning
  • multiple links use forced exact-match phrasing that reads unnaturally
  • unrelated pages link to a target only because they have traffic or backlinks
  • a new or refreshed page does not connect to its surrounding topic cluster

The technical queue asks, “Can a crawler reach the right URL?” The editorial queue asks, “Does this link make sense in the reader's journey?”

Prioritize targets before choosing sources

Raw inlink count is a weak priority rule. Ten boilerplate links from tag pages are not equivalent to two relevant contextual links from pages that readers already use.

Score target pages with criteria your team can defend:

Criterion Question Example score
Business role Does the page support evaluation, activation, or retention? 0–3
Search opportunity Does the page already have impressions, useful rankings, or validated demand? 0–3
Structural need Is it orphaned, deep, or weakly supported by relevant pages? 0–3
Content readiness Is the destination accurate, useful, canonical, and fit to receive traffic? 0–3
Fix confidence Can the team identify a genuinely relevant source and placement? 0–3

Prioritize high-value pages with structural need and a sound destination. Do not push more internal traffic to a thin, outdated, redirected, or conversion-hostile page. Fix the destination first.

This is also where you avoid a common audit failure: adding links to every orphan. Some orphan candidates should be merged, redirected, removed from the sitemap, or left out of the index rather than rescued.

Choose the source page and placement together

Once you have a target shortlist, search the content inventory for pages that discuss the same problem, task, entity, or next step.

A useful source page passes four checks:

  1. Topical fit: The surrounding section naturally relates to the target.
  2. Reader utility: The destination helps the reader continue, compare, implement, or verify.
  3. Page quality: The source is canonical, indexable, and worth maintaining.
  4. Placement clarity: You can point to an existing paragraph or heading where the link belongs.

If you cannot name the sentence-level reason for the link, do not add it yet.

Recent practitioner discussions make the same distinction. One r/TechSEO thread argues that a technically crawlable page can still lack meaningful support when it has few links from relevant pages or vague anchors. Another discussion notes that an inlink count misses where links come from and whether the anchor describes the destination. These are practitioner observations, not proof of a ranking effect, but they expose a real audit-quality problem. Read the first discussion and the follow-up discussion.

Use AgentSEO to rank supplied targets for one source page

AgentSEO's /content/internal-links endpoint handles the editorial layer of the workflow. You provide one source URL or its Markdown plus 1–50 candidate target pages. It returns ranked opportunities, suggested anchor text, a source section, placement instructions, confidence, anchor risk, and review guardrails.

It does not crawl the entire site graph in v1. Use a crawler, CMS export, sitemap audit, or Search Console data to build and prioritize the candidate set first.

Here is a copy-paste request using supplied Markdown, which makes the input reproducible:

curl -X POST "https://www.agentseo.dev/api/v1/content/internal-links?sync=true" \
  -H "x-api-key: $AGENTSEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "keyword": "SEO API",
    "target": "AgentSEO",
    "max_suggestions": 4,
    "source_markdown": "# Build an SEO agent\n\nAn SEO agent needs stable search data, explicit workflow boundaries, and a review gate before changes reach production.\n\n## Choose the integration\n\nUse a tool protocol when the model should discover and call SEO capabilities during a conversation. Use REST when your application controls orchestration, retries, and storage.\n\n## Validate the result\n\nCheck the returned evidence, confidence, limitations, and next action before allowing an automated change.",
    "target_pages": [
      {
        "url": "https://www.agentseo.dev/seo-mcp-server",
        "title": "AgentSEO MCP Server",
        "description": "Connect SEO search intelligence tools to compatible AI clients.",
        "keywords": ["SEO MCP server", "MCP tools"]
      },
      {
        "url": "https://www.agentseo.dev/docs/api-reference",
        "title": "AgentSEO API Reference",
        "description": "REST endpoints, request fields, and response contracts.",
        "keywords": ["SEO API reference", "REST endpoints"]
      },
      {
        "url": "https://www.agentseo.dev/editorial-policy",
        "title": "AgentSEO Editorial and Evidence Policy",
        "description": "Evidence, review, disclosure, and publication standards.",
        "keywords": ["editorial review", "evidence policy"]
      }
    ]
  }'
Enter fullscreen mode Exit fullscreen mode

Use your actual page descriptions and topic labels. Weak metadata creates weak matching.

I verified this exact request against the production endpoint on August 27, 2026. The short sync window returned a standard 202 job envelope, and polling the supplied poll_url returned a completed result with three opportunities:

Suggested target Anchor Relevance Confidence
AgentSEO API Reference SEO API reference 26/100 0.64
AgentSEO Editorial and Evidence Policy editorial review 25/100 0.63
AgentSEO MCP Server SEO MCP server 21/100 0.60

The output also flagged the 71-word sample as thin and recommended adding useful context before inserting several links. That is the right kind of resistance: all three matches are candidates for review, not automatic edits. This was one supplied-markdown test with three candidate targets, so it verifies the request and response contract rather than recommendation quality across a full site.

The endpoint currently costs two credits and does not call a paid SERP provider. See the current request contract in the AgentSEO API reference and test the workflow in the AgentSEO Playground.

Review the output as a recommendation, not an instruction

A returned opportunity should survive a human review before implementation.

For each suggestion, ask:

  • Is the target the canonical page for this intent?
  • Does the source paragraph actually introduce the target's topic?
  • Would a reader reasonably want the destination at this point?
  • Is the proposed anchor descriptive without sounding forced?
  • Does the source already link to this destination?
  • Will the link render in production as an <a> element with an href?
  • Are you creating too many links in one paragraph or section?

An automated relevance score cannot see every business constraint. It may not know that a product page is being retired, that two docs pages are about to merge, or that a legally required disclaimer changes the best placement.

Keep a rejection reason in the audit sheet. “Not relevant enough,” “target being consolidated,” and “destination not ready” are useful training data for the next review. Silent deletion is not.

Write anchors for comprehension

Google recommends anchor text that is descriptive, reasonably concise, and relevant to both the source and destination. That is a better rule than forcing the same target keyword every time.

Prefer:

  • AgentSEO API reference
  • content decay workflow
  • compare MCP and REST for SEO agents

Avoid:

  • click here
  • learn more
  • a long sentence linked in full
  • the same exact commercial phrase on every source page

Anchor diversity should come from natural language and different source contexts, not a spreadsheet quota. If the most accurate anchor repeats occasionally, that is less concerning than rewriting useful copy into awkward variants.

Ship the fixes in controlled batches

Do not rewrite the entire link graph in one release. Start with a small group of priority targets and record:

  • deployment date and changed URLs
  • source URL, target URL, anchor, and placement
  • reason for the change
  • pre-change crawl depth and unique linking pages
  • pre-change 28-day and 90-day Search Console page/query metrics
  • conversion or activation event tied to the target page

Verify the rendered pages immediately. Then review recrawl and indexation after 3–7 days, directional page/query movement after 14 days, primary performance after 28 days, and retain/iterate decisions after 56 days.

Do not claim that a ranking change came from one internal link unless you controlled the other variables. Search demand, page edits, external links, competitors, and Google systems can all move at the same time.

The audit is complete when every recommendation has an owner

A useful internal linking audit does not end with a severity score. It ends with a decision:

  • fix the broken or redirected link
  • add a relevant contextual link
  • improve the destination before linking
  • merge or redirect the target
  • leave the link graph unchanged
  • monitor because the evidence is incomplete

The practical next move is to choose five important target pages, reconcile their crawl and sitemap status, then review only the most relevant source pages. That small batch will teach you more than automatically inserting hundreds of links.

Disclosure: AI assisted with research organization, drafting, editing, and cover-image creation. Daniel Martin should review the claims, examples, recommendations, and final publication decision before this article is published.

Top comments (1)

Collapse
 
citedy profile image
Dmitry Sergeev

tbh i usually just export a crawl and call it a day, didn't think about the actual "useful fixes" part. helps a lot.