# Water Utility Rate Lookup (SF, NYC, Austin) (`kevinserver24/water-utility-rate-lookup`) Actor

Current water rate schedules for San Francisco, New York City and Austin, normalized from three differently structured tariff PDFs into one schema. Charged only per rate row delivered.

- **URL**: https://apify.com/kevinserver24/water-utility-rate-lookup.md
- **Developed by:** [Kevin](https://apify.com/kevinserver24) (community)
- **Categories:** Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$50.00 / 1,000 rate row delivereds

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/actors/running/actors-in-store.md#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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Water Utility Rate Lookup (San Francisco, New York City, Austin)

*An independent tool. It is not affiliated with, endorsed by, or operated by
the San Francisco Public Utilities Commission, the New York City Water
Board, or the City of Austin Water Utility. All three publish their tariffs
as public rate schedules. This Actor reads each utility's own current tariff
document and reports what it says, normalized into one schema.*

**A periodically refreshed snapshot, not a live fetch per run.** A water
rate typically changes once or twice a year, on a fiscal-year boundary that
differs by utility — re-parsing three differently-laid-out government PDFs
on every customer request would trade real fragility for no real freshness
benefit. `SUMMARY.json` in the run's key-value store reports the snapshot
actually served; each row carries its own `effective_date` and `source_url`
so you can verify it against the utility's current tariff yourself.

***

### Why this exists

Water utility rates in the US are not centrally published. Bluefield
Research's free index covers only the ~30-50 largest cities and gates
utility-level detail behind contact-sales; the AWWA/Raftelis Rate Survey
(~500 utilities) is itself a paid subscription report, not a queryable feed.
Thousands of small and mid-size municipal and co-op utilities publish only
their own PDF ordinance or tariff document, each laid out differently. This
Actor reads three of them today — San Francisco, New York City and Austin —
and reconciles genuinely different rate-schedule shapes (meter-size-keyed
fixed charges, tier-keyed fixed charges, flat no-tier rates) into one row
format, instead of leaving you to open three different PDFs by hand.

### What you get per row

| Field | Meaning |
|---|---|
| `utility` | The full utility name |
| `state` | Two-letter state code |
| `service_type` | `single_family_residential`, `multi_family_residential`, `commercial_industrial`, or `all_metered_premises` (NYC, which does not split by class in its base metered rate) |
| `rate_component` | `fixed_monthly_charge`, `fixed_daily_minimum` (NYC only), or `usage_rate` |
| `meter_size` | The meter size this fixed charge applies to (San Francisco only) — `null` where the source does not key its charge to meter size |
| `tier`, `tier_label` | The usage tier's number and the tariff's own wording for it — `null` for a flat, untiered rate |
| `tier_min_units`, `tier_max_units` | The tier's usage bounds, in the source's own unit — `null` where not applicable |
| `usage_unit` | `ccf` (100 cubic feet, San Francisco and NYC) or `kgal` (1,000 gallons, Austin) — never converted between utilities, so you always know exactly what you are comparing |
| `amount_usd` | The dollar amount |
| `effective_date` | When this rate took effect |
| `source_url` | A direct link to the utility's own tariff document, to verify |
| `charged` | Whether this row cost you anything |
| `not_charged_reason` | Why it did not, in plain English |

### The billing rule, stated plainly

One event: **rate row delivered**, charged once per row in the result. A row
that appears again on a later run because the tariff has not changed since
your last request is charged again — you are paying for the answer, not
for a change having happened, the same convention `puc-rate-case-tracker`
uses for a docket that reappears unchanged.

### Coverage — read this before you rely on it

**v1 covers three utilities: San Francisco (all three residential/
commercial service classes), New York City (its single flat metered rate),
and Austin (single-family residential only — Multifamily, Commercial, Large
Volume and the CAP low-income tariff all exist in Austin's own source and
are not yet covered).** `SUMMARY.json` reports exactly which utilities were
requested and how many rows were found for each.

***

### Input

```json
{
  "utilities": ["sfpuc_ca", "nyc_ny", "austin_tx"]
}
```

Leave `utilities` empty to look up all three. Invalid or unsupported slugs
are ignored; if nothing valid is given, all three supported utilities are
returned.

### Output

```json
{
  "utility": "San Francisco Public Utilities Commission",
  "state": "CA",
  "service_type": "single_family_residential",
  "rate_component": "usage_rate",
  "meter_size": null,
  "tier": 1,
  "tier_label": "First 4 units per month",
  "tier_min_units": 0,
  "tier_max_units": 4,
  "usage_unit": "ccf",
  "amount_usd": 12.2,
  "effective_date": "2026-07-01",
  "source_url": "https://www.sfpuc.gov/sites/default/files/accounts-and-services/Rates_Schedule_Water_Sewer_2026-7.pdf",
  "charged": true,
  "not_charged_reason": ""
}
```

A `SUMMARY.json` lands in the key-value store with which utilities were
requested, how many rows were found, and a breakdown of charged vs. free
rows.

# Actor input Schema

## `utilities` (type: `array`):

Which water utility's rate schedule to return. Leave empty to return all three. More utilities are planned -- see the README for coverage and why only three exist today.

## Actor input object example

```json
{
  "utilities": [
    "sfpuc_ca",
    "nyc_ny",
    "austin_tx"
  ]
}
```

# Actor output Schema

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

One row per fixed-charge or usage-rate line: utility, state, service type, rate component, tier, amount, effective date, and a link back to the utility's own tariff.

## `resultsCsv` (type: `string`):

The same rows as a spreadsheet.

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

Which utilities were requested, how many rows were found, charged and free.

# 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 = {
    "utilities": [
        "sfpuc_ca",
        "nyc_ny",
        "austin_tx"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("kevinserver24/water-utility-rate-lookup").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 = { "utilities": [
        "sfpuc_ca",
        "nyc_ny",
        "austin_tx",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("kevinserver24/water-utility-rate-lookup").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 '{
  "utilities": [
    "sfpuc_ca",
    "nyc_ny",
    "austin_tx"
  ]
}' |
apify call kevinserver24/water-utility-rate-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kevinserver24/water-utility-rate-lookup"
        }
    }
}

```

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/ERhJ68X52QIsW5Mnh/builds/d1CYSaslQZDTyc3bU/openapi.json
