Authentication
Getting Bearer Tokens
-
Create a new user login either by registering to create a new free account, or by sending an invitation to join an existing account
-
Login to the OpenSolar App to automatically create your bearer token
-
Once you've created the token, you can acquire it via the command line by POSTing your username and password to the login endpoint
Note: Standard user tokens expire after 7 days. To prevent tokens from expiring, set your user to be a machine user.
Sample request and response:
$ curl "https://api.opensolar.com/api-token-auth/" -H "Content-Type: application/json" --request POST -d '{"username":"arnie@illbeback.com","password":"gettothechopper"}'
output: { "token": "d7e1b00845ae0d9d3fdfc8c0cbf2300766d94002", "user": { ... }, ... }
Using Bearer Tokens
To authenticate, use this code:
# Pass the header and token with each request curl "api_endpoint_here" -H "Authorization: Bearer <token>"
OpenSolar uses Bearer tokens in the HTTP Authentication header to allow access to the API.
OpenSolar expects the API key to be included in all API requests to the server in a header that looks like the following:
Authorization: Bearer <token>
Keep your bearer token secure! Never make a shared bearer token visible in the client side.
How to set Machine User
Use the bearer token and supply the "is_machine_user" payload to set the user as machine user.
Note: Once is_machine_user is set to true, token expiration for that account will not apply anymore.
Sample request and response:
Note: Bearer token should be provided as an Authorization header
Note: The http method user here is PATCH which is stateful
Note: To disable machine user, just change true to false in the machine user payload
$ curl "https://api.opensolar.com/auth/users/{your_user_id}/" -H "Content-Type: application/json" -H "Authorization: Bearer <token>" --request PATCH -d '{"is_machine_user":true}'
{ "url": "https://api.opensolar.com/auth/users/{your_user_id}/", "email": "arnie@illbeback.com", "is_machine_user>": true }
Schema Overview
-
Orgs
-
(Customer Data)
-
Projects
-
Systems
-
Assigned Contacts (Contact)
-
Assigned Team Member (Role)
-
Assigned Site Inspector (Role)
-
Assigned Installer (Role)
-
Private Files
-
Current Utility Tariff (link to UtilityTariff or custom)
-
Proposed Utility Tariff (link to UtilityTariff or custom)
-
Events
-
-
Contacts
-
Systems
-
Roles
-
(Configuration)
-
Team (Role)
-
Org Settings / API Keys
-
Pricing Schemes
-
Payment Options
-
Costings
-
Setbacks & Design Settings
-
Component Activations
-
Modules (link to Component Database or custom)
-
Inverters (link to Component Database or custom)
-
Batteries (link to Component Database or custom)
-
Others (link to Component Database or custom)
-
-
Incentives
-
Document Templates
-
Lead Capture Forms
-
Public Files
-
Utility Tariffs (private)
-
-
User Logins
-
Public Database
-
Utility Tariffs (public)
-
Component Database
-
Modules
-
Inverters
-
Batteries
-
Others
-
Utilities
-
Distributors/Territories
-
-
Event Types
-
Roof Types
Orgs
Sample request and response:
curl "https://api.opensolar.com/api/orgs/:org_id/" -H "Authorization: Bearer <token>"
{ "id": 1, "name": "My Company Name", "projects": "https://api.opensolar.com/api/orgs/:org_id/projects/", ... }
An Org stores all your data on OpenSolar, including projects, contacts, team, configuration, etc.
Most endpoints are prefixed with the /api/orgs/:org_id/...
EndpointDescription
GET /api/orgs/:org_id/Get Org
POST /api/orgs/:org_id/Update Org
Projects
A Project stores all the data for a particular project location, including [system designs], assigned contacts and a team members, utility information, project-specific files, events, etc.
Sample GET request and response:
curl "https://api.opensolar.com/api/orgs/:org_id/projects/" -H "Authorization: Bearer <token>"
[ { "id": 1, "address": "4 Main St", "contacts": [ "https://api.opensolar.com/api/orgs/1/contacts/34/" ], ... }, ... ]
EndpointDescriptionQuery Parameters
GET /api/orgs/:org_id/projects/:id/Get Project
POST /api/orgs/:org_id/projects/Create Project
PATCH /api/orgs/:org_id/projects/:id/Update Project
DELETE /api/orgs/:org_id/projects/:id/Delete Project
GET /api/orgs/:org_id/projects/List Projectspage, limit, fieldset (list, studio)
Reading/Writing Related Resources
Assigned Role
-
project.assigned_role_data is read-only data for the assigned role, specified in project.assigned_role_id.
-
To replace the role assigned to this project, update project.assigned_role with the URL for the new role.
-
To update the data for this role who has been assigned to the project, use the Update Role endpoint for the resource found at the url in project.assigned_role.
Contacts
-
project.contacts_data is a read-only data for contacts associated with the project.
-
To create a new project while creating or updating a project, use the project.contacts_new field.
-
To update the data for a contact associated with the project, use the Update Contact endpoint for the resource found at the url in project.contacts.
-
To replace the assigned contacts for a project, call the Update Project endpoint and include new contact urls in project.contacts.
Sample POST request and response
curl "https://api.opensolar.com/api/orgs/:org_id/projects/" -H "Content-Type: application/json" -H "Authorization: Bearer <bearer-token>" --request POST -d '{ "identifier": "123456", "is_residential": "1", "lead_source": "Door Knockers", "notes": "Has a pool, needs LG panel.", "lat": "35.12364", "lon": "128.23216", "address": "123 Fake st", "locality": "Fakesville", "state": "NSW", "country_iso2": "AU", "zip": "2020", "number_of_phases": "1", "roof_type": "https://api.opensolar.com/api/roof_types/6/", "assigned_role": "https://api.opensolar.com/api/orgs/1/roles/123/", // assigned_installer_role and assigned_site_inspector_role also available "contacts_new": [ { "first_name": "George", "family_name": "Costanza", "email": "gconstanza@vanderlayindustries.com", "phone": "0400000000", "date_of_birth": "1990-01-01", "gender": "2" // 0 = unset, 1 = female, 2 = male } ] }'
{ "address": "123 Fake st", "id": 6624, "identifier": "123456", "lat": 35.12364, "lead_source": "Door Knockers", "locality": "Fakesville", "lon": 128.23216, "notes":"Has a pool, needs LG panel.", "number_of_phases": 1, "org_id": 1, "org": "https://api.opensolar.com/api/orgs/1/", "state":"NSW", "systems": [ ... ], "url": "https://api.opensolar.com/api/orgs/1/projects/6624/", "zip":"2020", "customer_proposal_data":null, "assigned_role_data": { "id": 1, "email": "bob@company.com.au", "is_admin": true, "user": "https://api.opensolar.com/auth/users/10/", "user_email": "bob@company.com", "org": "https://api.opensolar.com/api/orgs/30/", "is_hidden": false, "url": "https://api.opensolar.com/api/orgs/1/roles/50/", "first_name": "Bob", "family_name": "Company", "job_title": "Important Job", "accreditation": "", "user_phone": "", "display": "Bob S. Company", "phone": "94811111", "allow_email_notifications": true, "portrait_image": null, "google_calendar_id": null, "has_logged_in": true, "schedule_meeting_url": "https://calendly.com/bobby/customer-walk-through", "schedule_meeting_label": "Schedule a time to discuss!", "api_key_chat": "1233-333-11-9000", "user_is_staff": true, "org_name": "SunCo" }, "assigned_role_email": "bob@company.com", "assigned_role_id": 1, "assigned_role_name": "Bob S. Company", "assigned_role_phone": "94811111", "assigned_role": "https://api.opensolar.com/api/orgs/1/roles/50/", "assigned_role_accreditation": "", "contacts": [ "https://api.opensolar.com/api/orgs/1/contacts/60/" ], "contacts_data": [ { "id": 60, "first_name": "George", "family_name": "Costanza", "email": "gconstanza@vanderlayindustries.com", "phone": "0400000000", "date_of_birth": "1990-01-01", "gender": 2, "url": "https://api.opensolar.com/api/orgs/1/contacts/60/" } ] }
Contacts
Sample request and response:
curl "https://api.opensolar.com/api/orgs/:org_id/contacts/" -H "Authorization: Bearer <token>"
[ { "id": 34, "first_name": "Edmond", "family_name": "Becquerel", ... }, ... ]
Personal details for an individual Customer is stored as a Contact.
A Contact may optionally have an OpenSolar User Login attached, which allows a Customer to login to MyEnergy.
EndpointQuery Parameters
GET /api/orgs/:org_id/contacts/:id/
POST /api/orgs/:org_id/contacts/
PUT /api/orgs/:org_id/contacts/:id/
DELETE /api/orgs/:org_id/contacts/:id/
GET /api/orgs/:org_id/contacts/page, limit
Systems
A System stores all of the detail, energy output, system size, pricing etc. for a particular system design. There may be more than one System associated with a Project.
Sample request and response:
curl "https://api.opensolar.com/api/orgs/:org_id/systems/?fieldset=list" -H "Authorization: Bearer <token>"
[ { "id": 1253, "url": "https://api.opensolar.com/api/orgs/1/systems/1253/", "name": "", "uuid": "E583FD88-EB6C-4311-91A9-AC719041EAA8", "order": 0, "system_lifetime": 0, "inverter_range": null, "dc_optimizer_active": false, "dc_optimizer_efficiency": 1.0, "show_customer": true, "is_current": false, "auto_string": true, "discount": 0.0, "adders_per_system": 0.0, "adders_per_panel": 0.0, "adders_per_watt": 0.0, "kw_stc": 2.76, "battery_total_kwh": 0.0, "price_including_tax": 5520.0, "price_excluding_tax": 5018.18, "net_profit": 11416.05, "module_quantity": 8, "co2_tons_lifetime": 65.96, "project": "https://api.opensolar.com/api/orgs/1/projects/100/", "org": "https://api.opensolar.com/api/orgs/1/", "pricing_scheme": "https://api.opensolar.com/api/orgs/1/pricing_schemes/1408/", "output_annual_kwh": 5497, "consumption_offset_percentage": 82, "modules": [ { "module_activation_id": 613, "code": "JKM285M-60", "manufacturer_name": "Jinko Solar Co., Ltd", "quantity": 20 } ], "inverters": [], "batteries": [], "others": [] }, ... ]
EndpointQuery Parameters
GET /api/orgs/:org_id/systems/:id/fieldset (list) (required)
GET /api/orgs/:org_id/systems/fieldset (list) (required), page, limit, project (id)
Systems Details
Returns an object with design-related data for each system in a given project. The data returned includes hardware, adders, incentives and information on module layout.
Sample request and response:
curl "https://api.opensolar.com/api/orgs/:org_id/projects/:project_id/systems/details/" -H "Authorization: Bearer <token>"
{ "systems": [ { "kw_stc": 6.21, "uuid": "E583FD88-EB6C-4311-91A9-AC719041EAA8", "id": 8280, "name": "System 1 (6.21 kW)", "modules": [ { "manufacturer_name": "LG Electronics Inc.", "code": "LG345N1C-V5", "quantity": 18 } ], "total_module_quantity": 18, "inverters": [ { "manufacturer_name": "123", "code": "123", "quantity": 1 } ], "batteries": [ { "manufacturer_name": "GoodWe", "code": "2*LX U5.4-L", "quantity": 1 } ], "other_components": [ { "manufacturer_name": "Hardware Co.", "code": "dc_isolator_xyz", "quantity": 1 } ], "adders": [ { "label": "Adder", "total_value": 20.0, "total_cost": 0, "show_customer": false, "quantity": 2 }, { "label": "Discount", "total_value": -30.0, "total_cost": 0, "show_customer": false, "quantity": 3 }, { "label": "Cost", "total_value": 0, "total_cost": 20.0, "show_customer": false, "quantity": 1 } ], "module_groups": [ { "module_quantity": 18, "azimuth": 7, "slope": 20.0, "layout": "portrait" } ], "incentives": [ { "paid_to_customer": true, "value": 884, "title": "6% Base Federal Investment Tax Credit (ITC)" } ], "data":{} }, ... ] }
Endpoint
GET /api/orgs/:org_id/projects/:project_id/systems/details/
System Image
A System image can be acquired by using the uuid in the System payload
EndpointQuery Parameters
GET api/orgs/:org_id/projects/:project_id/systems/:uuid/image/"width and height (required)
Sample request and response:
curl "https://api.opensolar.com/api/orgs/:org_id/projects/:project_id/systems/:uuid/image/?width=500&height=500" -H "Authorization: Bearer <token>"
Roles
Sample request and response:
curl "https://api.opensolar.com/api/orgs/:org_id/roles/" -H "Authorization: Bearer <token>"
[ { "id": 99, "email": "john@workplace.com.au", "is_admin": true, "user": "https://api.opensolar.com/auth/users/99/", "user_email": "john@workplace.com.au", "org": "https://api.opensolar.com/api/orgs/88/", "is_hidden": false, "url": "https://api.opensolar.com/api/orgs/88/roles/77/", "first_name": "John", "family_name": "Person", "job_title": "Sales Person", "accreditation": "", "user_phone": "", "display": "John person", "phone": "94811111", "allow_email_notifications": true, "portrait_image": null, "google_calendar_id": null, "has_logged_in": true, "schedule_meeting_url": "https://calendly.com/john-os/customer-walk-through", "schedule_meeting_label": "Schedule a time to discuss!", "api_key_chat": "1234-567-11-0000", "user_is_staff": true, "org_name": "SunCo" }, ... ]
Details about a users role.
EndpointQuery Parameters
GET /api/orgs/:org_id/roles/
GET /api/orgs/:org_id/roles/:id/fieldset (list), range, page, limit, ordering (id, is_admin)
Pricing Schemes
Sample request and response:
curl "https://api.opensolar.com/api/orgs/:org_id/pricing_schemes/" -H "Authorization: Bearer <token>"
[ { "url": "https://api.opensolar.com/api/orgs/1/pricing_schemes/68/", "org": "https://api.opensolar.com/api/orgs/1/", "is_archived": false, "pricing_formula": "Price Per Module/Inverter/Battery", "title": "per equipment", "priority": 1, "configuration_json": "{\"price_per_module\":500,\"price_per_inverter\":1000,\"price_per_battery\":2000,\"tax_percentage_included\":10}", "created_date": "2019-02-12T01:43:54.320315Z", "modified_date": "2019-02-12T01:43:54.320357Z", "auto_apply_enabled": true, "auto_apply_only_specified_states": null, "auto_apply_only_specified_zips": null, "id": 68 }, ... ]
EndpointQuery Parameters
GET /api/orgs/:org_id/pricing_schemes/:id
POST /api/orgs/:org_id/pricing_schemes/:id
DELETE /api/orgs/:org_id/pricing_schemes/:id
GET /api/orgs/:org_id/pricing_schemes/page, limit, priority (int), auto_apply_enabled (true, false),
pricing_formula (Markup Percentage, Price Per Watt, Price Per Watt By Size, Fixed Price)
Payment Options
Sample request and response:
curl "https://api.opensolar.com/api/orgs/:org_id/payment_options/" -H "Authorization: Bearer <token>"
[ { "url": "https://api.opensolar.com/api/orgs/1/payment_options/242/", "org": "https://api.opensolar.com/api/orgs/1/", "utility_tariff_override": null, "is_archived": false, "payment_type": "loan_advanced", "title": "1 year Delay", "priority": 1, "configuration_json": "{\"collect_signature\":true,\"final_payment_frequency\":\"monthly\",\"final_term\":24,\"final_interest_rate\":6,\"final_dealer_fee_percentage\":null,\"final_dealer_fee_fixed\":null,\"down_payment_percentage\":10,\"down_payment_min\":10,\"down_payment_max\":10000,\"delayed_down_payment_duration\":12,\"down_payment_interest_rate\":7,\"down_payment_dealer_fee_percentage\":10,\"down_payment_dealer_fee_fixed\":50}", "description": "", "integration_external_reference": null, "created_date": "2019-10-13T23:51:34.296889Z", "modified_date": "2019-10-20T02:40:51.347454Z", "auto_apply_enabled": false, "use_highest_standard_system_price": true, "auto_discount": true, "auto_apply_only_specified_states": null, "auto_apply_only_specified_zips": null, "contract_template": "", "id": 242 }, ... ]
EndpointQuery Parameters
GET /api/orgs/:org_id/payment_options/:id
POST /api/orgs/:org_id/payment_options/:id
DELETE /api/orgs/:org_id/payment_options/:id
GET /api/orgs/:org_id/payment_options/page, limit, priority (int), auto_apply_enabled (true, false),
payment_type (cash, loan, loan_advanced, ppa, regular_payment, lease)
Costing
Sample request and response:
curl "https://api.opensolar.com/api/orgs/:org_id/costings/" -H "Authorization: Bearer <token>"
[ { "url": "https://api.opensolar.com/api/orgs/1/costings/1/", "org": "https://api.opensolar.com/api/orgs/1/", "roof_type_adder_1_roof_type": null, "roof_type_adder_2_roof_type": null, "roof_type_adder_3_roof_type": null, "roof_type_adder_4_roof_type": null, "roof_type_adder_5_roof_type": null, "title": "Default Project Configuration", "description": "Default settings ready for customization.", "priority": true, "created_date": "2020-04-15T06:49:15.938679Z", "modified_date": "2020-04-15T06:49:15.938715Z", "supplier_shipping_per_system": 0.0, "supplier_shipping_per_panel": 0.0, "supplier_shipping_per_watt": 0.0, "racking_per_system": 0.0, "racking_per_panel": 0.0, "racking_per_watt": 0.0, "bos_per_system": 0.0, "bos_per_panel": 0.0, "bos_per_watt": 0.0, "job_site_shipping_and_warehousing_per_system": 0.0, "job_site_shipping_and_warehousing_per_panel": 0.0, "job_site_shipping_and_warehousing_per_watt": 0.0, "labor_per_system": 0.0, "labor_per_panel": 0.0, "labor_per_watt": 0.0, "allocation_of_lead_gen_per_system": 0.0, "allocation_of_lead_gen_per_panel": 0.0, "allocation_of_lead_gen_per_watt": 0.0, "allocation_of_salary_per_system": 0.0, "allocation_of_salary_per_panel": 0.0, "allocation_of_salary_per_watt": 0.0, "commission_per_system": 0.0, "commission_per_panel": 0.0, "commission_per_watt": 0.0, "commission_percentage_of_cogs_and_labor": 0.0, "project_management_per_system": 0.0, "project_management_per_panel": 0.0, "project_management_per_watt": 0.0, "design_drawings_per_system": 0.0, "design_drawings_per_panel": 0.0, "design_drawings_per_watt": 0.0, "permit_costs_per_system": 0.0, "permit_costs_per_panel": 0.0, "permit_costs_per_watt": 0.0, "other_costs_per_system": 0.0, "other_costs_per_panel": 0.0, "other_costs_per_watt": 0.0, "presale_software_and_design_per_system": 0.0, "presale_software_and_design_per_panel": 0.0, "presale_software_and_design_per_watt": 0.0, "roof_type_adder_1_cost_per_system": 0.0, "roof_type_adder_1_cost_per_panel": 0.0, "roof_type_adder_1_cost_per_watt": 0.0, "roof_type_adder_2_cost_per_system": 0.0, "roof_type_adder_2_cost_per_panel": 0.0, "roof_type_adder_2_cost_per_watt": 0.0, "roof_type_adder_3_cost_per_system": 0.0, "roof_type_adder_3_cost_per_panel": 0.0, "roof_type_adder_3_cost_per_watt": 0.0, "roof_type_adder_4_cost_per_system": 0.0, "roof_type_adder_4_cost_per_panel": 0.0, "roof_type_adder_4_cost_per_watt": 0.0, "roof_type_adder_5_cost_per_system": 0.0, "roof_type_adder_5_cost_per_panel": 0.0, "roof_type_adder_5_cost_per_watt": 0.0, "storeys_two_cost_per_system": 0.0, "storeys_two_cost_per_panel": 0.0, "storeys_two_cost_per_watt": 0.0, "storeys_three_plus_cost_per_system": 0.0, "storeys_three_plus_cost_per_panel": 0.0, "storeys_three_plus_cost_per_watt": 0.0, "steep_pitch_1_slope": 25, "steep_pitch_1_cost_per_system": 0.0, "steep_pitch_1_cost_per_panel": 0.0, "steep_pitch_1_cost_per_watt": 0.0, "steep_pitch_2_slope": 40, "steep_pitch_2_cost_per_system": 0.0, "steep_pitch_2_cost_per_panel": 0.0, "steep_pitch_2_cost_per_watt": 0.0, "split_array_layout_cost_per_system": 0.0, "split_array_layout_cost_per_panel": 0.0, "split_array_layout_cost_per_watt": 0.0, "tilt_rack_cost_per_system": 0.0, "tilt_rack_cost_per_panel": 0.0, "tilt_rack_cost_per_watt": 0.0, "id": 1 }, ... ]
EndpointQuery Parameters
GET /api/orgs/:org_id/costings/:id
POST /api/orgs/:org_id/costings/:id
DELETE /api/orgs/:org_id/costings/:id
GET /api/orgs/:org_id/costings/page, limit, priority (true, false)
Modules
Sample request and response:
curl "https://api.opensolar.com/api/orgs/:org_id/component_module_activations/" -H "Authorization: Bearer <token>"
[ { "org": "https://api.opensolar.com/api/orgs/1/", "module": "https://api.opensolar.com/api/component_modules/8520/", "module_id": 8520, "manufacturer_name": "LG Energy", "cost": 0.0, "price_adjustment": 0.0, "quantity": 0, "data": "{\"annual_degradation_override\": 0.45, \"max_power_voltage\": 33.7, \"code\": \"LG330N1C-A5\", \"performance_warranty\": 25, \"cells_in_series\": 60, \"voc\": 40.9, \"product_warranty\": 25, \"temp_coefficient_voc\": -0.27, \"temp_coefficient_vpmax\": -0.37, \"kw_stc\": 0.33, \"height\": 1.686, \"width\": 1.016, \"noct\": 45.9, \"imp\": 9.8, \"temp_coefficient_isc\": 0.03, \"isc\": 10.45, \"transmission\": null, \"bifaciality\": 0.0, \"technology\": \"Mono-c-Si\", \"skus\": \"\", \"manufacturer_name\": \"LG Energy\"}", "code": "LG330N1C-A5", "is_default": false, "id": 1, "url": "https://api.opensolar.com/api/orgs/1/component_module_activations/1/", "_sku": "LG330N1C-A5", "is_archived": false, "product_warranty": null, "performance_warranty": null, "logo": "https://api.opensolar.com/static/s3_local/logo" }, ... ]
EndpointQuery Parameters
GET /api/orgs/:org_id/component_module_activations/:id
POST /api/orgs/:org_id/component_module_activations/:id
DELETE /api/orgs/:org_id/component_module_activations/:id
GET /api/orgs/:org_id/component_module_activations/page, limit
Inverters
Sample request and response:
curl "https://api.opensolar.com/api/orgs/:org_id/component_inverter_activations/" -H "Authorization: Bearer <token>"
[ { "org": "https://api.opensolar.com/api/orgs/1/", "inverter": "https://api.opensolar.com/api/component_inverters/44/", "inverter_id": 44, "manufacturer_name": "Power-One", "cost": 0.0, "price_adjustment": 0.0, "quantity": 0, "data": "{\"voltage_minimum\": 100.0, \"microinverter\": \"N\", \"code\": \"PVI-3.0-OUTD-S-US [240V]\", \"power_consumption_at_night\": 0.1, \"product_warranty\": null, \"mppt_quantity\": 2, \"efficiency\": 96.0, \"additional_parts_warranty\": null, \"mppt_voltage_max\": null, \"voltage_nominal\": 240.0, \"voltage_max\": 480.0, \"max_power_rating\": 3.0, \"skus\": \"\", \"manufacturer_name\": \"Power-One\"}", "code": "PVI-3.0-OUTD-S-US [240V]", "is_default": false, "id": 3, "url": "https://api.opensolar.com/api/orgs/1/component_inverter_activations/3/", "_sku": "", "is_archived": false, "product_warranty": null, "additional_parts_warranty": null, "logo": "https://api.opensolar.com/static/s3_local/logo" }, ... ]
EndpointQuery Parameters
GET /api/orgs/:org_id/component_inverter_activations/:id
POST /api/orgs/:org_id/component_inverter_activations/:id
DELETE /api/orgs/:org_id/component_inverter_activations/:id
GET /api/orgs/:org_id/component_inverter_activations/page, limit
Batteries
Sample request and response:
curl "https://api.opensolar.com/api/orgs/:org_id/component_battery_activations/" -H "Authorization: Bearer <token>"
[ { "org": "https://api.opensolar.com/api/orgs/1/", "battery": "https://api.opensolar.com/api/component_batteries/1/", "battery_id": 1, "manufacturer_name": "TESLA", "cost": 0.0, "price_adjustment": 0.0, "quantity": 0, "data": "{\"code\": \"POWERWALL1 (240V)\", \"end_of_life_capacity\": 0.6, \"power_max_continuous\": 3.3, \"aging_factor\": 1.0, \"rating_optimal\": 0.0, \"depth_of_discharge_factor\": 1.0, \"voltage\": 240.0, \"kwh_optimal\": 6.4, \"warranty_kwh_1_cycle_per_day\": 15709.0, \"power_optimal\": 3.3, \"efficiency_factor\": 0.89, \"manufacturer\": \"TESLA\", \"manufacturer_name\": \"TESLA\"}", "code": "POWERWALL1 (240V)", "id": 3, "url": "https://api.opensolar.com/api/orgs/1/component_battery_activations/3/", "_sku": "", "is_archived": false, "product_warranty": null }, ... ]
EndpointQuery Parameters
GET /api/orgs/:org_id/component_battery_activations/:id
POST /api/orgs/:org_id/component_battery_activations/:id
DELETE /api/orgs/:org_id/component_battery_activations/:id
GET /api/orgs/:org_id/component_battery_activations/page, limit
Other Components
Sample request and response:
curl "https://api.opensolar.com/api/orgs/:org_id/component_other_activations/" -H "Authorization: Bearer <token>"
[ { "org": "https://api.opensolar.com/api/orgs/1/", "other": null, "other_id": null, "manufacturer_name": "", "cost": 100.0, "price_adjustment": 0.0, "quantity": 0, "data": "{\"product_warranty\": null, \"show_customer\": true, \"code\": \"component\", \"description\": \"\", \"manufacturer_name\": \"\"}", "code": "component", "id": 2, "url": "https://api.opensolar.com/api/orgs/1/component_other_activations/2/", "_sku": "", "is_archived": false, "product_warranty": null }, ... ]
EndpointQuery Parameters
GET /api/orgs/:org_id/component_other_activations/:id
POST /api/orgs/:org_id/component_other_activations/:id
DELETE /api/orgs/:org_id/component_other_activations/:id
GET /api/orgs/:org_id/component_other_activations/page, limit
Event Types
IDDefinition
0Email Invitation Sent
1Customer Read Invitation Email
2Customer Viewed Online Proposal
3Customer Accepted Online Proposal
4Customer Made a Payment
20Call (outbound)
21Call (outbound, no answer)
22Call (inbound)
23Email (outbound)
24Email (inbound)
25SMS
26Instant Message
27In Person Meeting
28Appointment
29Activity (Miscellaneous)
30Busy
40On-site Installation
41On-site Maintenance Visit
42On-site Sales Visit
44System Changed
45Project Assigned
49Finance Application Accessed
50Finance Application Updated
51Docusign Contract Viewed
52Docusign Contract Completed
53Docusign Authentication Failed
54Docusign Account Disconnected
55Contact Missing Phone Number
56Project Stage Changed
57Docusign SMS Authentication disabled
59Finance Decision Updated
60Financed Project Status Updated
61Customer Signed Loan Agreement
62Loan Agreement Complete
63Docusign Contract Signed
64Docusign Contract Re-Created
65Docusign Countersigner Not Properly Configured
66Docusign Contract Reset
67Customer Signed Docusign Envelope
68Docusign Envelope Complete
71Proposal Acceptance Documents Emailed
72Notice to Proceed Issued
73Disbursement Complete
74All Stipulation Documents Uploaded
75Stipulation Cleared
Roof Types
IDDefinition
6Composition / Asphalt Shingle
7Flat Concrete
8Flat Foam
9Membrane EPDM
10Membrane PVC
11Membrane TPO
12Metal Decramastic
13Metal Shingle
14Metal Standing Seam
15Metal Stone Coated
16Metal Tin
17Tar and Gravel / Bitumen
18Thatched
19Tile Clay
20Tile Concrete
21Tile Slate
22Wood/Shake Shingle
23Other
24Kliplock
Webhooks
Webhooks can be used to keep in sync with Opensolar. To create a webhook, provide Opensolar with an endpoint and the appropriate headers.
EndpointDescriptionParameters
GET /api/orgs/:org_id/webhooks/Get Org webhooks
POST /api/orgs/:org_id/webhooks/Create Org webhookstrigger_fields ,payload_fields, enabled (true/false), debug (true/false), endpoint
PATCH /api/orgs/:org_id/webhooks/:idUpdate Org webhookstrigger_fields ,payload_fields, enabled (true/false), debug (true/false), endpoint
Parameters
-
debug (boolean): required when creating a webhook. Currently 'debug' flag is not used.
-
enabled (boolean): required when creating a webhook.
-
endpoint (string): required when creating a webhook.
-
trigger_fields (json): Webhooks will be triggered only if the fields in this list are updated. To use default values, set the field to null.
-
payload_fields (json): The fields in this list will be included in the webhook's request. To use default values, set the field to null.
Default values
-
trigger_fields: ["contact.*", "event.*", "project.address", "project.zip", "project.state", "project.lat", "project.lon", "project.country", "project.locality", "project.county", "project.contacts", "project.identifier", "project.notes", "project.systems.price_including_tax", "project.systems.output_annual_kwh", "project.systems.modules", "project.systems.inverters", "project.systems.others", "project.systems.batteries", "project.systems.kw_stc", "project.stage", "project.system_sold", "project.payment_option_sold", "project.sold_date", "project.installation_date", "project.system_installed", "project.assigned_installer_role", "project.assigned_role", "project.assigned_site_inspector_role", "project.events_data", "project.usage", "project.utility_tariff_or_guess", "project.utility_tariff_proposed"]
-
payload_fields: ["contact.*", "event.*", "project.address", "project.zip", "project.state", "project.lat", "project.lon", "project.country_iso2", "project.locality", "project.county", "project.contacts_data.email", "project.contacts_data.family_name", "project.contacts_data.first_name", "project.contacts_data.id", "project.contacts_data.phone", "project.systems.price_including_tax", "project.systems.output_annual_kwh", "project.systems.url", "project.systems.modules", "project.systems.inverters", "project.systems.others", "project.systems.batteries", "project.systems.kw_stc", "project.id", "project.identifier", "project.notes", "project.site_notes", "project.actions", "project.stage", "project.system_sold", "project.payment_option_sold", "project.sold_date", "project.installation_date", "project.system_installed", "project.assigned_installer_role_data.user_email", "project.assigned_installer_role_data.id", "project.assigned_installer_role_data.first_name", "project.assigned_installer_role_data.family_name", "project.assigned_installer_role_data.phone", "project.assigned_role_data.user_email", "project.assigned_role_data.id", "project.assigned_role_data.first_name", "project.assigned_role_data.family_name", "project.assigned_role_data.phone", "project.assigned_site_inspector_role_data.user_email", "project.assigned_site_inspector_role_data.id", "project.assigned_site_inspector_role_data.first_name", "project.assigned_site_inspector_role_data.family_name", "project.assigned_site_inspector_role_data.phone", "project.events_data", "project.usage", "project.utility_tariff_or_guess.data", "project.utility_tariff_proposed_or_guess.data"]
Creating a webhook via POST:
curl "https://api.opensolar.com/api/orgs/:org_id/webhooks/" --request POST -H "Content-Type: application/json" -H "Authorization: Bearer <token>" -d '{"endpoint": "https://somesolar.com/api/", "headers": "{\"Authorization\": \"Token <your-token>\"}", "enabled": true, "debug": false, "trigger_fields":["contact.*", "event.*", "project.*"], "payload_fields":["contact.*", "event.*", "project.*"]}'
Updating existing webhook via PATCH:
curl "https://api.opensolar.com/api/orgs/:org_id/webhooks/123/" --request PATCH -H "Content-Type: application/json" -H "Authorization: Bearer <token>" -d '{"enabled": false, "trigger_fields":["contact.*", "event.*", "project.*"], "payload_fields":["contact.*", "event.*", "project.*"]}'
Note: Currently 'debug' flag is not used.
Structure
There are 3 models that invoke webhooks - Project, Contact and Event
The webhook payload has the following structure:
-
timestamp: A timestamp of when the event occured.
-
identifier: A unique identifier which can be set by the creator or automatically generated by OpenSolar. Typically used to store the primary key from an external integration, such as a SalesForce Object Id.
-
model: The model that triggered the webhook.
-
model_id: The primary key of the model instance.
-
event: CREATE, UPDATE, DELETE
-
event_id: The id of this particular webhook event.
-
fields: Contains the fields that are part of the model. Note this is only for CREATE/UPDATE.
Base Structure:
{ "timestamp": "1605831713", "model": "Project", "model_id": 1, "identifier": "6ab6a60d-1a4d-4374-88af-92f7c02e3223", "event": "UPDATE", "event_id": 1, "fields": { ... } }
Project
A project payload contains details about the state of a project.
Note: The URL for downloading private files ("file_contents") is time-delimited and will expire after 1 hour.
Sample data:
{ "timestamp": "1605832669", "model": "Project", "model_id": 12, "identifier": "6ab6a60d-1a4d-4374-88af-92f7c02e3223", "event": "UPDATE", "event_id": 1, "fields": { "access": 0, "actions": [ { "created_date": "2020-11-20T02:36:30.991737Z", "events": [ { "action_id": 8, "completion_date": "2020-11-20 02:36:31.019842+00:00", "created_date": "2020-11-20T02:36:31.020451Z", "duration": 0, "end": "2020-11-20T02:36:31.019842Z", "event_type_id": 29, "id": 17, "is_archived": false, "is_complete": true, "is_planned": false, "modified_date": "2020-11-20T02:36:31.676738Z", "notes": null, "project_id": 34, "project_name": "Vandelay Industries", "start": "2020-11-20 02:36:31.019831+00:00", "task_status": 0, "title": "Design Systems", "who": { "display": "george costanza", "email": "george@vanderlayindustries.com", "portrait_image_public_url": null } } ], "id": 8, "modified_date": "2020-11-20T02:36:30.991783Z", "order": 10, "org": "http://localhost:8000/api/orgs/42/", "stage": 1, "title": "Design Systems", "url": "http://localhost:8000/api/orgs/42/actions/8/" }, { "created_date": "2020-11-20T02:36:31.002570Z", "events": [], "id": 9, "modified_date": "2020-11-20T02:36:31.002614Z", "order": 40, "org": "http://localhost:8000/api/orgs/42/", "stage": 0, "title": "Contact Customer", "url": "http://localhost:8000/api/orgs/42/actions/9/" } ], "address": null, "assigned_installer_role": null, "assigned_installer_role_data": null, "assigned_role": null, "assigned_role_data": null, "assigned_site_inspector_role": null, "assigned_site_inspector_role_data": null, "available_customer_actions": [], "business_identifier": "", "business_name": "Vandelay Industries", "configuration": { "apply_tilt_racks_below_slope": 10, "created_date": null, "discount_rate": 6.75, "feed_in_tariff_inflation_annual": 0, "id": null, "inverter_modelling_automation": 0, "modified_date": null, "org_id": null, "performance_adjustment": 100, "performance_calculator": 0, "priority": 1, "proposed_usage_adjustment": 0, "setbacks_default": 0.3, "setbacks_dormer": 0.3, "setbacks_flat_gutter": 0.3, "setbacks_gutter": 0.3, "setbacks_hip": 0.3, "setbacks_objects": 0.3, "setbacks_rake": 0.3, "setbacks_ridge": 0.3, "setbacks_shared": 0.3, "setbacks_skylight": 0.3, "setbacks_valley": 0.3, "tilt_rack_default_tilt": 13, "utility_inflation_annual": 3, "years_to_simulate": 0 }, "configuration_override": null, "contacts": [], "contacts_data": [], "contract": null, "contract_date": null, "contract_terms": "", "costing": { "allocation_of_lead_gen_per_panel": 0, "allocation_of_lead_gen_per_system": 0, "allocation_of_lead_gen_per_watt": 0, "allocation_of_salary_per_panel": 0, "allocation_of_salary_per_system": 0, "allocation_of_salary_per_watt": 0, "bos_per_panel": 0, "bos_per_system": 0, "bos_per_watt": 0, "commission_per_panel": 0, "commission_per_system": 0, "commission_per_watt": 0, "commission_percentage_of_cogs_and_labor": 0, "created_date": null, "design_drawings_per_panel": 0, "design_drawings_per_system": 0, "design_drawings_per_watt": 0, "id": null, "job_site_shipping_and_warehousing_per_panel": 0, "job_site_shipping_and_warehousing_per_system": 0, "job_site_shipping_and_warehousing_per_watt": 0, "labor_per_panel": 0, "labor_per_system": 0, "labor_per_watt": 0, "modified_date": null, "org_id": null, "other_costs_per_panel": 0, "other_costs_per_system": 0, "other_costs_per_watt": 0, "permit_costs_per_panel": 0, "permit_costs_per_system": 0, "permit_costs_per_watt": 0, "presale_software_and_design_per_panel": 0, "presale_software_and_design_per_system": 0, "presale_software_and_design_per_watt": 0, "priority": 1, "project_management_per_panel": 0, "project_management_per_system": 0, "project_management_per_watt": 0, "racking_per_panel": 0, "racking_per_system": 0, "racking_per_watt": 0, "roof_type_adder_1_cost_per_panel": 0, "roof_type_adder_1_cost_per_system": 0, "roof_type_adder_1_cost_per_watt": 0, "roof_type_adder_1_roof_type_id": null, "roof_type_adder_2_cost_per_panel": 0, "roof_type_adder_2_cost_per_system": 0, "roof_type_adder_2_cost_per_watt": 0, "roof_type_adder_2_roof_type_id": null, "roof_type_adder_3_cost_per_panel": 0, "roof_type_adder_3_cost_per_system": 0, "roof_type_adder_3_cost_per_watt": 0, "roof_type_adder_3_roof_type_id": null, "roof_type_adder_4_cost_per_panel": 0, "roof_type_adder_4_cost_per_system": 0, "roof_type_adder_4_cost_per_watt": 0, "roof_type_adder_4_roof_type_id": null, "roof_type_adder_5_cost_per_panel": 0, "roof_type_adder_5_cost_per_system": 0, "roof_type_adder_5_cost_per_watt": 0, "roof_type_adder_5_roof_type_id": null, "split_array_layout_cost_per_panel": 0, "split_array_layout_cost_per_system": 0, "split_array_layout_cost_per_watt": 0, "steep_pitch_1_cost_per_panel": 0, "steep_pitch_1_cost_per_system": 0, "steep_pitch_1_cost_per_watt": 0, "steep_pitch_1_slope": 25, "steep_pitch_2_cost_per_panel": 0, "steep_pitch_2_cost_per_system": 0, "steep_pitch_2_cost_per_watt": 0, "steep_pitch_2_slope": 40, "storeys_three_plus_cost_per_panel": 0, "storeys_three_plus_cost_per_system": 0, "storeys_three_plus_cost_per_watt": 0, "storeys_two_cost_per_panel": 0, "storeys_two_cost_per_system": 0, "storeys_two_cost_per_watt": 0, "supplier_shipping_per_panel": 0, "supplier_shipping_per_system": 0, "supplier_shipping_per_watt": 0, "tilt_rack_cost_per_panel": 0, "tilt_rack_cost_per_system": 0, "tilt_rack_cost_per_watt": 0 }, "costing_override": null, "country": null, "county": null, "created_date": "2020-11-20T00:37:49.023050Z", "customer_proposal_data": { "has_contacts_active": false, "has_contacts_active_with_login": false, "has_customer_view": false, "has_customer_view_system": false, "ready": false }, "events": [], "events_data": [], "has_cellular_coverage": 0, "id": 12, "identifier": "xxxx", "installation_date": null, "is_residential": true, "lat": null, "lead_source": "", "locality": null, "lon": null, "meter_identifier": "", "modified_date": "2020-11-20T00:37:49.023103Z", "natron": null, "notes": "", "number_of_phases": null, "number_of_storeys": null, "number_of_wires": null, "org": "http://localhost:8000/api/orgs/16/", "org_id": 16, "parcel_identifier": "", "payment_option_sold": null, "power_factor": null, "priority": 2, "private_files": [], "private_files_data": [ { "url": "https://localhost:8000/api/orgs/<org_id>/private_files/<file_id>/", "org": "https://localhost:8000/api/orgs/<org_id>/", "project": "https://localhost:8000/api/orgs/<org_id>/projects/<project_id>/", "user": "https://localhost:8000/api/global_users/<user_id>/", "file_tags": [], "file_tags_data": [], "title": "sample.pdf", "system_uuid": null, "input_data": null, "input_data_hash": "f05e78eaa71afc73967c26b4936c4eb2", "file_hash": "2fb20d73e0de53b2d9890233f5df9d29", "status": "created", "status_message": "", "filesize": 219730, "file_contents": "https://localhost:8000/media/private/sample.pdf?Expires=1639011238", "show_customer": false, "created_date": "2020-01-02T12:00:00.000000Z", "modified_date": "2020-01-02T12:00:00.000000Z", "temporary": false, "id": "<file_id>" } ], "proposal_content": "", "proposal_message": "", "proposal_template": null, "roof_type": null, "serial_numbers_batteries": "", "serial_numbers_inverters": "", "serial_numbers_panels": "", "site_notes": "", "sold_date": null, "stage": 0, "stars": [], "state": null, "system_installed": null, "system_sold": null, "systems": [], "tags": [], "tags_data": [], "testimonials": [], "testimonials_data": [], "timezone_offset": 11, "title": "Vandelay Industries", "transactions_data": [], "url": "http://localhost:8000/api/orgs/16/projects/12/", "usage": null, "usage_annual_or_guess": 10766, "utility_tariff_current": null, "utility_tariff_current_custom": null, "utility_tariff_current_data": null, "utility_tariff_or_guess": null, "utility_tariff_proposed": null, "utility_tariff_proposed_custom": null, "utility_tariff_proposed_data": null, "utility_tariff_proposed_or_guess": null, "valid_until_date": null, "wind_region": null, "years_to_simulate": 20, "zip": null } }
Contact
A Contact payload contains details about contacts related to a project.
{ "timestamp": "1605832666", "model": "Contact", "model_id": 5, "identifier": "6ab6a60d-1a4d-4374-88af-92f7c02e3223", "event": "UPDATE", "event_id": 1, "fields": { "display": "george costanza", "email": "george@vanderlayindustries.com", "family_name": "costanza", "first_name": "george", "id": 5, "org": "/api/orgs/14/", "phone": "99991234", "projects": ["/api/orgs/14/projects/10/"], "url": "/api/orgs/14/contacts/5/", "user": "/auth/users/6/" } }
Event
An Event payload contains details about events related to a project.
{ "timestamp": "1605832669", "model": "Event", "model_id": 5, "identifier": "6ab6a60d-1a4d-4374-88af-92f7c02e3223", "event": "UPDATE", "event_id": 1, "fields": { "action": "/api/orgs/27/actions/1/", "archive_for": null, "completion_date": "2020-01-01T12:00:00.000000Z", "contact": "/api/orgs/15/contacts/6/", "created_date": "2020-01-02T12:00:00.000000Z", "duration": 0, "end": null, "event_type_id": 29, "id": 5, "is_archived": false, "is_complete": true, "location_override": "", "modified_date": "2020-01-01T12:00:00.000000Z", "notes": null, "org": "/api/orgs/15/", "project": "/api/orgs/15/projects/11/", "project_name": "Vandelay Industries", "repeat": 0, "start": null, "task_status": 0, "team_members": [], "title": "Design Systems", "url": "/api/orgs/15/events/5/", "user": "/auth/users/7/", "who": { "display": "george costanza", "email": "george@vanderlayindustries.com", "portrait_image_public_url": null } } }
Webhooks Queue
Queued webhooks can be inspected at http://api.opensolar.com/api/orgs/:org_id/webhook_process_logs/ as a standard API response or as CSV by adding the querystring format=csv.
Webhooks Logs
Webhook logs can be inspected at http://api.opensolar.com/api/orgs/:org_id/webhook_process_logs/ as a standard API response or as CSV by adding the querystring format=csv.
ParameterDefaultDescription
include_catsfalseIf set to true, the result will also include cats.
availabletrueIf set to false, the result will include kittens that have already been adopted.
Errors
The API uses the following error codes:
HTTP Status CodeNameMeaning
400Bad RequestYour request is invalid.
401UnauthorizedAPI key invalid or not supplied.
403ForbiddenNot permitted for this user.
404Not Found
405Method Not Allowed
429Too Many RequestsAPI access throttled. Please reduce number or frequency of requests.
500Internal Server ErrorUnexpected Error in our API. Please try again later or contact support.
503Service UnavailableWe're temporarily offline for maintenance. Please try again later.
504Gateway TimeoutMaximum duration exceeded.