# Table of Contents - [Introduction - Postiz Docs](#introduction-postiz-docs) - [Public API - Postiz Docs](#public-api-postiz-docs) - [How it works - Postiz Docs](#how-it-works-postiz-docs) - [Quickstart - Postiz Docs](#quickstart-postiz-docs) - [Docker Compose - Postiz Docs](#docker-compose-postiz-docs) - [Docker - Postiz Docs](#docker-postiz-docs) - [Helm - Postiz Docs](#helm-postiz-docs) - [Development Environment - Postiz Docs](#development-environment-postiz-docs) - [Dev Container - Postiz Docs](#dev-container-postiz-docs) - [Coolify - Postiz Docs](#coolify-postiz-docs) - [Nginx - Postiz Docs](#nginx-postiz-docs) - [Traefik + Docker Compose - Postiz Docs](#traefik-docker-compose-postiz-docs) - [Caddy - Postiz Docs](#caddy-postiz-docs) - [How to add a new provider - Postiz Docs](#how-to-add-a-new-provider-postiz-docs) - [Email Notifications - Postiz Docs](#email-notifications-postiz-docs) - [Discord - Postiz Docs](#discord-postiz-docs) - [R2 Configuration - Postiz Docs](#r2-configuration-postiz-docs) - [Providers - Postiz Docs](#providers-postiz-docs) - [Configuration Reference - Postiz Docs](#configuration-reference-postiz-docs) - [Dribbble - Postiz Docs](#dribbble-postiz-docs) - [Instagram - Postiz Docs](#instagram-postiz-docs) - [Bluesky - Postiz Docs](#bluesky-postiz-docs) - [Facebook - Postiz Docs](#facebook-postiz-docs) - [Linkedin - Postiz Docs](#linkedin-postiz-docs) - [LinkedIn Page - Postiz Docs](#linkedin-page-postiz-docs) - [Pinterest - Postiz Docs](#pinterest-postiz-docs) - [Mastodon - Postiz Docs](#mastodon-postiz-docs) - [Slack - Postiz Docs](#slack-postiz-docs) - [Reddit - Postiz Docs](#reddit-postiz-docs) - [Telegram - Postiz Docs](#telegram-postiz-docs) - [Threads - Postiz Docs](#threads-postiz-docs) - [Tiktok - Postiz Docs](#tiktok-postiz-docs) - [Youtube - Postiz Docs](#youtube-postiz-docs) - [Developer Guide - Postiz Docs](#developer-guide-postiz-docs) - [X - Postiz Docs](#x-postiz-docs) - [404: This page could not be found](#404-this-page-could-not-be-found) - [Support - Postiz Docs](#support-postiz-docs) --- # Introduction - Postiz Docs Introduction ![Hero Dark](/logo/dark.png) What is Postiz?[](#what-is-postiz) ----------------------------------- Postiz helps you to manage all your social media accounts. * Schedule social media and articles. * Generate posts with AI * Exchange or buy posts from other members on the marketplace. [Learn how to install the project and start using it](/quickstart) [Learn the architecture of the project](/howitworks) [Public API](/public-api "Public API") [How it works](/howitworks "How it works") --- # Public API - Postiz Docs Public API Public API allows you to work with Postiz in headless mode[](#public-api-allows-you-to-work-with-postiz-in-headless-mode) -------------------------------------------------------------------------------------------------------------------------- To use the Public API, go to Postiz settings and copy the API Key. With each request you need to pass the API Key in the header `Authorization: {apiKey}`. If you are using the hosted version of Postiz the URL will be `https://api.postiz.com/public/v1`. If you are self-hosting Postiz the URL will be `https://{NEXT_PUBLIC_BACKEND_URL}/public/v1`. There is a limit of **30** requests per hours. Here are the following API endpoints you can use: ### Get all added integrations[](#get-all-added-integrations) GET https://api.postiz.com/public/v1/integrations Response: [\ {\ "id": "asdfasf2342dsaxfcsf",\ "name": "Nevo David",\ "identifier": "facebook",\ "picture": "https://upload.postiz.com/picture.png",\ "disabled": false,\ "profile": "nevo_david",\ "customer": {\ "id": "asdfasf2342dsaxfcsfsadfsadf",\ "name": "My Customer"\ }\ }\ ] * * * ### Upload a new file (from-data)[](#upload-a-new-file-from-data) POST https://api.postiz.com/public/v1/upload Payload: `file` - File Response: { "id": "e639003b-f727-4a1e-87bd-74a2c48ae41e", "name": "vXJYn8EzSB.png", "path": "https://uploads.gitroom.com/vXJYn8EzSB.png", "organizationId": "85460a39-6329-4cf4-a252-187ce89a3480", "createdAt": "2024-12-14T08:18:54.274Z", "updatedAt": "2024-12-14T08:18:54.274Z" } * * * ### Post list[](#post-list) GET https://api.postiz.com/public/v1/posts Query: | Name | Type | Value | | --- | --- | --- | | display | string | day \| week \| month | | day | number | 0-6 | | week | number | 1-52 | | month | number | 1-12 | | year | number | 2022+ | \*\* day is required if display is day \*\* week is required if display is week or day \*\* month is required if display is month or week \*\* year is required Response: { "posts": [\ {\ "id": "cm4gklk8o00008copo77fa0f8",\ "content": "blabla",\ "publishDate": "2024-12-09T05:06:00.000Z",\ "releaseURL": "https://twitter.com/nevodavid/status/1865986385708204316",\ "state": "QUEUE|PUBLISHED|ERROR|DRAFT",\ "integration": {\ "id": "cm4ean69r0003w8w1cdomox9n",\ "providerIdentifier": "x",\ "name": "Nevo David",\ "picture": "https://uploads.gitroom.com/5g9mEIVCAq.jpeg"\ }\ }\ ] } * * * ### Create / update a post[](#create--update-a-post) POST https://api.postiz.com/public/v1/posts Payload: { "type": "draft|schedule|now", "date": "2024-12-14T08:18:54.274Z", "posts": [\ {\ "integration": {\ "id": "asdfsad23rwdfasfsddc"\ },\ "value": [\ {\ "content": "This is my cool post",\ "id": "Only if you want to edit an existing post",\ "image": [\ {\ "id": "string"\ }\ ]\ }\ ],\ "group": "uniqueId for all the posts in the same group",\ "settings": {\ "[key]": "check each integration DTOs in the files, or wait for the error on a new request"\ }\ }\ ] } Response: { "id": "e639003b-f727-4a1e-87bd-74a2c48ae41e" } * * * ### Delete a post[](#delete-a-post) DELETE https://api.postiz.com/public/v1/posts/:id Response: { "id": "e639003b-f727-4a1e-87bd-74a2c48ae41e" } [Introduction](/introduction "Introduction") --- # How it works - Postiz Docs How it works Architecture[](#architecture) ------------------------------ Postiz is composed of 4 main services and 3 external services - all 4 of the main services typically run within a **single docker container**, and talk to each other through HTTP. Those 4 main servers typically talk to other containers, running the external services - the SQL Database, Redis Queue and Storage. * [Frontend](#frontend) - Provides the Web user interface, talks to the Backend. * [Backend](#backend) - Does all the real work, provides an API for the frontend, and posts work to the redis queue. * [Workers](#worker) - Consumes work from the Redis Queue. * [Cron](#cron) - Run jobs at scheduled times. * [Redis Queue](#redis) - A simple queue for the workers to consume work from. * [SQL Database](#db) - Stores all the data, Postgres is typically used, but any SQL database can be used. * [Storage](#storage) - Stores all the files, this used to be CloudFlare R2 as the default, but now it’s just a local file system. ### Frontend[](#frontend) The frontend is the part that you see, the web interface. It relies on the backend to: * Schedule posts * Show analytics * Manage users ### Backend[](#backend) The backend is the “brain” of Postiz, and coordinates all the work. Typically the SQL database it talks to is Postgres, but other databases can be used. ### Cron[](#cron) The cron service does the following; * Refresh tokens from different social media platforms. * Check for trending change every hour and inform users about it. * Sync the amount of stars for every repository at the end of the day. ### Worker[](#worker) The worker services does the following; * Post scheduled posts to social media platforms. * Perform multiple jobs coming from the cron. [Introduction](/introduction "Introduction") [Quickstart](/quickstart "Quickstart") --- # Quickstart - Postiz Docs Quickstart Self Hosted installation options[](#self-hosted-installation-options) ---------------------------------------------------------------------- You can choose between the following installation options; * [Docker Compose](/installation/docker-compose) - Recommended option for **users**. * [Development](/installation/development) - Recommended option for **developers**. Cloud hosting platforms[](#cloud-hosting-platforms) ---------------------------------------------------- * [Coolify](/installation/coolify) - recommended if you’re used to Coolify. Advanced installation options[](#advanced-installation-options) ---------------------------------------------------------------- * [Docker (standalone)](/installation/docker) - Run from the command line with Docker. * [Helm](/installation/kubernetes-helm) - Run with Kubernetes + Helm. [How it works](/howitworks "How it works") [Docker Compose](/installation/docker-compose "Docker Compose") --- # Docker Compose - Postiz Docs InstallationDocker Compose Docker Compose[](#docker-compose) ---------------------------------- This guide assumes that you have docker installed, with a reasonable amount of resources to run Postiz. This Docker Compose setup has been tested with; * Virtual Machine, Ubuntu 24.04, 4Gb RAM, 2 vCPUs. Installation Prerequisites[](#installation-prerequisites) ---------------------------------------------------------- This section will ask you to install & configure several services exaplained below. ### Network Requirements[](#network-requirements) #### HTTPS / HTTP Requirement[](#https--http-requirement) Postiz marks it’s login cookies as Secure, this is called “secure context” in modern web browsers. If you want to use an secure Login Process, you need to set up an Certificate, which can be done via Reverse Proxy like Caddy or Nginx. If you cannot use a certificate (HTTPS), add the following environment variable to your `.env` file: NOT_SECURED=true **Security Warning**: Setting `NOT_SECURED=true` disables secure cookie requirements. This should only be used in development environments or when you fully understand the security implications. Not recommended for production use. #### Network Ports[](#network-ports) * **5000/tcp**: for a single **single entry point** for postiz when running in a container. This is the one port your reverse proxy should talk to. * **4200/tcp**: for the **Frontend** service (the web interface). Most users **do not** need to expose this port publicly. * **3000/tcp**: for the **Backend** service (the API). Most users **do not** need to expose this port publicly. * **5432/tcp**: for the **Postgres** container. Most users **do not** need to expose this port publicly. * **6379/tcp**: for the **Redis** container. Most users **do not** need to expose this port publicly. If you are using docker images, we recommend just exposing port 5000 to your external proxy. This will reduce the likelihood of misconfiguration, and make it easier to manage your network. ### Installation Prerequisites[](#installation-prerequisites) The docker containers for Postiz are entirely configured with environment variables. * **Option A** - environment variables in your `docker-compose.yml` file * **Option B** - environment variables in a `postiz.env` file mounted in `/config` for the Postiz container only * **Option C** - environment variables in a `.env` file next to your `docker-compose.yml` file (not recommended). … or a mixture of the above options! There is a [configuration reference](/configuration/reference) page with a list of configuration settings. Network Requirements[](#network-requirements) ---------------------------------------------- services: postiz: image: ghcr.io/gitroomhq/postiz-app:latest container_name: postiz restart: always environment: # You must change these. Replace `postiz.your-server.com` with your DNS name - this needs to be exactly the URL you're accessing Postiz on. MAIN_URL: "https://postiz.your-server.com" FRONTEND_URL: "https://postiz.your-server.com" NEXT_PUBLIC_BACKEND_URL: "https://postiz.your-server.com/api" JWT_SECRET: "random string that is unique to every install - just type random characters here!" # These defaults are probably fine, but if you change your user/password, update it in the # postiz-postgres or postiz-redis services below. DATABASE_URL: "postgresql://postiz-user:postiz-password@postiz-postgres:5432/postiz-db-local" REDIS_URL: "redis://postiz-redis:6379" BACKEND_INTERNAL_URL: "http://localhost:3000" IS_GENERAL: "true" # Required for self-hosting. # The container images are pre-configured to use /uploads for file storage. # You probably should not change this unless you have a really good reason! STORAGE_PROVIDER: "local" UPLOAD_DIRECTORY: "/uploads" NEXT_PUBLIC_UPLOAD_DIRECTORY: "/uploads" volumes: - postiz-config:/config/ - postiz-uploads:/uploads/ ports: - 5000:5000 networks: - postiz-network depends_on: postiz-postgres: condition: service_healthy postiz-redis: condition: service_healthy postiz-postgres: image: postgres:17-alpine container_name: postiz-postgres restart: always environment: POSTGRES_PASSWORD: postiz-password POSTGRES_USER: postiz-user POSTGRES_DB: postiz-db-local volumes: - postgres-volume:/var/lib/postgresql/data networks: - postiz-network healthcheck: test: pg_isready -U postiz-user -d postiz-db-local interval: 10s timeout: 3s retries: 3 postiz-redis: image: redis:7.2 container_name: postiz-redis restart: always healthcheck: test: redis-cli ping interval: 10s timeout: 3s retries: 3 volumes: - postiz-redis-data:/data networks: - postiz-network volumes: postgres-volume: external: false postiz-redis-data: external: false postiz-config: external: false postiz-uploads: external: false networks: postiz-network: external: false HTTPS / HTTP Requirement[](#https--http-requirement) ----------------------------------------------------- Save the file contents to `docker-compose.yml` in your directory you create for postiz. Run `docker compose up` to start the services. ⚠️ **Note** When you change variables, you must run `docker compose down` and then `docker compose up` to recreate these containers with these updated variables. Look through the logs for startup errors, and if you have problems, check out the [support](/support) page. If everything looks good, then you can access the Postiz web interface at [https://postiz.your-server.com](https://postiz.your-server.com) Controlling container services[](#controlling-container-services) ------------------------------------------------------------------ When the environment variable `POSTIZ_APPS` is not set, or is set to an empty string, all services will be started in a single container. This is normally fine for small, personal deployments. However, you can only start specific services within the docker container by changing this environement variable. If you need to scale, you can experiement with having multiple containers defined like; * Frontend only: `POSTIZ_APPS="frontend"` * Backend only: `POSTIZ_APPS="backend"` * Worker and Cron only: `POSTIZ_APPS="worker cron"` Network Ports[](#network-ports) -------------------------------- [Learn the architecture of the project](/howitworks) [Set up providers such as Linkedin, X and Reddit](/providers) [Quickstart](/quickstart "Quickstart") [Docker (standalone)](/installation/docker "Docker (standalone)") --- # Docker - Postiz Docs [Installation](/installation/docker-compose "Installation") Docker (standalone) ⚠️ **This is a not a recommended installation option.** * **For Users**: [Docker Compose](/installation/docker-compose) is recommended. * **For Developers**: [Developer Environment](/installation/development) is recommended. The instructions on this page are provided for more advanced or custom installations. Please only use these if the standard options don’t fit your needs. Installation Prerequisites[](#installation-prerequisites) ---------------------------------------------------------- This section will ask you to install & configure several services exaplained below. ### Network Requirements[](#network-requirements) #### HTTPS / HTTP Requirement[](#https--http-requirement) Postiz marks it’s login cookies as Secure, this is called “secure context” in modern web browsers. If you want to use an secure Login Process, you need to set up an Certificate, which can be done via Reverse Proxy like Caddy or Nginx. If you cannot use a certificate (HTTPS), add the following environment variable to your `.env` file: NOT_SECURED=true **Security Warning**: Setting `NOT_SECURED=true` disables secure cookie requirements. This should only be used in development environments or when you fully understand the security implications. Not recommended for production use. #### Network Ports[](#network-ports) * **5000/tcp**: for a single **single entry point** for postiz when running in a container. This is the one port your reverse proxy should talk to. * **4200/tcp**: for the **Frontend** service (the web interface). Most users **do not** need to expose this port publicly. * **3000/tcp**: for the **Backend** service (the API). Most users **do not** need to expose this port publicly. * **5432/tcp**: for the **Postgres** container. Most users **do not** need to expose this port publicly. * **6379/tcp**: for the **Redis** container. Most users **do not** need to expose this port publicly. If you are using docker images, we recommend just exposing port 5000 to your external proxy. This will reduce the likelihood of misconfiguration, and make it easier to manage your network. Set environment variables ========================= Postiz configuration is entirely via environment variables for now. You might be used to setting environment variables when starting containers, however postiz needs a LOT of environment variables, so setting these on command line or in a docker-compose is probably not practical for long term maintainability. It is recommended to use a `.env` file, which the Postiz containers look for in /config. Docker will automatically create this file for you on a docker volume the first time you start up Postiz. The default .env file can be found here; [example .env file](https://raw.githubusercontent.com/gitroomhq/postiz-app/main/.env.example) Installation Prerequisites[](#installation-prerequisites) ---------------------------------------------------------- This example below shows how to create the Postiz container on the command line. Note that you will need to replace the `./config` with the path to your config directory. You will also need Postgres and Redis running. docker create --name postiz -v postiz-uploads:/uploads/ -v postiz-config:/config/ -p 5000:5000 ghcr.io/gitroomhq/postiz-app:latest Controlling container services[](#controlling-container-services) ------------------------------------------------------------------ When the environment variable `POSTIZ_APPS` is not set, or is set to an empty string, all services will be started in a single container. This is normally fine for small, personal deployments. However, you can only start specific services within the docker container by changing this environement variable. If you need to scale, you can experiement with having multiple containers defined like; * Frontend only: `POSTIZ_APPS="frontend"` * Backend only: `POSTIZ_APPS="backend"` * Worker and Cron only: `POSTIZ_APPS="worker cron"` Network Requirements[](#network-requirements) ---------------------------------------------- [Configure uploads](/configuration/r2) [Learn the architecture of the project](/howitworks) [Set up email for notifications](/emails) [Set up providers such as Linkedin, X and Reddit](/providers) [Docker Compose](/installation/docker-compose "Docker Compose") [Kubernetes with Helm](/installation/kubernetes-helm "Kubernetes with Helm") --- # Helm - Postiz Docs [Installation](/installation/docker-compose "Installation") Kubernetes with Helm **NOTE:** This page is marked “earlydoc”, or “early documentation”, which means it might be brief, or contain information about parts of the app that are under heavy development. If you encounter issues with instructions found here, please check out the [support](/support) page for options. ⚠️ **This is a not a recommended installation option.** * **For Users**: [Docker Compose](/installation/docker-compose) is recommended. * **For Developers**: [Developer Environment](/installation/development) is recommended. The instructions on this page are provided for more advanced or custom installations. Please only use these if the standard options don’t fit your needs. Installation Prerequisites[](#installation-prerequisites) ---------------------------------------------------------- This section will ask you to install & configure several services exaplained below. ### Network Requirements[](#network-requirements) #### HTTPS / HTTP Requirement[](#https--http-requirement) Postiz marks it’s login cookies as Secure, this is called “secure context” in modern web browsers. If you want to use an secure Login Process, you need to set up an Certificate, which can be done via Reverse Proxy like Caddy or Nginx. If you cannot use a certificate (HTTPS), add the following environment variable to your `.env` file: NOT_SECURED=true **Security Warning**: Setting `NOT_SECURED=true` disables secure cookie requirements. This should only be used in development environments or when you fully understand the security implications. Not recommended for production use. #### Network Ports[](#network-ports) * **5000/tcp**: for a single **single entry point** for postiz when running in a container. This is the one port your reverse proxy should talk to. * **4200/tcp**: for the **Frontend** service (the web interface). Most users **do not** need to expose this port publicly. * **3000/tcp**: for the **Backend** service (the API). Most users **do not** need to expose this port publicly. * **5432/tcp**: for the **Postgres** container. Most users **do not** need to expose this port publicly. * **6379/tcp**: for the **Redis** container. Most users **do not** need to expose this port publicly. If you are using docker images, we recommend just exposing port 5000 to your external proxy. This will reduce the likelihood of misconfiguration, and make it easier to manage your network. Installation Prerequisites[](#installation-prerequisites) ---------------------------------------------------------- Postiz has a helm chart that is in very active development. You can find it here; Note that this is a OCI compliant helm chart, meaning that you don’t do `helm repo add`, and if you are using Flux or Helm, you must set them to OCI mode. [https://github.com/gitroomhq/postiz-helmchart](https://github.com/gitroomhq/postiz-helmchart) The `values.yml` file can be found in the repository, or a direct link to it is: [https://github.com/gitroomhq/postiz-helmchart/blob/main/charts/postiz/values.yaml](https://github.com/gitroomhq/postiz-helmchart/blob/main/charts/postiz/values.yaml) Network Requirements[](#network-requirements) ---------------------------------------------- [Set up providers such as Linkedin, X and Reddit](/providers) [Learn the architecture of the project](/howitworks) [Docker (standalone)](/installation/docker "Docker (standalone)") [Development Environment](/installation/development "Development Environment") --- # Development Environment - Postiz Docs [Installation](/installation/docker-compose "Installation") Development Environment This is currently the recommended option to install Postiz in a supportable configuration. The docker images are in active and heavy development for now. Tested configurations[](#tested-configurations) ------------------------------------------------ * MacOS * Linux (Fedora 40) Naturally you can use these instructions to setup a development environment on any platform, but there may not be much experience in the community to help you with any issues you may encounter. ### Warning about Windows[](#warning-about-windows) Several users using Windows (and WSL) have reported issues with the setup. This is not well tested as the main developers of the project do not use Windows/WSL for development. If you are using Windows and encounter issues, please let us know in the [support](/support) page. Installation Prerequisites[](#installation-prerequisites) ---------------------------------------------------------- This section will ask you to install & configure several services exaplained below. ### Network Requirements[](#network-requirements) #### HTTPS / HTTP Requirement[](#https--http-requirement) Postiz marks it’s login cookies as Secure, this is called “secure context” in modern web browsers. If you want to use an secure Login Process, you need to set up an Certificate, which can be done via Reverse Proxy like Caddy or Nginx. If you cannot use a certificate (HTTPS), add the following environment variable to your `.env` file: NOT_SECURED=true **Security Warning**: Setting `NOT_SECURED=true` disables secure cookie requirements. This should only be used in development environments or when you fully understand the security implications. Not recommended for production use. #### Network Ports[](#network-ports) * **5000/tcp**: for a single **single entry point** for postiz when running in a container. This is the one port your reverse proxy should talk to. * **4200/tcp**: for the **Frontend** service (the web interface). Most users **do not** need to expose this port publicly. * **3000/tcp**: for the **Backend** service (the API). Most users **do not** need to expose this port publicly. * **5432/tcp**: for the **Postgres** container. Most users **do not** need to expose this port publicly. * **6379/tcp**: for the **Redis** container. Most users **do not** need to expose this port publicly. If you are using docker images, we recommend just exposing port 5000 to your external proxy. This will reduce the likelihood of misconfiguration, and make it easier to manage your network. ### Installation Prerequisites[](#installation-prerequisites) * **Node.js** - for running the code! (version 18+) * **PostgreSQL** - or any other SQL database (instructions beleow suggest Docker) * **Redis** - for handling worker queues (instructions below suggest Docker) We have some messages from users who are using Windows, which should work, but they are not tested well yet. Network Requirements[](#network-requirements) ---------------------------------------------- ### HTTPS / HTTP Requirement[](#https--http-requirement) A complete guide of how to install NodeJS can be found [here](https://nodejs.org/en/download/) . ### Network Ports[](#network-ports) You can choose **Option A** to **Option B** to install the database. #### Prerequisite Local Services[](#prerequisite-local-services) You can install [Docker](https://www.docker.com/products/docker-desktop) and run: docker run -e POSTGRES_USER=root -e POSTGRES_PASSWORD=your_password --name postgres -p 5432:5432 -d postgres docker run --name redis -p 6379:6379 -d redis #### Installation Instructions[](#installation-instructions) Download the [docker-compose.yaml file here](https://raw.githubusercontent.com/gitroomhq/postiz-app/main/docker-compose.dev.yaml) , or grab it from the repository in the next step. docker compose -f "docker-compose.dev.yaml" up NodeJS (version 18+)[](#nodejs-version-18) ------------------------------------------- ### PostgreSQL (or any other SQL database) & Redis[](#postgresql-or-any-other-sql-database--redis) git clone https://github.com/gitroomhq/postiz-app.git ### Option A) Postgres and Redis as Single containers[](#option-a-postgres-and-redis-as-single-containers) Copy the `.env.example` file to `.env` and fill in the values # Required Settings DATABASE_URL="postgresql://postiz-user:postiz-password@localhost:5432/postiz-db-local" REDIS_URL="redis://localhost:6379" JWT_SECRET="random string for your JWT secret, make it long" FRONTEND_URL="http://localhost:4200" NEXT_PUBLIC_BACKEND_URL="http://localhost:3000" BACKEND_INTERNAL_URL="http://localhost:3000" # Optional. Your upload directory path if you host your files locally. UPLOAD_DIRECTORY="/opt/postiz/uploads/" # Optional: your upload directory slug if you host your files locally. NEXT_PUBLIC_UPLOAD_STATIC_DIRECTORY="" # Your email provider, optional EMAIL_PROVIDER="resend|nodemailer" RESEND_API_KEY="re_1234567890" # api key if you choose resend EMAIL_HOST="smtp.gmail.com" # smtp host if you choose nodemailer EMAIL_PORT="465" # smtp port if you choose nodemailer EMAIL_SECURE="true" # smtp secure if you choose nodemailer EMAIL_USER="user" # smtp user if you choose nodemailer EMAIL_PASS="pass" # smtp pass if you choose nodemailer ## These are dummy values, you must create your own from Cloudflare. ## Remember to set your public internet IP address in the allow-list for the API token. CLOUDFLARE_ACCOUNT_ID="QhcMSXQyPuMCRpSQcSYdEuTYgHeCXHbu" CLOUDFLARE_ACCESS_KEY="dcfCMSuFEeCNfvByUureMZEfxWJmDqZe" CLOUDFLARE_SECRET_ACCESS_KEY="zTTMXBmtyLPwHEdpACGHgDgzRTNpTJewiNriLnUS" CLOUDFLARE_BUCKETNAME="postiz" CLOUDFLARE_BUCKET_URL="https://QhcMSXQyPuMCRpSQcSYdEuTYgHeCXHbu.r2.cloudflarestorage.com/" CLOUDFLARE_REGION="auto" # Social Media API Settings X_API_KEY="Twitter API key for normal oAuth not oAuth2" X_API_SECRET="Twitter API secret for normal oAuth not oAuth2" LINKEDIN_CLIENT_ID="Linkedin Client ID" LINKEDIN_CLIENT_SECRET="Linkedin Client Secret" REDDIT_CLIENT_ID="Reddit Client ID" REDDIT_CLIENT_SECRET="Linkedin Client Secret" GITHUB_CLIENT_ID="GitHub Client ID" GITHUB_CLIENT_SECRET="GitHub Client Secret" # AI OPENAI_API_KEY="OpenAI API key" # Developer Settings NX_ADD_PLUGINS=false IS_GENERAL="true" # required for now ### Option B) Postgres and Redis as docker-compose[](#option-b-postgres-and-redis-as-docker-compose) npm install ### Build Postiz[](#build-postiz) npm run prisma-db-push ### Clone the repository[](#clone-the-repository) npm run dev If everything is running successfully, open [http://localhost:4200](http://localhost:4200) in your browser! If everything is not running - you had errors in the steps above, please head over to our [support](/support) page. Set environment variables[](#set-environment-variables) -------------------------------------------------------- [Configure uploads](/configuration/r2) [Learn the architecture of the project](/howitworks) [Set up email for notifications](/emails) [Set up providers such as Linkedin, X and Reddit](/providers) [Kubernetes with Helm](/installation/kubernetes-helm "Kubernetes with Helm") [Devcontainer](/installation/devcontainer "Devcontainer") --- # Dev Container - Postiz Docs [Installation](/installation/docker-compose "Installation") Devcontainer **NOTE:** This page is marked “earlydoc”, or “early documentation”, which means it might be brief, or contain information about parts of the app that are under heavy development. If you encounter issues with instructions found here, please check out the [support](/support) page for options. ⚠️ **This is a not a recommended installation option.** * **For Users**: [Docker Compose](/installation/docker-compose) is recommended. * **For Developers**: [Developer Environment](/installation/development) is recommended. The instructions on this page are provided for more advanced or custom installations. Please only use these if the standard options don’t fit your needs. npm install -g @devcontainers/cli devcontainer up [Development Environment](/installation/development "Development Environment") [Coolify](/installation/coolify "Coolify") --- # Coolify - Postiz Docs [Installation](/installation/docker-compose "Installation") Coolify **NOTE:** This page is marked “earlydoc”, or “early documentation”, which means it might be brief, or contain information about parts of the app that are under heavy development. If you encounter issues with instructions found here, please check out the [support](/support) page for options. ⚠️ **Warning:** This current Documentation does **not** work in Coolify. We are working on an fix for this Issue. Installation Prerequisites[](#installation-prerequisites) ---------------------------------------------------------- This section will ask you to install & configure several services exaplained below. ### Network Requirements[](#network-requirements) #### HTTPS / HTTP Requirement[](#https--http-requirement) Postiz marks it’s login cookies as Secure, this is called “secure context” in modern web browsers. If you want to use an secure Login Process, you need to set up an Certificate, which can be done via Reverse Proxy like Caddy or Nginx. If you cannot use a certificate (HTTPS), add the following environment variable to your `.env` file: NOT_SECURED=true **Security Warning**: Setting `NOT_SECURED=true` disables secure cookie requirements. This should only be used in development environments or when you fully understand the security implications. Not recommended for production use. #### Network Ports[](#network-ports) * **5000/tcp**: for a single **single entry point** for postiz when running in a container. This is the one port your reverse proxy should talk to. * **4200/tcp**: for the **Frontend** service (the web interface). Most users **do not** need to expose this port publicly. * **3000/tcp**: for the **Backend** service (the API). Most users **do not** need to expose this port publicly. * **5432/tcp**: for the **Postgres** container. Most users **do not** need to expose this port publicly. * **6379/tcp**: for the **Redis** container. Most users **do not** need to expose this port publicly. If you are using docker images, we recommend just exposing port 5000 to your external proxy. This will reduce the likelihood of misconfiguration, and make it easier to manage your network. ### Installation Prerequisites[](#installation-prerequisites) * **Name**: Postiz * Select the “production” environment. ### Network Requirements[](#network-requirements) Copy the Coolify docker-compose file here - and be careful to read the comments about variables you must change!; services: postiz: image: ghcr.io/gitroomhq/postiz-app:latest container_name: postiz restart: always environment: # You must change these. `yourServerAddress` this needs to be exactly the URL you're accessing Postiz on. MAIN_URL: "https://postiz.your-server.com" FRONTEND_URL: "https://postiz.your-server.com" NEXT_PUBLIC_BACKEND_URL: "https://postiz.your-server.com/api" JWT_SECRET: "random string that is unique to every install - just type random characters here!" # These defaults are probably fine, but if you change your user/password, update it in the # postiz-postgres or postiz-redis services below. DATABASE_URL: "postgresql://postiz-user:postiz-password@postiz-postgres:5432/postiz-db-local" REDIS_URL: "redis://postiz-redis:6379" BACKEND_INTERNAL_URL: "http://localhost:3000" IS_GENERAL: "true" # Required for self-hosting. # The container images are pre-configured to use /uploads for file storage. # You probably should not change this unless you have a really good reason! STORAGE_PROVIDER: "local" UPLOAD_DIRECTORY: "/uploads" NEXT_PUBLIC_UPLOAD_DIRECTORY: "/uploads" volumes: - postiz-config:/config/ - postiz-uploads:/uploads/ ports: - 5000:5000 networks: - postiz-network labels: - "traefik.enable=true" - "traefik.https.routers..rule=Host(`coolify.io`) && PathPrefix(`/`)" - "traefik.https.routers..entryPoints=https" depends_on: postiz-postgres: condition: service_healthy postiz-redis: condition: service_healthy postiz-postgres: image: postgres:14.5 container_name: postiz-postgres restart: always environment: POSTGRES_PASSWORD: postiz-password POSTGRES_USER: postiz-user POSTGRES_DB: postiz-db-local volumes: - postgres-volume:/var/lib/postgresql/data ports: - 5432:5432 networks: - postiz-network healthcheck: test: pg_isready -U postiz-user -d postiz-db-local interval: 10s timeout: 3s retries: 3 postiz-redis: image: redis:7.2 container_name: postiz-redis restart: always ports: - 6379:6379 healthcheck: test: redis-cli ping interval: 10s timeout: 3s retries: 3 volumes: - postiz-redis-data:/data networks: - postiz-network volumes: postgres-volume: external: false postiz-redis-data: external: false postiz-config: external: false networks: postiz-network: external: false Save the configuration. ### HTTPS / HTTP Requirement[](#https--http-requirement) * In the “Service Stack” tab; * Suggest changing the “Service Name” to just “postiz” for clarity. * Click the “Connect to Predefined Network” tab. * Check that 3 services are defined - `postiz`, `postiz-postgres` and `postiz-redis`. * In the “Storages” tab, check that the 3 related volumes are created. ### Network Ports[](#network-ports) Postiz is approximately 2.5Gb and several container layers, it will take some time to download, be patient. You should see “Downloading” and “Extracting” messages. The Postiz dependencies are almost 200k files, and this can take a while. Hopefully you will see a message like `Container postiz-dssc8gc880s88cg08cck884s Started.` in the logs. Once you see this message, close the startup logs view. Check that the services are running in the “Service Stack” tab, and make sure they are not constantly restarting, or failing to start. [Devcontainer](/installation/devcontainer "Devcontainer") [Caddy](/reverse-proxies/caddy "Caddy") --- # Nginx - Postiz Docs [Reverse Proxies](/reverse-proxies/caddy "Reverse Proxies") Nginx **NOTE:** This page is marked “earlydoc”, or “early documentation”, which means it might be brief, or contain information about parts of the app that are under heavy development. If you encounter issues with instructions found here, please check out the [support](/support) page for options. How to add Nginx as a reverse proxy[](#how-to-add-nginx-as-a-reverse-proxy) ---------------------------------------------------------------------------- ℹ️ The following commands are tailored for Ubuntu/Debian systems. If you’re using a different Linux distribution, you may need to adjust package management commands accordingly (e.g., `yum` for CentOS, `brew` for macOS). ### Install Nginx:[](#install-nginx) sudo apt update && sudo apt install nginx -y sudo systemctl start nginx && sudo systemctl enable nginx ### Install Certbot for SSL:[](#install-certbot-for-ssl) sudo apt update && sudo apt install python3-certbot-nginx -y ### Create the Webroot Directory:[](#create-the-webroot-directory) sudo mkdir -p /var/www/certbot/.well-known/acme-challenge && sudo chown -R www-data:www-data /var/www/certbot ### Create a temporary Nginx config for creating SSL certificates[](#create-a-temporary-nginx-config-for-creating-ssl-certificates) 💡 Make sure to change subdomain.domain.tld to your actual subdomain and ensure that it is pointed to your server’s IP address. **Edit the file** `/etc/nginx/sites-available/subdomain.domain.tld` (e.g., use `sudo nano /etc/nginx/sites-available/subdomain.domain.tld` if you’re using `nano`). server { listen 80; listen [::]:80; # IPv6 support server_name ; # CHANGE HERE location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 301 https://$host$request_uri; } # Hide NGINX version for security reasons server_tokens off; } sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/ ### Obtain SSL Certificates Using Webroot method:[](#obtain-ssl-certificates-using-webroot-method) sudo certbot certonly --webroot -w /var/www/certbot -d --email your-email@example.com --agree-tos --no-eff-email ### Edit the Nginx config:[](#edit-the-nginx-config) **Edit the file** `/etc/nginx/sites-available/subdomain.domain.tld` (e.g., use `sudo nano /etc/nginx/sites-available/subdomain.domain.tld` if you’re using `nano`). Copy your config from here: More "robust" and secure config (recommended)Simple config # HTTP -> HTTPS Redirection server { listen 80; listen [::]:80; # IPv6 support server_name ; # CHANGE HERE location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 301 https://$host$request_uri; } # Hide NGINX version for security reasons server_tokens off; } # HTTPS Configuration server { listen 443 ssl http2; listen [::]:443 ssl http2; # Enable HTTP/2 and IPv6 support if you need server_name ; # CHANGE HERE # Hide NGINX version server_tokens off; # SSL Certificates ssl_certificate /etc/letsencrypt/live//fullchain.pem; # CHANGE HERE ssl_certificate_key /etc/letsencrypt/live//privkey.pem; # CHANGE HERE ssl_trusted_certificate /etc/letsencrypt/live//chain.pem; # CHANGE HERE # Security: Stronger SSL Configuration ssl_session_cache shared:SSL:10m; # Cache SSL sessions ssl_session_timeout 1d; # Set session timeout to 1 day ssl_session_tickets off; # Disable SSL session tickets # Use only modern SSL/TLS protocols (disables older insecure ones) ssl_protocols TLSv1.2 TLSv1.3; # Configure SSL ciphers (strong encryption algorithms) ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; # Allow clients to prefer their ciphers # Diffie-Hellman parameter for Perfect Forward Secrecy (PFS) ssl_dhparam /etc/ssl/certs/dhparam.pem; # Generate with `sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048` # OCSP Stapling for improved SSL/TLS performance ssl_stapling on; ssl_stapling_verify on; # DNS resolver for OCSP resolver 1.1.1.1 1.0.0.1 valid=300s; resolver_timeout 5s; # some HTTP Security Headers add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; # HSTS add_header X-Frame-Options "SAMEORIGIN" always; # Prevent Clickjacking add_header X-Content-Type-Options "nosniff" always; # Prevent MIME-type sniffing add_header X-XSS-Protection "1; mode=block" always; # XSS Protection add_header Referrer-Policy "no-referrer" always; # Better privacy control add_header Permissions-Policy "geolocation=(self), microphone=(), camera=()" always; # Limit browser permissions # Reverse Proxy to Postiz application location / { proxy_pass http://localhost:5000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket Support proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # Disable directory listing for security autoindex off; # Increase maximum post size to prevent 413 error with images larger than 2MB (changes max size to 100MB) client_max_body_size 100M; # Enable Gzip compression for better performance gzip on; gzip_comp_level 6; gzip_min_length 1100; gzip_buffers 4 32k; gzip_proxied any; gzip_types text/plain text/css text/javascript application/json application/xml image/svg+xml; # Optional Access/Error Logging access_log /var/log/nginx/.log; # CHANGE HERE error_log /var/log/nginx/.log; # CHANGE HERE } # HTTP -> HTTPS Redirection server { listen 80; server_name ; # CHANGE HERE # Location for Let's Encrypt validation location /.well-known/acme-challenge/ { root /var/www/certbot; } return 301 https://$host$request_uri; # Redirect all traffic to HTTPS } # HTTPS Configuration server { listen 443 ssl; server_name ; # CHANGE HERE # SSL certificate ssl_certificate /etc/letsencrypt/live//fullchain.pem; # CHANGE HERE ssl_certificate_key /etc/letsencrypt/live//privkey.pem; # CHANGE HERE # Proxy requests to Postiz running on port 5000 location / { proxy_pass http://localhost:5000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket Support proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # Optional Access/Error Logging access_log /var/log/nginx/.log; # CHANGE HERE error_log /var/log/nginx/.log; # CHANGE HERE } ### Generate DH Parameters:[](#generate-dh-parameters) (Needed if you are using the “robust” nginx config option) sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 ### Test your Nginx configuration:[](#test-your-nginx-configuration) sudo nginx -t ### Automatic reload Nginx when SSL Certificates are renewed:[](#automatic-reload-nginx-when-ssl-certificates-are-renewed) echo -e '#!/bin/bash\nginx -t && systemctl reload nginx' | sudo tee /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh && sudo chmod a+x /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh ### Reload Nginx[](#reload-nginx) sudo systemctl reload nginx ### Vuola![](#vuola) Your Nginx reverse proxy is now running, securely serving your Postiz instance at your subdomain.domain.tld. 🎉 [Caddy](/reverse-proxies/caddy "Caddy") [Traefik + Docker Compose](/reverse-proxies/traefik "Traefik + Docker Compose") --- # Traefik + Docker Compose - Postiz Docs [Reverse Proxies](/reverse-proxies/caddy "Reverse Proxies") Traefik + Docker Compose **NOTE:** This page is marked “earlydoc”, or “early documentation”, which means it might be brief, or contain information about parts of the app that are under heavy development. If you encounter issues with instructions found here, please check out the [support](/support) page for options. This is a very popular configuration to get an easy reverse proxy up and running with Traefik and Docker Compose. Add Traefik to your Docker Compose file[](#add-traefik-to-your-docker-compose-file) ------------------------------------------------------------------------------------ version: '3.8' services: postiz: ## ## Include all the other configuration from the standard compose example. ## labels: # Router for main Postiz entrypoint (on port 5000) - "traefik.http.routers.postiz.rule=Host(`postiz.example.lan`)" # Replace with your domain - "traefik.http.services.postiz.loadbalancer.server.port=5000" # Internal port for postiz - "traefik.http.routers.postiz.entrypoints=websecure" # Postiz requires HTTPS - "traefik.http.routers.postiz.tls=true" traefik: image: "traefik:v2.9" container_name: "traefik" command: #- "--log.level=DEBUG" - "--api.insecure=true" - "--api.dashboard=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.websecure.address=:443" ports: - "443:443" volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" networks: - postiz-network [Nginx](/reverse-proxies/nginx "Nginx") [How to add a new provider](/configuration/create-provider "How to add a new provider") --- # Caddy - Postiz Docs Reverse ProxiesCaddy This page briefly explains how to use Caddy to reverse proxy Postiz. A configuration file example is below; Example Caddyfile[](#example-caddyfile) ---------------------------------------- postiz.example.lan { reverse_proxy * localhost:5000 tls internal } In this example, we have a single port for Postiz, port 5000, which is the internal proxy built into the Docker container images. The `tls internal` directive is used to enable internal TLS for secure communication. You will need to install the certificate into your browser with this configuration. If you are hosting on a public domain, Caddy allows you to use LetsEncrypt for automatic certificate management. For more information, refer to the [Caddy documentation](https://caddyserver.com/docs/) . Postiz configuration[](#postiz-configuration) ---------------------------------------------- To ensure that Postiz works correctly behind a reverse proxy, you may need to adjust its configuration in your .env file / environment variables. The following variables should be set to the correct values: MAIN_URL="https://postiz.example.lan" FRONTEND_URL="https://postiz.example.lan" NEXT_PUBLIC_BACKEND_URL="https://postiz.example.lan/api" [Coolify](/installation/coolify "Coolify") [Nginx](/reverse-proxies/nginx "Nginx") --- # How to add a new provider - Postiz Docs ConfigurationHow to add a new provider Steps to implement a new provider ================================= 1. ### The backend logic:[](#the-backend-logic) * Define DTO for the settings of the provider * Generate an authentication URL * Authenticate the user from the callback * Refresh the user token 2. ### The frontend logic:[](#the-frontend-logic) * Implement the settings page * Implement the preview page * Upload the provider image Social Media[](#social-media) ------------------------------ ### Backend[](#backend) For our example, we will use the X provider. 1. First, we need to create a DTO for the settings of the provider. head over to `nestjs-libraries/src/dtos/posts/providers-settings` And create a new file `x-provider-settings.dto.ts` (you don’t have to create a DTO if there are no settings) Once created head over to `nestjs-libraries/src/dtos/posts/providers-settings/all.providers.settings.ts` And add the new DTO. Head to `libraries/nestjs-libraries/src/dtos/posts/create.post.dto.ts` look for the discriminator and add another line in the format of { value: DTOClassName, name: 'providerName' }, 2. head over to `libraries/nestjs-libraries/src/integrations/social` And create a new provider file `providerName.provider.ts` The content of the file should look like this: For oAuth2 providers[](#for-oauth2-providers) ---------------------------------------------- import { AuthTokenDetails, PostDetails, PostResponse, SocialProvider, } from '@gitroom/nestjs-libraries/integrations/social/social.integrations.interface'; export class XProvider implements SocialProvider { identifier = 'providerName'; name = 'Provider Name'; async refreshToken(refreshToken: string): Promise { ...refresh the token } async generateAuthUrl() { ...generate the auth url } async authenticate(params: { code: string; codeVerifier: string }) { ...authenticate the user } async post( id: string, accessToken: string, postDetails: PostDetails[] ): Promise { ...post the content } } Take a look at the exising providers to see how to implement the methods. ### Custom functions[](#custom-functions) You might want to create custom functions for the providers for example: get available orgs, get available pages, etc. You can create a public function in the provider for example `organizations` and later call it from a special hook from the frontend. ### Integration Manager[](#integration-manager) Open `libraries/nestjs-libraries/src/integrations/integration.manager.ts` And add the new provider to either `socialIntegrationList` (oAuth2) or `articleIntegrationList` (Token) * * * ### Frontend[](#frontend) 1. Head over to `apps/frontend/src/components/launches/providers` Create a new folder with the providerName Add a new file `providerName.provider.tsx` The content of the file should look like this: import { FC } from 'react'; import { withProvider } from '@gitroom/frontend/components/launches/providers/high.order.provider'; import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values'; import { useIntegration } from '@gitroom/frontend/components/launches/helpers/use.integration'; const ProviderPreview: FC = () => { const { value } = useIntegration(); const settings = useSettings(); return ( ...Preview ); }; const ProviderSettings: FC = () => { const form = useSettings(); const { date } = useIntegration(); return ( ...Settings ); }; export default withProvider(DevtoSettings, DevtoPreview, DTOClassName); If you want to use a custom function for the provider you can use the `useCustomProviderFunction` hook. import { useCustomProviderFunction } from '@gitroom/frontend/components/launches/helpers/use.custom.provider.function'; import { useCallback } from 'react'; const customFunc = useCustomProviderFunction(); // and use it like that: const getOrgs = useCallback(() => { customFunc.get('organizations', { anyKey: 'anyValue' }) }, []); It will automatically interact with the right provider saved for the user. You can look at the other integration to understand what data to put inside. 2. Open `apps/frontend/src/components/launches/providers/show.all.providers.tsx` And add the new provider to the list. {identifier: 'providerName', component: DefaultImportFromHighOrderProvider}, [Traefik + Docker Compose](/reverse-proxies/traefik "Traefik + Docker Compose") [Email Notifications](/configuration/emails "Email Notifications") --- # Email Notifications - Postiz Docs [Configuration](/configuration/create-provider "Configuration") Email Notifications Postiz supports two email providers: Resend and NodeMailer (SMTP). If you have an email provider configured, then new users will require activation. EMAIL_PROVIDER: "resend|nodemailer" You must also set the sender name and email address for all providers as follows; EMAIL_FROM_NAME: "Postiz Emailer" EMAIL_FROM_ADDRESS: "postiz@example.com" Resend[](#resend) ------------------ Postiz uses Resend to send email notifications to users. If this key is set, users will also require activation. * Register to [Resend](https://resend.com) , and connect your domain. * Copy your API Key from the Resend control panel. * Open the .env file and edit the following line. EMAIL_PROVIDER="resend" RESEND_API_KEY="" NodeMailer (SMTP)[](#nodemailer-smtp) -------------------------------------- This is an alternative to Resend. You can use NodeMailer, which is simply a SMTP library, to connect to any SMTP server. EMAIL_PROVIDER: "nodemailer" EMAIL_HOST: "smtp.gmail.com" # smtp host if you choose nodemailer EMAIL_PORT: "465" # smtp port if you choose nodemailer EMAIL_SECURE: "true" # smtp secure if you choose nodemailer EMAIL_USER: "user" # smtp user if you choose nodemailer EMAIL_PASS: "pass" # smtp pass if you choose nodemailer [How to add a new provider](/configuration/create-provider "How to add a new provider") [R2 Configuration](/configuration/r2 "R2 Configuration") --- # Discord - Postiz Docs [Providers Configuration](/providers "Providers Configuration") Discord 💡 This integration requires that you have **Manage Server** permissions on the Discord server you want to integrate with. ### Create a Discord Application[](#create-a-discord-application) Login to Discord on the web, and then go to the [Discord Developer Portal](https://discord.com/developers/applications) and click on “New Application”. ![New Application](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fdiscord_create_app.58755353.png&w=1080&q=75) ### Get and set your **Client ID** and **Client Secret** to a safe place.[](#get-and-set-your-client-id-and-client-secret-to-a-safe-place) You can find this in the **OAuth2** section of the Discord Developer Portal. ![Copy Keys](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fdiscord_copy_keys.b0dcb080.png&w=1920&q=75) Set these in your .env file as follows; DISCORD_CLIENT_ID="your_client_id" DISCORD_CLIENT_SECRET="your_client_secret" ### Add a Redirect URI[](#add-a-redirect-uri) The OAuth2 Redirect URI is the location where the provider will redirect to after trying to login. This needs to set to your Postiz `FRONTEND_URL` + `/integrations/social/` + `discord`. * eg: If you are running on a container, and your Postiz URL is: `https://postiz.example.com`, then your OAuth2 Redirect URI is `https://postiz.example.com/integrations/social/discord` * eg: If you are running on localhost, and your Postiz URL is `http://localhost:4200`, then your OAuth2 Redirect URI is `http://localhost:4200/integrations/social/discord` You only need to set one OAuth2 Redirect URI when you are setting up your Postiz app. The redirect URI is the URL that Discord will redirect to after you have logged in. Assuming you are running Postiz on `postiz.example.com`, this would be: `https://postiz.example.com/integrations/social/discord`. Alternatively if you are running on `localhost:4200`, this would be `http://localhost:4200/integrations/social/discord`. You only really need one of these, depending on where you are running Postiz. You can find this in the **OAuth2** section of the Discord Developer Portal. ![Redirect URI](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fdiscord_redirect_uri.18be3024.png&w=1080&q=75) ### Create a Bot[](#create-a-bot) Navigate to the “Bot” section of the Discord Developer Portal. Fill out the bot details however you like, and then click “Reset Token”. With the token that is generated, set it in your .env file as follows; DISCORD_BOT_TOKEN_ID="your_bot_token" If you do not set this, you will get 404 errors when trying to add the Discord channel in the Postiz web interface. Stop Postiz if it is running, and then start it using the .env file with the Discord details. ### Add a Discord channel in the Postiz web interface[](#add-a-discord-channel-in-the-postiz-web-interface) Go to the Postiz web interface, and click on the “Add Channel” button, and then select “Discord”. You should be redirected to Discord to login. [Bluesky](/providers/bluesky "Bluesky") [Dribbble](/providers/dribbble "Dribbble") --- # R2 Configuration - Postiz Docs [Configuration](/configuration/create-provider "Configuration") R2 Configuration At the moment, the only way to upload images is to configure R2. It’s free. ### Create account and login to the console[](#create-account-and-login-to-the-console) Go to the [Cloudflare Dashboard](https://dash.cloudflare.com/r2/overview) , and register if needed, then login. ### New Bucket[](#new-bucket) In the dashboard sidebar, and head to the R2 page. ![](https://github.com/user-attachments/assets/6d540494-b439-4715-9e8c-615e1f734aef) Create a new Bucket. * Choose Automatic * Choose Standard ![](https://github.com/user-attachments/assets/f679ff9f-1a9c-4d09-b663-2fa2baadea93) Create your R2 Token by clicking “Manage R2 API Tokens” ![](https://github.com/user-attachments/assets/f47e0b90-834f-4c18-abe0-a89b62ca6458) Under “Permissions” choose “Object Read & Write” and under “Specify bucket(s)” search for your created Bucket. ![](https://github.com/user-attachments/assets/30991d43-9920-47d4-9c53-bde619974009) After the R2 Token was created, copy your “Access Key ID” and “Secret Access Key” ![](https://github.com/user-attachments/assets/d4b4218f-fe20-47ec-937a-0d516fa74c64) Copy the information respectfully into your .env environment. CLOUDFLARE_ACCOUNT_ID="accountId" CLOUDFLARE_ACCESS_KEY="accessKey" CLOUDFLARE_SECRET_ACCESS_KEY="secretAccessKey" CLOUDFLARE_BUCKETNAME="bucketName" CLOUDFLARE_REGION="region (like wnam)" ### Custom Domain and CORS policies[](#custom-domain-and-cors-policies) Go to configuration and connect a custom domain (if you don’t have one, you can use the one that CloudFlare provides.) Add it to your .env file. CLOUDFLARE_BUCKET_URL="https://customdomain.com" ![](https://github.com/user-attachments/assets/a7bff532-f69b-4095-bb66-e46b7d3b14bd) Click to edit the CORS policy and add the following JSON: [\ {\ "AllowedOrigins": [\ "http://localhost:4200",\ "https://yourDomain.com"\ ],\ "AllowedMethods": [\ "GET",\ "POST",\ "HEAD",\ "PUT",\ "DELETE"\ ],\ "AllowedHeaders": [\ "Authorization",\ "x-amz-date",\ "x-amz-content-sha256",\ "content-type"\ ],\ "ExposeHeaders": [\ "ETag",\ "Location"\ ],\ "MaxAgeSeconds": 3600\ }\ ] ![](https://github.com/user-attachments/assets/1f84fe71-dd2d-4ca6-92bf-6193d36c9b54) [Email Notifications](/configuration/emails "Email Notifications") [Configuration Reference](/configuration/reference "Configuration Reference") --- # Providers - Postiz Docs Providers Configuration You can see all the providers that Postiz supports documented in the sidebar, under “**Providers Configuration**”. Please note that no providers are configured by default. You will need to configure them all in your `.env` file, or as environment variables. You will need to restart Postiz whenever you change environment variables. If you are using docker compose, you must run `docker compose down` and then docker compose `up` to rebuild the containers with the updated variables. [Configuration Reference](/configuration/reference "Configuration Reference") [Bluesky](/providers/bluesky "Bluesky") --- # Configuration Reference - Postiz Docs [Configuration](/configuration/create-provider "Configuration") Configuration Reference At the moment, Postiz is entirely configured by environment variables. It is important to understand that any configuration change to environment variables will require an application restart. An example file of the most used configuration settings can be found here; [example postiz.env file](https://raw.githubusercontent.com/gitroomhq/postiz-app/main/.env.example) Required Settings[](#required-settings) ---------------------------------------- ### `DATABASE_URL`[](#database_url) eg: `postgresql://postiz-user:postiz-password@localhost:5432/postiz-db-local` Postgres is not strictly necessary, Postiz uses Prisma to connect to the database, so technically mariadb or other databases could be used. ### `REDIS_URL`[](#redis_url) eg: `redis://localhost:6379` ### `JWT_SECRET`[](#jwt_secret) A random string that should be unique for every installation, this is used to secure your JWT auth tokens. ### `FRONTEND_URL`[](#frontend_url) eg: `http://postiz.example.lan:4200` ### `NEXT_PUBLIC_BACKEND_URL`[](#next_public_backend_url) eg: `http://postiz.example.lan:3000` ### `BACKEND_INTERNAL_URL`[](#backend_internal_url) If running everything in the same host/container: `http://localhost:3000` Social Media keys[](#social-media-keys) ---------------------------------------- See the “providers” section of the documentation for the provider you want to configure, for details about how to set that up. [R2 Configuration](/configuration/r2 "R2 Configuration") [Providers Configuration](/providers "Providers Configuration") --- # Dribbble - Postiz Docs [Providers Configuration](/providers "Providers Configuration") Dribbble ### Register your application[](#register-your-application) [Register your application on Dribbble](https://dribbble.com/account/applications/new) . * **Name:** `MyPostizInstance` * **Description:** `My Postiz Instance` * **Website:** `https://example.com` * **Redirect URI:** (see below) The OAuth2 Redirect URI is the location where the provider will redirect to after trying to login. This needs to set to your Postiz `FRONTEND_URL` + `/integrations/social/` + `dribble`. * eg: If you are running on a container, and your Postiz URL is: `https://postiz.example.com`, then your OAuth2 Redirect URI is `https://postiz.example.com/integrations/social/dribble` * eg: If you are running on localhost, and your Postiz URL is `http://localhost:4200`, then your OAuth2 Redirect URI is `http://localhost:4200/integrations/social/dribble` You only need to set one OAuth2 Redirect URI when you are setting up your Postiz app. ### Copy your client secret to environment variables[](#copy-your-client-secret-to-environment-variables) These can be found immediately after registering your application. These are both 64 characters long. DRIBBLE_CLIENT_ID="1234..." DRIBBLE_CLIENT_SECRET="5678..." Restart Postiz with the updated environment variables ### Add a Dribbble channel in the Postiz web interface[](#add-a-dribbble-channel-in-the-postiz-web-interface) Go to the Postiz web interface, and click on the “Add Channel” button. Select “Dribbble” from the list of available channels. You should be redirected to Dribbble to authorize the application. [Discord](/providers/discord "Discord") [Facebook](/providers/facebook "Facebook") --- # Instagram - Postiz Docs [Providers Configuration](/providers "Providers Configuration") Instagram ⚠️ **NOTE:** Please be advised that Instagram and Facebook can use the same app (no need to create two separate apps) ### Step 1[](#step-1) Create a [new app in Instagram developers](https://developers.instagram.com/apps/creation/) , choose the business you want to connect it to. Please be advised that for public applications you would need to verify you business. ![Create app](https://github.com/user-attachments/assets/e24f15a7-d9b1-48cb-8952-7a5258923b4c) ### Step 2[](#step-2) Select “Other” and click next ![Other](https://github.com/user-attachments/assets/9c976b82-0b73-4d1d-b3ef-cf98e4cc0c50) ### Step 3[](#step-3) Then select business ![Business](https://github.com/user-attachments/assets/74bde861-5441-46bb-b5b8-c5229e980237) Add all your details and click Create App ### Step 4[](#step-4) ![CleanShot 2024-09-24 at 13 45 54](https://github.com/user-attachments/assets/f0c03825-0f9b-4467-94a4-ab8cf6ed7e1d) Set final details ### Step 5[](#step-5) ![Setup Login with Instagram](https://github.com/user-attachments/assets/08d3c1d1-d498-49d1-adac-aa6248e7c10c) Set up login for business ### Step 6[](#step-6) Set up a redirect URI back to the application ![Instagram](https://github.com/user-attachments/assets/78496d3f-3b84-4724-afc8-ed217d892c6d) The OAuth2 Redirect URI is the location where the provider will redirect to after trying to login. This needs to set to your Postiz `FRONTEND_URL` + `/integrations/social/` + `instagram`. * eg: If you are running on a container, and your Postiz URL is: `https://postiz.example.com`, then your OAuth2 Redirect URI is `https://postiz.example.com/integrations/social/instagram` * eg: If you are running on localhost, and your Postiz URL is `http://localhost:4200`, then your OAuth2 Redirect URI is `http://localhost:4200/integrations/social/instagram` You only need to set one OAuth2 Redirect URI when you are setting up your Postiz app. ### Step 7[](#step-7) ![step 7](https://github.com/user-attachments/assets/a81aa2a3-de66-4099-906b-b78c641d1a23) Go to advanced permission and request access for the following scopes: `instagram_basic` `pages_show_list` `pages_read_engagement` `business_management` `instagram_content_publish` `instagram_manage_comments` `instagram_manage_insights` ### Step 8[](#step-8) ![Keys](https://github.com/user-attachments/assets/ac11f87f-4951-47f8-8344-7fbc9de942e4) Go to basic permissions copy your App ID and App Secret and paste them in your `.env` file FACEBOOK_APP_ID="app id" FACEBOOK_APP_SECRET="app secret" Instagram should now be working! [Facebook](/providers/facebook "Facebook") [Linkedin](/providers/linkedin "Linkedin") --- # Bluesky - Postiz Docs [Providers Configuration](/providers "Providers Configuration") Bluesky ### Add BlueSky as a Channel[](#add-bluesky-as-a-channel) You do not need to configure any environment variables for BlueSky, you can simply add your account from the UI. ![New Channel](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fbluesky_add.6d586664.png&w=1080&q=75) You should be redirected and be able to start posting immediately. If you have any issues, check the backend service logs. [Providers Configuration](/providers "Providers Configuration") [Discord](/providers/discord "Discord") --- # Facebook - Postiz Docs [Providers Configuration](/providers "Providers Configuration") Facebook ⚠️ **NOTE:** Please be advised that Instagram and Facebook can use the same app (no need to create two separate apps) ### Step 1[](#step-1) Create a [new app in Facebook developers](https://developers.facebook.com/apps/creation/) , choose the business you want to connect it to. Please be advised that for public applications you would need to verify you business. ![Create app](https://github.com/user-attachments/assets/e24f15a7-d9b1-48cb-8952-7a5258923b4c) ### Step 2[](#step-2) Select “Other” and click next ![Other](https://github.com/user-attachments/assets/9c976b82-0b73-4d1d-b3ef-cf98e4cc0c50) ### Step 3[](#step-3) Then select business ![Business](https://github.com/user-attachments/assets/74bde861-5441-46bb-b5b8-c5229e980237) Add all your details and click Create App ### Step 4[](#step-4) ![CleanShot 2024-09-24 at 13 45 54](https://github.com/user-attachments/assets/f0c03825-0f9b-4467-94a4-ab8cf6ed7e1d) Set final details ### Step 5[](#step-5) ![Setup Login with Facebook](https://github.com/user-attachments/assets/08d3c1d1-d498-49d1-adac-aa6248e7c10c) Set up login for business ### Step 6[](#step-6) Set up a redirect URI back to the application ![step 6](https://github.com/user-attachments/assets/8bf1774b-b6fe-4ac6-aea5-97d8c8bbf5da) The OAuth2 Redirect URI is the location where the provider will redirect to after trying to login. This needs to set to your Postiz `FRONTEND_URL` + `/integrations/social/` + `facebook`. * eg: If you are running on a container, and your Postiz URL is: `https://postiz.example.com`, then your OAuth2 Redirect URI is `https://postiz.example.com/integrations/social/facebook` * eg: If you are running on localhost, and your Postiz URL is `http://localhost:4200`, then your OAuth2 Redirect URI is `http://localhost:4200/integrations/social/facebook` You only need to set one OAuth2 Redirect URI when you are setting up your Postiz app. ### Step 7[](#step-7) ![step 7](https://github.com/user-attachments/assets/a81aa2a3-de66-4099-906b-b78c641d1a23) Go to advanced permission and request access for the following scopes: `pages_show_list` `business_management` `pages_manage_posts` `pages_manage_engagement` `pages_read_engagement` `read_insights` ### Step 8[](#step-8) ![Keys](https://github.com/user-attachments/assets/ac11f87f-4951-47f8-8344-7fbc9de942e4) Go to basic permissions copy your App ID and App Secret and paste them in your `.env` file FACEBOOK_APP_ID="app id" FACEBOOK_APP_SECRET="app secret" Facebook should now be working! [Dribbble](/providers/dribbble "Dribbble") [Instagram](/providers/instagram "Instagram") --- # Linkedin - Postiz Docs [Providers Configuration](/providers "Providers Configuration") Linkedin Head over to [Linkedin developers](https://www.linkedin.com/developers/apps) and create a new app. ![Linkedin](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Flinkedin-001.5d512567.png&w=3840&q=75) Fill in all the details, once created head over to Products and make sure you add all the required products. ![Linkedin](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Flinkedin-002.0d61be59.png&w=3840&q=75) It is important to request the Advertising API permissions and fill up the request form, or you will not have the ability to refresh your tokens. The OAuth2 Redirect URI is the location where the provider will redirect to after trying to login. This needs to set to your Postiz `FRONTEND_URL` + `/integrations/social/` + `linkedin`. * eg: If you are running on a container, and your Postiz URL is: `https://postiz.example.com`, then your OAuth2 Redirect URI is `https://postiz.example.com/integrations/social/linkedin` * eg: If you are running on localhost, and your Postiz URL is `http://localhost:4200`, then your OAuth2 Redirect URI is `http://localhost:4200/integrations/social/linkedin` You only need to set one OAuth2 Redirect URI when you are setting up your Postiz app. If you are using the “LinkedIN Page” provider, then the redirect url should be “linkedin-page”. Copy the created `Client ID` and `Client Secret` and add them to your `.env` file. LINKEDIN_CLIENT_ID="" LINKEDIN_CLIENT_SECRET="" You can find those under the Auth Tab of your LinkedIn App in the developer portal. [Instagram](/providers/instagram "Instagram") [LinkedIn Page](/providers/linkedin-page "LinkedIn Page") --- # LinkedIn Page - Postiz Docs [Providers Configuration](/providers "Providers Configuration") LinkedIn Page Head over to [LinkedIn developers](https://www.linkedin.com/developers/apps) and create a new app. ![Linkedin](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Flinkedin-001.5d512567.png&w=3840&q=75) Verify your app with LinkedIn ![Linkedin](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Flinkedin-004.e4b4dc46.png&w=1920&q=75) You will need to follow the verification process to request the necessary permissions listed below. Fill in all the details, once created head over to Products and make sure you add all the required products. ![Linkedin](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Flinkedin-003.6c915f6b.png&w=1920&q=75) It is important to request the Advertising API permissions and fill up the request form, or you will not have the ability to refresh your tokens. The OAuth2 Redirect URI is the location where the provider will redirect to after trying to login. This needs to set to your Postiz `FRONTEND_URL` + `/integrations/social/` + `linkedin-page`. * eg: If you are running on a container, and your Postiz URL is: `https://postiz.example.com`, then your OAuth2 Redirect URI is `https://postiz.example.com/integrations/social/linkedin-page` * eg: If you are running on localhost, and your Postiz URL is `http://localhost:4200`, then your OAuth2 Redirect URI is `http://localhost:4200/integrations/social/linkedin-page` You only need to set one OAuth2 Redirect URI when you are setting up your Postiz app. Copy the created `Client ID` and `Client Secret` and add them to your `.env` file. LINKEDIN_CLIENT_ID="" LINKEDIN_CLIENT_SECRET="" You can find those under the Auth Tab of your LinkedIn App in the developer portal. [Linkedin](/providers/linkedin "Linkedin") [Mastodon](/providers/mastodon "Mastodon") --- # Pinterest - Postiz Docs [Providers Configuration](/providers "Providers Configuration") Pinterest 💡 This integration requires that you have a Pinterest Company Account. ### Step 1 Create Pinterest App[](#step-1-create-pinterest-app) Head to [Pinterest Developer Dashboard](https://developers.pinterest.com/apps/) and create your App. Fill out all reqiured Information and wait on the App to get approved. ### Step 2 Copy the App ID and Secret[](#step-2-copy-the-app-id-and-secret) Copy the App ID at “App id” and the Secret Key at “App secret key” [Copy App ID and Secret](https://github.com/egelhaus/postiz-docs/blob/cfd39114ef6d44da864717b23d704f6265cefa84/public/images/providers/pinterest/pinterest-002.png) ### Step 3 Configure Redirect URI[](#step-3-configure-redirect-uri) The OAuth2 Redirect URI is the location where the provider will redirect to after trying to login. This needs to set to your Postiz `FRONTEND_URL` + `/integrations/social/` + `pinterest`. * eg: If you are running on a container, and your Postiz URL is: `https://postiz.example.com`, then your OAuth2 Redirect URI is `https://postiz.example.com/integrations/social/pinterest` * eg: If you are running on localhost, and your Postiz URL is `http://localhost:4200`, then your OAuth2 Redirect URI is `http://localhost:4200/integrations/social/pinterest` You only need to set one OAuth2 Redirect URI when you are setting up your Postiz app. [Setup of Redirect URIs](https://github.com/egelhaus/postiz-docs/blob/d11ea333ad8d70c5dee7ac0ad76283ded514219b/public/images/providers/pinterest/pinterest-001.png) PINTEREST_CLIENT_ID="" PINTEREST_CLIENT_SECRET="" You should now be able to add the Pinterest Provider to your User / Team Account. [Mastodon](/providers/mastodon "Mastodon") [Reddit](/providers/reddit "Reddit") --- # Mastodon - Postiz Docs [Providers Configuration](/providers "Providers Configuration") Mastodon ⚠️ **NOTE:** Postiz is currently hard-coded to use mastodon.social only. This will become more flexible to support other servers in a future release. Mastodon client registration is not done via ther web interface, but by talking to the API directly. In the example below, we use `curl` to register a new client. Optionally check that you have `jq` installed on your system. You can normally install this with brew, apt-get, yum or chocolatey. If you don’t have `jq` installed, you can remove it from the command below. The OAuth2 Redirect URI is the location where the provider will redirect to after trying to login. This needs to set to your Postiz `FRONTEND_URL` + `/integrations/social/` + `mastodon`. * eg: If you are running on a container, and your Postiz URL is: `https://postiz.example.com`, then your OAuth2 Redirect URI is `https://postiz.example.com/integrations/social/mastodon` * eg: If you are running on localhost, and your Postiz URL is `http://localhost:4200`, then your OAuth2 Redirect URI is `http://localhost:4200/integrations/social/mastodon` You only need to set one OAuth2 Redirect URI when you are setting up your Postiz app. Run the following curl command in a terminal to get the Mastodon client id and client secret. curl -X POST -sS https://mastodon.social/api/v1/apps -F "client_name=YourAppName" -F "redirect_uris=http://localhost:4200/integrations/social/mastodon" -F "scopes=write:statuses write:media profile" | jq This will give you output that looks something like this; { "id": "1234567890", "redirect_uris": [\ "http://localhost:4200/integrations/social/mastodon"\ ], ... "client_id": "your_client_id", "client_secret": "your_client_secret" } Make a note of your `client_id` and `client_secret` and add them to your `.env` file. MASTODON_CLIENT_ID="shown in the output from the above command" MASTODON_CLIENT_SECRET="shown in the output from the above command" Stop Postiz if it is running, and then start it using the .env file with the Mastodon details. Click through the new channel setup and you should be asked to login on Mastodon. [LinkedIn Page](/providers/linkedin-page "LinkedIn Page") [Pinterest](/providers/pinterest "Pinterest") --- # Slack - Postiz Docs [Providers Configuration](/providers "Providers Configuration") Slack 💡 This integration requires that you have a Slack Workspace ### Step 1 Create Slack App[](#step-1-create-slack-app) Head to [Slack Applications Dashboard](https://api.slack.com/apps) and select “From scratch”, fill out all the required Information. #### Step 2 Set up OAuth Scopes and redirect URIs[](#step-2-set-up-oauth-scopes-and-redirect-uris) The OAuth2 Redirect URI is the location where the provider will redirect to after trying to login. This needs to set to your Postiz `FRONTEND_URL` + `/integrations/social/` + `slack`. * eg: If you are running on a container, and your Postiz URL is: `https://postiz.example.com`, then your OAuth2 Redirect URI is `https://postiz.example.com/integrations/social/slack` * eg: If you are running on localhost, and your Postiz URL is `http://localhost:4200`, then your OAuth2 Redirect URI is `http://localhost:4200/integrations/social/slack` You only need to set one OAuth2 Redirect URI when you are setting up your Postiz app. Head to Features > OAuth & Permissions 1. Add the redirect URI (see above) 2. At Scopes > Bot Token Scopes, add these Scopes: 3. “chat:write” 4. “channels:read” 5. “users:read” 6. “groups:read” 7. “channels:join” ### Step 3 Set an App Icon[](#step-3-set-an-app-icon) Head back to Settings > Basic Information > Display Information Now set an Icon that meets these Requirements: 1. It has to be an Square 2. It has to be 512pxx512px to 2000pxx2000px If you do not set an App Icon, Postiz won’t let you install the Integration. ### Step 4 Copy Client ID and Secret[](#step-4-copy-client-id-and-secret) Head back to App Credentials, copy the Client ID and Secret and paste it to your Environment: SLACK_ID="" SLACK_SECRET="" [Reddit](/providers/reddit "Reddit") [Telegram](/providers/telegram "Telegram") --- # Reddit - Postiz Docs [Providers Configuration](/providers "Providers Configuration") Reddit ### Create an app on Reddit Developerrs[](#create-an-app-on-reddit-developerrs) Head over to [Reddit developers](https://www.reddit.com/prefs/apps) and click on **create a new app**. * **Name:** `MyPostizInstance` (or whatever you like) * **App type:** `web app` * **Redirect URI:** (see below) The OAuth2 Redirect URI is the location where the provider will redirect to after trying to login. This needs to set to your Postiz `FRONTEND_URL` + `/integrations/social/` + `reddit`. * eg: If you are running on a container, and your Postiz URL is: `https://postiz.example.com`, then your OAuth2 Redirect URI is `https://postiz.example.com/integrations/social/reddit` * eg: If you are running on localhost, and your Postiz URL is `http://localhost:4200`, then your OAuth2 Redirect URI is `http://localhost:4200/integrations/social/reddit` You only need to set one OAuth2 Redirect URI when you are setting up your Postiz app. ### Set environment variables[](#set-environment-variables) Copy the Reddit client id and client secret and add them to your `.env` file. ![Reddit](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Freddit-001.b77834e8.png&w=3840&q=75) REDDIT_CLIENT_ID="" REDDIT_CLIENT_SECRET="" [Pinterest](/providers/pinterest "Pinterest") [Slack](/providers/slack "Slack") --- # Telegram - Postiz Docs [Providers Configuration](/providers "Providers Configuration") Telegram ### Step 1: Create a Telegram Bot[](#step-1-create-a-telegram-bot) 1. Open Telegram and message [@BotFather](https://t.me/botfather) . 2. Click Start 3. Click Menu * click “Create a new bot” * Enter a name for your bot (e.g., `MyPostizBot`). ![Name Bot](https://github.com/user-attachments/assets/974c1ad3-4648-4d41-8d20-22b6e8cb0bc8) * Choose a unique username ending with “bot” (e.g., `MyPostizBot_bot`). ![Unique Bot Name](https://github.com/user-attachments/assets/e4824ed2-c812-4a03-b43a-bf4f680eff23) Once your bot is created, **BotFather** will give you an **API Token**. Keep it safe—you’ll need it later. ![Bot Token](https://github.com/user-attachments/assets/71bdc32c-36d5-45cd-b0d8-08d5eefcaadc) ### Step 2: Configure Bot Group Permissions (optional but recommended)[](#step-2-configure-bot-group-permissions-optional-but-recommended) 1. Click on “Menu” 2. Click on “Edit your bots” 3. Select your bot 4. Click on “Bot Settings” ![Bot Settings](https://github.com/user-attachments/assets/908924ee-2567-4c13-bfeb-52f5684680a3) 5. Click on “Group Privacy” ![Group Privacy](https://github.com/user-attachments/assets/6a756212-7af3-437f-88fe-74ca5579666d) 6. if “Privacy mode” is enabled, turn it off (it is enabled by default) ### Step 3: Add Your Bot to Telegram Groups or Channels[](#step-3-add-your-bot-to-telegram-groups-or-channels) 1. Navigate to your group/channel 2. Add your bot to your group/channel 3. The bot requires these permissions to work with Postiz: * access to messages || so the bot can read messages sent in the group/channel * Send Text Messages || so the bot can send messages * Send Media || so the bot can send media **INFO:** While not strictly required, making your bot an `admin` is **recommended**. It will give the bot all the permissions needed and make the setup easier and faster. ### Step 4: Add Bot Token to Your Application[](#step-4-add-bot-token-to-your-application) In your `.env` file, add the **Telegram Bot Name** (Without the @) and the **Telegram Bot API Token** that you received from **BotFather** in Step 1: TELEGRAM_BOT_NAME="MyPostizBot_bot" TELEGRAM_TOKEN="MyPostizBot token" **INFO:** If you are using Docker Compose, include the `NTBA_FIX_350: 1` variable directly in your `docker-compose.yml`. see [Node Telegram Bot API](https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#file-options-metadata) for reference. You should be able to connect your group/channel to Postiz now! [Slack](/providers/slack "Slack") [Threads](/providers/threads "Threads") --- # Threads - Postiz Docs [Providers Configuration](/providers "Providers Configuration") Threads 💡 This integration requires that you have setup a Facebook developer account already. You can start by going to the [Meta/Facebook Developer Portal](https://developers.facebook.com/apps) . This is a very complex integration, and it may take some time to get it right. If you have any issues, please reach out to us on the Postiz Discord. This documentation is not yet complete sadly, because at the time of writing the Threads API seems like it’s having issues. This page was written to get something up to get you started. ### Create an app[](#create-an-app) Go to the [Meta/Facebook Developer Portal](https://developers.facebook.com/apps) and click on “Create app”. ![Create app](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fthreads_create_app.cbc594b2.png&w=750&q=75) ### Give your app a name and email[](#give-your-app-a-name-and-email) ![Create app](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fthreads_app_name.24621c4e.png&w=1920&q=75) ### Request access to Threads[](#request-access-to-threads) Select _Access the Threads API_. ![Request access](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fthreads_request_api.1e26bbee.png&w=2048&q=75) ### Add business details, or skip[](#add-business-details-or-skip) ![Add business details](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fthreads_business.13b82171.png&w=1920&q=75) ### Finish creating the app[](#finish-creating-the-app) You should not have any extra requirements to publish and maintain access. ### Configure API access[](#configure-api-access) On the app dashboard, Select “Access the Threads API” to begin customizing the API access. Add the “threads\_content\_publish” and “threads\_basic” (automatically selected) to your app. ![Configure API access](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fthreads_access.91dc7717.png&w=2048&q=75) ### Set threads API settings[](#set-threads-api-settings) * Copy your “Threads App ID”, and set the postiz environment variables `THREADS_APP_ID` to this value. * Click the “Show” button next to the Threads App Secret, and set the postiz environment variable `THREADS_APP_SECRET` to this value. Note that the next box is quite small, make sure you scroll across the copy the full value. It should be 32 characters long. The OAuth2 Redirect URI is the location where the provider will redirect to after trying to login. This needs to set to your Postiz `FRONTEND_URL` + `/integrations/social/` + `threads`. * eg: If you are running on a container, and your Postiz URL is: `https://postiz.example.com`, then your OAuth2 Redirect URI is `https://postiz.example.com/integrations/social/threads` * eg: If you are running on localhost, and your Postiz URL is `http://localhost:4200`, then your OAuth2 Redirect URI is `http://localhost:4200/integrations/social/threads` You only need to set one OAuth2 Redirect URI when you are setting up your Postiz app. \*\* Note that you have to “click” the URL to make it active, otherwise the form will not save. \*\* You can use the same value for the **Uninstall Callback URL** and **Delete Callback URL**, but note that Postiz does not support either at this time. The form will not save unless you enter something. ![Set threads API settings](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fthreads_api_settings.2d66f02c.png&w=2048&q=75) On the dashboard view of the Facebook developers portal, make sure you click through the setup wizard to finish the step “Yes I am finished creating the app” to complete the setup. The AP may not work until you’ve done this. ### Restart Postiz[](#restart-postiz) Stop Postiz if it is running, and then start it again to pick up the new environment variables. You should not try to add a Threads account to Postiz at this time. ### Add the Threads account as a tester[](#add-the-threads-account-as-a-tester) * In the sidebar go to “App roles” -> “roles”. * Select the “Testers” tab. Click “Add People”. * Under _Additional Roles for this App_, select _Threads Tester_. * Enter usernames of the threads users you want to test the app. Probably your own username. Note that this is probably different from your Meta developers account which is tied to Facebook. ### Allow the app on your threads account[](#allow-the-app-on-your-threads-account) * On threads.net, open your account settings; [https://www.threads.net/settings/account](https://www.threads.net/settings/account) * Open _Website permissions_, and switch to the _Invitations_ tab; * If all has gone well, you should have a pending invite. Accept that invite. ![Threads invite](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fthreads_invite.207c49d6.png&w=1920&q=75) ### Start testing[](#start-testing) * Go back to the Meta developers portal, and in the sidebar, click _Testing_, and then open the _Open Graph API Explorer_. * In the header, dropdown the API selector and change it to threads.net v1. ![API Version](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fthreads_api_version.0f555aa8.png&w=1200&q=75) * In the right sidebar, under _Access Token_, click _Generate Threads Access Token_. This will open a new window where you can select the Threads account you want to test with - it should be an account that accepted the earlier invite. ### …Good luck![](#good-luck) This documentation is not yet complete sadly, because at the time of writing the Threads API seems like it’s having issues. This page was written to get something up to get you started. This is a very complex integration, and it may take some time to get it right. If you have any issues, please reach out to us on the Postiz Discord. [Telegram](/providers/telegram "Telegram") [Tiktok](/providers/tiktok "Tiktok") --- # Tiktok - Postiz Docs [Providers Configuration](/providers "Providers Configuration") Tiktok * * * title: TikTok description: How to add TikTok to your system[](#title-tiktokdescription-how-to-add-tiktok-to-your-system) ------------------------------------------------------------------------------------------------------------------------- 💡 This integration requires that you have a TikTok developer account. It also requires that you have a public website, with https, and can upload files to that site to verify ownership. TikTok will also not allow http:// for your app redirect URI, so you will need to be accessing Postiz from HTTPS. ### Create you app[](#create-you-app) Go here: [https://developers.tiktok.com/apps](https://developers.tiktok.com/apps) ![Create a new app](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftiktok_create_app.4e78636b.png&w=828&q=75) * **App Name:** `MyPostiz` * **Redirect URI:** (see below) The OAuth2 Redirect URI is the location where the provider will redirect to after trying to login. This needs to set to your Postiz `FRONTEND_URL` + `/integrations/social/` + `tiktok`. * eg: If you are running on a container, and your Postiz URL is: `https://postiz.example.com`, then your OAuth2 Redirect URI is `https://postiz.example.com/integrations/social/tiktok` * eg: If you are running on localhost, and your Postiz URL is `http://localhost:4200`, then your OAuth2 Redirect URI is `http://localhost:4200/integrations/social/tiktok` You only need to set one OAuth2 Redirect URI when you are setting up your Postiz app. ### Set a TOS and Privacy Policy[](#set-a-tos-and-privacy-policy) This needs to be on a public domain that you have access to, that is hosted on HTTPS. Tick “Web” for your platforms. ### Add apps[](#add-apps) Add the “Login Kit” and “Content Posting API” to your app. For “Login Kit”, set the redirect URI to [http://localhost:4200/integrations/social/tiktok](http://localhost:4200/integrations/social/tiktok) For Content posting API, enable “Direct Post”. ### Add scopes[](#add-scopes) * user.info.basic * video.create * video.upload ### Copy your client secret to environment variables[](#copy-your-client-secret-to-environment-variables) These can be found immediately after registering your application. The client ID is 16 characters long and the secret is 32 characters long. TIKTOK_CLIENT_ID=1234567890123456 TIKTOK_CLIENT_SECRET=12345678901234567890123456789012 Restart Postiz with the updated environment variables ### Add a TikTok channel in the Postiz web interface[](#add-a-tiktok-channel-in-the-postiz-web-interface) Go to the Postiz web interface, and click on the “Add Channel” button. Select “TikTok” from the list of available channels. You should be redirected to TikTok to authorize the application. [Threads](/providers/threads "Threads") [X](/providers/x "X") --- # Youtube - Postiz Docs [Providers Configuration](/providers "Providers Configuration") Youtube * * * title: YouTube description: How to add YouTube to your system[](#title-youtubedescription-how-to-add-youtube-to-your-system) ----------------------------------------------------------------------------------------------------------------------------- 💡 This integration requires that you have a Google account. Follow the instructions as availabe in the [Obtaining authorization credentials](https://developers.google.com/youtube/registering_an_application) . ### Step 1 Go to Credentials Page[](#step-1-go-to-credentials-page) Make sure you are logged in to your Google account and visit the [Credentials - APIs & Services](https://console.cloud.google.com/projectselector2/apis/credentials) page. Make sure to read the terms and conditions and “Agree and Continue”. ### Step 2 Create Project[](#step-2-create-project) Create a new project by clicking on the “Create Project” button. ### Step 3[](#step-3) Fill in the project name, and details and click “Create”. ### Step 4 Create OAuth Credentials[](#step-4-create-oauth-credentials) Create credentials by clicking on the “Create Credentials” button. Select the “OAuth client ID” option. ### Step 5 Configure Consent Screen[](#step-5-configure-consent-screen) Make sure that your consent screen has been configured. Add yourself as a test user of the application. ### Step 6 Fill in OAuth Details[](#step-6-fill-in-oauth-details) Create the OAuth client ID. Select “Web application” as the application type and fill in the details. Under “Authorized redirect URIs”, insert your OAuth2 Redirect URI. ### Add a Redirect URI[](#add-a-redirect-uri) The OAuth2 Redirect URI is the location where the provider will redirect to after trying to login. This needs to set to your Postiz `FRONTEND_URL` + `/integrations/social/` + `youtube`. * eg: If you are running on a container, and your Postiz URL is: `https://postiz.example.com`, then your OAuth2 Redirect URI is `https://postiz.example.com/integrations/social/youtube` * eg: If you are running on localhost, and your Postiz URL is `http://localhost:4200`, then your OAuth2 Redirect URI is `http://localhost:4200/integrations/social/youtube` You only need to set one OAuth2 Redirect URI when you are setting up your Postiz app. ### Step 7 Activate YouTubes API[](#step-7-activate-youtubes-api) Go to Activated APIs and Services. Then click on Activate APIs and Services. Search YouTube Data API v3 and activate the API by clicking it and clicking Activate. Do the same Process with YouTube Analytics API and YouTube Reporting API. After following all of the steps above you should be met with a screen that shows your client ID and client secret. Add these to your providers configuration. YOUTUBE_CLIENT_ID="" YOUTUBE_CLIENT_SECRET="" ADDITIONAL STEPS FOR BRAND ACCOUNTS Note: When using a Brand account you will need to set your APP to External and setup a test user. You do not need to publish the APP, but it does take time for the changes to propegate. You will also need to add the app to the trusted apps within your google workspace Admin. ### Step 1 Go to admin.google.com[](#step-1-go-to-admingooglecom) sign in ### Step 2 go to Security —> Access and data Controls —> API Controls[](#step-2-go-to-security----access-and-data-controls----api-controls) Click Manage Third Party App Access ### Step 3 Click Configure new App[](#step-3-click-configure-new-app) Put your Client ID for the app you created in previous steps into the search box and select your app ### Step 4 Set scopes and Google Data Access for the app to Trusted[](#step-4-set-scopes-and-google-data-access-for-the-app-to-trusted) Once set, click save ### Step 5 Wait at least 5 hours for the changes to propegate.[](#step-5-wait-at-least-5-hours-for-the-changes-to-propegate) After this time you should now be able to add your Youtube channel to your Postiz account [X](/providers/x "X") [Support](/support "Support") --- # Developer Guide - Postiz Docs Developer Guide Understand how to develop with Postiz[](#understand-how-to-develop-with-postiz) -------------------------------------------------------------------------------- How to setup your development environment[](#how-to-setup-your-development-environment) ---------------------------------------------------------------------------------------- This page explains [How to setup your development environment](/installation/development) . Architecture Overview[](#architecture-overview) ------------------------------------------------ Before getting started with development, have a good read of the [architecture overview](/howitworks) . This will give you a good understanding of how the project is structured and how the different parts of the project interact with each other. Repository Overview[](#repository-overview) -------------------------------------------- Postiz is an open-source project, and the source code is available on [GitHub](https://github.com/gitroomhq/postiz-app) . The project is generally built using scripts in the `package.json` file with npm. The main scripts are: * `npm run dev` - Starts the development server * `npm run prisma-generate` - Generates the Prisma client * `npm run prisma-db-push` - Pushes the database schema to the database The entire project is built under [NX](https://nx.dev/) to have a monorepo with multiple projects. Unlike other NX project, this project has one `.env` file that is shared between all the apps. It makes it easier to develop and deploy the project. ### Frontend[](#frontend) The frontend is built with [NextJS](https://nextjs.org/) and [TailwindCSS](https://tailwindcss.com/) . ### Backend[](#backend) The backend is built with [NestJS](https://nestjs.com/) with a basic architecture of controllers, services, repositories and dtos. It uses [Prisma](https://www.prisma.io/) as an ORM to interact with the database. By default Prisma uses [Postgres](https://www.postgresql.org/) as a database, but it can be easily changed to any other database since there are no native queries. It uses Redis to schedule posts and run background jobs. ### Cron[](#cron) cron is built with [NestJS](https://nestjs.com/) and share components with the backend. ### Worker[](#worker) worker is built with [NestJS](https://nestjs.com/) and share components with the backend. Contributors Guide[](#contributors-guide) ------------------------------------------ The Postiz [contributors guide](https://github.com/gitroomhq/postiz-app/blob/main/CONTRIBUTING.md) is contained in the main repository. It provides information on how to contribute to the project, mainly the format for how to submit a pull request. [Support](/support "Support") --- # X - Postiz Docs [Providers Configuration](/providers "Providers Configuration") X X is a bit different. They created an oAuth2 flow, but it works only with Twitter v2 API. But in order to upload pictures to X, you need to use the old Twitter v1 API. So we are going to use the normal oAuth1 flow for that (that supports Twitter v2 also 🤷🏻‍). Head over the [Twitter developers page](https://developer.twitter.com/en/portal/dashboard) and create a new app. Click to sign-up for a new free account ![X](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fx-001.f386ecb7.png&w=3840&q=75) Click to edit the application settings ![X](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fx-002.96ef9dff.png&w=3840&q=75) The click to set up an authentication flow ![X](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fx-003.664b662a.png&w=3840&q=75) In the App Permission set it to `Read and Write` In the Type of App set it to `Web App, Automated App or Bot` In the App Info set the `Callback URI / Redirect URL`. The OAuth2 Redirect URI is the location where the provider will redirect to after trying to login. This needs to set to your Postiz `FRONTEND_URL` + `/integrations/social/` + `x`. * eg: If you are running on a container, and your Postiz URL is: `https://postiz.example.com`, then your OAuth2 Redirect URI is `https://postiz.example.com/integrations/social/x` * eg: If you are running on localhost, and your Postiz URL is `http://localhost:4200`, then your OAuth2 Redirect URI is `http://localhost:4200/integrations/social/x` You only need to set one OAuth2 Redirect URI when you are setting up your Postiz app. Save it and go to “Keys and Tokens” tab Click on “Regenerate” inside “Consumer Keys” and copy the `API Key` and `API Key Secret`. Open .env file and add the following: X_API_KEY="" X_API_SECRET="" [Tiktok](/providers/tiktok "Tiktok") [Youtube](/providers/youtube "Youtube") --- # 404: This page could not be found 404 === This page could not be found. ----------------------------- --- # Support - Postiz Docs Support Sometimes, things can go wrong, or you need some help! Note that the Self Hosted version of Postiz is supported by the community in their free time, on a best-efforts basis. Please post your question and be patient. * [Discord](https://discord.com/invite/sf7QjTcX37) - Flexible chat, with screenshots and screen sharing, probably the best option for support. * [GitHub issue](https://github.com/gitroomhq/postiz-app/issues/new/choose) - backup option if you are unable to use Discord. How to effectively ask for support[](#how-to-effectively-ask-for-support) -------------------------------------------------------------------------- Try to follow this guide when asking for support, in this order; **Goal, Environment, Changes, Results**. * **Goal:** Start off by explaining what you were trying to do * _I want to schedule a post on Reddit at 6pm_ * _I want to run in a Linux container on a Raspberry Pi_ * _I want to use a custom domain name_ * **Environment:** - Share the relevant parts about your environment. Web App issues; Are you using Firefox, Chrome, etc? Installation/Other issues; a Mac, Linux, Windows, how did you install? * _I’m using Firefox on Windows 10_ * _I’m using a Raspberry Pi 4 with Ubuntu 20.04, and Node version 18_ * _This is a new installation on a Mac_ * **Changed:** - Most likely something has changed, what is it? * _I updated my browser to the latest version and now …_ * _I found a change in the latest version and now …_ * _I think this used to work, but now…_ * **Results:** - What happened? What did you expect to happen? * _I see a blank screen_ * _I see an error message_ * _I see a 404 page_ [Youtube](/providers/youtube "Youtube") [Developer Guide](/developer-guide "Developer Guide") ---