Events API
Everything on events.xtech.dev is also available as JSON, as a calendar subscription, and as a card you can drop straight into your own website. No key, no signup, no rate-limit paperwork — just fetch it. Second Life has no events API of its own, so as far as we know this is the only one.
Start here
One request, no authentication:
curl https://events.xtech.dev/directory/live
Everything here is GET only, returns JSON, and sends
Access-Control-Allow-Origin: * — so a plain fetch() from a
browser on any origin works:
const r = await fetch('https://events.xtech.dev/directory/upcoming?hours=24');
const { events } = await r.json();
At is a Unix epoch
in seconds, UTC. Fields ending SLT are wall-clock strings in Second Life Time
(America/Los_Angeles), which is what a resident sees in their viewer. Use the
epoch for arithmetic, and the SLT string when you want to show what the venue would have
written on a poster.Getting your venue listed
Nothing appears here until a venue owner turns it on. In Manage Venue → Public listing there are two separate switches:
- List us publicly — your venue and its public events appear in the directory and in this API.
- Publish our images — separate, and it asks you to confirm you hold the rights to have your posters republished. You can be listed without it; your cards just use a plain coloured panel instead.
Performers have their own switch, under Settings → Second Life profile. If someone turns it on, their name is withheld everywhere on this surface — their night still appears, listed as Line-up TBC. A person's choice overrides the venue's, always.
Who's playing now
GET https://events.xtech.dev/directory/live
| Returns | |
|---|---|
acts[] | People clocked in right now —
name, job, since, endsAt,
spanDays, image, colour,
venue. |
venues[] | Every listed venue — live,
crowd, onNow[], accent, image,
logo, slurl, maturity. |
generatedAt | When we built this response. |
endsAt: null means the person is working but we have no booking to read an end
time from — show "on now" and no countdown; please don't guess a duration.
crowd: null means that venue's in-world server has gone quiet, so we don't
currently know. That is different from crowd: 0, which means it reported and
nobody is there. A confidently wrong number is worse than an honest dash.A name of null means the slot isn't confirmed or the
performer has opted out. The two are deliberately indistinguishable — please render
them identically, or the difference advertises the opt-out.
What's coming up
GET https://events.xtech.dev/directory/upcoming?hours=168&offset=0&limit=60
| Parameter | Default | Notes |
|---|---|---|
hours | 168 (7 days) | Clamped 1–336. |
offset | 0 | For paging. Results are ordered by start time, so page 2 continues exactly where page 1 stopped. |
limit | 60 | Clamped 1–60. |
Each event carries title, startsAt/endsAt,
startSLT/endSLT, spanDays, inProgress,
dj/dj2, hasPerformers, typeName,
typeSlug, styleName, typeColour,
styleColour, image, uncovered, recurring
and venue. The response also carries total and
truncated, so you can always tell whether you have everything.
inProgress ones to show as “on now”, sort those by
endsAt ascending rather than by start. A week-long fair started days ago, so
by start order it outranks a DJ set playing right this minute — and a few multi-day
events will hold the top of your list all week. Ending soonest puts what someone is about
to miss first. It is what events.xtech.dev itself does.inProgress: true means it has already started — show "on now", not a
start time in the past. spanDays > 0 is a multi-day run: show a date range
and never a minutes countdown, because the end time belongs to the final day.
hasPerformers: false is a type with no line-up at all — a store sale has
no DJ, so omit the performer line entirely rather than printing "TBC" on it.Filtering by type and style
Both rails take type and style, using the same slugs the
pages do:
GET /directory/live?type=music
GET /directory/upcoming?type=music&style=80s
GET /directory/types // the list, so you need not hardcode it
/directory/types returns every browsable type with its colour, the label
that type uses for its style axis (“Genre” under music, “Subject”
under a class), and its styles. It is derived from the live taxonomy, so a type added
tomorrow appears without anyone redeploying — which is why type= takes
a slug rather than a numeric id.
?type=musicc quietly returning nothing looks exactly like a quiet week, and
that typo would ship. You get {"error": "Unknown type \"musicc\"…"} instead.
A style without a type is also a 400 — styles belong to a
type, and two types can have a style of the same name.Subscribe in a calendar app
https://events.xtech.dev/directory.ics // every listed venue, 30 days
https://events.xtech.dev/directory.ics?days=90 // up to 90
https://events.xtech.dev/music.ics // or just one type
https://events.xtech.dev/v/your-venue.ics // or just one venue
A venue's own feed is also what its page offers, and what a browser picks up if it offers to subscribe while you are looking at that venue.
Recurring nights are expanded to real dates for the whole range you ask for, so
?days=90 genuinely contains ninety days.
Add it to Google Calendar, Apple Calendar or Outlook as a subscribed calendar and it keeps itself up to date. Event IDs are stable, so edits arrive as edits rather than piling up as duplicates, and times are published in UTC so your calendar shows them correctly in your own zone.
Individual venues also publish their own calendar from their board link — see Manage Venue → In-world boards.
Put a live card on your own site
Paste this anywhere you can put HTML. Your board token is on Manage Venue → In-world boards — use the public one.
<iframe src="https://events.xtech.dev/w/YOUR_PUBLIC_TOKEN"
width="320" height="240" frameborder="0"
title="What is on at our venue"></iframe>
An iframe rather than a script tag, on purpose: nothing of ours runs on your page,
nothing collides with your CSS, and it works on Wix, Squarespace and hosted WordPress, all
of which strip <script>.
| Option | Values | What it does |
|---|---|---|
rail | both (default), live,
next | Who's on, what's next, or both. |
limit | 1–10, default 3 | How many upcoming events to list. |
compact | 1 | A single line, for a narrow sidebar. |
theme | auto (default), light,
dark | auto follows your visitor's system setting.
Set it explicitly if your site is always one or the other. |
Your accent colour comes through automatically from Venue theme — the same colours as your in-world boards. The card sizes itself sensibly and scrolls internally, so the snippet above really is all you need. If you would rather it resize to fit exactly, it also broadcasts its height:
<script>
addEventListener('message', e => {
if (e.data && e.data.xtechHeight)
document.querySelector('iframe[src*="events.xtech.dev"]').height = e.data.xtechHeight;
});
</script>
A badge for forums and Marketplace
Forum signatures, blog sidebars and Marketplace listings usually allow images but ban iframes and JavaScript. A badge is an ordinary image:
<img src="https://events.xtech.dev/w/YOUR_PUBLIC_TOKEN/badge.svg"
alt="What is on at our venue">
320×56, your accent colour, a red dot when you're live, and either whoever's playing or what's next. It refreshes about once a minute.
If you're a DJ, host or live artist
The card above belongs to a venue. You get your own, and it follows you across every venue you work at — so one snippet on your website, blog or profile stays right without you touching it. Turn it on under Settings → Your live card, then paste:
<iframe src="https://events.xtech.dev/p/YOUR_CARD_TOKEN"
width="320" height="220" frameborder="0"
title="Where I am playing"></iframe>
There's a badge too, for forum signatures and Marketplace listings:
<img src="https://events.xtech.dev/p/YOUR_CARD_TOKEN/badge.svg" alt="Where I am playing">
It shows your next few bookings with the venue and time, a red dot and the venue name
while you're actually on, and your profile picture. ?limit= and
?theme= work the same as the venue card.
You also get your own calendar feed — add it to Google Calendar, Apple Calendar or Outlook as a subscribed calendar and your own dates keep themselves up to date. Share it and anyone following you can subscribe to the same thing:
https://events.xtech.dev/p/YOUR_CARD_TOKEN/calendar.ics
It's the same token and the same lifecycle: replacing your link changes the calendar with it, and turning the card off turns the calendar off too.
Covers are handled properly: a night you hand over drops off your card, and one you pick up appears. If you've turned off Show my name in public listings, that still holds everywhere else — the directory and venue cards keep showing you as “line-up TBC”. Your own card names you, because you made it.
Browsable pages
If you would rather link than integrate, every event type has its own page:
https://events.xtech.dev/ // everything
https://events.xtech.dev/music // DJ sets and live artists together
https://events.xtech.dev/quiz // and one per type: sale, shopping, hunt, class...
The current list is always in sitemap.xml.
Share links
Every venue and every night has its own address, so you can paste one anywhere and it renders as a card with the poster, the title and the details — in Discord, on a forum, in a blog post:
https://events.xtech.dev/v/your-venue // your venue
https://events.xtech.dev/e/8000-2026-08-14/blues-night // one night
https://events.xtech.dev/p/YOUR_CARD_TOKEN // a performer
Event links keep working. The id and the date decide which night it is; the words
after them are decorative, so renaming the event redirects the old link to the new one
rather than breaking it. Every event in the JSON feeds carries its own
shareUrl, so you never have to build one yourself.
Limits and fair use
- No key, no quota. There is a per-IP rate limit, set generously enough that normal use never meets it.
- Responses are cached for about 30 seconds (5 minutes for the calendar). Polling faster returns the same bytes — once a minute is plenty for a "live now" display.
- Cache what you fetch if you're serving it to many visitors, rather than calling us per page view.
- Please link back to events.xtech.dev if you republish listings. Not a legal condition — just what keeps this worth running.
What you won't find
- No avatar UUIDs, anywhere, in any response. Names are stage names wherever a performer has set one.
- No private events and no staff notices. This surface only ever sees what a venue marked public.
- No visitor names.
crowdis a number and nothing more. - Only XTech venues. Linden Lab publishes no grid-wide events feed, so no directory can honestly claim full coverage — ours included.
Building something with this? We'd like to hear about it — and if you need a field we don't return yet, ask.