---
name: prometheus
description: Get verified, runnable Firecrawl code for any web-data task, and manage self-healing, parameterized data scripts with schedules or on-demand runs. Use this skill whenever you need to scrape, extract, or collect data from a website or the web in code — instead of hand-writing scraping logic. Triggers on "scrape", "extract data from", "get all the X from <site>", "pull <data> from the web", "build a scraper/collector", "monitor/track <site> on a schedule", "keep this data fresh", "data API endpoint for <site>", or when a feature needs structured web data. Also triggers on the marketplace — "find an existing collector", "is there a scraper for", "publish my collector", "share this script", "marketplace". Prometheus returns a TypeScript script (Firecrawl SDK) plus a data sample you embed directly; saves it as a versioned script that self-heals when the site changes and can take CLI parameters; runs it on a cron schedule or on demand as a data endpoint; or reuses a collector someone already published.
---

# Prometheus

Prometheus turns a plain-English data request into a **verified, reproducible
Firecrawl collector**: a TypeScript `script.ts` that prints JSON, plus a sample
of the data it produced. It runs the collector before returning, so the code is
known to work. Use it instead of writing scraping/extraction code by hand.

Four things you can do:

1. **Build** — one-shot: prompt → code + sample. Embed the code in your project.
2. **Script** — save a collector as a versioned script that **self-heals**
   (re-derives itself) when the site changes. Scripts can declare
   **parameters** — CLI flags callers vary per run (a city, a query, a count).
3. **Run / Schedule** — execute a script on demand with parameters
   (`prometheus run`, the API-endpoint trigger), or put it on a **schedule**: a
   cron plus fixed parameter values that produces a recurring data feed.
4. **Marketplace** — search collectors others have published and use one
   instead of building; or publish your own.

**Which to reach for:**

- **Check the marketplace first** — a published, verified collector may already
  exist; deploying it is instant.
- **Build** when you need code (or data) once and will run it yourself.
- **Create a script** when the data must stay fresh without you (recurring
  pulls, monitoring, dashboards) or callers need a parameterized endpoint.
- **`run`** when you need fresh data on demand — it executes the collector now
  with your params and returns the JSON inline.

## Setup (once)

Prometheus runs as a hosted service, authenticated with a **Prometheus API
token** obtained by connecting a Firecrawl account (OAuth):

```bash
prometheus login                                # browser flow; saves the token to ~/.prometheus/config.json
# or, headless: export PROMETHEUS_TOKEN=pmt_... # a token minted in the web app's Settings
export PROMETHEUS_URL=http://localhost:3000     # optional — defaults to the hosted instance
```

Use the CLI if it's installed (`prometheus …`); otherwise call the HTTP API with
`curl` (send `-H "authorization: Bearer $PROMETHEUS_TOKEN"`). If there's no
token (the CLI says "not logged in", or the API returns
`401 {"code":"auth_required"}`), tell the user to run `prometheus login` (or
mint a token in Settings) and stop. A `403 {"code":"reconnect_required"}` means
their Firecrawl connection expired — they should reconnect in Settings.

## Get code for a one-off data task

Prefer the CLI:

```bash
prometheus build "top 5 Hacker News stories with title, url, points" --json
```

Or the API directly:

```bash
curl -s "${PROMETHEUS_URL:-https://firecrawl.dev}/prometheus/api/v1/build" \
  -H 'content-type: application/json' -H "authorization: Bearer $PROMETHEUS_TOKEN" \
  -d '{"prompt":"top 5 Hacker News stories with title, url, points"}'
```

Either returns JSON:

```jsonc
{
  "sessionId": "build-…",     // keep this if you want to save it as a script later
  "script": "import Firecrawl from '@mendable/firecrawl-js'; …",
  "sample": [ /* the data the script produced */ ],
  "rowCount": 5,
  "howItWorks": "…and the assumptions Prometheus made",
  "parameters": [             // the script's declared CLI flags ([] when none)
    { "name": "city", "type": "string", "description": "…", "required": true, "example": "Paris" }
  ],
  "integration": { "dependencies": ["@mendable/firecrawl-js"], "env": ["FIRECRAWL_API_KEY"], "run": "tsx script.ts --city=<value>" }
}
```

**How to use the result in your project:**

1. Write `script` to a file (e.g. `src/collect.ts`).
2. `npm i @mendable/firecrawl-js` and ensure `FIRECRAWL_API_KEY` is set.
3. Run with `tsx script.ts` (plus `--name=value` flags for any declared
   parameters) — it prints the same JSON shape as `sample` to stdout.
4. Read `howItWorks` and confirm the assumptions match the user's intent. If not,
   re-build with a more specific prompt (name the site, exact fields, item count).

Pipe trick: `prometheus build "<prompt>" --json | jq -r .script > src/collect.ts`.

**Tips for good prompts:** name the target site/URL, the exact fields you want,
how many items, and the JSON shape. If callers should vary an input per run
(a city, a search term, a count), SAY SO — "take the city as a parameter" —
and the script declares it as a CLI flag. Pass `--url <URL>` (CLI) or
`"urls": [...]` (API) to pin starting pages, and a JSON Schema
(`--schema file.json` / `"schema": {...}`) to enforce an exact output shape.

Builds run the agent and take ~30–180s. That's expected.

## Keep data fresh — scripts, runs, and schedules

When the user wants data that stays current (monitoring, dashboards, recurring
pulls) or a parameterized data endpoint, save a script instead of a one-off
build.

```bash
# build + save + schedule in one step
prometheus scripts create "OpenAI blog post titles + urls" --every daily@09:00 --name "OpenAI blog"

# or save a build you already ran (instant — no rebuild)
prometheus scripts create --session build-XCFpO8Z… --every 6h

# or a parameterized on-demand endpoint (no schedule)
prometheus scripts create "weather for a city, city as a parameter" --name "Weather"
```

API equivalent: `POST $PROMETHEUS_URL/prometheus/api/v1/scripts` with
`{ "prompt"|"sessionId", "name", "heal", "schedule": { "every", "params" } }`
(omit `schedule` for on-demand only).

**Run on demand (the API-endpoint trigger):**

```bash
prometheus run <scriptId> --param city=Paris -o latest.json
```

```bash
curl -s -X POST "$PROMETHEUS_URL/prometheus/api/v1/scripts/<id>/run" \
  -H 'content-type: application/json' -H "authorization: Bearer $PROMETHEUS_TOKEN" \
  -d '{"params":{"city":"Paris"}}'
```

Executes synchronously (~2 min max) and returns `{run, data}`. Params are
validated against the script's declared interface — unknown keys, missing
required params, or type mismatches come back as
`400 {"code":"invalid_params","errors":{"city":"required parameter missing"}}`
and no run happens. See the declared interface in `prometheus scripts show <id>`
(`script.parameters`).

**Schedules** bind a cron to fixed parameter values — each schedule is a
coherent recurring feed:

```bash
prometheus schedules add <scriptId> --every daily@09:00 --param city=Paris
prometheus schedules data <scheduleId>     # the feed's latest dataset
prometheus schedules ls [<scriptId>]       # every schedule, or one script's
prometheus schedules pause/resume/rm <scheduleId>
prometheus schedules webhook <scheduleId> <url|off>  # push the feed: signed POST per run
```

Prefer push? `--webhook URL` (or the `webhook` command) gets each run's result
and full dataset POSTed to you, HMAC-signed — the signing secret prints once on
creation (details in reference.md).

Schedule grammar (`--every`, UTC): `hourly` · `30m` · `6h` · `daily` ·
`daily@14:00` · `weekly` · `monday@09:00` · raw cron `"0 9 * * 1"`. Creating a
schedule fails fast (per-key 400) if the script's required parameters aren't
covered by the bound values plus declared defaults.

**Self-heal (`--heal`, default `repair_then_rebuild`):** when a run fails
because the site changed, Prometheus fixes the collector automatically — a
successful heal appends a NEW VERSION (same parameter interface) that every
schedule picks up. Failures caused by bad caller params don't trigger heals.
Leave it on.

Consume and manage:

```bash
prometheus scripts ls                     # scripts + their schedules, with health: ● healthy ✗ failing ↻ healing ○ pending
prometheus scripts show <id>              # detail + parameters + schedules + versions
prometheus scripts data <id> -o out.json  # latest collected JSON (most recent successful run)
prometheus scripts runs <id> --status error --param city=Paris   # data-producing run history, filtered
prometheus scripts events <id> --type repair,rebuild             # system-events log: heal attempts + lifecycle
prometheus scripts heal <id>              # fix a broken script now
prometheus scripts pin <id> <V|latest>    # pin runs to one version / subscribe to latest
```

History is split in two (both kept forever). **Runs** are data-producing
executions only (schedule runs + one-offs): filter with `--status`,
`--trigger`, `--schedule`, `--since`/`--until`, and **partial params match**
via repeatable `--param k=v` — matches runs whose effective params CONTAIN
those key/values, whatever the other params were. Over HTTP that's
`GET /prometheus/api/v1/scripts/<id>/runs` with `params.<key>=<value>` query
args (e.g. `?params.city=Paris`; values parse as JSON scalars when possible,
else match as strings; scalar values only) → `{runs, nextCursor}`, paged with
`limit`/`cursor`. **Heal attempts are NOT runs** — they live in the
system-events log: `prometheus scripts events <id>` /
`GET /prometheus/api/v1/scripts/<id>/events` → `{events, nextCursor}`, narrowed
with `type=` (comma-separated: `repair`, `rebuild`, `schedule_auto_pause`,
`cache_sync`, `auto_fork`, `gate_verdict`, `version_append`).

Data reads over HTTP: `GET /prometheus/api/v1/scripts/<id>/schedules/<sid>/data` (a
schedule's feed), `GET /prometheus/api/v1/scripts/<id>/runs/<rid>/data` (one run's
dataset), or the synchronous `/run` response itself.

## Reuse a published collector — the marketplace

Before building anything, check whether a verified collector already exists.
Search and inspection are **public** — they need no token.

```bash
prometheus marketplace search "hacker news top stories"   # public; add --json for machine output
prometheus marketplace show <id>                          # script + prompt + parameters + sample
prometheus marketplace deploy <id> --subscribe            # or --fork (needs login)
```

Or the API directly:

```bash
curl -s "${PROMETHEUS_URL:-https://firecrawl.dev}/prometheus/api/v1/marketplace/listings?q=hacker%20news"
curl -s -X POST "$PROMETHEUS_URL/prometheus/api/v1/marketplace/listings/<id>/deploy" \
  -H 'content-type: application/json' -H "authorization: Bearer $PROMETHEUS_TOKEN" \
  -d '{"mode":"subscribe","schedule":{"every":"6h"}}'
```

To use one:

1. `prometheus marketplace search "<what you need>"` and pick the closest match
   (prefer `official: true` publishers and high `copies`).
2. `prometheus marketplace show <id>` — confirm the prompt, parameters, schema,
   and sample match the user's need.
3. `prometheus marketplace deploy <id> --subscribe` (or `--fork`) — it appears in
   the user's library as a script; consume it via `prometheus run <scriptId>`
   (fresh, with `--param`) or schedule it.
4. No match? Build fresh (above) — and consider
   `prometheus marketplace publish <scriptId>` to share the result (first
   publish needs `--handle`, a permanent public publisher handle; every publish
   runs a sterility gate and may come back `"status": "rejected"` with a reason).

**Subscribe vs fork:** `--subscribe` runs the listing's current approved version — the
platform maintains it (no local copy, no self-heal needed). `--fork` takes an
independent snapshot the user owns and self-heals. Default to `--subscribe` for
official, popular listings; `--fork` when the user wants to customize the
script or control healing (`prometheus scripts fork <id>` converts later —
one-way; subscribed scripts also auto-fork if the listing is unpublished).

## Choosing the right call

- **Marketplace first** — deploying a published collector is instant and skips
  the build entirely.
- **Build** — you need the data (or the code) once, or you'll run the script
  yourself on your own cadence.
- **Script + schedule** — the data must stay fresh without you, or the target
  site changes often and you want automatic self-healing.
- **`run` with `--param`** — the user (or their app) needs fresh data right now,
  possibly varying inputs per call.

## More detail

See `reference.md` (next to this file) for the full command and endpoint tables,
error codes, and the Script/Schedule/Run object shapes.
