Listen. Watch. Shop. Share.

Stashbox Radio

A custom RDS-backed music, video, merchandise, and advertising platform built to feel simple on the surface while running a sophisticated stack underneath.

33+ Tracks managed from RDS
3 Active ad inventory tests
2 Ad break methodologies
Live Dev to production workflow

Executive Summary

Stashbox Radio began as a music player and evolved into a custom media platform that connects songs, videos, merchandise, advertising, analytics, and admin publishing tools into one lightweight experience. The public player is intentionally simple: a listener can play a song, watch a video, like, share, shop, and continue through the catalog. Behind that simple interface is a custom backend system using AWS, PostgreSQL, API Gateway, Lambda, S3 media, and a custom admin console.

The sophistication of the system is in its simplicity. The user sees a radio experience. The admin sees editable song records, product links, ads, settings, and stats. The platform quietly handles media playback, deep links, persistent likes, ad delivery rules, ad tracking, product carousels, and RDS-backed content management without requiring a full commercial CMS.

Core idea: Stashbox Radio is not just a playlist. It is a lightweight custom radio station, video player, ad server, merchandise gateway, and music CMS built around the Stashbox catalog.

Primary Tools and Platforms Used

Frontend

  • HTML for page structure
  • CSS for responsive player/admin styling
  • JavaScript for player logic, UI state, tracking, filters, ads, and admin forms
  • GitHub Pages for static site hosting

Backend

  • AWS Lambda running Node.js 22.x
  • AWS API Gateway HTTP API
  • PostgreSQL on AWS RDS
  • DBeaver for RDS inspection and SQL updates
  • CloudWatch for Lambda logs and error diagnosis

Media and Commerce

  • AWS S3 for audio, artwork, and ad media files
  • YouTube embeds for music videos and video-only records
  • Shopify product data for merch cards
  • Specific product URLs per song
  • Future external Shopify metadata support planned

Languages and Technical Stack

HTML CSS JavaScript Node.js SQL PostgreSQL JSON REST APIs AWS Lambda API Gateway S3 RDS

The Architecture

The architecture separates the public listening experience from the admin publishing experience. The public site is static and fast. The dynamic behavior comes from API calls to Lambda, which reads and writes to RDS.

1
Public player loads

The browser opens /radio/ or /radio/dev/ and loads songs, counts, ad settings, products, and active ads from API endpoints.

2
Lambda processes API requests

API Gateway routes requests into the Lambda function, which normalizes paths, validates requests, and queries PostgreSQL.

3
RDS stores the source of truth

Songs, ads, settings, likes, stats events, product URLs, and admin-managed fields live in PostgreSQL.

4
Admin updates the system

The admin dashboard edits songs, saves specific product URLs, manages ads, updates ad delivery settings, and reviews stats.

5
Listener actions feed analytics

Likes, plays, shares, ad starts, ad clicks, ad skips, product clicks, and other events are tracked through API calls.

Public Radio Player Features

Music and Video

  • Audio-only songs
  • Song plus video records
  • Video-only tracks
  • YouTube video support
  • Deep links by song key, such as /radio/?song=<song_key>
  • Spacebar play/pause behavior
  • Mobile and desktop playback handling

Engagement

  • Persistent likes saved to RDS
  • Share links using production song URLs
  • Play counts
  • Product click tracking
  • Video click tracking
  • Mobile share URL repair

Shopping

  • Song-specific product URLs
  • Fallback Shopify product carousel
  • Product cards with image, title, and price where available
  • Specific product links saved from admin
  • Future support for external Shopify metadata

Sorting and Filtering

  • Song list filtering
  • Videos-only quick filter
  • Shuffle all
  • Latest sorting
  • Most played sorting support
  • Reset filters

Admin System

The admin system turns Stashbox Radio into a manageable platform rather than a hard-coded player. The admin can edit songs, manage product links, review dashboard stats, archive records, and operate the ad system.

Dashboard

  • Operational stats
  • Play starts
  • Shares
  • Likes
  • Product clicks
  • Listening time

Song Management

  • Edit Song loads saved RDS data
  • Save Song updates RDS
  • Specific product URLs save correctly
  • Public notes and internal notes
  • Artist, genre, mood, release format, artwork, video, and audio fields

Ads Admin

  • Ad inventory list
  • Ad title and description
  • Active/inactive controls
  • Ad ratio and media metadata
  • View, click, skip, CTR, and skip-rate stats

API Overview

The system uses a practical REST-style API design. Static pages stay simple and fast, while dynamic data is requested only when needed.

Method
Endpoint
Purpose
GET
/radio/songs
Returns public songs, audio/video metadata, artwork URLs, counts, and deep-link data.
GET
/radio/ads
Returns active ad inventory for the public player, including video URL, title, description, skip rules, stats, and targeting fields.
GET
/radio/ad-settings
Returns public ad delivery settings, including master ads on/off, count mode, seconds mode, ads per break, target seconds, and break interval.
POST
/radio/track
Tracks plays, full plays, likes, shares, product clicks, video clicks, ad starts, ad clicks, ad skips, ad completes, and other events.
GET
/admin/stats/summary
Returns private dashboard totals for events, plays, likes, shares, clicks, and listening time.
GET
/admin/songs
Returns admin song records for song management.
GET
/admin/songs/:song_key
Loads an individual song record for Edit Song.
PUT
/admin/songs/:song_key
Saves song edits, including specific product URLs and metadata fields.
GET
/admin/ads
Returns private ad inventory for the ads admin panel.
POST
/admin/ads
Creates new ad inventory records.
PUT
/admin/ads/:id
Updates existing ad inventory records.
DELETE
/admin/ads/:id
Deletes or removes ad records from the admin inventory.
GET
/admin/ad-settings
Loads private ad controller settings for the admin panel.
PUT
/admin/ad-settings
Saves ad controller settings to RDS.
POST
/admin/uploads/presign
Supports secure media upload workflows through S3 presigned URLs where enabled.
API sophistication: The API is intentionally small, but it handles a wide range of platform behavior: content retrieval, admin editing, stats tracking, ad serving, ad settings, persistent likes, product links, and analytics.

How the Ads Roll

The ad system functions like a lightweight custom ad server for Stashbox Radio. Ads are stored in RDS, served through the public API, controlled by the admin panel, and tracked through events.

Ad Inventory

  • Ad title
  • Description
  • Video URL
  • Click URL
  • Ratio label and dimensions
  • Skip-after seconds
  • No-skip option
  • Active/hidden status
  • Frequency/rotation weight
  • Optional genre, mood, artist, and song targeting fields

Ad Playback UX

  • Ads play after songs or videos based on controller settings
  • Ad title and description show in the ad player
  • Learn More button opens the CTA link
  • Skip countdown shows when skipping is allowed
  • Ad duration shows as current time / total time
  • Ad break indicator shows progress, such as Ad 2 of 4
  • Seconds mode can show a master ad break countdown
  • Tap-to-resume handles paused ad playback

Two Ad Delivery Methodologies

Method 1: By Number of Ads

The admin can choose how many ads play in a break. Current options are 1, 2, 3, 4, or 5 ads per break.

  • Example: Ads Per Break = 3
  • The listener sees Ad 1 of 3, Ad 2 of 3, Ad 3 of 3
  • After the final ad, the next song or video resumes

Method 2: By Total Seconds

The admin can choose a target amount of ad time, such as 15, 30, 45, 60, or 90 seconds.

  • Example: Target Ad Break Length = 30 seconds
  • The player continues selecting ads until the break reaches the target duration
  • This prevents one short 5-second ad from counting as a full break

Ad Rotation and Frequency

Each ad has a Low, Medium, or High frequency setting. This is best understood as rotation weight, not break frequency. High-weight ads are more likely to be selected. Low-weight ads are less likely. The break frequency itself is controlled by the Ad Controller.

Ad Controller Settings

Sort Methods and Discovery

Stashbox Radio uses simple listener-facing controls to keep discovery easy. The goal is not to overload the listener with a complex database interface. It is to give them fast ways to find songs and videos.

Latest

Sorts the catalog toward newer or recently added content, helping the radio experience feel alive and current.

Most Played

Uses play metrics to surface tracks with stronger listener activity.

Videos Filter

Quickly narrows the catalog to songs and records with video content.

Shuffle All

Creates a radio-style experience by moving away from manual selection and into discovery mode.

Deep Links

Every song can be shared as a direct URL using a song key.

Search and Filters

The player supports simple filtering across song, album, artist, and metadata-oriented discovery.

Data Model Overview

The database model is built around a few practical entities rather than an overcomplicated enterprise CMS.

Songs

  • Song key
  • Song name and display title
  • Artist
  • Genre and secondary genre
  • Mood and mood tags
  • Release format
  • Album name
  • Audio URL
  • Video URL or YouTube link
  • Artwork URL
  • Specific product URLs
  • Persistent likes
  • Visibility and feature flags

Ads

  • Ad title
  • Description
  • Video URL
  • Click URL
  • Frequency weight
  • Skip settings
  • Views
  • Clicks
  • Skips
  • CTR
  • Skip rate
  • Targeting fields

Ad Settings

  • Master ads enabled
  • Break method
  • Ads per break
  • Target seconds
  • Break interval

Events and Analytics

  • Play starts
  • Full plays
  • Partial plays
  • Likes
  • Shares
  • Video clicks
  • Product clicks
  • Ad starts
  • Ad clicks
  • Ad skips
  • Ad completes

Sophistication Through Simplicity

The platform avoids the trap of looking complicated to the user. The public interface is simple enough for a fan to understand instantly, while the backend keeps track of many moving pieces.

Simple to the Listener

  • Click play
  • Watch a video
  • Like a song
  • Share a link
  • Shop the track
  • Continue listening

Sophisticated Underneath

  • RDS-backed song records
  • Persistent likes and stats
  • Ad server logic
  • Ad controller settings
  • Count-based and seconds-based ad breaks
  • Shopify product integrations
  • Admin dashboard and edit flows
The system is custom enough to fit Stashbox specifically, but simple enough to operate without becoming a bloated platform.

Project Timeline

Phase I: Player Foundation

Built the public Stashbox Radio experience with song cards, playback controls, artwork, video support, basic filtering, and shopping placement.

Phase II: Dev and Production Strategy

Established a safer workflow separating /radio/dev/ from /radio/ and /radio-admin/dev/ from /radio-admin/.

Phase III-A: RDS and API Foundation

Connected the system to AWS RDS PostgreSQL using Lambda and API Gateway. Songs and stats began moving away from legacy static or sheet-based workflows.

Phase III-B: Admin and Song Management

Expanded the admin environment so song records could load from RDS, be edited, saved, and managed with metadata fields.

Phase III-C: Ads Inventory

Added RDS-backed ad inventory with video URLs, click URLs, active status, frequency weight, and public ad loading.

Phase III-D: Ad Stats

Added ad views, clicks, skips, CTR, and skip-rate tracking. Improved skip countdown, Learn More click behavior, and ad resume handling.

Phase III-E: Ad Controller and Multi-Ad Breaks

Added admin-controlled ad delivery settings including master ads on/off, ads per break, target ad seconds, and ad break timing. Added count mode and seconds mode.

Phase III-F: Product Links and Persistent Likes

Fixed Edit Song product URL saving, added persistent likes to RDS, repaired deep-link likes, and made song-specific product links usable in the public player.

Production Promotion

Promoted tested dev work from /radio/dev/ to /radio/, from /radio-admin/dev/ to /radio-admin/, and from /radio-admin/dev/ads/ to /radio-admin/ads/, with backups and rollback awareness.

Future Phase: External Shopify Metadata

Planned expansion to fetch product image, title, price, and source metadata from outside Shopify stores when those stores allow metadata access.

Current Environment URLs

Future Roadmap

External Product Metadata

Add metadata fetching for external Shopify and product URLs that allow data access. Cards should show image, title, price, and source when available, with a clean fallback when blocked.

Production API Separation

The current working API base may still include a dev name. A future cleanup can create separately named production Lambda/API resources once the system is fully stabilized.

Expanded Ad Targeting

Genre, mood, artist, and song targeting can become smarter so ads can match the listening context more precisely.

Intro and Outro System

Add randomized DJ-style voice intros and outros by global, artist, genre, or song-specific rules.

Additional Analytics

Expand dashboards with completion curves, repeat listeners, product conversion paths, and ad break performance by setting.

CloudFront Media Optimization

Add or expand CDN delivery for audio, artwork, and ad media to improve speed and reduce direct S3 delivery dependency.

Conclusion

Stashbox Radio is now a custom digital music platform with a strong foundation: a public player, RDS-backed content, admin publishing tools, ad inventory, ad delivery controls, persistent likes, product links, and analytics. The system is built in a way that keeps the fan experience simple while giving the admin practical control over the catalog, ads, and engagement data.

The project demonstrates a useful model for independent music brands: own the platform, own the data, connect the music directly to merchandise, and create a custom ad system that can grow without depending entirely on third-party platforms.