# Automation Rules Source: https://docs.reactor.tools/analytics/automation # Automation Rules Automation rules let Reactor take action automatically when a condition is met. Rules run in the background and can trigger brief creation, scheduling changes, or alerts. ## Rule structure Each rule has: - A **trigger type** -- what condition activates the rule - A **threshold** -- the numeric value at which the trigger fires - An **action type** -- what Reactor does when triggered - An **action config** -- parameters for the action ## Trigger types | Trigger | Description | |---|---| | `engagement_threshold` | A post's engagement rate crosses a defined value | | `topic_velocity` | A topic is being searched or referenced at an accelerating rate | | `posting_gap` | No content has been published for N days on a platform | | `conversion_rate` | A funnel's conversion rate drops below a threshold | ## Action types | Action | Description | |---|---| | `create_brief` | Automatically create a brief with the specified topic and platform | | `pause_platform` | Stop publishing to a platform until manually re-enabled | | `alert` | Send a notification (webhook or in-app) | | `reschedule` | Move a scheduled post to a different time | ## Creating a rule ### Via MCP ```json { "tool": "create_automation_rule", "arguments": { "name": "Revive top performers", "triggerType": "engagement_threshold", "triggerConfig": { "threshold": 0.05, "comparison": "above", "platform": "linkedin" }, "actionType": "create_brief", "actionConfig": { "topic": "Follow-up on high-engagement post", "platform": "linkedin", "angle": "Expand on the key insight from the top performer" } } } ``` ### Via UI Go to **Analytics > Automation** (coming soon in a future release) or use the MCP tool. ## Listing rules ```json { "tool": "list_automation_rules", "arguments": {} } ``` Returns all active and inactive rules for the workspace. ## Rule evaluation Rules are evaluated hourly as part of the analytics sync cycle. There is no real-time trigger evaluation -- the maximum latency between a condition being met and the action firing is approximately one hour. ## Use cases **Always-on content machine**: Create a rule that fires a new brief whenever there has been no post on LinkedIn in the last 3 days. This ensures your content cadence never stalls. **Amplify what works**: Fire a create-brief action whenever a post exceeds 5% engagement rate on X. The brief topic is the same subject so you can expand it into a longer piece. **Protect your metrics**: Set a conversion rate threshold that triggers an alert if your funnel drops below 2%, so you can investigate before it becomes a bigger problem. --- # Data Sources Source: https://docs.reactor.tools/analytics/data-sources # Data Sources Data sources are the external analytics platforms Reactor pulls data from. Connect them in **Settings > Data Sources**. ## Available data sources ### Google Analytics 4 Pulls sessions, users, pageviews, bounce rate, and UTM attribution data. **Required credentials:** - Property ID (format: `G-XXXXXXXXXX` or numeric) - OAuth access token (via Google service account) **Sync frequency:** Hourly **What it enables:** Website traffic section of analytics dashboard, UTM content attribution table, funnel data --- ### Google Search Console Pulls search query data: impressions, clicks, CTR, and average position. **Required credentials:** - Site URL (verified in GSC) - OAuth access token (via Google service account) **Sync frequency:** Daily (GSC data is delayed 2-3 days by Google) **What it enables:** GSC platform deep-dive page, keyword opportunity analysis --- ### Plausible Analytics Privacy-first web analytics. Supports both Plausible Cloud and self-hosted instances. **Required credentials:** - Site domain (e.g., `yoursite.com`) - API key (from Plausible > Settings > API Keys) - Base URL (optional, for self-hosted -- defaults to `https://plausible.io`) **Sync frequency:** Hourly **What it enables:** Website traffic, UTM breakdown --- ### Matomo Open-source analytics. Supports both Matomo Cloud and self-hosted instances. **Required credentials:** - Site ID (numeric ID from Matomo > Settings > Websites) - API token (from Matomo > Settings > Security > Auth tokens) - Base URL (your Matomo instance URL) **Sync frequency:** Hourly **What it enables:** Website traffic, campaign attribution via Matomo's campaign tracker **Note:** For UTM-based attribution in Matomo, ensure the [Marketing Campaigns Reporting](https://plugins.matomo.org/MarketingCampaignsReporting) plugin is installed. Without it, campaign data falls back to the built-in referrer campaigns report. --- ### Beehiiv Newsletter analytics for Beehiiv publications. **Required credentials:** - API key (from Beehiiv > Settings > Integrations > API) - Publication ID (format: `pub_xxxxxxxx`) **Sync frequency:** Hourly **What it enables:** Email analytics page, open rate and click rate trends, per-issue performance table --- ### ConvertKit Email analytics for ConvertKit accounts. **Required credentials:** - API key (from ConvertKit > Settings > Advanced) **Sync frequency:** Hourly **What it enables:** Email analytics page, subscriber metrics, broadcast performance --- ### HubSpot CRM and email analytics from HubSpot. **Required credentials:** - Private app token (format: `pat-xxxxxxxx-xxxx`, from HubSpot > Settings > Integrations > Private Apps) **Sync frequency:** Every 15 minutes **What it enables:** Contact attribution, email analytics, pipeline conversion data --- ### Ghost (Analytics) Member and visitor analytics from Ghost publications. **Required credentials:** - Ghost instance URL - Admin API key (from Ghost Admin > Settings > Integrations, in `id:secret` format) **Sync frequency:** Hourly **What it enables:** Member count, unique visitor data, post performance --- ## Connecting a data source 1. Go to **Settings > Data Sources** 2. Find the platform you want to connect 3. Click **Connect** 4. Enter the required credentials 5. Click **Save** Reactor will attempt a test sync immediately and show a `connected` badge if successful. ## Manual sync Click **Sync Now** at the top of the Data Sources page to trigger an immediate sync of all connected sources. Via MCP: ```json { "tool": "sync_analytics", "arguments": {} } ``` ## Sync status Check last sync time per source on the Data Sources page or via MCP: ```json { "tool": "get_sync_status", "arguments": {} } ``` --- # Analytics Funnels Source: https://docs.reactor.tools/analytics/funnels # Analytics Funnels Funnels let you track multi-step conversion paths from content to goal completion. ## What funnels measure A funnel defines a sequence of steps you want a user to complete after interacting with your content. Reactor tracks how many users complete each step and where they drop off. Example funnel: LinkedIn post visit > website session > pricing page > signup ## Creating a funnel Funnels are created via the MCP tool (UI builder coming soon): ```json { "tool": "create_funnel", "arguments": { "name": "Content to Signup", "steps": [ { "name": "Social post click", "event": "utm_content_visit" }, { "name": "Pricing page", "url_contains": "/pricing" }, { "name": "Signup", "event": "goal_signup" } ] } } ``` Steps are matched using UTM data from your analytics integration (GA4 or Plausible). ## Funnel results Once a funnel is defined, Reactor queries your analytics data to populate conversion rates per step. Results are available on the analytics funnels page and via MCP. Funnel data shows: - Entry count (how many users started the funnel) - Per-step completion count - Per-step drop-off rate - Overall conversion rate (step 1 to last step) ## Funnel attribution Funnels use the `utm_content` parameter to link content items to funnel entries. This requires UTM-tagged links in your content. See [UTM Tracking](./utm-tracking) for setup. ## Limitations - Funnel matching depends on event data available in your connected analytics platform - Cross-device funnel completion is not tracked - Funnels require at least 7 days of historical data to produce meaningful results --- # Content Insights Source: https://docs.reactor.tools/analytics/insights # Content Insights Insights are AI-generated observations about your content performance. They surface patterns and opportunities you might miss from looking at raw metrics. ## Insight types | Type | Description | |---|---| | `top_performer` | A piece of content is significantly outperforming your average engagement rate | | `posting_time` | A consistent pattern in which days or hours produce better engagement | | `topic_cluster` | A set of topics that consistently drive high engagement | | `platform_shift` | Engagement is rising on one platform and declining on another | | `decay_alert` | A high-performing piece of older content is losing engagement and may benefit from a follow-up | | `strategy_suggestion` | A synthesized recommendation based on multiple signals | ## Insight severity | Severity | Meaning | |---|---| | `opportunity` | Something you could do to improve | | `info` | An interesting pattern worth knowing | | `warning` | Something declining or at risk | ## Viewing insights Insights appear in the insights panel on the analytics dashboard. Each card shows the type, severity, a title, and a description with specific data points. ## Acting on insights Each insight includes an action button. Depending on the type: - **Top performer insights** link to the content item so you can study what worked - **Topic cluster insights** open a pre-filled brief for a follow-up piece on the same topic - **Posting time insights** show recommended posting times and link to the scheduling panel - **Decay alerts** link to the original content and suggest a refresh or repurpose ## Generating insights via MCP ```json { "tool": "get_insights", "arguments": { "limit": 10 } } ``` Returns active (non-dismissed) insights sorted by severity and recency. ## Dismissing insights Insights can be dismissed once you have acted on them or if they are not relevant. ```json { "tool": "dismiss_insight", "arguments": { "insightId": "insight_abc123" } } ``` Dismissed insights do not reappear. ## Insights from analytics The `suggest_brief_from_analytics` tool takes a step further -- it analyzes your top-performing content and generates a complete brief (not just an insight) that you can immediately generate content from. ```json { "tool": "suggest_brief_from_analytics", "arguments": { "platform": "linkedin" } } ``` --- # Analytics Overview Source: https://docs.reactor.tools/analytics/overview # Analytics Overview The analytics dashboard gives you a consolidated view of how your content is performing across every channel and data source. ## Dashboard sections ### Content performance The main KPI strip shows aggregate metrics across all channels: - Total impressions - Total engagements - Average engagement rate - Total reach - Published posts in the period These aggregate across all connected channels (X, LinkedIn, Discord, email). ### Platform breakdown Below the KPI strip, performance is broken down per platform. Each platform card shows total posts, impressions, and engagement rate for the period. Click any platform card to go to the [platform deep-dive](./platforms). ### Website traffic If you have connected Google Analytics, Plausible, or Matomo, website sessions and pageviews are shown in the traffic section with a time-series chart. ### Top content The top content table lists your best-performing posts by engagement rate, with links to the source content item so you can analyze what worked. ### Content insights The insights panel surfaces AI-generated observations about your content performance: top performers, posting time patterns, topic clusters, engagement decay alerts, and strategic suggestions. Each insight can be dismissed or acted on. ## Period selection Use the period picker in the top right to change the date range. Available presets: 7 days, 30 days, 90 days. You can also enter a custom date range. Enable the **Compare** toggle to show a side-by-side comparison with the prior equivalent period. ## Syncing data Analytics data is synced hourly from all connected data sources. You can trigger a manual sync from **Settings > Data Sources** or by calling the `sync_analytics` MCP tool. Last sync time is shown per data source in Settings > Data Sources. --- # Platform Deep Dives Source: https://docs.reactor.tools/analytics/platforms # Platform Deep Dives Each connected channel has a dedicated analytics page with platform-specific metrics. Access platform deep dives from **Analytics > Platforms** in the sidebar. ## X (Twitter) The X analytics page shows: **KPIs**: Total impressions, total engagements, average engagement rate, total likes, total retweets **Engagement over time**: Line chart of impressions and engagements per day **Best days to post**: Bar chart of average engagement rate by day of week, based on your historical data **Top tweets**: Table of your best-performing tweets in the period, ranked by engagement rate, with impression and like counts ## LinkedIn The LinkedIn analytics page shows: **KPIs**: Total impressions, total engagements, average engagement rate, total reactions, total comments, total shares **Engagement over time**: Line chart with impressions and engagements **Best days to post**: Bar chart of average engagement rate by day of week **Top posts**: Table of top posts ranked by engagement rate ## Website (GA4 and Plausible and Matomo) The web analytics page shows: **KPIs**: Total sessions, total users, average bounce rate, total pageviews **Traffic over time**: Line chart of sessions and pageviews per day **UTM content attribution**: Table showing which Reactor content pieces are driving the most traffic, via `utm_content` parameter matching **Top traffic sources**: Breakdown by source/medium ## Google Search Console The GSC page shows: **KPIs**: Total clicks, total impressions, average CTR, average position **Top queries**: Table of search queries sorted by impressions, with clicks, CTR, and position **Top pages**: Table of your best-ranking pages **Keyword opportunities**: Computed list of queries where you rank on page 1 (position 3-10) with CTR below 3% and impressions above 50. These are queries where a better title or meta description could increase clicks without needing to improve the ranking itself. ## Email (Beehiiv and ConvertKit) The email analytics page shows: **KPIs**: Average open rate, average click rate, total delivered, total unsubscribes, total bounces **Performance over time**: Line chart of open rate and click rate per day, with reference lines at 20% (industry avg open rate) and 2.5% (industry avg click rate) **Per-newsletter table**: Each issue with its open rate, click rate, and delivered count. Open rates are color-coded: green above 25%, neutral 15-25%, red below 15% ## Discord The Discord analytics page shows message activity, reaction counts, and top announcements by engagement. ## Navigating between platforms The Platforms landing page shows a grid of all connected platforms. Click any platform to go to its deep dive. Platforms with no connected data source are shown but link to the connection setup page. --- # UTM Tracking Source: https://docs.reactor.tools/analytics/utm-tracking # UTM Tracking Reactor generates UTM-tagged links for every piece of content so you can see exactly which posts are driving website traffic in Google Analytics, Plausible, or Matomo. ## How UTM tagging works When you publish or schedule content, Reactor can append UTM parameters to any URLs in the content: | Parameter | Value | |---|---| | `utm_source` | Platform name (e.g., `linkedin`) | | `utm_medium` | `social` or `email` or `organic` | | `utm_campaign` | Workspace name or campaign slug | | `utm_content` | Content ID for precise attribution | The `utm_content` parameter is the key to closed-loop attribution -- it links a specific piece of content in Reactor to a session in your analytics platform. ## Generating a UTM link ### Via MCP ```json { "tool": "generate_utm_link", "arguments": { "url": "https://yoursite.com/blog/my-post", "contentId": "content_abc123", "platform": "linkedin", "campaign": "product-launch-q1" } } ``` Returns the full tagged URL. ### Automatic tagging When publishing via the UI or the `publish_now` MCP tool, UTM parameters are appended automatically to the primary URL in the content if one is present. ## Attribution in the analytics dashboard The **UTM content attribution** table on the GA4 and Plausible analytics pages shows which content IDs drove the most sessions. Sessions are matched by the `utm_content` parameter. This means you can see, for a given blog post in Reactor, how many website sessions it generated -- regardless of which platform the link was shared on. ## UTM link database All generated UTM links are stored in the `utmLinks` table. You can query them via the MCP tool or view them on the UTM section of the analytics dashboard. ## Best practices - Use the same `utm_campaign` slug for all content in a launch or campaign so you can roll up traffic by initiative - Set `utm_content` to the content ID (done automatically by Reactor) to get per-post attribution - For newsletters, use `utm_medium: email` to separate email-driven traffic from social --- # Hand setup to an AI Source: https://docs.reactor.tools/build-with-ai/ai-setup # Hand setup to an AI You don't have to set Reactor up by hand. Give an AI agent the **Reactor setup skill** and it will: 1. **Install the Reactor MCP** in your client. 2. **Connect your services** (or tell you which ones need a click in the UI). 3. **Fill your initial engine content** — voice, brand, positioning, writing rules, audiences, and competitors — by interviewing you or researching your website. ## Get the skill Download the skill and hand it to your agent: **[`/reactor-setup/SKILL.md`](https://docs.reactor.tools/reactor-setup/SKILL.md)** It is a standard [agent skill](https://modelcontextprotocol.io): a Markdown file with instructions the agent follows. Point your agent at the file (or drop it into your client's skills directory) and ask it to set up Reactor. ## Install the MCP The skill begins by installing Reactor's remote MCP server. Generate an API key first (Settings → API), then the agent runs: ```bash npx -y mcp-remote https://app.reactor.tools/api/mcp --header "Authorization: Bearer YOUR_API_KEY" ``` See [Install the MCP](./install) for per-client config and [Authentication](./authentication) for getting a key. ## What the agent does Step by step, the skill walks the agent through: 1. **Install the MCP** using the command above with your API key. 2. **Inspect the current engine** with `get_engine_config` to see what already exists. 3. **Gather context** — interview you about your product, audience, and positioning, or read your website to draft them. 4. **Write engine content** via MCP tools: `update_engine`, `update_voice`, `update_brand`, `update_positioning`, `update_writing_rules`, `add_audience`, `add_competitor`, and `set_platform_tone`. 5. **Check connections** with `get_connected_channels` and report which services still need authorizing. ## Connecting services Two kinds of connections, handled differently: | Connection type | How to connect | |---|---| | **OAuth channels** — X, LinkedIn, Discord, Webflow | Must be authorized in the UI under **Settings → Connections**. The agent cannot complete an OAuth flow for you; it will point you to the page. | | **API-key services** — email providers (ESPs), analytics | Can be added from the app; the agent can confirm them with `get_connected_channels`. | All **engine content** — voice, brand, positioning, rules, audiences, competitors, per-platform tone — can be created and edited entirely through MCP tools. Once channels are authorized, the same agent can generate, publish, and analyze. --- # Authentication Source: https://docs.reactor.tools/build-with-ai/authentication # Authentication Reactor's MCP server uses **API key** authentication. Every request carries your key as a Bearer token, and the key identifies your workspace — there is nothing else to configure. ## Generate an API key 1. Log in to Reactor and go to **Settings → API**. 2. Click **Generate New Key**. 3. Name the key for the integration that will use it (e.g. "Claude Code", "Automation"). 4. Copy the key immediately — it is shown only once. ## Use the key Pass the key as a Bearer token in the `Authorization` header. With the remote MCP, that's the `--header` flag on `mcp-remote`: ```bash npx -y mcp-remote https://app.reactor.tools/api/mcp --header "Authorization: Bearer YOUR_API_KEY" ``` In a client config block: ```json { "mcpServers": { "reactor": { "command": "npx", "args": [ "-y", "mcp-remote", "https://app.reactor.tools/api/mcp", "--header", "Authorization: Bearer YOUR_API_KEY" ] } } } ``` See [Install the MCP](./install) for full per-client setup. ## How it works Reactor stores only a SHA-256 hash of your key, never the plaintext. On each request it hashes the presented key, matches it to the stored hash, and resolves the workspace the key belongs to. All tool calls are then scoped to that workspace automatically. ## Security notes - Don't commit API keys to source control. - Use a separate key per integration so you can revoke one without disrupting the others. - Rotate keys periodically from **Settings → API**. - Keys are valid until you revoke them — there is no automatic expiry. - Deleting a key takes effect immediately; any client using it will start getting `401`s. ## Error responses | Error | Cause | |---|---| | `401 Unauthorized` | Missing, malformed, or revoked API key | | `403 Forbidden` | Key is valid but lacks access to the requested resource | | `429 Too Many Requests` | Rate limit exceeded | --- # Install the MCP Source: https://docs.reactor.tools/build-with-ai/install # Install the MCP Reactor runs a **remote** MCP server at `https://app.reactor.tools/api/mcp`. Clients reach it through [`mcp-remote`](https://www.npmjs.com/package/mcp-remote), which bridges the remote HTTP server to clients that speak local (stdio) MCP. Authentication is a Bearer token — your Reactor API key, which identifies your workspace. First, generate a key (see [Authentication](./authentication)). Then add the server **one of two ways**. ## Option 1 — One-line command Run this in any client that adds an MCP server from the command line: ```bash npx -y mcp-remote https://app.reactor.tools/api/mcp --header "Authorization: Bearer YOUR_API_KEY" ``` In **Claude Code**, register it in one step: ```bash claude mcp add reactor -- npx -y mcp-remote https://app.reactor.tools/api/mcp --header "Authorization: Bearer YOUR_API_KEY" ``` ## Option 2 — Editor config snippet For clients configured with an `mcpServers` block, add the `reactor` entry to your editor's MCP config: ```json { "mcpServers": { "reactor": { "command": "npx", "args": [ "-y", "mcp-remote", "https://app.reactor.tools/api/mcp", "--header", "Authorization: Bearer YOUR_API_KEY" ] } } } ``` - **Claude Desktop** — Settings → Developer → Edit Config (`claude_desktop_config.json`), add the entry, then restart. - **Cursor** — Settings → MCP → Add new MCP server, add the entry to `mcp.json`. Replace `YOUR_API_KEY` with the key from **Settings → API**. ## Verify Ask your client to list the Reactor tools, or call `get_engine_config`. The server is [self-describing](./mcp) — your client reads each tool's description and input schema over the protocol. --- # For LLMs Source: https://docs.reactor.tools/build-with-ai/llms # For LLMs These docs are built to be read by AI agents as well as people. Every page is available as plain Markdown, and the whole site is published in two LLM-friendly formats. ## llms.txt and llms-full.txt Following the [llms.txt standard](https://llmstxt.org), the site publishes two files at build time: | File | Contents | |---|---| | [`/llms.txt`](https://docs.reactor.tools/llms.txt) | An index of every doc page — title, link, and one-line summary. | | [`/llms-full.txt`](https://docs.reactor.tools/llms-full.txt) | Every page concatenated into a single Markdown file. | Point an agent at `/llms.txt` to let it discover pages, or feed it `/llms-full.txt` to load the entire documentation set in one shot. ## Copy page Every page has a **Copy page** button at the top right. It copies the page as clean Markdown — useful for pasting into a chat with an AI or grabbing a single guide as context. Each page is also served as raw Markdown at its route with a `.md` suffix (for example, `https://docs.reactor.tools/build-with-ai/llms.md`). ## Pointing an AI at the docs - **Quick context:** copy a single page with the **Copy page** button. - **Browse:** give the agent `https://docs.reactor.tools/llms.txt` and let it follow links. - **Full load:** give the agent `https://docs.reactor.tools/llms-full.txt` for everything at once. To go beyond reading the docs and actually operate Reactor, install the MCP — see [Build with AI](./overview). --- # MCP Overview Source: https://docs.reactor.tools/build-with-ai/mcp # MCP Overview Reactor ships a built-in [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that exposes every Reactor capability as a callable tool. Any MCP-compatible client — Claude Code, Claude Desktop, Cursor, or a custom integration — can configure the engine, generate content, publish, and read analytics without touching the UI. ## What is MCP? MCP is an open standard for connecting AI models to external tools and data. An MCP server advertises a set of tools; the model invokes them as structured function calls during a conversation. Reactor's server is reachable at `https://app.reactor.tools/api/mcp` and authenticated with a Bearer API key, which also scopes every call to your workspace. See [Install the MCP](./install) to connect a client and [Authentication](./authentication) for keys. ## The server is self-describing There is **no per-tool reference page** to maintain or memorize. When your client connects, it calls the protocol's tool-listing method and reads each tool's **name, description, and input schema** directly. Ask your agent to "list the Reactor tools" and it will show you everything available, always current with the server. This page summarizes what the tools *cover* so you know what's possible. For the exact arguments of any tool, read its schema from your client. ## What the tools cover The tools fall into a few broad categories: - **Engine config and writes** — read the full engine config, enable or configure channels, and edit every part of the brand engine: voice, brand, positioning, writing rules, per-platform tone, audiences, and competitors. Single-record sections merge the fields you provide, so partial updates never wipe existing values. - **Content generation** — create briefs, trigger generation, poll status, read and edit drafts, move content through draft → ready → published, and refine a piece through an AI chat thread. - **Publishing and calendar** — list connected channels, publish immediately, schedule for a specific time, and list, reschedule, cancel, or view the calendar of scheduled posts. - **Analytics** — pull the full dashboard, per-content performance, top content, topic clusters, posting-time recommendations, AI insights, and Search Console data; generate UTM links; and trigger or check syncs. Automation rules can act on metric thresholds. - **Categories and owners** — create categories, tag content, assign owners, and break down performance by owner and category. - **Visuals** — generate on-brand images and kick off (and poll) image-to-video renders. - **Email** — list a connected provider's lists and templates, and send or schedule campaigns. ## Context document tools Reference documents that ground generation can also be managed over MCP: upload a document into the engine context and list what's there. ## Example prompts A few things you can say to a client connected to Reactor: > "Create a LinkedIn post about our new API rate limits, generate it, and schedule it for Thursday at 2pm." > "Show me the top 5 performing posts from the last 30 days across all platforms." > "Look at what's trending in our analytics and suggest three new content ideas." > "Publish the current draft of content ID `abc123` to LinkedIn using our main company account." See [example workflows](./workflows) for multi-step recipes. ## Transport and rate limits The server uses the MCP Streamable HTTP transport, bridged to local clients with [`mcp-remote`](./install). Tool calls that hit external platforms (publishing, syncing) are also subject to those platforms' own rate limits. --- # Build with AI Source: https://docs.reactor.tools/build-with-ai/overview # Build with AI Every action in Reactor is also a [Model Context Protocol](https://modelcontextprotocol.io) (MCP) tool. That means an AI agent — Claude Code, Claude Desktop, Cursor, or anything that speaks MCP — can drive Reactor end to end with no UI: - **Configure the engine** — set brand voice, positioning, writing rules, audiences, competitors, and per-platform tone. - **Generate content** — create briefs and produce platform-native drafts for X, LinkedIn, blog, newsletter, Discord, and more. - **Publish and schedule** — post now or queue to the calendar; reschedule and cancel. - **Analyze** — read cross-platform analytics, top content, insights, and posting recommendations, then feed them back into the next brief. ## Two ways to start ### 1. Hand setup to an agent Give an AI agent the **Reactor setup skill** and it will install the MCP, help you connect your services, and draft your initial engine content from an interview or your website. → [Hand setup to an AI](./ai-setup) ### 2. Call the MCP directly Install the Reactor MCP in your client and start issuing tool calls yourself. - [Install the MCP](./install) — add Reactor to Claude Code, Claude Desktop, or Cursor. - [Authentication](./authentication) — generate an API key and pass it as a Bearer token. - [MCP overview](./mcp) — how the server is structured and what the tools cover. ## The server is self-describing There is no per-tool reference to memorize. Reactor's MCP server advertises its tools over the protocol — your client reads each tool's name, description, and input schema at connect time. See [MCP overview](./mcp) for the tool categories and [example workflows](./workflows) for end-to-end recipes. --- # Example Workflows Source: https://docs.reactor.tools/build-with-ai/workflows # Example Workflows These end-to-end workflows show how to combine MCP tools to accomplish common content tasks. Tool names are real; for each tool's exact arguments, read its schema from your client — the [server is self-describing](./mcp). ## 1. Generate and publish a LinkedIn post The most common workflow: brief, generate, review, publish. ``` 1. get_engine_config // Confirm LinkedIn is enabled 2. create_brief // Set topic, angle, key points 3. generate_content // Start generation with briefId 4. get_generation_status // Poll until status: "done" 5. get_content // Read the draft 6. send_chat_message // (Optional) Refine the draft 7. get_connected_channels // Get LinkedIn connection ID 8. publish_now // Post immediately ``` **Full example prompt to an AI client connected to Reactor:** > "Write a LinkedIn post about why developer tools with opinionated defaults win over flexible frameworks. Use a counterintuitive angle. Keep it under 1300 characters. Publish it to our LinkedIn account." ## 2. Schedule a week of content Build a full week of posts across platforms and schedule them at optimal times. ``` 1. get_engine_config // Check which channels are active 2. get_posting_recommendations // Get best times per platform 3. get_analytics_overview // See what's already scheduled this week 4. get_calendar // Check for gaps in schedule 5. create_brief (x3-5) // Create briefs for each platform 6. generate_content (each) // Generate all drafts 7. get_generation_status (each) // Wait for each to complete 8. schedule_content (each) // Schedule at recommended times 9. get_calendar // Verify week is populated ``` ## 3. Analyze and replicate top performers Use analytics to understand what works and create more of it. ``` 1. get_analytics_overview // See overall performance period 2. get_top_content // Identify top performers 3. get_topic_clusters // Understand which topics win 4. suggest_brief_from_analytics // Generate a data-driven brief 5. create_brief // Create the brief from the suggestion 6. generate_content // Generate 7. get_generation_status // Wait 8. get_posting_recommendations // Get best time to post 9. schedule_content // Schedule at optimal time ``` ## 4. Find and act on keyword opportunities Use GSC data to identify content gaps and generate posts to close them. ``` 1. get_search_analytics // Get keyword opportunities 2. create_brief // Brief on the top opportunity keyword // topic: "Guide to [keyword]" // angle: "Optimize for [query] intent" 3. generate_content // Generate blog post draft 4. get_generation_status // Wait 5. publish_now // Post to blog (Webflow/Ghost) 6. generate_utm_link // Tag the blog URL for tracking ``` ## 5. Set up automated content cadence Configure automation so Reactor keeps publishing even when you are not actively creating. ``` 1. list_automation_rules // Check what exists 2. create_automation_rule // Add posting gap rule per platform // trigger: posting_gap (3 days) on linkedin // action: create_brief (auto-topic) 3. create_automation_rule // Add top performer follow-up rule // trigger: engagement_threshold (5%) on x // action: create_brief (expand on insight) 4. list_automation_rules // Confirm rules are active ``` Once these rules are in place, Reactor will automatically create new briefs when your publishing cadence lapses or when a post significantly outperforms expectations. ## 6. Upload context and refresh generation When you update your product or messaging, refresh the reference documents so future content reflects the change. ``` 1. list_documents // See what's currently uploaded 2. upload_document // Upload new product spec or messaging doc // type: "product_context" 3. create_brief // Brief on a feature announcement 4. generate_content // Generate -- will incorporate new doc 5. get_generation_status 6. get_content // Review the draft 7. schedule_content // Schedule for launch day ``` --- # Content Briefs Source: https://docs.reactor.tools/content/briefs # Content Briefs A brief is the planning document that tells the AI what to write. Every piece of content starts with a brief. ## Why briefs matter Without a brief, AI-generated content is generic. With a well-formed brief, the output is specific, on-brand, and targeted to the right audience and platform. A brief answers: What is this about? Who is it for? What platform? What angle? What should the reader do next? ## Brief fields | Field | Required | Description | |---|---|---| | `topic` | Yes | The main subject of the content | | `platform` | Yes | Where this will be published | | `audience` | No | Which audience segment to target | | `angle` | No | The specific take or frame for the topic | | `tone` | No | Tone override (default: from engine config) | | `targetLength` | No | Approximate word or character count | | `keyPoints` | No | Bullet list of points to include | | `callToAction` | No | What to ask the reader to do | | `references` | No | Links, quotes, or data to incorporate | | `context` | No | Any additional notes for the AI | ## Creating a brief in the UI 1. Go to **Content** and click **New** 2. Select the platform 3. Fill in the topic and any additional fields 4. Click **Create Brief** The brief enters a `pending` state and is available for generation. ## Creating briefs via MCP ```json { "tool": "create_brief", "arguments": { "topic": "Why context windows don't solve memory in AI agents", "platform": "linkedin", "audience": "Developer advocates", "angle": "Counterintuitive take: bigger context != better memory", "keyPoints": [ "Context windows are volatile, not persistent", "Real memory requires retrieval, not recency", "Agents that chunk into context fail at scale" ], "callToAction": "Ask what retrieval strategy they're using" } } ``` The `create_brief` tool's full schema is advertised by the MCP server and read directly by your client. See the [MCP overview](/build-with-ai/mcp) for how this works. ## Generating from analytics The `suggest_brief_from_analytics` MCP tool analyzes your top-performing content and suggests a new brief that follows the same patterns. This is useful for scaling what's already working. ## Brief status | Status | Meaning | |---|---| | `pending` | Brief created, ready to generate | | `generating` | AI is currently writing content from this brief | | `done` | Content has been generated | | `failed` | Generation failed -- brief can be retried | --- # Content Editor Source: https://docs.reactor.tools/content/editor # Content Editor The content editor is where you review, refine, and publish generated content. ## Editor layout The editor is split into two panels: - **Left panel**: The draft content, fully editable as plain text - **Right panel**: Chat interface for AI-assisted refinement Above the editor is the action bar with publish and schedule controls. ## Editing content Click anywhere in the left panel to edit. The editor is a plain text area -- formatting is applied when the content is published to its target platform. What you see is the raw content string. For blog posts, markdown is rendered on the preview tab. ## Chat refinement The right panel is a conversation with the AI anchored to the current draft. Type any instruction and the AI applies it to the live draft. Examples: - "Rewrite the intro to lead with the problem, not the solution" - "Add three bullet points summarizing key takeaways" - "Remove all adjectives from the first paragraph" - "Make this suitable for a technical audience" - "Write a version that's 50% shorter" Changes are applied immediately. There is no undo -- copy the draft to a separate document if you want to preserve a version. ## Publishing from the editor ### Publish now Click **Publish** in the action bar to open the publish panel. Select your connected channel and click **Post**. The content is sent to the platform immediately and the status is updated to `published`. Supported platforms for direct posting: - X (Twitter) - LinkedIn - Discord - Webflow (blog posts) - Ghost (blog posts) ### Schedule Click **Schedule** to open the scheduling panel. Select a connection, pick a date, pick a time, and click **Add to Calendar**. The post appears on the calendar and publishes automatically at the scheduled time. ## Content status The status badge in the top-right of the editor shows the current state: | Status | Description | |---|---| | `generating` | AI is still writing | | `draft` | Generated but not yet reviewed | | `ready` | Marked as approved | | `published` | Successfully posted to a platform | You can manually move status with the **Mark Ready** button or the `set_content_status` MCP tool. ## Keyboard shortcuts | Shortcut | Action | |---|---| | `Cmd+S` | Save (auto-saved on blur) | | `Cmd+Enter` | Send chat message | --- # Content Generation Source: https://docs.reactor.tools/content/generation # Content Generation Once a brief exists, Reactor generates full content from it using a multi-step AI pipeline. ## How generation works 1. The brief, engine config, and relevant reference documents are combined into a structured prompt 2. The AI generates a draft tailored to the platform's format and character limits 3. The draft is stored as a `draft` in the content database 4. You can review, edit, and refine before publishing ## Triggering generation ### From the UI Open a brief and click **Generate**. The status indicator shows the progress in real time. Generation typically takes 5-15 seconds. ### From MCP ```json { "tool": "generate_content", "arguments": { "briefId": "brief_abc123" } } ``` The tool returns a `generationId`. Poll for completion with `get_generation_status`: ```json { "tool": "get_generation_status", "arguments": { "generationId": "gen_xyz789" } } ``` When `status` is `"done"`, the `contentId` field is populated and you can fetch the content with `get_content`. ## Platform-specific formatting Reactor formats content differently per channel: | Platform | Format behavior | |---|---| | X | Enforces 280 character limit, adds relevant hashtags | | LinkedIn | Professional register, includes line breaks for readability, 1300 char recommendation | | Blog | Full article with H2/H3 structure, intro, body, conclusion | | Newsletter | Email-friendly structure with subject line suggestion | | Discord | Conversational tone, shorter form, markdown-safe | | Instagram | Caption with hashtag block, emoji-friendly | | Reddit | Text post format appropriate for the community context | ## Iterative refinement via chat After generation, you can continue refining through chat in the content editor. The AI maintains context of the current draft and applies your edits as instructions: - "Make the opening line more punchy" - "Add a concrete example in the second paragraph" - "Shorten this by 30%" - "Change the CTA to focus on booking a demo instead" Each chat message is applied to the draft in place. Previous versions are not saved unless you copy them manually. ## Generation status states | Status | Meaning | |---|---| | `generating` | AI pipeline is running | | `draft` | Generation complete, awaiting review | | `ready` | Reviewed and approved, ready to publish | | `published` | Content has been published to a platform | --- # Engine Configuration Source: https://docs.reactor.tools/getting-started/engine-config # Engine Configuration Engine config is the core persona and strategy file that powers all AI generation. Every brief and every content generation prompt draws from this configuration. ## What is in engine config? Engine config stores: - **Workspace name** -- Used in MCP responses and UI labels - **Product description** -- Grounding context injected into all generation prompts - **Brand voice** -- Tone, style, and language preferences - **Channels** -- Which platforms you distribute content on - **Audiences** -- Segments you write for, with platform affinities - **Content pillars** -- Recurring topic themes (optional) - **Competitor context** -- Positioning notes (optional) ## Editing engine config Go to **Settings > Engine Config** or call the `get_engine_config` and `update_channel` MCP tools. All fields are optional but more detail produces better content. A strong product description and clear audience definitions are the highest-leverage inputs. ## Channels Each channel in your config has settings specific to that platform: | Channel | Key settings | |---|---| | X | Max character count, preferred hashtag strategy | | LinkedIn | Article vs. post preference, target connection type | | Blog | Default content length, internal link strategy | | Newsletter | Issue format (long-form vs. digest), send cadence | | Discord | Server and channel target, tone (casual vs. formal) | | YouTube | Script vs. outline, description format | | Instagram | Caption style, hashtag density | | Reddit | Subreddit targets, link post vs. text post | ## Audiences You can define up to four audience segments. Each segment includes a name, a description of what they care about, and which platforms they prefer. The AI uses audience data to adjust framing, vocabulary, and calls to action. Example audiences: - **Primary**: Founders building B2B SaaS products -- care about growth, churn, positioning - **Secondary**: Heads of marketing at Series A companies -- care about attribution, pipeline - **Niche**: Developer advocates -- care about technical depth, code examples, credibility ## Reference documents Upload documents that give the AI additional context. Good candidates: - Product spec or feature list - Past high-performing blog posts - Brand voice and style guide - Messaging framework or positioning deck - Customer research or FAQ Documents are retrieved via semantic search during generation. The AI references the most relevant sections based on the brief topic. ## Updating config via MCP ```json { "tool": "update_channel", "arguments": { "platform": "linkedin", "enabled": true, "voiceNotes": "Professional but direct. No buzzwords. Lead with the insight." } } ``` The `update_channel` tool's exact arguments are described by its input schema, which your MCP client reads directly. See the [MCP overview](/build-with-ai/mcp) for how the self-describing server works. --- # Onboarding and Configuration Source: https://docs.reactor.tools/getting-started/onboarding # Onboarding and Configuration When you first log in, Reactor walks you through a workspace setup flow. This page explains each step and all available configuration options. ## Workspace setup ### Step 1: Workspace name Give your workspace a short name. This is used in the UI and in MCP tool responses. ### Step 2: Product description Write a concise description of what your product or company does. This is injected into every content generation prompt as grounding context. Be specific -- include what you make, who uses it, and what problem you solve. ### Step 3: Target audiences Define up to four audience segments (primary, secondary, tertiary, niche). Each audience has: - **Name** -- e.g. "Startup founders" - **Description** -- pain points, goals, what they care about - **Platforms** -- where this audience spends time Audience data shapes how the AI frames content for each channel. ### Step 4: Channel selection Check the channels you plan to publish on. Available channels: - X (Twitter) - LinkedIn - Blog (via Webflow or Ghost) - Newsletter (via Beehiiv or ConvertKit) - Discord - YouTube - Instagram - Reddit You can change this later in engine config. ### Step 5: Reference documents (optional) Upload any documents you want the AI to reference when generating content: product specs, past blog posts, brand voice guidelines, messaging frameworks, FAQ documents. Supported types: PDF, DOCX, TXT, Markdown. ## Environment variables ### Required | Variable | Description | |---|---| | `DATABASE_URL` | PostgreSQL connection string | | `NEXTAUTH_SECRET` | 32+ character random string | | `NEXTAUTH_URL` | Full base URL including protocol | | `OPENAI_API_KEY` | OpenAI API key for generation | ### Publishing integrations | Variable | Description | |---|---| | `TWITTER_CLIENT_ID` | X (Twitter) OAuth 2.0 client ID | | `TWITTER_CLIENT_SECRET` | X (Twitter) OAuth 2.0 client secret | | `LINKEDIN_CLIENT_ID` | LinkedIn OAuth 2.0 client ID | | `LINKEDIN_CLIENT_SECRET` | LinkedIn OAuth 2.0 client secret | | `DISCORD_BOT_TOKEN` | Discord bot token | | `WEBFLOW_CLIENT_ID` | Webflow OAuth client ID | | `WEBFLOW_CLIENT_SECRET` | Webflow OAuth client secret | ### Analytics integrations | Variable | Description | |---|---| | `GOOGLE_SERVICE_ACCOUNT_EMAIL` | Google service account for GA4 and GSC | | `GOOGLE_SERVICE_ACCOUNT_KEY` | Base64-encoded private key | ### Cron security | Variable | Description | |---|---| | `CRON_SECRET` | Bearer token used to protect cron endpoints | Set this in Vercel's environment variables and in your `vercel.json` cron configuration. ### MCP | Variable | Description | |---|---| | `MCP_API_KEY_HASH` | SHA-256 hash of your MCP API key | See [Authentication](/build-with-ai/authentication) for how to generate an API key. ## After onboarding Once setup is complete you land on the Reactor dashboard. From here: - Go to **Settings > Connections** to authenticate publishing channels - Go to **Settings > Data Sources** to connect analytics platforms - Go to **Settings > API Keys** to generate an MCP API key --- # Quickstart Source: https://docs.reactor.tools/getting-started/quickstart import { Cards, Card } from '@site/src/components/Cards'; # Quickstart There are two ways to get started with Reactor. Pick whichever fits how you work. ## Option 1 — Start in the app The fastest way in, no setup beyond signing up. 1. **Sign up** at [reactor.tools](https://reactor.tools) and start your free trial. 2. **Onboard** — name your company, name your engine, and optionally add your website so Reactor can tailor your prompts. 3. **Configure your engine** — add your voice, audiences, and positioning. Write them yourself, or click ✨ to have AI draft them from your site. 4. **Generate** — give a topic, pick channels, and Reactor writes a native draft for each one. 5. **Publish or schedule** — post now, or drop it on the calendar. → Continue with [Onboarding](./onboarding), then [Configure your engine](./engine-config). ## Option 2 — Hand it to an AI agent Prefer to drive Reactor with AI? Connect the Reactor **MCP server** to your agent (Claude Code, Claude Desktop, Cursor, and others) and hand it the setup skill. The agent installs the server, helps you connect your services, and fills in your engine for you. Add the MCP to your client: ```bash npx -y mcp-remote https://app.reactor.tools/api/mcp --header "Authorization: Bearer YOUR_API_KEY" ``` Then point your agent at the [setup skill](/build-with-ai/ai-setup) and ask it to get you started. → See [Build with AI](/build-with-ai/overview) and [Hand setup to an AI](/build-with-ai/ai-setup). ## Using these docs - **Getting Started** — onboarding and engine configuration. - **Learn** — feature guides for content, publishing, analytics, and settings. - **Build with AI** — the MCP server, installing it, and the agent setup skill. Every page has a **Copy page** button (top right) to grab it as Markdown for an LLM, and the whole site is published as [`llms.txt`](https://docs.reactor.tools/llms.txt) and [`llms-full.txt`](https://docs.reactor.tools/llms-full.txt). ## Popular tasks Turn a topic into platform-native drafts for every channel. Configure the voice, audiences, positioning, and rules behind every generation. Schedule posts and see everything queued in one weekly view. Track performance across channels with UTM attribution and insights. --- # Introduction Source: https://docs.reactor.tools/intro # Reactor **The content engine for AI-native teams.** Configure your brand voice, audience, positioning, and rules once. Then generate platform-native content for every channel, publish or schedule it, and measure what works — driven from the app or from any MCP client. ## Start here - **[Quickstart](/getting-started/quickstart)** — go from sign-up to your first published post in a few minutes. - **[Configure your engine](/getting-started/engine-config)** — the voice, audiences, landscape, and rules every generation draws from. - **[Build with AI](/build-with-ai/overview)** — hand setup to an AI agent and drive Reactor headlessly over MCP. ## What Reactor does - **One engine, every channel.** A single source of truth for voice, audiences, positioning, writing rules, and per-platform tone. Each piece is written *for* its platform — X, LinkedIn, blog, newsletter, Discord — not reformatted from one draft. - **Publish and schedule.** Post now or queue to a calendar; a scheduler ships due posts automatically. - **Measure and learn.** Per-platform analytics, UTM attribution, insights, and automation rules that feed the next brief. - **AI-native.** Every action in the app is also an MCP tool, so an agent can configure the engine, generate, publish, and read analytics with no UI. ## Three ways to learn | Pillar | What's inside | |---|---| | **[Getting Started](/getting-started/quickstart)** | Sign up, onboard, configure the engine. | | **[Learn](/content/briefs)** | Feature guides: content, publishing, analytics, settings. | | **[Build with AI](/build-with-ai/overview)** | MCP, authentication, installing the server, and handing setup to an agent. | :::tip For LLMs Every page has a **Copy page** button (top right) to grab it as Markdown. The whole site is also available as [`llms.txt`](https://docs.reactor.tools/llms.txt) and [`llms-full.txt`](https://docs.reactor.tools/llms-full.txt). ::: --- # Calendar Source: https://docs.reactor.tools/publishing/calendar # Calendar The calendar shows all scheduled and published posts across every channel in a weekly grid view. ## Calendar view The calendar is organized by day of week. Each post card shows: - The platform (color-coded tag) - Post status (scheduled, published, failed) - A preview of the content - A link to the source content item ## Interacting with posts **Hover over a scheduled post** to reveal a **Post Now** button. Clicking it publishes the post immediately without waiting for the scheduled time. **Click the content link** on any post card to open the full content editor. ## Calendar navigation Use the date navigation arrows to move forward and backward by week. The current week is shown by default. ## Post statuses on the calendar | Status | Color | Description | |---|---|---| | `scheduled` | Default | Set to go out at a future time | | `publishing` | Pulsing | Currently being processed | | `published` | Muted | Already sent | | `failed` | Red | Publishing failed -- click to retry | | `canceled` | Strikethrough | Manually canceled | ## Cron publishing Reactor publishes due posts automatically every 5 minutes via a Vercel Cron job at `GET /api/calendar/publish-due`. This endpoint: 1. Finds all posts where `scheduledAt <= now` and `status = 'scheduled'` 2. Atomically sets each post to `status = 'publishing'` 3. Calls the platform API 4. Sets status to `published` or `failed` The cron endpoint is protected by a `CRON_SECRET` Bearer token. ## Reading the calendar via MCP ```json { "tool": "get_calendar", "arguments": { "startDate": "2025-01-13", "endDate": "2025-01-19" } } ``` Returns all scheduled and published posts in the date range, grouped by day. --- # Platform Connections Source: https://docs.reactor.tools/publishing/connections # Platform Connections Connections are the authenticated integrations Reactor uses to post content on your behalf. Each channel you publish on requires a connection. ## Supported platforms | Platform | Auth method | What it posts | |---|---|---| | X (Twitter) | OAuth 2.0 | Tweets | | LinkedIn | OAuth 2.0 | Posts and articles | | Discord | Bot token | Messages to a channel | | Webflow | OAuth 2.0 | CMS items (blog posts) | | Ghost | Admin API key | Posts | ## Setting up a connection Go to **Settings > Connections** and click **Connect** next to the platform you want to add. ### X (Twitter) 1. Click **Connect X** 2. You are redirected to Twitter's OAuth flow 3. Authorize Reactor to post on your behalf 4. You are redirected back and the connection is shown as active Required environment variables: `TWITTER_CLIENT_ID`, `TWITTER_CLIENT_SECRET` ### LinkedIn 1. Click **Connect LinkedIn** 2. Authorize via LinkedIn OAuth 3. Reactor stores your access token and profile ID Required environment variables: `LINKEDIN_CLIENT_ID`, `LINKEDIN_CLIENT_SECRET` ### Discord 1. Paste your bot token 2. Enter the channel ID you want to post to 3. Click **Save** Your bot must have `Send Messages` permission in the target channel. Required environment variable: `DISCORD_BOT_TOKEN` ### Webflow 1. Click **Connect Webflow** 2. Authorize via Webflow OAuth 3. Select the site and CMS collection to publish to Required environment variables: `WEBFLOW_CLIENT_ID`, `WEBFLOW_CLIENT_SECRET` ### Ghost 1. Enter your Ghost instance URL 2. Enter your Admin API key (format: `id:secret`) 3. Click **Save** Ghost API keys are created in Ghost Admin under **Settings > Integrations**. ## Token refresh OAuth tokens for X and LinkedIn expire. Reactor automatically refreshes them using stored refresh tokens. If a connection shows `expired`, reconnect via **Settings > Connections**. ## Multiple connections You can have multiple connections for the same platform (e.g., two different LinkedIn accounts). When publishing or scheduling, you select which connection to use. ## Connection status | Status | Meaning | |---|---| | Connected | Token is valid and ready | | Expired | Token expired, needs reconnection | | Error | Last API call failed | --- # Publish Now Source: https://docs.reactor.tools/publishing/publish-now # Publish Now Publish Now sends a piece of content to a connected platform immediately. No scheduling, no queue -- it posts and returns confirmation. ## From the UI 1. Open the content in the editor 2. Click **Publish** in the action bar 3. Select the connection (platform and account) 4. Click **Post** The status indicator shows the post going out. On success, the content status changes to `published` and the post record is created in the database. ## From MCP ```json { "tool": "publish_now", "arguments": { "contentId": "content_abc123", "platform": "linkedin", "connectionId": "conn_xyz789" } } ``` The tool returns the published post ID and the external platform post ID. ## What happens on publish 1. Reactor fetches the content text 2. Reactor looks up the connection credentials for the platform 3. The content is sent to the platform API 4. A `scheduledPosts` record is created with `status: 'published'` 5. The content status is updated to `published` 6. Any UTM tracking parameters are appended if configured ## Platform behavior on publish **X**: Posts as a tweet. Long-form content is truncated to 280 characters. Reactor recommends writing X content to the character limit in the brief. **LinkedIn**: Posts as a LinkedIn post. Supports longer text. Line breaks are preserved. **Discord**: Posts as a message to the configured channel. **Webflow**: Creates a draft CMS item and optionally publishes it. Requires a collection to be configured in the connection. **Ghost**: Creates a published post. Title is taken from the content heading if present, otherwise generated from the first line. ## Error handling If the platform API returns an error, Reactor records the failure in the `scheduledPosts` table with `status: 'failed'` and a reason field. You can retry from the content editor. Common errors: - **401 Unauthorized** -- Token expired, reconnect in Settings > Connections - **403 Forbidden** -- Account lacks permission (e.g., LinkedIn page posting requires page admin) - **429 Too Many Requests** -- Rate limited, try again in a few minutes --- # Scheduling Posts Source: https://docs.reactor.tools/publishing/scheduling # Scheduling Posts Scheduling queues content for future publishing at a specific date and time. ## Schedule from the editor 1. Open the content item you want to schedule 2. Click **Schedule** in the action bar 3. Select your connection (platform + account) 4. Pick a date and time 5. Click **Add to Calendar** The post is added to the calendar with `status: 'scheduled'` and will publish automatically at the specified time. ## Schedule via MCP ```json { "tool": "schedule_content", "arguments": { "contentId": "content_abc123", "platform": "x", "connectionId": "conn_xyz789", "scheduledAt": "2025-01-16T14:30:00Z" } } ``` All times are in UTC. The MCP tool accepts ISO 8601 datetime strings. ## Rescheduling To change the time for a scheduled post: **From the calendar**: Click the post, then use the reschedule option. **Via MCP**: ```json { "tool": "reschedule_post", "arguments": { "postId": "post_abc123", "scheduledAt": "2025-01-17T09:00:00Z" } } ``` ## Canceling a scheduled post **Via MCP**: ```json { "tool": "cancel_scheduled", "arguments": { "postId": "post_abc123" } } ``` The post status becomes `canceled` and it will not publish. ## Viewing scheduled posts **Via MCP**: ```json { "tool": "list_scheduled", "arguments": { "platform": "linkedin", "limit": 20 } } ``` All `platform` and `limit` arguments are optional. Without filters, all upcoming scheduled posts are returned. ## Best times to post The `get_posting_recommendations` MCP tool analyzes your historical engagement data and returns optimal posting times per platform. This is based on actual performance data from your past posts, not generic industry benchmarks. ```json { "tool": "get_posting_recommendations", "arguments": {} } ``` Returns a ranked list of day/hour combinations per platform, sorted by average engagement rate. ## How cron publishing works Reactor checks for due posts every 5 minutes. There is no real-time websocket trigger -- the maximum delay between a post's scheduled time and its actual publish time is 5 minutes. This is acceptable for scheduled social media content but not suitable for time-critical use cases like live event announcements where seconds matter. --- # API Keys Source: https://docs.reactor.tools/settings/api-keys # API Keys Reactor uses API keys to authenticate requests to the MCP server. Each key is scoped to a workspace. ## Generating an API key 1. Go to **Settings > API Keys** 2. Click **Generate New Key** 3. Give the key a name (e.g., "Claude Desktop", "n8n automation") 4. Click **Create** 5. Copy the key immediately -- it is only shown once ## How the key is stored Reactor stores only a SHA-256 hash of the key, never the plaintext. If you lose a key, generate a new one and delete the old entry. ## Using the key Pass the API key as a Bearer token in the `Authorization` header when connecting to the MCP endpoint: ``` Authorization: Bearer eng_your_key_here ``` The key is passed through `mcp-remote` when connecting a client: ```json { "mcpServers": { "reactor": { "command": "npx", "args": [ "-y", "mcp-remote", "https://app.reactor.tools/api/mcp", "--header", "Authorization: Bearer YOUR_API_KEY" ] } } } ``` See [Authentication](/build-with-ai/authentication) for full setup instructions. ## Revoking a key Click **Delete** next to any key on the API Keys page to revoke it immediately. Any MCP client using that key will receive a 401 error until it is reconfigured with a new key. ## Key naming Use descriptive names so you can track which keys are used by which integrations. If a key is compromised, you can identify and revoke it without disrupting other integrations. --- # Billing Source: https://docs.reactor.tools/settings/billing # Billing Reactor uses Stripe for subscription management. ## Plans | Plan | Description | |---|---| | `trial` | Full access for 14 days, no credit card required | | `pro` | Paid plan with full feature access | | `canceled` | Subscription canceled, read-only access until the period ends | ## Managing your subscription Go to **Settings > Billing** to: - View your current plan and renewal date - Upgrade from trial to pro - Update payment method - Cancel subscription - Download past invoices ## Trial period New workspaces start on a 14-day trial with full access to all features. No credit card is required to start the trial. At the end of the trial, you must upgrade to continue publishing and accessing analytics. ## Cancellation When you cancel, your subscription remains active until the end of the current billing period. After that, the workspace enters a read-only state. Your data is retained for 30 days before permanent deletion. ## Billing portal Clicking **Manage Subscription** opens the Stripe billing portal where you can handle payment details and invoices directly. ## Environment setup for billing Billing requires the following environment variables: | Variable | Description | |---|---| | `STRIPE_SECRET_KEY` | Stripe secret key (`sk_live_` or `sk_test_`) | | `STRIPE_WEBHOOK_SECRET` | Webhook signing secret from Stripe dashboard | | `STRIPE_PRICE_ID_HOBBY` | Stripe price ID for the Hobby plan ($19/mo) | | `STRIPE_PRICE_ID_PRO` | Stripe price ID for the Pro plan ($99/mo) | The Stripe webhook endpoint is at `/api/stripe/webhook`. --- # Team and Workspace Source: https://docs.reactor.tools/settings/team # Team and Workspace Reactor supports multi-member workspaces. All content, connections, and analytics are shared within a workspace. ## Roles | Role | Permissions | |---|---| | `owner` | Full access, billing, can delete workspace | | `admin` | Full access except billing and workspace deletion | | `editor` | Can create and publish content, cannot change settings | | `viewer` | Read-only access to content and analytics | ## Inviting team members 1. Go to **Settings > Team** 2. Enter the email address of the person you are inviting 3. Select their role 4. Click **Send Invite** The invitee receives an email with an accept link. Once accepted, they have access to the workspace. ## Changing roles Owners and admins can change the role of any member below their own role level. Owners cannot be demoted by admins. ## Removing members Click **Remove** next to any team member to revoke their access immediately. Their sessions are invalidated. ## Workspace settings From **Settings > Team** you can also update: - Workspace name - Workspace timezone (used for calendar display and posting time recommendations) ## Single workspace The current version of Reactor supports one workspace per account. Multi-workspace support (for agencies managing multiple brands) is planned for a future release.