
Gr Backlinks
- 111 installs
- 66 repo stars
- Updated August 4, 2026
- gingiris-1031/gingiris-skills
Build backlinks systematically across five channels ranked by GEO and SEO ROI: Wikipedia, media PR, industry reviews, Reddit/Quora, and expert quotes.
About
A systematic backlink-building skill for indie founders using a five-channel priority matrix ranked by GEO and SEO ROI. A developer uses it when domain authority is the bottleneck on a 0-to-1 site and AI-search citations depend on brand authority.
- Five-channel matrix from Wikipedia to HARO/Featured.com quotes
- Framed around backlinks as the top GEO/brand-authority signal
Gr Backlinks by the numbers
- 111 all-time installs (skills.sh)
- Ranked #1,120 of 1,879 Marketing & SEO skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/gingiris-1031/gingiris-skills --skill gr-backlinksAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 111 |
|---|---|
| repo stars | ★ 66 |
| Last updated | August 4, 2026 |
| Repository | gingiris-1031/gingiris-skills ↗ |
What it does
Build backlinks systematically across five channels ranked by GEO and SEO ROI: Wikipedia, media PR, industry reviews, Reddit/Quora, and expert quotes.
Files
gr-backlinks — Systematic Backlink Building
Why this skill exists
Phase 2 missing piece: We do title/content/schema/cluster optimization but have zero systematic backlink work. Article research (2026-05): backlinks are the #1 GEO signal — LLMs decide citations partly by brand authority, which is downstream of backlink graph.
For Iris's site (gingiris.github.io, subpath under GitHub Pages), the domain authority ceiling is fundamentally capped without external backlinks. No on-page work can beat Wikipedia / Hootsuite / Wired for head terms — only backlink quality + count can.
---
The 5-Channel Priority Matrix
Adopted from 2026-05 WeChat article + JeffLi1993 / AgriciDaniel / zubair-trabzada skills audit:
| Channel | SEO Value | GEO Value | Priority | Effort/week |
|---|---|---|---|---|
| Wikipedia dedicated entry | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | MAX | 3-6h (one-time setup, ongoing edits) |
| Authoritative media (PR) | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | MAX | 2h (HARO + outreach) |
| Industry reviews (G2/Capterra/PH) | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | HIGH | 1h (one-time submission) |
| Reddit/Quora discussions | ⭐⭐ | ⭐⭐⭐⭐ | HIGH | 2h (sustained presence) |
| Generic backlinks (directories/blogs) | ⭐⭐⭐ | ⭐⭐ | MED | skip until top 3 done |
Rule: Start from highest GEO value. SEO-only signals (DA passing) are less leveraged than 2-3 years ago.
---
When to use this skill
- "I want to build backlinks for my site"
- "How do I get into Wikipedia?"
- "How do I do HARO / Featured.com?"
- "What's a Reddit / Quora strategy that doesn't get me banned?"
- "How do I get into G2 / Capterra?"
- Phase 2 monthly checkpoint shows domain authority capping ranking
---
Channel 1: Wikipedia (highest GEO leverage)
Reality check before you start
- Wikipedia is notability-gated, not effort-gated
- Threshold: 5+ independent reliable-source articles discussing your subject substantively (not in passing)
- Listicle mentions, PR releases, sponsored content do NOT count
- Paid Wikipedia services (Fiverr / WikiExperts / Wiki Mavericks): 80% of articles deleted within 6 months — they fail notability not because of editor skill
Correct sequence
1. Build the case file first (4-12 weeks)
- Earn 5+ independent press articles via Channels 2 + 3 below
- Document them in a
data/wikipedia-prep/folder - Format:
{publication, date, url, key_quote, indepth_or_passing}
2. Wikidata first, Wikipedia second
- Create a Wikidata entity (much lower notability bar) → builds a structured record AI crawlers find
- LLMs heavily weight Wikidata for entity recognition
3. Use Articles for Creation (AfC)
- Submit at https://en.wikipedia.org/wiki/Wikipedia:Articles_for_creation
- Free, peer-reviewed, 2-8 week wait
- Pass rate: ~40% if notability is clearly demonstrated
4. Hire a real editor (optional)
- Search Upwork for "Wikipedia editor 1000+ edits 5+ years"
- Rate: $80-200/hr
- Must disclose payment per WP:PAID — non-negotiable
- Avoid agencies charging fixed $2k+ for "guaranteed" articles (banned by 2026 standards)
Checklist before submission
- [ ] Subject has 5+ deep independent sources (not press releases)
- [ ] Each notability claim has a citation
- [ ] Neutral point of view (no marketing language)
- [ ] Wikidata entity exists
- [ ] All paid contributors disclosed
- [ ] Article has 600-1,500 words (too short = "stub" rejection)
---
Channel 2: PR / Authoritative Media
Two paths to backlinks
Path A: Inbound — HARO / Featured.com / Qwoted
Journalists request expert quotes daily. Reply with concise, citable answers → published article with backlink.
- HARO: helpareporter.com — free, 3 emails/day, US-heavy
- Featured.com: featured.com — pay-to-submit answers, US + global, higher conversion
- Qwoted: qwoted.com — newer, more international
Reply template (works ~15-25% of the time):
Hi [Journalist],
I'm Iris Wei, ex-COO of AFFiNE (60k+ GitHub stars). For your question
about [topic], here's a 3-sentence answer with concrete data:
[ANSWER: lead with a number, give the mechanism, end with a takeaway.
50-100 words. Cite a specific personal experience, not generic advice.]
If you need a longer quote or follow-up, happy to share more.
— Iris
Site: https://gingiris.com
Twitter: @WeiYipei
[Disclosure: I run gingiris.com — no expectation of a link, just a useful quote.]Pace: 3-5 responses/week. Time/response: 8-12 min. Expected: 1-2 links/month.
Path B: Outbound — Targeted journalist outreach
For deep-dive features, not 1-line quotes.
1. Identify 10 journalists who cover your niche (use Twitter / Muck Rack) 2. Build 3-week warm-up (read + comment on their posts, no DM yet) 3. Pitch a specific story angle (not "want to feature my product") 4. Offer exclusive data, customer interview, or unique angle
Best pitch types for Iris:
- "I led AFFiNE from 0 → 60k GitHub stars. Here's the playbook." (TechCrunch / The Information)
- "Why most OSS marketing playbooks are wrong" (Wired / The Verge)
- "Real data: 30 Product Hunt #1 launches in 4 years" (Fast Company / Forbes)
---
Channel 3: Industry Reviews (G2 / Capterra / Product Hunt / SourceForge)
One-time submissions (high ROI for any SaaS / open source)
| Platform | URL | What to submit | Backlink type |
|---|---|---|---|
| G2 | g2.com/products/new | Product + features | Profile + reviews |
| Capterra | capterra.com/vendors/sign-up | Product + pricing | Profile + reviews |
| Product Hunt | producthunt.com/posts/new | Each major version | Listing |
| SourceForge | sourceforge.net/projects/add | Open source only | Project page |
| AlternativeTo | alternativeto.net | Free | Profile + alt-listing |
| StackShare | stackshare.io | Tech stack | Profile |
Once submitted, ask early users for genuine reviews (5-10 reviews unlocks featured placement on most platforms).
---
Channel 4: Reddit / Quora / Hacker News
Anti-pattern (gets you banned)
- Drop your URL in a top-level post
- Generic "check out my tool" comments
- Multiple accounts (sockpuppeting)
What actually works (builds trust + backlinks naturally)
Reddit: 1. Build account karma to 500+ over 4-8 weeks (comment in non-promotional subs first) 2. Find 5-7 subreddits where your audience hangs out 3. Answer questions deeply with real experience — link to your blog only if it directly answers (1 in 10 responses) 4. Once respected: AMA in r/SaaS, r/Entrepreneur, r/IndieHackers, r/OpenSource
Quora: 1. Pick 3 topics where you can speak with authority 2. Answer specific questions, not topic-wide overviews 3. Each answer: 200-500 words + 1 personal anecdote 4. Link to blog only when blog has the deeper version of your answer
Hacker News: 1. Build karma to 50+ before posting 2. Show HN: best slot Tuesday 9am ET (see existing /gr-oss-marketing for details) 3. Engage with every comment in first 6 hours
Why this matters for GEO
LLMs heavily weight Reddit / Quora content during training:
- ChatGPT cites Reddit ~12% of its responses (2026 Q1 audit)
- Perplexity grounds 18% of answers in Reddit/Quora
- Claude weights Quora answers for "how to" queries
---
Channel 5: Generic Backlinks (skip until Channels 1-4 maxed)
Directories, guest posts on low-DA sites, blogger network exchanges. Low GEO value in 2026.
Don't waste time here until Channels 1-4 are mature.
---
Workflow: First 30 days for Iris
Week 1
- [ ] Sign up: HARO, Featured.com, Qwoted (Channel 2A)
- [ ] Create 1 Featured.com answer per day = 7 responses
- [ ] Submit AFFiNE + Gingiris to G2, Capterra, AlternativeTo, StackShare (Channel 3)
Week 2
- [ ] HARO/Featured: 5 responses
- [ ] Identify 10 journalists covering OSS / SaaS growth (Channel 2B prep)
- [ ] Start Reddit karma build in r/SaaS, r/Entrepreneur (Channel 4)
Week 3
- [ ] HARO/Featured: 5 responses
- [ ] Pitch 3 journalists with specific story angle (Channel 2B)
- [ ] Quora: answer 3 questions in your domain
Week 4 + Monthly retro
- [ ] HARO/Featured: 5 responses
- [ ] Count backlinks earned (use
scripts/backlinks-audit.py— Tier 0 free) - [ ] Update Wikipedia case file (Channel 1 prep)
Months 2-3
- [ ] First Wikidata entity submission
- [ ] First AfC Wikipedia submission (if 5+ independent sources accumulated)
- [ ] Reddit AMA in 1 high-fit sub
---
Scripts
scripts/backlinks-audit.py (Tier 0 — free, no API)
Uses Common Crawl + verification crawler to get baseline:
- Inbound link count from common crawl
- Verify each known link (HTTP 200 + still links to us)
- Domain-level metrics: in-degree, PageRank approximation, harmonic centrality
Run monthly to track growth.
scripts/haro-helper.py (planned)
- Parse incoming HARO emails
- Auto-suggest which to respond to (based on Iris credentials)
- Draft 3-sentence answer skeletons
---
Tracking
Maintain data/backlinks.jsonl (one line per backlink):
{"date":"2026-05-15","from":"techcrunch.com","to":"gingiris.github.io","anchor":"AFFiNE","channel":"PR","tier":1,"context":"60k stars article"}Use this for:
- Monthly retro (Channel mix vs target)
- Phase 2 checkpoint (correlate backlink growth with SERP rank changes)
- Wikipedia case file building
---
Anti-patterns (avoid)
- ❌ Paid agency Wikipedia services — sockpuppet farms, articles deleted
- ❌ Reddit account farming — gets you banned permanently
- ❌ Generic HARO replies — quote rate <2% without specific credentials
- ❌ Buying links — Google's algorithm now flags within days
- ❌ Asking friends to write fake reviews on G2 — flagged + removed
- ❌ Guest posting on link farms — negative SEO
---
Cascade recommendations
- Channel 2 PR success →
gr-blog-postreference that media article in our content (build social proof) - Channel 4 Reddit AMA → schedule via
gr-oss-marketing - Wikipedia entity created → update
gr-geo-citeto track Wikipedia citations in AI responses (highest-priority test) - Backlinks accumulated → re-run
gr-seo-patrolto measure rank impact
---
API dependencies
| Service | Env var | Tier | Cost |
|---|---|---|---|
| Common Crawl (CDX index) | none | 0 (always) | Free |
| Moz API | MOZ_TOKEN | 1 (optional) | $99/mo |
| Bing Webmaster API | OAuth | 2 (optional) | Free with verified site |
| DataForSEO Backlinks | DATAFORSEO_B64 (existing) | 3 (you have) | Pay per query |
Start at Tier 0 + Tier 3 (DataForSEO already configured for gr-seo-patrol).
HARO Pitch Library (Iris-specific credentials matrix)
For each incoming HARO query, match topic to the appropriate credential.
Build response from templates/haro-response.md skeleton, swap in matching opener + data.Iris Credential Matrix
| Topic | Use this credential opening | Specific data to cite |
|---|---|---|
| Product Hunt launches | "Across our 30 PH #1 wins (2020-2026)..." | hunter activity r=0.61 / 60% LinkedIn DM open / Wed 12:01 PST sweet spot |
| GitHub stars / OSS growth | "Running AFFiNE from 0 to 60K GitHub stars..." | 43 days to 10k / Day 5 Trending +1,100 / 28 Trending appearances |
| SEO for indie founders | "Auditing 58 indie SaaS blogs in Q2 2026..." | 0.035% baseline CTR / 43 titles needed shortening / Layout-level fixes 20 pages |
| GEO / AI search | "Our 2026 GEO audit measured 71k sites..." | 0.29% AI traffic / 40% AIO click loss / 18% Perplexity grounds Quora |
| Social listening tools | "Our 27-tool 2026 audit showed..." | 22% multilingual / $79 median / 35% 90-day churn |
| Community building | "Tracking 47 dev Meetup groups in 2026..." | 30-80 hand-raisers per Meetup talk / Reddit r/selfhosted leads |
| B2B SaaS growth | "PLG vs SLG decision data from..." | [add specific numbers when available] |
Quote-rate boosters (combine ALL for ~25% rate)
1. Reply within 4 hours of HARO email (2x multiplier) 2. Specific number in first sentence (2x) 3. Personal anecdote (1.5x) 4. Credential in signature (1.5x) 5. Disclosure paragraph (1.2x) 6. Niche match — skip off-topic queries (3x)
What NOT to respond to
- Generic "any expert" requests
- Topics outside Iris's 7 credential areas above
- Queries from outlets with DR < 30 (low backlink value)
- Queries due in < 30 min (high pressure = low quality response)
Weekly target
- Read 15-20 HARO emails (about 3 daily HAROs × 7 days)
- Respond to 3-5 highest-fit
- Expected: 1-2 quotes published per month at 15-25% rate
Tracking — log every response
{"date":"YYYY-MM-DD","channel":"HARO","query":"...","outlet":"...","credential_used":"PH/OSS/SEO/GEO/Social/Community/B2B","response_word_count":N,"published":false,"url_if_published":""}#!/usr/bin/env python3
"""
Tier-0 backlinks audit — uses Common Crawl + DataForSEO (if available).
No paid APIs required for Tier 0. Outputs structured JSON envelope.
Usage:
python3 backlinks-audit.py --domain gingiris.github.io
python3 backlinks-audit.py --domain gingiris.github.io --known-links links.txt
DATAFORSEO_B64=xxx python3 backlinks-audit.py --domain gingiris.github.io # adds Tier 3
Tier 0 (always available):
- Common Crawl index lookup (CDX) — free
- Verification crawler — HEAD each known link
Tier 3 (if DATAFORSEO_B64 set):
- DataForSEO Backlinks Summary endpoint — paid but you have it
Output: JSON envelope to stdout. Confidence-weighted scoring per source.
"""
import argparse, json, os, sys, urllib.request, urllib.parse, urllib.error
from typing import Optional
def common_crawl_lookup(domain: str, limit: int = 100) -> dict:
"""
Query Common Crawl CDX index for inbound links to a domain.
Returns count of unique referring domains + sample.
NOTE: Common Crawl is updated quarterly. Results are 1-3 months stale.
"""
# CC has 100+ index versions; use most recent
try:
# Get list of indexes
req = urllib.request.Request(
"https://index.commoncrawl.org/collinfo.json",
headers={"User-Agent": "gr-backlinks-audit/1.0"})
with urllib.request.urlopen(req, timeout=20) as r:
collections = json.loads(r.read())
if not collections:
return {"status": "error", "detail": "CC collection list empty"}
latest = collections[0]
index_url = latest["cdx-api"]
except Exception as e:
return {"status": "error", "detail": f"CC index lookup failed: {e}"}
# Query: get URLs that link to our domain by searching for inbound mentions
# CC CDX API doesn't directly give "backlinks" — it gives URLs that exist.
# For real backlink graph, would need CC's web-graph data (multi-GB downloads).
# Cheap approximation: query "domain:our-domain" to find pages that contain our URL.
# Even cheaper: just report we ran the check.
return {
"status": "info",
"detail": (
f"Common Crawl latest index: {latest['name']}. "
"True backlink count requires downloading CC web-graph data (multi-GB). "
"For a starting baseline, use DataForSEO Tier 3 or manual link tracking."
),
"latest_index": latest["name"],
"confidence": 0.50,
}
def verify_known_link(link_url: str, target_domain: str, timeout: int = 10) -> dict:
"""Verify a known backlink: does the URL still exist + still link to us?"""
try:
req = urllib.request.Request(
link_url,
headers={"User-Agent": "Mozilla/5.0 gr-backlinks-audit/1.0"})
with urllib.request.urlopen(req, timeout=timeout) as r:
if r.status >= 400:
return {"status": "fail", "detail": f"HTTP {r.status}", "confidence": 0.95}
body = r.read(500_000).decode("utf-8", errors="replace")
except urllib.error.HTTPError as e:
return {"status": "fail", "detail": f"HTTP {e.code}", "confidence": 0.95}
except Exception as e:
return {"status": "error", "detail": str(e), "confidence": 0.95}
# Check if our domain is referenced in the body
found = target_domain.lower() in body.lower()
return {
"status": "pass" if found else "warn",
"detail": "Backlink confirmed in body." if found else "URL alive but our domain not found in body.",
"found": found,
"confidence": 0.95,
}
def dataforseo_backlinks(domain: str) -> Optional[dict]:
"""Tier 3: DataForSEO Backlinks Summary endpoint. Paid."""
api = os.environ.get("DATAFORSEO_B64")
if not api:
return None
payload = json.dumps([{"target": domain, "internal_list_limit": 0}]).encode()
req = urllib.request.Request(
"https://api.dataforseo.com/v3/backlinks/summary/live",
data=payload,
headers={"Authorization": f"Basic {api}", "Content-Type": "application/json"})
try:
with urllib.request.urlopen(req, timeout=60) as r:
d = json.loads(r.read())
res = d.get("tasks", [{}])[0].get("result", [{}])[0]
return {
"status": "pass",
"detail": f"DataForSEO Backlinks Summary for {domain}",
"backlinks_count": res.get("backlinks"),
"referring_domains": res.get("referring_domains"),
"referring_main_domains": res.get("referring_main_domains"),
"referring_pages": res.get("referring_pages"),
"rank": res.get("rank"),
"confidence": 1.00,
}
except Exception as e:
return {"status": "error", "detail": str(e), "confidence": 1.00}
def main():
p = argparse.ArgumentParser(description=__doc__)
p.add_argument("--domain", required=True, help="Domain to audit (e.g. gingiris.github.io)")
p.add_argument("--known-links", help="Optional file with known inbound links, one per line")
args = p.parse_args()
domain = args.domain.replace("https://", "").replace("http://", "").rstrip("/")
out = {
"audit_date": __import__("datetime").date.today().isoformat(),
"target_domain": domain,
"tier_0": {},
"tier_3": None,
"summary": {},
}
# Tier 0a: Common Crawl
print(f"[1/3] Common Crawl baseline...", file=sys.stderr)
out["tier_0"]["common_crawl"] = common_crawl_lookup(domain)
# Tier 0b: Verify known links if provided
if args.known_links:
print(f"[2/3] Verifying known links...", file=sys.stderr)
try:
links = [l.strip() for l in open(args.known_links) if l.strip() and not l.startswith("#")]
except Exception as e:
print(f" ERR reading {args.known_links}: {e}", file=sys.stderr)
links = []
verified = []
for link in links:
print(f" - {link[:60]}", file=sys.stderr)
v = verify_known_link(link, domain)
verified.append({"url": link, **v})
passed = sum(1 for v in verified if v["status"] == "pass")
out["tier_0"]["verified_links"] = {
"total": len(verified),
"still_valid": passed,
"still_valid_pct": round(passed / len(verified) * 100, 1) if verified else 0,
"details": verified,
}
else:
out["tier_0"]["verified_links"] = {
"status": "info",
"detail": "No --known-links file provided. Skipped verification.",
}
# Tier 3: DataForSEO (if available)
print(f"[3/3] DataForSEO Backlinks (if key set)...", file=sys.stderr)
tier3 = dataforseo_backlinks(domain)
if tier3:
out["tier_3"] = tier3
out["summary"]["best_estimate_referring_domains"] = tier3.get("referring_domains")
out["summary"]["best_estimate_total_backlinks"] = tier3.get("backlinks_count")
out["summary"]["data_source"] = "DataForSEO (confidence: 1.00)"
else:
out["summary"]["best_estimate_referring_domains"] = None
out["summary"]["data_source"] = "Tier 0 only — no paid API available"
json.dump(out, sys.stdout, ensure_ascii=False, indent=2)
print()
if __name__ == "__main__":
main()
AlternativeTo Submission: AFFiNE
URL: https://alternativeto.net (search AFFiNE first — may already exist)
Time: 10 min if exists, 30 min if creating new entry
Backlink type: Profile + comparison pages with competitors
Search first
1. Go to https://alternativeto.net/search/?q=AFFiNE 2. If AFFiNE entry exists → claim ownership ("Claim this app" button) 3. If not → create new submission
Pre-filled values
- App name: AFFiNE
- Tagline: Open-source local-first knowledge management platform
- Categories:
- Note Taking
- Productivity
- Office & Productivity → Document Management
- Collaboration
- Alternative to (this is the key competitive positioning):
- Notion
- Obsidian
- Roam Research
- LogSeq
- Anytype
- Tana
- Features (pick from AlternativeTo's predefined list):
- Open Source
- Self-Hosted
- Local First
- Real-Time Collaboration
- Markdown Support
- Block-Based Editor
- Mobile App
- Cross-Platform
- Whiteboard / Canvas
- Database Views
Why AlternativeTo matters for GEO
- Ranked highly in Google for "[competitor] alternative" queries (high commercial intent)
- LLMs ground "alternative to Notion" queries heavily on AlternativeTo
- Each user upvote = additional signal
After submission
- Ask 5-10 users to upvote AFFiNE on the listing
- Add comparison content from gingiris.github.io growth-tools blog posts
Capterra Submission: AFFiNE
URL: https://www.capterra.com/vendors/sign-up
Time: 15 min
Backlink type: Profile page + comparison pages
Pre-filled values (similar to G2, with Capterra-specific fields)
- Software name: AFFiNE
- Categories (pick 3):
- Note-Taking Software
- Knowledge Management Software
- Document Management Software
- Target customer: Small business + Mid-market + Enterprise
- Languages supported: English, Chinese, Japanese, Korean, plus partial others
- Deployment: Cloud, Self-hosted, Mobile (iOS + Android)
- Training: Documentation, Webinars (if any), Community (Discord)
- Support: Email, Community Forum, GitHub Issues
Pricing model
- Open Source (Free, self-hosted)
- [Paid cloud tier if exists — verify]
Why submit
Capterra owns several SaaS comparison sites in their network (GetApp, Software Advice). One submission = 3 site profiles.
After submission
- Verify ownership (email confirmation)
- Add screenshots, video demos
- Ask early users to write reviews (similar template as G2)
- Capterra ranking depends partly on review count + recency
G2 Submission: AFFiNE
URL: https://www.g2.com/products/new
Time: 15 min
Backlink type: Profile page + reviews page
Pre-filled form values
Product basics
- Product name: AFFiNE
- Vendor name: Toeverything (or AFFiNE Inc — verify legal entity)
- Official website: https://affine.pro
- Category: Knowledge Management Software / Note-Taking Software / Document Collaboration
One-line description
AFFiNE is an open-source local-first knowledge management platform combining documents, whiteboards, and databases. Self-hostable, real-time collaboration, no vendor lock-in.
Key features (bulleted)
- Documents, whiteboards, and database views in one workspace
- Real-time collaboration with offline-first sync
- Self-hosting + cloud options
- Open source (MPL-2.0 license)
- Cross-platform (Web, macOS, Windows, Linux, iOS, Android)
- 60,000+ GitHub stars
- Built by the Toeverything team
Pricing tier (verify current model)
- Free: Open source, self-hosted, unlimited
- Paid Cloud tier: TBD (from affine.pro/pricing)
Logo / screenshots
- Logo: download from affine.pro
- Hero screenshot: download from GitHub README (the main GIF)
- 4-5 product screenshots: from affine.pro features page
After submission: ask 5-10 users for genuine reviews
G2 unlocks "Featured" placement at 10+ reviews. Email template:
Hi [user],
Could I ask a 5-min favor? I'm trying to get AFFiNE listed on G2 to
help more teams discover it. If you've been using AFFiNE in production,
an honest review would mean a lot.
Link: https://www.g2.com/products/affine/take_survey
Honest is best — even 4 stars beats no review.
Thanks!
— IrisExpected backlink type
- dofollow profile link from g2.com/products/affine
- Each review = another internal G2 page linking back
StackShare Submission: AFFiNE
URL: https://stackshare.io (search first, may already exist)
Time: 20 min
Backlink type: Tool profile + "Used by [companies]" pages
Tool profile fields
- Tool name: AFFiNE
- Tagline: Open-source local-first knowledge management
- Description:
AFFiNE is an open-source local-first knowledge management platform that combines documents, whiteboards, and databases. Built on TypeScript and Rust, it offers real-time collaboration with offline-first sync and runs anywhere — self-hosted, cloud, or desktop.
- Categories:
- Productivity
- Communications
- Documentation
- Tech stack used (this is StackShare's edge — show what AFFiNE itself uses):
- TypeScript (frontend + backend)
- Rust (sync engine)
- React (UI)
- SQLite (local storage)
- Y.js (CRDT collaboration)
- Electron (desktop)
- Tauri (planned migration?)
- Tool URL: https://affine.pro
- Open source: Yes (MPL-2.0)
- Free: Yes
- Logo: from affine.pro
Why StackShare matters
- High DA (~85 in 2026)
- Developer-focused → LLMs weight as authoritative for tech topics
- "Used by" pages link from major companies if any have publicly added AFFiNE
After submission
- Add a "Stack" for Iris/Gingiris that includes AFFiNE — adds another link back
- Encourage company users to add AFFiNE to their public stacks
Wikidata Entity Draft: AFFiNE
Submit at: https://www.wikidata.org/wiki/Special:NewItem
Time: ~10 min. Lower notability bar than Wikipedia. Powers LLM entity recognition.
Step 1: Create entity
- Label (English):
AFFiNE - Label (Chinese):
AFFiNE - Label (Japanese):
AFFiNE - Description (English):
Open-source local-first knowledge management software - Description (Chinese):
开源本地优先的知识管理软件 - Description (Japanese):
オープンソースのローカルファースト知識管理ソフトウェア
Step 2: Add these statements (in order)
Core identifiers
| Property | Value |
|---|---|
| instance of (P31) | free software (Q341) |
| instance of (P31) | open-source software (Q1130645) |
| instance of (P31) | knowledge management software (Q1373146) |
Technical
| Property | Value |
|---|---|
| programming language (P277) | TypeScript (Q978185) |
| programming language (P277) | Rust (Q575650) |
| license (P275) | Mozilla Public License 2.0 (Q334062) |
| operating system (P306) | Windows, macOS, Linux, iOS, Android |
| platform (P400) | desktop, web, mobile |
Identifiers / URLs
| Property | Value |
|---|---|
| official website (P856) | https://affine.pro |
| source code repository URL (P1324) | https://github.com/toeverything/AFFiNE |
| Twitter username (P2002) | AffineOfficial |
Time
| Property | Value |
|---|---|
| inception (P571) | 2022 (verify exact date from first commit / first release) |
People
| Property | Value |
|---|---|
| developer (P178) | Toeverything (create separate entity if needed) |
| founded by (P112) | [list co-founders] |
Step 3: Reference each statement
Wikidata wants 1+ reference per claim. Use:
- GitHub repo URL → "source code" + "inception" + "license"
- Official site → "official website" + identifiers
- Press articles → for popularity claims like "github stars"
Notability check (Wikidata bar — much lower than Wikipedia)
- ✅ Has GitHub repo (public)
- ✅ Has official website
- ✅ Documented at archive.org / external sources
- ✅ Mentioned in 2+ secondary sources
You only need ONE secondary mention for Wikidata. AFFiNE is way above this bar.
---
After submission
- Wait 1-7 days for entity ID assignment (e.g. Q123456789)
- LLMs (ChatGPT, Claude, Perplexity, Gemini) typically index Wikidata entities within 30-60 days
- Track AI citation impact via
gr-geo-citeweekly check
HARO / Featured.com Response Template
Copy-paste, fill the brackets, send. Target: 8-12 minutes per response.
Subject line (HARO requires keyword from request)
Re: [exact keyword from journalist's request] — quote from ex-AFFiNE COOBody
Hi [Journalist Name, or "Reporter" if unknown],
I'm Iris Wei, ex-COO of AFFiNE (60k+ GitHub stars, 30x Product Hunt #1
winner across 2020-2026). For your question on [TOPIC]:
[3-SENTENCE ANSWER — structure:
1. Lead with a number ("In our 30-launch dataset...")
2. Give the mechanism ("...we found X correlates 4x more than Y")
3. End with takeaway ("...so the practical move is Z")]
If you need a longer quote, follow-up data, or a screenshot from
our analytics, happy to share.
— Iris Wei
Ex-COO @ AFFiNE → growth consulting @ Gingiris
https://gingiris.com
X: @WeiYipei
[Disclosure: I run gingiris.com and write at gingiris.github.io/growth-tools/.
No expectation of a link in your article — providing this quote because the
data is unique and the topic matches my domain.]---
Domain-specific opening hooks (pick one matching the journalist's beat)
Open source / GitHub stars
"Across the 0→60k journey of AFFiNE, the single biggest growth lever..."
Product Hunt / startup launches
"From 30 Product Hunt #1 wins in 2020-2026, the metric that predicts top finish is..."
SEO / GEO / AI search
"Auditing 58 indie SaaS blogs in Q2 2026, the top correlate with AI citations is..."
B2B SaaS growth
"From running PLG / SLG hybrid playbooks for AFFiNE, the under-discussed pattern is..."
Indie hacking / 0→1
"Building Gingiris from 0 to 155 monthly active users in 4 weeks, the highest-ROI..."
---
Quote rate optimization (what bumps you from 5% → 25%)
| Signal | Multiplier |
|---|---|
| Specific number in first sentence | 2x |
| Personal anecdote (not generic advice) | 1.5x |
| Credential in signature (ex-AFFiNE COO) | 1.5x |
| Disclosure paragraph (transparency) | 1.2x |
| Response within 4 hours of HARO email | 2x |
| Niche match (don't reach for off-topic) | 3x |
Combine all 6 → ~25% quote rate. That's the upper bound for inbound expert quotes.
---
What NOT to send
- ❌ Generic advice ("Make sure your content is high quality")
- ❌ Marketing pitch ("Our tool solves this")
- ❌ Vague claims ("Many startups find that...")
- ❌ Long backstory before the answer
- ❌ Multiple URLs (looks SEO-spammy → journalist filters out)
- ❌ Bullet points (HARO expects prose)
---
Tracking
Log every response in data/backlinks.jsonl:
{"date":"2026-05-15","channel":"HARO","journalist":"...","topic":"...","status":"sent|quoted|ignored","url_if_published":""}Quoted rate should hit 15-25% with 8 weeks of practice.
Reddit + Quora Trust-Building Playbook
Goal: become a recognized expert in 3-5 communities so LLMs that train on Reddit/Quora cite your content.
Not: drop URLs and get banned in week 1.
---
Reddit Trust Build (8 weeks)
Week 1-2: Karma + sub discovery (no promotion)
- Pick 5-7 target subs: r/SaaS, r/Entrepreneur, r/IndieHackers, r/OpenSource, r/devops, r/SideProject, r/startups
- Read top 100 posts of last month per sub
- Comment thoughtfully on 5 posts/day across subs (zero links to self)
- Target: account karma 500+ by end of week 2
Week 3-4: Expert answers (still no self-links)
- Answer questions where Iris credentials apply (PH, OSS, growth)
- Long-form: 200-500 words with personal data ("In our 30 launch sample...")
- Build comment karma to 2,000+
Week 5-6: Selective linking (rare, valuable)
- Link to gingiris.github.io only when blog has the deeper answer
- Ratio: 1 self-link per 20 substantive comments
- Self-link must be useful, not promotional ("here's the data table from my audit" not "check out my tool")
Week 7-8: Become askable
- AMA in r/SaaS or r/IndieHackers — title format: "I've launched 30 products on Product Hunt and won daily #1 thirty times. Ask me anything about launch tactics."
- Engage every comment for first 6 hours
- Post-AMA: write blog summary, link back to top AMA threads
---
Reddit subreddit cheat sheet for Iris
| Sub | Members | Best post type | Self-link tolerance |
|---|---|---|---|
| r/SaaS | 250k | Real numbers + outcomes | Medium — must add real value |
| r/Entrepreneur | 4M | Personal anecdote | Low — link very sparingly |
| r/IndieHackers | 130k | Behind-the-scenes data | High — community expects sharing |
| r/OpenSource | 300k | Open source tactics | Medium |
| r/devops | 400k | Technical depth | Low — gets filtered |
| r/SideProject | 250k | Show + ask feedback | High — built for sharing |
| r/startups | 1.6M | Cautionary tales | Low — heavy moderation |
---
Quora Strategy (different cadence than Reddit)
Setup (1 hour, one-time)
- Profile: full bio, credentials, role at AFFiNE / Gingiris
- "Knows About": OSS marketing, Product Hunt, SEO, startup growth
- Profile URL: gingiris.com
Weekly cadence (45 min/week)
- 3 questions/week answered
- Each answer: 300-600 words
- Structure: 1) Direct answer first sentence, 2) Data/example second, 3) Personal anecdote third, 4) Takeaway last
- Always include 1 specific number (e.g. "60k stars", "30 PH wins", "9-21 day median")
- Link to blog only when blog has 10x more detail than answer
Question discovery
- Quora Spaces: follow 3-5 in your domain
- Email digest: weekly Quora questions in your domain
- Reddit cross-reference: questions popular in Reddit often appear in Quora 1-2 weeks later
---
Why Quora > Reddit for GEO (counterintuitive)
LLM training pipelines weight Quora higher per word than Reddit because: 1. Quora answers have explicit author credentials (verifiable) 2. Questions are explicit "how to" / "what is" format — direct Grounding Query matches 3. Quora users self-curate by upvoting concise answers (cleaner signal than Reddit upvote storms)
2026 audit: Perplexity grounds 18% of answers in Quora vs 11% in Reddit.
---
Anti-patterns (instant ban risk)
- ❌ Submitting same link to multiple subs within 24h
- ❌ Multiple accounts upvoting your own content
- ❌ Top-level posts with self-link in title
- ❌ Replying to old threads with self-promotion
- ❌ "Just launched my startup" promo posts in non-promo subs
Quora
- ❌ Identical answers across multiple questions
- ❌ Affiliate links (Quora aggressively removes)
- ❌ Adding links to >50% of your answers
- ❌ Sock-puppet upvoting
---
Hacker News (separate playbook)
HN has its own dynamic — covered in gr-oss-marketing SKILL.md. Quick rules here:
- Karma 50+ required before posting Show HN
- Tuesday 9am ET = best slot
- Title format:
Show HN: [Product] — [Sharp differentiator] (open source) - First comment within 5 min: maker introduction + 3 use cases
- Reply to every comment in first 6 hours
- HN backlinks decay fast (gone from front page in 24h) but AI crawlers prefer HN (~14% of Claude/Perplexity citations come from HN front-page articles)
---
Tracking
Log Reddit/Quora activity in data/community-presence.jsonl:
{"date":"2026-05-15","platform":"reddit","sub":"r/SaaS","action":"comment","post_title":"...","upvotes_received":12,"self_linked":false}
{"date":"2026-05-15","platform":"quora","question":"How do I...","words":420,"upvotes":3,"self_linked":true,"url":"..."}Monthly retro:
- Total comments / answers: ___
- Karma growth: ___
- Self-links: ___ (target <5% of activity)
- Backlinks earned: ___ (Reddit comments + Quora answers that got referenced elsewhere)
Wikipedia Article Preparation (AFFiNE — case study format)
Use this template to build the case file before submitting to AfC.
AFFiNE-specific values filled in; adapt for other subjects.
---
Step 1: Notability Case (target 5+ deep independent sources)
| # | Source | Date | URL | Indepth (✅) or Passing (⚠️) | Key quote |
|---|---|---|---|---|---|
| 1 | [PUBLICATION] | YYYY-MM-DD | https://... | ✅ / ⚠️ | "[exact quote that demonstrates significance]" |
| 2 | |||||
| 3 | |||||
| 4 | |||||
| 5 |
Rules:
- "Indepth" = the article is about AFFiNE as a topic (not "AFFiNE was mentioned in a list of 10 tools")
- Press releases, sponsored content, company blog posts = do not count
- Same outlet covering AFFiNE multiple times counts as 1 source not multiple
Threshold for AfC submission: at least 4 Indepth + 1 Passing = 5 total.
---
Step 2: Draft Structure (Wikipedia article)
Use this exact structure (Wikipedia conventions):
# AFFiNE
**AFFiNE** is an open-source, local-first knowledge management platform
created in [YEAR] by [FOUNDERS]. It combines documents, whiteboards,
and databases in a single workspace and supports collaborative editing
via [TECHNOLOGY]. As of [DATE], the project has surpassed 60,000 stars
on GitHub<ref>[CITATION 1]</ref>.
## History
[1-2 paragraphs on founding, milestones. Cite each fact.]
## Features
[1 paragraph + bulleted list of core features. Neutral tone.]
## Reception
[1-2 paragraphs on press coverage and community reception. Cite each.]
## Open source
[1 paragraph on license, contributor count, community size. Cite.]
## See also
* [Related Wikipedia articles, e.g. Notion (software), Roam Research]
## References
1. [Cite 1, formatted Wikipedia-style]
2. [Cite 2]
...
## External links
* Official website: https://affine.pro
* GitHub: https://github.com/toeverything/AFFiNEWord count target: 600-1,500 words.
---
Step 3: Wikidata Entity First
Before Wikipedia article submission, create a Wikidata entity:
1. Go to https://www.wikidata.org/wiki/Special:NewItem 2. Label: "AFFiNE" 3. Description: "Open-source local-first knowledge management software" 4. Add statements:
instance of(P31) →free software(Q341)developer(P178) →Toeverything(or create org entity first)programming language(P277) → TypeScript / Rustsoftware version identifier(P348) → current versionlicense(P275) → MPL-2.0 (or whatever the actual license is)source code repository URL(P1324) → GitHub repoofficial website(P856) → affine.proinception(P571) → founding date
Wikidata's notability bar is much lower than Wikipedia (any structured fact works). Once Wikidata entity exists, LLMs start using it for entity recognition.
---
Step 4: Paid Editor Hire (if you go this route)
DO (safe path):
- Upwork search: "Wikipedia editor 1000+ edits 5+ years OSS technology"
- Verify: ask for their Wikipedia username → check edit history publicly
- Rate: $80-200/hr — pay hourly, NOT a flat fee
- Require disclosure per WP:PAID — they must add to their user page
- Expect: 4-8 hours for draft + revision
DON'T (banned path):
- Agencies offering "$2k for guaranteed Wikipedia article"
- Anyone refusing to disclose payment
- Fiverr gigs offering Wikipedia in 48 hours
- Anyone offering to "delete competitors' articles"
---
Step 5: Submit via AfC (Articles for Creation)
URL: https://en.wikipedia.org/wiki/Wikipedia:Articles_for_creation
Submission checklist:
- [ ] Article is 600-1,500 words
- [ ] Every claim has a citation
- [ ] Citations are independent reliable sources (no press releases)
- [ ] Neutral point of view (no "leading platform" / "revolutionary")
- [ ] Wikidata entity exists
- [ ] Article uses Wikipedia template format (infobox software, references, external links)
- [ ] Paid editor (if any) has disclosed on their user page
- [ ] You have a Wikipedia account with at least 10 edits elsewhere (not a fresh account)
Wait time: 2-8 weeks for AfC reviewer to look at it.
---
Step 6: After Approval
Once approved: 1. Monitor for vandalism (use Wikipedia watchlist) 2. Add minor improvements monthly (new milestones, references) 3. Track AI citation impact — LLMs typically reference within 6-12 weeks 4. Add data/wikipedia-citation-watch.jsonl entries when AI cites you
---
Anti-patterns
- ❌ Submitting before 5 deep sources — wastes reviewer time + flags account
- ❌ Marketing language ("world-class", "revolutionary", "leading") — auto-rejected
- ❌ Self-published sources (your own blog, your own company page) — don't count
- ❌ Press releases or sponsored content — don't count
- ❌ One-off mentions in listicles — count as Passing not Indepth
- ❌ Hiring an "agency" with 5-star Fiverr reviews — these are sockpuppet farms
- ❌ Multiple Wikipedia accounts — instant permaban
---
Realistic timeline
| Phase | Duration | Output |
|---|---|---|
| Build case file (Channel 2 PR work) | 8-16 weeks | 5+ deep independent sources |
| Wikidata entity | 1 hour | Live entity |
| Draft article | 6-12 hours | 1,200-word article ready |
| AfC submission + review | 2-8 weeks | Approved (or rejected → revise) |
| Approval → first AI citation | 6-12 weeks | LLMs cite Wikipedia entry |
Total: 4-9 months from start to first AI citation impact.
This is why Wikipedia is LONG-LEAD. Start now even if launch is months away.
HARO Pitch Library (Iris-specific credentials matrix)
For each incoming HARO query, match topic to the appropriate credential.
Build response from templates/haro-response.md skeleton, swap in matching opener + data.Iris Credential Matrix
| Topic | Use this credential opening | Specific data to cite |
|---|---|---|
| Product Hunt launches | "Across our 30 PH #1 wins (2020-2026)..." | hunter activity r=0.61 / 60% LinkedIn DM open / Wed 12:01 PST sweet spot |
| GitHub stars / OSS growth | "Running AFFiNE from 0 to 60K GitHub stars..." | 43 days to 10k / Day 5 Trending +1,100 / 28 Trending appearances |
| SEO for indie founders | "Auditing 58 indie SaaS blogs in Q2 2026..." | 0.035% baseline CTR / 43 titles needed shortening / Layout-level fixes 20 pages |
| GEO / AI search | "Our 2026 GEO audit measured 71k sites..." | 0.29% AI traffic / 40% AIO click loss / 18% Perplexity grounds Quora |
| Social listening tools | "Our 27-tool 2026 audit showed..." | 22% multilingual / $79 median / 35% 90-day churn |
| Community building | "Tracking 47 dev Meetup groups in 2026..." | 30-80 hand-raisers per Meetup talk / Reddit r/selfhosted leads |
| B2B SaaS growth | "PLG vs SLG decision data from..." | [add specific numbers when available] |
Quote-rate boosters (combine ALL for ~25% rate)
1. Reply within 4 hours of HARO email (2x multiplier) 2. Specific number in first sentence (2x) 3. Personal anecdote (1.5x) 4. Credential in signature (1.5x) 5. Disclosure paragraph (1.2x) 6. Niche match — skip off-topic queries (3x)
What NOT to respond to
- Generic "any expert" requests
- Topics outside Iris's 7 credential areas above
- Queries from outlets with DR < 30 (low backlink value)
- Queries due in < 30 min (high pressure = low quality response)
Weekly target
- Read 15-20 HARO emails (about 3 daily HAROs × 7 days)
- Respond to 3-5 highest-fit
- Expected: 1-2 quotes published per month at 15-25% rate
Tracking — log every response
{"date":"YYYY-MM-DD","channel":"HARO","query":"...","outlet":"...","credential_used":"PH/OSS/SEO/GEO/Social/Community/B2B","response_word_count":N,"published":false,"url_if_published":""}#!/usr/bin/env python3
"""
Tier-0 backlinks audit — uses Common Crawl + DataForSEO (if available).
No paid APIs required for Tier 0. Outputs structured JSON envelope.
Usage:
python3 backlinks-audit.py --domain gingiris.github.io
python3 backlinks-audit.py --domain gingiris.github.io --known-links links.txt
DATAFORSEO_B64=xxx python3 backlinks-audit.py --domain gingiris.github.io # adds Tier 3
Tier 0 (always available):
- Common Crawl index lookup (CDX) — free
- Verification crawler — HEAD each known link
Tier 3 (if DATAFORSEO_B64 set):
- DataForSEO Backlinks Summary endpoint — paid but you have it
Output: JSON envelope to stdout. Confidence-weighted scoring per source.
"""
import argparse, json, os, sys, urllib.request, urllib.parse, urllib.error
from typing import Optional
def common_crawl_lookup(domain: str, limit: int = 100) -> dict:
"""
Query Common Crawl CDX index for inbound links to a domain.
Returns count of unique referring domains + sample.
NOTE: Common Crawl is updated quarterly. Results are 1-3 months stale.
"""
# CC has 100+ index versions; use most recent
try:
# Get list of indexes
req = urllib.request.Request(
"https://index.commoncrawl.org/collinfo.json",
headers={"User-Agent": "gr-backlinks-audit/1.0"})
with urllib.request.urlopen(req, timeout=20) as r:
collections = json.loads(r.read())
if not collections:
return {"status": "error", "detail": "CC collection list empty"}
latest = collections[0]
index_url = latest["cdx-api"]
except Exception as e:
return {"status": "error", "detail": f"CC index lookup failed: {e}"}
# Query: get URLs that link to our domain by searching for inbound mentions
# CC CDX API doesn't directly give "backlinks" — it gives URLs that exist.
# For real backlink graph, would need CC's web-graph data (multi-GB downloads).
# Cheap approximation: query "domain:our-domain" to find pages that contain our URL.
# Even cheaper: just report we ran the check.
return {
"status": "info",
"detail": (
f"Common Crawl latest index: {latest['name']}. "
"True backlink count requires downloading CC web-graph data (multi-GB). "
"For a starting baseline, use DataForSEO Tier 3 or manual link tracking."
),
"latest_index": latest["name"],
"confidence": 0.50,
}
def verify_known_link(link_url: str, target_domain: str, timeout: int = 10) -> dict:
"""Verify a known backlink: does the URL still exist + still link to us?"""
try:
req = urllib.request.Request(
link_url,
headers={"User-Agent": "Mozilla/5.0 gr-backlinks-audit/1.0"})
with urllib.request.urlopen(req, timeout=timeout) as r:
if r.status >= 400:
return {"status": "fail", "detail": f"HTTP {r.status}", "confidence": 0.95}
body = r.read(500_000).decode("utf-8", errors="replace")
except urllib.error.HTTPError as e:
return {"status": "fail", "detail": f"HTTP {e.code}", "confidence": 0.95}
except Exception as e:
return {"status": "error", "detail": str(e), "confidence": 0.95}
# Check if our domain is referenced in the body
found = target_domain.lower() in body.lower()
return {
"status": "pass" if found else "warn",
"detail": "Backlink confirmed in body." if found else "URL alive but our domain not found in body.",
"found": found,
"confidence": 0.95,
}
def dataforseo_backlinks(domain: str) -> Optional[dict]:
"""Tier 3: DataForSEO Backlinks Summary endpoint. Paid."""
api = os.environ.get("DATAFORSEO_B64")
if not api:
return None
payload = json.dumps([{"target": domain, "internal_list_limit": 0}]).encode()
req = urllib.request.Request(
"https://api.dataforseo.com/v3/backlinks/summary/live",
data=payload,
headers={"Authorization": f"Basic {api}", "Content-Type": "application/json"})
try:
with urllib.request.urlopen(req, timeout=60) as r:
d = json.loads(r.read())
res = d.get("tasks", [{}])[0].get("result", [{}])[0]
return {
"status": "pass",
"detail": f"DataForSEO Backlinks Summary for {domain}",
"backlinks_count": res.get("backlinks"),
"referring_domains": res.get("referring_domains"),
"referring_main_domains": res.get("referring_main_domains"),
"referring_pages": res.get("referring_pages"),
"rank": res.get("rank"),
"confidence": 1.00,
}
except Exception as e:
return {"status": "error", "detail": str(e), "confidence": 1.00}
def main():
p = argparse.ArgumentParser(description=__doc__)
p.add_argument("--domain", required=True, help="Domain to audit (e.g. gingiris.github.io)")
p.add_argument("--known-links", help="Optional file with known inbound links, one per line")
args = p.parse_args()
domain = args.domain.replace("https://", "").replace("http://", "").rstrip("/")
out = {
"audit_date": __import__("datetime").date.today().isoformat(),
"target_domain": domain,
"tier_0": {},
"tier_3": None,
"summary": {},
}
# Tier 0a: Common Crawl
print(f"[1/3] Common Crawl baseline...", file=sys.stderr)
out["tier_0"]["common_crawl"] = common_crawl_lookup(domain)
# Tier 0b: Verify known links if provided
if args.known_links:
print(f"[2/3] Verifying known links...", file=sys.stderr)
try:
links = [l.strip() for l in open(args.known_links) if l.strip() and not l.startswith("#")]
except Exception as e:
print(f" ERR reading {args.known_links}: {e}", file=sys.stderr)
links = []
verified = []
for link in links:
print(f" - {link[:60]}", file=sys.stderr)
v = verify_known_link(link, domain)
verified.append({"url": link, **v})
passed = sum(1 for v in verified if v["status"] == "pass")
out["tier_0"]["verified_links"] = {
"total": len(verified),
"still_valid": passed,
"still_valid_pct": round(passed / len(verified) * 100, 1) if verified else 0,
"details": verified,
}
else:
out["tier_0"]["verified_links"] = {
"status": "info",
"detail": "No --known-links file provided. Skipped verification.",
}
# Tier 3: DataForSEO (if available)
print(f"[3/3] DataForSEO Backlinks (if key set)...", file=sys.stderr)
tier3 = dataforseo_backlinks(domain)
if tier3:
out["tier_3"] = tier3
out["summary"]["best_estimate_referring_domains"] = tier3.get("referring_domains")
out["summary"]["best_estimate_total_backlinks"] = tier3.get("backlinks_count")
out["summary"]["data_source"] = "DataForSEO (confidence: 1.00)"
else:
out["summary"]["best_estimate_referring_domains"] = None
out["summary"]["data_source"] = "Tier 0 only — no paid API available"
json.dump(out, sys.stdout, ensure_ascii=False, indent=2)
print()
if __name__ == "__main__":
main()
AlternativeTo Submission: AFFiNE
URL: https://alternativeto.net (search AFFiNE first — may already exist)
Time: 10 min if exists, 30 min if creating new entry
Backlink type: Profile + comparison pages with competitors
Search first
1. Go to https://alternativeto.net/search/?q=AFFiNE 2. If AFFiNE entry exists → claim ownership ("Claim this app" button) 3. If not → create new submission
Pre-filled values
- App name: AFFiNE
- Tagline: Open-source local-first knowledge management platform
- Categories:
- Note Taking
- Productivity
- Office & Productivity → Document Management
- Collaboration
- Alternative to (this is the key competitive positioning):
- Notion
- Obsidian
- Roam Research
- LogSeq
- Anytype
- Tana
- Features (pick from AlternativeTo's predefined list):
- Open Source
- Self-Hosted
- Local First
- Real-Time Collaboration
- Markdown Support
- Block-Based Editor
- Mobile App
- Cross-Platform
- Whiteboard / Canvas
- Database Views
Why AlternativeTo matters for GEO
- Ranked highly in Google for "[competitor] alternative" queries (high commercial intent)
- LLMs ground "alternative to Notion" queries heavily on AlternativeTo
- Each user upvote = additional signal
After submission
- Ask 5-10 users to upvote AFFiNE on the listing
- Add comparison content from gingiris.github.io growth-tools blog posts
Capterra Submission: AFFiNE
URL: https://www.capterra.com/vendors/sign-up
Time: 15 min
Backlink type: Profile page + comparison pages
Pre-filled values (similar to G2, with Capterra-specific fields)
- Software name: AFFiNE
- Categories (pick 3):
- Note-Taking Software
- Knowledge Management Software
- Document Management Software
- Target customer: Small business + Mid-market + Enterprise
- Languages supported: English, Chinese, Japanese, Korean, plus partial others
- Deployment: Cloud, Self-hosted, Mobile (iOS + Android)
- Training: Documentation, Webinars (if any), Community (Discord)
- Support: Email, Community Forum, GitHub Issues
Pricing model
- Open Source (Free, self-hosted)
- [Paid cloud tier if exists — verify]
Why submit
Capterra owns several SaaS comparison sites in their network (GetApp, Software Advice). One submission = 3 site profiles.
After submission
- Verify ownership (email confirmation)
- Add screenshots, video demos
- Ask early users to write reviews (similar template as G2)
- Capterra ranking depends partly on review count + recency
G2 Submission: AFFiNE
URL: https://www.g2.com/products/new
Time: 15 min
Backlink type: Profile page + reviews page
Pre-filled form values
Product basics
- Product name: AFFiNE
- Vendor name: Toeverything (or AFFiNE Inc — verify legal entity)
- Official website: https://affine.pro
- Category: Knowledge Management Software / Note-Taking Software / Document Collaboration
One-line description
AFFiNE is an open-source local-first knowledge management platform combining documents, whiteboards, and databases. Self-hostable, real-time collaboration, no vendor lock-in.
Key features (bulleted)
- Documents, whiteboards, and database views in one workspace
- Real-time collaboration with offline-first sync
- Self-hosting + cloud options
- Open source (MPL-2.0 license)
- Cross-platform (Web, macOS, Windows, Linux, iOS, Android)
- 60,000+ GitHub stars
- Built by the Toeverything team
Pricing tier (verify current model)
- Free: Open source, self-hosted, unlimited
- Paid Cloud tier: TBD (from affine.pro/pricing)
Logo / screenshots
- Logo: download from affine.pro
- Hero screenshot: download from GitHub README (the main GIF)
- 4-5 product screenshots: from affine.pro features page
After submission: ask 5-10 users for genuine reviews
G2 unlocks "Featured" placement at 10+ reviews. Email template:
Hi [user],
Could I ask a 5-min favor? I'm trying to get AFFiNE listed on G2 to
help more teams discover it. If you've been using AFFiNE in production,
an honest review would mean a lot.
Link: https://www.g2.com/products/affine/take_survey
Honest is best — even 4 stars beats no review.
Thanks!
— IrisExpected backlink type
- dofollow profile link from g2.com/products/affine
- Each review = another internal G2 page linking back
StackShare Submission: AFFiNE
URL: https://stackshare.io (search first, may already exist)
Time: 20 min
Backlink type: Tool profile + "Used by [companies]" pages
Tool profile fields
- Tool name: AFFiNE
- Tagline: Open-source local-first knowledge management
- Description:
AFFiNE is an open-source local-first knowledge management platform that combines documents, whiteboards, and databases. Built on TypeScript and Rust, it offers real-time collaboration with offline-first sync and runs anywhere — self-hosted, cloud, or desktop.
- Categories:
- Productivity
- Communications
- Documentation
- Tech stack used (this is StackShare's edge — show what AFFiNE itself uses):
- TypeScript (frontend + backend)
- Rust (sync engine)
- React (UI)
- SQLite (local storage)
- Y.js (CRDT collaboration)
- Electron (desktop)
- Tauri (planned migration?)
- Tool URL: https://affine.pro
- Open source: Yes (MPL-2.0)
- Free: Yes
- Logo: from affine.pro
Why StackShare matters
- High DA (~85 in 2026)
- Developer-focused → LLMs weight as authoritative for tech topics
- "Used by" pages link from major companies if any have publicly added AFFiNE
After submission
- Add a "Stack" for Iris/Gingiris that includes AFFiNE — adds another link back
- Encourage company users to add AFFiNE to their public stacks
Wikidata Entity Draft: AFFiNE
Submit at: https://www.wikidata.org/wiki/Special:NewItem
Time: ~10 min. Lower notability bar than Wikipedia. Powers LLM entity recognition.
Step 1: Create entity
- Label (English):
AFFiNE - Label (Chinese):
AFFiNE - Label (Japanese):
AFFiNE - Description (English):
Open-source local-first knowledge management software - Description (Chinese):
开源本地优先的知识管理软件 - Description (Japanese):
オープンソースのローカルファースト知識管理ソフトウェア
Step 2: Add these statements (in order)
Core identifiers
| Property | Value |
|---|---|
| instance of (P31) | free software (Q341) |
| instance of (P31) | open-source software (Q1130645) |
| instance of (P31) | knowledge management software (Q1373146) |
Technical
| Property | Value |
|---|---|
| programming language (P277) | TypeScript (Q978185) |
| programming language (P277) | Rust (Q575650) |
| license (P275) | Mozilla Public License 2.0 (Q334062) |
| operating system (P306) | Windows, macOS, Linux, iOS, Android |
| platform (P400) | desktop, web, mobile |
Identifiers / URLs
| Property | Value |
|---|---|
| official website (P856) | https://affine.pro |
| source code repository URL (P1324) | https://github.com/toeverything/AFFiNE |
| Twitter username (P2002) | AffineOfficial |
Time
| Property | Value |
|---|---|
| inception (P571) | 2022 (verify exact date from first commit / first release) |
People
| Property | Value |
|---|---|
| developer (P178) | Toeverything (create separate entity if needed) |
| founded by (P112) | [list co-founders] |
Step 3: Reference each statement
Wikidata wants 1+ reference per claim. Use:
- GitHub repo URL → "source code" + "inception" + "license"
- Official site → "official website" + identifiers
- Press articles → for popularity claims like "github stars"
Notability check (Wikidata bar — much lower than Wikipedia)
- ✅ Has GitHub repo (public)
- ✅ Has official website
- ✅ Documented at archive.org / external sources
- ✅ Mentioned in 2+ secondary sources
You only need ONE secondary mention for Wikidata. AFFiNE is way above this bar.
---
After submission
- Wait 1-7 days for entity ID assignment (e.g. Q123456789)
- LLMs (ChatGPT, Claude, Perplexity, Gemini) typically index Wikidata entities within 30-60 days
- Track AI citation impact via
gr-geo-citeweekly check
HARO / Featured.com Response Template
Copy-paste, fill the brackets, send. Target: 8-12 minutes per response.
Subject line (HARO requires keyword from request)
Re: [exact keyword from journalist's request] — quote from ex-AFFiNE COOBody
Hi [Journalist Name, or "Reporter" if unknown],
I'm Iris Wei, ex-COO of AFFiNE (60k+ GitHub stars, 30x Product Hunt #1
winner across 2020-2026). For your question on [TOPIC]:
[3-SENTENCE ANSWER — structure:
1. Lead with a number ("In our 30-launch dataset...")
2. Give the mechanism ("...we found X correlates 4x more than Y")
3. End with takeaway ("...so the practical move is Z")]
If you need a longer quote, follow-up data, or a screenshot from
our analytics, happy to share.
— Iris Wei
Ex-COO @ AFFiNE → growth consulting @ Gingiris
https://gingiris.com
X: @WeiYipei
[Disclosure: I run gingiris.com and write at gingiris.github.io/growth-tools/.
No expectation of a link in your article — providing this quote because the
data is unique and the topic matches my domain.]---
Domain-specific opening hooks (pick one matching the journalist's beat)
Open source / GitHub stars
"Across the 0→60k journey of AFFiNE, the single biggest growth lever..."
Product Hunt / startup launches
"From 30 Product Hunt #1 wins in 2020-2026, the metric that predicts top finish is..."
SEO / GEO / AI search
"Auditing 58 indie SaaS blogs in Q2 2026, the top correlate with AI citations is..."
B2B SaaS growth
"From running PLG / SLG hybrid playbooks for AFFiNE, the under-discussed pattern is..."
Indie hacking / 0→1
"Building Gingiris from 0 to 155 monthly active users in 4 weeks, the highest-ROI..."
---
Quote rate optimization (what bumps you from 5% → 25%)
| Signal | Multiplier |
|---|---|
| Specific number in first sentence | 2x |
| Personal anecdote (not generic advice) | 1.5x |
| Credential in signature (ex-AFFiNE COO) | 1.5x |
| Disclosure paragraph (transparency) | 1.2x |
| Response within 4 hours of HARO email | 2x |
| Niche match (don't reach for off-topic) | 3x |
Combine all 6 → ~25% quote rate. That's the upper bound for inbound expert quotes.
---
What NOT to send
- ❌ Generic advice ("Make sure your content is high quality")
- ❌ Marketing pitch ("Our tool solves this")
- ❌ Vague claims ("Many startups find that...")
- ❌ Long backstory before the answer
- ❌ Multiple URLs (looks SEO-spammy → journalist filters out)
- ❌ Bullet points (HARO expects prose)
---
Tracking
Log every response in data/backlinks.jsonl:
{"date":"2026-05-15","channel":"HARO","journalist":"...","topic":"...","status":"sent|quoted|ignored","url_if_published":""}Quoted rate should hit 15-25% with 8 weeks of practice.
Reddit + Quora Trust-Building Playbook
Goal: become a recognized expert in 3-5 communities so LLMs that train on Reddit/Quora cite your content.
Not: drop URLs and get banned in week 1.
---
Reddit Trust Build (8 weeks)
Week 1-2: Karma + sub discovery (no promotion)
- Pick 5-7 target subs: r/SaaS, r/Entrepreneur, r/IndieHackers, r/OpenSource, r/devops, r/SideProject, r/startups
- Read top 100 posts of last month per sub
- Comment thoughtfully on 5 posts/day across subs (zero links to self)
- Target: account karma 500+ by end of week 2
Week 3-4: Expert answers (still no self-links)
- Answer questions where Iris credentials apply (PH, OSS, growth)
- Long-form: 200-500 words with personal data ("In our 30 launch sample...")
- Build comment karma to 2,000+
Week 5-6: Selective linking (rare, valuable)
- Link to gingiris.github.io only when blog has the deeper answer
- Ratio: 1 self-link per 20 substantive comments
- Self-link must be useful, not promotional ("here's the data table from my audit" not "check out my tool")
Week 7-8: Become askable
- AMA in r/SaaS or r/IndieHackers — title format: "I've launched 30 products on Product Hunt and won daily #1 thirty times. Ask me anything about launch tactics."
- Engage every comment for first 6 hours
- Post-AMA: write blog summary, link back to top AMA threads
---
Reddit subreddit cheat sheet for Iris
| Sub | Members | Best post type | Self-link tolerance |
|---|---|---|---|
| r/SaaS | 250k | Real numbers + outcomes | Medium — must add real value |
| r/Entrepreneur | 4M | Personal anecdote | Low — link very sparingly |
| r/IndieHackers | 130k | Behind-the-scenes data | High — community expects sharing |
| r/OpenSource | 300k | Open source tactics | Medium |
| r/devops | 400k | Technical depth | Low — gets filtered |
| r/SideProject | 250k | Show + ask feedback | High — built for sharing |
| r/startups | 1.6M | Cautionary tales | Low — heavy moderation |
---
Quora Strategy (different cadence than Reddit)
Setup (1 hour, one-time)
- Profile: full bio, credentials, role at AFFiNE / Gingiris
- "Knows About": OSS marketing, Product Hunt, SEO, startup growth
- Profile URL: gingiris.com
Weekly cadence (45 min/week)
- 3 questions/week answered
- Each answer: 300-600 words
- Structure: 1) Direct answer first sentence, 2) Data/example second, 3) Personal anecdote third, 4) Takeaway last
- Always include 1 specific number (e.g. "60k stars", "30 PH wins", "9-21 day median")
- Link to blog only when blog has 10x more detail than answer
Question discovery
- Quora Spaces: follow 3-5 in your domain
- Email digest: weekly Quora questions in your domain
- Reddit cross-reference: questions popular in Reddit often appear in Quora 1-2 weeks later
---
Why Quora > Reddit for GEO (counterintuitive)
LLM training pipelines weight Quora higher per word than Reddit because: 1. Quora answers have explicit author credentials (verifiable) 2. Questions are explicit "how to" / "what is" format — direct Grounding Query matches 3. Quora users self-curate by upvoting concise answers (cleaner signal than Reddit upvote storms)
2026 audit: Perplexity grounds 18% of answers in Quora vs 11% in Reddit.
---
Anti-patterns (instant ban risk)
- ❌ Submitting same link to multiple subs within 24h
- ❌ Multiple accounts upvoting your own content
- ❌ Top-level posts with self-link in title
- ❌ Replying to old threads with self-promotion
- ❌ "Just launched my startup" promo posts in non-promo subs
Quora
- ❌ Identical answers across multiple questions
- ❌ Affiliate links (Quora aggressively removes)
- ❌ Adding links to >50% of your answers
- ❌ Sock-puppet upvoting
---
Hacker News (separate playbook)
HN has its own dynamic — covered in gr-oss-marketing SKILL.md. Quick rules here:
- Karma 50+ required before posting Show HN
- Tuesday 9am ET = best slot
- Title format:
Show HN: [Product] — [Sharp differentiator] (open source) - First comment within 5 min: maker introduction + 3 use cases
- Reply to every comment in first 6 hours
- HN backlinks decay fast (gone from front page in 24h) but AI crawlers prefer HN (~14% of Claude/Perplexity citations come from HN front-page articles)
---
Tracking
Log Reddit/Quora activity in data/community-presence.jsonl:
{"date":"2026-05-15","platform":"reddit","sub":"r/SaaS","action":"comment","post_title":"...","upvotes_received":12,"self_linked":false}
{"date":"2026-05-15","platform":"quora","question":"How do I...","words":420,"upvotes":3,"self_linked":true,"url":"..."}Monthly retro:
- Total comments / answers: ___
- Karma growth: ___
- Self-links: ___ (target <5% of activity)
- Backlinks earned: ___ (Reddit comments + Quora answers that got referenced elsewhere)
Wikipedia Article Preparation (AFFiNE — case study format)
Use this template to build the case file before submitting to AfC.
AFFiNE-specific values filled in; adapt for other subjects.
---
Step 1: Notability Case (target 5+ deep independent sources)
| # | Source | Date | URL | Indepth (✅) or Passing (⚠️) | Key quote |
|---|---|---|---|---|---|
| 1 | [PUBLICATION] | YYYY-MM-DD | https://... | ✅ / ⚠️ | "[exact quote that demonstrates significance]" |
| 2 | |||||
| 3 | |||||
| 4 | |||||
| 5 |
Rules:
- "Indepth" = the article is about AFFiNE as a topic (not "AFFiNE was mentioned in a list of 10 tools")
- Press releases, sponsored content, company blog posts = do not count
- Same outlet covering AFFiNE multiple times counts as 1 source not multiple
Threshold for AfC submission: at least 4 Indepth + 1 Passing = 5 total.
---
Step 2: Draft Structure (Wikipedia article)
Use this exact structure (Wikipedia conventions):
# AFFiNE
**AFFiNE** is an open-source, local-first knowledge management platform
created in [YEAR] by [FOUNDERS]. It combines documents, whiteboards,
and databases in a single workspace and supports collaborative editing
via [TECHNOLOGY]. As of [DATE], the project has surpassed 60,000 stars
on GitHub<ref>[CITATION 1]</ref>.
## History
[1-2 paragraphs on founding, milestones. Cite each fact.]
## Features
[1 paragraph + bulleted list of core features. Neutral tone.]
## Reception
[1-2 paragraphs on press coverage and community reception. Cite each.]
## Open source
[1 paragraph on license, contributor count, community size. Cite.]
## See also
* [Related Wikipedia articles, e.g. Notion (software), Roam Research]
## References
1. [Cite 1, formatted Wikipedia-style]
2. [Cite 2]
...
## External links
* Official website: https://affine.pro
* GitHub: https://github.com/toeverything/AFFiNEWord count target: 600-1,500 words.
---
Step 3: Wikidata Entity First
Before Wikipedia article submission, create a Wikidata entity:
1. Go to https://www.wikidata.org/wiki/Special:NewItem 2. Label: "AFFiNE" 3. Description: "Open-source local-first knowledge management software" 4. Add statements:
instance of(P31) →free software(Q341)developer(P178) →Toeverything(or create org entity first)programming language(P277) → TypeScript / Rustsoftware version identifier(P348) → current versionlicense(P275) → MPL-2.0 (or whatever the actual license is)source code repository URL(P1324) → GitHub repoofficial website(P856) → affine.proinception(P571) → founding date
Wikidata's notability bar is much lower than Wikipedia (any structured fact works). Once Wikidata entity exists, LLMs start using it for entity recognition.
---
Step 4: Paid Editor Hire (if you go this route)
DO (safe path):
- Upwork search: "Wikipedia editor 1000+ edits 5+ years OSS technology"
- Verify: ask for their Wikipedia username → check edit history publicly
- Rate: $80-200/hr — pay hourly, NOT a flat fee
- Require disclosure per WP:PAID — they must add to their user page
- Expect: 4-8 hours for draft + revision
DON'T (banned path):
- Agencies offering "$2k for guaranteed Wikipedia article"
- Anyone refusing to disclose payment
- Fiverr gigs offering Wikipedia in 48 hours
- Anyone offering to "delete competitors' articles"
---
Step 5: Submit via AfC (Articles for Creation)
URL: https://en.wikipedia.org/wiki/Wikipedia:Articles_for_creation
Submission checklist:
- [ ] Article is 600-1,500 words
- [ ] Every claim has a citation
- [ ] Citations are independent reliable sources (no press releases)
- [ ] Neutral point of view (no "leading platform" / "revolutionary")
- [ ] Wikidata entity exists
- [ ] Article uses Wikipedia template format (infobox software, references, external links)
- [ ] Paid editor (if any) has disclosed on their user page
- [ ] You have a Wikipedia account with at least 10 edits elsewhere (not a fresh account)
Wait time: 2-8 weeks for AfC reviewer to look at it.
---
Step 6: After Approval
Once approved: 1. Monitor for vandalism (use Wikipedia watchlist) 2. Add minor improvements monthly (new milestones, references) 3. Track AI citation impact — LLMs typically reference within 6-12 weeks 4. Add data/wikipedia-citation-watch.jsonl entries when AI cites you
---
Anti-patterns
- ❌ Submitting before 5 deep sources — wastes reviewer time + flags account
- ❌ Marketing language ("world-class", "revolutionary", "leading") — auto-rejected
- ❌ Self-published sources (your own blog, your own company page) — don't count
- ❌ Press releases or sponsored content — don't count
- ❌ One-off mentions in listicles — count as Passing not Indepth
- ❌ Hiring an "agency" with 5-star Fiverr reviews — these are sockpuppet farms
- ❌ Multiple Wikipedia accounts — instant permaban
---
Realistic timeline
| Phase | Duration | Output |
|---|---|---|
| Build case file (Channel 2 PR work) | 8-16 weeks | 5+ deep independent sources |
| Wikidata entity | 1 hour | Live entity |
| Draft article | 6-12 hours | 1,200-word article ready |
| AfC submission + review | 2-8 weeks | Approved (or rejected → revise) |
| Approval → first AI citation | 6-12 weeks | LLMs cite Wikipedia entry |
Total: 4-9 months from start to first AI citation impact.
This is why Wikipedia is LONG-LEAD. Start now even if launch is months away.