Skip to content

Connect Reddit

The platform publishes approved post drafts to Reddit the same way it posts to X and LinkedIn: a draft targets a connected account, and the publish worker submits it via Reddit’s API.

Reddit differs from the other social destinations in one product-shaped way: a connection is the signed-in user’s own account, not one of viite’s shared company identities. So the connect provider is owner-principal (like YouTube), not admin — connecting does not require being named in ADMIN_EMAILS, and onboarding a customer is not a redeploy.

At https://www.reddit.com/prefs/apps, create an app:

FieldValue
typeweb app — not “installed app”. A web app is a confidential client, which is what the token endpoint’s HTTP Basic auth needs.
redirect urihttps://platform-api.viite.ai/api/connect/reddit/callback — byte-for-byte. Add http://127.0.0.1:3000/api/connect/reddit/callback as well for local development.

The app is owned by whichever Reddit account registers it (viite’s is u/Viite-ai). That account is not a credential and not the posting identity — it is just the owner of record. Users connect their own accounts against it.

Then set three environment variables (see Environment variables):

Terminal window
REDDIT_CLIENT_ID=...
REDDIT_CLIENT_SECRET=...
REDDIT_OAUTH_REDIRECT_URI=https://platform-api.viite.ai/api/connect/reddit/callback

Until all three are set — plus SOCIAL_TOKEN_ENCRYPTION_KEY — the provider stays dormant: it is not registered, Reddit does not appear on /channels/new, and no publisher is built.

On Channels → Add a channel, pick Post, then Reddit. The OAuth dance stores an encrypted token on a post://@<handle>@reddit.com connector row, and the account shows up as a destination for new post drafts.

The requested scopes are identity, submit, read, flair. read and flair are not used yet and are requested anyway on purpose: Reddit issues a token against the scopes granted at consent time and a refresh preserves that grant — it does not pick up scopes added later. Widening the set afterwards would force every already-connected user to disconnect and reconnect.

Every Reddit submission names a target subreddit. A draft may name one in its subreddit field (the Subreddit card on the draft editor); absent that, the post goes to the connected account’s own profile subreddit, u_<handle> — which every Reddit account has. That default is what makes a freshly connected account publishable with no further configuration.

Both forms are accepted in the field: typescript and r/typescript.

Community rules still apply and are enforced by Reddit, not by us: a subreddit that requires post flair, blocks link-heavy posts, or does not accept your account rejects the submission at publish time and the card returns with the reason.

  • Always a self (text) post. A Reddit link submission carries a URL and no body, and the composer already embeds the source URL inside the composed text — so a link submission would publish a bare URL and discard the post that was written and reviewed. The URL rides in the selftext instead.
  • A title is required. Reddit rejects a submission without one; the draft’s title is used, and publishing refuses before spending a request if it is blank.
  • No media. Reddit’s image upload is a separate asset flow and is not implemented, so the reddit destination declares image: 'none' / video: 'none' and the draft editor offers no picker.
  • Body cap: 40 000 characters (Reddit’s selftext limit). The composer is steered to a much shorter 10 000.
SymptomCause
Reddit missing from the channel pickerOne of the three REDDIT_* vars (or SOCIAL_TOKEN_ENCRYPTION_KEY) is unset, so the provider never registered. Check GET /api/connect/status.
Works for an hour, then “no refresh token is stored”The grant was not permanent — reconnect the account once the authorize URL carries duration=permanent.
403 or 429 on every callA generic User-Agent. Reddit requires a descriptive one; REDDIT_USER_AGENT is sent on every request including the token endpoint.
“Reddit submit rejected: SUBREDDIT_NOTALLOWED”The account cannot post in that subreddit — wrong name, private community, or unmet karma/age requirements.