diff --git a/docs.json b/docs.json
index 169b249..9350aba 100644
--- a/docs.json
+++ b/docs.json
@@ -217,15 +217,6 @@
"knowledge-base/analytics"
]
},
- {
- "group": "Automations",
- "pages": [
- "knowledge-base/automations/introduction",
- "knowledge-base/automations/triggers-and-nodes",
- "knowledge-base/automations/variables",
- "knowledge-base/automations/monitoring"
- ]
- },
{
"group": "Accounts",
"pages": [
diff --git a/knowledge-base/automations/introduction.mdx b/knowledge-base/automations/introduction.mdx
deleted file mode 100644
index e6cf6d0..0000000
--- a/knowledge-base/automations/introduction.mdx
+++ /dev/null
@@ -1,93 +0,0 @@
----
-title: "Automations"
-description: "Build flows that fetch, generate, and publish content on autopilot"
-icon: "bolt"
----
-
-
- Automations are in **beta**. The building blocks below are stable, but expect new node types and refinements over time.
-
-
-Automations let you wire together a **flow** that runs on its own: a trigger starts it, action nodes fetch data and generate content, and output nodes publish posts or call webhooks. Think of it as a visual pipeline for content that would otherwise be manual.
-
-A few things you can build:
-
-- Turn a blog or news **RSS feed** into a daily AI-written post.
-- React whenever you **publish a post** and notify an external service.
-- Pull data from any **HTTP API** and generate a post from it on a schedule.
-
-## How a flow works
-
-Every automation is a graph of **nodes** connected by lines:
-
-
-
- A schedule, or a post being published or scheduled. There is exactly one trigger per automation.
-
-
- Fetch an RSS feed or HTTP endpoint, generate content with AI, branch on a condition, or wait.
-
-
- Publish the generated post, or send an HTTP request from a [Webhook node](/knowledge-base/automations/triggers-and-nodes#output-nodes). For signed post-lifecycle notifications outside a flow, use [workspace webhooks](/knowledge-base/webhooks).
-
-
-
-Data flows **downstream**: each node can use the data produced by the nodes connected before it. See [Variables and expressions](/knowledge-base/automations/variables) for the full picture.
-
-## The editor
-
-Open an automation to land in the **Workflow** editor — a canvas where you drag nodes from the sidebar and connect them. Click any node to open its settings in that same panel.
-
-The detail screen has four tabs:
-
-
-
- The visual editor where you build and save the flow.
-
-
- A log of every real run, with per-node detail. See [Monitoring](/knowledge-base/automations/monitoring).
-
-
- Run health and output charts over a date range.
-
-
- Rename, activate or pause, and delete the automation.
-
-
-
-## Build your first automation
-
-
-
- Go to **Automations** and click **New automation**. It opens in the Workflow editor with a schedule trigger already in place.
-
-
- Click the trigger node and pick when it fires — a schedule, or a post event. See [Triggers and nodes](/knowledge-base/automations/triggers-and-nodes).
-
-
- Drag nodes from the sidebar onto the canvas and connect them by dragging from one node's handle to the next.
-
-
- In any text field, type `{{` to autocomplete the data available at that point in the flow.
-
-
- Click **Run test** to execute the flow end-to-end with synthesized data before going live.
-
-
- Click **Save**, then open the **Settings** tab and flip the status switch to activate. The automation now runs on its own.
-
-
-
-## Statuses
-
-An automation is always in one of three states:
-
-| Status | Meaning |
-| --- | --- |
-| **Draft** | Being built. It never runs. |
-| **Active** | Live. The trigger fires and the flow runs. |
-| **Paused** | Stopped. The trigger no longer fires until you reactivate it. |
-
-
- Activating and pausing live in the **Settings** tab. You can pause anytime without losing your flow.
-
diff --git a/knowledge-base/automations/monitoring.mdx b/knowledge-base/automations/monitoring.mdx
deleted file mode 100644
index 0c99f3a..0000000
--- a/knowledge-base/automations/monitoring.mdx
+++ /dev/null
@@ -1,90 +0,0 @@
----
-title: "Testing and monitoring"
-description: "Test runs, the invocations log, metrics, and lifecycle settings"
-icon: "chart-line"
----
-
-Once a flow is built, you can test it before going live and watch how it performs once it's running.
-
-## Testing
-
-Click **Run test** in the Workflow editor to execute the whole flow end-to-end and inspect what each node does. The result panel shows every node's **input** and **output** as it runs — the fastest way to confirm your expressions resolve correctly.
-
-There are two modes:
-
-| Mode | What it does |
-| --- | --- |
-| **Dry run** (default) | Runs every node, including AI generation, but **never publishes** a post or triggers external side effects. The generated content is shown but not saved. |
-| **With real data** | Actually publishes posts and fires webhooks. Use it for a final end-to-end check. |
-
-
- A **With real data** test really publishes and fires side effects. Use it deliberately.
-
-
-
- Test runs never appear in the Invocations log or Metrics — those report only on real, automatic executions.
-
-
-## Invocations
-
-The **Invocations** tab is the run log: every time the live automation fires, it lands here, newest first.
-
-Each row shows:
-
-- **Timestamp** — when the run started
-- **Run** — its ID (click to copy)
-- **Status** — completed, failed, running, waiting, pending, or cancelled
-- **Last message** — a summary and the number of steps it ran
-- **Duration** — how long it took
-
-Click any row to expand it and see the **per-node breakdown** of that run. Use the **status filter** to narrow to failures, and the **search** box to find a run by ID.
-
-
- Only real executions show up here. Tests you run from the editor are kept out so the log stays meaningful.
-
-
-## Metrics
-
-The **Metrics** tab charts the automation's health and output over a date range you pick with the range picker.
-
-**Run health**
-
-- Total runs, completed, failed, in progress
-- Success rate and average duration
-- A chart of runs started, completed, and failed over time
-
-**Output**
-
-- Posts created by the automation
-- A breakdown of those posts by platform
-
-
- Like Invocations, Metrics count only real runs — test runs never inflate the numbers.
-
-
-## Settings and lifecycle
-
-The **Settings** tab is where you operate the automation:
-
-
-
- Change the automation's name without touching the flow.
-
-
- Flip the status switch to go live or stop. Pausing keeps the flow intact — the trigger simply stops firing until you reactivate.
-
-
- In the **danger zone**, permanently remove the automation and its run history. This can't be undone.
-
-
-
-## Related
-
-
-
- The big picture and a build walkthrough.
-
-
- Pass data between nodes.
-
-
diff --git a/knowledge-base/automations/triggers-and-nodes.mdx b/knowledge-base/automations/triggers-and-nodes.mdx
deleted file mode 100644
index 29433e0..0000000
--- a/knowledge-base/automations/triggers-and-nodes.mdx
+++ /dev/null
@@ -1,108 +0,0 @@
----
-title: "Triggers and nodes"
-description: "Every building block you can drop into a flow"
-icon: "diagram-project"
----
-
-A flow is built from **nodes**. One trigger starts it; the rest fetch data, shape the flow, or deliver output. Drag nodes from the editor sidebar and connect them by dragging from a node's handle to the next node.
-
-## Triggers
-
-Every automation has exactly one trigger. It decides **when** the flow runs.
-
-| Trigger | Fires when | Provides |
-| --- | --- | --- |
-| **Schedule** | A cron-style schedule you set (every N minutes/hours/days, weekly, monthly, or a custom expression) | `trigger.event`, `trigger.fired_at` |
-| **Post published** | One of your posts is published | `trigger.post.*` |
-| **Post scheduled** | One of your posts is scheduled | `trigger.post.*` |
-
-
- The trigger is created with the automation and can't be removed — you can only change its type. The schedule editor lets you pick an interval, time, weekdays, or a custom cron expression, and the timezone defaults to your workspace timezone.
-
-
-## Source nodes
-
-Source nodes pull external data into the flow. Both expose two output handles — **has items** and **no items** — so you can branch on whether anything new came back.
-
-
-
- Reads an RSS/Atom feed from a **Feed URL** and exposes the matched item as `fetched.title`, `fetched.link`, `fetched.description`, and `fetched.pubDate`.
-
- TryPost remembers which items it has already seen, so the flow only runs for genuinely **new** entries.
-
-
- Calls any HTTP endpoint. Configure the **URL**, **method** (GET/POST/PUT/PATCH/DELETE), authentication (none, bearer, basic, or API key), headers, and a body template. Auth tokens and passwords are stored encrypted.
-
- The JSON response becomes `fetched`, so you reference any field with `{{ fetched. }}`. Optional **items path**, **item key path**, and **item date path** settings let it walk a list response and dedupe items the same way the RSS node does.
-
-
-
-
- **First run sets a baseline.** The first time a source node polls an existing feed or endpoint, it records what's already there and produces nothing — only items that appear *after* that trigger the flow.
-
- **New items fan out.** When a source node then finds several new items at once, each one runs the downstream nodes independently — five new feed entries produce five posts. A test run only ever processes the first item, so it stays predictable.
-
-
-## Content node
-
-
- Generates a post with AI and attaches it to one or more social accounts.
-
- - **Accounts** — which connected accounts and content types to post to. The most restrictive selected platform (smallest character limit) drives the generated copy so it fits everywhere.
- - **Prompt** — your instruction. Reference upstream data with `{{ }}`, e.g. `Write a post about {{ fetched.title }}`.
- - **Image count** — `0` for text-only (LinkedIn, X, Threads), `1` for a single image, or `2–10` for a carousel. The picker only offers counts the selected accounts support.
- - **Use brand voice** — when off, the post stays faithful to the source instead of being rewritten in your brand persona. Useful for news curation.
- - **Use brand visuals** — when off, generated images skip your brand colors and identity.
-
- Provides `generated.content` and `generated.post_url`.
-
-
-
- The Generate node uses the same content engine as **Create with AI** — see [AI features](/knowledge-base/ai-features) and [Brand profile](/knowledge-base/brand-profile).
-
-
-## Flow nodes
-
-These shape the path the run takes.
-
-
-
- Branches the flow. Compares a **field** (any `{{ }}` expression) against a **value** using one of: `contains`, `not contains`, `equals`, `not equals`, `matches` (regex), `greater than`, or `less than`. The flow continues down the matching branch.
-
-
- Pauses the flow for a **duration** in minutes, hours, or days before continuing. Useful for spacing out actions.
-
-
-
-## Output nodes
-
-
-
- Publishes the post created by an upstream Generate node. Choose a **mode**:
-
- | Mode | Result |
- | --- | --- |
- | **Now** | Publishes immediately |
- | **Scheduled** | Schedules it, offset by N minutes from now (default 60) |
- | **Draft** | Leaves it as a draft for you to review |
-
-
- Sends an HTTP request to an external system. Configure the **URL**, **method**, headers, and a **payload template** where you can inject any `{{ }}` expression.
-
- This is a one-off call inside the flow — not a workspace [event webhook](/knowledge-base/webhooks). Posts this flow creates still emit workspace webhook events if you subscribed (`created_via` is `automation`). Use workspace webhooks when you want signed `post.published` / `post.failed` deliveries for every matching post.
-
-
- Stops the automation at that point. Optional — a branch ends on its own when it has no more nodes.
-
-
-
-## What's next
-
-
-
- Pass data between nodes with `{{ }}`.
-
-
- Test runs, the invocations log, and metrics.
-
-
diff --git a/knowledge-base/automations/variables.mdx b/knowledge-base/automations/variables.mdx
deleted file mode 100644
index a3cc61b..0000000
--- a/knowledge-base/automations/variables.mdx
+++ /dev/null
@@ -1,124 +0,0 @@
----
-title: "Variables and expressions"
-description: "Pass data between nodes with double-brace expressions and reusable workflow variables"
-icon: "code"
----
-
-Automations move data between nodes with **expressions**. Wrap a path in double braces and TryPost replaces it at run time with the real value:
-
-```text
-Write a short post about {{ fetched.title }} and link to {{ fetched.link }}.
-```
-
-Expressions work in **any text field** of any node — prompts, webhook payloads, HTTP bodies, condition fields, and more.
-
-## What data is in scope
-
-This is the rule that trips people up most:
-
-
- A node can only use data from nodes connected **before** it (upstream). If a node isn't on the path leading into the current node, its data isn't available.
-
-
-So a Generate node placed after a **Fetch RSS** node can use `{{ fetched.title }}`, but a node that runs *before* the fetch cannot — the data doesn't exist yet at that point in the flow.
-
-
- In any field, type `{{` to open an autocomplete of exactly what's in scope at that node. Known references are highlighted; unknown ones are flagged so you catch typos before running.
-
-
-## Expression reference
-
-Which expressions exist depends on which nodes run upstream.
-
-### Schedule trigger
-
-Available when the flow starts from a **Schedule** trigger.
-
-| Expression | Value |
-| --- | --- |
-| `{{ trigger.event }}` | The trigger event name |
-| `{{ trigger.fired_at }}` | When the trigger fired |
-
-### Post trigger
-
-Available when the flow starts from a **Post published** or **Post scheduled** trigger.
-
-| Expression | Value |
-| --- | --- |
-| `{{ trigger.post.id }}` | The triggering post's ID |
-| `{{ trigger.post.content }}` | Its content |
-| `{{ trigger.post.status }}` | Its status |
-| `{{ trigger.post.scheduled_at }}` | When it's scheduled |
-| `{{ trigger.post.published_at }}` | When it was published |
-
-### Fetch RSS
-
-Available downstream of a **Fetch RSS** node.
-
-| Expression | Value |
-| --- | --- |
-| `{{ fetched.title }}` | The feed item's title |
-| `{{ fetched.link }}` | Its link |
-| `{{ fetched.description }}` | Its description |
-| `{{ fetched.pubDate }}` | Its publish date |
-
-### HTTP Request
-
-Available downstream of an **HTTP Request** node. The whole JSON response is exposed as `fetched`, so you append whatever path you need:
-
-```text
-{{ fetched.data.0.title }}
-{{ fetched.user.name }}
-```
-
-| Expression | Value |
-| --- | --- |
-| `{{ fetched. }}` | Any field from the JSON response |
-
-### Generate
-
-Available downstream of a **Generate** node.
-
-| Expression | Value |
-| --- | --- |
-| `{{ generated.content }}` | The AI-generated post content |
-| `{{ generated.post_url }}` | The generated post's URL |
-
-### Always available
-
-These work anywhere in any flow.
-
-| Expression | Value |
-| --- | --- |
-| `{{ variables.YOUR_KEY }}` | A workflow variable (see below) |
-| `{{ now }}` | The current date and time |
-
-## Workflow variables
-
-Workflow variables are **reusable values** you define once and reference anywhere with `{{ variables.KEY }}`. They're scoped to a single automation.
-
-Use them for values you repeat across nodes or want to keep out of node fields — API keys, base URLs, account handles, a default hashtag.
-
-
-
- In the Workflow editor, switch to the **Variables** tab in the right sidebar.
-
-
- Give it a **key** (letters, numbers, and underscores — e.g. `API_KEY`) and a **value**.
-
-
- Use `{{ variables.API_KEY }}` in any field, in any node.
-
-
-
-
- Variable values are **stored encrypted**. They're safe for secrets like API keys.
-
-
-## See it in action
-
-The surest way to learn what's available is to run the flow:
-
-
- Click **Run test** in the editor and open the result panel. Each node shows its exact **input** and **output**, so you can see precisely what every expression resolves to. See [Testing and monitoring](/knowledge-base/automations/monitoring).
-
diff --git a/knowledge-base/plans-and-billing.mdx b/knowledge-base/plans-and-billing.mdx
index f107422..87d32c8 100644
--- a/knowledge-base/plans-and-billing.mdx
+++ b/knowledge-base/plans-and-billing.mdx
@@ -18,7 +18,7 @@ TryPost Cloud has one plan, priced per workspace. Every feature is included on e
| Social accounts | One account on each network (your social set) |
| Team members | Unlimited, with roles and approvals |
| AI credits | 2,500 per month, pooled across your account |
-| Included | Calendar, AI Copilot, automations, MCP server, REST API, analytics, signatures, labels |
+| Included | Calendar, AI Copilot, MCP server, REST API, analytics, signatures, labels |
Pricing is localized in some regions (for example, **R$60 / month** in Brazil). See the [pricing page](https://trypost.it/pricing) for current rates.
diff --git a/knowledge-base/social-accounts.mdx b/knowledge-base/social-accounts.mdx
index 87df830..4d5f233 100644
--- a/knowledge-base/social-accounts.mdx
+++ b/knowledge-base/social-accounts.mdx
@@ -97,7 +97,7 @@ If any of these detects a disconnected or expired account, the workspace owner r
## Reconnecting an account
-A card that needs attention shows a **Reconnect** button. Reconnecting refreshes that specific card — it keeps its posts, its scheduling history, and its place in your automations. It never creates a second card.
+A card that needs attention shows a **Reconnect** button. Reconnecting refreshes that specific card — it keeps its posts and its scheduling history. It never creates a second card.
Because it is tied to one card, you have to authorize **the same account** you are reconnecting:
diff --git a/knowledge-base/webhooks.mdx b/knowledge-base/webhooks.mdx
index 77c1010..00368bf 100644
--- a/knowledge-base/webhooks.mdx
+++ b/knowledge-base/webhooks.mdx
@@ -6,7 +6,7 @@ icon: "webhook"
Workspace webhooks POST a signed JSON payload to a URL you control whenever a subscribed post event fires. Use them to sync a CRM, trigger an internal job, or keep another system in step with TryPost.
-They are **outgoing** event subscriptions for the workspace. They are not the [automation Webhook node](/knowledge-base/automations/triggers-and-nodes#output-nodes) (a one-off HTTP call inside a flow), and they are not inbound Telegram/Stripe webhooks.
+They are **outgoing** event subscriptions for the workspace — not inbound Telegram/Stripe webhooks.
## Who can manage webhooks
@@ -62,7 +62,7 @@ Publish now (dashboard **Post now**, REST `PUT` with `status=publishing`, or `pu
Edits that do **not** change status send nothing: content, media, labels, platforms, or a new `scheduled_at` on a post that is already `scheduled`. [Duplicate](/knowledge-base/posts#duplicating-a-post) is a new post, so it fires `post.created`. A failed or published post cannot be republished in place — duplicate it and you will get a fresh lifecycle.
-There are no events for comments, mentions, social-account disconnects, or team changes — those stay in [notifications](/knowledge-base/notifications). AI Create has no dedicated `post.ready` event; when the draft is saved you get `post.created` (`created_via` is `web`). Posts created by an [automation](/knowledge-base/automations/introduction) still fire these events (`created_via` is `automation`). Deleting a [workspace](/knowledge-base/workspaces) removes the webhooks with it and does **not** send `post.deleted` for each post.
+There are no events for comments, mentions, social-account disconnects, or team changes — those stay in [notifications](/knowledge-base/notifications). AI Create has no dedicated `post.ready` event; when the draft is saved you get `post.created` (`created_via` is `web`). Deleting a [workspace](/knowledge-base/workspaces) removes the webhooks with it and does **not** send `post.deleted` for each post.
## Receive a delivery
@@ -151,7 +151,7 @@ For every post event except `post.deleted`, `data` is the post at the moment of
| `workspace_id` | Workspace UUID |
| `user_id` | Author user UUID |
| `status` | `draft`, `scheduled`, `publishing`, `published`, `partially_published`, or `failed` |
-| `created_via` | `web`, `api`, `mcp`, `automation`, or `null` |
+| `created_via` | `web`, `api`, `mcp`, or `null` |
| `content` | Post body. May include HTML from the editor (e.g. `…
`), or be an empty string |
| `scheduled_at` / `published_at` / `created_at` / `updated_at` | ISO 8601, or `null` — not the `Y-m-d H:i:s` strings used by [`GET /posts`](/api-reference/endpoint/list-posts) |
| `author` | `{ id, name }` only — no email — or `null` |
@@ -303,9 +303,6 @@ List and update responses omit `signing_secret`. Create, get, and rotate return
Five deliveries in a row exhausted their retries. Fix the endpoint, then set status back to **enabled**.
-
- Workspace webhooks fire on post lifecycle events and are always signed the same way. The [automation Webhook node](/knowledge-base/automations/triggers-and-nodes#output-nodes) is an HTTP step inside a flow — you pick the method, headers, and body template.
-
Seven days. Older rows are pruned daily. Deleting the webhook removes the remaining logs.
@@ -328,12 +325,9 @@ List and update responses omit `signing_secret`. Create, get, and rotate return
No. `post.scheduled` only fires when status becomes `scheduled`. Editing `scheduled_at` on an already-scheduled post is silent.
- No. Workspace webhooks are always `POST` with `Content-Type`, `User-Agent`, and `X-Webhook-Signature`. For a custom request, use the [automation Webhook node](/knowledge-base/automations/triggers-and-nodes#output-nodes).
+ No. Workspace webhooks are always `POST` with `Content-Type`, `User-Agent`, and `X-Webhook-Signature`.
No. Only the seven post lifecycle events. Comments, mentions, and account disconnects stay in [notifications](/knowledge-base/notifications).
-
- Yes. Create, schedule, publish, and delete still emit the matching events. `created_via` is `automation`. That is separate from the [automation Webhook node](/knowledge-base/automations/triggers-and-nodes#output-nodes).
-
diff --git a/self-hosting/configuration.mdx b/self-hosting/configuration.mdx
index a86bd08..96eb525 100644
--- a/self-hosting/configuration.mdx
+++ b/self-hosting/configuration.mdx
@@ -136,7 +136,7 @@ BROADCAST_CONNECTION=reverb
| Variable | Recommended | Why |
|----------|-------------|-----|
-| `QUEUE_CONNECTION` | `redis` | Horizon processes Redis queues (publishing, notifications, automations) |
+| `QUEUE_CONNECTION` | `redis` | Horizon processes Redis queues (publishing, notifications, webhooks) |
| `CACHE_STORE` | `redis` | Cache + `onOneServer()` schedule locks across instances |
| `SESSION_DRIVER` | `database` | Durable sessions behind multiple app workers |
| `BROADCAST_CONNECTION` | `reverb` | Real-time dashboard updates |
@@ -551,7 +551,7 @@ TRYPOST_USER_AGENT="TryPost.it/1.0 (+https://trypost.it)"
| Variable | Default | Description |
|----------|---------|-------------|
-| `TRYPOST_ALLOW_PRIVATE_NETWORK` | `false` | When `true`, allows HTTP requests from TryPost (RSS, [workspace webhooks](/knowledge-base/webhooks), URL media fetches, etc.) to private/internal network addresses. Keep `false` unless you intentionally need that for a private network install. |
+| `TRYPOST_ALLOW_PRIVATE_NETWORK` | `false` | When `true`, allows HTTP requests from TryPost ([workspace webhooks](/knowledge-base/webhooks), URL media fetches, brand autofill, etc.) to private/internal network addresses. Keep `false` unless you intentionally need that for a private network install. |
| `TRYPOST_USER_AGENT` | `TryPost.it/1.0 (+https://trypost.it)` | `User-Agent` sent on outgoing HTTP, including webhook deliveries and test pings. |
## Next Steps
diff --git a/self-hosting/installation.mdx b/self-hosting/installation.mdx
index 9d963e7..69a2001 100644
--- a/self-hosting/installation.mdx
+++ b/self-hosting/installation.mdx
@@ -69,7 +69,7 @@ FILESYSTEM_DISK=public
|-------|-----|
| `APP_KEY` | Already set by `key:generate` — encrypts sessions, cookies, encrypted data |
| Database | Where posts, users, and Passport clients live. The block above is PostgreSQL; for MySQL use `DB_CONNECTION=mysql` on port `3306` — see [Database](/self-hosting/configuration#database) |
-| Redis + queue/cache drivers | Horizon publishes posts and runs automations from Redis queues |
+| Redis + queue/cache drivers | Horizon publishes posts and processes background jobs from Redis queues |
| `BROADCAST_CONNECTION=reverb` | Live dashboard updates |
| `FILESYSTEM_DISK=public` | Local media on disk (use `s3` / `r2` / `spaces` for object storage) |
| `SELF_HOSTED=true` | Disables Stripe billing and public `/register` |
@@ -175,9 +175,9 @@ This starts `php artisan serve`, a queue listener, log tail, and Vite. Open `htt
| Process | Command | Purpose |
|---------|---------|---------|
| Web (PHP-FPM + Nginx) | see [Production](/self-hosting/production#nginx-configuration) | Serve HTTP |
-| **Horizon** | `php artisan horizon` | Queues — publish posts, notifications, automations, webhooks |
+| **Horizon** | `php artisan horizon` | Queues — publish posts, notifications, webhooks |
| **Reverb** | `php artisan reverb:start` | WebSockets |
-| **Scheduler** | cron → `php artisan schedule:run` | Due posts, token refresh, automations |
+| **Scheduler** | cron → `php artisan schedule:run` | Due posts, token refresh, stuck-post recovery |
Full Supervisor configs, Nginx (including Reverb `/app/` + `/apps/`), SSL, and caches: [Production setup](/self-hosting/production).
diff --git a/self-hosting/production.mdx b/self-hosting/production.mdx
index dd21615..c9b9fb5 100644
--- a/self-hosting/production.mdx
+++ b/self-hosting/production.mdx
@@ -61,7 +61,7 @@ TryPost uses queues for critical background processing:
- **Sending notifications** (email and in-app)
- **Verifying social account connections**
- **Processing analytics events**
-- **Running automations**
+- **Delivering [webhooks](/knowledge-base/webhooks)** and their retries
Without a running queue worker, scheduled posts will not be published. Use Supervisor to keep Horizon running.
@@ -190,15 +190,11 @@ sudo certbot --nginx -d your-domain.com
## Scheduled Tasks (Cron)
-TryPost uses Laravel's task scheduler for several recurring jobs. The scheduler **must** run every minute or scheduled posts won't publish, automations won't fire, expiring tokens won't refresh, and stuck posts won't recover.
+TryPost uses Laravel's task scheduler for several recurring jobs. The scheduler **must** run every minute or scheduled posts won't publish, expiring tokens won't refresh, and stuck posts won't recover.
| Command | Schedule | Purpose |
|---------|----------|---------|
| `posts:process-scheduled` | every minute | Dispatches `PublishPost` jobs for posts that are due |
-| `automation:fire-schedule` | every minute | Fires time-based automation triggers |
-| `automation:process-delays` | every minute | Advances automation runs waiting on delay nodes |
-| `automation:recover-stuck-runs` | every 5 minutes | Recovers automation runs stuck mid-flight |
-| `automation:prune-dry-runs` | every 10 minutes | Prunes dry-run automation history |
| `social:refresh-expiring-tokens` | every 15 minutes | Refreshes OAuth tokens that are about to expire |
| `social:recover-stuck-posts` | every 30 minutes | Detects posts stuck in `publishing` and retries or fails them |
| `social:check-connections` | daily | Verifies every connected social account still has a valid token |
@@ -217,7 +213,7 @@ Add this line:
```
- This is required. Without the cron job, scheduled posts will not be published automatically, automations will stall, and social tokens will expire silently.
+ This is required. Without the cron job, scheduled posts will not be published automatically and social tokens will expire silently.
## WebSocket Server (Reverb)
@@ -275,9 +271,9 @@ Make sure all of these are in place in production:
| **Storage link** | `php artisan storage:link` (once, if `FILESYSTEM_DISK=public`) | Local media URLs — skip for S3 / R2 / Spaces |
| **Redis** | `QUEUE_CONNECTION=redis` + Redis up | Queues, cache, schedule locks |
| **Mail** | SMTP or SendKit | Invites, password reset, alerts |
-| **Horizon** | `php artisan horizon` (Supervisor) | Publishes posts, notifications, automations, and [webhooks](/knowledge-base/webhooks) |
+| **Horizon** | `php artisan horizon` (Supervisor) | Publishes posts, notifications, and [webhooks](/knowledge-base/webhooks) |
| **Reverb** | `php artisan reverb:start` (Supervisor) | Real-time WebSocket updates |
-| **Scheduler** | cron → `schedule:run` every minute | Due posts, token refresh, automations |
+| **Scheduler** | cron → `schedule:run` every minute | Due posts, token refresh, stuck-post recovery |
If Horizon, Reverb, or the scheduler are not running, TryPost will not function correctly. Scheduled posts won't publish, notifications won't send, and the dashboard won't update in real time.
diff --git a/self-hosting/upgrading.mdx b/self-hosting/upgrading.mdx
index 92dceb6..3f7a052 100644
--- a/self-hosting/upgrading.mdx
+++ b/self-hosting/upgrading.mdx
@@ -27,7 +27,7 @@ This release adds a database constraint that a workspace cannot hold the same id
**Why it matters:** earlier versions could store the same account more than once — the per-network guard was skipped on self-hosted installs, and Pinterest created a fresh row on every connect. Duplicates like that would block the new constraint, so the migration merges them first.
-For each duplicated identity it keeps the **most recently created** account, moves that account's scheduled posts and automation targets onto the survivor, and deletes the rest.
+For each duplicated identity it keeps the **most recently created** account, moves that account's scheduled posts onto the survivor, and deletes the rest.
Merging can leave a post aimed at the same account twice, which would publish it twice. Those repeats are collapsed: