Every public Hack Club event, as JSON, free to use. No key needed, and you can call it from a browser on any site.
Try it
GET /api/v1/events
Upcoming events, soonest first, 50 at a time. Options, all optional:
when – upcoming (the default), past (newest first) or alltags – only events with any of these tags, comma-separated, like ama,workshopfeatured – true for the featured section of the home page, false for community eventsama – true for AMAs onlylanguage – a language code, like en or esfrom, to – only events starting in this range, like 2026-10-01limit – how many per page, up to 200page – which page, starting at 1{
"version": "v1",
"page": 1,
"pages": 3,
"total": 112,
"events": [ … ]
}
GET /api/v1/events/{id or slug}
The slug is the end of the event page's address, so /e/code-in-the-dark is /api/v1/events/code-in-the-dark.
{ "version": "v1", "event": { … } }
GET /api/v1/tags
Every tag in use, most used first: { "version": "v1", "tags": [{ "tag": "ama", "count": 42 }] }
{
"id": "8a20db4e-35e8-47a3-a075-d392173a86d9",
"slug": "code-in-the-dark",
"url": "https://events.hackclub.com/e/code-in-the-dark/",
"title": "Code in the Dark",
"description": "On a live call, we're going to…",
"start": "2026-10-09T17:00:00.000Z",
"end": "2026-10-09T18:00:00.000Z",
"status": "upcoming",
"kind": "workshop",
"tags": ["workshop", "beginner-friendly"],
"featured": true,
"language": "en",
"host": {
"name": "ada",
"avatar": "https://…",
"url": "https://events.hackclub.com/hosts/U0ADA12345"
},
"location": { "label": "#code-in-the-dark", "url": "https://hackclub.slack.com/…" },
"rsvps": 24,
"rsvpUrl": null,
"image": "https://events.hackclub.com/api/og/?…",
"youtube": null,
"ama": false,
"seriesId": null
}
description is Markdown.host.name is the host's Slack display name, or their Slack ID if they haven't set one.status is upcoming, live or ended. Cancelled events are left out.rsvps counts people who RSVPed here. rsvpUrl is set when the organizer collects RSVPs somewhere else instead.location is null when the event has no place set yet.image is the event's link preview image, 1200 × 630.seriesId is shared by every date of a repeating event.GET /api/calendar.ics
Every upcoming event as a calendar you can subscribe to in Google Calendar, Apple Calendar or Outlook. Add ?tags=ama to only get some.
Errors come back with a matching HTTP status and a body like this:
{ "error": { "code": "bad_date", "message": "`from` and `to` have to be dates, like 2026-10-01." } }
Responses can be cached for a minute. Please don't poll more often than that.
These still work, so nothing built on them breaks, but new code should use /api/v1. They return everything in one go, in the older format below, and take ?tags=.
/api/events/upcoming – upcoming events/api/events/upcoming-monthly – upcoming, grouped by month/api/events/all – every event/api/events/all-monthly – every event, grouped by month/api/amas – AMAs; add ?upcoming=true for only upcoming ones{
"id": "8a20db4e-35e8-47a3-a075-d392173a86d9",
"slug": "code-in-the-dark",
"title": "Code in the Dark",
"desc": "On a live call, we're going to…",
"leader": "ada",
"cal": "https://www.google.com/calendar/render?action=TEMPLATE&…",
"start": "2026-10-09T17:00:00.000Z",
"end": "2026-10-09T18:00:00.000Z",
"youtube": null,
"ama": false,
"amaId": "",
"amaAvatar": "",
"avatar": "https://…",
"tags": ["workshop"],
"featured": true
}