Skip to content

fix(ahrefs): align tool coverage and outputs with the Ahrefs API v3#5367

Merged
waleedlatif1 merged 4 commits into
stagingfrom
worktree-ahrefs-validate
Jul 2, 2026
Merged

fix(ahrefs): align tool coverage and outputs with the Ahrefs API v3#5367
waleedlatif1 merged 4 commits into
stagingfrom
worktree-ahrefs-validate

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • 5 of 8 Ahrefs tools were missing the API's required select param (list endpoints reject requests without it), and 3 sent a date param the endpoint doesn't accept
  • every list endpoint sent an offset param that doesn't exist anywhere in Ahrefs API v3 (only limit is supported)
  • domain_rating and backlinks_stats read the response at the wrong nesting level and always returned zeros; several other tools mapped outputs to column names the API doesn't return (position, url, traffic, backlinks, dofollow_backlinks, http_code) instead of the real ones (best_position, best_position_url, sum_traffic, links_to_target, dofollow_links, http_code_target)
  • keyword_overview sent the wrong param name entirely (keyword instead of keywords), so it always returned empty
  • added ahrefs_metrics and ahrefs_organic_competitors tools (both real, commonly-used Ahrefs endpoints not previously covered)
  • fixed docsLink to point at docs.sim.ai instead of ahrefs.com
  • every output field that changed name/shape was verified against the live API docs to confirm the old field never actually worked (always defaulted to 0/empty) rather than being a working feature that got dropped

Type of Change

  • Bug fix

Testing

Verified every tool's URL, params, and response parsing against the live Ahrefs API v3 reference docs with 3 independent parallel verification passes (param/response correctness, block↔tool alignment, backward-compatibility of output fields). bun run lint and full-repo typecheck pass clean.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

- 5 of 8 tools were missing the required `select` param (API v3 rejects
  list-endpoint requests without it) and 3 sent a `date` param the
  endpoint doesn't accept
- all list endpoints sent an `offset` param that doesn't exist on any
  Ahrefs v3 site-explorer endpoint (only `limit` is supported)
- domain_rating and backlinks_stats read response fields at the wrong
  nesting level and always returned zeros; several other tools mapped
  output fields to column names the API doesn't return (position, url,
  traffic, backlinks, dofollow_backlinks, http_code) instead of the
  real ones (best_position, best_position_url, sum_traffic,
  links_to_target, dofollow_links, http_code_target)
- keyword_overview used the wrong endpoint param entirely (`keyword`
  instead of `keywords`) so it always returned empty
- added ahrefs_metrics (site-explorer/metrics) and
  ahrefs_organic_competitors (site-explorer/organic-competitors) tools
- fixed docsLink to point at docs.sim.ai instead of ahrefs.com
@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 2, 2026 3:36pm

Request Review

@cursor

cursor Bot commented Jul 2, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Large integration surface with breaking output shapes on backlinks stats and removed offset/history-vs-date params; fixes broken behavior but existing workflows referencing old field names may need updates.

Overview
Aligns the Ahrefs block and tools with Ahrefs API v3 so requests succeed and parsed data matches the real response shapes.

API request fixes: List endpoints now send required select fields; backlinks use all-backlinks with history (replacing invalid date / offset); referring domains use history the same way; keyword overview sends keywords (not keyword) and reads the first row from data.keywords. Domain rating and backlinks stats read nested domain_rating / metrics instead of flat fields that always returned zeros.

New coverage: Adds ahrefs_metrics and ahrefs_organic_competitors tools, wires them through the block operation dropdown, registry, types, and new template/skill content. Block docsLink points to Sim docs; shared country/mode/date wand config reduces duplication.

Outputs & UI: Backlinks stats output is reshaped to live/all-time backlink and refdomain totals (replacing dofollow/nofollow/text breakdowns). Organic keywords, top pages, referring domains, broken backlinks, and keyword overview map v3 column names and expose more nullable/optional fields (e.g. search intents on keyword overview). Block drops offset input and adds History for backlinks and referring domains; default list limits move toward 1000.

Reviewed by Cursor Bugbot for commit db3fa6c. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes deep API-alignment bugs across the entire Ahrefs tool suite and adds two new tools (ahrefs_metrics, ahrefs_organic_competitors). Every fix was driven by verifying the tools against the live Ahrefs API v3 reference, and the code changes are internally consistent.

  • Response-parsing fixes: domain_rating now correctly reads data.domain_rating.domain_rating (was data.domain_rating); backlinks_stats now reads data.metrics.live / live_refdomains / all_time / all_time_refdomains (was flat data.live); organic_keywords, referring_domains, and top_pages map to the correct API field names (best_position, sum_traffic, links_to_target, dofollow_links, last_seen).
  • Request fixes: The required select param is now included for every list endpoint; offset is removed everywhere (doesn't exist in v3); keyword_overview fixes the param name from keyword to keywords; backlinks and referring_domains switch from a date param to the correct history param; backlinks moves to the correct /all-backlinks endpoint.
  • Block UI: COUNTRY_OPTIONS, MODE_OPTIONS, and DATE_WAND_CONFIG are extracted as shared constants, eliminating significant duplication; history dropdowns replace date pickers for the two affected operations; Broken Backlinks and two new tools are added to the operation dropdown.

Confidence Score: 5/5

Safe to merge — all changes are targeted API-alignment fixes with internally consistent SELECT_FIELDS, response-parsing, and type definitions throughout.

Every SELECT_FIELDS constant was cross-checked against its response-parsing code and type definitions and all are consistent. The two new tools follow established patterns exactly. The endpoint URL changes (/backlinks/all-backlinks, keywordkeywords param) are well-supported by the PR description's verification methodology. No regressions or unhandled edge cases were identified.

No files require special attention. The response-parsing fixes in backlinks_stats.ts and domain_rating.ts are the highest-impact changes (they turn always-zero outputs into real values) but the logic is straightforward.

Important Files Changed

Filename Overview
apps/sim/tools/ahrefs/backlinks_stats.ts Fixes response parsing to read from the correct data.metrics nesting level; strips the non-existent date param from the request; output fields now match the v3 API shape.
apps/sim/tools/ahrefs/domain_rating.ts Fixes response to read data.domain_rating.domain_rating / data.domain_rating.ahrefs_rank instead of the flat (always-zero) top-level fields.
apps/sim/tools/ahrefs/backlinks.ts Switches to the correct /all-backlinks endpoint, adds required select param, replaces date with the history param, removes non-existent offset.
apps/sim/tools/ahrefs/organic_keywords.ts Adds required select param; remaps output fields to correct API names (best_position, best_position_url, sum_traffic, keyword_difficulty); removes offset.
apps/sim/tools/ahrefs/keyword_overview.ts Fixes critical param name bug (keywordkeywords), adds select, reads result from data.keywords[0], maps fields correctly including new intents object.
apps/sim/tools/ahrefs/referring_domains.ts Adds select, switches from date to history param, corrects field names (links_to_target, dofollow_links, last_seen), removes offset.
apps/sim/tools/ahrefs/top_pages.ts Fixes select to use sum_traffic (not traffic), removes user-configurable select/offset params, maps response correctly.
apps/sim/tools/ahrefs/broken_backlinks.ts Adds select, fixes HTTP code field to http_code_target, removes non-existent date/offset params.
apps/sim/tools/ahrefs/metrics.ts New tool covering the site-explorer/metrics endpoint; correctly reads from data.metrics nesting, maps all org/paid fields, defaults country to 'us'.
apps/sim/tools/ahrefs/organic_competitors.ts New tool for site-explorer/organic-competitors; SELECT_FIELDS and response-field mappings are internally consistent; country, date, and limit params are correct for this endpoint.
apps/sim/tools/ahrefs/types.ts Type definitions updated to match new tool shapes; AhrefsHistory union type added; nullable fields correctly typed; two new param/response interfaces added.
apps/sim/blocks/blocks/ahrefs.ts Block UI refactored to match tool changes: shared option constants eliminate duplication, history dropdowns replace date pickers for relevant ops, two new tools registered.
apps/sim/tools/ahrefs/index.ts Exports two new tools and adds export * from types to make types available from the module index.
apps/sim/tools/registry.ts Registers two new Ahrefs tools and re-orders existing entries alphabetically; no functional issues.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    Block["AhrefsBlock\n(ahrefs.ts)"]
    Block -->|operation| Switch{tool switch}

    Switch -->|ahrefs_domain_rating| DR["domain_rating.ts\n/v3/site-explorer/domain-rating\nReads: data.domain_rating.domain_rating"]
    Switch -->|ahrefs_metrics| MET["metrics.ts NEW\n/v3/site-explorer/metrics\nReads: data.metrics.org_traffic …"]
    Switch -->|ahrefs_backlinks| BL["backlinks.ts\n/v3/site-explorer/all-backlinks\nselect=… history=all_time|live"]
    Switch -->|ahrefs_backlinks_stats| BS["backlinks_stats.ts\n/v3/site-explorer/backlinks-stats\nReads: data.metrics.live …"]
    Switch -->|ahrefs_referring_domains| RD["referring_domains.ts\n/v3/site-explorer/refdomains\nselect=… history=all_time|live"]
    Switch -->|ahrefs_broken_backlinks| BB["broken_backlinks.ts\n/v3/site-explorer/broken-backlinks\nselect=… (no date)"]
    Switch -->|ahrefs_organic_keywords| OK["organic_keywords.ts\n/v3/site-explorer/organic-keywords\nselect=… date=today"]
    Switch -->|ahrefs_organic_competitors| OC["organic_competitors.ts NEW\n/v3/site-explorer/organic-competitors\nselect=… date=today"]
    Switch -->|ahrefs_top_pages| TP["top_pages.ts\n/v3/site-explorer/top-pages\nselect=url,sum_traffic,…"]
    Switch -->|ahrefs_keyword_overview| KO["keyword_overview.ts\n/v3/keywords-explorer/overview\nparams: keywords= (was keyword=)"]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    Block["AhrefsBlock\n(ahrefs.ts)"]
    Block -->|operation| Switch{tool switch}

    Switch -->|ahrefs_domain_rating| DR["domain_rating.ts\n/v3/site-explorer/domain-rating\nReads: data.domain_rating.domain_rating"]
    Switch -->|ahrefs_metrics| MET["metrics.ts NEW\n/v3/site-explorer/metrics\nReads: data.metrics.org_traffic …"]
    Switch -->|ahrefs_backlinks| BL["backlinks.ts\n/v3/site-explorer/all-backlinks\nselect=… history=all_time|live"]
    Switch -->|ahrefs_backlinks_stats| BS["backlinks_stats.ts\n/v3/site-explorer/backlinks-stats\nReads: data.metrics.live …"]
    Switch -->|ahrefs_referring_domains| RD["referring_domains.ts\n/v3/site-explorer/refdomains\nselect=… history=all_time|live"]
    Switch -->|ahrefs_broken_backlinks| BB["broken_backlinks.ts\n/v3/site-explorer/broken-backlinks\nselect=… (no date)"]
    Switch -->|ahrefs_organic_keywords| OK["organic_keywords.ts\n/v3/site-explorer/organic-keywords\nselect=… date=today"]
    Switch -->|ahrefs_organic_competitors| OC["organic_competitors.ts NEW\n/v3/site-explorer/organic-competitors\nselect=… date=today"]
    Switch -->|ahrefs_top_pages| TP["top_pages.ts\n/v3/site-explorer/top-pages\nselect=url,sum_traffic,…"]
    Switch -->|ahrefs_keyword_overview| KO["keyword_overview.ts\n/v3/keywords-explorer/overview\nparams: keywords= (was keyword=)"]
Loading

Reviews (4): Last reviewed commit: "feat(ahrefs): expose search intent flags..." | Re-trigger Greptile

Comment thread apps/sim/tools/ahrefs/metrics.ts Outdated
Comment thread apps/sim/tools/ahrefs/metrics.ts Outdated
Greptile and Cursor Bugbot both flagged that ahrefs_metrics omitted
the country when unset, unlike every other country-accepting Ahrefs
tool, which silently returns global data instead of US data on
direct tool calls.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/tools/ahrefs/backlinks.ts Outdated
…omains

Cursor Bugbot flagged that history was only sent when explicitly set,
even though the block UI defaults it to all_time — same class of gap
as the metrics.ts country fix, applied for direct tool-call consistency.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 92ac0ee. Configure here.

Adds the real intents field (informational, navigational, commercial,
transactional, branded, local) from keywords-explorer/overview, which
was verified valid against the live API docs but not yet surfaced.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit db3fa6c. Configure here.

@waleedlatif1 waleedlatif1 merged commit 02b1de4 into staging Jul 2, 2026
18 checks passed
@waleedlatif1 waleedlatif1 deleted the worktree-ahrefs-validate branch July 2, 2026 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant