Once a page is live, Distribution is how you push it out: browser notifications to your subscribers, and scheduled posts to your social networks. Both live under Distribution in the admin (and the /api/distribution/* API + distribution_* MCP tools).
| Channel | What it does | Who delivers |
|---|---|---|
| Web push | Browser notifications to visitors who opted in on your site | StaticOwl (built in) |
| Scheduled social | Posts scheduled ahead of time, fired to Facebook / LinkedIn / X / Instagram / … | Your Zapier / Make / n8n workflow |
Compiling a page into a social caption or an email is a separate, earlier step — the Channels tab in the content editor (POST /api/content/:type/:id/_compile). This doc is about sending: notifications and scheduled posts.
Scheduled social posting
Schedule a post for a future time; StaticOwl fires it automatically when the time arrives. Posts go out through a fan-out webhook you connect once — a Zapier, Make, or n8n "Catch Hook" URL. Each due post is POSTed there as JSON; your workflow posts it to the actual networks. One webhook covers every network.
Why we don't post to Facebook / LinkedIn / X directly
Direct posting means owning an approved app on each platform: X's API is paid, and LinkedIn and Meta both gate posting behind app review that can take weeks and must be renewed. That's per-platform infrastructure and ongoing compliance work for one feature — and it locks you into whatever those APIs allow that month.
Instead we hand the post to your automation tool, which already has approved connections to every network you use. Same rationale as the email channel: we produce the payload, your provider does the delivery. You keep control of the accounts, the credentials never touch us, and you can route the same post to ten networks by editing your workflow — no StaticOwl change needed.
Connect your webhook (once)
- In Zapier / Make / n8n, create a workflow that starts with a webhook trigger ("Catch Hook" in Zapier, "Custom webhook" in Make, "Webhook" node in n8n). Copy the URL it gives you.
- In StaticOwl: Distribution → Connect social, paste the URL, Connect. It must be
https://. - Add steps to your workflow that post to your networks (Zapier's "Facebook Pages", "LinkedIn", "X" actions, etc.), mapping the fields below.
That's it. From then on every scheduled post is delivered to your workflow.
What we send to your webhook
Each fired post is a single JSON POST:
{
"network": "linkedin",
"message": "Our Q3 report is live — https://yoursite.com/blog/q3/",
"url": "https://yoursite.com/blog/q3/",
"contentId": "post:q3-report",
"scheduledAt": "2026-09-10T14:00:00Z",
"firedAt": "2026-09-10T14:00:07Z"
}
networkis the label you chose when scheduling — it's how your workflow decides where to route the post (a Zapier Path, a Make router). With a fan-out webhook StaticOwl doesn't talk to the network itself, sonetworkis a routing hint, not a hard constraint.messageis your post text (include any link inline).urlis the canonical page URL if you attached one.contentIdlinks the post back to a content item.scheduledAtis when it was meant to fire;firedAtis when it actually did.
Your workflow should return a 2xx. A non-2xx (or a timeout — we wait 15s) is treated as a failure and retried up to 5 times across later dispatch ticks; after that the post is marked failed with the last error.
Schedule a post
Distribution → Schedule a post: pick a network label, write the message, set the date/time, Schedule. It sits pending until its time comes, then fires on the next dispatch tick (within ~a minute). The schedule table shows pending / sent / failed / cancelled, attempt count, and any last error. Cancel a pending post anytime; sent posts can't be cancelled.
If no webhook is connected, posts still schedule — they just stay pending and don't fire until you connect one. Run dispatch now flushes everything due immediately instead of waiting for the tick.
Via MCP / API
- MCP:
distribution_connect_webhook(connect/update, empty URL disconnects),distribution_webhook_get,distribution_schedule,distribution_schedules_list,distribution_schedule_delete,distribution_dispatch,distribution_networks. In theengagementtoolset — add?toolsets=engagement(orall) to your MCP URL to surface them. - API: the
/api/distribution/*routes —PUT /webhook,POST /schedules,POST /dispatch,GET /networks(all site-scoped, write role required).
Web push notifications
Browser notifications to visitors who opted in — no app, no third party.
- Distribution → Add to my site mints an embed snippet (a
<script>+ a subscribe button). Paste it near</body>on your site. The button must callstaticowlPush.subscribe()on click — browsers only allow the permission prompt from a user gesture. - Once you have subscribers, send a broadcast (title + body + optional URL) to everyone. The broadcasts table shows delivered / attempted per send.
Dead subscriptions (browsers that unsubscribed or expired) are pruned automatically. Delivery needs a push provider configured on the server; without one, broadcasts are logged but not sent (attempted = 0).
What's NOT in scope
- We don't hold your social credentials. The fan-out webhook means your Zapier/Make/n8n account owns every network connection.
- No direct-to-network posting without a webhook — see the rationale above. If you want it for a specific network, that's a roadmap item gated on that platform's app approval.
- Social images (rendering a post graphic) need a raster engine — deliberately not bundled; the compiled
social_postchannel gives you the caption, you supply the image in your workflow.