fix(ahrefs): align tool coverage and outputs with the Ahrefs API v3#5367
Conversation
- 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
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview API request fixes: List endpoints now send required New coverage: Adds 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 Reviewed by Cursor Bugbot for commit db3fa6c. Configure here. |
Greptile SummaryThis PR fixes deep API-alignment bugs across the entire Ahrefs tool suite and adds two new tools (
Confidence Score: 5/5Safe 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 ( No files require special attention. The response-parsing fixes in Important Files Changed
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=)"]
%%{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=)"]
Reviews (4): Last reviewed commit: "feat(ahrefs): expose search intent flags..." | Re-trigger Greptile |
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.
|
@cursor review |
…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.
|
@cursor review |
There was a problem hiding this comment.
✅ 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.
|
@cursor review |
There was a problem hiding this comment.
✅ 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.
Summary
selectparam (list endpoints reject requests without it), and 3 sent adateparam the endpoint doesn't acceptoffsetparam that doesn't exist anywhere in Ahrefs API v3 (onlylimitis supported)domain_ratingandbacklinks_statsread 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_overviewsent the wrong param name entirely (keywordinstead ofkeywords), so it always returned emptyahrefs_metricsandahrefs_organic_competitorstools (both real, commonly-used Ahrefs endpoints not previously covered)docsLinkto point at docs.sim.ai instead of ahrefs.comType of Change
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 lintand full-repo typecheck pass clean.Checklist