Etsy Keyword Researcher
Data & Research apifyExtracts a keyword universe + demand proxy + clusters from Etsy autocomplete.
Live output preview
A plan is required to view this content
Choose a plan to access input format, sample outputs, and live previews.
View Plans →About the skill
/etsy-keywords-apify-fetcher — Library Skill: Etsy Autocomplete Keyword Universe
A standard, agent-facing interface to the Apify maximedupre/etsy-keywords-research-tool actor (APIFY_ETSY_KEYWORDS_ACTOR env override). In a single call (the actor accepts a keywords[] array), it expands a seed list into the Etsy search bar's autocomplete suggestions, dedupes them, and produces a relative demand proxy.
v2.0.0 — actor changed. The previous
easyapi/etsy-keywords-research-toolactor was running but returning 0 results (backend down, confirmed 2026-06-14). It was replaced with the working + cheaper + better-schema'dmaximedupre/etsy-keywords-research-tool(array input,rank,normalizedSuggestion, alphabet expansion).
⚠️ Data Reality — Read First
- This actor does NOT give ABSOLUTE search volume. Etsy's official API does not expose search volume; no free source gives the true in-Etsy monthly search count.
- The signal it returns: the terms real buyers type, from Etsy autocomplete, ordered by autocomplete position (
rank).best_rank=1= what Etsy suggests at the very top for that seed = the strongest demand signal. - The caller must NOT present it as "X searches per month." The correct framing is: "relative demand ranking / autocomplete position."
- Competitor supply / sales counts are NOT in this actor → for that,
automation-lab/etsy-scraper(listing + price + rating) is used separately.
How It's Called
Skill tool: etsy-keywords-apify-fetcher
Input: {
seeds: <string[]>, // ["gothic shirt","witchy tee",...] — all in a SINGLE call
country?: <ISO-3166-1>, // default "US" (Etsy is US-heavy)
language?: <ISO-639-1>, // default "en"
max_results_per_seed?: <int>, // default 30, clamp [10,80]
expand_prefixes?: <bool>, // default false; true = seed + a-z (MORE results + MORE cost)
prefix_characters?: <string>, // default "abcdefghijklmnopqrstuvwxyz"
max_retries?: <int>, // retry if empty, default 2
min_breadth?: <int>, // lower bound for seed_breadth in results, default 1
output_path?: <abs path> // stdout JSON if absent
}
Credentials & Prerequisites
set -e
ENV_FILE="$HOME/.claude/.env"
[ -f "$ENV_FILE" ] || { echo "FAIL: $ENV_FILE yok" >&2; exit 1; }
APIFY_API_TOKEN=$(grep -E '^APIFY_API_TOKEN=' "$ENV_FILE" | head -1 | cut -d= -f2- | tr -d '"' | tr -d "'")
APIFY_ETSY_KEYWORDS_ACTOR=$(grep -E '^APIFY_ETSY_KEYWORDS_ACTOR=' "$ENV_FILE" | head -1 | cut -d= -f2- | tr -d '"' | tr -d "'")
[ -n "$APIFY_ETSY_KEYWORDS_ACTOR" ] || APIFY_ETSY_KEYWORDS_ACTOR="maximedupre/etsy-keywords-research-tool"
[ -n "$APIFY_API_TOKEN" ] || { echo "FAIL: APIFY_API_TOKEN boş" >&2; exit 1; }
command -v jq >/dev/null || { echo "FAIL: jq yok" >&2; exit 1; }
Flow
1. Input Validation
seedsis required, 1-40 range. Duplicate seed → dedupe, trim.country/languagedefault "US"/"en".max_results_per_seedclamp [10,80].expand_prefixesdefault false (if true, results and cost increase ~5-10x).min_breadthdefault 1.
2. Cost / Quota Note
Pay-per-result: ~$0.00265 / keyword result (≈ $2.65/1000) + a small actor-start. Rough estimate: 15 seeds × 30 results ≈ 450 results ≈ ~$1.2. expand_prefixes:true multiplies this many times over — turn it on only when deep coverage is needed.
3. Apify run-sync — SINGLE CALL (array input)
ACTOR_SLUG=$(echo "$APIFY_ETSY_KEYWORDS_ACTOR" | tr '/' '~') # maximedupre~etsy-keywords-research-tool
PER="${max_results_per_seed:-30}"
COUNTRY="${country:-US}"; LANG="${language:-en}"
EXP="${expand_prefixes:-false}"; PREFIX="${prefix_characters:-abcdefghijklmnopqrstuvwxyz}"
MAX_RETRIES="${max_retries:-2}"
SEED_COUNT=${#seeds[@]}
TOT=$(( PER * SEED_COUNT )); [ "$TOT" -lt 30 ] && TOT=30
SEEDS_JSON=$(printf '%s\n' "${seeds[@]}" | jq -R . | jq -s 'map(select(length>0)) | unique')
PAYLOAD=$(jq -n --argjson kw "$SEEDS_JSON" --argjson n "$PER" --argjson tot "$TOT" \
--argjson exp "$EXP" --arg pc "$PREFIX" --arg c "$COUNTRY" --arg l "$LANG" '{
keywords: $kw,
maxResultsPerKeyword: $n,
maxTotalResults: $tot,
expandPrefixes: $exp,
prefixCharacters: $pc,
sortOutputBy: "sourceOrder",
country: $c,
language: $l,
includeNormalizedKeyword: true,
includeSearchUrls: true
}')
RAW=$(mktemp -t etsy-kw-raw.XXXXXX.json); attempt=0; count=0
while [ "$attempt" -le "$MAX_RETRIES" ]; do
attempt=$((attempt+1))
if curl -fsS -X POST \
"https://api.apify.com/v2/acts/${ACTOR_SLUG}/run-sync-get-dataset-items?token=${APIFY_API_TOKEN}&timeout=240&format=json&clean=true" \
-H "Content-Type: application/json" --data "$PAYLOAD" --max-time 300 > "$RAW" 2>/dev/null; then
if jq -e 'type=="array"' "$RAW" >/dev/null 2>&1; then count=$(jq 'length' "$RAW"); [ "$count" -gt 0 ] && break; fi
fi
echo "[warn] attempt $attempt → 0/err" >&2
done
⚠️ Because this actor takes a keywords[] array, multiple seeds = a single run (in the old actor each seed was a separate run). If it returns empty, retry up to max_retries.
4. Dedupe + Demand Proxy + Sort
MIN_BREADTH="${min_breadth:-1}"
FINAL_KW=$(jq --argjson minb "$MIN_BREADTH" '
group_by(.normalizedSuggestion // (.suggestion | ascii_downcase))
| map({
suggestion: .[0].suggestion,
normalized: (.[0].normalizedSuggestion // (.[0].suggestion | ascii_downcase)),
type: (.[0].suggestionType // "autocomplete"),
best_rank: (map(.rank // .sourceRank // 999) | min),
seed_breadth: (map(.seedKeyword) | unique | length),
seeds: (map(.seedKeyword) | unique),
search_url: (.[0].searchUrl // null),
demand_proxy_score: ((100.0 / (map(.rank // .sourceRank // 999) | min)) | floor)
})
| map(select(.seed_breadth >= $minb))
| sort_by(-(.seed_breadth), .best_rank)
' "$RAW")
# seed_diagnostics: which seed returned results / empty
DIAG=$(jq -n --argjson raw "$(cat "$RAW")" --argjson req "$SEEDS_JSON" '
($raw | group_by(.seedKeyword) | map({key:.[0].seedKeyword, value:length}) | from_entries) as $hit
| $req | map({seed:., status:(if ($hit[.] // 0) > 0 then "ok" else "no_data" end), count:($hit[.
How do I use this skill?
Upload the etsy-keywords-apify-fetcher.zip you downloaded as-is — no packaging needed, the format is already correct (folder at root).
- Open Settings → Customize → Skills
- Upload → select the
etsy-keywords-apify-fetcher.zipyou downloaded - Claude reads
SKILL.md; the name + description appear. Ready ✅
Scripts run in Anthropic's code-execution environment (sandbox) — not on your machine.