> ## Documentation Index
> Fetch the complete documentation index at: https://docs.incentives.leap.energy/llms.txt
> Use this file to discover all available pages before exploring further.

# Check Incentives

> Get aggregated incentive calculations from multiple utility programs based on customer address and device

## Overview

Calculate incentives across multiple utility programs for a customer address and device. This endpoint automatically handles customer creation, utility lookup, and incentive aggregation.

The API supports three operation types:

* **`lookup`**: First-time customers or when you need fresh utility data (requires full address and `device_ids` or `device_names`)
* **`refresh`**: Returning customers using cached utilities (fastest, only requires `reference_id`)
* **`override`**: Replace all customer devices with new ones, then refresh calculation

You can identify devices by Leap device ID (`device_ids`) or by your own equipment/product names (`device_names`). When using `device_names`, the API resolves them via your organization's equipment map. See the [Incentives API Guide](/incentives-guide#device-names) for details on resolution behavior and handling partial matches.

<Tip>
  **Performance Tip**: Use `operation_type="refresh"` for returning customers to skip geocoding and use cached utility data. You can even omit `device_ids` to use all existing devices automatically.
</Tip>

The response distinguishes between programs the customer is *eligible* for (`incentives.by_program`) and the subset Leap can *complete an application for today* (`processing_summary`). When surfacing an offer to a customer, prefer `processing_summary.incentive_amount` over `incentives.total_incentive_amount` — see [Processing Status](/incentives-guide#processing-status) for the full rationale. The `connect_url` is populated only when at least one processing-enabled program is eligible.

For detailed operation type behavior, device handling, and best practices, see the [Incentives API Guide](/incentives-guide).


## OpenAPI

````yaml POST /incentives
openapi: 3.0.3
info:
  title: Leap Energy API
  description: >-
    The Leap Energy API provides a unified interface for managing rebate
    incentives and applications.


    ## Incentives API

    Search for and calculate incentive amounts across multiple utility programs.
    Given a customer

    address and building type, the API identifies applicable utility programs
    and calculates potential

    incentive amounts for various device and tier combinations. When your
    organization has a webhook URL

    configured (Webhook Config API), each successful lookup triggers a POST to
    your URL with the response

    and optional custom fields (`webhook_custom_fields`).


    ## Applications API

    Manage rebate applications on behalf of customers. Applications represent a
    customer's request

    for a rebate under a specific utility program, including customer
    information, device details,

    and application metadata.
  version: 2.0.0
  contact:
    name: Leap Energy
    url: https://leap.energy
servers:
  - url: https://api.incentives.leap.energy/alpha
    description: Production API
security:
  - ApiKeyAuth: []
  - BearerAuth: []
paths:
  /incentives:
    post:
      summary: Get aggregated incentives for a customer
      description: >
        Retrieves and aggregates incentive calculations from multiple utility
        programs

        based on the customer's address and building type.


        The API automatically:

        1. Creates or finds the customer based on address components

        2. Links the customer to your organization using the `reference_id`

        3. Associates devices with the customer (via `device_ids` or
        `device_names`)

        4. Identifies the utility serving the address

        5. Finds all active programs for that utility and building type

        6. Calls each program's incentive calculation function

        7. Optionally creates application records (if `create_application=true`
        and customer is eligible)

        8. Aggregates and returns the results

        9. If your organization has a webhook URL configured (see Webhook Config
        API), sends a POST to that URL with the response plus any
        `webhook_custom_fields` you include in the request


        **Authentication:** Requires API key via `x-api-key` header.


        **Reference ID:** The `reference_id` is required and must be unique per
        organization. It's used to link customers to your organization and is
        returned in the response for your records. To update applications later,
        use the PATCH endpoint with `application_id` (requires API key
        authentication).


        **Device Identification:** You can specify devices using either
        `device_ids` (Leap device IDs) or `device_names` (your equipment/product
        names). When using `device_names`, the API resolves them to Leap device
        IDs via your organization's equipment map. If some names cannot be
        resolved, the API proceeds with the resolved devices and includes a
        `warnings` object in the response.


        **Operation Types:**

        - `lookup`: New calculation with geocoding (requires address and
        `device_ids` or `device_names`)

        - `refresh`: Re-calculate using cached utilities (`device_ids` optional,
        uses existing devices if not provided; `device_names` not supported)

        - `override`: Replace all customer devices with new ones, then refresh
        calculation
      operationId: getAggregatedIncentives
      requestBody:
        required: true
        description: >-
          Customer address, building type, and device information for incentive
          calculation
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IncentiveRequest'
            examples:
              residential_request:
                summary: Lookup operation - New incentive calculation
                value:
                  operation_type: lookup
                  reference_id: external-ref-123
                  address:
                    street_1: 123 Main St
                    street_2: Apt 4B
                    city: San Francisco
                    state_or_province_code: CA
                    postal_code: '94102'
                    country_code: US
                  building_type: RESIDENTIAL
                  device_ids:
                    - 42
                  create_application: true
              refresh_request:
                summary: Refresh operation - Using cached utilities (faster)
                value:
                  operation_type: refresh
                  reference_id: external-ref-123
                  create_application: true
              device_names_request:
                summary: Lookup operation - Using equipment names instead of device IDs
                value:
                  operation_type: lookup
                  reference_id: external-ref-456
                  address:
                    street_1: 456 Oak Ave
                    city: Portland
                    state_or_province_code: OR
                    postal_code: '97201'
                    country_code: US
                  building_type: RESIDENTIAL
                  device_names:
                    - Mitsubishi Hyper-Heat MSZ-RXT09
                    - Rheem ProTerraDERA2060
                  create_application: true
              override_request:
                summary: Override operation - Replace all customer devices
                value:
                  operation_type: override
                  reference_id: external-ref-123
                  building_type: RESIDENTIAL
                  device_ids:
                    - 55
                    - 66
                    - 77
                  create_application: true
      responses:
        '200':
          description: Successful response with aggregated incentive data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IncentiveAggregationResponse'
              examples:
                successful_calculation:
                  summary: Eligible — single processing-enabled program
                  value:
                    utility:
                      eiaid: '14354'
                      name: PacifiCorp (Oregon)
                    possible_utilities:
                      - eiaid: '14354'
                        name: PacifiCorp (Oregon)
                    address: 123 Main St, Apt 4B, Bend, OR, 97701
                    building_type: RESIDENTIAL
                    customer_id: 453
                    programs_evaluated: 2
                    incentives:
                      total_incentive_amount: 750
                      total_eligible_combinations: 1
                      by_program:
                        - program_id: 838
                          program_name: >-
                            Pacific Power – Oregon "Charge at Home" EV Charger
                            Rebate
                          total_incentive: 750
                          eligible_combinations: 1
                          processing_enabled: true
                          device_tier_results:
                            - device_id: 42
                              device_name: Level 2 EV Charger
                              tier_id: 456
                              tier_name: Standard Rebate
                              eligible: true
                              incentive_amount: 750
                              calculation_details: 'Fixed rebate per device: $750'
                              failed_requirements: []
                              ignored_requirements:
                                - >-
                                  Installation must be within 90 days of
                                  application
                                - Must use licensed contractor
                              completed_requirements: []
                    processing_summary:
                      program_ids:
                        - 838
                      incentive_amount: 750
                    connect_url: >-
                      https://connect.incentives.leap.energy/your-company/refId/external-ref-123
                    reference_id: external-ref-123
                processing_not_enabled:
                  summary: Eligible — program not yet processing-enabled
                  value:
                    utility:
                      eiaid: '17609'
                      name: Sacramento Municipal Util Dist
                    possible_utilities:
                      - eiaid: '17609'
                        name: Sacramento Municipal Util Dist
                    address: 789 Oak Avenue, Sacramento, CA, 95814
                    building_type: RESIDENTIAL
                    customer_id: 455
                    programs_evaluated: 1
                    incentives:
                      total_incentive_amount: 500
                      total_eligible_combinations: 1
                      by_program:
                        - program_id: 1001
                          program_name: SMUD Charge@Home EV Rebates
                          total_incentive: 500
                          eligible_combinations: 1
                          processing_enabled: false
                          device_tier_results:
                            - device_id: 42
                              device_name: Level 2 EV Charger
                              tier_id: 789
                              tier_name: Standard Tier
                              eligible: true
                              incentive_amount: 500
                              calculation_details: 'Fixed rebate per device: $500'
                              failed_requirements: []
                              ignored_requirements: []
                              completed_requirements: []
                    processing_summary:
                      program_ids: []
                      incentive_amount: 0
                    connect_url: ''
                    reference_id: external-ref-789
                no_eligible_programs:
                  summary: Ineligible — no incentive available
                  value:
                    utility:
                      eiaid: '15248'
                      name: Portland General Electric Co
                    possible_utilities:
                      - eiaid: '15248'
                        name: Portland General Electric Co
                    address: 100 SW Main St, Portland, OR, 97204
                    building_type: RESIDENTIAL
                    customer_id: 454
                    programs_evaluated: 1
                    incentives:
                      total_incentive_amount: 0
                      total_eligible_combinations: 0
                      by_program:
                        - program_id: 900
                          program_name: PGE Smart Charging – Tesla Telematics Path
                          total_incentive: 0
                          eligible_combinations: 0
                          processing_enabled: true
                          device_tier_results:
                            - device_id: 123
                              device_name: Dumb Level 1 Charger
                              tier_id: 501
                              tier_name: Smart Charger Tier
                              eligible: false
                              incentive_amount: 0
                              calculation_details: Device does not meet tier requirements
                              failed_requirements:
                                - Device not OCPP compliant
                                - Charger level must be at least LEVEL_2
                              ignored_requirements: []
                              completed_requirements: []
                    processing_summary:
                      program_ids: []
                      incentive_amount: 0
                    connect_url: ''
                    reference_id: external-ref-456
        '400':
          description: Bad request — request body or parameters could not be accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                missing_devices:
                  summary: Missing device_ids / device_names
                  value:
                    error: >-
                      device_ids or device_names array is required and must
                      contain at least one device for lookup and override
                      operations
                    error_code: missing_devices
                mutually_exclusive_device_inputs:
                  summary: Both device_ids and device_names provided
                  value:
                    error: Provide either device_ids or device_names, not both.
                    error_code: mutually_exclusive_device_inputs
                invalid_building_type:
                  summary: Invalid building_type
                  value:
                    error: Invalid building_type
                    error_code: invalid_building_type
                device_names_on_refresh:
                  summary: device_names not supported for refresh
                  value:
                    error: >-
                      device_names is not supported for refresh operations. Use
                      device_ids or omit devices entirely.
                    error_code: device_names_not_supported_for_refresh
                device_names_unresolved:
                  summary: No device names could be resolved
                  value:
                    error: >-
                      No device names could be resolved. Please update equipment
                      map.
                    error_code: device_names_unresolved
                    details:
                      unresolved_device_names:
                        - Unknown Model ABC
                        - Unknown Model XYZ
                invalid_json_body:
                  summary: Invalid JSON body
                  value:
                    error: Invalid or empty JSON body
                    error_code: invalid_json_body
        '401':
          description: Unauthorized — missing or invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: Authorization header required
        '404':
          description: >-
            No utility found for the provided address (territory gap or unmapped
            EIA ID)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                no_utility_at_address:
                  summary: No utility serves this address
                  value:
                    error: No utility found for this address
                    error_code: no_utility_at_address
                    details:
                      upstream: utility-programs-lookup
                      upstream_status: 404
                no_valid_eiaid:
                  summary: Matched utilities are missing EIA IDs in our catalog
                  value:
                    error: Utility matched but has no valid EIA ID in catalog
                    error_code: no_valid_eiaid
        '405':
          description: Method not allowed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: Method not allowed
        '422':
          description: >-
            Unprocessable entity — request was syntactically valid but the
            address or building type could not be resolved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                address_not_geocodable:
                  summary: Address could not be geocoded
                  value:
                    error: Address could not be geocoded
                    error_code: address_not_geocodable
                building_type_unresolved:
                  summary: Building type could not be resolved during refresh
                  value:
                    error: >-
                      Could not resolve building_type for this customer. Include
                      building_type explicitly.
                    error_code: building_type_unresolved
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                internal_error:
                  summary: Unexpected server error
                  value:
                    error: Internal server error
                    error_code: internal_error
                legacy_internal_error:
                  summary: Generic internal error
                  value:
                    error: Internal server error
        '502':
          description: >-
            Bad gateway — upstream geocoder or programs service is unavailable.
            Safe to retry with exponential backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                upstream_transient:
                  summary: Transient upstream failure
                  value:
                    error: Upstream programs service returned a transient error
                    error_code: upstream_transient
                    details:
                      upstream: utility-programs-lookup
                      upstream_status: 503
                upstream_infra:
                  summary: Upstream infrastructure error
                  value:
                    error: Upstream programs service returned an infrastructure error
                    error_code: upstream_infra
                    details:
                      upstream: utility-programs-lookup
                      upstream_status: 500
      x-codeSamples:
        - lang: curl
          label: cURL (device IDs)
          source: |-
            curl -X POST \
              "https://api.incentives.leap.energy/alpha/incentives" \
              -H "x-api-key: leap_live_..." \
              -H "Content-Type: application/json" \
              -d '{
                "operation_type": "lookup",
                "reference_id": "external-ref-123",
                "address": {
                  "street_1": "123 Main St",
                  "street_2": "Apt 4B",
                  "city": "San Francisco",
                  "state_or_province_code": "CA",
                  "postal_code": "94102",
                  "country_code": "US"
                },
                "building_type": "RESIDENTIAL",
                "device_ids": [42],
                "create_application": true
              }'
        - lang: curl
          label: cURL (device names)
          source: |-
            curl -X POST \
              "https://api.incentives.leap.energy/alpha/incentives" \
              -H "x-api-key: leap_live_..." \
              -H "Content-Type: application/json" \
              -d '{
                "operation_type": "lookup",
                "reference_id": "external-ref-456",
                "address": {
                  "street_1": "456 Oak Ave",
                  "city": "Portland",
                  "state_or_province_code": "OR",
                  "postal_code": "97201",
                  "country_code": "US"
                },
                "building_type": "RESIDENTIAL",
                "device_names": ["Mitsubishi Hyper-Heat MSZ-RXT09", "Rheem ProTerraDERA2060"],
                "create_application": true
              }'
        - lang: python
          label: Python
          source: |-
            import requests

            url = "https://api.incentives.leap.energy/alpha/incentives"

            payload = {
                "operation_type": "lookup",
                "reference_id": "external-ref-123",
                "address": {
                    "street_1": "123 Main St",
                    "street_2": "Apt 4B",
                    "city": "San Francisco",
                    "state_or_province_code": "CA",
                    "postal_code": "94102",
                    "country_code": "US"
                },
                "building_type": "RESIDENTIAL",
                "device_ids": [42],
                "create_application": True
            }

            headers = {
                "x-api-key": "leap_live_...",
                "Content-Type": "application/json"
            }

            response = requests.post(url, json=payload, headers=headers)
            print(response.json())
        - lang: javascript
          label: JavaScript
          source: |-
            const response = await fetch(
              'https://api.incentives.leap.energy/alpha/incentives',
              {
                method: 'POST',
                headers: {
                  'x-api-key': 'leap_live_...',
                  'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                  operation_type: 'lookup',
                  reference_id: 'external-ref-123',
                  address: {
                    street_1: '123 Main St',
                    street_2: 'Apt 4B',
                    city: 'San Francisco',
                    state_or_province_code: 'CA',
                    postal_code: '94102',
                    country_code: 'US'
                  },
                  building_type: 'RESIDENTIAL',
                  device_ids: [42],
                  create_application: true
                })
              }
            );

            const data = await response.json();
            console.log(data);
        - lang: php
          label: PHP
          source: |-
            <?php

            $url = 'https://api.incentives.leap.energy/alpha/incentives';

            $payload = [
                'operation_type' => 'lookup',
                'reference_id' => 'external-ref-123',
                'address' => [
                    'street_1' => '123 Main St',
                    'street_2' => 'Apt 4B',
                    'city' => 'San Francisco',
                    'state_or_province_code' => 'CA',
                    'postal_code' => '94102',
                    'country_code' => 'US'
                ],
                'building_type' => 'RESIDENTIAL',
                'device_ids' => [42],
                'create_application' => true
            ];

            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'x-api-key: leap_live_...',
                'Content-Type: application/json'
            ]);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

            $response = curl_exec($ch);
            curl_close($ch);

            print_r(json_decode($response, true));
        - lang: java
          label: Java
          source: >-
            import java.net.http.*;

            import java.net.URI;


            HttpClient client = HttpClient.newHttpClient();


            String json = """{
              "operation_type": "lookup",
              "reference_id": "external-ref-123",
              "address": {
                "street_1": "123 Main St",
                "street_2": "Apt 4B",
                "city": "San Francisco",
                "state_or_province_code": "CA",
                "postal_code": "94102",
                "country_code": "US"
              },
              "building_type": "RESIDENTIAL",
              "device_ids": [42],
              "create_application": true
            }""";


            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://api.incentives.leap.energy/alpha/incentives"))
                .header("x-api-key", "leap_live_...")
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(json))
                .build();

            HttpResponse<String> response = client.send(request,
            HttpResponse.BodyHandlers.ofString());

            System.out.println(response.body());
        - lang: ruby
          label: Ruby
          source: |-
            require 'net/http'
            require 'json'

            uri = URI('https://api.incentives.leap.energy/alpha/incentives')

            payload = {
              operation_type: 'lookup',
              reference_id: 'external-ref-123',
              address: {
                street_1: '123 Main St',
                street_2: 'Apt 4B',
                city: 'San Francisco',
                state_or_province_code: 'CA',
                postal_code: '94102',
                country_code: 'US'
              },
              building_type: 'RESIDENTIAL',
              device_ids: [42],
              create_application: true
            }

            http = Net::HTTP.new(uri.host, uri.port)
            http.use_ssl = true

            request = Net::HTTP::Post.new(uri)
            request['x-api-key'] = 'leap_live_...'
            request['Content-Type'] = 'application/json'
            request.body = payload.to_json

            response = http.request(request)
            puts JSON.parse(response.body)
        - lang: go
          label: Go
          source: "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n)\n\nfunc main() {\n\turl := \"https://api.incentives.leap.energy/alpha/incentives\"\n\n\tpayload := map[string]interface{}{\n\t\t\"operation_type\": \"lookup\",\n\t\t\"reference_id\":   \"external-ref-123\",\n\t\t\"address\": map[string]interface{}{\n\t\t\t\"street_1\":               \"123 Main St\",\n\t\t\t\"street_2\":               \"Apt 4B\",\n\t\t\t\"city\":                   \"San Francisco\",\n\t\t\t\"state_or_province_code\": \"CA\",\n\t\t\t\"postal_code\":            \"94102\",\n\t\t\t\"country_code\":           \"US\",\n\t\t},\n\t\t\"building_type\":      \"RESIDENTIAL\",\n\t\t\"device_ids\":          []int{42},\n\t\t\"create_application\": true,\n\t}\n\n\tjsonData, _ := json.Marshal(payload)\n\treq, _ := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\treq.Header.Set(\"x-api-key\", \"leap_live_...\")\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tclient := &http.Client{}\n\tresp, _ := client.Do(req)\n\tdefer resp.Body.Close()\n\n\tvar result map[string]interface{}\n\tjson.NewDecoder(resp.Body).Decode(&result)\n\tfmt.Println(result)\n}"
components:
  schemas:
    IncentiveRequest:
      type: object
      required:
        - operation_type
        - reference_id
      properties:
        operation_type:
          type: string
          description: >-
            Operation type: 'lookup' for new calculations with geocoding,
            'refresh' for using cached utility data (faster), 'override' for
            replacing all customer devices
          enum:
            - lookup
            - refresh
            - override
          example: lookup
        reference_id:
          type: string
          description: >-
            Your internal reference ID for tracking this customer within your
            organization (unique per organization)
          example: external-ref-123
        address:
          type: object
          description: >-
            Customer's address information. Required for 'lookup' operation,
            optional for 'refresh' and 'override' operations (uses stored
            address if not provided)
          properties:
            street_1:
              type: string
              description: >-
                Street address line 1 (primary street address). Required for
                'lookup' operation.
              example: 123 Main St
            street_2:
              type: string
              description: Street address line 2 (apartment, suite, unit, etc.). Optional.
              example: Apt 4B
            city:
              type: string
              description: City name. Required for 'lookup' operation.
              example: San Francisco
            state_or_province_code:
              type: string
              description: >-
                State or province code (2-letter abbreviation). Required for
                'lookup' operation.
              example: CA
            postal_code:
              type: string
              description: Postal/ZIP code. Required for 'lookup' operation.
              example: '94102'
            country_code:
              type: string
              description: >-
                Country code (2-letter ISO code). Required for 'lookup'
                operation.
              example: US
        building_type:
          type: string
          description: >-
            Type of building for which to calculate incentives. Required for
            'lookup' and 'override' operations, optional for 'refresh' (uses
            stored building_type_id if not provided)
          enum:
            - RESIDENTIAL
            - MULTIFAMILY
            - MANUFACTURED_HOME
            - COMMERCIAL
          example: RESIDENTIAL
        device_ids:
          type: array
          description: >-
            Array of Leap device IDs to check incentives for. Required for
            'lookup' and 'override' operations unless device_names is provided.
            Optional for 'refresh' (uses existing devices if not provided). Can
            contain duplicates. Cannot be combined with device_names.
          items:
            type: integer
          example:
            - 32
            - 44
            - 44
            - 44
        device_names:
          type: array
          description: >-
            Array of your equipment/product names to check incentives for. The
            API resolves these to Leap device IDs using your organization's
            equipment map. Required for 'lookup' and 'override' operations
            unless device_ids is provided. Not supported for 'refresh'
            operations. Cannot be combined with device_ids.
          items:
            type: string
          example:
            - Mitsubishi Hyper-Heat MSZ-RXT09
            - Rheem ProTerraDERA2060
        create_application:
          type: boolean
          description: >-
            Whether to create/update application records and return a
            connect_url
          example: true
        webhook_custom_fields:
          type: object
          additionalProperties:
            type: string
          description: >-
            Optional custom fields to include in the webhook payload when your
            organization has a webhook URL configured (e.g. Project ID, Record
            ID). Only keys allowed by your org's webhook `field_names` config
            are merged into the POST body.
          example:
            Project ID: proj-123
            Record ID: row-5
        customer:
          type: object
          description: >-
            Supplementary customer fields applied at customer creation time.
            Only honored on `lookup` operations that create a new customer —
            ignored for existing customers and for `refresh`/`override`. Use the
            Applications PATCH endpoint to update an existing customer's fields.
          additionalProperties: true
          example:
            first_name: Jane
            last_name: Doe
            email: jane@example.com
            phone: 415-555-0100
        customer_devices:
          type: array
          description: >-
            Supplementary device fields applied at device creation time, indexed
            positionally to `device_ids`. Only honored on `lookup` operations
            that create new customer devices — ignored for existing customers
            and for `refresh`/`override`. Each entry is partial; common fields
            include `purchase_price`, `purchase_date`, `installation_date`,
            `contractor_name`. Use the Applications PATCH endpoint to update
            existing device fields.
          items:
            type: object
            additionalProperties: true
          example:
            - purchase_price: 1500
              installation_date: '2026-03-01'
            - purchase_price: 2000
    IncentiveAggregationResponse:
      type: object
      required:
        - utility
        - possible_utilities
        - address
        - building_type
        - customer_id
        - reference_id
        - programs_evaluated
        - incentives
        - processing_summary
        - connect_url
      properties:
        utility:
          type: object
          description: Information about the utility serving the address
          required:
            - eiaid
            - name
          properties:
            eiaid:
              type: string
              description: EIA utility identification number
              example: '14354'
            name:
              type: string
              description: Name of the utility company
              example: PacifiCorp (Oregon)
        address:
          type: string
          description: Formatted address string built from the request address fields
          example: 123 Main St, Apt 4B, San Francisco, CA, 94102
        possible_utilities:
          type: array
          description: >-
            All utilities whose service territory contains this address. The
            primary `utility` is selected from this list; the others are
            returned so partners can see when an address falls in an overlap
            region.
          items:
            type: object
            required:
              - eiaid
              - name
            properties:
              eiaid:
                type: string
                description: EIA utility identification number
                example: '14354'
              name:
                type: string
                description: Name of the utility company
                example: PacifiCorp (Oregon)
        building_type:
          type: string
          description: The building type that was used for the calculation
          enum:
            - RESIDENTIAL
            - MULTIFAMILY
            - MANUFACTURED_HOME
            - COMMERCIAL
          example: RESIDENTIAL
        customer_id:
          type: integer
          description: >-
            Leap's internal customer ID (created or found based on
            `reference_id` and address)
          example: 453
        reference_id:
          type: string
          description: >-
            Your internal reference ID that was provided in the request, echoed
            back for correlation
          example: external-ref-123
        connect_url:
          type: string
          description: >-
            Branded Connect URL where the customer completes their application.
            Populated only when `create_application=true` AND
            `incentives.total_incentive_amount > 0`; otherwise returned as an
            empty string.
          example: >-
            https://connect.incentives.leap.energy/your-company/refId/external-ref-123
        programs_evaluated:
          type: integer
          description: >-
            Number of programs that were evaluated for this address + building
            type combination
          example: 2
        incentives:
          type: object
          required:
            - total_incentive_amount
            - total_eligible_combinations
            - by_program
          properties:
            total_incentive_amount:
              type: number
              format: float
              description: >-
                Total incentive amount across all evaluated programs (in USD).
                Includes programs whose `processing_enabled` is currently false
                — use `processing_summary.incentive_amount` for the amount Leap
                is currently set up to process applications for.
              example: 2250
            total_eligible_combinations:
              type: integer
              description: >-
                Total number of eligible device-tier combinations across all
                programs
              example: 4
            by_program:
              type: array
              description: Per-program breakdown of incentives and eligibility
              items:
                $ref: '#/components/schemas/ProgramIncentive'
        processing_summary:
          type: object
          description: >-
            Subset of `incentives` covering only programs that Leap is currently
            set up to process applications for (i.e.
            `by_program[].processing_enabled === true`). Use this to decide
            whether to surface the Connect URL and a concrete offer amount to
            the customer — programs that aren't processing-enabled may still be
            listed in `by_program` but Leap cannot complete the application for
            them today.
          required:
            - program_ids
            - incentive_amount
          properties:
            program_ids:
              type: array
              description: >-
                IDs of programs from `by_program` whose `processing_enabled` is
                true
              items:
                type: integer
              example:
                - 838
            incentive_amount:
              type: number
              format: float
              description: >-
                Sum of `total_incentive` across processing-enabled programs (in
                USD)
              example: 750
        warnings:
          type: object
          description: >-
            Present when device_names was used and some names could not be
            resolved. The API proceeds with the resolved devices and reports
            unresolved names here.
          properties:
            unresolved_device_names:
              type: array
              description: >-
                Equipment names that could not be matched in your organization's
                equipment map
              items:
                type: string
              example:
                - Unknown Model XYZ
            message:
              type: string
              description: Human-readable summary of the warning
              example: 1 device name(s) could not be resolved and were skipped.
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: >-
            Human-readable error message, suitable for logs or support tickets.
            The message may be revised over time — branch on `error_code` for
            stable matching.
          example: No utility found for this address
        error_code:
          type: string
          description: >-
            Stable, typed identifier for the failure mode. Use this (not
            `error`) when building retry logic or branching. See the [Incentives
            API Guide](/incentives-guide#error-code-reference) for the full
            table of codes, status mappings, and retryability. A small number of
            legacy validation paths still return `4xx` without this field — fall
            back to matching on `error` when absent.
          example: no_utility_at_address
        details:
          description: >-
            Optional diagnostic payload whose shape varies by `error_code`. Safe
            to log; never contains PII. For `upstream_*` codes, includes
            `upstream` (component name) and `upstream_status` (HTTP status) so
            Leap support can triage tickets without joining back to logs. For
            `device_names`-related failures, includes `unresolved_device_names`.
          example:
            upstream: utility-programs-lookup
            upstream_status: 404
    ProgramIncentive:
      type: object
      required:
        - program_id
        - program_name
        - total_incentive
        - eligible_combinations
        - processing_enabled
        - device_tier_results
      properties:
        program_id:
          type: integer
          description: Unique identifier for the program
          example: 838
        program_name:
          type: string
          description: Name of the incentive program
          example: Pacific Power – Oregon "Charge at Home" EV Charger Rebate
        total_incentive:
          type: number
          format: float
          description: Total incentive amount for this program (in USD)
          example: 750
        eligible_combinations:
          type: integer
          description: Number of eligible device-tier combinations for this program
          example: 1
        processing_enabled:
          type: boolean
          description: >-
            Whether Leap is currently set up to process applications for this
            program. `true` when the program's form requirements have been fully
            captured; `false` when the program is still being onboarded.
            Eligibility and incentive amounts are still calculated when `false`
            — only the ability to submit an application is gated. Programs
            counted in `processing_summary` are exactly those with
            `processing_enabled = true`.
          example: true
        device_tier_results:
          type: array
          description: Detailed results for each device-tier combination
          items:
            $ref: '#/components/schemas/DeviceTierResult'
    DeviceTierResult:
      type: object
      required:
        - device_id
        - device_name
        - tier_id
        - tier_name
        - eligible
        - incentive_amount
        - failed_requirements
        - ignored_requirements
        - completed_requirements
      properties:
        device_id:
          type: integer
          description: Unique identifier for the device type
          example: 123
        device_name:
          type: string
          description: Name of the device type
          example: Level 2 EV Charger
        tier_id:
          type: integer
          description: Unique identifier for the incentive tier
          example: 456
        tier_name:
          type: string
          description: Name of the incentive tier
          example: Standard Rebate
        eligible:
          type: boolean
          description: |
            Whether this device-tier combination is eligible for the customer.
            True if all eligibility checks passed and incentive amount > 0.
          example: true
        incentive_amount:
          type: number
          format: float
          description: Incentive amount for this device-tier combination (in USD)
          example: 750
        calculation_details:
          type: string
          description: >-
            Human-readable explanation of how the incentive amount was derived
            for this device-tier combination. Format varies per program —
            partners should treat this as opaque diagnostic text, not parse it.
          example: 'Fixed rebate per device: $750'
        failed_requirements:
          type: array
          description: |
            List of eligibility requirements that failed for this combination.
            Empty if eligible is true.
          items:
            type: string
          example: []
        ignored_requirements:
          type: array
          description: |
            List of eligibility requirements that were ignored/skipped.
            Provided for transparency.
          items:
            type: string
          example: []
        completed_requirements:
          type: array
          description: List of eligibility requirements that were completed/passed.
          items:
            type: string
          example: []
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >
        API key for authentication. Include your Leap API key in the `x-api-key`
        header: `x-api-key: leap_live_...`
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Clerk JWT token for portal authentication

````