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.
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.
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.
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.
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.
How it works
One REST call for the live period. A forward timeline for the irrigation set. A webhook when the period actually flips.
customer_class=agricultural. Add street, city, and state when the ZIP is shared by two utilities. The class is on every plan, including Free.
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.
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.
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.
A booster or a single well on one ZIP. Refresh at next_change_at. That’s a handful of calls a day — inside Free (500 calls, 3 locations).
A pivot needs the windows ahead of the water order. /query/forward is 24 hours on Builder, 7 days on Growth, 30 days on Business.
A grower or a pump controller across utilities. Each ZIP is its own clock. Webhooks, not a 15-minute poll of every site.
Many ZIPsInstall
Live period for the loop. A timeline so the set lands on off-peak before the crew is already in the field.
Refresh at next_change_at. Free is current period only.
Seasons, weekdays, and excluded holidays are already applied.
# 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)
/query/forward returns period, start_at, end_at.
Growth covers 7 days. Builder is the next 24 hours.
# 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"])
What moves
Hold through on_peak. Start again on off_peak. A single ZIP that refreshes at the boundary fits Free.
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.
Horry Electric agricultural irrigation is on-peak 3–6 PM, April through October, and 6–9 AM, November through March — every day.
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.
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.
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.
Many ZIPs
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.
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.
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.
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.
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.
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.
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.
No credit card to try one ZIP. Contact sales when the pumps span unlimited locations and need an SLA.