Install
openclaw skills install find-product-directoriesUse whenever the user wants to find, rank, or shortlist directories, listing sites, or launch platforms where they can submit a software product, SaaS, app, tool, or startup — to get backlinks, referral traffic, and launch-day reach. Triggers on "where can I submit my SaaS for launch", "list of Product Hunt alternatives", "directories to get backlinks for our app", "high-authority software listing sites", "where should I list my startup", or "pull submission details for these 8 directory domains", even when described indirectly (we're launching next week, where do we post; how do we get backlinks by listing in directories). Drives the ServiceGraph API (api.servicegraph.co) — a catalog of 1,000+ product directories enriched with Domain Rating, backlinks, and organic traffic. Defer to find-mcp-directories for MCP-server listings and find-ai-directories for AI-tool / AI-agent / agent-skill listings. Skip finding a firm/agency to hire (use the find-* agency skills), finding products *inside* a directory ("recommend the best CRM"), building a directory site (do-the-work), local/business directories for brick-and-mortar listings, and link-building *services*.
openclaw skills install find-product-directoriesDrive the ServiceGraph API (https://api.servicegraph.co) to find and
rank directories where a founder can submit a software product — SaaS
review sites (Capterra, G2, SaaSHub), launch platforms (Product Hunt and its
alternatives), app/startup listings, and general software directories — via
the product_directory dataset. The catalog has 1,000+ directories, each
enriched with Domain Rating (dr), backlink counts, and organic
traffic, so you can rank by real SEO value and reach instead of guessing.
This is a "where to launch / where to get backlinks" skill, not a "who to hire" skill. Each row is a directory you submit to, not a firm and not a product. The payoff for the user is twofold: a backlink from a high-authority domain (SEO) and launch-day referral traffic.
Any HTTP client works (curl, fetch, requests). Examples below use curl.
If the user's product is specifically one of these, defer to the dedicated skill (its catalog slice and recipes are tuned for it):
find-mcp-directoriesfind-ai-directoriesThis skill is the umbrella for everything else founders launch — SaaS, web apps, mobile apps, dev tools, startups in general — and is the right pick when the ask spans niches or names none.
If your harness has the ServiceGraph MCP server loaded (recognizable by tool
names containing servicegraph), prefer those tools — the harness handles
credentials in its own sandbox via OAuth 2.1 + PKCE, so no token enters LLM
context. Otherwise use the REST flow below.
product_directory)Every endpoint requires the bearer (Authorization: Bearer vk_…). There is
no anonymous tier.
| Endpoint | Cost | Use it for |
|---|---|---|
GET /v1/datasets/product_directory/fields[?include_values=1&q=] | free | Filter-field catalog + DSL grammar. Call first per session. |
GET /v1/datasets/product_directory/values/:field[?q=&limit=] | free | Enumerate values for one field (e.g. industry, has). |
GET /v1/datasets/product_directory/check?filter=… | free | Validate a filter. Returns {valid, normalized} or {valid:false, error}. |
POST /v1/datasets/product_directory/translate-intent | free | {intent} → LLM-generated DSL filter + sanity count. |
GET /v1/datasets/product_directory/search?filter=…&limit=&offset= | free | Brief directory cards (incl. dr) + per-row unlock hint + total. |
GET /v1/datasets/product_directory/:apex | free | Single row brief; gated fields only if unlocked. |
POST /v1/datasets/product_directory/unlocks | 10 credits / row | {apexes:[...]} ≤100. Atomic batch; 30-day TTL; was_cached:true rows free. |
GET /v1/me/credits | free | Balance. |
Cost model. Discovery / validation / search / brief reads are free —
including the dr ranking signal. Unlocking a row costs 10 credits and
lasts 30 days; it reveals the gated fields: editor_note (the
hand-written submission note — how to submit and whether the listing gives
a backlink), organic_traffic, and total_visits. Re-fetching an unlocked
row within TTL is free.
Tokens are vk_* API keys minted in the dashboard.
Keep the token out of the LLM context — never read .env* into your
context; dispatch every authed call through a shell wrapper.
Just try the call through a shell wrapper that sources .env.local:
( set -a; [ -f .env.local ] && . ./.env.local; set +a;
curl -sS -H "Authorization: Bearer $SERVICEGRAPH_API_KEY" \
'https://api.servicegraph.co/v1/datasets/product_directory/fields' )
On 401 unauthorized, prompt the user (don't accept the key in chat):
"Open https://servicegraph.co/profile/api-keys, sign in, click Create key, and copy the
vk_…value. Then addSERVICEGRAPH_API_KEY=vk_…to.env.localhere (or export it in your shell). Tell me when done. Please don't paste the key into chat."
Retry the same call after the user signals ready. A later 401 means the key was rotated/revoked — re-prompt.
GitHub-search-style.
filter := orExpr
orExpr := andExpr ("OR" andExpr)*
andExpr := notExpr (("AND")? notExpr)* # whitespace = implicit AND
notExpr := ("NOT" | "-") notExpr | atom
atom := "(" filter ")" | predicate
predicate:= IDENT op valueOrList | bareword
op := ":" | "=" | ">=" | "<=" | ">" | "<"
Four rules that bite:
a OR b c parses as a OR (b AND c). Use parens.industry:software_saas,fintech = either.-x or NOT x. Use saas -crm, not keyword:saas,-crm.niche
tag (so saas matches dirs whose niche is "SaaS products"). Multiple
barewords AND. Wrap multi-word phrases in double quotes ("product launch").This dataset ranks directories by SEO value and reach, so the numeric signals are the point:
| Field | Free in brief? | Use it for |
|---|---|---|
dr | yes | Ahrefs-style Domain Rating 0–100. The primary authority filter — a backlink from dr>=70 is worth far more than from dr<30. Briefs are returned sorted by dr descending, so the strongest domains come first. |
referring_main_domains | yes (when populated) | Distinct apexes linking in — "is this a real backlink source?". >=100 decent, >=1000 strong. |
backlinks | yes (when populated) | Total inbound links; a sanity floor, long-tailed. |
organic_keywords | yes (when populated) | Distinct US Google keywords ranked for. |
organic_traffic | gated | Est. monthly US organic visits — the real-reach metric. Filterable even while hidden (organic_traffic>=10000), but the value shows only after unlock. |
total_visits | gated | Est. total monthly visits. |
editor_note | gated | Hand-written submission note: how to submit, and whether you get a backlink. |
industry | yes | High-level vertical of the directory (e.g. software_saas, fintech, design_creative). A coarse refiner; keyword on niche is usually sharper. |
has | yes | Presence of a structured field / third-party listing (has:pricing, has:g2, …). |
Because dr is free and briefs are pre-sorted by it, you can rank a
shortlist by authority without spending a single credit — unlock only the
ones the user wants submission instructions for.
apexDirectories are keyed by apex domain (producthunt.com, not
www.producthunt.com/posts). Strip user-supplied URLs to the apex before
calling :apex endpoints or building unlock batches.
User: "Where can I launch my SaaS next week besides Product Hunt?"
GET /v1/datasets/product_directory/search?filter=launch&limit=15
# → cards sorted by dr desc; producthunt.com, uneed.best, peerpush.net, tinylaunch.com, …
Present the top N by dr (free). Tighten to high-authority only:
GET /v1/datasets/product_directory/search?filter=launch+dr>=60&limit=15
User: "High-authority directories to list our B2B SaaS for SEO."
GET /v1/datasets/product_directory/search?filter=saas+dr>=60&limit=20
# → saashub.com, saasworthy.com, financesonline.com, capterra.com (via 'saas' niche), …
Software in general (broader than SaaS):
GET /v1/datasets/product_directory/search?filter=software+dr>=60&limit=20
User: "Which directories actually send traffic, not just a backlink?"
organic_traffic is gated but filterable — gate on it to surface
high-reach dirs, then unlock to see the numbers:
GET /v1/datasets/product_directory/search?filter=saas+organic_traffic>=50000&limit=15
# → small set of high-traffic dirs. Unlock the user's picks to reveal traffic + how to submit.
User: "Directories for our fintech app." / "design-tool listing sites."
Combine a keyword (matched against the niche tag) with the industry
refiner, or just lead with the keyword:
GET /v1/datasets/product_directory/search?filter=fintech&limit=15
GET /v1/datasets/product_directory/search?filter=design+dr>=50&limit=15
If a keyword over-narrows, drop it and use industry: (e.g.
industry:software_saas, industry:fintech) plus dr>=.
User: "Where do I get our new dev tool in front of developers and pick up backlinks?"
POST /v1/datasets/product_directory/translate-intent
{ "intent": "directories to list a developer tool for backlinks and traffic" }
# → {filter, normalized, count}. Sanity-check the count, then search.
User has a shortlist and wants to actually submit:
# Present briefs ranked by dr (free). "Unlocking 6 = 60 credits, 30-day TTL —
# this reveals each one's submission note (how to submit, backlink yes/no) and traffic."
POST /v1/datasets/product_directory/unlocks
{ "apexes": ["producthunt.com", "saashub.com", "uneed.best", "..."] }
# → editor_note + organic_traffic + total_visits for each.
The editor_note is the operational payoff — e.g. "Listing doesn't give a
backlink but seeds several other directories; submit via CLI, see …". Surface
it verbatim so the user knows the effort and the SEO return before submitting.
User pastes a list of directory domains:
GET /v1/datasets/product_directory/:apex per domain — free brief with
dr (404 = not in catalog, no charge). Flag misses and rank the hits by dr.POST /unlocks with all of them = 10×N
credits, single atomic charge; reveals submission notes + traffic.find-* agency skill. If they want to find a product
listed somewhere ("best CRM for us"), this dataset can't answer that — it
lists the directories, not their contents.dr is free and briefs are pre-sorted by it — rank and shortlist for
zero credits; spend only to reveal submission notes + traffic.organic_traffic>=10000 narrows the
set even though the value stays hidden until unlock.business_directory). If the user wants to list a restaurant, clinic, or
local service, this isn't it — point them at the branded servicegraph skill.product launch parses as
two AND'd keywords; "product launch" is one phrase.POST /unlocks with 6 apexes either charges (up to) 60
credits or leaves balance untouched on 402. Plan the batch.was_cached:true).JSON envelope: {"error": {"code": "...", "message": "..."}}.
| Status | Code | What to do |
|---|---|---|
| 400 | filter_parse_error | position included; fix and re-validate with /check. |
| 400 | kind_in_filter | Strip any kind: from filter — URL is authoritative. |
| 400 | field_not_in_dataset | Field isn't allowed on product_directory; drop it. |
| 400 | invalid_apex | Re-normalize to apex. |
| 401 | unauthorized / invalid_audience | Re-prompt for a fresh vk_…. |
| 402 | insufficient_credits | needed and balance in payload; nothing charged. |
| 404 | not_found / not_in_dataset | Apex isn't in this dataset. Skip; not charged. |
| 429 | rate_limited | Honor Retry-After. |
User: "We're launching our B2B SaaS in two weeks. Find the highest-authority directories to submit to for backlinks, and tell me how to submit to the top five."
# 1. Discover (once per session)
GET /v1/datasets/product_directory/fields?include_values=1
# 2. Validate + scope (free)
GET /v1/datasets/product_directory/check?filter=saas+dr>=60
# 3. Search briefs (free) — already sorted by dr desc
GET /v1/datasets/product_directory/search?filter=saas+dr>=60&limit=20
# → present ranked by dr; note which look like launch platforms vs review sites
# 4. User picks 5. "Unlocking 5 = 50 credits, 30-day TTL — reveals each one's
# submission note (how to submit + backlink yes/no) and traffic."
# 5. Atomic unlock (charges 50 credits)
POST /v1/datasets/product_directory/unlocks
{ "apexes": ["saashub.com", "saasworthy.com", "producthunt.com", "uneed.best", "financesonline.com"] }
# 6. Surface each editor_note verbatim + traffic so the user can prioritize.