Solar Panel Rooftop Lead Scorer: No-Key PVGIS Google Solar API avatar

Solar Panel Rooftop Lead Scorer: No-Key PVGIS Google Solar API

Pricing

from $14.00 / 1,000 property analyzeds

Go to Apify Store
Solar Panel Rooftop Lead Scorer: No-Key PVGIS Google Solar API

Solar Panel Rooftop Lead Scorer: No-Key PVGIS Google Solar API

Keyless solar pre-screening with EU JRC PVGIS 5.3: modeled yield, energy ranges, confidence and explainable lead scores for solar installers and solar panel sales. No Google key needed. US addresses and PVGIS-covered coordinates supported. Optional Google Solar API BYOK mode adds rooftop geometry.

Pricing

from $14.00 / 1,000 property analyzeds

Rating

0.0

(0)

Developer

Kamer Ozkan

Kamer Ozkan

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 hours ago

Last modified

Categories

Share

Solar Rooftop Lead Scorer - No-Key PVGIS + Google Solar API

Turn property locations into explainable solar-sales pre-screens without asking every customer to configure Google Cloud.

The default OPEN_DATA mode needs no API key, account, card, or separate provider bill. It uses European Commission JRC PVGIS 5.3 for solar resource and production modelling. Complete U.S. addresses can be resolved through the official U.S. Census Geocoder; coordinates work in most PVGIS-covered land areas, subject to provider coverage.

For projects that need Google rooftop geometry, imagery, panel configurations, and building-level matching, the original GOOGLE BYOK Google Solar API mode remains available.

This Actor is a screening tool. It does not replace an on-site survey, engineering review, structural assessment, electrical design, permit check, or binding quote.

Keyless quick start · Two analysis modes · Input · Pricing · Terms · Privacy

Keyless quick start

Use a coordinate in a PVGIS-covered land area and, when available, a measured or customer-supplied roof area:

{
"providerMode": "OPEN_DATA",
"acceptTerms": true,
"coordinates": [
{
"id": "lead-42",
"latitude": 52.52,
"longitude": 13.405,
"roofAreaM2": 100
}
]
}

No googleApiKey is required.

If roofAreaM2 and systemCapacityKw are both absent, the Actor runs a standardized 5 kW comparison scenario by default. The result is marked standardized_system_screening, receives low confidence, and never claims that 5 kW was measured on the roof.

Qualification requires property-specific capacity evidence: an item-level roofAreaM2 or systemCapacityKw. A standardized system or shared defaultRoofAreaM2 scenario can compare solar resource and production, but is always not_qualified.

Two analysis modes

ModeKey neededCoverageWhat it measuresMain limitation
OPEN_DATANoMost PVGIS-covered land areas via coordinates; U.S. addressesRegional solar resource, modeled kWh/kWp, production ranges, assumption-based capacity and economicsSubject to PVGIS coverage; no roof planes, exact shade, obstructions, structural data, or panel layout
GOOGLECustomer Google keyGoogle Solar coverageBuilding match, rooftop geometry, imagery quality/date, panel configurations, Google financial data when availableBYOK setup, Google billing/licensing, coverage, attribution, and retention rules
DEMONoIllustrative onlyOutput shape and workflowNot a real property analysis

When providerMode is omitted:

  • a googleApiKey supplied in Actor input selects GOOGLE;
  • otherwise the Actor selects OPEN_DATA.

This preserves existing input-key integrations while making new no-key runs work by default. An Actor GOOGLE_SOLAR_API_KEY environment value alone does not auto-switch the mode; set providerMode: "GOOGLE" to use that environment key.

Open-data sources and provenance

Solar resource

The Actor calls the pinned server-side endpoint:

https://re.jrc.ec.europa.eu/api/v5_3/PVcalc

PVGIS is maintained by the European Commission Joint Research Centre. PVGIS states that its information is free with no restrictions on use, requires no registration, and supports automated API access. The API publishes a limit of 30 calls per second per IP and may return 429 or 529 during overload. This Actor applies bounded retries and exponential backoff.

Every open-data result exposes the radiation database, meteorological database, model years, terrain-horizon source, model orientation, assumptions, uncertainty range, and attribution.

U.S. address coordinates

OPEN_DATA address input uses the official U.S. Census Geocoder with the Public_AR_Current benchmark. Census coordinates are calculated or interpolated from TIGER address ranges; they are not claimed as rooftop centroids. The result therefore uses TIGER_ADDRESS_RANGE_INTERPOLATION and lower spatial precision.

Keyless address matching fails closed:

  • the input must contain house number, street, city, two-letter state code, and five-digit ZIP;
  • house number, state, and ZIP must agree with the returned Census match;
  • multiple Census candidates are rejected instead of silently selecting one.

Census does not return a native confidence score for this endpoint. The Actor exposes the matched components, candidate count, and a conservative geocodingConfidenceLevel derived by the Actor. That label describes address-match evidence, not rooftop-coordinate precision.

For non-U.S. keyless properties, provide latitude and longitude. The Actor deliberately does not rely on public Nominatim or another unsupported bulk-geocoding endpoint.

What open-data mode returns

  • providerMode, assessmentScope, and capacitySource
  • Transparent 0-100 pre-screen leadScore
  • geocodingConfidenceLevel and structured address-match evidence
  • openDataConfidence and evidenceCompletenessScore
  • Explicit scenario panel-equivalent count and system capacity
  • A separate assumption-based packing estimate when roof-area evidence is available
  • Specific yield in kWh/kWp
  • Annual plane-of-array irradiation in kWh/m²
  • Base, low, and high annual AC-energy estimates
  • Optional gross modeled annual energy value, assumed installed cost, illustrative payback, and carbon estimates from user assumptions
  • Monthly production estimates
  • Evidence completeness kept separate from the lead score
  • Exact assumptions and limitations used
  • requiresSiteSurvey: true
  • Source names, URLs, database versions, model years, and attribution

A real qualified lead, unedited

This record comes from a live run on 2026-07-28 (open-data mode, keyless). Every confidence signal is declared inside the record itself: geocoding precision and match quality, openDataConfidence, evidenceCompletenessScore kept separate from the leadScore, and assessmentScope naming exactly what was assessed. Null-only and very long sub-objects are shortened here; the full record ships as-is.

{
"sourceId": "address-item-1",
"source": "addressItems",
"providerMode": "OPEN_DATA",
"inputAddress": "350 5th Ave, New York, NY 10118",
"formattedAddress": "350 5TH AVE, NEW YORK, NY, 10118",
"addressComponents": {
"houseNumber": null,
"street": "5TH AVE",
"unit": null,
"city": "NEW YORK",
"county": null,
"state": "NY",
"stateCode": "NY",
"postalCode": "10118",
"country": "United States",
"countryCode": "US"
},
"latitude": 40.747848600317,
"longitude": -73.985077152891,
"geocodingPlaceId": "US_CENSUS_TIGER:59653473",
"geocodingLocationType": "TIGER_ADDRESS_RANGE_INTERPOLATION",
"geocodingConfidenceLevel": "medium",
"regionCode": "US",
"administrativeAreaCode": "NY",
"postalCode": "10118",
"geocodingMatchQuality": {
"precision": "TIGER_ADDRESS_RANGE_INTERPOLATION",
"leadingHouseNumberMatched": true,
"fiveDigitZipMatched": true,
"stateCodeMatched": true,
"candidateCount": 1,
"confidenceLevel": "medium",
"confidenceSource": "ACTOR_DERIVED_COMPONENT_MATCH"
},
"tigerAddressRangeStart": "350",
"leadScore": 93,
"qualified": true,
"scenarioPanels": 247,
"scenarioSystemCapacityKw": 108.68,
"estimatedPackingPanels": 247,
"estimatedPackingSystemCapacityKw": 108.68,
"estimatedAnnualEnergyKwhAc": 159297,
"estimatedAnnualEnergyKwhAcLow": 127437,
"estimatedAnnualEnergyKwhAcHigh": 191156,
"wholeRoofAreaM2": 900,
"usableArrayAreaM2": 495,
"annualIrradiationKwhM2": 1794,
"annualPlaneOfArrayIrradiationKwhM2": 1794,
"specificYieldKwhPerKwp": 1466,
"assessmentScope": "roof_area_screening",
"openDataConfidence": "medium",
"evidenceCompletenessScore": 55,
"pvgisPanelTiltDegrees": 38,
"pvgisPanelAzimuthDegrees": -5,
"pvgisAnnualVariabilityKwhPerKwp": 38.6,
"pvgisTotalLossPercent": 18.3,
"pvgisMountingType": "free-standing",
"pvgisPvTechnology": "crystSi2025",
"radiationDatabase": "PVGIS-ERA5",
"meteorologicalDatabase": "ERA5",
"dataYearStart": 2005,
"dataYearEnd": 2023,
"horizonSource": "DEM-calculated",
"monthlyEnergyKwh": [
{
"month": 1,
"energyKwh": 11318
},
{
"month": 2,
"energyKwh": 12322
},
{
"month": 3,
"energyKwh": 15200
},
{
"month": 4,
"energyKwh": 15077
},
{
"month": 5,
"energyKwh": 14836
},
{
"month": 6,
"energyKwh": 14467
},
{
"month": 7,
"energyKwh": 15104
},
{
"month": 8,
"energyKwh": 14758
},
{
"month": 9,
"energyKwh": 13517
},
{
"month": 10,
"energyKwh": 12068
},
{
"month": 11,
"energyKwh": 11026
},
{
"month": 12,
"energyKwh": 9606
}
],
"requiresSiteSurvey": true,
"assumptions": "(assumptions, shortened here)",
"limitations": [
"No roof-plane geometry, obstructions, nearby tree/building shade, structural condition, or panel layout was measured.",
"PVGIS models regional solar resource and terrain horizon; it does not model parcel-level rooftop shading.",
"Verify the address match, roof dimensions, orientation, electrical connection, permits, tariff, and economics before a quote."
],
"reasonCodes": [
"STRONG_OPEN_SOLAR_RESOURCE",
"USER_SUPPLIED_ROOF_AREA",
"QUALIFIED_PRE_SCREEN"
],
"explanation": [
"1466 kWh/kWp annual PVGIS yield supports strong production.",
"Open-data pre-screen score 93 meets the 65 threshold."
],
"dataSource": {
"geocoding": "U.S. Census Geocoder Public_AR_Current",
"solarResource": "European Commission JRC PVGIS 5.3",
"rooftopGeometry": "Not measured"
},
"dataSourceUrls": {
"geocoding": "https://geocoding.geo.census.gov/geocoder/",
"solarResource": "https://re.jrc.ec.europa.eu/pvg_tools/en/"
},
"openDataAttribution": "Solar resource: European Commission Joint Research Centre, PVGIS 5.3. Address coordinates: U.S. Census Bureau Geocoder.",
"solarDataAttribution": "European Commission Joint Research Centre - PVGIS 5.3",
"derivedContentAttribution": "Derived by Solar Rooftop Lead Scorer from PVGIS and user assumptions.",
"processedAt": "2026-07-28T14:51:18.820Z",
"capacitySource": "item_roof_area",
"panelCapacityWatts": 440,
"energyUncertaintyPercent": 20,
"pvgisMountingPlace": "free",
"pvgisPvTechnologyLabel": "c-Si2025",
"status": "qualified"
}

What happens when the evidence is not there

An ambiguous address without a city resolves to nothing, and the record says so: status: "no_data", qualified: null rather than false, and every estimate stays null instead of being modeled from a guessed location.

{
"sourceId": "address-item-3",
"source": "addressItems",
"providerMode": "OPEN_DATA",
"inputAddress": "1600 Pennsylvania Ave",
"formattedAddress": null,
"latitude": null,
"leadScore": null,
"qualified": null,
"status": "no_data"
}

The legacy Google rooftop fields maxPanels, recommendedPanels, maxSystemCapacityKw, and recommendedSystemCapacityKw are null in OPEN_DATA. Use scenarioPanels, scenarioSystemCapacityKw, estimatedPackingPanels, and estimatedPackingSystemCapacityKw instead; none is an exact panel layout.

Open-data mode does not return or imply:

  • exact roof-plane geometry, pitch, or orientation unless supplied by the user;
  • building-specific shade from trees, chimneys, or nearby structures;
  • exact panel placement or count;
  • roof material, age, structural capacity, or electrical suitability;
  • permit, tariff, interconnection, tax, financing, or installation approval.

Input

Coordinates in PVGIS-covered land areas

Per-item roofAreaM2 or systemCapacityKw improves the estimate:

{
"providerMode": "OPEN_DATA",
"acceptTerms": true,
"coordinates": [
{
"id": "known-roof",
"latitude": 40.4168,
"longitude": -3.7038,
"roofAreaM2": 120
},
{
"id": "known-system",
"latitude": 48.1372,
"longitude": 11.5756,
"systemCapacityKw": 8
}
]
}

Keyless U.S. addresses

Use addressItems when roof area or proposed capacity is available:

{
"providerMode": "OPEN_DATA",
"acceptTerms": true,
"countryCode": "US",
"addressItems": [
{
"id": "lead-nyc-1",
"address": "350 5th Ave, New York, NY 10118",
"roofAreaM2": 120
}
],
"defaultSystemCapacityKw": 5
}

systemCapacityKw can be supplied instead of roofAreaM2. It takes precedence when both are present. Property-specific roof area or capacity lets an otherwise strong open-data result pass the qualification-evidence gate.

The original string-list input remains supported for existing integrations:

{
"providerMode": "OPEN_DATA",
"acceptTerms": true,
"addresses": [
"4600 Silver Hill Rd, Washington, DC 20233"
]
}

String-only addresses have no item-level roof area or system capacity, so they receive a production-comparison scenario and cannot be marked qualified. The Census Geocoder returns an address-range coordinate; verify the match before using any score in a customer workflow.

Existing Apify dataset

{
"providerMode": "OPEN_DATA",
"acceptTerms": true,
"inputDatasetId": "DATASET_ID",
"idField": "leadId",
"latitudeField": "latitude",
"longitudeField": "longitude",
"roofAreaM2Field": "roofAreaM2",
"systemCapacityKwField": "systemCapacityKw",
"maxItems": 1000
}

If a dataset row has valid coordinates and an address, coordinates take precedence.

Google Solar API mode

Provide a restricted key from a billing-enabled Google Cloud project with both Geocoding API and Solar API enabled:

{
"providerMode": "GOOGLE",
"googleApiKey": "YOUR_RESTRICTED_GOOGLE_API_KEY",
"acceptTerms": true,
"addresses": [
"1600 Amphitheatre Parkway, Mountain View, CA 94043"
],
"countryCode": "US",
"requiredQuality": "BASE"
}

The key is a secret Actor input. Provider messages are redacted if they echo it. Missing, placeholder, denied, disabled, billing-blocked, and quota-blocked keys fail before a property result is charged.

Illustrative demo

{
"demoMode": true,
"acceptTerms": true
}

The demo returns one clearly marked illustrative record, makes no live provider call, and triggers no property-analyzed event. A small Actor-start charge may still apply.

This Actor is also exposed to AI agents through Apify's MCP server (mcp.apify.com): an agent can discover it by search and run it with the same pay-per-event billing, with no separate integration.

Open-data assumptions

You can control:

  • defaultSystemCapacityKw - fallback comparison system, default 5 kW
  • defaultRoofAreaM2 - optional shared roof-area assumption
  • usableRoofFraction - default 0.55
  • panelPowerWatts - default 440 W
  • panelAreaM2 - default 2 m²
  • systemLossPercent - default 14%
  • pvgisMountingPlace - default free, a ventilated-rack proxy; building models fully integrated modules with no rear airflow
  • pvgisPvTechnology - default crystSi2025; use crystSi only for a legacy crystalline-silicon comparison
  • roofTiltDegrees and roofAzimuthDegrees - optional pair; otherwise PVGIS optimal orientation is used
  • energyUncertaintyPercent - default ±20%
  • annualElectricityUsageKwh - optionally right-sizes a roof-area scenario
  • electricityPricePerKwhUsd and installationCostPerWattUsd - optional user assumptions for gross modeled energy value and illustrative simple payback
  • incentiveRate - optional user assumption, default 0; no incentive is assumed unless you provide one
  • gridCarbonIntensityKgPerKwh - optional avoided-emissions assumption

The output repeats material assumptions. Missing values are not silently represented as measured facts.

OPEN_DATA reports user-price-derived amounts as grossAnnualEnergyValueUsd (plus low/high range) and grossValueSimplePaybackYears. Those values do not model self-consumption, export compensation, fixed charges, degradation, taxes, financing, or realized bill savings. The legacy Google fields estimatedAnnualSavingsUsd, estimatedAnnualSavingsUsdLow, estimatedAnnualSavingsUsdHigh, and simplePaybackYears remain null in OPEN_DATA.

How the open-data score works

The OPEN_DATA score is deterministic, has a theoretical maximum of 98, and is reported on the shared 0-100 lead-score scale:

SignalMaximum
PVGIS specific annual yield55
Item-level evidenced capacity35
Capacity evidence quality8

Properties must also clear minimum capacity and annual-energy rules. The default qualification threshold is 65. A standardized system or shared default-roof scenario can never qualify; only an item-level roof area or system capacity provides the required property-specific capacity evidence. Financial assumptions and gross-value payback do not increase the score or affect qualification.

Evidence completeness is separate from the lead score. A high solar-resource score can still carry low openDataConfidence and a low evidenceCompletenessScore when it uses a standardized system or an interpolated address coordinate. assessmentConfidenceScore remains reserved for Google-mode compatibility and is null in OPEN_DATA.

The original Google Solar API score remains deterministic and uses Google sunshine, usable array area, panel count, modeled energy, imagery quality/freshness, and building-match distance.

Output example

This is a live Berlin coordinate example using the current default crystSi2025 and free PVGIS models:

{
"sourceId": "lead-42",
"providerMode": "OPEN_DATA",
"status": "qualified",
"leadScore": 78,
"qualified": true,
"assessmentScope": "roof_area_screening",
"capacitySource": "item_roof_area",
"openDataConfidence": "medium",
"assessmentConfidenceScore": null,
"evidenceCompletenessScore": 65,
"requiresSiteSurvey": true,
"maxPanels": null,
"recommendedPanels": null,
"maxSystemCapacityKw": null,
"recommendedSystemCapacityKw": null,
"scenarioPanels": 27,
"scenarioSystemCapacityKw": 11.88,
"estimatedPackingPanels": 27,
"estimatedPackingSystemCapacityKw": 11.88,
"specificYieldKwhPerKwp": 1085,
"annualPlaneOfArrayIrradiationKwhM2": 1314,
"estimatedAnnualEnergyKwhAc": 12885,
"estimatedAnnualEnergyKwhAcLow": 10308,
"estimatedAnnualEnergyKwhAcHigh": 15462,
"pvgisPanelTiltDegrees": 40,
"pvgisPanelAzimuthDegrees": -5,
"pvgisMountingPlace": "free",
"pvgisPvTechnology": "crystSi2025",
"radiationDatabase": "PVGIS-SARAH3",
"dataYearStart": 2005,
"dataYearEnd": 2023,
"googleMapsAttribution": null,
"googleContentExpiresAt": null,
"solarDataAttribution": "European Commission Joint Research Centre - PVGIS 5.3"
}

Pricing and spending control

  • Up to $0.02 per property that returns a completed qualified or not_qualified analysis
  • no_data and error records are free
  • The small apify-actor-start event may apply when a run starts
  • OPEN_DATA has no separate API-key or provider bill
  • GOOGLE calls are billed separately to the Google Cloud project connected to the supplied key

Set Apify Maximum cost per run before starting. maxItems limits workload but is not a billing cap. The Actor checks the remaining event budget before each batch, commits successful results and charges atomically, and stops gracefully when the spending limit is reached.

Successful analysesMaximum property-event charge
1Up to $0.02
100Up to $2.00
1,000Up to $20.00

Reliability behavior

  • Bounded timeouts and retries for transient network errors
  • Explicit retries for PVGIS 429, 529, and server errors
  • Complete-address validation and fail-closed handling for ambiguous Census matches
  • No retries for permanent validation or unsupported-country errors
  • In-run deduplication that includes property and capacity assumptions
  • Structured free no_data and error records
  • A real failed run when every processed item is an error
  • Atomic pay-per-event commits and graceful spending-limit stops
  • No silent fallback from a failed live request to demo data

Local development

npm ci
npm run check
npm test

Run locally with an Apify local INPUT.json:

$npm start

Google Solar API mode can also read GOOGLE_SOLAR_API_KEY from the Actor environment. Never commit a key.

Data retention and deletion

Open-data mode

Open-data results set:

{
"googleContentExpiresAt": null,
"googleMapsAttribution": null
}

No Google content is used. Apify input and output retention remains controlled by the Actor user and their Apify account. Delete personal property data when it is no longer needed for the stated purpose.

Google Solar API mode

Google-derived results contain processedAt and googleContentExpiresAt, set 30 consecutive days apart. Delete Google-derived fields or the dataset by that time unless your own Google Maps Platform agreement expressly permits longer retention or another exception applies.

Keep the Google attribution fields with displayed or exported Google results.

Terms of Use

Effective date: July 28, 2026.

By running this Actor, you agree to these Terms and the Privacy Policy below.

Permitted use

Use the Actor only to evaluate the feasibility, design, installation, or permitted downstream transaction of an energy system. If an output will be used for person-targeted solar marketing, you represent that the affected person requested the service or opted in and that your use complies with applicable privacy, marketing, and consumer-protection law.

You must not use the Actor to:

  • send unconsented marketing to purchased, scraped, or otherwise non-opt-in personal-address lists;
  • make housing, credit, employment, insurance, or another legally protected high-impact decision;
  • represent an automated pre-screen as engineering, structural, electrical, tax, investment, permit, or installation approval;
  • conceal material assumptions, confidence, limitations, or required provider attribution;
  • submit addresses or personal data without a valid lawful basis and necessary rights;
  • retain Google content beyond the period allowed by your Google agreement.

Third-party terms

Open-data use is subject to the applicable provider documentation and conditions:

Google Solar API mode is also governed by:

Apify account, storage, billing, and platform use are governed by Apify's terms.

Estimates and availability

Provider coverage, data vintages, geocoder matches, solar models, tariffs, incentives, costs, and third-party availability can change. Results are automated estimates provided on an as-available basis. Verify material decisions using current site information and qualified professionals.

To the maximum extent permitted by law, the maintainer is not responsible for indirect or consequential loss arising from an estimate, third-party outage, user-supplied data, or misconfiguration.

Support

Report reproducible problems through the Issues tab. Do not include API keys, unnecessary personal data, or confidential customer lists.

Privacy Policy

Effective date: July 28, 2026.

Data processed

Depending on mode, the Actor processes:

  • submitted addresses, coordinates, identifiers, roof/system values, and financial assumptions;
  • a secret Google API key in GOOGLE mode;
  • Census and PVGIS responses in OPEN_DATA mode;
  • Google Geocoding and Solar API responses in GOOGLE mode;
  • generated scores, confidence, assumptions, explanations, errors, timestamps, and summary counts.

How data is used and shared

In OPEN_DATA mode:

  • coordinates and modelling inputs are sent to PVGIS;
  • U.S. addresses are sent to the Census Geocoder, then the returned coordinate is sent to PVGIS;
  • coordinate inputs are sent directly to PVGIS and are not reverse-geocoded.

In GOOGLE mode, addresses or coordinates and the key are sent to the applicable Google endpoints.

Inputs and results are processed and stored on Apify as part of the user's run. The maintainer does not create a cross-run property cache, sell customer lists, or use submitted properties for independent marketing.

User control

Run input and output retention is controlled by the Actor user's Apify account. Users can delete runs, datasets, and key-value stores through Apify Console or API. Submit only the minimum data needed, honor data-subject rights, and do not submit personal addresses without a lawful basis and any required consent.