# Stafford Data Center Planning Monitor (`mikechiou/stafford-data-center-planning`) Actor

Monitor Stafford County CivicClerk agendas and packets for data-center, substation, CUP, rezoning, and comprehensive-plan planning items.

- **URL**: https://apify.com/mikechiou/stafford-data-center-planning.md
- **Developed by:** [Mike Chiou](https://apify.com/mikechiou) (community)
- **Categories:** Agents, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $40.00 / 1,000 data-center planning matches

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Stafford Data Center Planning Monitor

Monitor Stafford County, Virginia CivicClerk agendas and packets for data-center, electric-substation, utility, rezoning, conditional-use, and comprehensive-plan planning signals.

### What This Actor Does

- Fetches public Stafford County CivicClerk event metadata from the official public API.
- Scans public agenda, agenda-packet, and minutes plain-text streams with `plainText=true`.
- Matches deterministic data-center and power-infrastructure terms without LLM interpretation.
- Extracts case IDs such as `CUP25156868`, `COM25156869`, `RC24155947`, `PCR26-14`, `O26-13`, and `R26-125`.
- Extracts visible project names such as Potomac Creek Campus, GWV Data Center, Simms Farm Data Center, and Vantage VA41 Substation when present in source text.
- Emits source-backed records with event URLs, file URLs, matched snippets, case IDs, project names, event type, and dedupe key.
- Persists event fingerprints so repeated monitor runs do not emit the same event again.
- Supports pay-per-event charging with a safe no-op fallback for local or unpublished runs.

### Inputs

- `meetingBodies`: CivicClerk meeting categories to scan. Defaults to Planning Commission, Board of Supervisors, and Historical Commission.
- `fileTypes`: file types to scan. Defaults to Agenda, Agenda Packet, and Minutes.
- `keywords`: custom terms to match in addition to the built-in data-center, substation, utility, transmission, and known-project patterns. Broad planning terms such as `comprehensive plan` are best used only when you intentionally want a wider feed.
- `dateWindow`: explicit `{ "start": "YYYY-MM-DD", "end": "YYYY-MM-DD" }` or `{ "lookbackDays": 180 }`.
- `includeUnmatchedFiles`: when true, emits `new_planning_file` for unmatched new files too.
- `maxSourceEvents`, `maxFilesPerEvent`, `maxEvents`: safety controls.
- `stateStoreName`: named key-value store for monitor-mode dedupe. Use `__RUN_DEFAULT__` for isolated demo runs.

### Output

Each dataset item uses this shape:

```json
{
    "event_type": "data_center_planning_match",
    "jurisdiction": "Stafford County, VA",
    "source_system": "CivicClerk",
    "event_id": 2724,
    "event_name": "May 13, 2026 Planning Commission Meeting",
    "event_date": "2026-05-13",
    "meeting_body": "Planning Commission Meetings",
    "file_id": 6063,
    "file_type": "Agenda Packet",
    "file_name": "May 13, 2026 Planning Commission Agenda Packet",
    "case_ids": ["CUP25156868", "COM25156869"],
    "project_names": ["Potomac Creek Campus"],
    "matched_keywords": ["data center", "conditional use permit"],
    "match_category": "data_center_planning",
    "match_strength": "multi",
    "matched_snippet": "CONSIDER A REQUEST FOR A CONDITIONAL USE PERMIT FOR MAXIMUM BUILDING HEIGHT OF ANY DATA CENTER BUILDING...",
    "source_event_url": "https://staffordcova.portal.civicclerk.com/event/2724",
    "source_file_url": "https://staffordcova.api.civicclerk.com/v1/Meetings/GetMeetingFile(fileId=6063,plainText=false)",
    "public_portal_file_url": "https://staffordcova.portal.civicclerk.com/event/2724",
    "dedupe_key": "stafford-civicclerk:2724:6063:CUP25156868+COM25156869:data_center_planning"
}
````

### Event Pricing Plan

Pay-per-event pricing is configured on Apify.

- `data_center_planning_match`: `$0.04` primary event.
- `substation_or_power_match`: `$0.04` primary event.
- `new_planning_file`: `$0.02`, only when `includeUnmatchedFiles` is enabled.

Use all-inclusive pay-per-event pricing. Do not enable pay-per-event plus usage unless the margin model changes.

### Local Development

```bash
npm install
npm run build
npm test
npm run lint
npm run canary
apify run --purge
```

The local smoke input lives at `storage/key_value_stores/default/INPUT.json`.

### Data Sources

- Stafford County public portal: `https://staffordcova.portal.civicclerk.com/`
- Stafford County public event API: `https://staffordcova.api.civicclerk.com/v1/Events`
- Event detail example: `https://staffordcova.api.civicclerk.com/v1/Events/2724`
- Plain-text file stream example: `https://staffordcova.api.civicclerk.com/v1/Meetings/GetMeetingFileStream(fileId=6063,plainText=true)`

### Limitations

- This Actor reports public source facts and deterministic keyword matches. It does not provide legal, zoning, real-estate, investment, tax, utility, or compliance advice.
- v1 is Stafford County specific. New Albany, Mesa, Henrico, Loudoun, Prince William County, and Manassas adapters are out of scope unless each passes a separate source gate.
- Prince William County, Loudoun County, and Manassas Granicus sources were explicitly parked because their Granicus hosts disallow `/` for `User-agent: *` in `robots.txt`.
- v1 uses CivicClerk `plainText=true` streams. It does not parse PDFs directly.
- The Actor is not affiliated with, endorsed by, or sponsored by Stafford County, CivicClerk, or CivicPlus.

### Maintenance

Run the canary daily:

```bash
npm run canary
```

Open a fix ticket if the CivicClerk event API returns HTML/404, event `2724` or file `6063` disappears and the fallback canary fails, `publishedFiles` disappears, plain-text file streams stop returning source text, or the parser no longer emits at least one data-center or substation event from a known source file.

### Kill / Scale Gate

After 60 days listed on Apify, continue only if the Actor reaches at least 5 paid-plan users, at least `$25` in charged events, credible direct inbound, or repeated paid usage by the same non-Mike account. Otherwise archive/freeze and move to the next validated build.

# Actor input Schema

## `meetingBodies` (type: `array`):

CivicClerk meeting categories to monitor.

## `fileTypes` (type: `array`):

Published file types to scan. Agenda Packet usually has the richest source text.

## `keywords` (type: `array`):

Additional terms matched against event names, file names, and plain-text agenda or packet streams. Keep broad planning or generic transmission terms optional to avoid noisy paid events.

## `dateWindow` (type: `object`):

Use explicit start/end ISO dates or a rolling lookback. Default is 120 days.

## `includeUnmatchedFiles` (type: `boolean`):

When true, emits new\_planning\_file for unmatched new files too. Default false keeps output focused on data-center and power signals.

## `maxSourceEvents` (type: `integer`):

Maximum CivicClerk events to fetch from the source API.

## `maxFilesPerEvent` (type: `integer`):

Maximum published files to scan per meeting event.

## `maxEvents` (type: `integer`):

Safety cap for one run.

## `stateStoreName` (type: `string`):

Named key-value store used for monitor-mode dedupe. Use **RUN\_DEFAULT** for isolated demo runs.

## Actor input object example

```json
{
  "meetingBodies": [
    "Planning Commission Meetings",
    "Board of Supervisors",
    "Historical Commission"
  ],
  "fileTypes": [
    "Agenda",
    "Agenda Packet",
    "Minutes"
  ],
  "keywords": [
    "data center",
    "substation",
    "electric substation",
    "public utility",
    "Potomac Creek Campus"
  ],
  "dateWindow": {
    "lookbackDays": 180
  },
  "includeUnmatchedFiles": false,
  "maxSourceEvents": 50,
  "maxFilesPerEvent": 4,
  "maxEvents": 10,
  "stateStoreName": "__RUN_DEFAULT__"
}
```

# Actor output Schema

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

No description

## `summary` (type: `string`):

No description

# 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 = {
    "meetingBodies": [
        "Planning Commission Meetings",
        "Board of Supervisors",
        "Historical Commission"
    ],
    "fileTypes": [
        "Agenda",
        "Agenda Packet",
        "Minutes"
    ],
    "keywords": [
        "data center",
        "substation",
        "electric substation",
        "public utility",
        "Potomac Creek Campus"
    ],
    "dateWindow": {
        "lookbackDays": 180
    },
    "maxEvents": 10,
    "stateStoreName": "__RUN_DEFAULT__"
};

// Run the Actor and wait for it to finish
const run = await client.actor("mikechiou/stafford-data-center-planning").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 = {
    "meetingBodies": [
        "Planning Commission Meetings",
        "Board of Supervisors",
        "Historical Commission",
    ],
    "fileTypes": [
        "Agenda",
        "Agenda Packet",
        "Minutes",
    ],
    "keywords": [
        "data center",
        "substation",
        "electric substation",
        "public utility",
        "Potomac Creek Campus",
    ],
    "dateWindow": { "lookbackDays": 180 },
    "maxEvents": 10,
    "stateStoreName": "__RUN_DEFAULT__",
}

# Run the Actor and wait for it to finish
run = client.actor("mikechiou/stafford-data-center-planning").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "meetingBodies": [
    "Planning Commission Meetings",
    "Board of Supervisors",
    "Historical Commission"
  ],
  "fileTypes": [
    "Agenda",
    "Agenda Packet",
    "Minutes"
  ],
  "keywords": [
    "data center",
    "substation",
    "electric substation",
    "public utility",
    "Potomac Creek Campus"
  ],
  "dateWindow": {
    "lookbackDays": 180
  },
  "maxEvents": 10,
  "stateStoreName": "__RUN_DEFAULT__"
}' |
apify call mikechiou/stafford-data-center-planning --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=mikechiou/stafford-data-center-planning",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Stafford Data Center Planning Monitor",
        "description": "Monitor Stafford County CivicClerk agendas and packets for data-center, substation, CUP, rezoning, and comprehensive-plan planning items.",
        "version": "0.1",
        "x-build-id": "QNUAZZaPHreyMp6O3"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/mikechiou~stafford-data-center-planning/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-mikechiou-stafford-data-center-planning",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/mikechiou~stafford-data-center-planning/runs": {
            "post": {
                "operationId": "runs-sync-mikechiou-stafford-data-center-planning",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/mikechiou~stafford-data-center-planning/run-sync": {
            "post": {
                "operationId": "run-sync-mikechiou-stafford-data-center-planning",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "meetingBodies": {
                        "title": "Meeting bodies",
                        "maxItems": 12,
                        "type": "array",
                        "description": "CivicClerk meeting categories to monitor.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "fileTypes": {
                        "title": "File types",
                        "maxItems": 8,
                        "type": "array",
                        "description": "Published file types to scan. Agenda Packet usually has the richest source text.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "keywords": {
                        "title": "Keywords",
                        "type": "array",
                        "description": "Additional terms matched against event names, file names, and plain-text agenda or packet streams. Keep broad planning or generic transmission terms optional to avoid noisy paid events.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "dateWindow": {
                        "title": "Date window",
                        "type": "object",
                        "description": "Use explicit start/end ISO dates or a rolling lookback. Default is 120 days.",
                        "properties": {
                            "start": {
                                "type": "string",
                                "title": "Start date",
                                "description": "Inclusive event-date window start in YYYY-MM-DD format."
                            },
                            "end": {
                                "type": "string",
                                "title": "End date",
                                "description": "Inclusive event-date window end in YYYY-MM-DD format."
                            },
                            "lookbackDays": {
                                "type": "integer",
                                "title": "Lookback days",
                                "description": "Rolling window size when start/end are omitted.",
                                "minimum": 1,
                                "maximum": 730
                            }
                        }
                    },
                    "includeUnmatchedFiles": {
                        "title": "Include unmatched files",
                        "type": "boolean",
                        "description": "When true, emits new_planning_file for unmatched new files too. Default false keeps output focused on data-center and power signals.",
                        "default": false
                    },
                    "maxSourceEvents": {
                        "title": "Maximum source events",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Maximum CivicClerk events to fetch from the source API.",
                        "default": 50
                    },
                    "maxFilesPerEvent": {
                        "title": "Maximum files per event",
                        "minimum": 1,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Maximum published files to scan per meeting event.",
                        "default": 4
                    },
                    "maxEvents": {
                        "title": "Maximum emitted events",
                        "minimum": 1,
                        "maximum": 250,
                        "type": "integer",
                        "description": "Safety cap for one run.",
                        "default": 50
                    },
                    "stateStoreName": {
                        "title": "State store name",
                        "type": "string",
                        "description": "Named key-value store used for monitor-mode dedupe. Use __RUN_DEFAULT__ for isolated demo runs."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
