Reddit listings + Citedy Agent API autopilot (no scout credits). Optional interactive setup.
Project description
citedy-reddit-writer
Turn relevant Reddit threads into Citedy articles — automatically, on a schedule, without spending scout/reddit credits on each poll.
This small CLI watches the subreddits you care about, keeps a local dedupe ledger, and calls Citedy’s Agent API POST /api/agent/autopilot with source_urls pointing at real Reddit posts. You choose filters, daily caps, and whether Citedy should auto-publish or stop at a draft.
| Links | |
|---|---|
| Source | github.com/citedy/citedy-reddit-writer |
| Package | pypi.org/project/citedy-reddit-writer |
| Citedy | citedy.com — Agent API key (citedy_agent_…) |
Install (fastest)
Recommended — isolated CLI (no virtualenv to remember):
pipx install citedy-reddit-writer
citedy-reddit-setup # first time: writes config.yaml + .env
citedy-reddit-run --config config.yaml
Or with pip (use a venv in production):
pip install citedy-reddit-writer
Check the install:
citedy-reddit-run --help
citedy-reddit-setup --help
Minimal run (API key only)
From v0.1.1, you can skip config.yaml if the bundled defaults are fine (sample subreddits SEO, bigseo, filters, caps — see citedy_reddit_writer/default_config.yaml in the repo). Set CITEDY_AGENT_API_KEY (and optionally CITEDY_BASE_URL if not using https://www.citedy.com), load .env if you use one, then:
set -a && source .env && set +a
citedy-reddit-run --dry-run
citedy-reddit-run
If config.yaml exists in the current directory, it wins. If there is no config.yaml but config.example.yaml is present, that file is used. Otherwise the packaged defaults apply and relative paths (e.g. state file) resolve from the current working directory.
Upgrade later:
pipx upgrade citedy-reddit-writer
# or: pip install -U citedy-reddit-writer
First run in two minutes
-
Install (see above).
-
Run
citedy-reddit-setup— it asks for your Citedy base URL, Agent API key, subreddits, keyword filters, limits, andauto_publish. It writesconfig.yamland.env(keep the key in.env, not in git). -
Load env and run once:
set -a && source .env && set +a citedy-reddit-run --config config.yaml
Dry-run (no API calls, no state file updates — safe to try anytime):
citedy-reddit-run --config config.yaml --dry-run
Get your Agent API key
This CLI talks to Citedy’s Agent API using a key that looks like citedy_agent_…. Put it in .env as CITEDY_AGENT_API_KEY (the setup wizard does this for you).
Option A — Dashboard (fastest for most people)
-
Sign in at citedy.com.
-
Open Settings → Team & API:
citedy.com/dashboard/settings?section=team -
Create or copy your Agent API key and paste it when
citedy-reddit-setupasks — or add it manually to.env:CITEDY_AGENT_API_KEY=citedy_agent_your_key_here
Option B — Register an agent via API (one-time, email approval)
curl -sS -X POST "https://www.citedy.com/api/agent/register" \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","name":"My Agent"}'
Open the approval link in the email you receive. The JSON may return a field named api_key — put that value in .env as CITEDY_AGENT_API_KEY=…. This is the same env name this CLI, citedy-reddit-setup, and Citedy MCP expect for the Agent API (Bearer token).
Sanity check
curl -sS "https://www.citedy.com/api/agent/health" \
-H "Authorization: Bearer $CITEDY_AGENT_API_KEY"
Real-world stories (human flow)
These are not magic prompts into Reddit itself — the tool fetches public subreddit listings locally, picks a post that matches your filters, then sends one Reddit URL to Citedy autopilot. The “human” part is how you drive it from an IDE or another agent.
Overview — three ways to drive the same CLI
flowchart TB
subgraph S1["Story 1: IDE"]
A1[You chat in Cursor / Claude / Codex]
A2[Agent runs CLI with skill]
A1 --> A2
end
subgraph S2["Story 2: Agent + shell"]
B1[OpenClaw or headless agent]
B2[pipx install and setup]
B1 --> B2
end
subgraph S3["Story 3: Schedule"]
C1[cron or systemd]
C1 --> C2[citedy-reddit-run]
end
A2 --> CLI[citedy-reddit-run]
B2 --> CLI
C2 --> CLI
CLI --> OUT[Reddit URL to Citedy autopilot then blog if auto_publish]
Story 1 — You’re in Cursor, Claude Code, or Codex
flowchart TB
U[You type plain language in chat]
U --> SK[Skill loads CLI and .env path rules]
SK --> E[source .env or load CITEDY_AGENT_API_KEY]
E --> DR[dry-run: log topic and Reddit URL only]
DR --> Q{Good angle?}
Q -->|Adjust config| U
Q -->|Yes| RR[Real run: citedy-reddit-run]
RR --> AP[Citedy autopilot]
AP --> BL[Blog post when auto_publish is true]
- Install (once):
pipx install citedy-reddit-writer(orpip install …). - In a terminal (or ask the agent to run it):
citedy-reddit-setup— point atr/SEO(or your niches), add keywords likeagency,growth,ranking, setauto_publish: trueif you want live posts on your Citedy blog. - You type in chat, in plain language:
“Runcitedy-reddit-run --config config.yaml --dry-runand tell me which Reddit thread you would send to Citedy.”
The skill / agent shouldcdinto the project folder,source .env, then run the command. You see no article yet — only log lines like DRY_RUN: would call autopilot … with a topic + URL. - When it looks right:
“Same thing but for real — one article, env loaded.”
→citedy-reddit-run --config config.yaml - If autopilot succeeds and
auto_publishis on, a post can appear on your blog on citedy.com within the time your plan allows (async jobs may take minutes).
Why use the skill? So the agent knows the flags, your config.yaml path, and never pastes your key into chat — only reads .env.
Story 2 — OpenClaw, Claude Code on a headless box, or “any agent with a shell”
flowchart LR
AG[Agent or you in terminal]
AG --> PX[pipx install citedy-reddit-writer]
PX --> SU[citedy-reddit-setup]
SU --> OP[Optional: add SKILL.md to agent]
OP --> DR[dry-run]
DR --> AP[You approve]
AP --> RR[Real run]
RR --> CY[Citedy autopilot and blog]
- You (or the agent) run:
pipx install citedy-reddit-writer - You say:
“After install, runcitedy-reddit-setupand configure for [topic]. Then dry-run once.” - Same pattern: dry-run first (safe), then real run when you approve.
You can paste the skill text from this repo (.claude/skills/…/.cursor/skills/…) into the product’s skill store so the agent doesn’t guess the CLI.
Story 3 — Scheduled, hands-off
flowchart LR
T[cron or systemd timer]
T --> R[citedy-reddit-run]
R --> ENV[Environment has CITEDY_AGENT_API_KEY]
ENV --> CY[Citedy autopilot]
CY --> BL[New post when filters match and cap allows]
You don’t talk to the IDE for each post: cron or systemd runs citedy-reddit-run every few hours. The “conversation” happened once when you wrote config.yaml.
Case study: from “what’s hot on r/SEO?” to a live article
Setup: Subreddit r/SEO, filters around agency growth / SEO industry / ranking, reasonable min_score and max_age_hours, articles_per_run: 1, auto_publish: true.
-
Dry-run — You (or your agent) run:
citedy-reddit-run --config config.yaml --dry-run
Logs show which thread would be used assource_urlsand the synthetic topic string — no Citedy write, no state update. -
Real run — Same command without
--dry-run, withCITEDY_AGENT_API_KEYin the environment. The CLI callsPOST /api/agent/autopilotwith that Reddit URL; Citedy generates the article and, withauto_publish, can publish to your site. -
Outcome (real example) — One such production-style run produced a long-form guide that went live on the Citedy blog, e.g.
SEO Agency Growth Guide: Build Your Agency Through SEO Only
Your URLs will differ by account, topic, and filters; this link illustrates the end state: a public post you can share, not a file stuck on your laptop.
Takeaway: Install → key from Team & API (or register flow) → setup wizard → dry-run (human checks the angle) → one real run → optional live blog post on your Citedy-hosted content.
How it works
High-level flow:
flowchart LR
subgraph Reddit["Reddit (public .json)"]
R[Listings per subreddit]
end
subgraph Local["Your machine"]
F[Keyword and score filters]
D[State file dedupe]
C[Per-run and daily caps]
end
subgraph CitedyAPI["Citedy Agent API"]
A["POST /autopilot + source_urls"]
P{200 sync or 202 async}
Q[Poll job until done]
end
R --> F --> D --> C --> A --> P --> Q
Step by step
- Fetch recent posts from each configured subreddit using Reddit’s public listing endpoints (not the paid “scout” Reddit scout inside Citedy — so you don’t burn scout credits on every scheduler tick).
- Filter by include/exclude keywords, minimum score, and max post age.
- Dedupe using a local JSON state file (post IDs and title hashes), optionally cross-checking recent article titles from your Citedy account so you don’t repeat topics.
- Respect caps:
articles_per_runandmax_articles_per_dayprevent bursts. - For each chosen post, build a topic from your template and call autopilot with
source_urls: [post.url](and yourauto_publish,language,size, etc.). - If the API returns 202, the CLI polls the job until it finishes or times out (configurable). On success, state is updated so the same post is not picked again.
You can run this manually, from cron, or via systemd timer (see crontab.example and systemd/).
Why this exists
- Automation: Same story as “I want a steady pipeline from social signals to published content,” without babysitting the UI.
- Cost-aware: Polling Reddit uses public listings + your own rate limits; it does not use Citedy’s scout/reddit quota for those fetches.
- Control: You own
config.yaml— subreddits, filters, caps, and whether articles go live withauto_publish.
Configuration
| What | How |
|---|---|
| Interactive | citedy-reddit-setup → config.yaml + .env |
| Reference | config.example.yaml (all keys explained in comments) |
| Env vars | CITEDY_AGENT_API_KEY (required), CITEDY_REDDIT_CONFIG (config path), optional CITEDY_BASE_URL, CITEDY_ALERT_WEBHOOK_URL, DRY_RUN |
Paths like dedupe.state_path are resolved relative to the config file’s directory.
Scheduling
- Cron: see
crontab.example. - systemd:
systemd/citedy-reddit-writer.service+citedy-reddit-writer.timer.
Ensure the service environment loads .env or injects CITEDY_AGENT_API_KEY securely.
Agent skills (Claude Code, Cursor, Codex)
| Environment | Skill / command |
|---|---|
| Claude Code | .claude/skills/citedy-reddit-writer/SKILL.md + slash command /citedy-reddit-writer (.claude/commands/citedy-reddit-writer.md) |
| Cursor | In the saas-blog monorepo: .cursor/skills/citedy-reddit-writer/SKILL.md |
| Codex | In the saas-blog monorepo: .codex/skills/citedy-reddit-writer/SKILL.md |
This repo includes .claude/ and .cursor/skills/ for a standalone clone. For Codex-only setups, copy .codex/skills/... from the monorepo if needed.
saas-blog monorepo: one command from the Next.js repo root
If CITEDY_AGENT_API_KEY (and optional vars) live in the monorepo .env and config.yaml is under citedy-reddit-writer/ (after citedy-reddit-setup), run:
npm run citedy-reddit-writer -- --dry-run # safe: no API writes
npm run citedy-reddit-writer # real run
This uses run-with-env.sh: loads ../.env then citedy-reddit-writer/.env (package overrides parent). Uses citedy-reddit-writer/.venv/bin/citedy-reddit-run when present; otherwise citedy-reddit-run on PATH. Install once: cd citedy-reddit-writer && python3 -m venv .venv && .venv/bin/pip install -e ..
Development install (from a git clone)
git clone https://github.com/citedy/citedy-reddit-writer.git
cd citedy-reddit-writer
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
citedy-reddit-setup
Requirements & etiquette
- Python 3.10+
- A valid Citedy Agent API key.
- Respect Reddit Data API terms: set a honest
user_agent, don’t hammer endpoints, stay within reasonable automation.
Security
- Do not commit
.envor aconfig.yamlthat embedsagent_api_key. Prefer an empty key in YAML and load secrets from the environment. - Treat
config.yamland state files as sensitive if they reveal your editorial strategy.
For maintainers
Open-source users only need this repo and PyPI. Releasing (monorepo → citedy/citedy-reddit-writer, subtree, PyPI tags) is documented inside the private Citedy monorepo at docs/citedy-reddit-writer/DEPLOYMENT.md — it is intentionally not shipped here.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file citedy_reddit_writer-0.1.1.tar.gz.
File metadata
- Download URL: citedy_reddit_writer-0.1.1.tar.gz
- Upload date:
- Size: 20.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
362f574bd17f27464c4aaab778e032e5a245b2ade54ff4a62aaeca70e69765b0
|
|
| MD5 |
ff2e66f8f4a352212b118da2ffd5a31a
|
|
| BLAKE2b-256 |
1332872cb05e81dc9c2c5127d27169001c35c727bc7a72c172bc3fbab4c1b55d
|
Provenance
The following attestation bundles were made for citedy_reddit_writer-0.1.1.tar.gz:
Publisher:
publish-pypi.yml on citedy/citedy-reddit-writer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
citedy_reddit_writer-0.1.1.tar.gz -
Subject digest:
362f574bd17f27464c4aaab778e032e5a245b2ade54ff4a62aaeca70e69765b0 - Sigstore transparency entry: 1329297739
- Sigstore integration time:
-
Permalink:
citedy/citedy-reddit-writer@06386d733e8ed562b5c23e1dfec336b3577000e1 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/citedy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@06386d733e8ed562b5c23e1dfec336b3577000e1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file citedy_reddit_writer-0.1.1-py3-none-any.whl.
File metadata
- Download URL: citedy_reddit_writer-0.1.1-py3-none-any.whl
- Upload date:
- Size: 21.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cdd9d50abdafa16de77bb07ac13a2d352f1f33719d0a88034317cf623347ca23
|
|
| MD5 |
c225b000bf2874432a47f23a5b94b16f
|
|
| BLAKE2b-256 |
65479451b932389996cc11816723f440bfa398d0e9b5752da993f3b75ea1e5e0
|
Provenance
The following attestation bundles were made for citedy_reddit_writer-0.1.1-py3-none-any.whl:
Publisher:
publish-pypi.yml on citedy/citedy-reddit-writer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
citedy_reddit_writer-0.1.1-py3-none-any.whl -
Subject digest:
cdd9d50abdafa16de77bb07ac13a2d352f1f33719d0a88034317cf623347ca23 - Sigstore transparency entry: 1329297864
- Sigstore integration time:
-
Permalink:
citedy/citedy-reddit-writer@06386d733e8ed562b5c23e1dfec336b3577000e1 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/citedy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@06386d733e8ed562b5c23e1dfec336b3577000e1 -
Trigger Event:
push
-
Statement type: