Ahrefs Organic Keywords

The Ahrefs Organic Keywords node reads the keywords a domain ranks for in one country, with position, search volume, landing page and estimated traffic, under a row budget that caps the API cost.

What does the Ahrefs Organic Keywords node do?

The Ahrefs Organic Keywords node reads the keywords a domain ranks for in one country, with position, search volume, landing page and estimated traffic. It supports an Ahrefs filter expression, an ordering and a row budget.

This is the most expensive node of the connector, and the reason the cache exists. Ahrefs bills organic-keywords per returned row and per selected column, so a careless read of a large domain is the single biggest line on the bill.

Three defaults keep that in check — five columns, a limit of 100 rows and a 24-hour cache window — and the node reports what it actually spent, so the trade-off is visible rather than theoretical. A read that was truncated says so: a keyword list that looks complete and is not is how a report understates a site by an order of magnitude.

Common use cases:

  • Finding the keywords that bring a site its traffic.
  • Auditing a competitor’s keyword footprint.
  • Extracting the top landing pages by organic traffic.
  • Building a quick-win list from keywords ranking between positions 11 and 20.
  • Feeding a content plan with real search volumes.

Quick setup

Connect your Ahrefs account

In the Draft & Goal sidebar, open Integrations and connect your Ahrefs API token.

Add the node to the canvas

Open the Node Library, go to Integrations > SEO Tools > Ahrefs, then drag the Ahrefs Organic Keywords node onto your workspace.

Set the target and the country

Fill in Target and pick a Country. The country is required: a keyword’s position is a position in one country’s results.

Set a row budget

Row limit defaults to 100. Raise it deliberately — every row is billed — and keep the ordering that puts the rows you want first.

Narrow the columns if you can

Leave Columns empty for the five default columns, or name exactly the ones you consume. Each extra column is billed on every row.

Connect the outputs

Connect Keywords to a list, a sheet or a Loop Node, and Summary wherever the counts and the truncation flag need to be checked.

Configuration parameters

Required fields

Ahrefs integration integration required

Integration — The connected Ahrefs account whose API token authenticates the call.

Target string required

Target domain or URL — The site to read. The scheme and a trailing slash are removed on save, except a slash on a path under Exact URL or Prefix, where it is part of the request.

Scope enum required default: domain

Target scope — domain, subdomains, prefix or exact.

Country string required default: us

Country — A lowercase ISO 3166-1 alpha-2 code from the list Ahrefs accepts. The United Kingdom is gb, not uk, and eu is not a country.

Row limit number required default: 100

Row budget for the run — Between 1 and 10000. Rows are billed, so this is a budget and not a hint: pagination stops here and the result says it was truncated.

Cache window enum required default: 24h

Cache window — off, 1h, 6h, 24h, 7d or 30d. Pages are cached per offset, so a re-run is free and a run that raises its limit re-uses the pages already paid for.

Optional fields

Protocol enum default: both

Protocol — http, https or both.

Date string

Snapshot date — A YYYY-MM-DD date. Empty sends today’s date: Ahrefs refuses this endpoint without one.

Volume mode enum default: monthly

Volume mode — Search volumes for the last month (monthly) or as a twelve-month average (average).

Columns array

Columns to return — Empty returns the five defaults. Duplicates are dropped: a column named twice is billed twice and returned once.

Sort by string default: sum_traffic:desc

Ordering — column or column:asc / column:desc. Ordering matters under a row budget: it decides which rows you pay for.

Filter string

Ahrefs filter expression, as JSON. Passed through untouched — the grammar is Ahrefs’ own, and its error names the offending field more precisely than a local parser could, at no cost since a rejected request is not billed.

Force refresh boolean default: false

Ignore the cache — Skips the cached pages and calls Ahrefs. The fresh pages are still cached.

Default columns

ColumnWhat it holds
keywordThe search term
best_positionBest position the domain holds on that term
volumeMonthly search volume
best_position_urlThe page that ranks
sum_trafficEstimated monthly visits from that keyword

Those five answer “which keyword, at which position, how big, on which page, for how much traffic”, which is the question a report asks. Others are available and billed per row, among them keyword_difficulty, cpc, is_branded, is_commercial, is_informational, is_navigational, is_transactional, is_local, serp_features, words, language, last_update, sum_paid_traffic, volume_desktop_pct and volume_mobile_pct.

What does the node output?

AnchorContents
KeywordsThe keyword rows on their own, ready for a list, a sheet or a Loop Node
SummaryCounts, the truncation flag, the columns read and the units spent
keywords string

A JSON payload with the keyword rows, the provenance, the truncation state and the cache report.

{
  "target": "example.com",
  "mode": "domain",
  "country": "us",
  "date": "2026-10-21",
  "columns": ["keyword", "best_position", "volume", "best_position_url", "sum_traffic"],
  "keywords": [
    {
      "keyword": "best seo tools",
      "best_position": 3,
      "volume": 12000,
      "best_position_url": "https://example.com/seo-tools",
      "sum_traffic": 2400
    }
  ],
  "keyword_count": 100,
  "complete": false,
  "truncated": true,
  "hit_row_cap": false,
  "requested_limit": 100,
  "truncation_notice": "Read 100 of the matching keywords and stopped at the requested limit of 100. Ahrefs bills per returned row, so the read does not continue on its own: raise the limit, or narrow the set with a filter.",
  "retrieved_at": "2026-10-21T16:04:11Z",
  "source": "Ahrefs API v3 (Site Explorer)",
  "cache": { "requests": 1, "cached_requests": 0, "units_cost": 150 }
}
Note

complete is false whenever the read filled its budget exactly. Whether more rows exist upstream cannot be known without paying for another call, and claiming completeness on a guess is the failure this field exists to prevent.

Usage examples

Example 1: Top keywords of a domain

Workflow:

  1. A Url node provides the domain.
  2. Ahrefs Organic Keywords with Country us, Sort by sum_traffic:desc, Row limit 100 and Cache window 7d.
  3. The Keywords anchor is written to a Google Sheets tab.

Example 2: Quick-win list

Keywords ranking just off the first page, where a small gain in position is worth the most.

Workflow:

  1. Ahrefs Organic Keywords with a Filter keeping best_position between 11 and 20, Columns keyword, best_position, volume, keyword_difficulty, best_position_url, Sort by volume:desc, Row limit 200.
  2. The Keywords anchor feeds an LLM asked to prioritise the list.

Filtering upstream is cheaper than filtering downstream: rows Ahrefs never returns are never billed.

Example 3: Competitor footprint

Workflow:

  1. A Text node lists the competitors.
  2. A Loop Node feeds the Target input.
  3. Ahrefs Organic Keywords with Row limit 50 and three columns.
  4. A Merge With Template node assembles the comparison.

Example 4: Content plan from real demand

Workflow:

  1. Ahrefs Organic Keywords returns the keyword list.
  2. A Loop Node iterates over the Keywords anchor — the rows alone, with no envelope to unwrap first.
  3. An LLM writes a brief per keyword.
  4. A Google Docs node stores them.

Common issues

`complete` is false and the result looks short

Cause: The read filled its row budget. It does not continue on its own, because every further row would be billed.

Solution: Raise Row limit, or narrow the set with a Filter so the rows you want fit inside the budget. truncation_notice says which.

`hit_row_cap` is true

Cause: A hard cap of 10000 rows per run stopped the read, whatever the configured limit.

Solution: Split the read — by country, by path prefix, or with a filter. The cap exists so that a mistyped target cannot turn into a five-figure bill.

`Ahrefs organic-keywords has no column ...`

Cause: A column name that does not exist on this endpoint, usually a near-miss like position instead of best_position or url instead of best_position_url.

Solution: The error lists every available column. Nothing was called, so nothing was billed.

`The Ahrefs keyword limit is capped at 10000 rows per run`

Cause: The configured limit is above the hard cap.

Solution: Lower it, and split the read if you genuinely need more rows.

The run reports a 402 or a 429

Cause: A 402 means the unit balance is exhausted; a 429 means too many calls in too short a window.

Solution: Check the balance in the settings panel. The node never retries a call, because a call that reached Ahrefs may already have been billed. Lower the limit, narrow the columns, or widen the cache window.

Best practices and pitfalls

Warning

The two levers are multiplicative. 100 rows cost a tenth of 1000, and five columns cost half of ten. Ten columns on 1000 rows is not the same bill as five columns on 100 — it is twenty times it.

Tip

Use Filter rather than reading wide and filtering downstream. A row Ahrefs never returns is a row you never pay for, and the filter also makes the row budget go further.

Note

Pages are cached per offset. A run that raises its limit re-uses the pages already paid for and only bills the new ones.

How does it fit into a workflow?

graph LR
    Url[Url<br/>target domain] --> Keywords[Ahrefs Organic Keywords]
    Keywords -->|Keywords| Loop[Loop Node]
    Loop --> LLM[LLM<br/>brief per keyword]
    Keywords -->|Summary| Check{complete?}
    LLM --> Docs[Google Docs]