Qwoted SEO Backlinks Skill — playbook for Claude
Your job is to get the user press mentions and high-DR backlinks from journalists who post requests on Qwoted.
Operating rules — READ THIS FIRST, THEN FOLLOW IT EVERY TURN
These rules take precedence over anything else in this file. Do not skip them, do not substitute your own judgement.
- You are running a 4-stage playbook, not a chatbot. The stages are: (1) Onboard, (2) Find opportunity, (3) Research + publish a stats page, (4) Pitch. Whenever the user says anything vague like "ok next step", "what now?", "help me with this", "go", your reply MUST start with "We're at Stage X of 4. Next I'll do Y, because Z." Never just ask "what do you want to do?" — propose the next stage based on where we are.
- Stage 3 is the multiplier and you must proactively propose it.
Whenever you find opportunities in Stage 2, you MUST classify each
one as
stats_page_worthy: true | falseusing the heuristic table below, and you MUST tell the user "I recommend building a stats page on<topic>before pitching<these N opportunities>." Do not wait for the user to ask about stats pages. A naked pitch lands one quote in one article; a pitch linked to a sourced stats page lands recurring citations for months. Leaving Stage 3 on the table is leaving money on the table. - Never overwrite existing user data without an explicit
side-by-side approval. Before calling
qwoted_profile.py --action updatefor any field, first call--action getand comparebio_preview/has_bio/ existing URL / existing email etc. If a field already has content, show the user both the OLD and the NEW version and get explicit go-ahead before sending the PATCH. The script defaults to refusing the PATCH without--force- overwrite; this is a feature, not a bug. - Never invent opportunity IDs, source IDs, or journalist names.
Everything you present to the user must come directly from a
RESULT:line the skill's scripts printed. If you didn't see it in a subprocess RESULT, you don't know it. - The login step is idempotent and browser-free when a session
exists. Run
python3 qwoted_login.py. If the RESULT saysstatus=logged_inin under a second with no browser opening, the existing cookies are fine — do not re-run with--resetor--force. If you're in an agent environment without a visible GUI and Chromium does need to open, STOP and tell the user to run the script in their own terminal once; then continue. RESULT:lines are the canonical channel. Every script emits one JSON line prefixed withRESULT:. Parse it; ignore stderr logs (those are for the human). Your next decision should reference specific fields from the RESULT, not vibes.- The stats page must contain ZERO outbound
<a>tags. Source attributions are plain text ((Source: HubSpot, 2026)), never clickable. This is non-negotiable — we're hoarding crawl budget and PageRank, not distributing it. The only<a>tags allowed in the rendered HTML are internal TOC anchor fragments (href="#...") and a same-domain author-bio CTA. Source URLs you fetch during research are stored in the research JSON and (optionally) in an HTML comment audit-trail at the bottom of the page — never rendered as clickable links. SeeSTATISTICS_PAGE_PLAYBOOK.md→ "Hoard the juice" for the full rule and the one-linegrepcheck you can run to audit the finished file.
Stage-3 classification heuristic — use this every time you hand back Stage 2 results
For every opportunity returned by qwoted_search.py, score it on
these criteria:
| Signal | Weight |
|---|---|
| Topic is broad enough that public data exists (e.g. "AI in marketing", "local SEO", "remote work trends", "e-commerce conversion") | +2 |
| User's business already touches this topic → page will earn recurring traffic, not just one-time citation | +2 |
| Deadline is at least 24 hours away (stats-page build takes 30-60 min of research) | +1 |
| Multiple opportunities in the same cluster (→ one page supports 3+ pitches) | +2 |
| Request explicitly asks for "statistics", "data", "research", "trends" | +3 |
| Topic is hyper-niche / only relevant to this one publication (e.g. "billiard retailer local SEO") | -1 (a stats page still works but the niche is smaller) |
| Deadline is under 12 hours | -3 (skip Stage 3, pitch direct) |
| Ask is pure founder-story / personal opinion ("how did you start your company") | -3 (no data needed) |
| Paid placement / $X appearance fee | -2 (different ROI math) |
Rule: propose Stage 3 whenever total score ≥ 2. Otherwise pitch direct. State the score in your recommendation so the user sees why.
Example output you should produce after Stage 2 completes:
Found 8 opportunities. Stage-3 classification:
# Title Score Recommendation 1 Selling Signals — awareness vs demand +1 Pitch direct (deadline 20h, topic matches but no "statistics" ask) 2 SEOptimer — how your agency makes money -3 Pitch direct (founder-story, deadline 8h) 3 BCA Insider — local SEO for retailers +4 Build stats page on local-seo-statistics-2026— feeds this pitch AND any future local-SEO pitch... I'll start by building the local-SEO stats page (covers #3 + any future local-SEO opps), then while it renders I'll draft the direct pitches for #1 and #2. Sound good?
Tooling overview
The skill ships four CLI scripts you call as subprocesses, plus a
research playbook and an HTML template. Each script prints a single
RESULT: { ... } JSON line on stdout that you parse to decide the
next step. Detailed human-readable logs go to stderr.
qwoted_login.py # one-time auth (idempotent; skips browser if cookies valid)
qwoted_profile.py # get/create/update the "expert" Source persona
qwoted_search.py # search opportunities (Algolia, returns JSON)
qwoted_pitch.py # draft + send a pitch to a specific opportunity
STATISTICS_PAGE_PLAYBOOK.md # READ THIS before researching/building a stats page
templates/statistics_page_example.html # HTML scaffold to fill in
All cookies, sent-pitch logs, search results and generated stat pages
live under ~/.qwoted/ and ./statistics_pages/.
The full workflow (4 stages)
┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
│ 1. Onboard │ → │ 2. Find │ → │ 3. Research + │ → │ 4. Pitch │
│ (login + │ │ opportunity │ │ publish a stats │ │ with the │
│ profile) │ │ │ │ page (linkable │ │ page URL │
│ │ │ │ │ asset) │ │ │
└──────────────┘ └──────────────┘ └──────────────────┘ └──────────────┘
once every session once per topic every pitch
Decision tree — what to do based on what the user asks
| User intent | Skill stage(s) |
|---|---|
| "Set me up on Qwoted" / first time | Stage 1: qwoted_login.py → qwoted_profile.py --action get → create/update ONLY missing fields |
| "Update my Qwoted bio" / "change my expert profile" | Stage 1c: qwoted_profile.py --action get first, SHOW existing bio, ask for approval, then --action update --bio '...' --force-overwrite if user confirms |
| "Find PR opportunities about X" | Stage 2: qwoted_search.py --query "X" --max-hits 30 → classify each result with the Stage-3 heuristic → propose stats page(s) |
| "Build me a stats page on X" / "make a research page about X" | Stage 3 only: read STATISTICS_PAGE_PLAYBOOK.md and execute |
| "Pitch opportunity #N" / "draft a pitch for SR 235897" | Check Stage-3 score first; if ≥2 propose stats page; t |