Submit an EV Charger Installation Request

Wattbuy enables you to add EV charger installation to your customer experience through the Qmerit installation platform. The integration follows four steps:

  1. Confirm that installation service is available for the customer
  2. Retrieve the fields required to create the installation request
  3. Submit the request through the Forms API
  4. The customer receives an email from Qmerit where they can view and manage their installation through our installer network

Quickstart



1. Check installation availability

Use the Offers API to find offers available for the customer's ZIP code.

This step is optional. Because the Qmerit offer ID is known in advance, you can proceed directly to retrieving the form fields when an availability check is not required.

curl --request GET \
  --url "https://apis.wattbuy.com/v3/offers?zip=61820&category=ev_chargers" \
  --header "accept: application/json" \
  --header "x-api-key: YOUR_API_KEY"

A successful response contains a list of available offers:

{
  "status": "ok",
  "wattkey": "MzgyMCBWaXRydXZpYW4gV2F5IEFwdCAxMTE=@5qv-x53-nyv",
  "offers": [
    {
      "offer_id": "qmerit",
      "offer_category": "ev_chargers",
      "has_form": true
    }
  ]
}

Confirm that the response includes an offer with an offer_id of qmerit.

2. Get the required form fields

Retrieve the fields required to submit a Qmerit installation request.

curl --request GET \
  --url "https://apis.wattbuy.com/v3/form?offer_id=qmerit" \
  --header "accept: application/json" \
  --header "x-api-key: YOUR_API_KEY"

The response describes each field, including whether it is required, its data type, validation message, form section, and available options.

{
  "status": "ok",
  "data": {
    "supplierForm": {
      "form": {
        "firstName": {
          "required": true,
          "errMsg": "First name is required.",
          "formSection": "personal"
        },
        "serviceZip": {
          "required": true,
          "errMsg": "Postal Code is required.",
          "formSection": "address"
        },
        "mainPanelImages": {
          "required": true,
          "minItems": 3,
          "errMsg": "At least 3 panel photos required.",
          "formSection": "panel"
        },
        "vehicleMake": {
          "required": true,
          "errMsg": "Vehicle make is required.",
          "options": [
            "Acura",
            "Audi",
            "BMW",
            "Ford",
            "Honda",
            "Tesla",
            "Toyota"
          ],
          "cascading_group": {
            "group": "vehicle_selection",
            "level": 1
          },
          "formSection": "vehicle"
        }
      }
    }
  }
}

Use the returned schema as the source of truth when building and validating your intake form.

3. Submit the installation request

Submit the completed form to the enrollment API.

The enrollment endpoint uses enroll.wattbuy.com, rather than apis.wattbuy.com.

The following query parameters are required:

ParameterDescription
offer_idUse qmerit
ip_addressThe customer's IP address

The optional send_email parameter defaults to true.

curl --request POST \
  --url "https://enroll.wattbuy.com/v3/form?offer_id=qmerit&ip_address=192.0.2.1" \
  --header "accept: application/json" \
  --header "content-type: application/json" \
  --header "x-api-key: YOUR_API_KEY" \
  --data '{
    "form": {
      "firstName": "Jane",
      "lastName": "Smith",
      "phone": "5125550123",
      "email": "[email protected]",
      "contactMethod": "Email",
      "serviceAddress1": "123 Main St Apt 4",
      "serviceCity": "Austin",
      "serviceState": "TX",
      "serviceZip": "78701",
      "country": "US",
      "vehicleMake": "Ford",
      "vehicleModel": "Mustang Mach-E",
      "vehicleYear": "2023",
      "mainPanelImages": [
        "https://example.com/panel1.jpg",
        "https://example.com/panel2.jpg",
        "https://example.com/panel3.jpg"
      ],
      "mainBreakerAmperage": 200,
      "mainBreakerCount": 2,
      "openBreakerSlots": 4,
      "distanceToCharger": 20,
      "garageType": "Attached",
      "garageSpaces": 2,
      "acUnits": 1,
      "pools": 0
    }
  }'

The fields required in the request body are determined by the response from GET /form.

Successful response

A successful request returns a WattBuy order ID and the Qmerit reference ID.

{
  "status": "SUBMITTED",
  "sub_status": "Approved",
  "customer_messaging": null,
  "code": "S1",
  "metadata": {
    "order_id": "WB-HCA-5MY1000815",
    "reference_id": "5de22d4e-1a15-4048-8dc8-debd7e39141f",
    "error_message": null,
    "status_reason": "success",
    "full_name": "Jane Smith",
    "telephone": "5125550123",
    "service_address": "123 Main St Apt 4, Austin, TX, 78701",
    "email": "[email protected]",
    "vehicle_make": "Ford",
    "vehicle_model": "Mustang Mach-E",
    "vehicle_year": "2023",
    "contact_method": "Email"
  }
}

Store metadata.order_id as WattBuy's identifier for the installation request. The reference_id identifies the corresponding request in the Qmerit workflow.

Implementation considerations



Cache the form schema

The Qmerit form schema can be cached rather than retrieved during every customer session.

Refresh the cached schema periodically so your integration continues to reflect changes to required fields, options, and validation rules. Avoid permanently hardcoding the form definition.

Support dynamic fields

The form response may contain:

  • Required and optional fields
  • Field types and validation messages
  • Dropdown options
  • Minimum item requirements
  • Field groupings
  • Cascading options

For example, vehicle selection uses a three-level cascade:

vehicleMake → vehicleModel → vehicleYear

The valid models depend on the selected make, and the valid years depend on the selected model.

Validate uploaded images

mainPanelImages is required and specifies a minimum of three images.

Your application should upload the images to an accessible location and include their URLs in the enrollment request.

{
  "mainPanelImages": [
    "https://example.com/panel1.jpg",
    "https://example.com/panel2.jpg",
    "https://example.com/panel3.jpg"
  ]
}

Handle failed submissions

A failed request may still return an order_id along with information describing the failure.

For example, an existing customer may return:

{
  "status": "FAILED",
  "sub_status": "EXISTING_CUSTOMER",
  "customer_messaging": null,
  "code": "F3",
  "metadata": {
    "order_id": "WB-HCA-4AB9876543",
    "reference_id": null,
    "error_message": "An order already exists for this customer.",
    "status_reason": "EXISTING_CUSTOMER",
    "full_name": "Jane Smith",
    "telephone": "5125550123",
    "service_address": "123 Main St Apt 4, Austin, TX, 78701",
    "email": "[email protected]",
    "vehicle_make": "Ford",
    "vehicle_model": "Mustang Mach-E",
    "vehicle_year": "2023",
    "contact_method": "Email"
  }
}

Use the following fields when determining how to handle the result:

FieldPurpose
statusOverall submission status
sub_statusMore specific outcome
codeMachine-readable result code
metadata.order_idWattBuy order identifier
metadata.reference_idQmerit workflow identifier, when available
metadata.status_reasonMachine-readable reason for the result
metadata.error_messageMore detailed failure information

Do not treat an HTTP 200 response alone as confirmation that the installation request succeeded. Check the response's status, sub_status, and code.

Next steps

Review the complete API references for:

  • Offers
  • Get Form Fields
  • Submit an Offer Enrollment