Time-of-Use API FAQ's
Plans, quota, webhooks, what the API returns, and which call to make for your use case.
Plans
Which plan do I need for Home Assistant?
Free, if you follow the recipe: refresh at
next_change_at instead
of polling. That's a handful of calls per day and one ZIP — well inside
250 calls and 3 locations. A 15-minute poll is ~2,880 calls/month and will
exhaust Free. Recipe: /docs/#home-assistant.
Which plan for a 50-site charger fleet?
Builder, on webhooks. 50 sites fit the 75-location cap. One webhook endpoint
can watch every location on the plan, and deliveries do not count as API
calls. Polling those 50 sites every 15 minutes is ~144,000 calls/month and
needs Growth.
How many seats do I get?
Free and Builder are 1 seat. Growth is 5, Business is 15, Enterprise is
unlimited. Roles are owner, admin, and member. Everyone in the org shares
one quota pool — seats are people, not extra locations or calls.
Can I switch plans mid-month?
Yes. Upgrades take effect immediately and we prorate the difference. Downgrades
apply at the start of your next billing cycle so you don't lose paid-for capacity.
Is there an annual discount?
Annual billing is available on Growth and above — contact us for a quote. Enterprise
agreements are always annual.
Quota
What counts as a "unique location"?
A unique location is any distinct ZIP code or address you've queried in
the current billing period. Querying
94103 ten times in one day still
counts as one location. Street addresses in the same ZIP still count as that
ZIP. Locations reset at the start of each billing cycle.
What's the difference between a ZIP and a street address?
Pass a ZIP and we never call Geocodio. Pass
street,
city, or state and we geocode on a cache miss;
that consumes one geocode from a separate per-cycle cap: 25 on Free, 250 on
Builder, 1,500 on Growth, 7,500 on Business, unlimited on Enterprise. Cached
addresses are free. ZIP-only queries never consume a geocode. Hitting the cap
returns 429 (geocode_quota_exceeded) — we don't bill
an overage.
What happens if I exceed my monthly call limit?
Once you hit the call or location cap, further new usage returns
429 Too Many Requests. We don't auto-bill overages or silently
degrade. Free accounts get one email at 80% of the call cap per cycle. We
don't send a 100% email, on any plan. Paid plans see the 429
(with an upgrade hint) and no quota emails. Upgrade and the next call goes
through.
Does a 403 count against my call quota?
No. A
403 is a plan gate — for example an over-horizon
forward request — not a usage cap. Rejected calls
(400, 401, 403,
404, 422, 429) still appear
in the request log, but only 2xx responses debit the
call meter.
Does the MCP server count against my call quota?
Yes — every MCP tool invocation counts as one API call against the same key
and monthly quota as REST. Locations are deduplicated the same way. A chatty
agent loop can burn the Free 250-call cap in a single session.
What's in the request log?
Every REST and MCP call shows up in the dashboard request log as a paginated
list (10 per page): timestamp, endpoint, source, status code, and duration.
It does not include the location queried, the request or response body,
search, or CSV/JSON export. Plans differ only in how far back the log
reaches — 24 hours on Free up to 90 days on Business.
Webhooks
How do webhooks work, and what's the endpoint limit?
On every paid plan, we POST to your server whenever a TOU period changes
for a location you're watching — so you can react to peak/off-peak
transitions without polling. An endpoint is a destination URL that
receives those events; the limit is the number of distinct URLs you can
register:
3 on Builder, 10 on Growth,
25 on Business, and unlimited on Enterprise. The limit is on
endpoints only — each one can cover any of the locations included in your
plan, so you don't pick a separate webhook quota. Webhooks aren't available
on the Free plan. Product page: /webhooks/.
Do webhook deliveries count as API calls?
No. Server-side watches and the POSTs to your endpoints do not debit the
call meter. Watched ZIPs still count as unique locations, and you still have
an endpoint-URL cap. That's why a 50-site fleet fits Builder on webhooks but
not on a 15-minute poll.
The API
Do you offer pricing in $/kWh?
No. tou.tools returns TOU-specific data only — period names, period boundaries,
and schedules. Actual rate values vary by tariff rider, customer class, and
baseline allowance, which are out of scope. If you need dollar amounts, look them
up against your own bill or your utility's published schedule.
What period names do you return?
Every
period is one of off_peak,
mid_peak, on_peak,
super_off_peak, or critical_peak.
off_peak is the implicit default when no schedule
rule matches. Not every tariff uses every name — many are peak /
off-peak only. Docs:
/docs/#periods.
What does confidence: ambiguous mean?
Utility territories don't follow ZIP lines.
unique — one utility. ambiguous — the
ZIP overlaps more than one; every candidate is in
results. no_coverage — none mapped.
Pass street (plus city /
state) to geocode and narrow to the territory that
contains the point. If geocoding fails, the full ambiguous result
is returned — coverage is never dropped silently. Docs:
/docs/#resolution.
Why does a query return more than one rate plan?
results is every active TOU plan for that ZIP and
customer_class. We don't know which tariff the meter
is enrolled on — that's on the bill. Pick the plan the site
actually uses, or present the list. A ZIP can have several
residential TOU options at once.
How far ahead can I query?
GET /query/forward — and a future at on
/query/current — is gated by your plan's forward
schedule horizon. Free is current period only. Builder is 24 hours,
Growth 7 days, Business 30 days, Enterprise custom. Ask for more
than that and the call returns 403
(horizon_exceeded) with an upgrade hint — the window is
never silently clamped. Docs:
/docs/#forward.
Do I need a paid plan for customer_class=agricultural or ev?
No.
customer_class is a query parameter on every plan, including
Free: residential (default), commercial,
industrial, agricultural, ev. It
selects which rate plan we return for that ZIP, not a paid add-on.
How fast do you pick up tariff changes?
Utilities file tariff revisions on their own schedule, and new rules sometimes
take effect within days of being filed. To leave room for us to detect and
incorporate the change, the Accuracy Guarantee has a 14-day grace
window: responses served within 14 days of a tariff revision's effective
date aren't covered. The guarantee resumes for queries dated after the window.
The effective date — not the filing date or the date we learned of the change —
governs. See terms section 5.3.
Use cases
Can I plan battery charge and discharge windows?
Yes.
GET /query/forward returns a concrete period
timeline with start/end timestamps, out to your plan's horizon:
24 hours on Builder, 7 days on Growth, 30 days on
Business. Free is current period only. Pair it with webhooks so
dispatch reacts when the period actually flips. We still don't
return $/kWh — your value model stays yours. Docs:
/docs/#forward.
Do you return critical-peak events?
When the tariff publishes them,
period is
critical_peak. Webhooks fire on that transition the
same as any other boundary. Those windows are declared on a
limited number of days and can land with little notice — the
Accuracy Guarantee's 14-day grace still applies. Docs:
/docs/#periods.
Can device firmware poll every 15 minutes?
Don't. That's ~2,880 calls per device per month and will exhaust
Free (250) — at fleet scale it chews through Builder (25,000)
too. Resolve the utility at install (pass a street address if the
ZIP is
ambiguous), then refresh at
next_change_at, or use webhooks on a paid plan.
Unique locations equal installed units, not polls.
How do I run a portfolio of buildings?
Pass
customer_class=commercial or
industrial. Each distinct ZIP is one unique location
— about 1,500 sites fit Business. Watch them with webhooks
instead of a 15-minute poll. We tell you when on-peak is; we
don't compute kW demand charges.
How do agricultural TOU schedules work?
Pass
customer_class=agricultural. Ag clocks are often
seasonal and different hours than the residential plan on the
same ZIP — the default residential class is the
wrong table. Same endpoints as any other class: current, forward,
or webhooks. Not a paid add-on.
How do I connect an AI agent over MCP?
Point the client at
https://tou.tools/mcp with the
same tou_… API key you use for REST. Tools:
get_current_period, get_schedule,
get_forward_schedule,
list_utilities. Every tool call counts as one API
call — don't loop get_current_period in a chat
session or you'll burn the Free 250-call cap. Docs:
/docs/#mcp.
Do I need a credit card to start?
No. Free is $0, 3 locations, 250 calls/month, no card. Enough for
a weekend project if you refresh at
next_change_at instead of polling.