terminal://docs.overview
[ DOCUMENTATION ]

Overview

Write a markdown file. Drop it in a folder. Blurt publishes it to 6 platforms and writes the permalinks back into your file. That's it.

How it works

queue/my-post.md  -->  worker polls every 60s  -->  sent/my-post.md (with permalinks)
                                                -->  failed/my-post.md (with errors)
  • Write a markdown file with YAML frontmatter specifying target platforms
  • Drop it into queue/
  • The worker picks it up, publishes to each platform in parallel
  • The file moves to sent/ with platform permalinks written back into the frontmatter
  • If anything fails, the file moves to failed/ with error details and any successful URLs

You can also use the CLI or the HTTP API to create, manage, and publish posts programmatically.

Post format

Social post

---
platforms:
  - bluesky
  - mastodon
  - linkedin
scheduledAt: 2026-03-24T09:00:00Z  # optional
---

Your post content here. Supports **markdown**.

Blog post

Blog platforms (Medium, Dev.to, Substack) require a title field. You can target both social and blog platforms in the same post.

---
title: "Why Posterous Was Ahead of Its Time"
platforms:
  - medium
  - devto
  - substack
  - bluesky
---

Long-form **markdown** content here...

Post with images

Place the markdown file and images together in a subdirectory of queue/:

queue/
  my-post/
    post.md
    photo.jpg
    banner.png
---
platforms:
  - bluesky
  - linkedin
images:
  - path: photo.jpg
    alt: "A sunset over the mountains"
  - path: banner.png
---

Post content here.

Frontmatter reference

Field Required Description
platforms Yes One or more of bluesky, mastodon, linkedin, medium, devto, substack
title For blog platforms Post title for Medium, Dev.to, and Substack
scheduledAt No ISO 8601 timestamp. Post waits in queue until this time
images No Array of {path, alt}. Max 4 images. Formats: jpg, png, gif, webp

Supported platforms

Platform Type Format Features
Bluesky Social Plaintext Rich text facets (links, mentions, hashtags), link previews, images
Mastodon Social Plaintext Bare domain auto-linking, image attachments with alt text
LinkedIn Social Plaintext Link previews with OG thumbnails, image attachments
Medium Blog HTML Requires title
Dev.to Blog Raw markdown Requires title
Substack Blog HTML via SMTP Arrives as draft, requires title

System of record

After publishing, Blurt writes platform permalinks back into the frontmatter of each file. The sent/ directory is your system of record.

---
title: "My Post"
platforms:
  - bluesky
  - mastodon
publishedAt: "2026-03-28T14:30:45Z"
results:
  bluesky:
    url: "https://bsky.app/profile/you.bsky.social/post/abc123"
    publishedAt: "2026-03-28T14:30:44Z"
  mastodon:
    url: "https://mastodon.social/@you/123456789"
    publishedAt: "2026-03-28T14:30:45Z"
---

My post content.

Failed posts move to failed/ with error details and any URLs that did succeed, so you know exactly what happened.

Architecture

queue/  -->  QueueScanner finds pending posts
        -->  PublishOrchestrator publishes to all platforms in parallel
        -->  PostMover moves to sent/ (with permalinks) or failed/ (with errors)
  • Posts are POROsPost is a plain Ruby object that reads .md files. No ActiveRecord.
  • Filesystem is authoritative — SQLite stores PublishLog for fast queries. The files in sent/ are the source of truth.
  • File locking — prevents double-processing via .publishing suffix rename.
  • Parallel publishing — all platforms publish simultaneously via Concurrent::Future.
  • Link previews — Bluesky and LinkedIn automatically fetch OG metadata and attach link cards.