Ghost is one of the few newsletter platforms that publishers actually own. It is open source, self-hostable, and its subscription tooling is genuinely good. Ghost reports that publications running on it earn more than $100,000,000 a year with 0% payment fees, which tells you exactly where the platform has invested: memberships and paid subscriptions.
Sponsorships sit outside that. There is no booking system, no availability calendar, no payment flow for advertisers, and no asset collection. If you sell sponsorships on Ghost, you are running that operation yourself, and there is one Ghost-specific limitation that catches almost everyone the first time they try to automate it.
This post covers what Ghost handles, what it leaves to you, the embed limitation and its fix, the manual workflow most creators end up with, and which parts of it are worth automating first.
What Ghost handles, and what it leaves to you
Ghost's monetization features are built around members. Paid tiers, member signup, offers and promotions, and native analytics for opens and clicks. Sponsorship is a different transaction with a different counterparty, and Ghost does not model it.
What that means in practice:
Ghost handles well. Delivery and deliverability, which directly affect what a sponsor gets. Member segmentation, which lets you offer a sponsor a targeted send. Click tracking on every link in a post, including sponsor links, which is the raw material for a performance report. Card-level control over what appears where, which matters more than it sounds and is covered below.
Ghost leaves to you. Publishing your rates. Showing which issues are still open. Taking payment. Collecting the sponsor's copy, image and destination link. Chasing assets before your deadline. Reporting results afterward. Deciding when a slot is sold.
None of this is a defect in Ghost. It is a publishing platform with a subscription business attached, and it does that job well. The operational work still has to live somewhere.
The embed limitation every Ghost creator hits
Here is the one that costs people an afternoon.
You sign up for a booking tool, you get an embed snippet, you paste it into your Ghost post, and it works perfectly on your website. Then you send the issue, and subscribers see nothing.
Ghost documents the reason directly: most modern email clients disable dynamic embeds for security. Iframes are included in that. This is not specific to sponsorship tools, and no booking platform can engineer around it. It applies to every embed you might put in a Ghost post, and it is a property of email clients rather than of Ghost.
The fix is in the Ghost editor, and it is the reason this limitation is workable.
Ghost applies visibility settings to individual cards. Its changelog describes them as letting you "choose where the content displays. Like in your newsletter, article, or both", and confirms these settings apply to the HTML card specifically. Ghost's developer documentation records the same thing at the API level: HTML and Call to Action cards carry a visibility property with separate web and email objects. Each of those also takes a memberSegment filter, which is the mechanism behind hiding a card from particular member tiers rather than from a whole channel. The two are worth keeping straight: the web-and-email switch decides where a card appears, the member segment decides who sees it.
So the working pattern on Ghost is:
- Put the interactive booking content in an HTML card, set to show on web.
- Leave that card out of the email send.
- In the email, link readers to a standing sponsor page that always carries current availability.
The link travels fine in email. The interactive content works on the web. You stop fighting a limitation that will not move.
This is worth setting up once as a permanent page rather than repeating per issue. A standing sponsor booking page linked from your newsletter footer gets found by sponsors who read an issue six weeks from now.
Where sponsorship content actually goes in Ghost
The HTML card is the mechanism for anything external. Ghost describes it as a way of "adding code to your posts, which is useful for embedding external content such as forms, custom buttons, adding custom styling, and integrating with third-party tools".
Two things follow from that, and both matter for choosing tools.
It needs no theme access. You are not uploading a theme or writing code injection, so a plan or setup that restricts those does not block you. It works the same on Ghost Pro and self-hosted Ghost.
It is per-post. Every card is independent, which is what makes the web-versus-email split possible, and also what makes a standing sponsor page more reliable than embedding in each issue.
That is where a booking calendar goes. The sponsor placement itself is a different job, and Ghost ships a card built for it.
Use the Call to Action card for the ad itself
There is no need to hand-roll a sponsor block in HTML. Ghost describes its Call to Action card as helping you "promote a specific message to the right audience", and lists what it gives you: "an image, an optional sponsor label, and a button that links anywhere", plus control over background colour, button style, link colour and image layout. It carries the same visibility property as the HTML card, so everything above about web-versus-email and member tiers applies to it too.
The useful consequence is that the card tells you what to collect from a sponsor before you build the issue:
| What to collect from the sponsor | Where it goes in the card |
|---|---|
| Company name | Sponsor label |
| Logo | Image |
| Headline and ad copy | Card body |
| Destination URL | Button link, and the sponsor label link |
| Button wording | Button text |
The last row is the one creators tend to fill in themselves, and it is the one worth asking for. "Get 20% off your first order" is a different proposition to "Learn more", and the sponsor knows their own offer better than you do. Collect it with the rest of the creative rather than inventing it at layout time.
Ghost's own suggestion is worth taking as well. Its changelog puts it directly: "Adding a link for advertisers to get in touch can invite more brand deals". A reader who notices your sponsor block is a candidate sponsor. Point that link at your standing sponsor page rather than an email address, so they can see your rates and open dates without waiting on a reply.
If you have promised paid members an ad-free read, the card's visibility settings hide the block from those tiers without you maintaining two versions of the issue.
The manual Ghost sponsorship workflow
Without external tooling, running a sponsorship on Ghost looks like this:
- A sponsor finds you and emails.
- You reply with rates and which dates are open.
- They ask about a date you have already provisionally promised someone else.
- You reconcile your calendar and confirm.
- You send an invoice or payment link.
- You chase the payment.
- They send creative, usually as an email attachment, often in the wrong format.
- You request a revision.
- You paste the approved creative into the Ghost post.
- You publish.
- You pull click data from Ghost analytics and write a report.
Every booking runs 30 to 60 minutes of coordination, and steps 3, 6 and 8 are where deals stall. At 1 or 2 sponsors a month this is fine. At 4 or more it stops being an admin cost and starts costing revenue, because a sponsor who waits two days for an availability answer books somewhere else.
The failure mode that hurts most is double-booking, which happens because your availability lives in your head and in a thread, and both go stale.
What to automate first
Not everything in that list is worth automating, and the order matters.
Availability, first. It is the question every sponsor asks first and the one that stalls deals longest. Published, live availability answers it without you.
Payment, second. Taking payment at the point of booking removes the invoice-and-chase loop and it protects you, because the slot is paid for before you commit inventory to it.
Asset collection, third. A structured form that asks for exactly the fields you need, with a deadline attached, removes the format problems and the revision round trips.
Reporting, fourth. Ghost gives you unique opens and per-link clicks. Turning those into a sponsor report is mechanical, and a consistent report is what drives rebookings. Our reporting guide covers the format.
Keep manual: creative approval. You should read every sponsor's copy before it goes to your list. This is the step where your judgment is the product, and automating it is how a placement you would never have run reaches your subscribers.
For rate-setting, price from unique opens rather than total subscribers, since opens are what a sponsor is actually buying. Our pricing guide covers how the published benchmarks are built and where their numbers come from.
Running this on Ghost with SponsorCal
SponsorCal handles the operational layer described above and leaves Ghost to publish.
You set your rates and which days you publish, connect Stripe, and publish a booking page. Sponsors see your open issues, pick one, pay by card, and submit their own creative through a guided form. You approve it and paste it into your Ghost post.
The mechanisms behind that, since the specifics are what determine whether it fits your setup:
Availability stays accurate under concurrency. When a sponsor starts checkout, that issue is held for 10 minutes while they pay, so the same slot cannot be sold twice. If they abandon checkout, it returns to the calendar automatically.
Assets arrive with deadlines attached. Sponsors get reminders 3 days before the deadline, 1 day before, and again if it passes, so chasing creative is not on your list.
Payouts run on a fixed schedule. Sponsors are charged at booking. Publishing starts a 7-day dispute buffer, and your payout is released by the first daily payout run after that buffer clears, so 7 to 8 days in practice depending on what time of day you publish. How quickly it then lands is down to Stripe and your bank, and varies by country.
It costs 5% of a paid booking. Stripe's processing fees come out of that 5% rather than your 95%. No monthly fee.
The embed will not affect your search rankings. It is served noindex, so it never competes with your own pages, and it is cached and lazy-loaded so it does not load until a reader reaches it.
The Ghost-specific setup, including the web-versus-email card handling covered above, is documented in our Ghost setup guide.
One honest limitation: SponsorCal does not find sponsors for you. It does not sell your inventory, pitch brands, or introduce you to anyone. It gives the sponsor interest you already have somewhere to land. If your problem is demand rather than coordination, start with how to find newsletter sponsors instead, because better booking infrastructure will not fix an empty pipeline.
Summary
Ghost gives you publishing, delivery, member billing and the analytics to report on a placement. It does not give you booking, sponsor payments, asset collection or availability, and it is not trying to.
The Ghost-specific thing to get right is the email embed limitation. Interactive content will not render in the send, Ghost says so directly, and the answer is to use card visibility settings to show it on the web and link email readers to a standing sponsor page.
Automate availability first, then payment, then asset collection, then reporting. Keep creative approval manual.
Stop managing sponsorships in spreadsheets and email threads.
SponsorCal gives sponsors a self-serve booking page. They book, pay via Stripe, and submit creative assets — before your deadline.
See how it worksPublishing somewhere else? We have equivalent guides for Substack and beehiiv.