PostFlow
API-First Social Media Automation
A developer-focused social media scheduling platform with REST API, multi-platform publishing, and subscription-based monetization. Built for reliability and self-hosting.
Problem
Social media management tools like Buffer and Hootsuite are expensive, bloated with features developers don't need, and lock users into proprietary platforms. Indie hackers and small teams need a lightweight, API-first solution they can self-host and extend.
Expensive
Enterprise tools cost $50-100/month per user
Locked In
Proprietary platforms with no data portability
Not API-First
Complex integrations, not developer-friendly
Architecture
The system follows a clean three-tier architecture: a FastAPI-based REST API handling authentication and business logic, a SQLite/PostgreSQL database for persistence, and a background worker process that processes the publishing queue using APScheduler.
API Layer
- •FastAPI with async request handling
- •JWT-based authentication
- •API key management for external access
- •Input validation with Pydantic models
Data Layer
- •SQLAlchemy ORM for database abstraction
- •SQLite for development, PostgreSQL for production
- •Alembic migrations for schema versioning
- •Connection pooling for concurrent access
Worker Layer
- •APScheduler for reliable job execution
- •Retry logic with exponential backoff
- •Queue-based processing with priority support
- •Dead letter queue for failed jobs
External APIs
- •Instagram Graph API for publishing
- •Twitter/X API v2 for tweets
- •LinkedIn API for company posts
- •Rate limit handling and token refresh
Technical Approach
Designed a clean REST API with API key authentication, JWT-based session management, and a SQLite-backed queue system. Implemented a worker process using APScheduler for reliable post execution. Created a simple web dashboard for non-technical users while keeping the API as the primary interface. Built subscription tiers directly into the data model for future monetization.
from sqlalchemy import Column, Integer, String, DateTime, Enum
from sqlalchemy.orm import declarative_base
from datetime import datetime
import enum
Base = declarative_base()
class PostStatus(str, enum.Enum):
DRAFT = "draft"
SCHEDULED = "scheduled"
PUBLISHING = "publishing"
PUBLISHED = "published"
FAILED = "failed"
class Post(Base):
__tablename__ = "posts"
id = Column(Integer, primary_key=True)
content = Column(String(2200), nullable=False)
platform = Column(String(50), nullable=False)
status = Column(Enum(PostStatus), default=PostStatus.DRAFT)
scheduled_at = Column(DateTime, nullable=True)
published_at = Column(DateTime, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow)
# Retry logic
retry_count = Column(Integer, default=0)
last_error = Column(String(500), nullable=True)Key Technical Decisions
SQLite for Single-Node Deployments
Chose SQLite as the default database to simplify deployment for individual users. The same SQLAlchemy models work with PostgreSQL for production multi-user deployments.
APScheduler Over Celery
Selected APScheduler for its simplicity and zero external dependencies (no Redis required). Suitable for the expected workload of hundreds of posts per day.
Docker-First Deployment
Packaged as a Docker Compose stack with automatic HTTPS via Traefik. One-command deployment for developers wanting to self-host.
Tech Stack
Results & Outcomes
Complete API with 15+ endpoints for posts, accounts, and analytics
Background worker processing queue with retry logic
Multi-tier subscription system (Free/Pro/Agency)
Docker Compose setup for one-command deployment
Built-in analytics tracking success rates and usage patterns
Live Demo
Explore the interactive dashboard showing real-time metrics, post queue status, and connected account health. This is a read-only demonstration of the system interface.
Open Dashboard Demo