A More Civilized API

TDLR: I built an API that returns quotes from Star Wars: The Clone Wars as either JSON or RSS. You can find it at wisdom.ferrell.rocks.
Despite my best efforts, I love a good holiday programming project. Mastowatch, arguably the biggest solo development undertaking of my life, started as a holiday project. And this week, Thanksgiving 2025 was no exception!
Friendship Shows Us Who We Really Are (04x14)
A friend recommended the Star Wars podcast A More Civilized Age to me a year or so ago and it has completely consumed my podcast listening time. I listened to their Star Wars Rebels coverage when we were isolating after Ripley's transplant back in January. I've been following their KOTOR 2 playthrough (including the actual footage of gameplay on their Youtube channel) this fall and with that now over, I've jumped back to 2021 and started listening to their Star Wars Clone Wars coverage.

Naturally, I was listening to their coverage of Saleucami in season 2 when I posted on Mastodon about how useful I've found the Tapestry connector for Wordpress that I built a few weeks ago. It was then that these two flavors combined in my brain like chocolate and peanut butter and gave me an idea...

Could I somehow funnel the opening text from each episode of The Clone Wars into Tapestry?
If There is No Path Before You, Create Your Own (07x05)
If you're unfamilar, (almost) every episode The Clone Wars opens with a kind of wisdom or quote that usually sums up the moral lesson of the episode.

I say "almost" because the final four episodes of the series had no opening quotes, but the other 129 all do.
Back to the idea though!
I briefly toyed with making this an iOS app with a widget to show the quotes on your Home Screen but I struggle to keep my two existing apps maintained, so the last thing that I need is another one. Plus, Tapestry supports RSS out of the box, so I wouldn't even need to build a connector if I could get the quotes into an RSS feed.
This leaves a few hurdles to overcome:
- Despite all appearances otherwise, I do not have this list of quotes memorized so I need a complete list of them with relevant episode data (season, title, etc.)
- Tapestry, and RSS generally, really expect entries to be dated. None of these quotes have relevent dates associated with them.
- While getting these into Tapestry is the main goal, having the widget would be nice. I want to serve these up in such a way that someone else could do that if the mood struck them.
The Search for Truth Begins with Belief (07x02)
First and foremost, a blog post on sagespeculation.com from 2017 was the original source of all this data. Huge shout to whoever runs that blog, that post made the rest of this all possible.
Their list is structured very consistently, so I was able to literally copy the source into a .html file and use it as a starting point.
<p>01×02 – Rising Malevolence: <em>Belief is not a matter of choice, but of conviction.</em></p>I've been toying with learning more Python recently, since they basically told the Trump administration to eat shit, and this was a perfect opporunity! BeautifulSoup made quick work of the HTML, leaving me with a JSON-formatted list of all the data.
Now how to serve up this JSON?
Choose What is Right, Not What is Easy (02x18)
If I'd wanted to just serve up a static JSON or RSS file, I could have hosted it on this site. That's super boring though! What if I wanted to filter by season, or manipulate the dates to tweak when and how they were displayed in Tapestry? I needed some very basic compute platform to take this JSON, transform it and then return it.
I've had a ton of success with Cloudflare Workers, their serverless compute product, so that was the obvious choice. Workers power all of the server-side (serverless-side?) features of both Mastowatch and Audracity and they've been rock solid since day one.
So a Worker it is!
With some debugging and help, I had this Worker...working...in like 15 minutes. It was super easy to add options for filtering, date controls and even serve up multiple formats.
A Failure in Planning is a Plan for Failure (03x08)
The API is live and free for anyone to use!
The root of the API is wisdom.ferrell.rocks and the most basic call just returns the entire list of quotes:
https://wisdom.ferrell.rocks/api/quotesThe response is an array of episode objects, each with their respective season, episode_number, episode_title and quote:
{
"index":0,
"season":"01",
"episode_number":"01",
"episode_title":"Ambush",
"quote":"Great leaders inspire greatness in others."
}To limit the response to a specific season, just add the season number to the path:
https://wisdom.ferrell.rocks/api/quotes/05Similarly, you can get a single episode by passing that number after the season number:
https://wisdom.ferrell.rocks/api/quotes/05/05If you pass a season of 0 to the API, it will return a random season:
https://wisdom.ferrell.rocks/api/quotes/0Similarly, if you pass in both a season and episode of 0, you will get back a random episode:
https://wisdom.ferrell.rocks/api/quotes/0/0But naturally, RSS is where the API really shines.
You can pass the format parameter with a value of rss to get back the list of quotes as an RSS feed:
https://wisdom.ferrell.rocks/api/quotes?format=rssBy default, the RSS feed begins on the first day of the current year and spaces the quotes out so that they fill the entire year, ending on or near New Year's Eve.
But what if it is, as it is today, November?
You can specify a start date!
By passing in a start_date parameter, formatted as YYYY-MM-DD, you can adjust when the RSS feed begins:
https://wisdom.ferrell.rocks/api/quotes?format=rss&start_date=2025-10-19Again, this will space the posts so that they are delivered over the course of roughly one year.
What if one year feels too fast though, and you want to savor the flavor? You can use the frequency parameter and pass in a value of weekly, which will deliver the quotes weekly for about 133 weeks:
https://wisdom.ferrell.rocks/api/quotes?format=rss&start_date=2025-10-19&frequency=weeklyIn the actual RSS response, it's what you'd expect. The season, episode and episode title are the title of the entry and the description is the quote, plus some administrative niceties and future-proofing:
<item>
<title>S01E01: Ambush</title>
<description>Great leaders inspire greatness in others.</description>
<pubDate>Wed, 01 Jan 2025 09:00:00 GMT</pubDate>
<dc:creator><![CDATA[Star Wars: The Clone Wars]]></dc:creator>
<guid isPermaLink="false">urn:quote:01-01</guid>
<link>https://wisdom.ferrell.rocks/api/quotes/01/01?format=html</link>
</item>That's cool and all, but what if you want the quote first and then the season and episode details in the description field? I thought of that!
https://wisdom.ferrell.rocks/api/quotes?format=rss&start_date=2025-10-19&frequency=weekly&content_focus=quoteYou can pass in the content_focus parameter with the value quote to swap those, so the quote is the title and the episode details move to the description:
<item>
<title>Great leaders inspire greatness in others.</title>
<description>S01E01: Ambush</description>
<pubDate>Wed, 01 Jan 2025 09:00:00 GMT</pubDate>
<dc:creator><![CDATA[Star Wars: The Clone Wars]]></dc:creator>
<guid isPermaLink="false">urn:quote:01-01</guid>
<link>https://wisdom.ferrell.rocks/api/quotes/01/01?format=html</link>
</item>In my testing, support for this kind of "fake" RSS feed can be a little hit and miss with various clients but most issues come down to posts that are dated for the future. To get around this, there is an exclude_future parameter that will hide any quote that is not scheduled for display yet:
https://wisdom.ferrell.rocks/api/quotes?format=rss&exclude_future=trueThe Future Has Many Paths – Choose Wisely (03x07)
I might go back one day and add the ability to get back stylized title cards as actual images. For now though, it's just the plain text. We'll see!
One Must Let Go of the Past to Hold On To the Future (04x19)
And that's it! You can start using the API right now. My only ask is that if you build something cool with it, you let me know via my Mastodon account.

May the Force be with you!