# TexasElectricity.org comparison API v2 HTML guide: https://texaselectricity.org/developers POST https://texaselectricity.org/api/v2/compare Content-Type: application/json No account or API key. Server-to-server access; POST responses are not cached. ## Request {"zip":"75001","monthly_usage_kwh":{"january":800,"july":1600,"august":1700}} zip is a five-digit string. monthly_usage_kwh has one to twelve full lowercase month names and non-negative whole-kWh numbers. Omit unavailable months. Zero is real usage, not missing data. Null, fractions, negative values, unknown fields, unknown month names and empty usage are rejected. Maximum body: 4096 UTF-8 bytes. Optional limit: integer 1–100, default 5. Set 100 for a broader comparison. coverage.returned_plans and has_more describe truncation; renewable_pct is the recorded percentage (0–100), or null when unavailable. Null is not zero. Optional territory: Oncor, CenterPoint, AEP Central, AEP North, TNMP, or LPL. When provided, it must match the ZIP lookup. Never infer a territory from a ZIP that has several matches: ask which delivery company appears on the bill. ## Results Every JSON response has schema_version "2.1". - estimates_available: eligible plans ranked by unrounded annual cost (five by default). - no_eligible_plans: the ZIP resolves but there are no eligible plans. - territory_required: no prices; use territory_options to ask the customer and resend the same ZIP and usage with territory set to their choice. - zip_not_supported: no prices; check the ZIP/provider. This means no match in our lookup, not proof that a particular address lacks retail choice. All four outcomes use HTTP 200. HTTP 400 rejects invalid input or a territory that does not match the ZIP; 413 rejects oversized bodies; 415 requires JSON; 503 means data is unavailable or incomplete. Retry 503 later. GET on the compare endpoint returns 405; use POST. A tool unable to POST is not an API outage. ## Usage and scope The same website estimator preserves supplied months and fills omitted months using Texas-wide seasonal factors, not ZIP-specific or North Texas factors. usage.supplied_months and estimated_months identify which is which; each monthly bill also has usage_estimated. At least one actual month is required. More supplied months can improve the estimate. All six supported territories; residential fixed-rate plans with exactly 12-month terms. No whole-market or per-address eligibility guarantee. coverage reports the catalog size and exclusions before the requested results are selected. website_unfiltered_plans = website_featured_plans + website_other_plans; the website shows its top three separately from the other-plans section. Do not compare that other-plans count alone with active_territory_plans_read. Annual costs use the supplied/estimated January-December profile, not a contract starting on a particular date. Current delivery charges are held constant for all months. Round prices to cents only for display. The annual cost uses unrounded months, so displayed monthly amounts can sum to a few cents different. ## Pricing and freshness We refresh our plan catalog daily using PowerToChoose. Unchanged listings retain previously validated pricing. Lead with freshness.summary for returned listings; refresh_status_explanation separates overall run status from plan checks. Use each plan's freshness.summary and listing_check: within_24_hours, older_than_24_hours, or unknown. The check is backed by an exact persisted plan/run link and completed run timestamps captured at build time. A different stage failing does not erase a plan's completed listing check. run_evidence.run_status describes the entire run, not each returned plan. Times use the run start as a conservative proxy, not the exact per-plan fetch. Unknown means the API lacks matching check evidence; do not call a plan stale solely on that basis. pricing_validated_at is separate from listing freshness. An older pricing-validation date alone does not mean the offer is outdated. current_efl_fetch_status is not_established_by_this_api: pricing passed validation, but the API does not establish a new EFL fetch at request time. generated_at is response time, not a source-check time. Confirm current provider terms to enroll. Costs include modeled energy, provider base fees, delivery charges, minimum-usage fees and setup fees spread over twelve months. Conditional credits assume their requirements are met. Inspect credit_windows, bill_credit_thresholds, cliff_warnings and special_terms. Missing terms do not establish no conditions. Excluded: claim-required rebates, cancellation charges, deposits, separately assessed taxes and unmodeled ancillary fees. Future delivery changes, eligibility and provider billing/rounding remain unknown. A zero provider base fee does not mean there is no fixed delivery charge. Compare cancellation fees at the same number of months remaining: $20/month remaining exceeds $150 at eight or more months. Equal estimated costs do not establish identical contract terms. No enrollment or provider contact occurs. ## Privacy and compatibility Send only ZIP, usage, optional territory and limit; no name, address, account number or billing document. Request bodies are not logged or persisted by the application; hosting/network infrastructure may retain ordinary metadata. Server-side GA counts API requests by version, outcome, territory, result count and response time. No ZIP, usage figures, caller IP or caller identifier is sent by API analytics; no browser cookies are used. Returned plan URLs contain usage figures. There is no browser CORS contract or availability SLA. Version 1 remains unchanged at /api/v1/compare for Oncor with twelve supplied months.