Skip to content
led-ticker

MLB promotions widget

Never miss bobblehead night again — your team’s upcoming home-game giveaways and theme nights, held on the wall so anyone walking past knows what’s worth the trip.

The baseball.promotions widget (type = "baseball.promotions", from the baseball plugin) pulls the home-game promotions feed for a tracked team and renders each promo as a held card on a wide sign or a scrolling crawl on a narrow one. Promotions come from MLB’s free StatsAPI schedule feed — no API key, no account, it just works.

baseball.promotions on a long panel: each home-game promo held as a card — the date, the promo name (BOBBLEHEAD NIGHT, then FIREWORKS FRIDAY), an opponent color chip with VS, the sponsor, the first-pitch time, and paging dots for the rest.
baseball.promotions on a long panel: each home-game promo held as a card — the date, the promo name (BOBBLEHEAD NIGHT, then FIREWORKS FRIDAY), an opponent color chip with VS, the sponsor, the first-pitch time, and paging dots for the rest.

That held card is what a mid-width sign shows by default, and what layout = "card" pins on any sign (it’s what the GIF above does). By default the widest signs run a hi-res crawl of the same fields instead, and the narrowest scroll classic promo lines — same widget, no config change.

Requires led-ticker-core >= 4.9. The demo = true mode used for the GIF on this page needs led-ticker-baseball >= 1.6.0.

Install the plugin first (steps just below this snippet), then drop it into a section:

[[playlist.section]]
mode = "slideshow"
hold_time = 6
[[playlist.section.widget]]
type = "baseball.promotions"
team = "TOR"
highlight = ["Loonie Dogs"]

team is the only required field. Here any promo whose name contains “Loonie Dogs” is emphasized — highlighted promos render in amber and sort first.

To install the plugin on a Docker deploy, add its line to the plugin manifest and restart:

Terminal window
# First plugin? Create your manifest from the example:
cp -n config/requirements-plugins.example.txt config/requirements-plugins.txt
# Add the package (one name per line), then restart:
echo "led-ticker-baseball==1.6.0" >> config/requirements-plugins.txt
docker compose restart

Other install paths (web UI Store tab, dev checkout) are on the Plugins page.

Set demo = true to render a fixed set of same-day promos with no StatsAPI call and no network:

[[playlist.section]]
mode = "slideshow"
hold_time = 4
[[playlist.section.widget]]
type = "baseball.promotions"
demo = true
layout = "card"

This is the exact widget block that rendered the hero GIF above (its full render config is baseball-promotions.toml, a [display] at default_scale = 4 with this one section). The layout = "card" line pins the held card on the wide panel — on a wide sign auto would run the crawl, so this shows off the richer card. It needs no team, since the fixture supplies its own promos — the fastest way to see the card shape without waiting for a home game.

On a narrow sign each promo scrolls past as a classic line; a mid-width sign holds each promo as a card with paging dots; the longest sign runs a hi-res crawl of the same fields. You don’t pick the default: layout (omit it — the default "auto") resolves at draw time from your sign’s real physical width. The GIF above pins the held card (layout = "card") on a long panel — the richest of the three, and worth forcing on a wide sign if you prefer it to the crawl.

Not sure which you have? Most short DIY builds are smallsign (scale-1); the 256- and 512-pixel-wide panels are bigsign and longboi — see the hardware guides. New here? Get a sign running first.

Your signWhat you see
smallsign (~160×16, scale-1)classic scrolling lines, one per promo (TOR Jun 22 · Retro Domer Hat Giveaway)
bigsign (~256px, scale>1)a held card, one promo per story with paging dots
longboi (~512px, scale>1)a hi-res crawl — the same fields as one continuous scrolling run

Pin a shape explicitly with layout = "ticker" (force the crawl on any sign) or layout = "card" (force the held card). The held card’s anatomy: the date in amber, the promo name in white (auto-scrolling in a clipped band if it’s too long), a team chip plus VS <opponent> in violet, <offer> · BY <sponsor> in cyan, and the start time in amber. Either the offer or the sponsor half is dropped when the feed doesn’t supply it — the widget never invents copy.

The widget shows today’s promos when there’s a home game today, otherwise the next home game’s. Sponsor tails (“presented by …”) are stripped and near-duplicate feed entries collapsed. With nothing to show it falls back to a team-prefixed Next home game: Jun 22, No home games soon (road trip), or Opens <date> (offseason).

team is required (unless demo = true); everything else is optional.

FieldTypeDefaultNotes
teamstrrequiredMLB team abbreviation (e.g. "TOR"). Case-insensitive. Optional when demo = true.
layout"auto" / "ticker" / "card""auto"Explicit override; omit to auto-select from real panel width — see One widget, every sign.
highlightlist of str[]Case-insensitive substrings; matching promos render amber and sort first. Applies to every layout.
filterlist of str[]If non-empty, only promos matching one of these substrings are shown. Applies to every layout.
limitint0Max promos shown (0 = no limit). Applied after highlight sorting, so highlighted promos are never the ones dropped.
lookahead_daysint14How far ahead to look for the next home game with promotions.
titlestr"<Team> Promos"Section title override.
timezonestr (IANA)system localTimezone governing the “Today” label and date formatting. See Scheduling.
font_colorcolor / "rainbow" / "color_cycle" / "shimmer" / tablecallout colorsRGB list tints promo names; the team prefix, date, and amber highlights keep their callout colors. Scale-1 only. See Color providers.
fontstr"6x12"Display font. A hires name needs font_size. Scale-1 only.
bg_color[r, g, b]noneBackground fill behind the messages. Scale-1 only.
paddingint, px6Horizontal spacing after each line when scrolling.
update_intervalint, seconds21600 (6 hours)How often to poll the StatsAPI schedule feed for fresh promotions — see Data source.
demoboolfalseRender the fixed promo set instead of calling StatsAPI — see Try it in demo mode.
scheduletablenoneCore visibility window — only show this widget during set hours. See Scheduling.

Promotions come from MLB’s StatsAPI schedule feed — free and keyless. The widget refreshes every update_interval seconds (21600, or 6 hours, by default — often enough to keep the “Today” label honest after midnight) and shows the target date’s promos: today’s home game if there is one, else the next home game within lookahead_days that has matching promos. A doubleheader whose two games each carry a promo shows both — one card or crawl segment per game, matching the per-game data the API returns.

  • Nothing shows up at all — a blank panel. Most likely the widget block isn’t nested inside a [[playlist.section]] — a bare [[playlist.section.widget]] yields zero sections and a blank sign. Every snippet on this page shows the wrapper. Also rule out that the baseball plugin isn’t installed (see the install step above), which usually surfaces as unknown widget type 'baseball.promotions' at config-load.
  • It says “Next home game” instead of a promo. The next home game within lookahead_days has no promotions in the feed, or your team is on a road trip. Raise lookahead_days to reach further ahead, or check the team’s schedule — not every home game has a giveaway.
  • My filter is hiding everything. filter is a strict allow-list — only promos whose name contains one of its substrings show. Loosen or remove it; use highlight instead if you just want to emphasize some promos without dropping the rest.
  • A highlighted promo isn’t amber. highlight matches case-insensitive substrings of the promo name — check the substring actually appears in the feed’s wording (sponsor tails are stripped, so match on the promo name, not “presented by …”).

Haven’t tried it yet? Try it in demo mode above takes about two minutes, no key and no network. Implementation notes live in the baseball package README.

The baseball plugin ships four more widgets that share this data and design. Put your promos in a game-day rotation next to baseball.scores for the live game, baseball.standings for the division race, the family showpiece baseball.statcast — the day’s longest home run drawing its own trajectory arc — and baseball.attendance for last night’s crowd. It also brings the baseball.roll* rolling-ball sprite transition and the :baseball.ball: emoji.