Announcing the Magic Pages Open House. Quarterly calls with our team!

Hosting your audio files

Updated Jul 13, 2026 · 4 min read

Pod doesn't care where your MP3 files live. It'll happily read them out of Ghost's file library, off Castopod, off Azuracast, off an S3 bucket, off a VPS you own, or off the podcast host you're trying to escape from. There are three ways to point Pod at an audio file. All three produce the same iTunes-spec + Podcasting 2.0 RSS enclosure; the only difference is where the MP3 physically sits and how you tell Pod about it.

Option 1 — Upload to Ghost

The simplest path, and what we recommend for most people. Ghost has a file library; your MP3 goes in it, next to any images or PDFs you've uploaded.

  1. In the Ghost editor, click the + to add a card and pick Audio.
  2. Drop your MP3 in.
  3. Publish.

Ghost hosts the file at a URL like https://yoursite.com/content/files/2026/07/ep01.mp3. Pod's RSS template automatically picks up the first <audio> element in the post body and uses it as the enclosure URL. No further configuration needed.

When to pick this: you're starting fresh, you're comfortable with Ghost being your only backend, and you want the simplest possible workflow.

Option 2 — Point at an externally-hosted MP3 via code injection

If your audio already lives elsewhere — Castopod, Azuracast, Simplecast, Blubrry, a legacy Buzzsprout account you don't want to break, an S3 or R2 bucket you're paying for anyway — Pod can point straight at it.

In your episode's Post settings → Code injection → Foot, add a single line:

<!-- pod:audio=https://castopod.example/episodes/ep01.mp3 -->

That URL becomes the RSS enclosure. Pod's on-page audio player uses it too. You can leave the post body empty of audio cards (or add anything you want — the pod:audio= marker always wins).

The episode metadata generator has an "Audio URL" field that outputs exactly this line, along with the file size (which Pod uses for the RSS enclosure's length attribute — download-progress bars in podcast apps rely on it).

When to pick this: you're migrating from another podcast host and want to keep the existing MP3 URLs alive (never break a listener's cached episode), or you have infrastructure reasons to serve audio from somewhere other than Ghost (CDN routing, egress costs, a self-hosted host you already run).

Option 3 — Point at an externally-hosted MP3 via an HTML card

If you'd rather see the audio player in the Ghost editor as you write the show notes — instead of it being invisible in a code injection field — drop an HTML card in the post body:

<audio src="https://castopod.example/episodes/ep01.mp3" controls preload="none"></audio>

When Pod's RSS template runs, it looks for a pod:audio= marker first, and falls back to the first <audio src> element it finds in the post body. So this snippet does double duty: it renders as a small audio player inside the Ghost editor's preview and on the published post, and it becomes the RSS enclosure URL.

When to pick this: you want the audio to be visible in the Ghost editor and post body itself, not tucked away in a settings panel. Also useful if you're adding audio to an existing post retroactively and don't want to fiddle with code injection.

Which one to use — a quick comparison

MethodMP3 lives atBest for
Ghost audio cardYour Ghost site's /content/files/New podcasts, simplicity
pod:audio= markerAnywhere, any URLMigrating from another host, keeping legacy URLs alive
HTML card with <audio>Anywhere, any URLSame as marker, but visible in the editor

The one thing to watch for: file size in the RSS feed

Every RSS feed's <enclosure> element carries a length attribute — the file size in bytes. Podcast apps use it to show accurate download-progress bars, and strict feed validators flag it as a warning when it's zero or missing.

When you use option 1 (Ghost audio card), Ghost doesn't expose the file size to the theme, so Pod emits length="0" unless you add a <!-- pod:audioLength=BYTES --> marker in the code injection foot alongside your other markers. The metadata generator's Fetch from URL button reads this over the network from your Ghost site and fills it in.

When you use option 2 or option 3, the same trick works — the generator's Fetch from URL button HEAD-requests the URL and reads the Content-Length header, provided your host allows CORS. If it doesn't, look up the byte count manually (right-click the file → Get info on macOS, Properties on Windows) and paste it in.

What Pod doesn't do

Pod is a Ghost theme; it doesn't transcode audio, generate transcripts, or optimise file sizes. If your MP3 is 300 MB, it's 300 MB in the RSS feed and 300 MB when a listener downloads it. For self-hosted encoding + hosting, we like Castopod. For upload-only encoding, the Encoder Settings in Audacity or Reaper are what most people use to hit the sweet spot (mono, 96 kbps VBR for voice-only shows). Either way, the audio ends up at some URL, and Pod points at it.

Same source powers the RSS feed and the on-page player

Whichever of the three methods you pick, Pod uses the same URL in two places: the RSS feed's <enclosure> tag (what Apple Podcasts, Spotify and every other podcast app downloads) and the branded on-page audio player. You never end up with a mismatch where the site plays one file and the RSS points at another.

The lookup order for the on-page player is: pod:audio= marker first, then the first <audio> element in the post body. If both are present, the marker wins — which is what you want for option 2, and the reason option 3 stays consistent with the RSS feed. When the player finds an <audio> element in the post body, it also hides the native element after picking up its URL, so listeners only ever see the branded player.

Migrating between the three

All three methods produce identical RSS output, so you can switch at any time without breaking listeners:

  • External → Ghost-hosted: upload the MP3 to Ghost, add an audio card in the post body, remove the pod:audio= line (or the HTML card).
  • Ghost-hosted → External: upload the MP3 to your new host, add a <!-- pod:audio=NEW_URL --> line to the code injection foot. It overrides the audio card. If you want to remove the card from the post body too, you can — the RSS still reads from the marker.

The one thing to remember: the RSS feed's <guid> for each episode is Ghost's post ID, not the audio URL. So changing where the audio is hosted doesn't cause podcast apps to treat the episode as new. Listeners' subscriptions carry on unaffected.

Still have questions?

We're here to help and want to make sure you get the most out of your theme. Reach out directly and we'll get back to you as soon as possible.

Ready to Publish? A snap of your fingers – and you're live!

Join 1,400+ publishers who chose Magic Pages as the home for their Ghost site.

Jannis - Founder of Magic Pages
Live in 5 minutes
Personal support from our team
All Ghost features included
14-day free trial, no credit card
Start Your 14-Day Free Trial

No credit card required

I personally guarantee you'll love the experience, or I'll help you find a better solution.

— Jannis, Founder of Magic Pages