### Submit Install Package API Source: https://docs.palmetto.com/finance/getting-started Use this endpoint to submit a complete install package. Ensure all required fields, such as system design and installer information, are provided. This is applicable for accounts in IL. ```javascript import fetch from 'node-fetch'; const response = await fetch(`${envBaseUrl}/api/v2/accounts/${accountId}/install-package/submit`, { method: 'POST', body: JSON.stringify({ systemDesign: { panelManufacturer: 'Canadian Solar', panelModel: 'CS3N-380MS', totalPanelCount: 20, inverters: [ { manufacturer: 'Enphase', model: 'IQ7-60-2-US', count: 1, }, ], mountingType: 'roof', mountingManufacturer: 'IronRidge', }, // this is only applicable to accounts in IL installer: { legalName: 'Installer Name', iccDocketNumber: '123456', qualifiedPersonOnsiteFirstName: 'Bob', qualifiedPersonOnsiteLastName: 'Builder', phoneNumber: '5555555555', email: 'bob-builder@installer.com', address: '123 Building St', city: 'Chicago', state: 'IL', }, monitoring: { monitoringSiteId: '123456', noInverterConsumptionCT: false, batteryMonitoringSiteId: '123456', // if a battery is installed noBatteryConsumptionCT: false, }, // only required if adders exist on the quote adders: [ { type: 'arbitrageBattery', quantity: 1, model: 'BAT-10K1PS0B-02', manufacturer: 'SolarEdge', }, ], designTool: 'Aurora', permitSubmittedDate: { palmetto: new Date(), }, permitApprovedDate: { palmetto: new Date(), }, installScheduledDate: { palmetto: new Date(), }, utility: { tariffId: 99999, }, }), headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, }); ``` -------------------------------- ### Verify Installer ID Exists Source: https://docs.palmetto.com/finance/direct-pay/integration-guide Verifies if a given installer ID exists in your system. This helps prevent errors during project creation and EPC setup. ```APIDOC ## Verify Installer ID Exists ### Description Verifies if a given installer ID exists in your system. This helps prevent errors during project creation and EPC setup. ### Method GET ### Endpoint `/installers/:installerId` ### Response #### Success Response (200) - **exists** (boolean) - Indicates whether the installer ID exists. ### Response Example ```json { "exists": true } ``` ``` -------------------------------- ### Submit Install Package Source: https://docs.palmetto.com/finance/getting-started This endpoint is used to submit the install package after all documents and information are ready. It requires a comprehensive set of data including system design, installer information, monitoring details, adders, design tool, and permit/install dates. ```APIDOC ## POST /api/v2/accounts/{accountId}/install-package/submit ### Description Submits the install package with all required documentation and information. ### Method POST ### Endpoint `/api/v2/accounts/{accountId}/install-package/submit` ### Request Body - **systemDesign** (object) - Required - Details about the system design, including panel manufacturer, model, total panel count, inverters, mounting type, and mounting manufacturer. - **installer** (object) - Optional - Applicable to accounts in IL. Contains installer legal name, ICC docket number, qualified person on-site details, phone number, email, and address. - **monitoring** (object) - Required - Monitoring details including monitoring site ID, consumption CT flags, and battery monitoring site ID if applicable. - **adders** (array) - Optional - Required if adders exist on the quote. Each adder object includes type, quantity, model, and manufacturer. - **designTool** (string) - Required - The design tool used. - **permitSubmittedDate** (object) - Required - The date the permit was submitted, with a `palmetto` key. - **permitApprovedDate** (object) - Required - The date the permit was approved, with a `palmetto` key. - **installScheduledDate** (object) - Required - The date the install was scheduled, with a `palmetto` key. - **utility** (object) - Required - Utility details including tariff ID. ### Request Example ```javascript { "systemDesign": { "panelManufacturer": "Canadian Solar", "panelModel": "CS3N-380MS", "totalPanelCount": 20, "inverters": [ { "manufacturer": "Enphase", "model": "IQ7-60-2-US", "count": 1 } ], "mountingType": "roof", "mountingManufacturer": "IronRidge" }, "installer": { "legalName": "Installer Name", "iccDocketNumber": "123456", "qualifiedPersonOnsiteFirstName": "Bob", "qualifiedPersonOnsiteLastName": "Builder", "phoneNumber": "5555555555", "email": "bob-builder@installer.com", "address": "123 Building St", "city": "Chicago", "state": "IL" }, "monitoring": { "monitoringSiteId": "123456", "noInverterConsumptionCT": false, "batteryMonitoringSiteId": "123456", "noBatteryConsumptionCT": false }, "adders": [ { "type": "arbitrageBattery", "quantity": 1, "model": "BAT-10K1PS0B-02", "manufacturer": "SolarEdge" } ], "designTool": "Aurora", "permitSubmittedDate": { "palmetto": new Date() }, "permitApprovedDate": { "palmetto": new Date() }, "installScheduledDate": { "palmetto": new Date() }, "utility": { "tariffId": 99999 } } ``` ### Response (Success and error response details not provided in source) ``` -------------------------------- ### End-to-End Document Upload Example Source: https://docs.palmetto.com/finance/documents Uploads a document by first initializing the upload to get a job ID and signed URLs, then performing a PUT request to the signed URL, and finally polling the job status until completion or failure. Requires `node-fetch` and `fs/promises`. ```javascript import fetch from 'node-fetch'; import { readFile } from 'node:fs/promises'; async function uploadDocument(envBaseUrl, accessToken, accountId, filePath, type) { const auth = { Authorization: `Bearer ${accessToken}` }; const bytes = await readFile(filePath); const filename = filePath.split('/').pop(); // 1. Initialize const initRes = await fetch(`${envBaseUrl}/api/v2/accounts/${accountId}/documents`, { method: 'POST', headers: { ...auth, 'Content-Type': 'application/json' }, body: JSON.stringify({ files: [{ filename, size: bytes.length }], type }), }); if (!initRes.ok) throw new Error(`Init failed: ${initRes.status}`); const { jobId, files } = await initRes.json(); // 2. PUT to the signed URL const [signed] = files; const putRes = await fetch(signed.uploadUrl, { method: 'PUT', body: bytes, headers: { 'Content-Type': signed.contentType }, }); if (!putRes.ok) throw new Error(`Upload failed: ${putRes.status}`); // 3. Poll for completion while (true) { const res = await fetch(`${envBaseUrl}/api/v2/accounts/${accountId}/documents/jobs/${jobId}`, { headers: auth, }); const event = await res.json(); if (event.type === 'complete' || event.type === 'imageVariantsReady') return event.documents; if (event.type === 'failed') throw new Error(event.error); await new Promise((r) => setTimeout(r, 2000)); } } ``` -------------------------------- ### Verify Installer ID API Response Source: https://docs.palmetto.com/finance/direct-pay/integration-guide This is a sample response body for the Verify Installer ID API, indicating whether the provided installer ID exists. ```json { exists: boolean; } ``` -------------------------------- ### Pricing API Response Example Source: https://docs.palmetto.com/finance/getting-started Example of the pricing data structure returned by the API, including product details, rates, and monthly payment schedules. ```json [ ... { productId: '646519316a223e9302c35744', type: 'ppa', name: 'LightReach Predictable PPA - 0.99%', description: 'Fixed cost PPA Lease', lseId: 2437, utilityName: 'Eversource Energy - East', state: 'MA', escalationRate: 0.0099, kwhRate: 0.16, ppwRate: 2.85, monthlyPayments: [ { year: 1, monthlyPayment: 68.08 }, ... { year: 25, monthlyPayment: 76.46 } ] } ... ] ``` -------------------------------- ### Account Creation Response Source: https://docs.palmetto.com/finance/getting-started This is an example of the JSON response received after successfully creating an account. It includes details about the account, applicant, utility, and system. ```json { id: '64a822dd2238174defd6b09c', organizationId: 'crown-pawn-shop', externalReference: '1994', friendlyName: 'Maynard', address: { address1: '20933 Roscoe Blvd', city: 'Canoga Park', state: 'MA', zip: '02779' }, applicants: [ { type: 'primary', firstName: 'Maynard', lastName: 'Crown', phoneNumber: '5555550001', email: 'maynard@crownpawn.com', address: { address1: '20933 Roscoe Blvd', city: 'Canoga Park', state: 'MA', zip: '02779' } } ], language: 'English', utility: { lseId: 2437, tariffId: 3428079, rate: 0.349085473480621, utilityName: 'Eversource Energy (Formerly NSTAR Electric Company)' }, systemDetails: { systemFirstYearProductionKwh: 5105.649683000001, systemSizeKw: 4, panelCount: 10 }, salesRepName: 'Quentin Tarantino', status: '1 - Created' } ``` -------------------------------- ### Save Install Package Source: https://docs.palmetto.com/finance/getting-started This endpoint allows users to save progress on an install package if not all information is ready for submission. Unlike the submit endpoint, all fields in the request body are optional. ```APIDOC ## POST /api/v2/accounts/{accountId}/install-package/submit ### Description Saves the current progress of the install package. All fields in the request body are optional. ### Method POST ### Endpoint `/api/v2/accounts/{accountId}/install-package/submit` ### Request Body - **systemDesign** (object) - Optional - Details about the system design. - **monitoring** (object) - Optional - Monitoring details. - **designTool** (string) - Optional - The design tool used. ### Request Example ```javascript { "systemDesign": { "panelManufacturer": "Canadian Solar", "panelModel": "CS3N-380MS", "totalPanelCount": 20 }, "monitoring": { "monitoringSiteId": "123456", "noInverterConsumptionCT": false, "batteryMonitoringSiteId": "123456", "noBatteryConsumptionCT": false }, "designTool": "Aurora" } ``` ### Response (Success and error response details not provided in source) ``` -------------------------------- ### Save Install Package API Source: https://docs.palmetto.com/finance/getting-started Use this endpoint to save progress on an install package when not all documents or information are ready for submission. Fields are optional in this request. ```javascript import fetch from 'node-fetch'; const response = await fetch(`${envBaseUrl}/api/v2/accounts/${accountId}/install-package/submit`, { method: 'POST', body: JSON.stringify({ systemDesign: { panelManufacturer: 'Canadian Solar', panelModel: 'CS3N-380MS', totalPanelCount: 20, }, monitoring: { monitoringSiteId: '123456', noInverterConsumptionCT: false, batteryMonitoringSiteId: '123456', // if a battery is installed noBatteryConsumptionCT: false, }, designTool: 'Aurora', }), headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, }); ``` -------------------------------- ### Document API Source: https://docs.palmetto.com/finance/getting-started Uploads install photos and documents required to complete the Install (M1) milestone after a project has been installed. Document size is currently limited to 32 MB. ```APIDOC ## POST /api/accounts/{accountId}/documents ### Description Uploads install photos and documents for a project. This is a prerequisite for completing the Install (M1) milestone. ### Method POST ### Endpoint /api/accounts/{accountId}/documents ### Parameters #### Path Parameters - **accountId** (string) - Required - The ID of the account for which documents are being uploaded. #### Request Body - **files** (multipart/form-data) - Required - The file(s) to upload. The `type` field in the form data specifies the document type. ### Request Example ```javascript const fileData = new FormData(); fileData.append('type', 'roof'); // Example: 'shadeReport', 'planSet', 'productionModel', etc. for (let i = 0; i < files.length; i++) { fileData.append(`files[${i}]`, files[i]); } // Then use fileData in the fetch request body ``` ### Response #### Success Response (200) - Returns an array of document objects, each containing details about the uploaded files. - **id** (string) - The unique identifier for the document. - **accountId** (string) - The ID of the associated account. - **status** (string) - The status of the document upload (e.g., 'pending'). - **archived** (boolean) - Indicates if the document is archived. - **type** (string) - The type of the document (e.g., 'roof', 'planSet'). - **files** (array) - Information about the uploaded files. - **originalName** (string) - The original name of the file. - **contentType** (string) - The MIME type of the file. - **md5Hash** (string) - The MD5 hash of the file. - **sizeKB** (number) - The size of the file in kilobytes. - **viewUrls** (array) - URLs to view the uploaded file. - **url** (string) - The URL to access the file. - **type** (string) - The type of URL (e.g., 'original'). - **meta** (object) - Metadata about the document. - **createdAt** (string) - The timestamp when the document was created. - **updatedAt** (string) - The timestamp when the document was last updated. #### Response Example ```json [ { "id": "64a8394a449225deda077efa", "accountId": "64a822dd2238174defd6b09c", "status": "pending", "archived": false, "type": "roof", "files": [ { "originalName": "roof.pdf", "contentType": "application/pdf", "md5Hash": "GxO72ZJpEVrGWE1AYKF96g==", "sizeKB": 4319.5, "viewUrls": [ { "url": "/api/accounts/${accountId}/documents/${id}/files/${filePath}", "type": "original" } ] } ], "meta": { "createdAt": "2024-01-05T17:11:04.630Z", "updatedAt": "2024-01-05T17:11:04.630Z" } } ] ``` **Note:** Each document type requires a separate `POST` request. The available document types are: `shadeReport`, `planSet`, `productionModel`, `permit`, `incentives`, `utilityBill`, `projectSite`, `roof`, `electrical`, `storage`, `systemCommissioning`. ``` -------------------------------- ### Upload Install Photos and Documents API Request Source: https://docs.palmetto.com/finance/getting-started Submit install photos and documents required for the M1 milestone. Note that document size is limited to 32MB. Each document type requires a separate POST request. ```javascript import fetch from 'node-fetch'; const response = await fetch(`${envBaseUrl}/api/accounts/${accountId}/documents`, { method: 'POST', headers: { Authorization: `Bearer ${accessToken}`, }, body: fileData, // see example of how to construct fileData below }); const document = await response.json(); ``` -------------------------------- ### Project Response Example Source: https://docs.palmetto.com/energy/getting-started This JSON object represents a typical response when creating or retrieving a project. It includes details about the project's status, contacts, address, design specifications, estimated costs, payment methods, and associated documents. ```json { "status": "DRAFT", "id": "64cd33c08697c006a821fccc", "name": "My Project", "type": "SOLAR_RESIDENTIAL", "contacts": [ { "firstName": "Maynard", "middleName": "Percy", "lastName": "Crown", "phones": [ { "tags": ["MOBILE"], "number": "+18048675309" } ], "email": "maynard@crownpawnshop.com", "locale": "en-US", "id": "64cd33c08697c006a821fccd", "tags": ["OWNER"] } ], "address": { "streetAddress": "20933 Roscoe Blvd", "locality": "Canoga Park", "region": "MA", "postalCode": "02779", "country": "US", "coordinates": { "lat": -71.0952744, "lon": 41.8718583 } }, "design": { "id": "64cd33c08697c006a821fcce", "arrays": [ { "sizeW": 400, "moduleQuantity": 1, "tilt": 14, "azimuth": 221, "tsrf": 0, "systemLosses": 0, "firstYearProductionKwh": 0 }, { "sizeW": 400, "moduleQuantity": 3, "tilt": 14, "azimuth": 221, "tsrf": 0, "systemLosses": 0, "firstYearProductionKwh": 0 }, { "sizeW": 400, "moduleQuantity": 2, "tilt": 14, "azimuth": 131, "tsrf": 0, "systemLosses": 0, "firstYearProductionKwh": 0 }, { "sizeW": 400, "moduleQuantity": 3, "tilt": 14, "azimuth": 131, "tsrf": 0, "systemLosses": 0, "firstYearProductionKwh": 0 }, { "sizeW": 400, "moduleQuantity": 4, "tilt": 14, "azimuth": 41, "tsrf": 0, "systemLosses": 0, "firstYearProductionKwh": 0 } ], "components": [ { "name": "Enphase IQ 8 Plus Microinverter", "sku": "iq8-plus", "quantity": 1 }, { "name": "Canadian Solar CS3N-395MS 395w", "sku": "canadianSolar-cs3n395ms", "quantity": 13 } ], "firstYearProductionKwh": 7409, "provider": "AURORA", "providerReferenceId": "aurora-id", "tsrf": 0.85 }, "estimate": { "dealerFee": 0.25, "totalAdjustments": [ { "name": "Dealer fee", "isCalculated": true, "rate": 0.25, "amount": 10450.16, "type": "DEALER_FEE" } ], "totalNetPrice": 19326, "totalGrossPrice": 29776.16, "lineItems": [ { "sku": "pv-residential", "name": "Solar System", "quantity": 5200, "units": "WATT", "netPrice": 18720, "grossPrice": 29018.75, "unitNetPrice": 3.6, "unitGrossPrice": 5.5805, "adjustments": [ { "name": "Dealer fee", "isCalculated": true, "rate": 0.25, "amount": 10298.75, "type": "DEALER_FEE" } ] }, { "name": "Palmetto Protect Essentials", "sku": "palmetto-protect-essentials", "quantity": 1, "units": "OTHER", "netPrice": 150, "grossPrice": 187.48, "unitNetPrice": 150, "unitGrossPrice": 187.48, "adjustments": [ { "name": "Dealer fee", "isCalculated": true, "rate": 0.25, "amount": 37.47999999999999, "type": "DEALER_FEE" } ] } ] }, "paymentMethods": [ { "type": "PPA", "amount": 18720, "provider": "PALMETTO", "providerReferenceId": "64a822dd2238174defd6b09c" } ], "documents": [], "owner": { "teamId": "5e9dd0997f5ed3003b24fc77", "userId": 3753 } } ``` -------------------------------- ### Get Project Details API Response Source: https://docs.palmetto.com/finance/direct-pay/integration-guide This is a sample response body for the Get Project Details API. It includes various fields related to project and customer information. ```json { customerName: string, address1: string, address2: string, city: string, state: string, zip: string, identifier: string, // 'the unique LightReach account/project installerIdentifier: string, // 'the installers unique id in your system' ntpDate: ISO date string, // 'date we may have sent the project achieved NTP' lrStatus: string, // our status we may have sent you (if at all) systemSize: number, projectCost: number, distributorStatus: string,// pending, finalized, shipped, cancelled invoiceStatus: string, // pending, sent, paid, voided } ``` -------------------------------- ### Webhook Registration Response Source: https://docs.palmetto.com/energy/subscriptions This is an example of the response received after successfully registering a webhook. It includes the webhook's status, ID, and configured details. ```json { "status": "ACTIVE", "triggers": [], "id": "64alz9c4372c6ddcf2052222", "method": "POST", "url": "https://3823-50-217-78-126.ngrok.io/webhook-test" } ``` -------------------------------- ### Project Submission Response Source: https://docs.palmetto.com/energy/getting-started This is an example of a successful response when a project is submitted. It indicates the current status and submission timestamp. ```json { "status": "PENDING", "submittedAt": "2023-08-05T22:11:39.181Z" } ``` -------------------------------- ### Contract Signing Link Result Source: https://docs.palmetto.com/finance/getting-started Example of the response containing a contract signing link. This URL is for direct access to the contract for signing. ```json { url: 'https://docusign.com/link-to-sign-document'; } ``` -------------------------------- ### Get a list of components Source: https://docs.palmetto.com/energy/getting-started Retrieve a list of all available products, including their SKUs and Aurora IDs. This list is useful for identifying components to include in project submissions. It is recommended to cache this list as it does not change frequently. ```APIDOC ## GET /api/products ### Description Retrieves a list of all products available in the system, including their SKUs, names, and attributes such as `auroraId`. ### Method GET ### Endpoint /api/products ### Parameters #### Query Parameters None #### Request Body None ### Request Example ```javascript import fetch from 'node-fetch'; const envBaseUrl = 'YOUR_BASE_URL'; // Replace with your actual base URL const accessToken = 'YOUR_ACCESS_TOKEN'; // Replace with your actual access token const response = await fetch(`${envBaseUrl}/api/products`, { method: 'GET', headers: { Accept: 'application/json', Authorization: `Bearer ${accessToken}`, }, }); const products = (await response.json()).data; const mapping = products ?.map((p) => ({ sku: p.sku, name: p.name, auroraId: p.attributes?.find((a) => a.key === 'auroraId')?.value, })) .filter((p) => p.auroraId); console.log(mapping); ``` ### Response #### Success Response (200) Returns a JSON object containing a list of products. Each product object includes details like `id`, `sku`, `name`, `manufacturer`, `description`, `type`, `classificationId`, `availability`, `restrictions`, and `attributes`. #### Response Example ```json { "data": [ { "id": "63f2898ad2d53c9e6465a656", "sku": "canadianSolar-cs3n395ms", "name": "Canadian Solar CS3N-395MS 395w", "manufacturer": "Canadian Solar", "shortDescription": "395W All Black Module", "longDescription": "Canadian Solar CS3N-395MS, 395W BOB 66C 35MM", "type": "simple", "classificationId": "63f27056245f32be8c8f64a3", "availability": { "available": true }, "restrictions": { "financiers": [], "states": [], "systemSize": [] }, "attributes": [ { "key": "auroraId", "value": "c0095004-109c-4feb-8813-0fbaab1107bd" } ] } ] } ``` ### Special Products - **Solar System**: SKU `pv-residential`. This is a roll-up of the entire solar system. - **Palmetto Protect Essentials**: SKU `palmetto-protect-essentials`. This is a standard charge included with all Palmetto installed systems. If not submitted as a line item, it will be assumed that the charge should be removed. ``` -------------------------------- ### Quote API Response Structure Source: https://docs.palmetto.com/finance/getting-started This is an example of the JSON response received after successfully creating a quote. It includes details about the quote ID, product, system information, pricing, and status. ```json { id: '64a8394a449225deda077ef9', accountId: '64a822dd2238174defd6b09c', productId: '646519316a223e9302c35744', externalReference: '', systemFirstYearProductionKwh: 5105.649683000001, systemSizeKw: 4, kwhPrice: 0.16, totalSystemCost: 11400, pricePerWatt: 2.85, preConAdderCost: 0, systemPricingDetails: [ { year: 1, monthlyPayment: 68.08, estimatedAnnualProduction: 5106, guaranteedAnnualProduction: 4595, yearlyCost: 816.96, kwhRate: 0.16 }, ... { year: 25, monthlyPayment: 76.43, estimatedAnnualProduction: 4527, guaranteedAnnualProduction: 4074, yearlyCost: 917.16, kwhRate: 0.2026 } ], totalAmountPaid: 21650.28, status: 'active' } ``` -------------------------------- ### Get Account Pricing Source: https://docs.palmetto.com/finance/getting-started Fetch pricing for a specific account. This is the preferred method to ensure relevant product and pricing information is returned. ```javascript import fetch from 'node-fetch'; const response = await fetch(`${envBaseUrl}/api/v2/accounts/${accountId}/pricing`, { method: 'GET', headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, }); const pricing = await response.json(); ``` -------------------------------- ### Construct FormData for File Upload Source: https://docs.palmetto.com/finance/getting-started Example of how to construct the FormData object for uploading files, specifying the document type and appending files to be uploaded. ```javascript const fileData = new FormData(); fileData.append('type', 'roof'); for (let i = 0; i < files.length; i++) { fileData.append(`files[${i}]`, files[i]); } ``` -------------------------------- ### Get Account Pricing with Adders Source: https://docs.palmetto.com/finance/getting-started Include specific adders, such as 'electricalUpgradeIncluded', in your pricing request to access additional pricing bands that cover adder costs. ```javascript import fetch from 'node-fetch'; const response = await fetch(`${envBaseUrl}/api/v2/accounts/${accountId}/pricing?electricalUpgradeIncluded=true`, { method: 'GET', headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, }); const pricing = await response.json(); ``` -------------------------------- ### Project Document Upload Response Structure Source: https://docs.palmetto.com/energy/getting-started This is an example of the JSON response you will receive after successfully uploading documents. It includes the document ID, type, and details about the uploaded files. ```json { id: '64d9aa7a3eb77429f9e4e902', type: 'HIC', archived: false, files: [ { contentType: 'image/jpeg', originalName: 'file.jpg', md5Hash: 'nZwbJzLOngS+2QHrRXs7/w==', sizeKB: 6067.8, viewUrls: [{ type: 'ORIGINAL', URL: '...' }] } ] } ``` -------------------------------- ### Get Estimated Pricing (No Adders) Source: https://docs.palmetto.com/finance/getting-started Use this endpoint to retrieve estimated pricing without specifying any adders. Provide all necessary information in the request body. This is useful for driving UI before an account is created. ```javascript import fetch from 'node-fetch'; const response = await fetch(`${envBaseUrl}/api/v2/accounts/estimatedPricing`, { method: 'POST', body: JSON.stringify({ lseId: 2437, state: MA, systemSizeKw: 9.3, systemFirstYearProductionKwh: 10755, }), headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, }); const pricing = await response.json(); ``` -------------------------------- ### Example Event Payload Source: https://docs.palmetto.com/energy/subscriptions This is an example of a payload received by your webhook endpoint when a registered event occurs. It contains the event type and relevant data. ```json { "event": "PROJECT_CREATED", "data": { "id": "64ccfad1372c6ddcf205b5bc" } } ``` -------------------------------- ### Create a Project Source: https://docs.palmetto.com/energy/getting-started This endpoint allows you to create a new project. A project is a container for all information related to a system submission, such as design, estimates, and documents. You can create a project with minimal required information and update it later, or provide all details upfront. ```APIDOC ## Create a Project ### Description Initiates the creation of a new project, which acts as a central repository for all system-related data including design specifications, cost estimates, and supporting documents. This endpoint offers flexibility by allowing project creation with essential details, which can be augmented as the customer's progress through your system, or by providing comprehensive information from the outset. ### Method POST ### Endpoint /api/projects ### Request Body - **name** (string) - Required - The name of the project. - **type** (string) - Required - The type of project (e.g., 'SOLAR_RESIDENTIAL'). - **externalId** (string) - Optional - An external identifier for the project. - **address** (object) - Required - The physical address associated with the project. - **streetAddress** (string) - Required - **locality** (string) - Required - **region** (string) - Required - **postalCode** (string) - Required - **country** (string) - Required - **coordinates** (object) - Optional - **lat** (number) - Required - **lon** (number) - Required - **contacts** (array) - Optional - A list of contacts associated with the project. - **tags** (array) - Optional - Tags for the contact (e.g., ['OWNER']). - **firstName** (string) - Required - **middleName** (string) - Optional - **lastName** (string) - Required - **phones** (array) - Optional - **tags** (array) - Optional - **number** (string) - Required - **email** (string) - Required - **locale** (string) - Optional - **design** (object) - Optional - Design specifications for the project. - **provider** (string) - Required - The design provider (e.g., 'AURORA'). - **providerReferenceId** (string) - Required - The reference ID from the provider. - **tsrf** (number) - Optional - Total System Resource Factor. - **firstYearProductionKwh** (number) - Optional - Estimated first-year electricity production in kWh. - **components** (array) - Optional - List of system components. - **name** (string) - Required - **sku** (string) - Required - **quantity** (number) - Required - **arrays** (array) - Optional - Details of solar arrays. - **sizeW** (number) - Required - Size of the array in Watts. - **moduleQuantity** (number) - Required - Number of modules in the array. - **tilt** (number) - Optional - Tilt angle of the array. - **azimuth** (number) - Optional - Azimuth angle of the array. - **tsrf** (number) - Optional - **systemLosses** (number) - Optional - **firstYearProductionKwh** (number) - Optional - **estimate** (object) - Optional - Cost estimate for the project. - **dealerFee** (number) - Optional - Dealer fee percentage. - **lineItems** (array) - Required - List of cost line items. - **name** (string) - Required - **sku** (string) - Required - **quantity** (number) - Required - **units** (string) - Required - **unitNetPrice** (number) - Required - **netPrice** (number) - Required - **paymentMethods** (array) - Optional - Details of payment methods. - **type** (string) - Required - Type of payment (e.g., 'PPA'). - **amount** (number) - Required - The payment amount. - **provider** (string) - Required - The payment provider. - **providerReferenceId** (string) - Required - The reference ID from the payment provider. ### Request Example ```javascript { "name": "My Project", "type": "SOLAR_RESIDENTIAL", "externalId": "external-id-123", "address": { "streetAddress": "20933 Roscoe Blvd", "locality": "Canoga Park", "region": "MA", "postalCode": "02779", "country": "US", "coordinates": { "lat": -71.0952744, "lon": 41.8718583 } }, "contacts": [ { "tags": ["OWNER"], "firstName": "Maynard", "middleName": "Percy", "lastName": "Crown", "phones": [ { "tags": ["MOBILE"], "number": "+18048675309" } ], "email": "maynard@crownpawnshop.com", "locale": "en-US" } ], "design": { "provider": "AURORA", "providerReferenceId": "aurora-id", "tsrf": 0.85, "firstYearProductionKwh": 7409, "components": [ { "name": "Enphase IQ 8 Plus Microinverter", "sku": "iq8-plus", "quantity": 1 }, { "name": "Canadian Solar CS3N-395MS 395w", "sku": "canadianSolar-cs3n395ms", "quantity": 13 } ], "arrays": [ { "sizeW": 400, "moduleQuantity": 1, "tilt": 14, "azimuth": 221, "tsrf": 0, "systemLosses": 0, "firstYearProductionKwh": 0 }, { "sizeW": 400, "moduleQuantity": 3, "tilt": 14, "azimuth": 221, "tsrf": 0, "systemLosses": 0, "firstYearProductionKwh": 0 }, { "sizeW": 400, "moduleQuantity": 2, "tilt": 14, "azimuth": 131, "tsrf": 0, "systemLosses": 0, "firstYearProductionKwh": 0 }, { "sizeW": 400, "moduleQuantity": 3, "tilt": 14, "azimuth": 131, "tsrf": 0, "systemLosses": 0, "firstYearProductionKwh": 0 }, { "sizeW": 400, "moduleQuantity": 4, "tilt": 14, "azimuth": 41, "tsrf": 0, "systemLosses": 0, "firstYearProductionKwh": 0 } ] }, "estimate": { "dealerFee": 0.25, "lineItems": [ { "name": "Solar System", "sku": "pv-residential", "quantity": 5200, "units": "WATT", "unitNetPrice": 3.6, "netPrice": 18720 }, { "name": "Palmetto Protect Essentials", "sku": "palmetto-protect-essentials", "quantity": 1, "units": "OTHER", "unitNetPrice": 150, "netPrice": 150 } ] }, "paymentMethods": [ { "type": "PPA", "amount": 18720, "provider": "PALMETTO", "providerReferenceId": "64a822dd2238174defd6b09c" } ] } ``` ### Response #### Success Response (200) - **project** (object) - The created project object. - **id** (string) - The unique identifier for the project. - **name** (string) - The name of the project. - **type** (string) - The type of the project. - **externalId** (string) - The external identifier for the project. - **createdAt** (string) - The timestamp when the project was created. - **updatedAt** (string) - The timestamp when the project was last updated. #### Response Example ```json { "project": { "id": "64a822dd2238174defd6b09c", "name": "My Project", "type": "SOLAR_RESIDENTIAL", "externalId": "external-id-123", "createdAt": "2023-08-29T10:00:00Z", "updatedAt": "2023-08-29T10:00:00Z" } } ``` ``` -------------------------------- ### Project Creation Request Body Source: https://docs.palmetto.com/finance/direct-pay/integration-guide Send this JSON payload to create a new project. Ensure all required fields are populated accurately. The installerIdentifier must be recognized by your system. ```json { customerName: string, // 'the name of the homeowner', address1: string, // 'the address line 1 of the install location', address2: string, // 'the address line 2 of the install location', city: string, // the city of the install location, state: string, // 'the state of the install location' zip: string, // 'the zip code of the install location', identifier: string, // 'the unique LightReach account/project identifier, installerIdentifier: string, // 'the installers unique identifier in your system', projectCost: number, // 'the total project cost', systemSize: number, // 'the system size in KW', ntpDate: ISO date string, // 'the date the project achieved NTP (e.g. '2025-01-01T22:23:28.404z') lrStatus: string, // `e.g(active)` } ``` -------------------------------- ### Create System Design Source: https://docs.palmetto.com/finance/getting-started Creates a new system design for the account. This design becomes the current active design. Basic information like production and size are optional, but recommended for a complete quote. ```APIDOC ## POST /api/accounts/{accountId}/system-design ### Description Creates a new system design for the account. This design becomes the current active design. Basic information like production and size are optional, but recommended for a complete quote. ### Method POST ### Endpoint /api/accounts/{accountId}/system-design ### Request Body - **systemFirstYearProductionKwh** (number) - Optional - The estimated system production in kWh for the first year. - **systemSizeKw** (number) - Optional - The size of the system in kilowatts. - **inverters** (array) - Required - An array of inverter objects. - **manufacturer** (string) - Required - The manufacturer of the inverter. - **model** (string) - Required - The model of the inverter. - **count** (number) - Required - The number of inverters. - **panelManufacturer** (string) - Required - The manufacturer of the solar panels. - **panelModel** (string) - Required - The model of the solar panels. - **totalPanelCount** (number) - Required - The total number of panels. - **mountingType** (string) - Required - The type of mounting used (e.g., 'roof'). - **mountingManufacturer** (string) - Required - The manufacturer of the mounting hardware. ### Request Example { "systemFirstYearProductionKwh": 12000, "systemSizeKw": 12, "inverters": [ { "manufacturer": "Enphase", "model": "IQ7-60-2-US", "count": 1 } ], "panelManufacturer": "Canadian Solar", "panelModel": "CS3N-380MS", "totalPanelCount": 20, "mountingType": "roof", "mountingManufacturer": "IronRidge" } ### Response #### Success Response (200) - **isCurrent** (boolean) - Indicates if this is the current system design. ```