A “platform account” is a single connected identity on an upstream platform — one Bluesky handle, one Facebook Page, one Twitter user. Posts are sent against an accountDocumentation Index
Fetch the complete documentation index at: https://docs.letmepost.dev/llms.txt
Use this file to discover all available pages before exploring further.
id, never against bare credentials.
Two connect shapes
| platform | shape | flow |
|---|---|---|
| Bluesky | credentials | submit handle + app password, no OAuth round-trip |
| everything else | oauth | redirect → upstream consent → callback |
platform_accounts and an id you reference from post bodies as account.id.
OAuth: connect → complete
connect.sh
Credentials: Bluesky
Bluesky doesn’t have OAuth; it uses scoped app passwords. Generate one at bsky.app/settings/app-passwords, then submit:bluesky.sh
platform_auth_failed.
Fan-out: Meta is one connect, two platforms
Connectingfacebook grants both Facebook Pages publish and the linked Instagram Business publish — Pages are discovered via GET /me/accounts, IG Business via the Page’s instagram_business_account field. The single OAuth produces two platform_accounts rows: one for facebook, one for instagram (when an IG Business is linked).
To post to Threads you connect separately — Threads has its own OAuth (threads.net), distinct from Facebook Login for Business.
Token lifecycle
We refresh access tokens on each platform’s published schedule and AES-256-GCM encrypt them at rest:| platform | access token lifetime | strategy |
|---|---|---|
| Bluesky | minutes | refresh on 401; the AT Proto session is short-lived |
| Twitter / X | 2 hours | refresh ~5 min before expiry |
| Threads | ~60 days | refresh long-lived token before expiry |
| Facebook / IG | ~60 days | exchange short-lived for long-lived; refresh on schedule |
| 60 days, no refresh | re-auth required; we fire token.expiring 7 days ahead | |
| 30 days | refresh ~24 h before expiry |
token.expiring and token.revoked to know when a connection needs user attention.
Listing and disconnecting
Errors during connect
| code | when |
|---|---|
platform_rejected | Upstream OAuth flow failed (consent denied, bad scopes, missing business asset). |
platform_auth_failed | A subsequent post hit a revoked or expired token. |
facebook.pages.none | The Facebook user has no Pages they can manage; can’t connect. |
See also
- Authentication — letmepost API keys (separate from OAuth tokens).
- Per-platform pages — exact scope sets and quirks.