Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.letmepost.dev/llms.txt

Use this file to discover all available pages before exploring further.

The hosted SaaS at api.letmepost.dev ships with platform-approved OAuth apps for every network we support. When you self-host, you bring your own — each platform requires that the OAuth client id match an app you control, registered against your own developer account. Bluesky is the exception: it uses app passwords and doesn’t need a developer app at all. For each platform below: register the app, configure the redirect URI exactly as listed (substituting your own ${BETTER_AUTH_URL} for the placeholder), paste the resulting client id + secret into your .env, and restart the API.
Throughout this page, ${BETTER_AUTH_URL} means whatever you set BETTER_AUTH_URL to — typically http://localhost:3000 in dev or https://api.letmepost.dev in prod. The redirect URI must match the platform’s record character-for-character, including trailing slash (or lack thereof).

LinkedIn

  • Portal: linkedin.com/developers/apps
  • Redirect URI: ${BETTER_AUTH_URL}/v1/accounts/oauth/linkedin/callback
  • Env vars: LINKEDIN_CLIENT_ID, LINKEDIN_CLIENT_SECRET
Enable these two products on the app:
  • Sign In with LinkedIn using OpenID Connect — gives openid, profile.
  • Share on LinkedIn — gives w_member_social.
letmepost requests these scopes:
  • Write: openid, profile, w_member_social
  • Extended: email, r_organization_social, w_organization_social
Personal posting works out of the box. Org / Company-Page posting (w_organization_social) requires LinkedIn’s Marketing Developer Platform (MDP) review — separate, slower process. The personal-posting flow doesn’t need MDP.

Twitter / X

  • Portal: developer.x.com
  • Redirect URI: ${BETTER_AUTH_URL}/v1/accounts/oauth/twitter/callback
  • Env vars: TWITTER_CLIENT_ID, TWITTER_CLIENT_SECRET
OAuth 2.0 settings on the app:
  • Type of App: Web App, Automated App or Bot
  • Authentication: OAuth 2.0 with PKCE (Confidential client)
  • Scopes (write): tweet.read, tweet.write, users.read, offline.access
  • Scopes (extended): like.read, follows.read
As of Feb 2026 X killed tiered pricing for new signups — Basic / Pro tiers are closed; pay-per-use is the only option for new developers. Posting requires write access on the paid tier. Optional billing safety net: TWITTER_LAUNCH_CAP_PER_ACCOUNT (default 50) caps billable posts per rolling 30-day window per account, so an uncapped publish loop can’t run up the PPU bill.

Pinterest

  • Portal: developers.pinterest.com/apps
  • Redirect URI: ${BETTER_AUTH_URL}/v1/accounts/oauth/pinterest/callback
  • Env vars: PINTEREST_CLIENT_ID, PINTEREST_CLIENT_SECRET
Scopes:
  • Write: boards:read, boards:write, pins:read, pins:write, user_accounts:read
  • Extended: pins:read_secret
New apps start in Trial Access — pin creation on production (api.pinterest.com) is blocked with a hard “use sandbox” error until Pinterest approves Standard Access. While you wait:
PINTEREST_API_BASE=https://api-sandbox.pinterest.com/v5
Clear PINTEREST_API_BASE once Standard Access is approved — it defaults back to https://api.pinterest.com/v5. The variable affects every /v5/* call and the OAuth token-exchange endpoint, since both live under the same host on Pinterest’s API.

Meta family

The Meta family used to be a single Facebook Login for Business app that fanned out to Facebook Pages, Instagram, and Threads. In the current build, each of those three is an independent OAuth flow with its own client credentials. You still register all three on developers.facebook.com/apps — Meta’s developer portal — but the apps, scopes, redirect URIs, and review tracks are separate.

Facebook Pages

  • Portal: developers.facebook.com/apps
  • Redirect URI: ${BETTER_AUTH_URL}/v1/accounts/oauth/facebook/callback
  • Env vars: META_APP_ID, META_APP_SECRET
Products to add on the app:
  • Facebook Login for Business
Scopes letmepost requests (write):
pages_manage_posts
pages_read_engagement
pages_show_list
business_management
The redirect URI ends in /facebook/callback, not /meta/callback. Earlier docs incorrectly said /meta/callback; if your Meta app has that registered, update it.
App Review takes 2–8 weeks per cycle and rejections are normal. Build against Development Mode + Tester accounts during the wait — same Graph API endpoints, same response shapes; review only lifts the testers-only gate. Business verification is required before submission. Optional: META_GRAPH_VERSION pins the Graph API version (the provider has a default; bump it on each platform version cut and re-run the contract test suite).

Instagram (Instagram API with Instagram Login)

  • Portal: developers.facebook.com/apps — same portal as Facebook, but you’ll enable the Instagram product → “Instagram API setup with Instagram Login” path.
  • Redirect URI: ${BETTER_AUTH_URL}/v1/accounts/oauth/instagram/callback
  • Env vars: INSTAGRAM_CLIENT_ID, INSTAGRAM_CLIENT_SECRET
Scopes letmepost requests (write):
instagram_business_basic
instagram_business_content_publish
This is different from the Instagram fan-out you used to get through Facebook Login for Business. Instagram Login is for users who want to connect with just their Instagram account — Professional accounts only (Business or Creator), no Facebook Page required. The token is bound to the IG user and publishes hit graph.instagram.com instead of graph.facebook.com. App Review is separate from the Facebook Login scopes — different scope namespace, different review cycle. The optional INSTAGRAM_GRAPH_BASE, INSTAGRAM_OAUTH_AUTHORIZE_URL, INSTAGRAM_OAUTH_TOKEN_URL variables are test-only — they let the contract suite point at a mock server. Leave them blank in production.

Threads

  • Portal: developers.facebook.com/apps — add the Threads API product.
  • Authorize URL: https://threads.net/oauth/authorize (NOT facebook.com/dialog/oauth)
  • Redirect URI: ${BETTER_AUTH_URL}/v1/accounts/oauth/threads/callback
  • Env vars: THREADS_CLIENT_ID, THREADS_CLIENT_SECRET
Scopes:
  • Write: threads_basic, threads_content_publish
  • Extended: threads_manage_replies, threads_read_replies
Threads has its own OAuth flow + client credentials, separate from Facebook Login for Business. The Threads API product on developers.facebook.com generates a distinct THREADS_CLIENT_ID / THREADS_CLIENT_SECRET — do not reuse META_APP_ID. Tokens are short-lived (1h) on first exchange, swapped server-side for 60-day long-lived tokens which are what letmepost persists. App Review for threads_content_publish is required for production; Dev Mode with Tester accounts is fully functional in the meantime — same API, same response shapes, review only lifts the testers-only gate. Optional: THREADS_API_BASE, THREADS_API_VERSION let tests point at a mock server. Defaults: https://graph.threads.net.

Bluesky

No registration. No client id. No secret. Bluesky’s documented integration path for third-party tools is the user-generated app password flow. The user creates an app password at bsky.app/settings/app-passwords, pastes it into the dashboard’s Bluesky connect form alongside their handle, and the API stores it encrypted with KEK_MASTER. There’s nothing to configure on a self-hosted instance — connecting Bluesky works the moment the API can reach bsky.social.

Verifying a connection

Once you’ve set credentials and restarted the API, the connect flow runs from the dashboard at /accounts. Pick the platform, complete OAuth at the provider, land back on the dashboard with a connected account row. If OAuth fails, the error envelope includes a stable code and a docUrl pointing at the troubleshooting page — see platform_auth_failed for the most common cause (a redirect URI that doesn’t match the platform’s record character-for-character).