Hold on-peak.
Irrigate off-peak.

Wells, pivots, and boosters follow the agricultural tariff at that ZIP. Pass customer_class=agricultural. Period names and boundaries — the residential plan on the same ZIP is a different clock.

Same ZIP, different clock

A query with no customer_class returns residential. On PG&E, Schedule AG is on-peak 5–8 PM every day. Residential E-ELEC on that utility is 4–9 PM every day.

House hours
hour = now.astimezone(zone).hour

if 16 <= hour < 21:
    hold_pumps()
else:
    run_pumps()

That’s E-ELEC. On Schedule AG it holds 4–5 PM and 8–9 PM, which are off-peak, and it still runs Wednesday evening on AG-F Option I.

From the tariff
plan = next(r for r in results
            if r["rate_plan"]["code"] == "AG")
period = plan["period"]

if period in ("on_peak", "critical_peak"):
    hold_pumps()
elif period in ("off_peak", "super_off_peak"):
    run_pumps()

The period is the clock the utility bills. Query it. These hours are examples of why a pasted window fails.

ZIP → agricultural period → run or hold

One REST call for the live period. A forward timeline for the irrigation set. A webhook when the period actually flips.

1

Pass the pump ZIP

customer_class=agricultural. Add street, city, and state when the ZIP is shared by two utilities. The class is on every plan, including Free.

2

Pin the schedule

Match rate_plan.code to the bill — AG, AG-F-I, TOU-PA-2-5TO8. is_optional: false is the mandatory TOU for that class, not proof the account is enrolled.

3

Run or hold

Run on off_peak and super_off_peak. Hold on on_peak. Treat mid_peak as its own decision — your controls still own flow, pressure, and the water order.

GET /api/v1/query/current?zip_code=93637&customer_class=agricultural
{
"confidence": "unique",
"customer_class": "agricultural",
"results": [
{ "period": "off_peak", "next_period": "on_peak",
"next_change_at": "2026-07-15T17:00:00-07:00",
"rate_plan": { "code": "AG", "is_optional": false } },
{ "period": "off_peak", "next_period": "on_peak",
"next_change_at": "2026-07-17T17:00:00-07:00",
"rate_plan": { "code": "AG-F-I", "is_optional": true } }
]
}

Wednesday, July 15, 2026, 10:00 Pacific, ZIP 93637 (PG&E only). Schedule AG next peaks at 5 PM today. AG-F Option I — Wednesday and Thursday off — stays off-peak until Friday 5 PM. Option II and Option III are in the same response. AG sorts first, so results[0] is the wrong plan for an Option I account.

Current period, then the week’s windows

Live period for the loop. A timeline so the set lands on off-peak before the crew is already in the field.

One account, current period

Refresh at next_change_at. Free is current period only. Seasons, weekdays, and excluded holidays are already applied.

python · one well
# GET /api/v1/query/current?zip_code=93637
#     &customer_class=agricultural&rate_plan_id=…
period = result["period"]
next_at = result["next_change_at"]

if period in ("on_peak", "critical_peak"):
    hold_pumps()
elif period in ("off_peak", "super_off_peak"):
    run_pumps()
# mid_peak: decide per plan. Some winter blocks are only mid_peak.

refresh_at(next_at)

The week’s run windows

/query/forward returns period, start_at, end_at. Growth covers 7 days. Builder is the next 24 hours.

python · one set
# GET /api/v1/query/forward?zip_code=93637
#     &customer_class=agricultural&rate_plan_id=…&hours=168

for segment in timeline:
    if segment["period"] in ("off_peak", "super_off_peak"):
        schedule_run(segment["start_at"], segment["end_at"])

Pumps, wells, pivots, boosters

Wells and boosters

Hold through on_peak. Start again on off_peak. A single ZIP that refreshes at the boundary fits Free.

Center pivots

The set is hours long. Forward gives the off-peak stretches before you commit the water. Super-off-peak is a run, same as off-peak.

Winter mornings

Horry Electric agricultural irrigation is on-peak 3–6 PM, April through October, and 6–9 AM, November through March — every day.

Flexible off days

PG&E AG-F keeps 5–8 PM and drops two days. Option I is Wednesday and Thursday. Option II is the weekend. Option III is Monday and Friday.

Summer shoulders

SCE TOU-PA-2 is on-peak 4–9 PM on summer weekdays, holidays excluded. Those hours are mid-peak on summer weekends, and mid-peak from October through May, when 8 AM–4 PM is super-off-peak. The 5–8 PM option is TOU-PA-2-5TO8.

Demand stays yours

We tell you which period is active. We don’t return ¢/kWh, kW, or connected load. Horsepower, ratchets, and the water order stay in your controls.

Every ranch has a different clock

PG&E Schedule AG is 5–8 PM every day. SCE TOU-PA-2 is a summer weekday 4–9 PM. Montana-Dakota’s Wyoming irrigation option is weekdays 4–6 PM, all year. Navopache’s Arizona irrigation time-of-use is 8 AM–9 PM every day, all year.

Watch locations with a signed tou.period.changed POST. Plan the set with /query/forward (24 h on Builder, 7 days on Growth, 30 days on Business). A location is a distinct ZIP this billing cycle — fifty wells on one ZIP are one location, not fifty.

We still don’t send ¢/kWh or kW. Bill savings and hydraulic limits stay yours. Enterprise is unlimited locations and calls from $1,200/mo, with a dedicated engineer and a contractual uptime SLA.

GET /query/current
Live period, next_change_at, and next_period. Pass customer_class=agricultural and pin rate_plan_id. The first result is the first code, not the account.
GET /query/forward
Concrete timeline: period, start_at, end_at. Seasons, weekdays, and holidays already applied. Schedule the set from the windows.
tou.period.changed
Webhook on paid plans. One POST at each boundary for every watched ZIP. Deliveries do not count as API calls.
locations
Free 3 · Builder 100 · Growth 500 · Business 2,000 · Enterprise unlimited. Distinct ZIPs, not pumps. Hitting the cap is a 429, not an overage bill.

Frequently asked

  1. How do I run irrigation pumps on off-peak hours?

    Call GET /api/v1/query/current with the pump ZIP and customer_class=agricultural. Pin rate_plan_id to the schedule on the bill — a utility often has several agricultural plans, and the first result is not the account. Run on off_peak and super_off_peak. Hold on on_peak and critical_peak. Paid plans add /query/forward for the week’s windows and webhooks for the flip.

  2. Why pass customer_class=agricultural?

    The default class is residential. On PG&E, Schedule AG is on-peak 5–8 PM every day, while residential E-ELEC is 4–9 PM every day. SCE TOU-PA-2 is on-peak 4–9 PM on summer weekdays, holidays excluded, and mid-peak for those hours from October through May. Passing agricultural selects that table. The parameter is on every plan, including Free. See customer classes.

  3. Does this return ¢/kWh or pump demand charges?

    No. tou.tools returns period names and clock boundaries. Prices live in riders and baselines. Demand and connected load are on the bill, not in the period name. Flow, pressure, and the water order stay in your controls.

  4. Which plan for pumps across many ZIPs?

    Locations are distinct ZIPs, not pumps. Fifty wells on one ZIP are one location. Fifty ZIPs fit Builder on webhooks (100 locations). One endpoint can watch every location, and deliveries do not count as API calls. Polling 50 ZIPs every 15 minutes is ~144,000 calls a month and needs Growth. Unlimited is Enterprise; contact sales.

  5. What if the plan uses mid-peak, or flexible off-peak days?

    A hold that only watches on_peak misses some irrigation tariffs. Alabama Power Farming Irrigation encodes October through May, weekdays 7 AM–9 PM, as mid_peak, holidays excluded, with no on-peak rule in that season. Otter Tail irrigation Option 2 has no on_peak rule — the block is mid_peak. PG&E AG-F keeps 5–8 PM and drops two days: Option I Wednesday and Thursday, Option II Saturday and Sunday, Option III Monday and Friday. Pin the option on the bill.

  6. Will this work with my utility?

    If we have a seeded agricultural TOU plan for the utility that serves the ZIP, yes. Filter coverage by Agricultural. When a ZIP is ambiguous (common in Texas / ERCOT), the API returns every candidate plan instead of guessing — pass street, city, and state, or pin rate_plan_id. The same question is on the FAQ.

Start Free, Or Talk Enterprise

No credit card to try one ZIP. Contact sales when the pumps span unlimited locations and need an SLA.