# Kickstarter Campaign Tracker - Backers, Pledged & Days Left (`neverempty/kickstarter-campaign-tracker`) Actor

Backers, amount pledged, goal, percent funded, days left and state of any Kickstarter project, with USD conversion. Monitoring mode returns a campaign only when its backers, pledged amount or state change, with the difference since the last check.

- **URL**: https://apify.com/neverempty/kickstarter-campaign-tracker.md
- **Developed by:** [NeverEmpty](https://apify.com/neverempty) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.40 / 1,000 campaign returneds

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

## Kickstarter Campaign Tracker - Backers, Pledged & Days Left

Backers, amount pledged, goal, percent funded, days left and state (live, successful, failed, canceled) for any Kickstarter project, one row per project. **Amounts come with a USD conversion**, so campaigns in GBP, EUR or JPY can sit in one table.

With monitoring on, **a campaign is returned only when its backers, pledged amount or state have changed**. The row carries the difference since the last check and the pace per day. The first check of a campaign is free.

Paste project links as they appear in the browser (`https://www.kickstarter.com/projects/<creator>/<project>`), one per line.

### Input

| Field | What it does |
|---|---|
| `projectUrls` | Kickstarter project links, one per line (`?ref=...` and `/description` at the end are fine) |
| `maxProjects` | Stop after this many projects (default 100) |
| `monitoringMode` | Return only campaigns that changed since the previous run |
| `monitorMode` | What counts as a change: `funding-change` (backers, pledged, state), `any-change` (also comments) or `milestones` (goal reached or state changed) |
| `resetMonitoringState` | Forget the remembered figures and start over with a free first check |
| `useProxy` | Move to fresh Apify datacenter proxy addresses if Kickstarter refuses requests (default on) |

### What you get

One row per project:

| Column | Meaning |
|---|---|
| `projectName` | The project title |
| `state` | `live`, `successful`, `failed`, `canceled`, `suspended` or `submitted`, as Kickstarter reports it |
| `backers` | Number of backers |
| `pledged` | Amount pledged, in the project's currency |
| `currency`, `goal` | The project's currency and funding goal |
| `percentFunded` | Pledged as a percentage of the goal, rounded down to one decimal (99.96% shows as 99.9, never 100) |
| `isGoalReached` | `true` when the pledged amount has reached the goal |
| `pledgedUsd`, `goalUsd` | Pledged and goal converted to US dollars at Kickstarter's own rate for the project |
| `averagePledge` | Pledged divided by backers |
| `daysLeft`, `hoursLeft` | Time until the deadline, rounded down; `0` once the deadline has passed |
| `deadline`, `launchedAt` | Deadline and launch time (ISO 8601, UTC) |
| `pledgedPerDay`, `backersPerDay` | Average per day since launch (up to the deadline for ended campaigns) |
| `commentsCount`, `updatesCount` | Comments and creator updates |
| `rewardsCount`, `lowestRewardAmount` | Number of reward tiers and the cheapest one |
| `staffPick`, `isInLatePledges` | Kickstarter's "Project We Love" flag, and whether the project accepts late pledges after the campaign |
| `blurb`, `creatorName`, `category`, `parentCategory`, `location`, `country`, `imageUrl` | Description and context |
| `projectId`, `projectUrl` | Kickstarter's numeric project ID and the project link |
| `detailsStatus`, `detailsReadAt` | Whether the name, goal and deadline were read in this run or remembered from an earlier one (see below) |
| `input`, `scrapedAt`, `status` | What you typed, when it was read, `ok` for a project row |

Monitoring columns (filled in monitoring mode): `change`, `isFirstCheck`, `changedFields` (for example `["backers","pledged"]` or `["state"]`), `backersChange`, `pledgedChange`, `pledgedChangeUsd`, `previousBackers`, `previousPledged`, `previousState`, `previousCheckedAt`, `goalReachedSinceLastCheck`, `backersPerDaySinceLastCheck`, `pledgedPerDaySinceLastCheck`.

Read on 2026-10-23:

| Project | state | backers | pledged | goal | percentFunded | pledgedUsd |
|---|---|---|---|---|---|---|
| An Infamous Traffic: Second Edition | live | 6436 | 601727 USD | 50000 | 1203.4 | 601727 |
| Nap Comix: First Steps | live | 192 | 4973 GBP | 8000 | 62.1 | 6628.02 |
| Good Kitties + Super Chonk: The Purr-fect Pair of Cat Games | live | 367 | 36758 USD | 9600 | 382.8 | 36758 |
| GENKI: Covert Dock 3 and ShadowCast 3 | successful | 12237 | 1437389 USD | 16800 | 8555.8 | 1437389 |
| Lil - The Book Series | failed | 49 | 2455 USD | 6000 | 40.9 | 2455 |

### Monitoring mode

Turn on **Monitoring mode** and run the same list on a schedule (for example every hour or every day):

1. **First run of a project**: its backers, pledged amount, state and comment count are remembered as the starting point. You get a `first-check` row without figures, and nothing is charged.
2. **Later runs**: each project is read and compared with what was remembered.
   - **Something changed**: you get the project row with `backersChange`, `pledgedChange`, `changedFields` and the pace since the last check, charged as one project row.
   - **Nothing changed** (or, in `milestones`, nothing that counts as a milestone): no project row; the project is charged as one check. When no project in the run is returned, you get one `no-change` row so an empty result is never ambiguous.

**What counts as a change**:

- `funding-change` (default): backers, pledged amount or state. A new comment alone is not reported.
- `any-change`: the same, plus the comment count.
- `milestones`: only when the project reaches its goal for the first time (`goalReachedSinceLastCheck: true`) or its state changes, for example `live` to `successful`. Smaller moves are charged as a check and remembered without being returned, so the next difference is measured from the latest check. While the goal is unknown (the project's details could not be read), the moves are not remembered, so passing the goal is still caught once the goal is read.

`backersPerDaySinceLastCheck` and `pledgedPerDaySinceLastCheck` are filled when at least one hour has passed since the previous check, so a few minutes between runs never turn into an inflated daily pace.

Figures are remembered per project ID, so adding a project to your list does not reset the others, and the same project given with two different links is one project. **Forget the remembered figures and start over** clears them, and the next run is a free first check again. A change that could not be delivered because the run's maximum total charge was reached is not remembered, so the next run returns it.

### What is charged

- **campaign-returned**: one per project row with `status: ok`.
- **campaign-checked**: monitoring mode only. One per project that was compared and not returned: it had not changed, or in `milestones` mode it moved without reaching its goal or changing state. A project that is returned is charged as a row only, not as a check.
- Not charged: `first-check`, `no-such-project`, `invalid-input`, `duplicate-input`, `unreadable`, `blocked`, `no-change`, `not-read` and `budget-reached` rows. There is no monthly fee.

If you set a maximum total charge, the run stops before it, lists the lines it did not read in a `not-read` row, and charges nothing for them. In monitoring mode the run stops as soon as the limit cannot cover one more check, before reading the next project, even if that project would have been a free first check.

### Rows that explain instead of failing

| status | When |
|---|---|
| `first-check` | Monitoring: the first time a project is seen, its starting point was remembered |
| `no-such-project` | Kickstarter has no project at the link: it was deleted, or the creator or project part of the link is wrong |
| `invalid-input` | The line is not a Kickstarter project link, for example a `kck.st` short link or a Discover page - or no project was given |
| `duplicate-input` | The same project appeared earlier in the list (also when it was given with a different link) |
| `unreadable` | The figures came back in a form that could not be read. No figure is guessed |
| `blocked` | Kickstarter kept refusing the request (HTTP 403/429) |
| `not-read` | Lines that were not requested: after a `blocked` row or three unreadable projects in a row, or when `maxProjects` or the charge limit was reached |
| `no-change` | Monitoring: every project was compared and none had changed |
| `budget-reached` | A changed project was ready but did not fit inside the run's maximum total charge |

### Questions people ask

**How do I track a Kickstarter campaign's backers and pledges over time?**
Put the project link in `projectUrls`, turn on monitoring mode and schedule the Actor. Each run returns only the campaigns that moved, with the change in backers and pledged amount since the previous run.

**How do I get the pledged amount and days left for many Kickstarter projects at once?**
Paste up to 1,000 project links in one run. Each row has `pledged`, `goal`, `percentFunded`, `daysLeft` and `hoursLeft`, plus `pledgedUsd` for comparing campaigns in different currencies.

**Can I get an alert when a Kickstarter campaign reaches its goal?**
Use monitoring mode with `monitorMode: milestones`. The project is returned once, with `goalReachedSinceLastCheck: true`, in the run after it passes its goal, and again when its state changes to `successful` or `failed`.

**Does it work for campaigns that have already ended?**
Yes. Successful, failed and canceled projects return their final backers and pledged amount, with `daysLeft: 0`.

### Good to know

- **Figures are fresh on every run**: backers, pledged amount, state and comments are read each time. The name, goal, deadline, rewards and the other details are read at most once a day per project and reused from memory in between (`detailsStatus: remembered`); they are read again as soon as the project's state changes. If the details cannot be read for a project, its row still has the figures, the detail columns are `null`, and `detailsStatus` says why.
- **One schedule per list**: do not let two monitoring runs of the same projects overlap. Both compare with the same remembered figures, so the same change can be returned and charged by each. A change that was returned is remembered at once, so a run that is aborted does not return it again.
- **Search is not included**: this Actor follows the projects you give it. Use the link from the project page.
- **Short `kck.st` links are not followed**: open one once in a browser and paste the full link.
- **Currency**: `pledged` and `goal` are in the project's currency. `pledgedUsd` and `goalUsd` use the exchange rate Kickstarter shows for the project, which can differ slightly from today's market rate.
- Requests go to Kickstarter's public project pages with a pause between them and a User-Agent that identifies this Actor. No login, no Kickstarter account and no residential proxy are used. If Kickstarter refuses requests from one address, the run moves to fresh Apify datacenter proxy addresses (you can turn this off).
- This Actor is not affiliated with, endorsed by or sponsored by Kickstarter. Kickstarter's terms restrict automated collection; decide for yourself whether your use is permitted before you run it.

### Thanks for using this Actor

We build these tools for people who run them every day, and we improve them from what users tell us.

- **Missing a field, or need another filter?** Tell us in the **Issues** tab. If the data is there, we add it.
- **Found a bug or a wrong value?** Post the run ID in the **Issues** tab. Wrong data is the thing we fix first.

If this Actor saved you time, a short review helps other people find it.

# Actor input Schema

## `projectUrls` (type: `array`):

Project links as they appear in the browser (https://www.kickstarter.com/projects/<creator>/<project>, with or without www, ?ref= or /description at the end) or just <creator>/<project>. Live, successful, failed and canceled projects all work. A link Kickstarter has no project for comes back as a "no-such-project" row that is not charged. Short kck.st links are rejected: open one once in a browser and paste the full link. Project names are not searched.

## `maxProjects` (type: `integer`):

With monitoring off, the run stops after this many project rows and lists the lines it did not read in a row that is not charged. Monitoring mode ignores this and checks every project you listed.

## `monitoringMode` (type: `boolean`):

Off = return every project you listed, charged per project row (campaign-returned). On = backers, amount pledged, state and comment count are remembered, and later runs return a project only when they differ, with the previous figures, the differences and the pace since the last check. The first monitoring run of a project only remembers its starting point: it is free and returns a first-check row without figures. After that, a project that changed is charged as one project row, and a project that was compared and had not changed is charged as one check (campaign-checked). Figures are remembered per project, not per list, so adding a project does not reset the others. Do not put the same project in two schedules that run at the same moment.

## `monitorMode` (type: `string`):

Funding change = returned when backers, amount pledged or state change (comments alone are ignored). Any change = also returned when only the comment count changes. Milestones = returned only when the project reaches its goal for the first time or its state changes (for example live to successful); smaller moves are still remembered, so the next difference is measured from the latest check.

## `resetMonitoringState` (type: `boolean`):

Clears every remembered project for this Actor on your account, so the next monitoring run takes a free first check of each project again. This affects all your monitoring runs, because figures are remembered per project rather than per list.

## `useProxy` (type: `boolean`):

Requests go directly to Kickstarter with a pause between them, and no residential proxy is used. If Kickstarter refuses a request (HTTP 403 or 429), the run continues from fresh Apify datacenter proxy addresses. Turn this off to never use a proxy: a refusal is then waited out once and, if it repeats, the run stops and lists what it did not read.

## Actor input object example

```json
{
  "projectUrls": [
    "https://www.kickstarter.com/projects/colewehrle/an-infamous-traffic-second-edition",
    "https://www.kickstarter.com/projects/flimsykitten/nap-comix-first-steps"
  ],
  "maxProjects": 100,
  "monitoringMode": false,
  "monitorMode": "funding-change",
  "resetMonitoringState": false,
  "useProxy": true
}
```

# Actor output Schema

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

One row per Kickstarter project: name, state, backers, amount pledged, goal, percent funded, pledged and goal in USD, average pledge, days and hours left, deadline, launch date, pledges per day, creator, category, location and, in monitoring mode, the previous figures, the differences, whether the goal was reached since the last check and which fields changed. Links Kickstarter has no project for, lines that are not project links, figures that could not be read, first monitoring checks and runs where nothing changed come back as their own rows and are not charged.

# 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 = {
    "projectUrls": [
        "https://www.kickstarter.com/projects/colewehrle/an-infamous-traffic-second-edition",
        "https://www.kickstarter.com/projects/flimsykitten/nap-comix-first-steps"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("neverempty/kickstarter-campaign-tracker").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 = { "projectUrls": [
        "https://www.kickstarter.com/projects/colewehrle/an-infamous-traffic-second-edition",
        "https://www.kickstarter.com/projects/flimsykitten/nap-comix-first-steps",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("neverempty/kickstarter-campaign-tracker").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 '{
  "projectUrls": [
    "https://www.kickstarter.com/projects/colewehrle/an-infamous-traffic-second-edition",
    "https://www.kickstarter.com/projects/flimsykitten/nap-comix-first-steps"
  ]
}' |
apify call neverempty/kickstarter-campaign-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,neverempty/kickstarter-campaign-tracker"
        }
    }
}
```

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/4k0Ikg91qaKhcBJKR/builds/8drznzkPPYSq4m9h5/openapi.json
