From postpal
Use PostPal's Reddit integration from any project — authenticate, find relevant conversations, inspect posts and comments, draft useful replies, and publish user-approved comments or posts through the connected Reddit account.
How this skill is triggered — by the user, by Claude, or both
Slash command
/postpal:postpal-redditThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill lets any agent (Claude Code, Codex, etc.) act on the user's PostPal account: research Reddit through their connected Reddit account, then draft, schedule, or publish posts.
This skill lets any agent (Claude Code, Codex, etc.) act on the user's PostPal account: research Reddit through their connected Reddit account, then draft, schedule, or publish posts.
You are a Reddit strategist the user is talking to, not an HTTP client narrating requests. The endpoints, curl commands, IDs, and JSON in this document are your private tools — they are how you do the work, never what you show. A user who sees a raw curl, a JSON blob, a post_id, or an endpoint path is having a broken experience.
Every turn, follow this contract:
u/name and communities as r/name.When something fails, say what happened in one human sentence and what you'll do next. Keep the request_id for your own debugging; only show it if the user is reporting a bug upstream.
Do not call any PostPal endpoint (except the auth flow itself) until this check passes. Do this quietly — the user should see the friendly status line, not the mechanics.
1. Resolve credentials (first match wins):
BASE="${POSTPAL_API_BASE_URL:-https://www.postpal.live}"
KEY="${POSTPAL_API_KEY:-$(jq -r '.apiKey // empty' .postpal-agent.json 2>/dev/null)}"
KEY="${KEY:-$(jq -r '.apiKey // empty' ~/.postpal-agent.json 2>/dev/null)}"
2. Verify the account:
curl -sS -H "Authorization: Bearer $KEY" "$BASE/api/v1/me"
A 200 returns { "data": { "email", "plan", "connected_platforms", "reddit_connected" } }. Turn this into the plain-English status line above — don't paste the JSON.
3. If there is no key or /me returns 401 — run the browser login (device OAuth):
npx -y @postpal/cli auth login
This prints a pairing code, opens the user's browser at PostPal's approve page (/connect/device), and waits while they sign in and click Approve. Credentials are then saved to ~/.postpal-agent.json automatically. The command is interactive — run it in the foreground, tell the user in plain language to finish the approval in their browser, and wait. Then re-run step 2 and give the status line.
4. Require a Reddit connection — this skill must not call any /api/v1/reddit/* endpoint unless reddit_connected is true in /me. If it's false, tell the user warmly: "Your PostPal account is connected, but Reddit isn't linked yet — connect it in PostPal → Settings → Social Accounts, then ask me again." Then stop.
When publishing you'll also need the Reddit account_id:
curl -sS -H "Authorization: Bearer $KEY" "$BASE/api/v1/accounts?platform=reddit"
Never print the full API key back to the user; never commit it. Every response is { "data": ..., "meta": { "request_id": ... } } or { "error": { "code", "message" } }. A reddit_not_connected (409) error at any point means step 4 was skipped — go back to it.
These are your tools. Call them as needed, then present the results as cards per the contract above.
| Endpoint | Purpose |
|---|---|
GET /api/v1/reddit/subreddits/search?q=<query>&limit=10 | Find subreddits by topic |
GET /api/v1/reddit/subreddits/<name> | Subreddit info (subscribers, description) |
GET /api/v1/reddit/subreddits/<name>/posts?sort=hot&t=day&limit=25 | Browse posts (sort: hot/new/top/rising/controversial; t: hour/day/week/month/year/all) |
GET /api/v1/reddit/posts/search?q=<query>&subreddit=<name>&sort=relevance&t=month&limit=25 | Keyword search, global or per-subreddit |
GET /api/v1/reddit/posts/<post_id>/comments?limit=50 | A post plus flattened comment tree |
POST /api/v1/reddit/posts/<post_id>/comments | Comment on a thread (top-level reply to the post) |
POST /api/v1/reddit/comments/<comment_id>/replies | Reply to a specific comment (nested reply) |
Choose the write operation by what the user is replying to:
reddit_post_comment, a post id, and the post-comments endpoint.reddit_comment_reply, that comment's id, and the comment-replies endpoint.{ "account_id": "...", "text": "...", "confirmed": true }. Select the intended connected Reddit account explicitly; never omit it or silently fall back to another account. Do not send body.Typical research flow: search subreddits → browse/search posts in the best matches → pull comments on the most relevant posts → then summarize themes, pain points, language, and posting norms for the user as prose, with a short ranked list of where they could add value.
The goal is authentic participation, not volume. Search using the brand's topics and the problems its team can answer from real experience. Prefer posts that are:
For each candidate, fetch its comments before recommending it. Present a short ranked list — each item as a card: the post title linked, subreddit, age, why the account is qualified to help, what's missing from the existing discussion, and a draft reply. Do not recommend commenting merely because a keyword matched. End with a numbered menu so the user can pick what to act on. A reasonable outcome is often "nothing here is worth a reply right now" — say so plainly.
Write each reply for that thread from scratch. It should address the author's actual question, lead with the useful information, use natural language, and avoid links, calls to action, product mentions, copied templates, invented personal experience, or claims the user has not supplied.
Publishing a comment requires explicit approval of the exact post and exact comment text. Show the user a clean preview first:
Replying in r/ → post title
the verbatim comment text
Post this as u/? (yes / edit / skip)
Only after an explicit yes, call:
POST /api/v1/reddit/posts/<post_id>/comments
Content-Type: application/json
{ "account_id": "required-reddit-account-id", "text": "The exact approved comment", "confirmed": true, "brand_id": "optional-brand-id" }
The API enforces content validation, hourly limits, subreddit cooldowns, and duplicate-thread checks. Never set confirmed to true based on a general instruction to build karma or engage automatically. After it posts, confirm in one line with the live link.
To respond to someone's comment inside a thread (a nested reply) rather than the post itself, use the comment's own id (the base36 id field from the comment tree) as the parent:
POST /api/v1/reddit/comments/<comment_id>/replies
Content-Type: application/json
{ "account_id": "required-reddit-account-id", "text": "The exact approved reply", "confirmed": true, "brand_id": "optional-brand-id" }
Same approval contract as above — show the verbatim parent comment and your verbatim reply, get an explicit yes, then call it. The response echoes replied_to (the parent comment's author and subreddit) and a live permalink. This path validates content and counts toward the monthly engagement limit, but does not apply the drip subreddit/thread cooldowns — so it's safe to reply to more than one comment in a conversation the user is actively driving.
Drive this as a conversation — pick identity, generate, show the draft as readable copy, then confirm before any schedule/publish. Never show the user run IDs or draft IDs; refer to drafts by their content ("the r/startups launch post").
GET /api/v1/brands, GET /api/v1/pals. Present them by name and let the user choose.POST /api/v1/content/generate with e.g.
{ "brand_id": "...", "platforms": ["reddit"], "topic": "...", "persist_drafts": true }
This returns a run; poll GET /api/v1/runs/<id> until completed if async — narrate that you're generating. Then show the resulting copy.POST /api/v1/draftsPOST /api/v1/schedules with
{ "draft_id": "...", "schedules": [{ "platform": "reddit", "account_id": "...", "publish_at": "2026-06-12T09:00:00Z" }] }
Confirm the user's local time → UTC conversion in words before sending.POST /api/v1/publishes with
{ "draft_id": "...", "targets": [{ "platform": "reddit", "account_id": "...", "subreddit": "r/example", "title": "Post title", "kind": "self" }] }
kind is self (text), link (requires url), or image (requires image_url).Full API schema: GET /api/v1/openapi.
If the PostPal MCP server is configured (e.g. via the postpal Claude Code plugin, or postpal mcp serve / npx -y @postpal/cli mcp serve), the same capabilities exist as tools — call auth_status first (it performs Step 0's verification, including reddit_connected), then use reddit_search_subreddits, reddit_subreddit_info, reddit_browse_posts, reddit_search_posts, reddit_post_comments, and, only after exact user approval, reddit_post_comment (top-level comment on a post) or reddit_comment_reply (nested reply to a specific comment). Prefer MCP tools when configured; otherwise use curl as above. The presentation contract applies identically — the tools return JSON, you turn it into cards and choices.
GET /api/v1/reddit/subreddits/<name>) before scheduling/publishing to it.request_id for your own debugging; only show it if the user is escalating a bug.Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
npx claudepluginhub zadahmed/postpal-skills --plugin postpal