# itch.io Game Jam Calendar: .ics, Alerts, No Login (`quiet-robots/itch-io-game-jam-calendar`) Actor

Get the upcoming and running game jams on itch.io as data: title, link, start, end, voting end, length, status and number joined. Also writes a calendar file (.ics) and a ready-to-paste digest, and can post only the new jams to your Discord. No login or API key.

- **URL**: https://apify.com/quiet-robots/itch-io-game-jam-calendar.md
- **Developed by:** [Quiet Robots](https://apify.com/quiet-robots) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 jams

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### 🎮 What does itch.io Game Jam Calendar do?

It reads the [game jam calendar on itch.io](https://itch.io/jams) and hands it to you as data:
every upcoming and running jam with its title, link, start, deadline, end of voting, length,
status and number of people joined. itch.io shows this calendar on a page but offers no export,
feed or calendar link for it.

- **Data, a calendar file and a digest in one run:** rows for spreadsheets and automations, an
  `.ics` file for Google Calendar or Outlook, and a short text ready to paste into a newsletter
  or a Discord post.
- **New-jam alerts:** put it on a schedule with "only new" switched on and each run returns just
  the jams that appeared since the last one, optionally posted to your own Discord channel.
- **Filters and sorting built in:** starting in the next N days, running now, minimum joined,
  featured only, words in the title, length, top N by any column.
- **No login, no API key, no proxy.** One request to itch.io per run.
- **$0.01 per run plus $2 per 1,000 jams.** A run that finds nothing new costs one cent.

> Press **Start** with the example input to see it work. That run returns up to 100 jams and
> costs about $0.21, well inside the free plan's monthly credit.

### 🚀 How to get itch.io game jams as data

1. Press **Start**. The example input returns upcoming and running jams that at least 10 people
   have joined, soonest first.
2. Open the **Output** tab: the jams as a table, plus links to the **calendar file** and the
   **digest**.
3. Download the rows as JSON, CSV or Excel, or read them through the
   [Apify API](https://docs.apify.com/api/v2).

The digest of a run looks like this:

```markdown
**Game jams on itch.io**: 2 jams, 2026-10-12 (times in Europe/Warsaw)

**Starting soon**
- [SCREAM JAM 2026](https://itch.io/jam/scream-jam-2026): starts Sat 17 Oct, 00:00, runs 7 days, 916 joined

**In voting**
- [Mini Jam 221: Autumn](https://itch.io/jam/mini-jam-221-autumn): voting ends Fri 16 Oct, 06:00, 1,273 joined
```

### 💡 What you can use the game jam data for

- **Discord servers and bots:** post a weekly "jams starting this week" list, or an alert
  whenever a new jam shows up, without keeping a scraper alive.
- **Newsletters and blogs:** paste the digest, or build your own layout from the rows.
- **Asset sellers, tool makers and sponsors:** find the big jams early (sort by number joined)
  and the ones for your engine or genre (title filter).
- **Your own calendar:** import the `.ics` file and see the jams next to everything else.
- **Tracking:** run it daily and keep the rows to see how sign-ups for a jam grow.

### 📥 Input

Every field is optional.

| Field | What it does |
|---|---|
| **Which jams** | Upcoming, running now, in voting, finished. Default: upcoming and running. |
| **Starting within** | Only jams that start in the next N days. |
| **Minimum joined** | Only jams that at least this many people have joined. |
| **Featured jams only** | Only the jams itch.io features at the top of its calendar. |
| **Title contains / does not contain** | Words or phrases, any capitalisation: `godot`, `horror`, `pixel`. |
| **Shortest / longest length** | In days; decimals work (0.5 is 12 hours). |
| **Sort by, direction** | What happens next (default), start, deadline, end of voting, length or number joined; ascending or descending. |
| **Maximum jams** | Keep only the top N after sorting. Also your price cap. |
| **Time zone** | For the local-time columns and the digest, e.g. `Europe/Warsaw`. |
| **Only jams new since the last run** | Return a jam once, then never again. For scheduled alerts. |
| **Memory name** | Separate memories for alerts with different filters. |
| **Discord webhook URL** | Posts the digest to your own Discord channel. |

The ten biggest jams starting this week, with times for New York:

```json
{
    "statuses": ["upcoming"],
    "startsWithinDays": 7,
    "sortBy": "joined",
    "sortDirection": "desc",
    "maxItems": 10,
    "timeZone": "America/New_York"
}
```

### 📤 Output

One row per jam:

```json
{
    "id": 419594,
    "title": "SCREAM JAM 2026",
    "url": "https://itch.io/jam/scream-jam-2026",
    "status": "upcoming",
    "startsAt": "2026-10-16T22:00:00Z",
    "endsAt": "2026-10-23T22:00:00Z",
    "votingEndsAt": "2026-10-30T22:00:00Z",
    "startsAtLocal": "2026-10-17 00:00",
    "endsAtLocal": "2026-10-24 00:00",
    "votingEndsAtLocal": "2026-10-30 23:00",
    "timeZone": "Europe/Warsaw",
    "lengthDays": 7,
    "lengthHours": 168,
    "daysUntilStart": 4.5,
    "daysLeft": null,
    "hasVoting": true,
    "votingDays": 7,
    "joined": 916,
    "featured": false,
    "checkedAt": "2026-10-12T09:41:18Z"
}
```

| Field | Meaning |
|---|---|
| `id` | itch.io's number for the jam. Stays the same if the jam is renamed. |
| `status` | `upcoming`, `running` (open for entries), `voting` (closed, being rated) or `finished`. |
| `startsAt`, `endsAt`, `votingEndsAt` | Start, submission deadline and end of voting, in UTC. `votingEndsAt` is null for jams without voting. |
| `…Local`, `timeZone` | The same three times in the time zone you chose, as `YYYY-MM-DD HH:MM`. |
| `lengthDays`, `lengthHours` | From start to deadline. |
| `daysUntilStart` | For upcoming jams. |
| `daysLeft` | Until the deadline for running jams; until the end of voting for jams in voting. |
| `hasVoting`, `votingDays` | Whether there is a voting period, and how long it is. |
| `joined` | People who have joined the jam so far. |
| `featured` | True for the jams itch.io puts at the top of its calendar. |

Two files are saved next to the rows, both linked from the run's Output tab:

- **`calendar.ics`**: one event per jam, from start to deadline, with the link and the end of
  voting in the description.
- **`digest.md`**: the text shown above, grouped into starting soon, running now, in voting and
  just finished.

### 🔔 How to get alerts for new game jams

1. Set your filters, switch on **Only jams new since the last run**, and save the input as a
   [task](https://docs.apify.com/platform/actors/running/tasks).
2. Put the task on a [schedule](https://docs.apify.com/platform/schedules), for example daily.
3. Optional: paste a **Discord webhook URL** and each run posts the new jams to that channel.
   In Discord: channel settings > Integrations > Webhooks > New Webhook > Copy Webhook URL.

The first run returns everything that matches; every later run returns only what was added
since. A run with nothing new returns no rows, posts nothing and costs $0.01.

> Running several alerts with different filters? Give each its own **Memory name**, otherwise
> a jam returned by one alert counts as already seen by the others.

In Discord, times appear in each reader's own time zone and no one is pinged, whatever a jam's
title contains. A post holds about 70 jams at most (five Discord messages); the rest are counted in a closing
line.

### 📅 How to add itch.io game jams to Google Calendar or Outlook

Download `calendar.ics` from the run's Output tab and import it:

- **Google Calendar:** Settings > Import & export > Import.
- **Outlook:** Add calendar > Upload from file.
- **Apple Calendar:** File > Import.

Each jam keeps the same event ID in every run, so calendar apps that match events by ID update
them when you import a newer file.

For a calendar that refreshes itself, schedule a task and subscribe your calendar app to the
last run's file ("From URL" in Google Calendar). Keep the link private: it contains your token.

```text
https://api.apify.com/v2/actor-tasks/YOUR_TASK_ID/runs/last/key-value-store/records/calendar.ics?status=SUCCEEDED&token=YOUR_TOKEN
```

Leave "only new" off for that task, so the file always holds the whole calendar.

### 💰 Pricing

You pay for each run and for each jam it returns. Jams removed by your filters, or by "only
new", cost nothing.

| Your Apify plan's discount tier | Calendar check (per run) | Per 1,000 jams returned |
|---|---|---|
| Free | $0.01 | $2.00 |
| Bronze | $0.01 | $1.80 |
| Silver | $0.01 | $1.60 |
| Gold | $0.01 | $1.40 |

- The example input: up to 100 jams = $0.01 + $0.20 = $0.21.
- A daily alert on a day with 5 new jams = $0.02; on a day with none = $0.01.
- Everything itch.io lists (about 600 jams) = about $1.20.
- Apify's free plan includes $5 of credit a month.
- Starting a run costs $0.00005. A run that cannot read itch.io charges nothing else.
- If you set a maximum charge for the run, the Actor returns only as many jams as that covers.

### 🔌 Use it from the API, an automation or an AI agent

Start a run and get the rows back in one call (replace `YOUR_TOKEN` with your Apify API token):

```bash
curl -X POST "https://api.apify.com/v2/acts/quiet-robots~itch-io-game-jam-calendar/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"statuses": ["upcoming"], "startsWithinDays": 7, "minJoined": 50}'
```

The same with the [JavaScript client](https://docs.apify.com/api/client/js), reading the digest
as well:

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('quiet-robots/itch-io-game-jam-calendar').call({
    statuses: ['upcoming'],
    startsWithinDays: 7,
    minJoined: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const digest = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('digest.md');
console.log(items.length, digest.value);
```

- **Make, Zapier, n8n and others:** through
  [Apify's integrations](https://docs.apify.com/platform/integrations).
- **AI assistants:** through [Apify's MCP server](https://docs.apify.com/platform/integrations/mcp)
  an assistant can call the Actor as a tool and answer "which game jams start this weekend?"
  from the rows.

### ⚠️ Limits and good to know

- **itch.io only.** Jams hosted elsewhere (Ludum Dare's own site, Global Game Jam) appear only
  if they also have an itch.io page.
- **What the calendar carries, nothing more.** No host, theme, rules, prizes or entry counts:
  those are on each jam's own page, which this Actor does not open.
- **The list is itch.io's.** It holds about 600 jams at a time: upcoming, running, in voting
  and recently finished. Older jams are not in it. Unlisted jams are not in it.
- **Anyone can create a jam,** so the list has tiny and test entries, and now and then a typo
  in a date (a start in the year 0206, an end in 2069). "Minimum joined" and "Longest length"
  clear most of that out.
- **Titles are itch.io's own,** including jams for adult games. To keep some out of a public
  post, list the words in **Title does not contain**.
- **"Only new" keeps a small memory** in a key-value store named `itch-jam-calendar-memory` in
  your own Apify account: the IDs of the jams already returned. Delete the store to start over.
- **If posting to Discord fails,** the run ends as failed and the memory is not updated, so the
  next run returns and posts those jams again.

### ❓ FAQ

#### Does itch.io have an API or a feed for game jams?

Not for the jam calendar. itch.io's page shows it, with no export, RSS feed or calendar link.
This Actor reads the same list that page is drawn from and returns it as JSON, CSV, Excel or
`.ics`.

#### Do I need an itch.io account or API key?

No. You only need an Apify account.

#### How current is the data?

Each run reads itch.io at that moment. `joined` and `status` are as of `checkedAt`.

#### Can I get only game jams for Godot, Unity or a certain genre?

When the word is in the jam's title, yes: put `godot` or `horror` into **Title contains**. The
calendar has no tags or descriptions, so a jam that mentions its engine only on its own page
will not match.

#### What counts as "new"?

A jam this Actor has not returned before under the same memory name. A jam that existed earlier
but only now passes your filters (say, it reached your "Minimum joined") counts as new too,
which is usually what an alert wants.

#### Can it post to Slack, Telegram or email instead of Discord?

Not directly. Use [Apify's integrations](https://docs.apify.com/platform/integrations) to send
the rows or the digest wherever you need them after each run.

#### What exactly does it read from itch.io?

One public page per run, https://itch.io/jams, without logging in. It returns facts about
public events: names, dates and counts. It collects no personal data.

### 💬 Support

Is a jam missing, a time wrong, or do you need another jam site? Open an issue on the Actor's
**Issues** tab and include the jam's link.

### 🤖 More from Quiet Robots

- [Bulk Domain Availability Checker](https://apify.com/quiet-robots/bulk-domain-availability-checker-registry-confirmed):
  paste a list of names and see which domains are free, confirmed at the registry.

# Changelog

This Actor's version history is a separate document: https://apify.com/quiet-robots/itch-io-game-jam-calendar/changelog.md

# Actor input Schema

## `statuses` (type: `array`):

Pick one or more. **Upcoming** jams have not started, **running** ones are open for entries, **in voting** ones are closed and being rated, **finished** ones are the recently ended jams itch.io still lists.

## `startsWithinDays` (type: `integer`):

Only jams that start in the next N days, for example 7 for "this week's jams". Jams that have already started are left out. Leave empty for no limit.

## `minJoined` (type: `integer`):

Only jams that at least this many people have joined. About 70% of listed jams have 10 or more, about 1 in 6 has 100 or more.

## `featuredOnly` (type: `boolean`):

Only the handful of jams itch.io itself features at the top of its calendar.

## `titleContains` (type: `array`):

Only jams whose title contains at least one of these words or phrases, for example `godot`, `horror`, `pixel`. Capital letters don't matter. itch.io's list has titles only, so a jam's theme or rules are not searched.

## `titleExcludes` (type: `array`):

Leave out jams whose title contains any of these words or phrases, for example `ttrpg` or `bundle`.

## `minLengthDays` (type: `number`):

Only jams that last at least this long. Decimals work: 0.5 is 12 hours.

## `maxLengthDays` (type: `number`):

Only jams that last at most this long, for example 3 for weekend jams or 31 to drop year-long ones.

## `sortBy` (type: `string`):

The order of the rows, the digest and the top-N cut below. **What happens next** puts the nearest start, deadline or end of voting first.

## `sortDirection` (type: `string`):

Ascending is soonest, shortest or smallest first. Descending is the reverse: use it with "Number joined" to get the biggest jams first.

## `maxItems` (type: `integer`):

Stop after this many jams, counted after filtering and sorting. You pay per jam returned, so this is also your price cap. 0 or empty means no limit (itch.io lists about 600 jams at a time).

## `timeZone` (type: `string`):

Used for the local-time columns and the digest, as an IANA name such as `Europe/Warsaw`, `America/New_York` or `Asia/Tokyo`. The main time columns are always UTC.

## `onlyNew` (type: `boolean`):

Return only jams that earlier runs have not returned yet, so a scheduled run works as a new-jam alert. The first run returns everything that matches; later runs only what was added. When nothing is new the run returns no rows and you pay only for the calendar check.

## `memoryName` (type: `string`):

"Only new" remembers which jams it has returned under this name. Give each alert with different filters its own name (for example `godot-jams`, `big-jams`) so they don't hide jams from each other. Runs with the same name share one memory.

## `discordWebhookUrl` (type: `string`):

Optional. Posts the digest to a channel on your own Discord server. In Discord: channel settings > Integrations > Webhooks > New Webhook > Copy Webhook URL. Stored encrypted. Nothing is posted when no jams are found.

## Actor input object example

```json
{
  "statuses": [
    "upcoming",
    "running"
  ],
  "minJoined": 10,
  "featuredOnly": false,
  "sortBy": "next",
  "sortDirection": "asc",
  "maxItems": 100,
  "timeZone": "UTC",
  "onlyNew": false,
  "memoryName": "default"
}
```

# Actor output Schema

## `results` (type: `string`):

Every jam that matched, with its times, length, status and number joined.

## `calendar` (type: `string`):

The same jams as events for Google Calendar, Outlook or Apple Calendar.

## `digest` (type: `string`):

The same jams as a short Markdown text, grouped into starting soon, running now and in voting.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "statuses": [
        "upcoming",
        "running"
    ],
    "minJoined": 10,
    "maxItems": 100,
    "timeZone": "UTC"
};

// Run the Actor and wait for it to finish
const run = await client.actor("quiet-robots/itch-io-game-jam-calendar").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "statuses": [
        "upcoming",
        "running",
    ],
    "minJoined": 10,
    "maxItems": 100,
    "timeZone": "UTC",
}

# Run the Actor and wait for it to finish
run = client.actor("quiet-robots/itch-io-game-jam-calendar").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "statuses": [
    "upcoming",
    "running"
  ],
  "minJoined": 10,
  "maxItems": 100,
  "timeZone": "UTC"
}' |
apify call quiet-robots/itch-io-game-jam-calendar --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,quiet-robots/itch-io-game-jam-calendar"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/OFlNIgeWb9cWXynZK/builds/UMw0MCdQ7b0cj6ajt/openapi.json
