Configuration
TryPost is configured through environment variables in the.env file.
Basic Configuration
Self-Hosted Mode
SELF_HOSTED=true is the default. It bypasses everything billing-related so you never have to touch Stripe or Cashier, and it locks down public sign-ups:
- Public registration is disabled —
/registeris closed so random users can’t create accounts on your instance. Bootstrap the first admin via theUserSeeder(see Seed default data and create the admin user); after that, every account comes from a workspace invite (Settings → Members). - No Stripe, Cashier, or
CASHIER_TRIAL_DAYSconfiguration required - The
LoadWorkspaceFromTokenmiddleware skips the402 Payment Requiredgate - Subscription gating is not enforced, so workspaces, social accounts, and members are unlimited per account
- AI calls go straight to your configured provider; you pay the provider directly (no Cloud metering)
false on a self-hosted install. The Cloud SaaS deployment is the only place that runs with billing enabled.
Multiple accounts per network
A workspace can connect as many accounts as you want on the same network — two LinkedIns, two Instagrams, and so on. There is no env flag for this. Two flavours of the same platform still collapse to one identity:- LinkedIn profile + LinkedIn Page
- Instagram Standalone + Instagram (Facebook Business)
ALLOW_MULTIPLE_SOCIAL_ACCOUNTS was removed. If it is still in your .env, you can delete it — it is ignored.
Database
TryPost runs on PostgreSQL or MySQL. Every change runs the full test suite against both, so the application treats them as equals — pick the one you already know how to back up and restore. What differs is the packaging around them:
MariaDB is close enough to MySQL that it may well work, but it is not tested and not something support can help with.
Pick one before you have data. Moving an existing install from one engine to the other is not a dump-and-load: the two disagree on types, quoting and JSON layout, so it needs a conversion tool and a careful check afterwards. That path is neither documented nor supported.
PostgreSQL
MySQL
utf8mb4 (see Installation) so emoji in posts survive. MySQL 8 already defaults to it; this matters on older servers and on MariaDB.
Redis
Redis is required for queues and caching.Runtime drivers
For a working production-like stack, point the Laravel drivers at Redis / Reverb / the database:
Without Redis queues, Horizon has nothing useful to process. Without Redis cache on multi-instance deploys, scheduled jobs can double-fire.
Passport (API & MCP tokens)
Passport signs and verifies both REST API keys (Personal Access Tokens) and MCP OAuth grants. You need:PASSPORT_PRIVATE_KEY and PASSPORT_PUBLIC_KEY in .env (PEM contents) instead of key files — required for Docker production (compose.prod.yaml) and useful for secret managers / multi-node deploys. Do not regenerate keys after users have issued tokens.
MCP clients authenticate with OAuth (mcp:use), not with an API key Bearer header. API keys are for the REST API only.
The API reference describes your instance too — same routes, same payloads, same MCP tools. Only two things differ: the base URL is your APP_URL followed by /api, and responses reflect the settings on this page rather than the Cloud plan. GET /social-accounts can return several accounts sharing one platform value, so read it by id. See multiple accounts per network.
Full install order: Installation.
Media size limits
Signed uploads are rate-limited per workspace and per IP (
MEDIA_SIGNED_UPLOAD_PER_WORKSPACE_PER_MINUTE, MEDIA_SIGNED_UPLOAD_PER_IP_PER_MINUTE). If you raise the video limit, also bump PHP’s upload_max_filesize / post_max_size and any reverse-proxy body-size cap to match.
File Storage
TryPost supports local public storage and S3-compatible cloud storage. The application default ispublic (FILESYSTEM_DISK=public). Use object storage (S3 / R2 / Spaces) when you outgrow local disk or run multiple app instances.
Public Disk
Stores files instorage/app/public and serves them directly from ${APP_URL}/storage.
public/storage to storage/app/public (once per install):
public disk. Object storage (s3, r2, spaces) does not use this symlink.
See Laravel’s public disk documentation for more details.
AWS S3
Cloudflare R2
DigitalOcean Spaces
Other S3-Compatible Storage
Any other S3-compatible storage (MinIO, Backblaze B2, etc.) can be used with thes3 disk configuration.
SendKit (recommended)
SendKit is TryPost’s official mailer — built by the same team and wired in as the default. Every new SendKit account is free and includes 3,000 transactional emails per month, which is plenty for a self-hosted TryPost instance handling post notifications, team invites, and account alerts.- Create a free account at sendkit.dev
- Copy your API key from the SendKit dashboard
- Drop it into your
.env:
SMTP
If you’d rather use your own SMTP server:Emails sent by TryPost
WebSockets (Reverb)
TryPost uses Laravel Reverb for real-time updates (live post status, notifications).In production, set
REVERB_SCHEME=https, set REVERB_HOST to your real public domain (e.g. app.example.com), and use a reverse proxy to handle SSL termination for WebSocket connections. REVERB_SERVER_HOST stays 0.0.0.0 so the daemon listens on all interfaces inside the box.Social Platforms
Each social platform requires API credentials from its developer portal. See each platform guide for step-by-step setup.Bluesky and Mastodon don’t require API credentials — they work out of the box. Telegram uses a single shared bot you create with @BotFather, and Discord uses a single shared bot application from the Discord Developer Portal — neither is a per-user OAuth app. See their credentials below.
All platform credentials
Telegram delivers
/connect commands and reactions over a webhook. After setting the variables above, register it with php artisan telegram:set-webhook. The webhook URL is {APP_URL}/telegram/webhook, so APP_URL must be a public HTTPS URL Telegram can reach — re-run the command whenever it changes. The bot must be added as an administrator of each channel or group it publishes to.Discord uses a single shared bot application (create one in the Discord Developer Portal). Use the OAuth2 Client Secret — not the application’s Public Key — for
DISCORD_CLIENT_SECRET, and add the redirect URL above under OAuth2 → Redirects. The bot invite permissions and scopes are configurable via DISCORD_PERMISSIONS (default 248832) and DISCORD_SCOPES (default bot,identify,guilds). See the Discord platform guide for the full setup.Enabling/disabling platforms
You can selectively enable or disable platforms without removing their credentials. This is useful when API credentials are pending approval or temporarily revoked.false to hide it from the UI. All platforms are enabled by default.
Link defusing on X
X charges much more to deliver a post that carries a link than a plain one, and its algorithm shows link posts to fewer people. With defusing on, every URL in the X version of a post is rewritten into a non-clickable form before it is published, so the address still reads normally but X no longer treats the post as a link post.
So
https://www.example.com/pricing publishes as example(.)com/pricing, and https://blog.example.com.br as blog(.)example(.)com(.)br. Every dot has to break — leaving one intact still leaves a domain X can resolve and bill for.
Only X is affected. The same post published to LinkedIn, Bluesky, Telegram or anywhere else keeps its links exactly as they were typed.
What counts as a link:
- Anything carrying
https://,http://orwww.is rewritten on sight, whatever it ends in. - A bare host is rewritten only when its last label is a delegated top-level domain, which is what tells
acme.comapart fromNode.js. The list mirrors the full IANA root zone, soREADME.mdandbackup.zipare rewritten too —.mdand.zipare real top-level domains and X links them. - Email addresses are left alone.
- Dots in the path or query string are left alone.
The default is off. A self-hosted install publishes through its own X app and pays its own X bill, so the saving this buys may not be worth links a reader cannot click. TryPost Cloud runs with it on.
Repurpose
Active repurposes poll Instagram and Facebook for videos published outside TryPost. The scheduler runsrepurpose:poll every five minutes; each source is checked when it is due.
Raise the interval if you are close to Meta’s app-wide quota. Horizon and the scheduler must both be running or nothing is replicated.
Social login
TryPost supports sign in with Google and GitHub. Both providers are off by default — set the corresponding*_AUTH_ENABLED flag and provide credentials to surface the buttons on the login/register pages.
https://your-domain.com/accounts/youtube/callback(YouTube connection)https://your-domain.com/auth/google/callback(Google login)
GitHub
${APP_URL}/auth/github/callback.
AI features (optional)
The Generate / Review / Create AI flows in the post editor need a configured text-generation provider. Without one, the AI buttons stay disabled. See AI Providers for the full list of supported providers, per-provider model overrides, and OpenRouter-specific gotchas.Asset library (Unsplash & Giphy)
The Assets page exposes optional Unsplash and Giphy tabs. Configure these to enable them:Analytics (optional)
PostHog
POSTHOG_ENABLED gates the entire integration — without it set to true, the keys are ignored.
Google Tag Manager
Horizon (Queue Dashboard)
Laravel Horizon provides a dashboard to monitor your queues. Access it at/horizon.
If not set, Horizon dashboard will be inaccessible in non-local environments.

