Get Example Code on GitHub

RebateBus API Documentation

View our Live Demo


Distributors and Manufacturers of lighting use the Rebate Bus API to give their users information about applicable rebates as they browse their websites. At a high level, the process of integrating your data consists of three main steps. First, a key is generated on an account that has permisson to manage a product inventory.

Second, the Manage Inventory tool should be used to upload data about the products for which rebate data is needed. Once Rebate Bus has this data, we can tell you what rebates it qualifies for and where. You can also maintain an inventory using our REST API. If you don't have access to the Manage Inventory tool, please get in touch so we can set up your account privileges.

Lastly, your server needs to be set up to save, update, and display the rebate data objects. How you do that is up to your company, but we've included some code samples to get you started.

Key Setup and Request Signing

Authenticating your requests to the Rebate Bus API is as simple as including your API key and user ID in HTTP POST requests made to any of our API endpoints.

You can obtain this information from the Edit Profile. Click "Manage API Key", then click "Generate". Your API Key and User ID will appear below. Every time you hit Generate, your old key is invalidated. Be sure to save it in a secure location, because if you lose your key you cannot get it back from the server - you'll need to generate a new one and add it to your server.


Rebate Bus exposes its key entities through a REST API. Please consult with Our Swagger API documentation for more information.

The Swagger REST API allows Rebate Bus users to perform administration of products, project proposals, incentive offers, and more. These functions allow for numerous use cases - get in touch for assistance or questions about your specific use case. Here are a few suggested uses:

  • Use the Proposal, Product, and ExistingProduct entities to build incentives into your project tool
  • Automatically maintain an accurate Rebate Bus representation of your incentive program by manipulating the Program and Rebate entities
  • Sync your product inventory programatically by manipulating the Product entity, then use the /api/getrebates route to maintain an up-to-date incentive section on your website

Adding Your Inventory

Adding your inventory data is done through our Manage Inventory tool. This tool can be used by exporting the relevant tables from your database to Excel, naming their columns for consistency with our data standards, exporting to CSV, and uploading the sheet. It can also be done manually by entering or editing products from the list using the graphical interface.

When the data that you wish to do rebate analysis on is in Rebate Bus, you're all set to add integration scripts to your server! Hit the download button before you leave this page - the productid column in that sheet is how you will make the association between products in your database and rebate data objects from the API.

Test Mode

When you're first getting set up with Rebate Bus, you'll probably want to do some testing to ensure that your code is written correctly. To facilitate such tests, you can switch your account to Test Mode, where you can submit rebate applications without worrying about mixing test and live data. Switch your account between test and live modes in your account settings.

Magento Plugins

Installation instructions for Magento 1 and 2 can be found at this Github link. Setup is fairly straightforward - first, add the SQL table. Then, add the module to your Magento backend and enable it. Next, add some products using the Inventory tool covered above. Finally, write some client scripts for your frontend which load in incentive offers. Full live examples are at and

Checkout Widget

After setting up your inventory, you can get your users actionable rebate data for any purcahse in one function call. Just reference our client Javascript file at and make a call like the one below:

		"uid": UID,
		"apikey": PUB_API_KEY,
		"productid_list": [TEST_PRODUCT_ID],
		"verified": function(code, amt, maxqty, zip) {
			alert("Got verification code " + code); // Add your own formatting 

This call initializes the Rebate Bus widget as an overlay iframe on your page. The widget loads code from our server which handles the process of directing the user to actionable rebate information. There are three incentive availability cases which the user might experience: instant incentives, downstream incentives, and no incentives. The "verified" callback to the widget is for the first case, and this is the only case that requires engagement from you. The callback should add the code, amount, quantity limit, and zip to the information stored in the cart for the product. The code, shipping address, and contact information must be sent to our server at /api/applymidstream once the user completes their purchase. If no instant incentive is available, Rebate Bus searches to find mail-in downstream incentives which they may be eligible for. If such incentives are found, the widget presents them to the user and allows them to open the application or program site in a new tab.

This widget should live at checkout. Rebate eligibility is different from product to product, and instant incentives may be available for some products in the cart but not others. The widget will handle every product in the cart simultaneously, as long as it is initialized with the correct products. The 'showdownstream' parameter can be used to restrict which rebates are shown: if it is false, the widget will only show rebates which can be delivered instantly. If false, it will fall back to rebates which must be mailed in to the program.

To view a live demo, please visit our demo and hit "Apply for Rebates". Using zip code 99999 and property type commercial will bring up our test instant incentive, which you can submit and use to test your integration. Use any zip code, such as 10526 for Con Edison in New York, and the commercial property type and you will see a rebate if there is one available at that location.

Search Widget

How do you let browsing users know about rebate availability before they hit checkout? Just download our client Javascript file and make a call like the one below: Download Widget

			"uid": UID,
			"apikey": PUB_API_KEY,
			"productid_list": products, 
			"showdownstream": true,
			"callback": function(productid, incentive) {
				$("#" + productid + " .pric1").append("$" + incentive.msrp + "");
				$("#" + productid + " .pric2").text("$" + (incentive.msrp - incentive.rebateAmount).toFixed(2));
				$("#" + productid + " .disc").text("$" + incentive.rebateAmount + " rebate from " + incentive.program);


This call initializes the Search Widget, which has two possible immediate outcomes depending on the state of browser cookies. If the Rebate Bus property type and zip code cookies are set, the widget immediately loads applicable rebate data and starts calling the provided callback. If not, the Rebate Bus server geolocates the user by IP address, then loads data and hits the callback. The widget is configurable by the user - using the bar which is loaded by default into the upper right, they are able to change their utility zip and property type to customize the rebate offerings they can view. The provided callback should alter your page in whatever way you see fit - just be sure to follow our utility attribution guideline: any time you advertise rebate availability for specific products to users, you must specify the program offering the rebate. Get this field from the provided incentive data as in this example.

To view a live demo, please visit our demo. Using zip code 99999 and property type commercial will bring up our test instant incentive which should be applicable to any product ids you configure the widget with. Use any zip code, such as 10526 for Con Edison in New York, and the commercial property type and you will see a rebate if there is one available at that location. If the showdownstream flag is included, mail-in rebate matches will call the provided function. Else only instant incentives will.

Custom Integration - Writing an eCommerce Plugin

Writing a Rebate Bus plugin for your eCommerce platform of choice can be accomplished for just about any software stack. Please contact us for support if you pursue such a plugin. The key requirements are as follows:

Geolocation and Eligibility: Users must somehow be resolved to a zip code and a property type. The Search Widget automatically handles geolocation using IP address. Your integration can build a dedicated incentives landing page which accomplishes this, or can use the Search Widget. If you opt to build a dedicated page on your own, please familiarize yourself with the /api/verifymidstream application route.

Utility Attribution: Users who are browsing the site and have been geolocated must see utility logos and incentive offers on applicable products as they shop.

Instant Application: When a user is eligible for incentives on the products in their cart, our MidstreamWidget should be used. This widget can be styled according to your color scheme and fonts by uploading a custom CSS file from your Rebate Bus Account Settings page. This widget loads an iframe with the application form, which is dynamically configurable by the utility. It can be added as a full-page overlay like in the Magento example, or loaded into a section of your cart page. The callback from MidstreamWidget must save the incentive on your backend, associated with the customer's quote.

Checkout: Incentives which customers add to their cart must show in the subtotal. The 'maxqty' and 'cap' fields which come back in the 'verified' callback, or the /api/verifymidstream API route, must be applied. The former must restrict the total number of products receiving incentives, while the latter must restrict the per-product incentive value to the specified cap, as a percent of price.

Order Placement: When a customer checks out with incentives in their cart, the /api/applymidstream route must be hit and returned from successfully. Finally, the emailed invoice to the customer must include the incentive amount and the name of the program.

Custom Checkout Integration - /api/verifymidstream and /api/applymidstream

It is one thing to tell a customer that they can get a discount by referring to a rebate form - it is quite another to be able to offer them an impactful markdown at the point of purchase! In select markets, Rebate Bus markets instant incentives. The API is structured in a two-step verification and approval process - payments are made regularly to you based on the approved rebates that are submitted to our system. Contact us before integrating this process or rebates from any new program in your application, as there may be product and/or vendor approval requirements. You can review the sample implementation on our demo site for a simple usage example for help getting started. We offer a Magento plugin as well.

Security is a very serious issue in the Instant Rebate API. Never let your API key be exposed client-side or communicate directly with the Rebate Bus server from a client! This is a violation of our terms, and you are responsible for the veracity of data submitted to the API with your key.

Once you've gotten approved, you can implement instant rebates! The result of the /api/getrebates call contains two fields - downstream and midstream. Use this data using the /api/verifymidstream and /api/applymidstream endpoints. The former endpoint is for ensuring rebate applicability and funds available. It has 6 parameters: your user id and API key, rebate id, product id, shipping zip, and quantity. Shipping zip is very important to verification - the zip provided in the /api/verifymidstream request must match with that of the final shipping location otherwise the rebate will not be able to be completed. If verification is successful, the HTTP status code will be 200 and response will include two fields: 'amount' and 'verification', 'amount' being the approved incentive value and 'verification' being a unique code.

We recommend that /api/verifymidstream be used when the customer adds a product to their cart, or similarly to applying a coupon in your checkout cart. When the customer checks out, /api/applymidstream is used to confirm the incentives in the cart with the Rebate Bus server.

/api/applymidstream should be called from your server in the process which runs when the customer's purchase has been confirmed. It is carried out as an atomic operation - either all incentives in the request are approved or none are. It takes the following parameters: your user id and API key, the shipping zip code and address, billing zip code and address, customer email address, customer phone number, and customer name. The incentives must be included in the request as a 'rebates' array - each rebate item must include the quantity and verification parameters. If it is successful, you should save the verification codes and rebate amounts in your database as they are the verification that you need in order to receive reimbursement for the incentive amount. When a rebate has been approved by the API, it should be placed on hold for at least 8 business hours to allow Rebate Bus time to detect any issues with the customer's eligibility and report the transaction to the utility.

/api/applymidstream Request Parameters

zip: A 5-digit numerical zip code of the shipping address

billzip: A 5-digit numerical zip code of the billing address

address: A string representation of the shipping address. Use the format "street, city, region".

billaddress: A string representation of the shipping address. Use the format "street, city, region".

contactname: The name (first and last) to whom the purchase is being billed.

contactphone: Phone number from the billing info

contactemail: Email address from the billing info

rebates: Array consisting of items with the following parameters:
	verification: Verification code returned from /api/verifymidstream

	quantity: Final purchase quantity. Must be less than or equal to the maxqty parameter returned from verifymidstream - failure to enforce this restriction may cause errors.

/api/applymidstream Response

200 OK: Rebate Bus agrees to pay for all rebates in the request - the verification codes are considered approved, and can no longer be used.

500 Server Error: Rebate Bus was unable to approve the request. A reason for the failure is given in the 'error' parameter of the response JSON.


V1 API Integration: /api/getrebates

Now that your data is in Rebate Bus, you can start using it in your code. We recommend that you store and manipulate the data server-side for security and performance reasons. This provides security by allowing you to keep your API key and high-level rebate data overview secret. It improves performance because when a user makes requests to your site, you can serve their response without the added network latency and processing time of a hit to the Rebate Bus server. Keeping traffic low reduces our server costs, and those savings are passed on to you. We recommend that you update your rebate data at least weekly.

To obtain or refresh this data, make requests to the api/getrebates endpoint as shown below. Optionally, you may include a productid_list parameter. If this parameter is present, only products with ids in this list will be matched with applicable rebates. If it is not present, this data will be provided for your whole inventory.

function getSomeRebates() {
		type: "POST",
		url: "",
		data: {"uid": YOUR_UID, "apikey": "YOUR_API_KEY"},
		complete: function(response, stat) {
		}, error: function(response, stat) {
			console.log("error retrieving data from Rebate Bus");

Data Overview

At this point, we have data objects containing actionable data for this product and for this user. Now, what does the data look like and how do we use it? And exactly what has been done to produce this match? The data under 'downstream' consists of an array of JSON objects with two keys: productid and rebates. The usage of this has been made clear already, so lets dive into the rebates data object.

The rebates object consists of two types: custom and prescriptive. Custom rebates are those where the exact amount of the rebate is dependent on the wattage of the fixture being replaced. Prescriptive rebates are those where the amount is fixed.

Both types of rebate have already had all quantifiable stipulations on the replacement product applied server side - this includes luminosity, wattage, efficacy, Primary Use category, incentive caps (such as capping rebates at 50% of total fixture cost), DLC status, and Energy Star status. However, sometimes there are certain stipulations not quantifiable by our system. These are expressed by our analysts when they write the 'replacementrequirement' field.

Additionally, there are several types of requirement which must be applied to the lighting that is being replaced or which relate to new construction versus existing building upgrade. These are expressed in our data for you to format graphically and present to your users, and are called out below.

Refer as needed to this reference list of the data which may be present in rebate objects. Not all fields will always be present.

/api/getrebates Request Parameters

productid_list: A list of product ids for which rebate data must be calculated. If omitted, will run the calculation for all products in your inventory - this may be a high-latency request if your inventory contains many products.

zip: If included, only utility programs for which this zip is eligible will be included in the response.

propertytype: If included, only utility programs for which this property type is eligible will be included in the response. If the specified property type is not 'residential' or 'commercial', this parameter is ignored.

/api/getrebates Response Parameters

applicationLink: An HTTP link to the forms for applying for the rebate

utility: The utility offering this rebate. Note that there may be duplicate rebates under the same program, if that program covers multiple utilities (for example, all WI utilities fall under Focus on Energy) 

state: The state where it is offered. Note that the same consideration for utilities applies for state as well

code: If the rebate program organizes its offerings using codes or numbers, they are given here

rebateAmount: Our estimate of the rebate amount, for a typical replacement. You can calculate your own for custom rebates using rate, amount, estimated operating hours, and the equivalent wattage, or use this estimate calculated by Rebate Bus which does just that

replacementrequirement: An open-ended description of additional stipulations on eligibility for this rebate

unit: For prescriptive rebates, a text field that describes the item being replaced (for example, Lamp or Fixture). For custom rebates, a field that describes the savings unit that the rebate is calculated with: watts (w), kilowatts (kw), or kilowatt-hours (kWh)

amount: The value of the rebate. For prescriptive rebates this is equal to rebateAmount. For custom rebates, it is the amount paid per 'unit'

newconstructioneligible: Boolean indicating whether new construction projects are eligible	

newconstructiononly: Boolean indicating whether only new construction projects are eligible	

existingwattage: An array indicating the range of existing product wattage values that are acceptable. The boundaries are inclusive. If existing product wattage must be greater than a certain value, then the array will have length one and the sole entry will be that value. Else, the array will be of length 2. 

existinglumens: An array indicating the range of existing product luminosity values that are acceptable. The boundaries are inclusive. If existing product luminosity must be greater than a certain value, then the array will have length one and the sole entry will be that value. Else, the array will be of length 2. 

minwattssaved: A string indicating a minimum watts saved requirement. Minimum watts saved requirements indicate that a new product must have a lower wattage than the existing product by some threshold, such as a value or a percent.

Localizing Rebate Offers - /api/getutilities

Before you can serve offers applicable to a given user, it is necessary to geolocate them and find programs which are likely to be relevant. Rebate Bus provides a second data object which facilitates this, accessible at the /api/getutilities endpoint. Data returned by this endpoint contains an entry for every program id which includes the relevant utilities and zip codes. In the given code example, client-side HTML5 geolocation is used to determine a longitude and latitude. This longitude and latitude is compared to the latitudes and longitudes of each zip code in the utilities object, for each program. The program applicable to the closest zip is passed off to the setProgramRebates function (shown in the demo), which uses the /api/getrebates data and this program's id to add incentive information to the page.

 * Infer a local program by finding the programid at the closest zip code to the geolocated location
 * After the program has been identified, call setProgramRebates to localize the page to this program
function localizeRebateOffers() {
        var curProgramId;
        var curUtility;
        var closestProgram = -1;
        var closestDifference = 999999999;
        var curDifference;
        var curLatDiff, curLngDiff;
        var i, j;
        var browseProgramId;
        var applicablePrograms = [];
        if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(function(position) {
                        for (curProgramId in utilityDict) {
                                for (i = 0; i < utilityDict[curProgramId].length; i++)
                                        curUtility = utilityDict[curProgramId][i];
                                        if (curUtility.zips) {
                                                for (j = 0; j < curUtility.zips.length; j++) {
                                                        curLatDiff = (curUtility.zips[j].latitude - position.coords.latitude);
                                                        curLngDiff = (curUtility.zips[j].longitude - position.coords.longitude);
                                                        curDifference = curLatDiff * curLatDiff + curLngDiff * curLngDiff;
                                                        if (curDifference < closestDifference) {
                                                                closestProgram = curProgramId;
                                                                closestDifference = curDifference;
                        if (closestProgram < 0) {
                                alert("Geolocation failed - rebate demos will not work properly");
                        else {

        } else {
                alert("Geolocation is not supported by this browser - rebate demos will not work properly!");