Sponsorship desk for every newsletter ad you have sold

By General Input

Track every ad placement from pitched to paid on one board, show sponsors what their issue actually did, and raise the invoice without leaving the app.

Integrations

  • beehiiv
  • Stripe

Type

App

Categories

  • Marketing
  • Finance

Build me a sponsorship desk app for my newsletter where I manage every ad placement I have sold, from the moment I pitch it to the moment the money lands. I sell ads in my beehiiv newsletter and bill sponsors through Stripe, and right now this all lives in a spreadsheet that breaks once I have more than about ten active deals.

Important: beehiiv has no ad network, sponsorship, boost, or referral operations in its catalog, so the app itself must own and persist the placement records. Do not try to read or write sponsorship data in beehiiv. Each placement record is stored by the app and linked to a beehiiv post by its post ID. Store per placement: sponsor name, billing contact name and email, agreed rate, status (pitched, booked, ran, invoiced, paid), the beehiiv post ID and cached post title plus publish date for the issue it runs in, the slot or position within that issue, free text notes, and once billing has happened the Stripe customer ID, invoice ID, invoice number, and hosted invoice URL.

The main surface is a placement board with a column per status: pitched, booked, ran, invoiced, paid. Each card shows the sponsor name, the rate, the issue title, and the issue date, and every column shows a count and a summed dollar total in its header. I can move a placement between columns from the card, and I can create a new placement from a button on the board.

When I create or edit a placement, the issue field is a dropdown populated by beehiiv List Posts for my publication, showing each post's title and publish or scheduled date, most recent first, with a search box because the list gets long. Selecting an issue stores its post ID on the placement. Issues I have marked sold out appear in the dropdown but are disabled with a sold out label so I cannot pick them.

I need to mark an issue as sold out so I never double book the same slot. The sold out flag is app-owned data keyed by beehiiv post ID, with an optional slot count so an issue with a primary and a secondary spot can hold two placements before it is full. Give me a place to toggle sold out per issue, and warn me before saving if I am adding a placement to an issue that already has one in the same slot.

A performance view covers every placement that has shipped, meaning status ran, invoiced, or paid. For each one, call beehiiv Get Post for the linked post ID with the stats expansion and show the real numbers: recipients, opens and open rate, clicks and click rate, and unique clicks where available. Present it per placement with the sponsor name next to it so that when a sponsor asks whether the placement was worth it I can read the answer straight off the screen. Also show a rollup across all shipped placements using beehiiv Get Post Aggregate Stats, which aggregates engagement across the posts matching a filter, as a top line for the period. Handle the case where an issue has not sent yet by showing a pending state instead of zeros.

Clicking a placement opens a detail panel with everything about the deal, its issue performance, and a button that raises the bill in Stripe. That button should: find the sponsor's Stripe customer with Stripe Search Customers on the billing contact email, falling back to Stripe Create Customer when there is no match; create a draft bill with Stripe Create Invoice for that customer with send invoice collection and payment terms I can set; add the placement rate as a line with Stripe Create Invoice Item, with a description naming the sponsor, the issue title, and the issue date; finalize it with Stripe Finalize Invoice; then email it with Stripe Send Invoice. Save the returned invoice ID, number, and hosted URL onto the placement, move it to invoiced, and show the hosted invoice link in the panel. If the placement already has an invoice ID, disable the button and show the existing invoice instead so I cannot bill a sponsor twice. Stripe amounts are in cents, so convert on the way in and out. Use Stripe List Invoice Items scoped to the stored invoice ID to show what was actually billed.

The board should move a placement to paid on its own once the money lands. When the board loads, and from a refresh control, read Stripe List Invoices and match settled invoices against the invoice IDs stored on placements. When an invoice for a placement has been paid, set the placement to paid and record the amount paid and the payment date. This reconciliation only reads from Stripe, it never writes.

Include a revenue summary for the current quarter showing booked versus collected. Booked is the sum of rates for placements whose issue date falls in the quarter and whose status is booked, ran, invoiced, or paid. Invoiced is the sum of rates for those already billed. Collected is the sum of settled Stripe invoice amounts in the quarter from the same List Invoices read. Show outstanding as invoiced minus collected, and let me switch quarters. Pitched placements are not counted as booked but show as a separate pipeline number so I can see what is still in play.

This is for me and maybe one teammate, so keep it simple: no roles or permissions, currency formatted as dollars everywhere, sensible empty states for a first run with no placements yet, and clear error messages if the beehiiv or Stripe connection fails rather than silent blank panels.

Related prompts

Explore more prompts
Let support send one-off Loops emails without an engineerCustomer lifecycle inspector for Loops, Stripe and PostHogMonth-end Stripe finance pack, stored and shared in SlackRank your Intercom queue by what each customer pays youCatch the trials quietly dying before the card gets chargedWork every open Stripe dispute from one chargeback war roomLook up any customer's support, billing and CRM in one pageInvestor update studio that builds your board deck monthlySell and invoice Ghost newsletter sponsor slots in one boardSupport console that pairs Gladly chats with orders and refunds