Find cool shows and cultural events nearby, effortlessly. All highly social.
The event calendar is one of Musiquay's core platform pillars — alongside the scene graph and the services marketplace. It transforms Musiquay from a place where music lives into a place where the scene happens.
Every city has a music scene. Every scene has shows, gigs, festivals, listening parties, workshops, art openings, film screenings. Right now, finding out what's happening requires following a dozen Instagram accounts, checking five different ticketing platforms, and hoping someone in your group chat saw the poster. It's fragmented, platform-locked, and hostile to discovery.
Musiquay's calendar fixes this. Location-based. Social-first. Protocol-native. One place to find everything the scene is doing near you.
The calendar is not a separate system bolted onto the side. It is Nostr events on the same relay, using the same identities, the same social graph, the same protocol primitives as everything else in Musiquay.
This means:
Nostr already has a specification for calendar events — NIP-52 — and it maps remarkably well to what Musiquay needs. Reuse first.
NIP-52 provides:
| Event Kind | Purpose | Musiquay Usage |
|---|---|---|
| Kind 31922 | Date-based calendar events (all-day/multi-day) | Festivals, multi-day events, release dates |
| Kind 31923 | Time-based calendar events (specific start/end) | Shows, gigs, listening parties, workshops |
| Kind 31924 | Calendars (collections of events) | Venue calendars, promoter seasons, tour schedules |
| Kind 31925 | RSVPs | "I'm going", "Maybe", "Can't make it" |
Key NIP-52 features already built in:
g tag) for searchable physical positioning. This is what powers geo-radius discovery.p tags with pubkeys and roles. A show can tag the performing artists, the venue, the promoter, the sound engineer — anyone involved.accepted, declined, tentative) with availability indicators (free, busy).t tags for categorization (genre, event type, etc.).r tags for links to external resources (ticket pages, video calls, maps).The protocol already handles the hard parts. Musiquay's job is to build a great UI on top of it and extend where needed.
The primary interface: what's happening near me?
This isn't a cold listings page. It's social by design.
When a show sells out, it's not over.
Protocol gaps to settle. NIP-52 has no capacity field, so capacity is a Musiquay convention (["capacity", "<n>"] on the event), and there is no authoritative queue head: promotion is a creator action (a DM to the attendee at the head of the recomputed queue), not a protocol transition. Queue order is derived from joined_at ascending, tie-broken by d ascending; the position tag is informational. The exact flow is specified in PROTOCOL_FLOWS.md.
Early access for the community.
Access windows are access filters. A pre-sale tier is a kind 32217 membership set — d = presale:<event-address>:<tier> — and the checkout checks the buyer against the current window's filter. Because relays serve all signed events to anyone, the window is enforced at purchase time, not by concealing the listing.
Ticket representation is an open decision. Three options are laid out in PROTOCOL_FLOWS.md: a Cashu P2PK ticket (identity-bound, check-in burns the token at the mint, no double entry), a BDHKE blind-signed ticket (unlinkable but transferable and not identity-bound), or a NIP-59 wrapped venue-signed deed. It must be settled before the calendar pillar ships, because it is the only commerce flow with a fraud surface.
Building anticipation as a social experience.
The calendar isn't limited to gigs. The scene is broader than concerts.
If the scene cares about it, it belongs on the calendar. The t (hashtag) tags handle categorization without requiring a rigid taxonomy.
The core data model is NIP-52 with Musiquay-specific conventions for tag usage.
Time-based event (kind 31923) — typical show listing:
{
"kind": 31923,
"pubkey": "<venue or promoter pubkey>",
"content": "Description of the event, lineup details, etc.",
"tags": [
["d", "<unique-identifier>"],
["title", "Friday Night at Lux Frágil"],
["summary", "DJ sets from local selectors"],
["image", "https://blossom.musiquay.com/<hash>"],
["start", "1735851600"],
["end", "1735876800"],
["D", "20090"],
["start_tzid", "Europe/Lisbon"],
["location", "Lux Frágil, Av. Infante Dom Henrique, Lisboa"],
["g", "eyckch"],
["p", "<artist-1-pubkey>", "wss://relay.musiquay.com", "performer"],
["p", "<artist-2-pubkey>", "wss://relay.musiquay.com", "performer"],
["p", "<sound-engineer-pubkey>", "wss://relay.musiquay.com", "sound"],
["p", "<photographer-pubkey>", "wss://relay.musiquay.com", "photographer"],
["t", "electronic"],
["t", "dj"],
["price", "10", "EUR"],
["r", "https://tickets.example.com/event/123"]
]
}
D is required by NIP-52 on time-based events: floor(unix_seconds / 86400), repeated once per day the event covers. It is what makes date-window queries cheap without scanning start/end.
RSVP (kind 31925):
{
"kind": 31925,
"pubkey": "<attendee-pubkey>",
"content": "",
"tags": [
["a", "31923:<venue-pubkey>:<event-d-tag>", "wss://relay.musiquay.com"],
["d", "<unique-identifier>"],
["status", "accepted"],
["fb", "busy"]
]
}
Waitlist entry (kind 31925, tag convention):
{
"kind": 31925,
"pubkey": "<attendee-pubkey>",
"content": "",
"tags": [
["a", "31923:<venue-pubkey>:<event-d-tag>", "wss://relay.musiquay.com"],
["d", "<unique-identifier>"],
["status", "waitlist"],
["position", "14"],
["joined_at", "1735851600"]
]
}
Queue order is derived from joined_at (tie-broken by d tag); position is informational — clients recompute it from the full set of waitlist RSVPs.
Where NIP-52 doesn't cover Musiquay's needs, custom event kinds or tag conventions extend it. Following the reuse-first NIP strategy:
| Concept | Approach |
|---|---|
| Waitlist position | Tag convention on NIP-52 RSVP (kind 31925) — status set to waitlist, plus position and joined_at tags. The RSVP's unique d tag and timestamp provide queue ordering. |
| Ticket purchase | Cashu P2PK ticket or blind-signed ticket (open decision — see PROTOCOL_FLOWS.md); settled by Lightning or Cashu with the payment linked to the calendar event via a tag |
| Release countdown | Date-based calendar event (kind 31922) with a custom tag indicating it's a release drop |
| Pre-sale access | Tag convention on ticket events — filtered by follow lists or supporter status |
| Post-event content | Standard Nostr notes/media events that reference the calendar event via a or e tags |
| Event roster | Full participant record with scene police validation — see FEATURES_ROSTER.md |
| Setlists | Per-artist song lists linked to tracks, with featured artist tagging — see FEATURES_ROSTER.md |
The calendar doesn't exist in isolation. It is deeply woven into the scene graph documented in ARCHITECTURE.md.
p tags.A show is not just a listing. It's a node in the scene graph connecting venues, artists, crew, fans, service companies, and the content they create together. Before the show, it's a calendar event. After the show, it's a piece of the scene's permanent history.
The social calendar enables organic discovery that cold listings cannot:
post-punk rank higher.No algorithm. No promoted listings. Just the social graph doing what social graphs do — connecting people to what their community cares about.
All financial transactions use the existing Lightning payment infrastructure:
Musiquay takes zero cut on ticket sales. The payment infrastructure is there to serve the scene, not to extract from it.