Building a Podcast Automation Platform with Ittybit
Part 1 - Architecture & File Ingestion
I've spent the last few years watching podcasters wrestle with the same problem over and over: they record an amazing conversation, then spend the next 2-3 hours manually processing it. Extract the audio. Optimize the video. Upload to multiple platforms. Generate transcripts. Write show notes. It's tedious, it's repetitive, and frankly, it's exactly the kind of work computers should be doing for us.
So I decided to build something about it. Not just a tool, but a complete exploration of how modern media processing APIs can eliminate this drudgery. This is the first article in a series where we'll build a real podcast automation platform using Ittybit's media processing API.
The Problem (And Why You Should Care)
Here's what a typical podcast workflow looks like today:
- Record a 60-minute video interview on StreamYard
- Download a 2GB video file
- Fire up Audacity or Adobe Audition to extract audio
- Export as MP3, fiddle with bitrate settings
- Upload to Transistor or Libsyn
- Open Premiere or Handbrake for video optimization
- Upload to YouTube (and wait... and wait...)
- Use another service for transcription
- Manually write show notes from the transcript
Each episode. Every single time.
If you're running a weekly show, you're spending 8-12 hours per month on pure mechanical work. If you've ever thought "there has to be a better way," well, there is. And we're going to build it.
What We're Building: The 10,000-Foot View
Our goal is simple: upload once, publish everywhere, automatically.
Here's what the final product will do:
And we're building this as a pure REST API. No frontend, no Livewire, no React. Just clean Laravel API endpoints that handle the heavy lifting. Why? Because:
- APIs are universal - Any client can consume them
- APIs force good architecture - You can't hide bad design behind UI tricks
- APIs are easier to test - No DOM, no JavaScript, just HTTP
- You can always add a UI later - But you can't easily extract an API from a monolith
The Architecture: API-First Design
Let me show you how this system is structured. I'm a big believer in understanding the "why" before the "how," so let's walk through the key architectural decisions.
The Stack
Key architectural choices:
- Stateless API - Every request is independent, fully authenticated
- Queue-driven processing - Long-running tasks don't block HTTP requests
- Webhook receivers - We listen for external events (Ittybit completion, etc.)
- Service layer - Business logic lives in dedicated service classes, not controllers
- Event-driven - Laravel events tie the system together without tight coupling
The Flow: From Upload to Publishing
Here's what happens when someone uploads a video:
This architecture gives us resilience (jobs retry on failure), scalability (add more queue workers), and observability (track every step).
Getting Files into Ittybit: The Foundation
Alright, enough theory. Let's write some code.
The first thing we need to do is get our video files into Ittybit. Looking at the Ittybit API docs, I can see two main approaches:
- Direct URL ingestion - Give Ittybit a publicly accessible URL
- Signed URL upload - Get a signed URL, upload directly from client
For our API, we'll use signed URLs. Why? Because:
- We don't want to store huge video files on our server
- Clients can upload directly to Ittybit's CDN (faster)
- We save bandwidth and storage costs
- It's more scalable
Setting Up Ittybit
First, let's create a service class to handle all Ittybit interactions:
Let me break down what's happening here:
The generateUploadSignature() method creates a time-limited, signed URL that clients can use to upload files directly to Ittybit. This is crucial - we're not handling the file upload ourselves. We're just brokering the permission.
The createMediaFromFile() method tells Ittybit "hey, I just uploaded a file, create a media object for it." This is where we attach metadata like title and description.
The getFile() method fetches details about a specific file. We'll use this later to check processing status and get URLs to processed files.
The Episode Creation Endpoint
Now let's build our first API endpoint. This is where clients will initiate the upload process:
How This Works in Practice
Here's the actual flow from a client perspective:
Step 1: Request upload permission
Response:
Step 2: Upload the file directly to Ittybit
Step 3: Confirm upload
Response:
And just like that, the file is in Ittybit's system and ready for processing.
Why This Approach Wins
Let me tell you why I love this architecture:
1. Zero Server Storage - We never touch the video file. It goes straight from client → Ittybit. No need for massive EBS volumes or S3 buckets.
2. Fast Uploads - Clients upload directly to Ittybit's CDN, which is geographically distributed. Much faster than routing through our server.
3. Security - Signed URLs expire. No permanent upload endpoints that could be abused.
4. Scalability - We can handle 1 upload or 1,000 uploads with the same infrastructure. The bottleneck is Ittybit's capacity, not ours.
5. Clean Separation - Our API orchestrates the workflow. Ittybit handles the heavy media processing. Each service does what it's good at.
The Database Schema (So Far)
Here's what our episodes table looks like at this stage:
What's Next?
In the next article, we'll tackle the processing pipeline. We'll:
- Create audio extraction tasks in Ittybit
- Handle video transcoding for YouTube
- Set up webhook receivers to know when tasks complete
- Build the queueing system that ties it all together
But for now, we have a solid foundation: an API that can accept episode uploads, generate signed URLs for direct client uploads, and track the status of episodes. The groundwork is laid.
Try It Yourself
Want to experiment with this approach? Here's what you'll need:
- Ittybit Account - Sign up at ittybit.com (they have a free tier).
- Laravel 12 - Fresh installation.
- Redis - For queue management.
- Sqlite database - Simple local storage.
- A test video file - MP4, MOV, anything Ittybit supports.
The code we've written today gives you everything you need to start accepting video uploads and preparing them for processing. In the next article, we'll make those videos actually do something.
Until then, happy coding. And if you've built something similar (or are thinking about it), I'd love to hear about your approach. Hit me up on Twitter or leave a comment below.