Skip to content
← Community packages

Read Reddit subreddits, listings, search, and users, and preview guarded writes through saved OAuth.

Browse files

  • Integrations
  • reddit
  • social
  • oauth
  • subreddit
  • listings
  • search
  • users
  • posting
License
MIT
Published
August 22, 2026
Pinned commit
2acae92
Rating
No ratings yet
Forks
0
Stars
0
Adaptation effort

README

@kody/reddit

Official Reddit logo (#FF4500) from Reddit brand guidelines.

Intent

Give any Kody account reusable, headless Reddit helpers for subreddit metadata, listings, search, user reads, a generic authenticated request escape hatch, and guarded writes (submit post, submit comment, vote). Author identity is always resolved from the connected Reddit account — never hard-coded to a specific username.

This listing is meant to be forked. After you fork, connect your Reddit account and run ./smoke-test on your copy. Do not treat the live @kody/reddit integration as yours.

When To Use

  • Verify the saved reddit OAuth integration and read the connected account
  • Look up a subreddit, listing, search result, user, or post/comment thread
  • Call uncommon Reddit OAuth endpoints with ./request
  • Preview a post, comment, or vote with dryRun: true, then mutate only after confirm: true

Do not use this package as a scraper, a 24/7 bot, or a place to paste access tokens. Jobs are off.

OAuth setup

Reddit is bring-your-own OAuth. There is no built-in Kody Reddit app. Tokens come from the hosted connect page (createAuthenticatedFetch('reddit')). Never paste a client secret or access token into chat.

  1. Open reddit.com/prefs/appscreate another app….
  2. Choose web app.
  3. redirect uri → add exactly https://kody.codes/connect/oauth (the connect page shows the same value with a copy button).
  4. Note the app’s client id (under the name) and secret (paste them into Kody, not into chat).
  5. Open this prefilled connect URL while signed in to Kody:
https://kody.codes/connect/oauth?provider=reddit

First-time setup also needs Reddit’s authorize and token URLs. Use this complete prefilled URL when the connection does not exist yet:

https://kody.codes/connect/oauth?provider=reddit&authorizeUrl=https%3A%2F%2Fwww.reddit.com%2Fapi%2Fv1%2Fauthorize&tokenUrl=https%3A%2F%2Fwww.reddit.com%2Fapi%2Fv1%2Faccess_token&apiBaseUrl=https%3A%2F%2Foauth.reddit.com&flow=confidential&tokenExchangeStyle=basic-form&allowedHosts=oauth.reddit.com%2Cwww.reddit.com&dashboardUrl=https%3A%2F%2Fwww.reddit.com%2Fprefs%2Fapps&scopes=identity%20read%20history%20mysubreddits%20submit%20edit%20vote%20save&extraAuthorizeParams=duration%3Dpermanent

Decoded:

  • Redirect / callback: https://kody.codes/connect/oauth
  • Authorize: https://www.reddit.com/api/v1/authorize
  • Token: https://www.reddit.com/api/v1/access_token
  • API base: https://oauth.reddit.com
  • Flow: confidential with tokenExchangeStyle=basic-form (HTTP Basic + form body)
  • Hosts: oauth.reddit.com, www.reddit.com
  • Extra authorize param: duration=permanent (needed for a refresh token)
  • Scopes: identity, read, history, mysubreddits, submit, edit, vote, save
  1. Paste the client id and secret into the Kody form, continue to Reddit, and approve.
  2. Run Smoke test on the forked package.

Reconnect the same connection with https://kody.codes/connect/oauth?provider=reddit. Kody reuses the saved authorize/token endpoints.

Scopes

ScopeUsed by
identity./smoke-test, ./get-me
readlistings, search, subreddit about, posts, comments, user about
historyauthenticated user history when requested through ./request
mysubredditssubscribed-community reads through ./request
submit./submit-post, ./submit-comment
editedits through ./request
vote./vote
savesaves through ./request

./request uses whatever scopes the saved token already has. ./smoke-test does not return the connected username.

Auth / transport

There is no usable public Reddit OpenAPI for the full OAuth surface. This package uses a compact request helper that authenticates with createAuthenticatedFetch('reddit') and sends Reddit’s required User-Agent on every oauth.reddit.com call.

Pass account: '<purpose>' for integration reddit-<purpose> (omit → reddit). Do not hard-code a username in forks.

Smoke test

After connect or reconnect, invoke ./smoke-test in the forked package runtime (not a static import):

import { packages } from 'kody:runtime'

export default async function main() {
	return await packages.invoke({
		kodyId: 'reddit',
		exportName: './smoke-test',
	})
}

Or import the published package:

import smokeTest from 'kody:@kody/reddit/smoke-test'

export default async function main() {
	return await smokeTest()
}

Success looks like { ok: true, integration: 'reddit', hasId: true, hasName: true } and does not return the username.

dryRun and writes

Submit and vote helpers never mutate Reddit when dryRun: true. A live write requires a fresh confirm: true after the user approved the exact payload.

import submitPost from 'kody:@kody/reddit/submit-post'

export default async function main() {
	return await submitPost({
		subreddit: 'test',
		title: 'Draft title',
		text: 'Draft body',
		dryRun: true,
	})
}

Exports

  • kody:@kody/reddit — package overview, connect URL, and scopes
  • kody:@kody/reddit/accounts — resolve reddit / reddit-<purpose>
  • kody:@kody/reddit/smoke-test — verify identity access without returning the username
  • kody:@kody/reddit/get-me — connected account from /api/v1/me
  • kody:@kody/reddit/get-subreddit — community about page
  • kody:@kody/reddit/get-listing — front page or subreddit listing
  • kody:@kody/reddit/search — post search, optionally in one subreddit
  • kody:@kody/reddit/get-user — user about, submitted, comments, or overview
  • kody:@kody/reddit/get-post — one post plus comments
  • kody:@kody/reddit/request — authenticated Reddit API request helper
  • kody:@kody/reddit/submit-post — self or link post helper (mutating)
  • kody:@kody/reddit/submit-comment — comment helper (mutating)
  • kody:@kody/reddit/vote — upvote / downvote / clear helper (mutating)

Examples

import getListing from 'kody:@kody/reddit/get-listing'

export default async function main() {
	return await getListing({ subreddit: 'programming', sort: 'hot', limit: 5 })
}
import search from 'kody:@kody/reddit/search'

export default async function main() {
	return await search({ query: 'kody agents', limit: 5 })
}

Troubleshooting

  • Connect page asks for authorize/token URLs: use the complete first-time URL in OAuth setup.
  • HTTP 401 / 403: reconnect at https://kody.codes/connect/oauth?provider=reddit. Confirm the Reddit app is a web app and the redirect URI is exactly https://kody.codes/connect/oauth.
  • HTTP 429: Reddit requires a unique User-Agent. This package sends web:kody.reddit:1.0.0 (https://kody.codes/@kody/reddit). If token exchange itself is blocked, the hosted connect page may need a Reddit-friendly User-Agent — reconnect after that is fixed rather than pasting tokens into chat.
  • redirect_uri mismatch: the Reddit app redirect must be exactly https://kody.codes/connect/oauth.
  • Writes no-op: pass dryRun: true to preview, then confirm: true only after the user approves the exact payload.
Report this listing

Log in to report this listing.