A community-built weekly schedule for X audio Spaces, with automatic local timezone conversion. Hosted at spaces.martyearthy.com Β· Created by @MartyEarthy Β· MIT licensed β Tesla, X, and friends are welcome to reuse it.
Each row shows a day's host. The time on the left (in blue) is your local time; hover or tap the small β info icon beside it to see the host's original scheduled time. If your local day differs from the scheduled day (e.g. you're viewing a Monday Space from a timezone where it falls on Tuesday), a small note appears next to the day name.
A banner at the top of the page highlights any live or upcoming Space.
$TSLA and Tesla to surface Spaces hosted by untracked accounts when our tracked hosts are guests. Search runs every 5 minutes; IDs are re-verified every refresh so rooms drop off as soon as they end.started_at, updated client-side every 30s.x.com/i/spaces/{id}.What the X API cannot tell us: who is just listening to a Space (no public endpoint exists for that). The Spaces Dashboard icon on each chip links to a third-party tool that surfaces that info via scraping.
Some days have more than one host β they appear stacked in a single card, separated by a divider. Notes on individual hosts (like "may start late") are shown in small text below the time.
Toggle the Spaces Dashboard Links switch in the header to reveal chart icons next to each host. These link to Spaces Dashboard, a third-party tool for browsing Space recordings and statistics. The gold money-sign beside that switch is a joke tip jar.
Between the weekly schedule and Awesome Hosts is a Community Resources & Sites strip. Order is shuffled on each page load (same idea as Awesome Hosts) so JSON order is not a ranking. Current entries: @Smokehbear β SmokehBear's Den, @dallastsladavid β Texas AV Tracker, @wholemars β FSD Database. Add more in schedule.json communityResources[].
The in-page suggestion form is temporarily hidden while it is reworked. To propose a host or slot, message @MartyEarthy on X.
This project is MIT licensed. Tesla, X, and anyone else in the Spaces community can copy it, fork it, ship it, or build on it. Keep the copyright notice. That's the whole deal.
The grant covers this site's own code, markup, styles, and original assets. It does not cover X API data, host avatars, or recordings of other people's Spaces. Those stay with their owners. Third-party fonts and icons keep their own licenses. API keys and push secrets are never included; bring your own.
Download the source zip. It is rebuilt on every deploy of this site, so it is the current code, not the old static snapshot. Our X API keys are not in it. You use your own bearer token from the X Developer Portal, and you pay X for Spaces/user reads. Cloudflare Pages/KV/D1 usually fit the free tier for a small fork.
Want only the weekly grid, no live badges? Skip the API and open index.html. Cards stay dark, and X charges nothing.
Want live status? Unzip, npm install, copy .dev.vars.example to .dev.vars with your bearer, then bash scripts/fork-setup.sh to create your own KV and D1. Step-by-step: FORK.md.
Open schedule.json. It has three top-level arrays:
One object per recurring slot. Multiple entries with the same dayIndex create a grouped card.
| Field | Type | Required | Description |
|---|---|---|---|
day | string | yes | "Monday" β¦ "Sunday" |
dayIndex | number | yes | JS Date.getDay(): Sun=0, Mon=1 β¦ Sat=6 |
host | string | yes | X handle without @ |
displayName | string | no | Human name (falls back to host) |
spaceTitle | string | no | Space title shown in italics |
time | string|null | yes | 24-hr "HH:MM", or null for variable times |
timezone | string | yes | IANA timezone, e.g. "America/Chicago" |
displayTime | string | yes | Human label, e.g. "11:00 AM CT" β cosmetic only |
dashboardUrl | string | no | Spaces Dashboard profile URL |
subscribersOnly | boolean | no | true renders the pink Sub badge |
tentative | boolean | no | true shows "Maybe?" in the live window |
note | string | no | Short note below the time; @mentions are auto-linked |
reminderPostUrl | string | no | Optional link to the host's reminder post on X (manual β not available from the Spaces API) |
Optional temporary panels (e.g. a welcome strip). Hosts are tracked for live/co-host/speak detection but are not added to Awesome Hosts chips. Set enabled to false (or empty the array) to take down. Visitors can Hide the panel; that preference stays in the browser only.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Stable id β used for hide preference |
title / badge / intro | string | no | Panel copy |
enabled | boolean | no | Default true. false = no UI and no X tracking for these hosts |
defaultVisible | boolean | no | First-visit show/hide before the visitor toggles |
hosts[] | array | no | Same shape as additionalHosts (handle, optional dashboardUrl) |
scheduled[] | array | no | Optional mini-schedule (day, displayTime, host, spaceTitle) |
links[] | array | no | label + url (e.g. @NICKIMINAJ profile β not API-tracked) |
| Field | Type | Required | Description |
|---|---|---|---|
handle | string | yes | X handle without @ |
dashboardUrl | string | no | Spaces Dashboard profile URL |
Optional top-level boolean (default true if omitted). Set to false to stop querying the X API for handles listed only under additionalHosts (saves User Reads; chips still show from this file, without live API data). Cloudflare env FETCH_ADDITIONAL_HOSTS_FROM_X_API=false on Pages and Worker overrides this without editing JSON. Details: notes.md (βCost toggleβ).
Optional strip between the schedule and Awesome Hosts. Empty array (or omit) hides the section. Avatars are local files, not the X API. Display order is shuffled once per page load.
| Field | Type | Required | Description |
|---|---|---|---|
url | string | yes | Destination (opens in a new tab) |
label | string | no | Name under the pfp (falls back to displayName β handle) |
handle | string | no | X handle without @, shown muted under the label |
avatar | string | no | Local image path, e.g. avatars/smokehbear.jpg |
title | string | no | Hover / accessibility title |
description | string | no | Short blurb under the handle (turns the pill into a compact card) |
displayName | string | no | Label fallback |
Drives header pills next to the logo. Entries with external: true use accent styling and a globe icon (third-party directory links); omit it for red broadcast-style pills pointing at X.
| Field | Type | Required | Description |
|---|---|---|---|
handle | string | no | X handle without @ (omit for non-X external links) |
displayName | string | no | Label fallback when label isn't set |
label | string | no | Button label (falls back to displayName β handle) |
url | string | yes | Destination URL. Use x.com/{handle}/live for always-current live tab |
external | boolean | no | true renders the accent directory pill (globe icon, no red pulse) |
note | string | no | Maintainer comment; ignored by UI |
After editing schedule.json, run npm run deploy to publish both the Pages Function and Worker in lockstep. See notes.md for the full operational runbook.