Publishing a music event #
bun event -- <handle|did> writes two records into the publisher's repo:
- a
community.lexicon.calendar.eventwith the name, dates and venue, the same record any calendar app can read - an
app.rocksky.event.musicthat points at it and adds what is specific to music: the kind of event, the genre and the lineup
Jetstream indexes the pair, links every billed artist to their Rocksky
page, and the event shows up in app.rocksky.event.getEvents, on each
artist's app.rocksky.artist.getArtistEvents, and to anyone who RSVPs
with a community.lexicon.calendar.rsvp. A calendar event without the
music record is left alone, so other events in the same repo never show
up as concerts.
Prerequisites #
apps/apiconfigured (database and OAuth client): the script writes through the API's own agent- The publisher has signed in to Rocksky at least once, so an OAuth session exists for their DID
- The publisher's DID is in the appview's
EVENT_PUBLISHER_DIDS(by defaulttsiry-sandratraina.comandrocksky.app), or Jetstream ignores the records
Example #
The show to list:
Concert
Slipknot
Wembley Stadium
London, United Kingdom
Sat, Jul 3, 2027 · 7:00 PM
Run the script from apps/api with the publisher's handle or DID:
cd apps/api
bun event -- rocksky.app
It asks for every field in turn. Dates are ISO-8601 with an offset, so
7:00 PM in London in July (BST) is 2027-07-03T19:00:00+01:00. Leave an
optional answer empty to skip it.
? Event name › Slipknot at Wembley Stadium
? Description (optional) › Slipknot headline Wembley Stadium.
? Starts at (ISO-8601) › 2027-07-03T19:00:00+01:00
? Ends at (ISO-8601, optional) › 2027-07-03T23:00:00+01:00
? Attendance mode › In person
? Status › Scheduled
? Venue name › Wembley Stadium
? Country (ISO 3166 code, e.g. FR) › GB
? City (optional) › London
? Region / state (optional) › England
? Street address (optional) › London HA9 0WS
? Postal code (optional) › HA9 0WS
? Latitude (optional) › 51.5560
? Longitude (optional) › -0.2796
? Event website (optional) › https://www.wembleystadium.com/events
? Kind of event › Concert
? Main genre (optional) › Metal
? Tags, comma-separated (optional) › nu metal, stadium
? Artist name (headliner) › Slipknot
ℹ Linked to at://did:plc:…/app.rocksky.artist/…
? Artist AT-URI (optional) › at://did:plc:…/app.rocksky.artist/…
? Role › Headliner
? Set time (ISO-8601, optional) ›
? MusicBrainz artist id (optional) › a466c2a2-6517-42fb-a160-1087c3bafd9f
? Next artist (leave empty to finish) ›
? Ticketmaster event id (optional) › 1A00ZK9GDF1234
? Songkick event id (optional) ›
? Bandsintown event id (optional) ›
? Resident Advisor event id (optional) ›
? setlist.fm event id (optional) ›
? DICE event id (optional) ›
? Eventbrite event id (optional) ›
? Tickets URL (optional) › https://www.ticketmaster.co.uk/slipknot-tickets
? Poster image URL (optional) › https://media.bandsintown.com/900x900/26140291.webp
When a billed name matches an artist Rocksky already knows, the script fills in the artist's AT-URI, which is what links the event to that artist's page. For a festival, each artist is also asked for a stage.
A poster URL is used twice: it stays on the music record as imageUrl,
and the image is downloaded and uploaded to the publisher's repo as a
blob in the calendar record's media array (role thumbnail, with its
aspect ratio), the shape Smoke Signal and the other calendar apps read.
The API serves it as media[] and falls back to it for imageUrl.
Both records are then printed as JSON for a last look:
ℹ Creating event with the following details:
{
"$type": "community.lexicon.calendar.event",
"name": "Slipknot at Wembley Stadium",
"startsAt": "2027-07-03T18:00:00.000Z",
"endsAt": "2027-07-03T22:00:00.000Z",
"mode": "community.lexicon.calendar.event#inperson",
"status": "community.lexicon.calendar.event#scheduled",
"locations": [
{
"$type": "community.lexicon.location.address",
"name": "Wembley Stadium",
"country": "GB",
"locality": "London",
...
}
],
...
}
{
"$type": "app.rocksky.event.music",
"kind": "concert",
"genre": "Metal",
"artists": [{ "name": "Slipknot", "role": "headliner", ... }],
"externalIds": { "ticketmaster": "1A00ZK9GDF1234" },
"ticketsUrl": "https://www.ticketmaster.co.uk/slipknot-tickets",
"imageUrl": "https://media.bandsintown.com/900x900/26140291.webp",
...
}
? Do you want to proceed? › yes
ℹ Downloading poster https://media.bandsintown.com/900x900/26140291.webp...
ℹ Uploaded poster: 900x900 image/webp, 61 KiB
ℹ Writing community.lexicon.calendar.event record...
ℹ Record created at: at://did:plc:…/community.lexicon.calendar.event/3m2…
ℹ Writing app.rocksky.event.music record...
✔ Event created successfully!
ℹ Record created at: at://did:plc:…/app.rocksky.event.music/3m2…
Within a few seconds Jetstream has indexed it:
curl "https://api.rocksky.app/xrpc/app.rocksky.event.getEvents?genre=metal"
If Slipknot already has an event on that day, the script says so before publishing. Publishing anyway is allowed, but the appview folds the new records onto the existing event as a duplicate: only the first one is listed, and RSVPs to either count together.
Changing or removing an event #
Records are the source of truth and Jetstream mirrors every change:
- Edit the calendar record (a new date, a cancelled status, another venue) and the event updates. Rocksky never rewrites your records.
- Edit the music record to change the lineup, genre or external ids.
- Delete the
app.rocksky.event.musicrecord to take the event off Rocksky while keeping the calendar event for other apps. Deleting the calendar record removes it as well.