{"openapi":"3.1.0","info":{"title":"Water Heater Lookup API","version":"0.21.0","description":"Evidence-backed equipment lookup, canonical supported-identifier and provider-program directories, one-call read-only agent service planning, point-in-time official-source and operating status, privacy-safe deployed-action capabilities, freshness-qualified provider discovery, public provider records, corrections, privacy-first agent handoffs, and explicit-consent service requests. MCP clients can additionally read bounded methodology, supported-identifier, provider-program, source-status, operations-status, service-capabilities, and current-provider resources at /mcp without enumerating the provider directory."},"servers":[{"url":"https://waterheaterlookup.com"}],"paths":{"/api/v1/supported-identifiers":{"get":{"operationId":"getSupportedIdentifiers","summary":"Read supported identifier families and refusal boundaries","description":"Returns the canonical input-free directory of supported serial brands, aliases, narrowly published formats, executable examples, ambiguity rules, explicit unsupported brands, model-catalog matching, recall-screening rules, sources, and safety limitations. It performs no lookup or write and contains no provider, customer, account, or configuration data. Unlisted serial families remain unsupported.","responses":{"200":{"description":"Deterministic read-only identifier directory shared with the MCP supported-identifiers resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportedIdentifiersDirectory"}}}}}}},"/api/v1/provider-program":{"get":{"operationId":"getProviderProgram","summary":"Read provider plans, qualification, and commercial boundaries","description":"Returns the canonical input-free provider-program contract shared with MCP: founding-market price hypotheses, plan limits and features, authorized application and manual-review workflow, public eligibility, exact capability vocabulary, plan-neutral ordering and routing, billing boundaries, unfinished legal terms, guarantee limits, and privacy. It performs no application, checkout, lookup, contact, or write and does not establish that live billing is enabled.","responses":{"200":{"description":"Deterministic read-only provider-program directory shared with the MCP provider-program resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderProgramDirectory"}}}}}}},"/api/v1/source-status":{"get":{"operationId":"getOfficialSourceStatus","summary":"Check current official-source availability","description":"Probes fixed, non-user-specific ENERGY STAR and CPSC endpoints. Returns 503 when either required source cannot be confirmed. This is a point-in-time dependency check, not historical uptime, lookup evidence, a safety determination, or provider-network readiness.","responses":{"200":{"description":"Every required official source is currently reachable and structurally usable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfficialSourceStatusReport"}}}},"503":{"description":"One or more required official sources could not be confirmed; the response body identifies each source state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfficialSourceStatusReport"}}}}}}},"/api/v1/operations-status":{"get":{"operationId":"getOperationsStatus","summary":"Check current service operating status","description":"Returns fixed low-cardinality states for the application response, official sources, durable application storage, service intake, scheduled notification and provider-lifecycle work, and paid-provider billing configuration. HTTP 503 means at least one required production component is unavailable, not configured, pending its first heartbeat, or stale. The report accepts no input and exposes no configuration values, database address, private records, event identifiers, or processing volumes.","responses":{"200":{"description":"Required operating components are available, with optional bounded degradation disclosed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OperatingStatusReport"}}}},"503":{"description":"At least one required operating component is unavailable, unconfigured, pending, or stale","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OperatingStatusReport"}}}}}}},"/api/v1/capabilities":{"get":{"operationId":"getServiceCapabilities","summary":"Read current deployed-action capabilities","description":"Reports which read and write interfaces are enabled before a client submits provider or customer data. New handoffs and service requests can be operationally paused without disabling lookup, provider discovery, provider applications, corrections, or existing private request access. The low-cardinality report never returns configuration keys or values. A write-enabled state confirms only the expected durable-storage, managed-schema, traffic-control, and retry-safety configuration shape; it does not test actual table structure, grants, or database connectivity and does not establish legal approval, provider coverage, email delivery, billing, operator response, or production launch readiness.","responses":{"200":{"description":"Current privacy-safe action capability report","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceCapabilitiesReport"}}}}}}},"/api/v1/lookup":{"post":{"operationId":"lookupWaterHeater","summary":"Look up equipment and official recall candidates","description":"Runs independent exact model, supported serial-date, and live CPSC recall checks. Exact model status requires a current U.S.-market ENERGY STAR row whose complete normalized brand and model match without relying on certification wildcards. The server fetches a bounded catalog and matches locally rather than adding the entered model to the EPA request URL.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LookupInput"}}}},"responses":{"200":{"description":"Evidence report","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LookupResult"}}}},"400":{"description":"Invalid input"},"429":{"description":"Rate limit exceeded; inspect Retry-After and RateLimit-* headers"}}}},"/api/v1/service-plans":{"post":{"operationId":"planWaterHeaterService","summary":"Plan the next service step without creating a write","description":"Read-only composition for person-facing assistants. Runs sourced equipment lookup and, only when an exact five-digit ZIP is supplied, current eligibility-constrained provider discovery. Recall candidates and unavailable official sources take precedence in the deterministic navigation rule. Contact fields are rejected; the call creates no handoff, service request, or provider contact. It may increment the same low-cardinality aggregate outcome counts as the constituent reads.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentServicePlanInput"}}}},"responses":{"200":{"description":"Read-only evidence, provider state, deterministic next step, and explicit pre-write boundary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentServicePlan"}}}},"400":{"description":"Invalid equipment, ZIP, service-need, or unexpected field input"},"413":{"description":"Request body too large"},"429":{"description":"Rate limit exceeded; inspect Retry-After and RateLimit-* headers"}}}},"/api/v1/providers":{"get":{"operationId":"findProviders","summary":"Find current eligibility-constrained providers","description":"Requires an explicitly confirmed public customer-facing phone, exact ZIP eligibility, active lead capacity, current paid or time-bounded founding access, current structured license and insurance evidence, and provider confirmation within 90 days. Capability matching is exact after case and punctuation normalization. Service diagnosis and repair are one search family; fuel gas maps only to natural-gas. In service plans, heat-pump equipment uses the heat-pump provider capability, while other or unknown equipment fuel does not become a provider constraint. ZIP, brand, and every other capability remain unwidened. The coarse coverage state distinguishes current matches, active network building, and an exact ZIP outside active sourcing without exposing market identity, internal status, thresholds, demand counts, or private sourcing records. An empty result never proves that no qualified local professional exists. Returned phone values are public business contact; private application contact is never substituted. Eligible results are alphabetical; payment cannot override qualification or ranking. Responses may be stored only in a private client cache and must be revalidated before reuse; unchanged conditional requests return 304 after current eligibility is rechecked.","parameters":[{"name":"postal_code","in":"query","required":true,"schema":{"type":"string","pattern":"^[0-9]{5}$"}},{"name":"brand","in":"query","schema":{"type":"string"}},{"name":"fuel_type","in":"query","description":"Optional bounded fuel or technology constraint. gas is accepted as an alias only for natural-gas; the response query is canonicalized.","schema":{"type":"string","enum":["electric","natural-gas","gas","propane","heat-pump"]}},{"name":"service_need","in":"query","description":"Optional bounded service constraint. repair is accepted as an alias for the diagnosis/repair family; the response query is canonicalized.","schema":{"type":"string","enum":["diagnosis","repair","replacement","maintenance","recall-check"]}},{"name":"If-None-Match","in":"header","required":false,"description":"Optional weak ETag from a prior response. The server rechecks current eligibility; HTTP 304 means the privately cached representation is still current at X-Water-Heater-Lookup-Validated-At. A provider that is no longer current returns 404, never 304.","schema":{"type":"string"}}],"responses":{"200":{"description":"Current provider records plus bounded coverage state, ranking, and freshness policies","headers":{"ETag":{"description":"Weak validator for this public representation. It excludes generatedAt but changes when public result data changes.","schema":{"type":"string"}},"X-Water-Heater-Lookup-Validated-At":{"description":"Server time at which current eligibility was rechecked for this response.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderDirectoryResult"}}}},"304":{"description":"The privately cached representation is unchanged after current eligibility revalidation; no response body","headers":{"ETag":{"description":"Weak validator for this public representation. It excludes generatedAt but changes when public result data changes.","schema":{"type":"string"}},"X-Water-Heater-Lookup-Validated-At":{"description":"Server time at which current eligibility was rechecked for this response.","schema":{"type":"string","format":"date-time"}}}},"400":{"description":"Invalid ZIP, brand length, fuel type, or service need"},"429":{"description":"Rate limit exceeded; inspect Retry-After and RateLimit-* headers"}}}},"/api/v1/providers/{id}":{"get":{"operationId":"getProvider","summary":"Read a current public provider record","description":"Returns a current provider entity with an opaque public reference version. Send the prior weak ETag in If-None-Match to avoid retransmitting unchanged data, but revalidate immediately before presentation, contact, or routing. Responses are private-cache only and a provider that becomes non-current returns 404 rather than 304.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"If-None-Match","in":"header","required":false,"description":"Optional weak ETag from a prior response. The server rechecks current eligibility; HTTP 304 means the privately cached representation is still current at X-Water-Heater-Lookup-Validated-At. A provider that is no longer current returns 404, never 304.","schema":{"type":"string"}}],"responses":{"200":{"description":"Current public provider record","headers":{"ETag":{"description":"Weak validator for this public representation. It excludes generatedAt but changes when public result data changes.","schema":{"type":"string"}},"X-Water-Heater-Lookup-Validated-At":{"description":"Server time at which current eligibility was rechecked for this response.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["provider","rankingPolicy","generatedAt"],"properties":{"provider":{"$ref":"#/components/schemas/PublicProvider"},"rankingPolicy":{"type":"string"},"generatedAt":{"type":"string","format":"date-time"}}}}}},"304":{"description":"The privately cached representation is unchanged after current eligibility revalidation; no response body","headers":{"ETag":{"description":"Weak validator for this public representation. It excludes generatedAt but changes when public result data changes.","schema":{"type":"string"}},"X-Water-Heater-Lookup-Validated-At":{"description":"Server time at which current eligibility was rechecked for this response.","schema":{"type":"string","format":"date-time"}}}},"404":{"description":"Unknown or non-current profile; a stale validator never preserves visibility"},"429":{"description":"Rate limit exceeded; inspect Retry-After and RateLimit-* headers"}}}},"/api/v1/providers/{id}/corrections":{"post":{"operationId":"requestProviderCorrection","summary":"Privately challenge a public provider record","description":"Write action. The correction is held privately for operator review and does not automatically change the public profile. Exact retries return the original receipt; changed input under the same Idempotency-Key is rejected.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique opaque key for this action. Reuse it only to retry exactly unchanged input after an uncertain result; use a new key for every new or changed action. UUIDs are recommended. Raw keys are not stored.","schema":{"type":"string","minLength":16,"maxLength":128,"pattern":"^(?!.*[\"\\\\])[!-~]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderCorrection"}}}},"responses":{"201":{"description":"Correction queued or original receipt replayed","headers":{"Idempotency-Replayed":{"description":"true when this is the original completed receipt for an unchanged retry; false when the write was created by this request.","schema":{"type":"string","enum":["true","false"]}}}},"400":{"description":"Invalid input, consent, or retry key"},"404":{"description":"Unknown or non-current profile"},"409":{"description":"Idempotency-Key was already used with different input"},"429":{"description":"Rate limit exceeded; inspect Retry-After and RateLimit-* headers"},"503":{"description":"Durable write storage, retry safety, or production traffic controls not configured"}}}},"/api/v1/provider-applications":{"post":{"operationId":"applyToProviderNetwork","summary":"Submit a provider application for private operator review","description":"Write action containing business contact and qualification data. Submit only with the provider's explicit authorization. contactPhone is private review contact; publicPhone is a deliberately confirmed customer-facing number and is the only phone eligible for publication after activation. Service and fuel/technology values are bounded; repair is stored as diagnosis, and gas is stored as natural-gas. The server records insurance-attestation time and the displayed terms version (provider-and-site-terms-2026-08-14); no payment is taken and nothing becomes public until separate operator review, verification, commercial access, and activation. Exact retries return the original receipt without duplicating the application or notification. A fresh key may create a separate private application, but the neutral receipt never reveals whether email or license data matches another record.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique opaque key for this action. Reuse it only to retry exactly unchanged input after an uncertain result; use a new key for every new or changed action. UUIDs are recommended. Raw keys are not stored.","schema":{"type":"string","minLength":16,"maxLength":128,"pattern":"^(?!.*[\"\\\\])[!-~]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderApplication"}}}},"responses":{"201":{"description":"Private application created or original receipt replayed","headers":{"Idempotency-Replayed":{"description":"true when this is the original completed receipt for an unchanged retry; false when the write was created by this request.","schema":{"type":"string","enum":["true","false"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderApplicationReceipt"}}}},"400":{"description":"Invalid input, attestations, or retry key"},"409":{"description":"Private prospect invitation unavailable, or Idempotency-Key reused with changed input; no new application stored"},"429":{"description":"Rate limit exceeded; inspect Retry-After and RateLimit-* headers"},"503":{"description":"Durable application storage, retry safety, or production traffic controls not configured"}}}},"/api/v1/quote-requests":{"post":{"operationId":"requestServiceQuotes","summary":"Create an explicit-consent service request","description":"Write action. Contact details may be shared with up to three current eligible providers. After every qualification, geography, capability, freshness, access, and capacity gate passes, a request-specific deterministic rotation selects at most three providers. Plan, payment, business name, and public directory position do not affect this selection. A valid optional serviceHandoffToken atomically links and consumes a previously prepared agent handoff. The response includes a private, single-use status URL for the consenting consumer; do not log, index, or disclose it to another person. Exact retries return the original request and private status URL without duplicate provider notifications.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique opaque key for this action. Reuse it only to retry exactly unchanged input after an uncertain result; use a new key for every new or changed action. UUIDs are recommended. Raw keys are not stored.","schema":{"type":"string","minLength":16,"maxLength":128,"pattern":"^(?!.*[\"\\\\])[!-~]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"}}}},"responses":{"201":{"description":"Request created or original receipt replayed","headers":{"Idempotency-Replayed":{"description":"true when this is the original completed receipt for an unchanged retry; false when the write was created by this request.","schema":{"type":"string","enum":["true","false"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequestReceipt"}}}},"400":{"description":"Invalid input, consent, or retry key"},"409":{"description":"Agent handoff unavailable, or Idempotency-Key reused with changed input; no new request was stored"},"429":{"description":"Rate limit exceeded; inspect Retry-After and RateLimit-* headers"},"503":{"description":"Service intake operationally paused, or durable write storage, retry safety, or production traffic controls not configured; no new request stored"}}}},"/api/v1/service-handoffs":{"post":{"operationId":"prepareServiceRequestHandoff","summary":"Prepare a private agent-to-human service handoff","description":"Creates a 7-day one-time handoff. Before submission, the server stores only an opaque handoff ID, a one-way token hash, a private HMAC retry fingerprint, timestamps, and REST source. Service context stays in the URL fragment; no homeowner contact details are accepted. The user reviews the context and supplies their own contact details and consent on Water Heater Lookup. Exact retries return the original private link.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique opaque key for this action. Reuse it only to retry exactly unchanged input after an uncertain result; use a new key for every new or changed action. UUIDs are recommended. Raw keys are not stored.","schema":{"type":"string","minLength":16,"maxLength":128,"pattern":"^(?!.*[\"\\\\])[!-~]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceHandoffContext"}}}},"responses":{"201":{"description":"Private handoff prepared or original receipt replayed","headers":{"Idempotency-Replayed":{"description":"true when this is the original completed receipt for an unchanged retry; false when the write was created by this request.","schema":{"type":"string","enum":["true","false"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceHandoffReceipt"}}}},"400":{"description":"Invalid context or retry key"},"409":{"description":"Idempotency-Key was already used with different input"},"429":{"description":"Rate limit exceeded; inspect Retry-After and RateLimit-* headers"},"503":{"description":"Service intake operationally paused, or durable write storage, retry safety, or production traffic controls not configured; no new handoff stored"}}}}},"components":{"schemas":{"LookupInput":{"type":"object","required":["brand"],"anyOf":[{"required":["model"]},{"required":["serial"]}],"properties":{"brand":{"type":"string"},"model":{"type":"string"},"serial":{"type":"string"},"unitType":{"type":"string","enum":["tank","tankless","heat-pump","unknown"]},"fuelType":{"type":"string","enum":["electric","natural-gas","propane","other","unknown"]}}},"Source":{"type":"object","required":["title","publisher","url","accessedAt"],"properties":{"title":{"type":"string"},"publisher":{"type":"string"},"url":{"type":"string","format":"uri"},"accessedAt":{"type":"string","format":"date"}}},"SupportedIdentifierExample":{"type":"object","additionalProperties":false,"required":["serial","interpretation"],"properties":{"serial":{"type":"string"},"interpretation":{"type":"string"}}},"SupportedIdentifierFormat":{"type":"object","additionalProperties":false,"required":["id","label","cleanedPattern","examples","decodedFields","validation","source"],"properties":{"id":{"type":"string"},"label":{"type":"string"},"cleanedPattern":{"type":"string","description":"Anchored regular expression applied only after the documented serial normalization."},"examples":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/SupportedIdentifierExample"}},"decodedFields":{"type":"array","minItems":1,"items":{"type":"string"}},"validation":{"type":"string"},"source":{"$ref":"#/components/schemas/Source"}}},"SupportedSerialFamily":{"type":"object","additionalProperties":false,"required":["id","canonicalBrand","normalizedBrand","aliases","formats","ambiguity","limitations"],"properties":{"id":{"type":"string"},"canonicalBrand":{"type":"string"},"normalizedBrand":{"type":"string"},"aliases":{"type":"array","minItems":1,"items":{"type":"string"}},"formats":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/SupportedIdentifierFormat"}},"ambiguity":{"type":"string"},"limitations":{"type":"array","minItems":1,"items":{"type":"string"}}}},"SupportedIdentifiersDirectory":{"type":"object","additionalProperties":false,"required":["schemaVersion","interfaceVersion","reviewedAt","mode","inputGuidance","serialNormalization","serialFamilies","explicitlyUnsupported","modelCatalog","recallScreening","globalLimitations","privacy"],"properties":{"schemaVersion":{"type":"string","const":"1.0"},"interfaceVersion":{"type":"string","const":"0.21.0"},"reviewedAt":{"type":"string","format":"date"},"mode":{"type":"string","const":"read-only-reference"},"inputGuidance":{"type":"object","additionalProperties":false,"required":["required","preferred","unsupportedBehavior"],"properties":{"required":{"type":"string"},"preferred":{"type":"string"},"unsupportedBehavior":{"type":"string"}}},"serialNormalization":{"type":"object","additionalProperties":false,"required":["brand","serial","yearResolution"],"properties":{"brand":{"type":"string"},"serial":{"type":"string"},"yearResolution":{"type":"string"}}},"serialFamilies":{"type":"array","minItems":5,"maxItems":5,"items":{"$ref":"#/components/schemas/SupportedSerialFamily"}},"explicitlyUnsupported":{"type":"array","minItems":1,"items":{"type":"object","additionalProperties":false,"required":["brand","normalizedBrand","reason"],"properties":{"brand":{"type":"string"},"normalizedBrand":{"type":"string"},"reason":{"type":"string"}}}},"modelCatalog":{"type":"object","additionalProperties":false,"required":["evidenceRole","acceptedIdentifier","matchRule","statuses","noMatchMeaning","privacy","source"],"properties":{"evidenceRole":{"type":"string"},"acceptedIdentifier":{"type":"string"},"matchRule":{"type":"string"},"statuses":{"type":"array","items":{"type":"string","enum":["exact-match","no-match","ambiguous","unavailable","not-run"]}},"noMatchMeaning":{"type":"string"},"privacy":{"type":"string"},"source":{"$ref":"#/components/schemas/Source"}}},"recallScreening":{"type":"object","additionalProperties":false,"required":["evidenceRole","acceptedIdentifiers","matchRule","commonWordBrandRule","statuses","emptyResult","source"],"properties":{"evidenceRole":{"type":"string"},"acceptedIdentifiers":{"type":"array","items":{"type":"string"}},"matchRule":{"type":"string"},"commonWordBrandRule":{"type":"string"},"statuses":{"type":"array","items":{"type":"string","enum":["candidates-found","none-found","unavailable"]}},"emptyResult":{"type":"string"},"source":{"$ref":"#/components/schemas/Source"}}},"globalLimitations":{"type":"array","minItems":4,"items":{"type":"string"}},"privacy":{"type":"object","additionalProperties":false,"required":["acceptedInputs","writesPerformed","storedData","statement"],"properties":{"acceptedInputs":{"type":"array","maxItems":0},"writesPerformed":{"type":"boolean","const":false},"storedData":{"type":"array","maxItems":0},"statement":{"type":"string"}}}}},"ProviderProgramPlan":{"type":"object","additionalProperties":false,"required":["id","label","commercialStatus","price","exactServicePostalCodeLimit","features"],"properties":{"id":{"type":"string","enum":["core","network"]},"label":{"type":"string"},"commercialStatus":{"type":"string","const":"first-market-price-hypothesis"},"price":{"type":"object","additionalProperties":false,"required":["currency","amountCents","billingInterval"],"properties":{"currency":{"type":"string","const":"USD"},"amountCents":{"type":"integer","enum":[19900,39900]},"billingInterval":{"type":"string","const":"month"}}},"exactServicePostalCodeLimit":{"type":"integer","enum":[25,100]},"features":{"type":"array","minItems":4,"items":{"type":"string"}}}},"ProviderProgramDirectory":{"type":"object","additionalProperties":false,"required":["schemaVersion","interfaceVersion","reviewedAt","mode","audience","programStatus","plans","application","qualification","capabilities","discovery","billingAndTerms","guarantees","privacy"],"properties":{"schemaVersion":{"type":"string","const":"1.0"},"interfaceVersion":{"type":"string","const":"0.21.0"},"reviewedAt":{"type":"string","format":"date"},"mode":{"type":"string","const":"read-only-reference"},"audience":{"type":"string"},"programStatus":{"type":"object","additionalProperties":false,"required":["stage","pricing","statement"],"properties":{"stage":{"type":"string","const":"founding-provider-cohort"},"pricing":{"type":"string","const":"first-market-price-hypothesis"},"statement":{"type":"string"}}},"plans":{"type":"array","minItems":2,"maxItems":2,"items":{"$ref":"#/components/schemas/ProviderProgramPlan"}},"application":{"type":"object","additionalProperties":false,"required":["url","statusUrl","apiPath","writeBoundary","chargeAtApplication","planSelectionEffect","review","retrySafety","storedDataClasses"],"properties":{"url":{"type":"string","const":"/providers/apply"},"statusUrl":{"type":"string","const":"/providers/application-status"},"apiPath":{"type":"string","const":"/api/v1/provider-applications"},"writeBoundary":{"type":"string"},"chargeAtApplication":{"type":"boolean","const":false},"planSelectionEffect":{"type":"string"},"review":{"type":"string"},"retrySafety":{"type":"string"},"storedDataClasses":{"type":"array","minItems":6,"items":{"type":"string"}}}},"qualification":{"type":"object","additionalProperties":false,"required":["workflow","publicEligibility","evidenceMaximumAgeDays","evidenceValidityRule","profileConfirmationMaximumAgeDays"],"properties":{"workflow":{"type":"array","minItems":5,"maxItems":5,"items":{"type":"object","additionalProperties":false,"required":["id","label","consequence"],"properties":{"id":{"type":"string","enum":["received","qualification","decision","account","directory"]},"label":{"type":"string"},"consequence":{"type":"string"}}}},"publicEligibility":{"type":"array","minItems":6,"items":{"type":"string"}},"evidenceMaximumAgeDays":{"type":"integer","const":365},"evidenceValidityRule":{"type":"string"},"profileConfirmationMaximumAgeDays":{"type":"integer","const":90}}},"capabilities":{"type":"object","additionalProperties":false,"required":["storedServiceValues","acceptedServiceSearchValues","storedFuelValues","acceptedFuelSearchValues","matchingPolicy"],"properties":{"storedServiceValues":{"type":"array","items":{"type":"string","enum":["diagnosis","replacement","maintenance","recall-check"]}},"acceptedServiceSearchValues":{"type":"array","items":{"type":"string","enum":["diagnosis","repair","replacement","maintenance","recall-check"]}},"storedFuelValues":{"type":"array","items":{"type":"string","enum":["electric","natural-gas","propane","heat-pump"]}},"acceptedFuelSearchValues":{"type":"array","items":{"type":"string","enum":["electric","natural-gas","gas","propane","heat-pump"]}},"matchingPolicy":{"type":"string","const":"Capability matching is exact after case and punctuation normalization. Service diagnosis and repair are one search family; fuel gas maps only to natural-gas. In service plans, heat-pump equipment uses the heat-pump provider capability, while other or unknown equipment fuel does not become a provider constraint. ZIP, brand, and every other capability remain unwidened."}}},"discovery":{"type":"object","additionalProperties":false,"required":["publicOrdering","requestRouting","maximumInitialRequestAssignments","paymentEffect","coveragePolicy"],"properties":{"publicOrdering":{"type":"string"},"requestRouting":{"type":"string","const":"After every qualification, geography, capability, freshness, access, and capacity gate passes, a request-specific deterministic rotation selects at most three providers. Plan, payment, business name, and public directory position do not affect this selection."},"maximumInitialRequestAssignments":{"type":"integer","const":3},"paymentEffect":{"type":"string"},"coveragePolicy":{"type":"string","const":"Coverage state is based only on current eligible directory matches and whether the exact ZIP belongs to an onboarding, invite-only, or live Water Heater Lookup market. It exposes no market name, internal status, provider target, readiness threshold, demand count, or private sourcing record. No current match or active market does not mean that no qualified local professional exists. For an exact-ZIP search, the provider application URL carries only that already-supplied ZIP in a browser fragment for editable prefill; opening it creates no application, provider attribution, or additional market-demand record."}}},"billingAndTerms":{"type":"object","additionalProperties":false,"required":["checkoutBoundary","runtimeAuthority","foundingAccess","cancellationAndRefunds","terms"],"properties":{"checkoutBoundary":{"type":"string"},"runtimeAuthority":{"type":"string"},"foundingAccess":{"type":"string"},"cancellationAndRefunds":{"type":"string"},"terms":{"type":"object","additionalProperties":false,"required":["status","version","effectiveDate","permanentPath","currentPath"],"properties":{"status":{"type":"string","const":"launch-stage-draft-requires-counsel-review"},"version":{"type":"string","const":"provider-and-site-terms-2026-08-14"},"effectiveDate":{"type":"string","format":"date"},"permanentPath":{"type":"string","const":"/terms/provider-and-site-terms-2026-08-14"},"currentPath":{"type":"string","const":"/terms"}}}}},"guarantees":{"type":"object","additionalProperties":false,"required":["provided","limitations"],"properties":{"provided":{"type":"array","maxItems":0},"limitations":{"type":"array","minItems":3,"items":{"type":"string"}}}},"privacy":{"type":"object","additionalProperties":false,"required":["acceptedInputs","writesPerformed","storedData","statement"],"properties":{"acceptedInputs":{"type":"array","maxItems":0},"writesPerformed":{"type":"boolean","const":false},"storedData":{"type":"array","maxItems":0},"statement":{"type":"string"}}}}},"OfficialSourceCheck":{"type":"object","required":["id","role","status","checkedAt","source","message"],"properties":{"id":{"type":"string","enum":["energy-star-water-heaters","cpsc-water-heater-recalls"]},"role":{"type":"string","enum":["model-catalog","recall-screening"]},"status":{"type":"string","enum":["available","unavailable"]},"checkedAt":{"type":"string","format":"date-time"},"source":{"$ref":"#/components/schemas/Source"},"message":{"type":"string"}}},"OfficialSourceStatusReport":{"type":"object","required":["status","checkedAt","nextCheckAfter","sources","privacy","limitations"],"properties":{"status":{"type":"string","enum":["available","degraded","unavailable"]},"checkedAt":{"type":"string","format":"date-time"},"nextCheckAfter":{"type":"string","format":"date-time"},"sources":{"type":"array","minItems":2,"maxItems":2,"items":{"$ref":"#/components/schemas/OfficialSourceCheck"}},"privacy":{"type":"string"},"limitations":{"type":"array","items":{"type":"string"}}}},"OperatingStatusComponent":{"type":"object","required":["id","label","status","checkedAt","message"],"properties":{"id":{"type":"string","enum":["application","official-sources","database","service-intake","notification-worker","provider-lifecycle-worker","billing-webhook"]},"label":{"type":"string"},"status":{"type":"string","enum":["available","degraded","unavailable","not-configured","pending"]},"checkedAt":{"type":"string","format":"date-time"},"lastRunAt":{"type":"string","format":"date-time"},"message":{"type":"string"}}},"OperatingStatusReport":{"type":"object","required":["schemaVersion","status","checkedAt","nextCheckAfter","components","privacy","limitations"],"properties":{"schemaVersion":{"type":"string","const":"1.0"},"status":{"type":"string","enum":["available","degraded","unavailable"]},"checkedAt":{"type":"string","format":"date-time"},"nextCheckAfter":{"type":"string","format":"date-time"},"components":{"type":"array","minItems":7,"maxItems":7,"items":{"$ref":"#/components/schemas/OperatingStatusComponent"}},"privacy":{"type":"string"},"limitations":{"type":"array","items":{"type":"string"}}}},"ServiceActionCapability":{"type":"object","required":["id","label","mode","status","availabilityBasis","confirmationRequired","interfaces","dataConsequence","limitation"],"properties":{"id":{"type":"string","enum":["agent-service-plan","equipment-lookup","provider-discovery","service-handoff","direct-service-request","provider-application","provider-record-correction"]},"label":{"type":"string"},"mode":{"type":"string","enum":["read","write"]},"status":{"type":"string","enum":["enabled","disabled"]},"availabilityBasis":{"type":"string","enum":["interface-published","deployment-configured","deployment-read-only","operationally-paused"]},"confirmationRequired":{"type":"boolean"},"interfaces":{"type":"object","required":["rest"],"properties":{"rest":{"type":"string"},"mcp":{"type":"string"}}},"dataConsequence":{"type":"string"},"limitation":{"type":"string"},"preferredAlternative":{"type":"string"},"retryContract":{"type":"string"}}},"ServiceIntakeCapability":{"type":"object","required":["status","availabilityBasis","message"],"properties":{"status":{"type":"string","enum":["open","paused"]},"availabilityBasis":{"type":"string","enum":["default-open","operator-control","deployment-override","control-unavailable"]},"updatedAt":{"type":"string","format":"date-time"},"message":{"type":"string"}}},"ServiceCapabilitiesReport":{"type":"object","required":["schemaVersion","writeMode","generatedAt","serviceIntake","actions","privacy","limitations"],"properties":{"schemaVersion":{"type":"string","const":"1.2"},"writeMode":{"type":"string","enum":["enabled","partial","read-only"]},"generatedAt":{"type":"string","format":"date-time"},"serviceIntake":{"$ref":"#/components/schemas/ServiceIntakeCapability"},"actions":{"type":"array","minItems":7,"maxItems":7,"items":{"$ref":"#/components/schemas/ServiceActionCapability"}},"privacy":{"type":"string"},"limitations":{"type":"array","items":{"type":"string"}}}},"ModelCatalogCheck":{"type":"object","required":["status","checkedAt","source","matchRule"],"properties":{"status":{"type":"string","enum":["exact-match","no-match","ambiguous","unavailable","not-run"]},"checkedAt":{"type":"string","format":"date-time"},"source":{"$ref":"#/components/schemas/Source"},"matchRule":{"type":"string"}}},"ModelRecord":{"type":"object","required":["brand","model","type","fuel","source"],"properties":{"brand":{"type":"string"},"model":{"type":"string"},"type":{"type":"string","enum":["tank","tankless","heat-pump"]},"fuel":{"type":"string","enum":["electric","natural-gas","propane","natural-gas-or-propane","other"]},"capacityGallons":{"type":"number"},"uef":{"type":"number"},"firstHourRating":{"type":"number"},"maxGpm":{"type":"number"},"certificationId":{"type":"string"},"certifiedAt":{"type":"string","description":"Certification date exactly as published by ENERGY STAR; the source value may not include a timezone."},"markets":{"type":"array","items":{"type":"string"}},"source":{"$ref":"#/components/schemas/Source"}}},"LookupResult":{"type":"object","required":["query","identity","manufacture","recalls","nextActions","limitations","generatedAt"],"properties":{"query":{"type":"object","required":["brand","serialProvided"],"properties":{"brand":{"type":"string"},"model":{"type":"string"},"serialProvided":{"type":"boolean"}}},"identity":{"type":"object","required":["status","catalog","message"],"properties":{"status":{"type":"string","enum":["exact-model","brand-only","unresolved"]},"record":{"$ref":"#/components/schemas/ModelRecord"},"catalog":{"$ref":"#/components/schemas/ModelCatalogCheck"},"message":{"type":"string"}}},"manufacture":{"type":"object","required":["status","confidence","candidates","explanation"],"properties":{"status":{"type":"string","enum":["decoded","ambiguous","unsupported","invalid"]},"confidence":{"type":"string","enum":["exact","high","possible","unsupported"]},"candidates":{"type":"array","items":{"type":"object","required":["year","label"],"properties":{"year":{"type":"integer"},"month":{"type":"integer"},"week":{"type":"integer"},"label":{"type":"string"}}}},"explanation":{"type":"string"},"source":{"$ref":"#/components/schemas/Source"}}},"recalls":{"type":"object","required":["status","candidates","message","checkedAt","source"],"properties":{"status":{"type":"string","enum":["candidates-found","none-found","unavailable"]},"candidates":{"type":"array","items":{"type":"object","required":["recallId","recallNumber","title","recallDate","url","hazard","productNames","matchReasons","confidence"],"properties":{"recallId":{"type":"integer"},"recallNumber":{"type":"string"},"title":{"type":"string"},"recallDate":{"type":"string"},"url":{"type":"string","format":"uri"},"hazard":{"type":"string"},"productNames":{"type":"array","items":{"type":"string"}},"matchReasons":{"type":"array","items":{"type":"string"}},"confidence":{"type":"string","enum":["high","possible"]}}}},"message":{"type":"string"},"checkedAt":{"type":"string","format":"date-time"},"source":{"$ref":"#/components/schemas/Source"}}},"nextActions":{"type":"array","items":{"type":"object","required":["kind","label"],"properties":{"kind":{"type":"string","enum":["manufacturer","recall","provider","emergency"]},"label":{"type":"string"},"href":{"type":"string","format":"uri"}}}},"limitations":{"type":"array","items":{"type":"string"}},"generatedAt":{"type":"string","format":"date-time"}}},"AgentServicePlanInput":{"type":"object","additionalProperties":false,"required":["brand"],"anyOf":[{"required":["model"]},{"required":["serial"]}],"properties":{"brand":{"type":"string","maxLength":80},"model":{"type":"string","maxLength":120},"serial":{"type":"string","maxLength":120},"unitType":{"type":"string","enum":["tank","tankless","heat-pump","unknown"]},"fuelType":{"type":"string","enum":["electric","natural-gas","propane","other","unknown"]},"postalCode":{"type":"string","pattern":"^[0-9]{5}$","description":"Optional exact ZIP. Provider discovery is not run when omitted."},"serviceNeed":{"type":"string","enum":["diagnosis","repair","replacement","maintenance","recall-check"],"description":"repair is accepted as an alias for the diagnosis/repair provider-search family."}}},"ProviderCoverage":{"type":"object","required":["status","message","providerApplicationUrl","policy"],"properties":{"status":{"type":"string","enum":["current-matches","network-building","outside-active-market","not-run"]},"message":{"type":"string"},"providerApplicationUrl":{"type":"string","format":"uri","description":"For an exact-ZIP search, carries only the already-supplied ZIP in the coverage_zip URL fragment for editable browser-local prefill. Opening it creates no application, provider attribution, or additional market-demand record; a provider must review the complete application before submitting."},"policy":{"type":"string","const":"Coverage state is based only on current eligible directory matches and whether the exact ZIP belongs to an onboarding, invite-only, or live Water Heater Lookup market. It exposes no market name, internal status, provider target, readiness threshold, demand count, or private sourcing record. No current match or active market does not mean that no qualified local professional exists. For an exact-ZIP search, the provider application URL carries only that already-supplied ZIP in a browser fragment for editable prefill; opening it creates no application, provider attribution, or additional market-demand record."}}},"AgentProviderSearch":{"type":"object","required":["status","query","providers","count","coverage","constraintPolicy","rankingPolicy","freshnessPolicy"],"properties":{"status":{"type":"string","enum":["not-run","some","none"]},"query":{"type":"object","description":"Canonical provider constraints actually applied. Alias inputs are not echoed as distinct capabilities.","properties":{"postalCode":{"type":"string","pattern":"^[0-9]{5}$"},"postalCodeProvided":{"type":"boolean","const":false},"brand":{"type":"string"},"fuelType":{"type":"string","enum":["electric","natural-gas","propane","heat-pump"]},"serviceNeed":{"type":"string","enum":["diagnosis","replacement","maintenance","recall-check"]}}},"providers":{"type":"array","items":{"$ref":"#/components/schemas/PublicProvider"}},"count":{"type":"integer","minimum":0},"coverage":{"$ref":"#/components/schemas/ProviderCoverage"},"constraintPolicy":{"type":"string","const":"Capability matching is exact after case and punctuation normalization. Service diagnosis and repair are one search family; fuel gas maps only to natural-gas. In service plans, heat-pump equipment uses the heat-pump provider capability, while other or unknown equipment fuel does not become a provider constraint. ZIP, brand, and every other capability remain unwidened."},"rankingPolicy":{"type":"string"},"freshnessPolicy":{"type":"string"},"generatedAt":{"type":"string","format":"date-time"},"reason":{"type":"string"}}},"AgentServicePlanRecommendation":{"type":"object","required":["id","label","reason"],"properties":{"id":{"type":"string","enum":["review-recall-candidates","review-source-unavailability","review-current-providers","no-current-eligible-provider","collect-exact-postal-code"]},"label":{"type":"string"},"reason":{"type":"string"}}},"AgentServicePlanWriteBoundary":{"type":"object","required":["performed","acceptedContactFields","message","beforeAnyWrite","preferred","direct"],"properties":{"performed":{"type":"boolean","const":false},"acceptedContactFields":{"type":"array","maxItems":0},"message":{"type":"string"},"beforeAnyWrite":{"type":"array","minItems":3,"maxItems":3,"items":{"type":"string"}},"preferred":{"type":"object","required":["rest","mcp","consequence"],"properties":{"rest":{"type":"string","const":"POST /api/v1/service-handoffs"},"mcp":{"type":"string","const":"prepare_service_request_handoff"},"consequence":{"type":"string"}}},"direct":{"type":"object","required":["rest","mcp","consequence"],"properties":{"rest":{"type":"string","const":"POST /api/v1/quote-requests"},"mcp":{"type":"string","const":"request_service_quotes"},"consequence":{"type":"string"}}}}},"AgentServicePlan":{"type":"object","required":["schemaVersion","mode","equipment","providerSearch","recommendation","writeBoundary","privacy","limitations","generatedAt"],"properties":{"schemaVersion":{"type":"string","const":"1.0"},"mode":{"type":"string","const":"read-only"},"equipment":{"$ref":"#/components/schemas/LookupResult"},"providerSearch":{"$ref":"#/components/schemas/AgentProviderSearch"},"recommendation":{"$ref":"#/components/schemas/AgentServicePlanRecommendation"},"writeBoundary":{"$ref":"#/components/schemas/AgentServicePlanWriteBoundary"},"privacy":{"type":"string"},"limitations":{"type":"array","items":{"type":"string"}},"generatedAt":{"type":"string","format":"date-time"}}},"ProviderReference":{"type":"object","required":["version","mustRevalidate","guidance"],"properties":{"version":{"type":"string","pattern":"^whl-provider-v1-[a-f0-9]{32}$","description":"Opaque version derived only from the public provider representation. It is a comparison hint, not permission to skip revalidation."},"mustRevalidate":{"type":"boolean","const":true},"guidance":{"type":"string"}}},"PublicProvider":{"type":"object","required":["id","profileUrl","recordUrl","businessName","phone","licenseState","brands","serviceTypes","fuelTypes","postalCodes","serviceRadiusMiles","emergencyService","qualification","reference"],"properties":{"id":{"type":"string","format":"uuid"},"profileUrl":{"type":"string","format":"uri","description":"Human-readable current profile."},"recordUrl":{"type":"string","format":"uri","description":"REST current-record reread path. Reread immediately before presentation, contact, or routing."},"businessName":{"type":"string"},"phone":{"type":"string","description":"Provider-confirmed public customer-facing phone. Private application and review contact numbers are never substituted."},"website":{"type":"string","format":"uri"},"licenseState":{"type":"string"},"brands":{"type":"array","items":{"type":"string"}},"serviceTypes":{"type":"array","items":{"type":"string"}},"fuelTypes":{"type":"array","items":{"type":"string"}},"postalCodes":{"type":"array","items":{"type":"string","pattern":"^[0-9]{5}$"}},"serviceRadiusMiles":{"type":"integer"},"emergencyService":{"type":"boolean"},"qualification":{"type":"object","required":["status","operatorReview","verifiedAt","verificationDueAt","profileConfirmedAt","profileConfirmationDueAt","disclaimer"],"properties":{"status":{"type":"string","const":"current"},"operatorReview":{"type":"string"},"verifiedAt":{"type":"string","format":"date-time"},"verificationDueAt":{"type":"string","format":"date-time"},"profileConfirmedAt":{"type":"string","format":"date-time"},"profileConfirmationDueAt":{"type":"string","format":"date-time"},"disclaimer":{"type":"string"}}},"reference":{"$ref":"#/components/schemas/ProviderReference"}}},"ProviderDirectoryResult":{"type":"object","required":["query","providers","count","coverage","constraintPolicy","rankingPolicy","freshnessPolicy","generatedAt"],"properties":{"query":{"type":"object","required":["postalCode"],"description":"Canonical constraints actually applied. Alias inputs are not echoed as distinct capabilities.","properties":{"postalCode":{"type":"string","pattern":"^[0-9]{5}$"},"brand":{"type":"string"},"fuelType":{"type":"string","enum":["electric","natural-gas","propane","heat-pump"]},"serviceNeed":{"type":"string","enum":["diagnosis","replacement","maintenance","recall-check"]}}},"providers":{"type":"array","items":{"$ref":"#/components/schemas/PublicProvider"}},"count":{"type":"integer","minimum":0},"coverage":{"$ref":"#/components/schemas/ProviderCoverage"},"constraintPolicy":{"type":"string","const":"Capability matching is exact after case and punctuation normalization. Service diagnosis and repair are one search family; fuel gas maps only to natural-gas. In service plans, heat-pump equipment uses the heat-pump provider capability, while other or unknown equipment fuel does not become a provider constraint. ZIP, brand, and every other capability remain unwidened."},"rankingPolicy":{"type":"string"},"freshnessPolicy":{"type":"string"},"generatedAt":{"type":"string","format":"date-time"}}},"ProviderCorrection":{"type":"object","required":["requesterName","requesterEmail","relationship","category","details","consent"],"properties":{"requesterName":{"type":"string","maxLength":100},"requesterEmail":{"type":"string","format":"email","maxLength":160},"relationship":{"type":"string","enum":["provider","customer","other"]},"category":{"type":"string","enum":["contact","coverage","capability","verification","other"]},"details":{"type":"string","maxLength":2000},"consent":{"type":"boolean","const":true}}},"ProviderApplication":{"type":"object","required":["businessName","contactName","email","contactPhone","publicPhone","licenseNumber","licenseState","brands","serviceTypes","fuelTypes","postalCodes","serviceRadiusMiles","emergencyService","insuranceAttested","plan","termsAccepted"],"properties":{"businessName":{"type":"string","maxLength":120},"contactName":{"type":"string","maxLength":100},"email":{"type":"string","format":"email","maxLength":160},"contactPhone":{"type":"string","maxLength":40,"description":"Private application and operator-review phone. It is not published or used as a fallback public number."},"publicPhone":{"type":"string","maxLength":40,"description":"Customer-facing business phone explicitly authorized for publication after activation. Repeat contactPhone only when customers should call the same number."},"website":{"type":"string","format":"uri","maxLength":250},"licenseNumber":{"type":"string","maxLength":80},"licenseState":{"type":"string","pattern":"^[A-Za-z]{2}$"},"brands":{"type":"array","minItems":1,"maxItems":20,"items":{"type":"string"}},"serviceTypes":{"type":"array","minItems":1,"maxItems":20,"description":"Bounded provider capability values. repair is accepted as an alias and stored as diagnosis.","items":{"type":"string","enum":["diagnosis","repair","replacement","maintenance","recall-check"]}},"fuelTypes":{"type":"array","minItems":1,"maxItems":10,"description":"Bounded provider fuel or technology values. gas is accepted as an alias and stored as natural-gas.","items":{"type":"string","enum":["electric","natural-gas","gas","propane","heat-pump"]}},"postalCodes":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","pattern":"^[0-9]{5}$"},"description":"Core supports at most 25 exact ZIPs; Network supports at most 100."},"serviceRadiusMiles":{"type":"integer","minimum":1,"maximum":250},"emergencyService":{"type":"boolean"},"insuranceAttested":{"type":"boolean","const":true},"plan":{"type":"string","enum":["core","network"]},"notes":{"type":"string","maxLength":1200},"termsAccepted":{"type":"boolean","const":true,"description":"Accepts the terms displayed at https://waterheaterlookup.com/terms/provider-and-site-terms-2026-08-14; the server records version provider-and-site-terms-2026-08-14."},"prospectInvitationToken":{"type":"string","pattern":"^[a-fA-F0-9]{64}$","description":"Optional private one-time prospect invitation token obtained from the URL fragment."}}},"ProviderApplicationReceipt":{"type":"object","description":"Private neutral receipt. It intentionally contains no duplicate-identity or existing-application signal.","required":["applicationId","status","billingAvailable","attributedInvitation","termsAcceptance","insuranceAttestedAt","idempotencyReplayed","message"],"properties":{"applicationId":{"type":"string","format":"uuid"},"status":{"type":"string","const":"applied"},"billingAvailable":{"type":"boolean","description":"Whether the selected plan's complete checkout lifecycle is configured; this does not mean approval or billing has begun."},"attributedInvitation":{"type":"boolean"},"termsAcceptance":{"type":"object","required":["version","acceptedAt","surface","documentPath"],"properties":{"version":{"type":"string"},"acceptedAt":{"type":"string","format":"date-time"},"surface":{"type":"string","const":"provider-application"},"documentPath":{"type":"string","description":"Permanent same-origin path for the accepted terms version."}}},"insuranceAttestedAt":{"type":"string","format":"date-time"},"idempotencyReplayed":{"type":"boolean"},"message":{"type":"string"}}},"QuoteRequest":{"type":"object","required":["serviceNeed","postalCode","name","email","consent"],"properties":{"brand":{"type":"string"},"model":{"type":"string"},"unitType":{"type":"string"},"fuelType":{"type":"string"},"serviceNeed":{"type":"string"},"postalCode":{"type":"string","pattern":"^[0-9]{5}$"},"name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"details":{"type":"string"},"consent":{"type":"boolean","const":true},"serviceHandoffToken":{"type":"string","pattern":"^[a-fA-F0-9]{64}$","description":"Optional private one-time agent handoff token. Human clients receive it in the handoff URL fragment."}}},"QuoteRequestReceipt":{"type":"object","required":["requestId","status","matchedProviderCount","requestOrigin","statusUrl","statusAccessExpiresAt","idempotencyReplayed","message"],"properties":{"requestId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["new","assigned","contacted","closed"]},"matchedProviderCount":{"type":"integer","minimum":0,"maximum":3},"requestOrigin":{"type":"string","enum":["direct","agent-direct","agent-handoff"]},"statusUrl":{"type":"string","format":"uri","description":"Private single-use consumer status link. The token is carried in the URL fragment so it is not sent in the HTTP request."},"statusAccessExpiresAt":{"type":"string","format":"date-time"},"idempotencyReplayed":{"type":"boolean"},"message":{"type":"string"}}},"ServiceHandoffContext":{"type":"object","required":["serviceNeed","postalCode"],"properties":{"brand":{"type":"string","maxLength":80},"model":{"type":"string","maxLength":120},"unitType":{"type":"string","enum":["tank","tankless","heat-pump","unknown"]},"fuelType":{"type":"string","enum":["electric","natural-gas","propane","other","unknown"]},"serviceNeed":{"type":"string","enum":["diagnosis","replacement","maintenance","recall-check"]},"postalCode":{"type":"string","pattern":"^[0-9]{5}$"}}},"ServiceHandoffReceipt":{"type":"object","required":["handoffUrl","expiresAt","idempotencyReplayed","storedBeforeOpen","message"],"properties":{"handoffUrl":{"type":"string","format":"uri","description":"Private URL whose fragment contains the token and non-contact service context."},"expiresAt":{"type":"string","format":"date-time"},"idempotencyReplayed":{"type":"boolean"},"storedBeforeOpen":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}}}}},"externalDocs":{"description":"Agent integration, methodology, and source policy","url":"https://waterheaterlookup.com/agents"}}