Skip to main content

Configuration

TryPost is configured through environment variables in the .env file.

Basic Configuration

APP_NAME="TryPost"
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost
VariableDescription
APP_NAMEYour application name
APP_ENVEnvironment: local, staging, production
APP_DEBUGEnable debug mode (set to false in production)
APP_URLYour application URL

Self-Hosted Mode

SELF_HOSTED=true
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/register is closed so random users can’t create accounts on your instance. Bootstrap the first admin via the UserSeeder (see Create the admin user); after that, every account comes from a workspace invite (Settings → Members).
  • No Stripe, Cashier, or CASHIER_TRIAL_DAYS configuration required
  • The LoadWorkspaceFromToken middleware skips the 402 Payment Required gate
  • Plan limits are not enforced — unlimited workspaces, social accounts, members, and AI credits per account
  • AI calls go straight to your configured provider; you pay the provider directly (no credit accounting)
There’s no reason to flip this to false on a self-hosted install. The Cloud SaaS deployment is the only place that runs with billing enabled.

Database

TryPost supports PostgreSQL and MySQL.
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=trypost
DB_USERNAME=postgres
DB_PASSWORD=your_password

MySQL

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=trypost
DB_USERNAME=root
DB_PASSWORD=your_password

Redis

Redis is required for queues and caching.
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

Media size limits

MEDIA_IMAGE_MAX_SIZE_MB=10
MEDIA_VIDEO_MAX_SIZE_MB=1024
MCP_UPLOAD_MAX_SIZE_MB=50
MCP_UPLOAD_URL_TTL_MINUTES=15
VariableDefaultDescription
MEDIA_IMAGE_MAX_SIZE_MB10Max image upload size, in MB. Applied to direct uploads and URL fetches.
MEDIA_VIDEO_MAX_SIZE_MB1024Max video upload size, in MB. Applied to direct uploads and URL fetches.
MCP_UPLOAD_MAX_SIZE_MB50Hard cap (in MB) for files uploaded through the MCP request-media-upload-tool signed-URL flow. Intentionally smaller than the per-type caps because uploads stream through the app server. Raise it if your operators / nginx are sized for larger payloads.
MCP_UPLOAD_URL_TTL_MINUTES15Lifetime of the signed upload URL returned by request-media-upload-tool.
If you raise the video limit, also bump PHP’s upload_max_filesize and post_max_size and any reverse-proxy body-size cap to match. The MCP upload endpoint is additionally rate-limited at 10 requests / minute / IP — this is a hard-coded defense; tune the surrounding nginx/Cloudflare limits if you need a different floor.

File Storage

TryPost supports local public storage and S3-compatible cloud storage. The default disk is Cloudflare R2 (FILESYSTEM_DISK=r2). For self-hosted installs without object storage configured, switch to public.

Public Disk

Stores files in storage/app/public and serves them directly from ${APP_URL}/storage.
FILESYSTEM_DISK=public
After switching, create the symlink from public/storage to storage/app/public:
php artisan storage:link
See Laravel’s public disk documentation for more details.

AWS S3

FILESYSTEM_DISK=s3
AWS_ACCESS_KEY_ID=your_key
AWS_SECRET_ACCESS_KEY=your_secret
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=your_bucket
AWS_URL=https://your-bucket.s3.amazonaws.com

Cloudflare R2

FILESYSTEM_DISK=r2
R2_ACCESS_KEY_ID=your_key
R2_SECRET_ACCESS_KEY=your_secret
R2_ENDPOINT=https://your-account.r2.cloudflarestorage.com
R2_REGION=auto
R2_BUCKET=your_bucket
R2_URL=https://your-custom-domain.com

DigitalOcean Spaces

FILESYSTEM_DISK=spaces
SPACES_ACCESS_KEY_ID=your_key
SPACES_SECRET_ACCESS_KEY=your_secret
SPACES_ENDPOINT=https://nyc3.digitaloceanspaces.com
SPACES_REGION=nyc3
SPACES_BUCKET=your_bucket

Other S3-Compatible Storage

Any other S3-compatible storage (MinIO, Backblaze B2, etc.) can be used with the s3 disk configuration.

Mail

TryPost sends transactional emails for post notifications, team invites, account alerts, and authentication (email verification, password reset). A working mail configuration is required. 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.
  1. Create a free account at sendkit.dev
  2. Copy your API key from the SendKit dashboard
  3. Drop it into your .env:
MAIL_MAILER=sendkit
SENDKIT_API_KEY=sk_your_sendkit_api_key
MAIL_FROM_ADDRESS="notifications@yourdomain.com"
MAIL_FROM_NAME="${APP_NAME}"
That’s it — no DNS warm-up, no domain verification dance to get the first emails out, and the free tier doesn’t expire.

SMTP

If you’d rather use your own SMTP server:
MAIL_MAILER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=your_username
MAIL_PASSWORD=your_password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="notifications@yourdomain.com"
MAIL_FROM_NAME="${APP_NAME}"

Emails sent by TryPost

EmailWhen it’s sent
Post publishedA scheduled post was successfully published
Post failedA post failed to publish on one or more platforms
Account disconnectedA social account lost its authorization and needs reconnection
Connections checkMultiple accounts in a workspace were found disconnected
Workspace inviteA team member is invited to join a workspace
Email verificationA new user needs to verify their email address
Password resetA user requests a password reset

WebSockets (Reverb)

TryPost uses Laravel Reverb for real-time updates (live post status, notifications).
REVERB_APP_ID=1001
REVERB_APP_KEY=your-reverb-key
REVERB_APP_SECRET=your-reverb-secret

# Public hostname / port the browser will connect to
REVERB_HOST="localhost"
REVERB_PORT=8080
REVERB_SCHEME=http

# Bind address the Reverb server listens on (defaults to 0.0.0.0:8080)
REVERB_SERVER_HOST=0.0.0.0
REVERB_SERVER_PORT=8080

VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"
VariableDescription
REVERB_APP_IDUnique application ID
REVERB_APP_KEYApplication key for client connections
REVERB_APP_SECRETSecret key for server-side authentication
REVERB_HOSTPublic hostname the browser uses to connect (advertised to clients)
REVERB_PORTPublic port the browser connects to
REVERB_SCHEMEProtocol: http or https
REVERB_SERVER_HOSTBind address the Reverb server listens on. Defaults to 0.0.0.0.
REVERB_SERVER_PORTPort the Reverb server listens on. Defaults to 8080.
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’s documentation for step-by-step setup.
Bluesky and Mastodon don’t require API credentials — they work out of the box.

All platform credentials

# LinkedIn (https://developer.linkedin.com)
LINKEDIN_CLIENT_ID=
LINKEDIN_CLIENT_SECRET=
LINKEDIN_CLIENT_REDIRECT="${APP_URL}/accounts/linkedin/callback"
LINKEDIN_PAGE_CLIENT_REDIRECT="${APP_URL}/accounts/linkedin-page/callback"

# X / Twitter (https://developer.twitter.com)
X_CLIENT_ID=
X_CLIENT_SECRET=
X_CLIENT_REDIRECT="${APP_URL}/accounts/x/callback"

# Facebook (https://developers.facebook.com)
FACEBOOK_CLIENT_ID=
FACEBOOK_CLIENT_SECRET=
FACEBOOK_CLIENT_REDIRECT="${APP_URL}/accounts/facebook/callback"

# Instagram (https://developers.facebook.com)
INSTAGRAM_CLIENT_ID=
INSTAGRAM_CLIENT_SECRET=
INSTAGRAM_CLIENT_REDIRECT="${APP_URL}/accounts/instagram/callback"

# Threads (https://developers.facebook.com)
THREADS_CLIENT_ID=
THREADS_CLIENT_SECRET=
THREADS_CLIENT_REDIRECT="${APP_URL}/accounts/threads/callback"

# TikTok (https://developers.tiktok.com)
TIKTOK_CLIENT_ID=
TIKTOK_CLIENT_SECRET=
TIKTOK_CLIENT_REDIRECT="${APP_URL}/accounts/tiktok/callback"

# Google / YouTube (https://console.cloud.google.com)
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_CLIENT_REDIRECT="${APP_URL}/accounts/youtube/callback"

# Pinterest (https://developers.pinterest.com)
PINTEREST_CLIENT_ID=
PINTEREST_CLIENT_SECRET=
PINTEREST_CLIENT_REDIRECT="${APP_URL}/accounts/pinterest/callback"

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.
LINKEDIN_ENABLED=true
LINKEDIN_PAGE_ENABLED=true
X_ENABLED=true
TIKTOK_ENABLED=true
YOUTUBE_ENABLED=true
FACEBOOK_ENABLED=true
INSTAGRAM_ENABLED=true
INSTAGRAM_FACEBOOK_ENABLED=true
THREADS_ENABLED=true
PINTEREST_ENABLED=true
BLUESKY_ENABLED=true
MASTODON_ENABLED=true
Set any platform to false to hide it from the UI. All platforms are enabled by default.

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.

Google

Google login reuses the OAuth credentials from the YouTube integration, with a separate callback URL.
GOOGLE_AUTH_ENABLED=true
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_AUTH_CALLBACK="${APP_URL}/auth/google/callback"
In the Google Cloud Console, add both callback URLs to your OAuth 2.0 client:
  • https://your-domain.com/accounts/youtube/callback (YouTube connection)
  • https://your-domain.com/auth/google/callback (Google login)

GitHub

GITHUB_AUTH_ENABLED=true
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
GITHUB_AUTH_CALLBACK="${APP_URL}/auth/github/callback"
Register a new OAuth App at github.com/settings/developers and set the Authorization callback URL to ${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.
AI_TEXT_PROVIDER=openai
AI_TEXT_MODEL=gpt-5.4
OPENAI_API_KEY=sk-...

# Optional — image generation for the AI Create wizard
AI_IMAGE_PROVIDER=openai

# Optional — voiceover / TTS (used by future video flows)
AI_AUDIO_PROVIDER=eleven
ELEVENLABS_API_KEY=
VariableDescription
AI_TEXT_PROVIDERopenai (default), anthropic, gemini, azure, groq, xai, deepseek, mistral, ollama, openrouter, cohere, jina, or voyageai.
AI_TEXT_MODELModel identifier for the text provider. Defaults to gpt-5.4.
AI_IMAGE_PROVIDERProvider used for AI image generation in the Create wizard. Defaults to openai. The active OpenAI image model is hardcoded to gpt-image-2.
AI_AUDIO_PROVIDERTTS provider. openai (default) or eleven. Note the key is eleven, not elevenlabs — setting elevenlabs will not resolve.
Provider API keysEach provider reads its own env: OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, XAI_API_KEY, DEEPSEEK_API_KEY, GROQ_API_KEY, MISTRAL_API_KEY, OPENROUTER_API_KEY, COHERE_API_KEY, JINA_API_KEY, VOYAGEAI_API_KEY, ELEVENLABS_API_KEY. Ollama uses OLLAMA_BASE_URL (no key by default).
Self-hosted instances skip the credit/quota check entirely (SELF_HOSTED=true), so AI calls go straight to the configured provider — you pay the provider directly.

Asset library (Unsplash & Giphy)

The Assets page exposes optional Unsplash and Giphy tabs. Configure these to enable them:
UNSPLASH_ACCESS_KEY=
UNSPLASH_SECRET_KEY=

GIPHY_API_KEY=
Without these keys, the Library tab still works — only the stock-photo and GIF tabs are hidden.

Analytics (optional)

PostHog

POSTHOG_ENABLED=true
POSTHOG_API_KEY=phc_your_key
POSTHOG_HOST=https://us.i.posthog.com

VITE_POSTHOG_API_KEY="${POSTHOG_API_KEY}"
VITE_POSTHOG_HOST="${POSTHOG_HOST}"
POSTHOG_ENABLED gates the entire integration — without it set to true, the keys are ignored.

Google Tag Manager

GTM_ID=GTM-XXXXXXX
Both are optional and only needed if you want to track usage analytics.

Horizon (Queue Dashboard)

Laravel Horizon provides a dashboard to monitor your queues. Access it at /horizon.
HORIZON_ALLOWED_EMAILS=admin@example.com,dev@example.com
VariableDescription
HORIZON_ALLOWED_EMAILSComma-separated list of emails allowed to access Horizon in production
If not set, Horizon dashboard will be inaccessible in non-local environments.

Next Steps