{
  "openapi": "3.0.0",
  "paths": {
    "/public/links/{slug}": {
      "get": {
        "description": "Retrieve public information about a shareable link, including the service address and property name. This endpoint does not require authentication.",
        "operationId": "PublicLinksController_findBySlug",
        "parameters": [
          {
            "name": "slug",
            "required": true,
            "in": "path",
            "description": "The unique link identifier (from the URL)",
            "schema": {
              "example": "abc123",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Link details"
          },
          "400": {
            "description": "Link is no longer active",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Link not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error. Safe to retry idempotent requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Get link details",
        "tags": [
          "public"
        ]
      }
    },
    "/public/links/{slug}/offers": {
      "get": {
        "description": "Retrieve all service offers available for the address associated with this link. Offers are grouped by category (internet, electricity, other). This endpoint does not require authentication.",
        "operationId": "PublicLinksController_getOffers",
        "parameters": [
          {
            "name": "slug",
            "required": true,
            "in": "path",
            "description": "The unique link identifier (from the URL)",
            "schema": {
              "example": "abc123",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Available offers grouped by category"
          },
          "400": {
            "description": "Link is no longer active",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Link not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error. Safe to retry idempotent requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Get available offers for a link",
        "tags": [
          "public"
        ]
      }
    },
    "/public/links/{slug}/orders": {
      "post": {
        "description": "Create a new order for the selected service offers. The order will be associated with the reseller who created the link. This endpoint does not require authentication.",
        "operationId": "PublicLinksController_createOrder",
        "parameters": [
          {
            "name": "slug",
            "required": true,
            "in": "path",
            "description": "The unique link identifier (from the URL)",
            "schema": {
              "example": "abc123",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePublicOrderDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Order successfully created"
          },
          "400": {
            "description": "Invalid order data or link is inactive",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Link not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error. Safe to retry idempotent requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Submit an order via a shareable link",
        "tags": [
          "public"
        ]
      }
    },
    "/public/shop/offers": {
      "get": {
        "description": "Returns active, consumer-enabled offers, optionally filtered by ZIP/city/state (coverage-checked through the offer's markets) and category. Unauthenticated — backs the public /shop storefront.",
        "operationId": "PublicShopController_listOffers",
        "parameters": [
          {
            "name": "zip",
            "required": false,
            "in": "query",
            "description": "ZIP code to browse",
            "schema": {
              "example": "78701",
              "type": "string"
            }
          },
          {
            "name": "city",
            "required": false,
            "in": "query",
            "schema": {
              "example": "Austin",
              "type": "string"
            }
          },
          {
            "name": "state",
            "required": false,
            "in": "query",
            "schema": {
              "example": "TX",
              "type": "string"
            }
          },
          {
            "name": "category",
            "required": false,
            "in": "query",
            "schema": {
              "example": "internet",
              "type": "string",
              "enum": [
                "internet",
                "electricity",
                "other"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching consumer offers"
          },
          "500": {
            "description": "Unexpected server error. Safe to retry idempotent requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Browse consumer-enabled offers",
        "tags": [
          "public"
        ]
      }
    },
    "/public/shop/offers/{publicSlug}": {
      "get": {
        "description": "Full pricing/compliance detail for one consumer-enabled offer. Pass `zip` to re-check coverage for that ZIP. Unauthenticated.",
        "operationId": "PublicShopController_getOffer",
        "parameters": [
          {
            "name": "publicSlug",
            "required": true,
            "in": "path",
            "schema": {
              "example": "fiber-500-by-acme",
              "type": "string"
            }
          },
          {
            "name": "zip",
            "required": false,
            "in": "query",
            "description": "ZIP the shopper is browsing from — when present, the response includes an `available` flag re-checking coverage for this specific ZIP.",
            "schema": {
              "example": "78701",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Offer detail"
          },
          "404": {
            "description": "Offer not found or not consumer-enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error. Safe to retry idempotent requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Get a consumer offer by its public slug",
        "tags": [
          "public"
        ]
      }
    },
    "/public/shop/serviceability": {
      "post": {
        "description": "Given a full street address, returns per-offer serviceability + exact price for offers whose markets reference an external serviceability source. Layered on top of ZIP coverage (not a gate) — offers without a source are simply absent from the result map. Unauthenticated.",
        "operationId": "PublicShopController_checkServiceability",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ShopServiceabilityDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Per-offer serviceability detail keyed by offer id"
          },
          "500": {
            "description": "Unexpected server error. Safe to retry idempotent requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Check address-level serviceability for on-screen offers",
        "tags": [
          "public"
        ]
      }
    },
    "/public/shop/orders": {
      "post": {
        "description": "Creates an order through the canonical transactional path (idempotent, snapshotted, outbox-emitting), attributed to the house reseller team. Re-checks coverage against the submitted address; unauthenticated.",
        "operationId": "PublicShopController_createOrder",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateShopOrderDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Order created (or the original, on idempotent replay)"
          },
          "422": {
            "description": "One or more offers are no longer available at this address",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error. Safe to retry idempotent requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Shop checkout is not configured (house reseller team unset)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Place a checkout-mode shop order",
        "tags": [
          "public"
        ]
      }
    },
    "/public/shop/clicks": {
      "post": {
        "description": "Logs a click for a consumer offer — a lead_gen click returns a redirectUrl (the provider URL with Offergrid attribution merged on); a checkout-mode click is fire-and-forget funnel logging with no redirect. Unauthenticated, lightly rate-limited per IP.",
        "operationId": "PublicShopController_createClick",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateShopClickDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Click recorded"
          },
          "404": {
            "description": "Offer not found or not consumer-enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error. Safe to retry idempotent requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Record an outbound shop click",
        "tags": [
          "public"
        ]
      }
    }
  },
  "info": {
    "title": "OfferGrid API",
    "description": "**Public API** - Unauthenticated endpoints with no API key required.\n\nThese power two public, no-login surfaces:\n- **Shareable links** (`/public/links/*`) - a reseller-branded landing page for a specific set of offers, used to collect an order from an end customer.\n- **Consumer shop** (`/public/shop/*`) - the offergrid.io/shop storefront, where consumers browse real offers by ZIP code and either check out directly or are redirected to a provider's own site.\n\nAll endpoints here are rate-limited and validate/re-check coverage server-side; none require the `x-api-key` header used by the Provider and Reseller APIs.",
    "version": "1.0",
    "contact": {}
  },
  "tags": [
    {
      "name": "public",
      "description": "Public: Unauthenticated endpoints for shareable links and the /shop storefront"
    }
  ],
  "servers": [
    {
      "url": "https://api.offergrid.io",
      "description": "Production"
    }
  ],
  "components": {
    "securitySchemes": {
      "api-key": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Team API key for authentication. Your team role (provider/reseller/hybrid) determines which endpoints you can access."
      }
    },
    "schemas": {
      "CreateOfferDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Public-facing name of the offer",
            "example": "High-Speed Internet 1000 Mbps"
          },
          "internalName": {
            "type": "string",
            "description": "Internal name for tracking (not shown to customers)",
            "example": "HSI-1000-Q4-2024"
          },
          "category": {
            "type": "string",
            "description": "Service category",
            "enum": [
              "internet",
              "electricity",
              "other"
            ],
            "example": "internet"
          },
          "status": {
            "type": "string",
            "description": "Current status of the offer",
            "enum": [
              "draft",
              "active",
              "inactive",
              "archived"
            ],
            "example": "draft",
            "default": "draft"
          },
          "sku": {
            "type": "string",
            "description": "Stock Keeping Unit (SKU) - must be unique",
            "example": "INT-1000-001"
          },
          "externalId": {
            "type": "string",
            "description": "External system identifier",
            "example": "ext-12345"
          },
          "externalProductKey": {
            "type": "string",
            "description": "Identifier of this offer's product in the provider's serviceability source. When the source returns several products for an address, this selects the one whose price/plan is shown for this offer; offers sharing a market can therefore each surface their own address-level pricing. Leave unset to use the source's default (payload-level) projection.",
            "example": "FIBER-500"
          },
          "metadata": {
            "type": "object",
            "description": "Custom metadata as JSON object",
            "example": {
              "tags": [
                "fiber",
                "residential"
              ],
              "priority": 1
            }
          },
          "description": {
            "type": "string",
            "description": "Detailed description of the offer",
            "example": "Blazing fast fiber internet with unlimited data"
          },
          "internalDescription": {
            "type": "string",
            "description": "Internal notes and description",
            "example": "Q4 promotional offer for new markets"
          },
          "marketingHeadline": {
            "type": "string",
            "description": "Marketing headline",
            "example": "Get Lightning-Fast Internet Today!"
          },
          "marketingDescription": {
            "type": "string",
            "description": "Marketing description",
            "example": "Experience the future of connectivity with our fiber-optic network"
          },
          "keyFeatures": {
            "description": "Array of key features",
            "example": [
              "1000 Mbps download",
              "Unlimited data",
              "No contract"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "imageUrl": {
            "type": "string",
            "description": "URL to offer image",
            "example": "https://cdn.example.com/offers/internet-1000.jpg"
          },
          "overview": {
            "type": "string",
            "description": "Detailed overview of the offer",
            "example": "This package includes installation, router, and 24/7 support"
          },
          "brandId": {
            "type": "string",
            "description": "Id of one of your team brands (see /provider/brands) to display the offer under. Takes precedence over brandName. Send null on update to clear the brand and fall back to the provider team identity.",
            "example": "a3f1c9c2-7f42-4b6e-9a8e-2f0d5c6b1e77"
          },
          "brandName": {
            "type": "string",
            "description": "Brand display name. When set, buyer-facing surfaces show this brand's name/logo instead of the owning provider team — used to load offers under another company's identity. If your team has no brand with this name it is created; matching is case/space-insensitive within your team. Falls back to the provider team name when omitted. Ignored when brandId is set.",
            "example": "Direct Energy"
          },
          "brandImageUrl": {
            "type": "string",
            "description": "Brand logo URL. Only used to set the image when the brand is first created (or when an existing brand has no image); it never overwrites an existing brand logo.",
            "example": "https://logo.clearbit.com/directenergy.com"
          },
          "submissionUrl": {
            "type": "string",
            "description": "URL for order submission",
            "example": "https://provider.example.com/api/orders"
          },
          "submissionConfig": {
            "type": "object",
            "description": "Submission configuration including form fields",
            "example": {
              "formFields": [
                {
                  "name": "address",
                  "type": "text",
                  "required": true
                },
                {
                  "name": "phone",
                  "type": "tel",
                  "required": true
                }
              ],
              "metadata": []
            }
          },
          "electricity": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ElectricityContractWrite"
              }
            ],
            "description": "Structured electricity contract — the only way to set an electricity offer’s pricing, term, plan and disclosures. Folded into storage server-side. Grouped as rate / term / plan / disclosures."
          },
          "internet": {
            "allOf": [
              {
                "$ref": "#/components/schemas/InternetContractWrite"
              }
            ],
            "description": "Structured internet contract — the only way to set an internet offer’s speed, data allowance, term and disclosures. Folded into storage server-side. Grouped as speed / data / term / disclosures."
          },
          "pricingType": {
            "type": "string",
            "description": "Pricing type",
            "enum": [
              "fixed",
              "variable",
              "tiered",
              "custom"
            ],
            "example": "fixed"
          },
          "monthlyPrice": {
            "type": "number",
            "description": "Monthly recurring price",
            "example": 59.99,
            "minimum": 0
          },
          "marketNames": {
            "description": "Scope the offer to one or more existing markets by NAME. Each name must match an existing market on your team (create markets separately via the markets API). Mirrors the CSV bulk-upload `marketNames` column so a JSON integration and the CSV path use the same identifier. Use `marketIds` if you already have market IDs. Cannot be combined with `marketIds`.",
            "example": [
              "Texas — Oncor",
              "Texas — CenterPoint"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "marketIds": {
            "description": "Scope the offer to one or more existing markets by ID. Each id must belong to a market on your team. Prefer `marketNames` when you have the market name (matches the CSV column and is easier to author). Cannot be combined with `marketNames`.",
            "example": [
              "b1c8d1e2-..."
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "consumerEnabled": {
            "type": "boolean",
            "description": "Publish this offer to the public /shop consumer storefront. Defaults to false — nothing appears in the shop without explicit opt-in. Independent of reseller (B2B) access.",
            "example": true
          },
          "consumerMode": {
            "type": "string",
            "description": "How a consumer-enabled offer converts on the shop. `checkout`: the shopper completes the order inside Offergrid. `lead_gen`: the CTA logs a click and redirects to your own `leadGenUrl` with attribution params; Offergrid creates no order. Required (enforced at publish) when consumerEnabled is true. Send null to clear.",
            "enum": [
              "lead_gen",
              "checkout"
            ],
            "example": "lead_gen"
          },
          "leadGenUrl": {
            "type": "string",
            "description": "Partner signup URL template for `lead_gen` offers — where the shop CTA sends the shopper. Must be an https:// URL and may embed {{variable}} placeholders in query-parameter values, rendered from collected customer data at handoff. Supported variables: first_name, last_name, full_name, email, phone, street, unit, city, state, zip, esiid, start_date, action (move/switch), tdsp_duns, click_id, offer_external_id. The full template (https, allowlisted variables, placeholders only in query values) is validated when the offer is published. Send null to clear.",
            "example": "https://partner.example.com/signup?ref=offergrid&fname={{first_name}}&zip={{zip}}"
          }
        },
        "required": [
          "name"
        ],
        "title": "Create Offer Request"
      },
      "UpdateOfferDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Public-facing name of the offer",
            "example": "High-Speed Internet 1000 Mbps"
          },
          "internalName": {
            "type": "string",
            "description": "Internal name for tracking (not shown to customers)",
            "example": "HSI-1000-Q4-2024"
          },
          "category": {
            "type": "string",
            "description": "Service category",
            "enum": [
              "internet",
              "electricity",
              "other"
            ],
            "example": "internet"
          },
          "status": {
            "type": "string",
            "description": "Current status of the offer",
            "enum": [
              "draft",
              "active",
              "inactive",
              "archived"
            ],
            "example": "draft",
            "default": "draft"
          },
          "sku": {
            "type": "string",
            "description": "Stock Keeping Unit (SKU) - must be unique",
            "example": "INT-1000-001"
          },
          "externalId": {
            "type": "string",
            "description": "External system identifier",
            "example": "ext-12345"
          },
          "externalProductKey": {
            "type": "string",
            "description": "Identifier of this offer's product in the provider's serviceability source. When the source returns several products for an address, this selects the one whose price/plan is shown for this offer; offers sharing a market can therefore each surface their own address-level pricing. Leave unset to use the source's default (payload-level) projection.",
            "example": "FIBER-500"
          },
          "metadata": {
            "type": "object",
            "description": "Custom metadata as JSON object",
            "example": {
              "tags": [
                "fiber",
                "residential"
              ],
              "priority": 1
            }
          },
          "description": {
            "type": "string",
            "description": "Detailed description of the offer",
            "example": "Blazing fast fiber internet with unlimited data"
          },
          "internalDescription": {
            "type": "string",
            "description": "Internal notes and description",
            "example": "Q4 promotional offer for new markets"
          },
          "marketingHeadline": {
            "type": "string",
            "description": "Marketing headline",
            "example": "Get Lightning-Fast Internet Today!"
          },
          "marketingDescription": {
            "type": "string",
            "description": "Marketing description",
            "example": "Experience the future of connectivity with our fiber-optic network"
          },
          "keyFeatures": {
            "description": "Array of key features",
            "example": [
              "1000 Mbps download",
              "Unlimited data",
              "No contract"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "imageUrl": {
            "type": "string",
            "description": "URL to offer image",
            "example": "https://cdn.example.com/offers/internet-1000.jpg"
          },
          "overview": {
            "type": "string",
            "description": "Detailed overview of the offer",
            "example": "This package includes installation, router, and 24/7 support"
          },
          "brandId": {
            "type": "string",
            "description": "Id of one of your team brands (see /provider/brands) to display the offer under. Takes precedence over brandName. Send null on update to clear the brand and fall back to the provider team identity.",
            "example": "a3f1c9c2-7f42-4b6e-9a8e-2f0d5c6b1e77"
          },
          "brandName": {
            "type": "string",
            "description": "Brand display name. When set, buyer-facing surfaces show this brand's name/logo instead of the owning provider team — used to load offers under another company's identity. If your team has no brand with this name it is created; matching is case/space-insensitive within your team. Falls back to the provider team name when omitted. Ignored when brandId is set.",
            "example": "Direct Energy"
          },
          "brandImageUrl": {
            "type": "string",
            "description": "Brand logo URL. Only used to set the image when the brand is first created (or when an existing brand has no image); it never overwrites an existing brand logo.",
            "example": "https://logo.clearbit.com/directenergy.com"
          },
          "submissionUrl": {
            "type": "string",
            "description": "URL for order submission",
            "example": "https://provider.example.com/api/orders"
          },
          "submissionConfig": {
            "type": "object",
            "description": "Submission configuration including form fields",
            "example": {
              "formFields": [
                {
                  "name": "address",
                  "type": "text",
                  "required": true
                },
                {
                  "name": "phone",
                  "type": "tel",
                  "required": true
                }
              ],
              "metadata": []
            }
          },
          "electricity": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ElectricityContractWrite"
              }
            ],
            "description": "Structured electricity contract — the only way to set an electricity offer’s pricing, term, plan and disclosures. Folded into storage server-side. Grouped as rate / term / plan / disclosures."
          },
          "internet": {
            "allOf": [
              {
                "$ref": "#/components/schemas/InternetContractWrite"
              }
            ],
            "description": "Structured internet contract — the only way to set an internet offer’s speed, data allowance, term and disclosures. Folded into storage server-side. Grouped as speed / data / term / disclosures."
          },
          "pricingType": {
            "type": "string",
            "description": "Pricing type",
            "enum": [
              "fixed",
              "variable",
              "tiered",
              "custom"
            ],
            "example": "fixed"
          },
          "monthlyPrice": {
            "type": "number",
            "description": "Monthly recurring price",
            "example": 59.99,
            "minimum": 0
          },
          "marketNames": {
            "description": "Scope the offer to one or more existing markets by NAME. Each name must match an existing market on your team (create markets separately via the markets API). Mirrors the CSV bulk-upload `marketNames` column so a JSON integration and the CSV path use the same identifier. Use `marketIds` if you already have market IDs. Cannot be combined with `marketIds`.",
            "example": [
              "Texas — Oncor",
              "Texas — CenterPoint"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "marketIds": {
            "description": "Scope the offer to one or more existing markets by ID. Each id must belong to a market on your team. Prefer `marketNames` when you have the market name (matches the CSV column and is easier to author). Cannot be combined with `marketNames`.",
            "example": [
              "b1c8d1e2-..."
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "consumerEnabled": {
            "type": "boolean",
            "description": "Publish this offer to the public /shop consumer storefront. Defaults to false — nothing appears in the shop without explicit opt-in. Independent of reseller (B2B) access.",
            "example": true
          },
          "consumerMode": {
            "type": "string",
            "description": "How a consumer-enabled offer converts on the shop. `checkout`: the shopper completes the order inside Offergrid. `lead_gen`: the CTA logs a click and redirects to your own `leadGenUrl` with attribution params; Offergrid creates no order. Required (enforced at publish) when consumerEnabled is true. Send null to clear.",
            "enum": [
              "lead_gen",
              "checkout"
            ],
            "example": "lead_gen"
          },
          "leadGenUrl": {
            "type": "string",
            "description": "Partner signup URL template for `lead_gen` offers — where the shop CTA sends the shopper. Must be an https:// URL and may embed {{variable}} placeholders in query-parameter values, rendered from collected customer data at handoff. Supported variables: first_name, last_name, full_name, email, phone, street, unit, city, state, zip, esiid, start_date, action (move/switch), tdsp_duns, click_id, offer_external_id. The full template (https, allowlisted variables, placeholders only in query values) is validated when the offer is published. Send null to clear.",
            "example": "https://partner.example.com/signup?ref=offergrid&fname={{first_name}}&zip={{zip}}"
          }
        },
        "title": "Update Offer Request"
      },
      "BulkUploadResultDto": {
        "type": "object",
        "properties": {
          "totalRows": {
            "type": "number",
            "description": "Total rows processed"
          },
          "successCount": {
            "type": "number",
            "description": "Number of successfully created offers"
          },
          "errorCount": {
            "type": "number",
            "description": "Number of failed offers"
          },
          "createdOfferIds": {
            "description": "Created offer IDs",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "errors": {
            "description": "Detailed errors for failed rows",
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "warnings": {
            "description": "Warnings for all rows",
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        },
        "required": [
          "totalRows",
          "successCount",
          "errorCount",
          "createdOfferIds",
          "errors"
        ],
        "title": "Bulk Upload Result"
      },
      "BulkUpdateResultDto": {
        "type": "object",
        "properties": {
          "totalRows": {
            "type": "number",
            "description": "Total rows processed"
          },
          "successCount": {
            "type": "number",
            "description": "Number of successfully updated offers"
          },
          "errorCount": {
            "type": "number",
            "description": "Number of failed rows"
          },
          "updatedOfferIds": {
            "description": "Updated offer IDs",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "errors": {
            "description": "Detailed errors for failed rows",
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "warnings": {
            "description": "Warnings for all rows",
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        },
        "required": [
          "totalRows",
          "successCount",
          "errorCount",
          "updatedOfferIds",
          "errors"
        ],
        "title": "Bulk Update Result"
      },
      "UpdateItemStatusDto": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "submitted_to_provider",
              "accepted",
              "rejected",
              "scheduled",
              "in_progress",
              "completed",
              "active",
              "cancelled",
              "failed"
            ],
            "description": "New status for the order item",
            "example": "accepted"
          },
          "providerNotes": {
            "type": "string",
            "description": "Notes from provider about this status update",
            "example": "Installation scheduled for next Tuesday"
          },
          "scheduledFor": {
            "type": "string",
            "description": "Scheduled date/time for installation or activation (ISO 8601)",
            "example": "2025-01-15T10:00:00Z"
          },
          "metadata": {
            "type": "object",
            "description": "Additional metadata for this status update",
            "example": {
              "trackingNumber": "ABC123",
              "estimatedCompletion": "2025-01-20"
            }
          }
        },
        "required": [
          "status"
        ],
        "title": "Update Item Status Request"
      },
      "CreateMarketDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Provider-facing market name. Unique per provider team.",
            "example": "Austin Metro"
          },
          "description": {
            "type": "string",
            "description": "Optional description of the market.",
            "example": "Fiber footprint across Travis and Williamson counties."
          },
          "status": {
            "type": "string",
            "description": "Lifecycle status.",
            "enum": [
              "draft",
              "active",
              "paused",
              "archived"
            ],
            "default": "draft"
          },
          "tags": {
            "description": "Free-form tags for grouping markets.",
            "example": [
              "fiber",
              "priority"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "name"
        ],
        "title": "Create Market"
      },
      "UpdateMarketDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Provider-facing market name. Unique per provider team.",
            "example": "Austin Metro"
          },
          "description": {
            "type": "string",
            "description": "Optional description of the market.",
            "example": "Fiber footprint across Travis and Williamson counties."
          },
          "status": {
            "type": "string",
            "description": "Lifecycle status.",
            "enum": [
              "draft",
              "active",
              "paused",
              "archived"
            ],
            "default": "draft"
          },
          "tags": {
            "description": "Free-form tags for grouping markets.",
            "example": [
              "fiber",
              "priority"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "title": "Update Market"
      },
      "UpsertMarketAreaDto": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "postal",
              "admin",
              "polygon",
              "h3",
              "utility_territory",
              "serviceability"
            ]
          },
          "operation": {
            "type": "string",
            "enum": [
              "include",
              "exclude"
            ],
            "default": "include"
          },
          "label": {
            "type": "string",
            "description": "Optional display label (e.g. \"Travis County\", \"78704 cluster\")."
          },
          "postalCodes": {
            "example": [
              "78701",
              "78702"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "postalCountry": {
            "type": "string",
            "example": "US"
          },
          "adminLevel": {
            "type": "string",
            "enum": [
              "state",
              "county",
              "city",
              "census_place"
            ]
          },
          "adminCountry": {
            "type": "string",
            "example": "US"
          },
          "adminState": {
            "type": "string",
            "example": "TX"
          },
          "adminCounty": {
            "type": "string",
            "example": "Travis"
          },
          "adminCity": {
            "type": "string",
            "example": "Austin"
          },
          "adminGeoid": {
            "type": "string",
            "description": "Census GEOID for stable matching."
          },
          "geometry": {
            "type": "object",
            "description": "GeoJSON Polygon or MultiPolygon."
          },
          "h3Cells": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "h3Resolution": {
            "type": "number",
            "example": 8
          },
          "utilityCodes": {
            "description": "TDSP/TDU DUNS codes, e.g. Oncor \"1039940674000\".",
            "example": [
              "1039940674000"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "utilityCountry": {
            "type": "string",
            "example": "US"
          },
          "sourceType": {
            "type": "string",
            "enum": [
              "fabric_upload",
              "external_api"
            ]
          },
          "sourceRef": {
            "type": "string",
            "description": "The IntegrationSource key this area resolves through. Required for serviceability areas, where it must name an active serviceability source owned by your team."
          },
          "gating": {
            "type": "boolean",
            "description": "Serviceability areas only. true = the market covers an address only when this source answers on-net; false (default) = the source enriches offer detail but never hides the offer. An unanswerable lookup never gates.",
            "default": false
          }
        },
        "required": [
          "type"
        ],
        "title": "Upsert Market Area"
      },
      "CreateWebhookDto": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "HTTPS endpoint that will receive signed order-event deliveries",
            "example": "https://your-system.example.com/offergrid-callback"
          },
          "events": {
            "type": "array",
            "description": "Event types this webhook subscribes to",
            "example": [
              "order.item.created",
              "order.item.status_changed"
            ],
            "items": {
              "type": "string",
              "enum": [
                "order.created",
                "order.item.created",
                "order.item.status_changed",
                "order.cancelled"
              ]
            }
          }
        },
        "required": [
          "url",
          "events"
        ],
        "title": "Create Webhook"
      },
      "UpdateWebhookDto": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "example": "https://your-system.example.com/offergrid-callback"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "order.created",
                "order.item.created",
                "order.item.status_changed",
                "order.cancelled"
              ]
            }
          },
          "isActive": {
            "type": "boolean",
            "description": "Pause/resume deliveries without deleting the webhook"
          }
        },
        "title": "Update Webhook"
      },
      "CreateBrandDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Display name buyers see on offers using this brand. Matched case-insensitively within your team — creating a name your team already uses returns a conflict.",
            "example": "Direct Energy"
          },
          "imageUrl": {
            "type": "string",
            "description": "Logo image URL shown on buyer-facing offer cards. Must serve an actual image; cards fall back to name initials when it fails to load.",
            "example": "https://cdn.example.com/logos/direct-energy.png"
          }
        },
        "required": [
          "name"
        ],
        "title": "Create Brand"
      },
      "UpdateBrandDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Display name buyers see on offers using this brand. Matched case-insensitively within your team — creating a name your team already uses returns a conflict.",
            "example": "Direct Energy"
          },
          "imageUrl": {
            "type": "string",
            "description": "Logo image URL shown on buyer-facing offer cards. Send an empty string to clear the logo (cards fall back to name initials).",
            "example": "https://cdn.example.com/logos/direct-energy.png"
          }
        },
        "title": "Update Brand"
      },
      "CreateTeamApiKeyDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Descriptive name for the API key"
          }
        },
        "required": [
          "name"
        ],
        "title": "Create Team Api Key"
      },
      "InviteTeamMemberDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "description": "Email address of the person to invite"
          }
        },
        "required": [
          "email"
        ],
        "title": "Invite Team Member"
      },
      "AddressDto": {
        "type": "object",
        "properties": {
          "street": {
            "type": "string",
            "example": "123 Main Street"
          },
          "unit": {
            "type": "string",
            "example": "Unit 205"
          },
          "city": {
            "type": "string",
            "example": "Austin"
          },
          "state": {
            "type": "string",
            "example": "TX"
          },
          "zipCode": {
            "type": "string",
            "example": "78701"
          },
          "country": {
            "type": "string",
            "example": "US",
            "default": "US"
          }
        },
        "required": [
          "street",
          "city",
          "state",
          "zipCode",
          "country"
        ],
        "title": "Address"
      },
      "CheckAvailabilityDto": {
        "type": "object",
        "properties": {
          "address": {
            "description": "Service address to check availability for",
            "allOf": [
              {
                "$ref": "#/components/schemas/AddressDto"
              }
            ]
          },
          "category": {
            "type": "string",
            "enum": [
              "internet",
              "electricity",
              "other"
            ],
            "description": "Only return offers in this service category",
            "example": "internet"
          },
          "minPrice": {
            "type": "number",
            "description": "Minimum monthly price",
            "example": 0
          },
          "maxPrice": {
            "type": "number",
            "description": "Maximum monthly price",
            "example": 100
          }
        },
        "required": [
          "address"
        ],
        "title": "Find Available Offers Request"
      },
      "OrderItemDto": {
        "type": "object",
        "properties": {
          "offerId": {
            "type": "string",
            "description": "ID of the offer to order",
            "example": "123e4567-e89b-12d3-a456-426614174000"
          },
          "metadata": {
            "type": "object",
            "description": "Per-item metadata stored on the resulting OrderItem. For electricity offers, carry enrollment details here so the provider can fulfill the enrollment.",
            "example": {
              "enrollment": {
                "enrollmentType": "switch",
                "esid": "10443720000000000",
                "requestedStartDate": "2026-07-15"
              }
            }
          }
        },
        "required": [
          "offerId"
        ],
        "title": "Order Item"
      },
      "ServiceAddressDto": {
        "type": "object",
        "properties": {
          "street": {
            "type": "string",
            "example": "123 Main St"
          },
          "city": {
            "type": "string",
            "example": "San Francisco"
          },
          "state": {
            "type": "string",
            "example": "CA"
          },
          "zipCode": {
            "type": "string",
            "example": "94102"
          },
          "country": {
            "type": "string",
            "example": "US"
          }
        },
        "required": [
          "street",
          "city",
          "state",
          "zipCode",
          "country"
        ],
        "title": "Service Address"
      },
      "CustomerInfoDto": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "example": "John"
          },
          "lastName": {
            "type": "string",
            "example": "Doe"
          },
          "fullName": {
            "type": "string",
            "example": "John Doe",
            "description": "Legacy single-field name — prefer firstName + lastName. Required only when both are absent; split on the last space when used."
          },
          "email": {
            "type": "string",
            "example": "john@example.com"
          },
          "phone": {
            "type": "string",
            "example": "+1-555-123-4567"
          }
        },
        "required": [
          "email",
          "phone"
        ],
        "title": "Customer Information"
      },
      "CreateOrderDto": {
        "type": "object",
        "properties": {
          "items": {
            "description": "Array of items to order (offers)",
            "example": [
              {
                "offerId": "123e4567-e89b-12d3-a456-426614174000"
              }
            ],
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderItemDto"
            }
          },
          "serviceAddress": {
            "description": "Service address for installation",
            "allOf": [
              {
                "$ref": "#/components/schemas/ServiceAddressDto"
              }
            ]
          },
          "customerInfo": {
            "description": "Customer information",
            "allOf": [
              {
                "$ref": "#/components/schemas/CustomerInfoDto"
              }
            ]
          },
          "notes": {
            "type": "string",
            "description": "Additional notes for the order",
            "example": "Customer prefers morning installations"
          },
          "metadata": {
            "type": "object",
            "description": "Additional metadata for the order",
            "example": {
              "referralSource": "property-listing",
              "unitNumber": "4B"
            }
          }
        },
        "required": [
          "items",
          "serviceAddress",
          "customerInfo"
        ],
        "title": "Create Order Request"
      },
      "CreateLinkDto": {
        "type": "object",
        "properties": {
          "address": {
            "description": "Service address for the tenant",
            "allOf": [
              {
                "$ref": "#/components/schemas/AddressDto"
              }
            ]
          },
          "propertyName": {
            "type": "string",
            "description": "Property name or description",
            "example": "Sunset Apartments Unit 205"
          },
          "moveInDate": {
            "type": "string",
            "description": "Expected move-in date (ISO 8601)",
            "example": "2025-02-01"
          }
        },
        "required": [
          "address"
        ],
        "title": "Create Link Request"
      },
      "UpdateLinkDto": {
        "type": "object",
        "properties": {
          "propertyName": {
            "type": "string",
            "description": "Property name or description",
            "example": "Sunset Apartments Unit 205"
          },
          "moveInDate": {
            "type": "string",
            "description": "Expected move-in date (ISO 8601)",
            "example": "2025-02-01"
          },
          "status": {
            "type": "string",
            "description": "Link status",
            "enum": [
              "active",
              "inactive"
            ],
            "example": "active"
          }
        },
        "title": "Update Link Request"
      },
      "CreateCustomerDto": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "example": "Jane"
          },
          "lastName": {
            "type": "string",
            "example": "Doe"
          },
          "fullName": {
            "type": "string",
            "example": "Jane Doe",
            "description": "Legacy single-field name — prefer firstName + lastName. Required only when both are absent; split on the last space when used."
          },
          "email": {
            "type": "string",
            "example": "jane@example.com"
          },
          "phone": {
            "type": "string",
            "example": "+1-555-123-4567"
          },
          "addressLine1": {
            "type": "string",
            "example": "123 Main St"
          },
          "addressLine2": {
            "type": "string",
            "example": "Apt 4B"
          },
          "city": {
            "type": "string",
            "example": "San Francisco"
          },
          "state": {
            "type": "string",
            "example": "CA"
          },
          "postalCode": {
            "type": "string",
            "example": "94102"
          },
          "country": {
            "type": "string",
            "example": "US"
          },
          "kind": {
            "type": "string",
            "description": "Whether to track as a lead (pre-order) or as a customer.",
            "enum": [
              "lead",
              "customer"
            ],
            "default": "lead"
          },
          "source": {
            "type": "string",
            "description": "Where this contact came from.",
            "enum": [
              "order",
              "link",
              "api_import",
              "manual",
              "event",
              "shop",
              "reseller"
            ],
            "default": "manual"
          },
          "notes": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "customFields": {
            "type": "object",
            "description": "Open-ended attributes (source URL, external IDs, etc.)",
            "example": {
              "sourceUrl": "https://example.com/listing/42"
            }
          }
        },
        "title": "Create Customer"
      },
      "UpdateCustomerDto": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "lead",
              "customer"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "churned",
              "unsubscribed"
            ]
          },
          "notes": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "title": "Update Customer"
      },
      "SelectedOfferDto": {
        "type": "object",
        "properties": {
          "offerId": {
            "type": "string",
            "description": "Offer ID to order",
            "example": "uuid-of-offer"
          }
        },
        "required": [
          "offerId"
        ],
        "title": "Selected Offer"
      },
      "CreatePublicOrderDto": {
        "type": "object",
        "properties": {
          "customerInfo": {
            "description": "Customer contact information",
            "allOf": [
              {
                "$ref": "#/components/schemas/CustomerInfoDto"
              }
            ]
          },
          "items": {
            "description": "List of offers to order (one per category)",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SelectedOfferDto"
            }
          },
          "moveInDate": {
            "type": "string",
            "description": "Move-in date (ISO 8601)",
            "example": "2025-02-01"
          },
          "notes": {
            "type": "string",
            "description": "Additional notes from the customer",
            "example": "Please contact me in the morning"
          },
          "idempotencyKey": {
            "type": "string",
            "description": "Client-generated key for this checkout attempt. A repeat submission with the same key (e.g. a network retry or double-click on Submit) returns the original order instead of creating a duplicate.",
            "example": "a1b2c3d4-checkout-attempt"
          }
        },
        "required": [
          "customerInfo",
          "items"
        ],
        "title": "Create Public Order Request"
      },
      "ShopServiceabilityDto": {
        "type": "object",
        "properties": {
          "street": {
            "type": "string",
            "example": "123 Main St"
          },
          "unit": {
            "type": "string",
            "example": "Unit 4B"
          },
          "zip": {
            "type": "string",
            "example": "78701"
          },
          "city": {
            "type": "string",
            "example": "Austin"
          },
          "state": {
            "type": "string",
            "example": "TX"
          },
          "country": {
            "type": "string",
            "example": "US",
            "default": "US"
          },
          "category": {
            "type": "string",
            "enum": [
              "internet",
              "electricity",
              "other"
            ],
            "example": "internet"
          },
          "offerIds": {
            "description": "Restrict the check to these offer ids (the cards on screen).",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "street",
          "zip"
        ],
        "title": "Shop Serviceability"
      },
      "ShopOrderItemDto": {
        "type": "object",
        "properties": {
          "offerId": {
            "type": "string",
            "description": "ID of the consumer-enabled offer to order"
          },
          "metadata": {
            "type": "object",
            "description": "Per-item metadata stored on the resulting OrderItem — for electricity offers, carry enrollment details here (mirrors the reseller checkout wizard).",
            "example": {
              "enrollment": {
                "enrollmentType": "switch",
                "esid": "10443720000000000",
                "requestedStartDate": "2026-07-15"
              }
            }
          }
        },
        "required": [
          "offerId"
        ],
        "title": "Shop Order Item"
      },
      "ShopServiceAddressDto": {
        "type": "object",
        "properties": {
          "street": {
            "type": "string",
            "example": "123 Main St"
          },
          "unit": {
            "type": "string",
            "example": "Unit 4B"
          },
          "city": {
            "type": "string",
            "example": "Austin"
          },
          "state": {
            "type": "string",
            "example": "TX"
          },
          "zipCode": {
            "type": "string",
            "example": "78701"
          },
          "country": {
            "type": "string",
            "example": "US",
            "default": "US"
          }
        },
        "required": [
          "street",
          "city",
          "state",
          "zipCode"
        ],
        "title": "Shop Service Address"
      },
      "ShopCustomerInfoDto": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "example": "Jane"
          },
          "lastName": {
            "type": "string",
            "example": "Doe"
          },
          "fullName": {
            "type": "string",
            "example": "Jane Doe",
            "description": "Legacy single-field name — prefer firstName + lastName. Required only when both are absent; split on the last space when used."
          },
          "email": {
            "type": "string",
            "example": "jane@example.com"
          },
          "phone": {
            "type": "string",
            "example": "555-123-4567"
          }
        },
        "required": [
          "email",
          "phone"
        ],
        "title": "Shop Customer Info"
      },
      "CreateShopOrderDto": {
        "type": "object",
        "properties": {
          "items": {
            "description": "Offers to order — checkout-mode offers only, one per category",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ShopOrderItemDto"
            }
          },
          "serviceAddress": {
            "description": "Service address for installation",
            "allOf": [
              {
                "$ref": "#/components/schemas/ShopServiceAddressDto"
              }
            ]
          },
          "customerInfo": {
            "description": "Shopper contact information",
            "allOf": [
              {
                "$ref": "#/components/schemas/ShopCustomerInfoDto"
              }
            ]
          },
          "notes": {
            "type": "string",
            "description": "Additional notes from the shopper"
          },
          "idempotencyKey": {
            "type": "string",
            "description": "Client-generated key for this checkout attempt. A repeat submission with the same key (network retry, double-click on Submit) returns the original order instead of creating a duplicate.",
            "example": "a1b2c3d4-checkout-attempt"
          },
          "sessionId": {
            "type": "string",
            "description": "Anonymous client-generated session id, so the checkout-mode click this order completes can be tied to the same funnel as its lead_gen counterpart.",
            "example": "a1b2c3d4-shopper-session"
          }
        },
        "required": [
          "items",
          "serviceAddress",
          "customerInfo"
        ],
        "title": "Create Shop Order"
      },
      "ShopClickContactDto": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "example": "Jane"
          },
          "lastName": {
            "type": "string",
            "example": "Doe"
          },
          "fullName": {
            "type": "string",
            "example": "Jane Doe",
            "description": "Legacy single-field name — prefer firstName + lastName. Required only when both are absent; split on the last space when used."
          },
          "email": {
            "type": "string",
            "example": "jane@example.com"
          },
          "phone": {
            "type": "string",
            "example": "555-123-4567"
          }
        },
        "required": [
          "email"
        ],
        "title": "Shop Click Contact"
      },
      "ShopClickServiceAddressDto": {
        "type": "object",
        "properties": {
          "street": {
            "type": "string",
            "example": "123 Main Street"
          },
          "unit": {
            "type": "string",
            "example": "Apt 4B"
          },
          "city": {
            "type": "string",
            "example": "Austin"
          },
          "state": {
            "type": "string",
            "example": "TX"
          },
          "zipCode": {
            "type": "string",
            "example": "78701"
          }
        },
        "required": [
          "street"
        ],
        "title": "Shop Click Service Address"
      },
      "ShopClickEnrollmentDto": {
        "type": "object",
        "properties": {
          "enrollmentType": {
            "type": "string",
            "example": "move_in",
            "description": "switch (existing meter stays on) or move_in (new occupancy)"
          },
          "esid": {
            "type": "string",
            "example": "10443720005941666"
          },
          "requestedStartDate": {
            "type": "string",
            "example": "2026-09-01"
          }
        },
        "title": "Shop Click Enrollment"
      },
      "CreateShopClickDto": {
        "type": "object",
        "properties": {
          "offerId": {
            "type": "string",
            "description": "The offer this click is for"
          },
          "zip": {
            "type": "string",
            "example": "78701"
          },
          "city": {
            "type": "string",
            "example": "Austin"
          },
          "state": {
            "type": "string",
            "example": "TX"
          },
          "sessionId": {
            "type": "string",
            "description": "Anonymous client-generated UUID grouping clicks within one shopper session",
            "example": "a1b2c3d4-shopper-session"
          },
          "referrer": {
            "type": "string",
            "example": "https://www.google.com/"
          },
          "utm": {
            "type": "object",
            "example": {
              "utm_source": "google",
              "utm_campaign": "internet-austin"
            }
          },
          "contact": {
            "description": "Optional contact capture before a lead_gen redirect — always skippable. When present, creates a provider lead (Customer + TeamCustomer).",
            "allOf": [
              {
                "$ref": "#/components/schemas/ShopClickContactDto"
              }
            ]
          },
          "serviceAddress": {
            "description": "Full service address, when the handoff was reached through the checkout wizard. Its city/state/zipCode fill in for any top-level zip/city/state left unset.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ShopClickServiceAddressDto"
              }
            ]
          },
          "enrollment": {
            "description": "Optional electricity enrollment details collected before a lead_gen handoff — used to fill the offer's URL template (ESIID, start date, move vs switch) so the partner prefills its signup flow.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ShopClickEnrollmentDto"
              }
            ]
          }
        },
        "required": [
          "offerId",
          "sessionId"
        ],
        "title": "Create Shop Click"
      },
      "ElectricityCharge": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "perKwh"
                ]
              },
              "centsPerKwh": {
                "type": "number",
                "minimum": 0
              },
              "owner": {
                "type": "string",
                "enum": [
                  "provider",
                  "utility"
                ]
              },
              "label": {
                "type": "string",
                "minLength": 1
              },
              "minUsageKwh": {
                "type": "number",
                "minimum": 0
              },
              "maxUsageKwh": {
                "type": "number",
                "minimum": 0
              }
            },
            "required": [
              "type",
              "centsPerKwh",
              "owner",
              "label"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "fixed"
                ]
              },
              "amountDollars": {
                "type": "number",
                "minimum": 0
              },
              "owner": {
                "type": "string",
                "enum": [
                  "provider",
                  "utility"
                ]
              },
              "label": {
                "type": "string",
                "minLength": 1
              },
              "minUsageKwh": {
                "type": "number",
                "minimum": 0
              },
              "maxUsageKwh": {
                "type": "number",
                "minimum": 0
              }
            },
            "required": [
              "type",
              "amountDollars",
              "owner",
              "label"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "credit"
                ]
              },
              "amountDollars": {
                "type": "number",
                "minimum": 0
              },
              "owner": {
                "type": "string",
                "enum": [
                  "provider",
                  "utility"
                ]
              },
              "label": {
                "type": "string",
                "minLength": 1
              },
              "minUsageKwh": {
                "type": "number",
                "minimum": 0
              },
              "maxUsageKwh": {
                "type": "number",
                "minimum": 0
              }
            },
            "required": [
              "type",
              "amountDollars",
              "owner",
              "label"
            ],
            "additionalProperties": false
          }
        ],
        "title": "Electricity Charge",
        "description": "A single provider (REP) or utility delivery (TDU) charge line. perKwh lines bill per kWh in an optional usage band; fixed/credit lines apply a flat dollar amount (credits entered positive, subtracted)."
      },
      "ElectricityContractWrite": {
        "type": "object",
        "properties": {
          "rate": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "fixed",
                  "variable",
                  "indexed"
                ]
              },
              "charges": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ElectricityCharge"
                }
              },
              "avgPriceAt1000Kwh": {
                "type": "number",
                "minimum": 0
              }
            },
            "additionalProperties": false
          },
          "term": {
            "type": "object",
            "properties": {
              "length": {
                "type": "string",
                "enum": [
                  "no_contract",
                  "month_to_month",
                  "months_12",
                  "months_24",
                  "months_36"
                ]
              },
              "earlyTerminationFee": {
                "nullable": true,
                "type": "number",
                "minimum": 0
              },
              "earlyTerminationFeeNotes": {
                "nullable": true,
                "type": "string"
              }
            },
            "additionalProperties": false
          },
          "plan": {
            "type": "object",
            "properties": {
              "renewablePercentage": {
                "type": "number",
                "minimum": 0,
                "maximum": 100
              },
              "freeNightsWeekends": {
                "type": "boolean"
              },
              "noDeposit": {
                "type": "boolean"
              }
            },
            "additionalProperties": false
          },
          "disclosures": {
            "type": "object",
            "properties": {
              "electricityFactsLabel": {
                "type": "object",
                "properties": {
                  "url": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uri"
                      },
                      {
                        "type": "string",
                        "enum": [
                          ""
                        ]
                      }
                    ]
                  },
                  "versionId": {
                    "type": "string"
                  },
                  "avgPrice500kwh": {
                    "type": "number",
                    "minimum": 0
                  },
                  "avgPrice1000kwh": {
                    "type": "number",
                    "minimum": 0
                  },
                  "avgPrice2000kwh": {
                    "type": "number",
                    "minimum": 0
                  },
                  "renewablePercent": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100
                  }
                },
                "additionalProperties": false
              },
              "puctCertNumber": {
                "type": "string"
              },
              "puctCertifiedName": {
                "type": "string"
              },
              "termsOfServiceUrl": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri"
                  },
                  {
                    "type": "string",
                    "enum": [
                      ""
                    ]
                  }
                ]
              },
              "yourRightsUrl": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri"
                  },
                  {
                    "type": "string",
                    "enum": [
                      ""
                    ]
                  }
                ]
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false,
        "title": "Electricity Contract (write)",
        "description": "The electricity offer payload accepted on create/update. When present it is authoritative for pricing/term/plan/disclosures and is folded into storage server-side. Grouped as rate / term / plan / disclosures."
      },
      "ElectricityContract": {
        "type": "object",
        "properties": {
          "rate": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "fixed",
                  "variable",
                  "indexed"
                ]
              },
              "charges": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ElectricityCharge"
                }
              },
              "avgPriceAt1000Kwh": {
                "type": "number",
                "minimum": 0
              },
              "estimatedMonthlyAt1000Kwh": {
                "nullable": true,
                "type": "number",
                "minimum": 0,
                "readOnly": true
              }
            },
            "additionalProperties": false
          },
          "term": {
            "type": "object",
            "properties": {
              "length": {
                "type": "string",
                "enum": [
                  "no_contract",
                  "month_to_month",
                  "months_12",
                  "months_24",
                  "months_36"
                ]
              },
              "earlyTerminationFee": {
                "nullable": true,
                "type": "number",
                "minimum": 0
              },
              "earlyTerminationFeeNotes": {
                "nullable": true,
                "type": "string"
              }
            },
            "additionalProperties": false
          },
          "plan": {
            "type": "object",
            "properties": {
              "renewablePercentage": {
                "type": "number",
                "minimum": 0,
                "maximum": 100
              },
              "freeNightsWeekends": {
                "type": "boolean"
              },
              "noDeposit": {
                "type": "boolean"
              }
            },
            "additionalProperties": false
          },
          "disclosures": {
            "type": "object",
            "properties": {
              "electricityFactsLabel": {
                "type": "object",
                "properties": {
                  "url": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uri"
                      },
                      {
                        "type": "string",
                        "enum": [
                          ""
                        ]
                      }
                    ]
                  },
                  "versionId": {
                    "type": "string"
                  },
                  "avgPrice500kwh": {
                    "type": "number",
                    "minimum": 0
                  },
                  "avgPrice1000kwh": {
                    "type": "number",
                    "minimum": 0
                  },
                  "avgPrice2000kwh": {
                    "type": "number",
                    "minimum": 0
                  },
                  "renewablePercent": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100
                  }
                },
                "additionalProperties": false
              },
              "puctCertNumber": {
                "type": "string"
              },
              "puctCertifiedName": {
                "type": "string"
              },
              "termsOfServiceUrl": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri"
                  },
                  {
                    "type": "string",
                    "enum": [
                      ""
                    ]
                  }
                ]
              },
              "yourRightsUrl": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri"
                  },
                  {
                    "type": "string",
                    "enum": [
                      ""
                    ]
                  }
                ]
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false,
        "title": "Electricity Contract",
        "description": "The electricity offer payload returned on read. Same shape as the write contract plus the derived, read-only `rate.estimatedMonthlyAt1000Kwh` headline."
      },
      "InternetContractWrite": {
        "type": "object",
        "properties": {
          "speed": {
            "type": "object",
            "properties": {
              "minBandwidthMbps": {
                "type": "number",
                "minimum": 0
              },
              "maxBandwidthMbps": {
                "type": "number",
                "minimum": 0
              },
              "connectionType": {
                "type": "string",
                "enum": [
                  "fiber",
                  "cable",
                  "dsl",
                  "satellite",
                  "fixed_wireless",
                  "5g_home"
                ]
              }
            },
            "additionalProperties": false
          },
          "data": {
            "type": "object",
            "properties": {
              "capGb": {
                "type": "number",
                "minimum": 0
              }
            },
            "additionalProperties": false
          },
          "term": {
            "type": "object",
            "properties": {
              "length": {
                "type": "string",
                "enum": [
                  "no_contract",
                  "month_to_month",
                  "months_12",
                  "months_24",
                  "months_36"
                ]
              },
              "earlyTerminationFee": {
                "nullable": true,
                "type": "number",
                "minimum": 0
              },
              "earlyTerminationFeeNotes": {
                "nullable": true,
                "type": "string"
              }
            },
            "additionalProperties": false
          },
          "disclosures": {
            "type": "object",
            "properties": {
              "broadbandLabel": {
                "type": "object",
                "properties": {
                  "url": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uri"
                      },
                      {
                        "type": "string",
                        "enum": [
                          ""
                        ]
                      }
                    ]
                  },
                  "typicalDownload": {
                    "type": "number",
                    "minimum": 0
                  },
                  "typicalUpload": {
                    "type": "number",
                    "minimum": 0
                  },
                  "typicalLatency": {
                    "type": "number",
                    "minimum": 0
                  },
                  "dataCapGb": {
                    "nullable": true,
                    "type": "number",
                    "minimum": 0
                  }
                },
                "additionalProperties": false
              },
              "networkManagementUrl": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri"
                  },
                  {
                    "type": "string",
                    "enum": [
                      ""
                    ]
                  }
                ]
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false,
        "title": "Internet Contract (write)",
        "description": "The internet offer payload accepted on create/update. When present it is authoritative for speed/data/term/disclosures and is folded into storage server-side. Grouped as speed / data / term / disclosures."
      },
      "InternetContract": {
        "type": "object",
        "properties": {
          "speed": {
            "type": "object",
            "properties": {
              "minBandwidthMbps": {
                "type": "number",
                "minimum": 0
              },
              "maxBandwidthMbps": {
                "type": "number",
                "minimum": 0
              },
              "connectionType": {
                "type": "string",
                "enum": [
                  "fiber",
                  "cable",
                  "dsl",
                  "satellite",
                  "fixed_wireless",
                  "5g_home"
                ]
              }
            },
            "additionalProperties": false
          },
          "data": {
            "type": "object",
            "properties": {
              "capGb": {
                "type": "number",
                "minimum": 0
              }
            },
            "additionalProperties": false
          },
          "term": {
            "type": "object",
            "properties": {
              "length": {
                "type": "string",
                "enum": [
                  "no_contract",
                  "month_to_month",
                  "months_12",
                  "months_24",
                  "months_36"
                ]
              },
              "earlyTerminationFee": {
                "nullable": true,
                "type": "number",
                "minimum": 0
              },
              "earlyTerminationFeeNotes": {
                "nullable": true,
                "type": "string"
              }
            },
            "additionalProperties": false
          },
          "disclosures": {
            "type": "object",
            "properties": {
              "broadbandLabel": {
                "type": "object",
                "properties": {
                  "url": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uri"
                      },
                      {
                        "type": "string",
                        "enum": [
                          ""
                        ]
                      }
                    ]
                  },
                  "typicalDownload": {
                    "type": "number",
                    "minimum": 0
                  },
                  "typicalUpload": {
                    "type": "number",
                    "minimum": 0
                  },
                  "typicalLatency": {
                    "type": "number",
                    "minimum": 0
                  },
                  "dataCapGb": {
                    "nullable": true,
                    "type": "number",
                    "minimum": 0
                  }
                },
                "additionalProperties": false
              },
              "networkManagementUrl": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri"
                  },
                  {
                    "type": "string",
                    "enum": [
                      ""
                    ]
                  }
                ]
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false,
        "title": "Internet Contract",
        "description": "The internet offer payload returned on read — the grouped speed / data / term / disclosures view of an internet offer."
      },
      "OfferResponse": {
        "type": "object",
        "title": "Offer",
        "description": "An offer. Always includes a top-level `serviceType` discriminator (\"electricity\", \"internet\", …); electricity offers additionally include a grouped `electricity` object and internet offers a grouped `internet` object. The underlying offer fields (name, status, markets, marketing, pricing, …) are also present.",
        "additionalProperties": true,
        "properties": {
          "serviceType": {
            "type": "string",
            "nullable": true,
            "description": "Flat service-type discriminator derived from category. Check this instead of `category` directly.",
            "example": "internet"
          },
          "electricity": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ElectricityContract"
              }
            ],
            "description": "Present only on electricity offers."
          },
          "internet": {
            "allOf": [
              {
                "$ref": "#/components/schemas/InternetContract"
              }
            ],
            "description": "Present only on internet offers."
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "title": "Error",
        "description": "Standard error envelope returned by every 4xx and 5xx response.",
        "required": [
          "statusCode",
          "message"
        ],
        "properties": {
          "statusCode": {
            "type": "integer",
            "description": "HTTP status code, repeated in the body.",
            "example": 404
          },
          "message": {
            "type": "string",
            "description": "Human-readable explanation of what went wrong.",
            "example": "Offer not found"
          },
          "error": {
            "type": "string",
            "description": "Short, stable name for the status code.",
            "example": "Not Found"
          }
        }
      },
      "ValidationErrorResponse": {
        "type": "object",
        "title": "Validation Error",
        "description": "Returned when request-body validation fails. `message` is an array with one entry per failed constraint.",
        "required": [
          "statusCode",
          "message"
        ],
        "properties": {
          "statusCode": {
            "type": "integer",
            "example": 400
          },
          "message": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "One human-readable message per failed constraint.",
            "example": [
              "name should not be empty",
              "category must be one of the following values: internet, electricity"
            ]
          },
          "error": {
            "type": "string",
            "example": "Bad Request"
          }
        }
      }
    }
  }
}