Open registry of 1.14M+ rooftop-solar detections across France, queryable by natural language.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Compute the total estimated installed capacity (kWp) and count of detections matching a set of filters — département, commune, capacity range, and cross-validation across sources (cross_validated) or imagery vintages (min_vintages) — plus a quality_summary for the summed sample. Unlike get_department_capacity_stats, which is a fixed pre-computed département-wide aggregate with no other filters, this tool sums a live filtered subset, up to max_rows detections. Example: "installed capacity in Gironde confirmed by at least two sources" -> dpt="33", cross_validated=true. Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. In this server, quality_filter=true keeps only detections identified by 2 or more sources (see source_encoding in get_data_quality_reference). Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
Cap on the number of matching detection rows fetched to compute the capacity sum. If the true match count exceeds this, total_kwp is a partial lower bound and `truncated` is true — increase max_rows or narrow the filters (e.g. add dpt or insee) for an exact total.
If true, only include detections identified by 2 OR MORE sources(the `sources` field lists at least two codes, e.g. "0,1" = DeepPVMapper pipeline + FRPV reference, "0,2" = pipeline + OpenStreetMap). Default false: all detections are included, including those found by a single source (typically the automated pipeline alone).
French département code, e.g. "33".
INSEE commune code.
Maximum estimated installed capacity, in kWp.
Minimum estimated installed capacity, in kWp.
Maximum estimated tilt from horizontal, in degrees.
Minimum estimated tilt from horizontal, in degrees.
true = only detections matched to an RNB building identifier (rnb_id not null); false = only detections without one.
Maximum estimated azimuth, degrees clockwise from true north (180 = south).
Maximum estimated PV array area, in m².
Minimum estimated azimuth, degrees clockwise from true north (180 = south).
Minimum estimated PV array area, in m².
Maximum number of imagery vintages (e.g. 1 = seen in a single year only).
Minimum number of distinct imagery vintages (years) the installation was independently detected in. Use 2+ as a persistence/confidence signal, since a one-off detection in a single vintage is more likely to be a transient artifact.
Upper bound on last_seen imagery year.
Lower bound on last_seen imagery year.
true = only detections that have an FRPV comparison (frpv_proba not null); false = only those without one. A null frpv_proba means "no comparison available", not probability 0.
Upper bound on first_seen imagery year.
Earliest imagery year of first detection, lower bound (e.g. 2018). Not an installation date.
Minimum frpv_proba. The data contract recommends 0.1 as a precision/recall trade-off. Note: detections with a null frpv_proba (no FRPV comparison available) are excluded when this is set; null does not mean probability 0.
Alias of quality_filter, kept for backward compatibility.
Only include detections present in ALL of these sources. Accepts names or codes, case-insensitive: dpvm/deeppvmapper/kasmi (0), frpv/thebault (1), osm/openstreetmap (2), manual/annotation (3), recall (4). Examples: ["osm"] = detections that are in OpenStreetMap; ["dpvm","frpv"] = present in both DeepPVMapper and FRPV. See get_source_reference for what each source is and where it comes from.
flagged = false_positive is true; not_flagged = false_positive is false; unrecorded = false_positive is null (no status recorded — NOT a confirmed true positive).
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Compute the total estimated installed capacity (kWp) and count of detections matching a set of filters — département, commune, capacity range, and cross-validation across sources (cross_validated) or imagery vintages (min_vintages) — plus a quality_summary for the summed sample. Unlike get_department_capacity_stats, which is a fixed pre-computed département-wide aggregate with no other filters, this tool sums a live filtered subset, up to max_rows detections. Example: "installed capacity in Gironde confirmed by at least two sources" -> dpt="33", cross_validated=true. Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. In this server, quality_filter=true keeps only detections identified by 2 or more sources (see source_encoding in get_data_quality_reference). Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
| Argument | Type | Description |
|---|---|---|
| dpt | string | French département code, e.g. "33". |
| insee | string | INSEE commune code. |
| max_kwp | number | Maximum estimated installed capacity, in kWp. |
| min_kwp | number | Minimum estimated installed capacity, in kWp. |
| max_rows* | integer | Cap on the number of matching detection rows fetched to compute the capacity sum. If the true match count exceeds this, total_kwp is a partial lower bound and `truncated` is true — increase max_rows or narrow the filters (e.g. add dpt or insee) for an exact total. |
| max_tilt | number | Maximum estimated tilt from horizontal, in degrees. |
| min_tilt | number | Minimum estimated tilt from horizontal, in degrees. |
| has_rnb_id | boolean | true = only detections matched to an RNB building identifier (rnb_id not null); false = only detections without one. |
| max_azimuth | number | Maximum estimated azimuth, degrees clockwise from true north (180 = south). |
| max_surface | number | Maximum estimated PV array area, in m². |
| min_azimuth | number | Minimum estimated azimuth, degrees clockwise from true north (180 = south). |
| min_surface | number | Minimum estimated PV array area, in m². |
| max_vintages | integer | Maximum number of imagery vintages (e.g. 1 = seen in a single year only). |
| min_vintages | integer | Minimum number of distinct imagery vintages (years) the installation was independently detected in. Use 2+ as a persistence/confidence signal, since a one-off detection in a single vintage is more likely to be a transient artifact. |
| max_last_seen | integer | Upper bound on last_seen imagery year. |
| min_last_seen | integer | Lower bound on last_seen imagery year. |
| has_frpv_proba | boolean | true = only detections that have an FRPV comparison (frpv_proba not null); false = only those without one. A null frpv_proba means "no comparison available", not probability 0. |
| max_first_seen | integer | Upper bound on first_seen imagery year. |
| min_first_seen | integer | Earliest imagery year of first detection, lower bound (e.g. 2018). Not an installation date. |
| min_frpv_proba | number | Minimum frpv_proba. The data contract recommends 0.1 as a precision/recall trade-off. Note: detections with a null frpv_proba (no FRPV comparison available) are excluded when this is set; null does not mean probability 0. |
| quality_filter* | boolean | If true, only include detections identified by 2 OR MORE sources(the `sources` field lists at least two codes, e.g. "0,1" = DeepPVMapper pipeline + FRPV reference, "0,2" = pipeline + OpenStreetMap). Default false: all detections are included, including those found by a single source (typically the automated pipeline alone). |
| cross_validated | boolean | Alias of quality_filter, kept for backward compatibility. |
| sources_include | array | Only include detections present in ALL of these sources. Accepts names or codes, case-insensitive: dpvm/deeppvmapper/kasmi (0), frpv/thebault (1), osm/openstreetmap (2), manual/annotation (3), recall (4). Examples: ["osm"] = detections that are in OpenStreetMap; ["dpvm","frpv"] = present in both DeepPVMapper and FRPV. See get_source_reference for what each source is and where it comes from. |
| false_positive_status | string | flagged = false_positive is true; not_flagged = false_positive is false; unrecorded = false_positive is null (no status recorded — NOT a confirmed true positive). |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"quality_filter",
"max_rows"
],
"properties": {
"dpt": {
"type": "string",
"description": "French département code, e.g. \"33\"."
},
"insee": {
"type": "string",
"description": "INSEE commune code."
},
"max_kwp": {
"type": "number",
"description": "Maximum estimated installed capacity, in kWp."
},
"min_kwp": {
"type": "number",
"description": "Minimum estimated installed capacity, in kWp."
},
"max_rows": {
"type": "integer",
"default": 5000,
"maximum": 20000,
"description": "Cap on the number of matching detection rows fetched to compute the capacity sum. If the true match count exceeds this, total_kwp is a partial lower bound and `truncated` is true — increase max_rows or narrow the filters (e.g. add dpt or insee) for an exact total.",
"exclusiveMinimum": 0
},
"max_tilt": {
"type": "number",
"description": "Maximum estimated tilt from horizontal, in degrees."
},
"min_tilt": {
"type": "number",
"description": "Minimum estimated tilt from horizontal, in degrees."
},
"has_rnb_id": {
"type": "boolean",
"description": "true = only detections matched to an RNB building identifier (rnb_id not null); false = only detections without one."
},
"max_azimuth": {
"type": "number",
"description": "Maximum estimated azimuth, degrees clockwise from true north (180 = south)."
},
"max_surface": {
"type": "number",
"description": "Maximum estimated PV array area, in m²."
},
"min_azimuth": {
"type": "number",
"description": "Minimum estimated azimuth, degrees clockwise from true north (180 = south)."
},
"min_surface": {
"type": "number",
"description": "Minimum estimated PV array area, in m²."
},
"max_vintages": {
"type": "integer",
"maximum": 9007199254740991,
"description": "Maximum number of imagery vintages (e.g. 1 = seen in a single year only).",
"exclusiveMinimum": 0
},
"min_vintages": {
"type": "integer",
"maximum": 9007199254740991,
"description": "Minimum number of distinct imagery vintages (years) the installation was independently detected in. Use 2+ as a persistence/confidence signal, since a one-off detection in a single vintage is more likely to be a transient artifact.",
"exclusiveMinimum": 0
},
"max_last_seen": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Upper bound on last_seen imagery year."
},
"min_last_seen": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Lower bound on last_seen imagery year."
},
"has_frpv_proba": {
"type": "boolean",
"description": "true = only detections that have an FRPV comparison (frpv_proba not null); false = only those without one. A null frpv_proba means \"no comparison available\", not probability 0."
},
"max_first_seen": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Upper bound on first_seen imagery year."
},
"min_first_seen": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Earliest imagery year of first detection, lower bound (e.g. 2018). Not an installation date."
},
"min_frpv_proba": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "Minimum frpv_proba. The data contract recommends 0.1 as a precision/recall trade-off. Note: detections with a null frpv_proba (no FRPV comparison available) are excluded when this is set; null does not mean probability 0."
},
"quality_filter": {
"type": "boolean",
"default": false,
"description": "If true, only include detections identified by 2 OR MORE sources(the `sources` field lists at least two codes, e.g. \"0,1\" = DeepPVMapper pipeline + FRPV reference, \"0,2\" = pipeline + OpenStreetMap). Default false: all detections are included, including those found by a single source (typically the automated pipeline alone)."
},
"cross_validated": {
"type": "boolean",
"description": "Alias of quality_filter, kept for backward compatibility."
},
"sources_include": {
"type": "array",
"items": {
"anyOf": [
{
"type": "integer",
"maximum": 4,
"minimum": 0
},
{
"type": "string"
}
]
},
"description": "Only include detections present in ALL of these sources. Accepts names or codes, case-insensitive: dpvm/deeppvmapper/kasmi (0), frpv/thebault (1), osm/openstreetmap (2), manual/annotation (3), recall (4). Examples: [\"osm\"] = detections that are in OpenStreetMap; [\"dpvm\",\"frpv\"] = present in both DeepPVMapper and FRPV. See get_source_reference for what each source is and where it comes from."
},
"false_positive_status": {
"enum": [
"flagged",
"not_flagged",
"unrecorded"
],
"type": "string",
"description": "flagged = false_positive is true; not_flagged = false_positive is false; unrecorded = false_positive is null (no status recorded — NOT a confirmed true positive)."
}
},
"additionalProperties": false
}Count detections matching a set of filters, exactly, without downloading rows (fast, no row cap). Use this for "how many ..." questions, e.g. "how many installations have an RNB id?" -> has_rnb_id=true; "how many are identified by 2+ sources?" -> quality_filter=true; "how many come from OpenStreetMap?" -> sources_include=[2]. Returns the matching count, the unfiltered registry total and the percentage. Counts are DETECTED systems, not an inventory. Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. In this server, quality_filter=true keeps only detections identified by 2 or more sources (see source_encoding in get_data_quality_reference). Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
| Argument | Type | Description |
|---|---|---|
| dpt | string | French département code, e.g. "33". |
| insee | string | INSEE commune code. |
| max_kwp | number | Maximum estimated installed capacity, in kWp. |
| min_kwp | number | Minimum estimated installed capacity, in kWp. |
| max_tilt | number | Maximum estimated tilt from horizontal, in degrees. |
| min_tilt | number | Minimum estimated tilt from horizontal, in degrees. |
| has_rnb_id |
Get a snapshot of ongoing community contribution activity on the map: how many corrections are currently pending moderation, their breakdown by action type (add / modify / delete), and the most recent submissions (timestamp, action, target). Submitted free-text comments are intentionally excluded from this tool. This reflects unmoderated, unverified user activity, not the registry itself — do not present it as confirmed detection data.
| Argument | Type | Description |
|---|---|---|
| recent_limit* | integer | How many of the most recent pending contributions to list. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"recent_limit"
],
"properties": {
"recent_limit": {
"type": "integer",
"default": 15,
"maximum": 50,
"description": "How many of the most recent pending contributions to list.",
"exclusiveMinimum": 0
}
},
"additionalProperties": false
}Find pending, unmoderated community contributions relevant to a specific area, to answer "has anyone flagged anything here that is not in the registry yet?" Two independent filters: dpt finds pending edits/deletions (action=modify/delete) targeting existing detections in that département; a full bounding box (min_lon/min_lat/max_lon/max_lat) finds pending new additions (action=add) whose proposed footprint centroid falls inside it. Combine with get_department_capacity_stats / search_detections / get_detections_in_bbox for the confirmed registry picture, and present this separately and clearly as unverified, pending community input — not confirmed detection data. Free-text comments are never included.
| Argument | Type | Description |
|---|---|---|
| dpt | string | Filter pending edits/deletions of EXISTING detections (action=modify or delete) to this département. Does not apply to proposed new additions (action=add), which have no département recorded on the pending item itself — use the bbox parameters for those. |
| max_lat | number | |
| max_lon | number | |
| min_lat | number | |
| min_lon | number | |
| scan_limit* | integer | How many recent proposed additions (action=add) to scan for a bbox match. Only relevant when all four bbox parameters are given — there is no server-side spatial index on pending items, so matching is done by fetching this many of the most recent ones and checking their centroid against the box. |
Return the DeepPVMapper/OpenPVMapper registry's documented data-quality characteristics: estimated detection recall, which fields are model-derived estimates vs. structural/observed fields, the source-encoding table, the recommended confidence threshold, confidence signals, and licensing/liability terms. Call this before advising how much to trust a result for a specific use case (e.g. exploratory research vs. a commercial or regulatory decision) — pair it with the quality_summary attached to search_detections / aggregate_detection_capacity results, which reflects the specific query rather than the registry as a whole.
No arguments.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {},
"additionalProperties": false
}Get installed rooftop-PV capacity (total kWp) and system counts for one or all French départements, from the DeepPVMapper/OpenPVMapper registry. This is a fixed, pre-computed department-wide aggregate with no other filters — use aggregate_detection_capacity instead if you need a filtered subset (e.g. only cross-validated detections). Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. In this server, quality_filter=true keeps only detections identified by 2 or more sources (see source_encoding in get_data_quality_reference). Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
| Argument | Type | Description |
|---|---|---|
| dpt | string | French département code, e.g. "33" for Gironde. Omit for all départements. |
| top_n | integer | If set and dpt is omitted, return only the top N départements by installed capacity. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"dpt": {
"type": "string",
"description": "French département code, e.g. \"33\" for Gironde. Omit for all départements."
},
"top_n": {
"type": "integer",
"maximum": 96,
"description": "If set and dpt is omitted, return only the top N départements by installed capacity.",
"exclusiveMinimum": 0
}
},
"additionalProperties": false
}One-call profile of a département: installed capacity and national rank, yearly trend (by first-seen imagery year), source mix, share identified by 2+ sources, and share matched to an RNB building id. Cross-references the pre-computed department statistics with live counts. Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. In this server, quality_filter=true keeps only detections identified by 2 or more sources (see source_encoding in get_data_quality_reference). Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
| Argument | Type | Description |
|---|---|---|
| dpt* | string | French département code, e.g. "33". |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"dpt"
],
"properties": {
"dpt": {
"type": "string",
"description": "French département code, e.g. \"33\"."
}
},
"additionalProperties": false
}Get yearly system counts and capacity by département, based on first-seen imagery year. Useful for tracking apparent PV deployment growth over time. Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. In this server, quality_filter=true keeps only detections identified by 2 or more sources (see source_encoding in get_data_quality_reference). Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
| Argument | Type | Description |
|---|---|---|
| dpt | string | French département code, e.g. "33". Omit for all départements. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"dpt": {
"type": "string",
"description": "French département code, e.g. \"33\". Omit for all départements."
}
},
"additionalProperties": false
}Get the full record of one detection by id: technical characteristics (surface, kwp, tilt, azimuth — model estimates), imagery years, sources decoded into plain labels, frpv_proba, false-positive flag, rnb_id and location codes, plus simple confidence signals. Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. In this server, quality_filter=true keeps only detections identified by 2 or more sources (see source_encoding in get_data_quality_reference). Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
| Argument | Type | Description |
|---|---|---|
| id* | integer | Registry identifier of the detection (the `id` field). |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"id"
],
"properties": {
"id": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Registry identifier of the detection (the `id` field)."
}
},
"additionalProperties": false
}Get rooftop-PV detections within a geographic bounding box (WGS84 lon/lat), including footprint geometry. Intended for map-style spatial queries over a small area. Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. In this server, quality_filter=true keeps only detections identified by 2 or more sources (see source_encoding in get_data_quality_reference). Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
| Argument | Type | Description |
|---|---|---|
| max_lat* | number | |
| max_lon* | number | |
| min_lat* | number | |
| min_lon* | number | |
| max_count* | integer | Maximum number of detections to return (max 500 here; the underlying API defaults to 2000, capped lower to keep responses manageable for an LLM). |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"min_lon",
"min_lat",
"max_lon",
"max_lat",
"max_count"
],
"properties": {
"max_lat": {
"type": "number"
},
"max_lon": {
"type": "number"
},
"min_lat": {
"type": "number"
},
"min_lon": {
"type": "number"
},
"max_count": {
"type": "integer",
"default": 100,
"maximum": 500,
"description": "Maximum number of detections to return (max 500 here; the underlying API defaults to 2000, capped lower to keep responses manageable for an LLM).",
"exclusiveMinimum": 0
}
},
"additionalProperties": false
}Completeness report: for each optional field of the registry (rnb_id, frpv_proba, false_positive, false_positive_source), how many detections have it filled in and what percentage. Answers "how many installations have an RNB id / an FRPV comparison / a false-positive flag?" in one call, for France or one département. For a single filtered count use count_detections instead. Null means "not available/recorded", never "0" or "confirmed ok". Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. In this server, quality_filter=true keeps only detections identified by 2 or more sources (see source_encoding in get_data_quality_reference). Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
| Argument | Type | Description |
|---|---|---|
| dpt | string | French département code. Omit for all of France. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"dpt": {
"type": "string",
"description": "French département code. Omit for all of France."
}
},
"additionalProperties": false
}Histogram of a numeric field (kwp, surface, tilt, azimuth, n_vintages, first_seen, last_seen) with exact counts per bin, for France or one département. Answers "how are installations distributed by size / tilt / orientation / year?". kwp, surface, tilt and azimuth are model estimates. first_seen/last_seen are imagery years, not installation dates. Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. In this server, quality_filter=true keeps only detections identified by 2 or more sources (see source_encoding in get_data_quality_reference). Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
| Argument | Type | Description |
|---|---|---|
| dpt | string | French département code. Omit for all of France. |
| field* | string | Numeric field to describe. |
| max_year | integer | For first_seen / last_seen: last year to count. |
| min_year | integer | For first_seen / last_seen: first year to count. |
| bin_edges | array | Custom ascending bin edges; each bin is [edge_i, edge_i+1) and the last is closed. Ignored for first_seen / last_seen, which are counted per year (use min_year / max_year). |
| quality_filter* | boolean | If true, restrict to detections identified by 2+ sources. |
Field-by-field documentation of a detection record: type, unit, nullability, whether it is observed or a model estimate, how to read it, and which tool filters or reports it. Call this when the user asks what a field means or how reliable it is.
No arguments.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {},
"additionalProperties": false
}Break down detections by source code (0=DPVM pipeline, 1=FRPV reference, 2=OSM, 3=manual correction, 4=recall sample), for one département or all of France, with human-readable labels. A detection can carry several sources, so per-source counts overlap and do not add up to the total. Also returns how many detections are identified by 2+ sources (the meaning of quality_filter). Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. In this server, quality_filter=true keeps only detections identified by 2 or more sources (see source_encoding in get_data_quality_reference). Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
| Argument | Type | Description |
|---|---|---|
| dpt | string | French département code, e.g. "33". Omit for all of France. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"dpt": {
"type": "string",
"description": "French département code, e.g. \"33\". Omit for all of France."
}
},
"additionalProperties": false
}Explain the data sources behind the registry's `sources` field: for each source, its code, short key, name, accepted aliases, and where the data comes from (with references: code, thesis, papers). Use it for questions like "what is FRPV?", "where does the OSM data come from?", "what is a manual correction?". The `sources` field answers "where do we have this installation?": each listed code is a dataset or process that contains it. Example: "0,1" = present in both DeepPVMapper (DPVM) and FRPV; "0,2" = present in DeepPVMapper and OpenStreetMap.
| Argument | Type | Description |
|---|---|---|
| source | string | A source name, alias or code (e.g. "frpv", "OpenStreetMap", "kasmi", "3"). Omit to list all. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"source": {
"type": "string",
"description": "A source name, alias or code (e.g. \"frpv\", \"OpenStreetMap\", \"kasmi\", \"3\"). Omit to list all."
}
},
"additionalProperties": false
}START HERE. Call this first when the user is new, asks what this server can do, or asks a vague question about DeepPVMapper. Returns a plain-language introduction, example questions, which tool answers which kind of question, a glossary and the main caveats. Reply to the user in their own language.
No arguments.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {},
"additionalProperties": false
}Search individual rooftop-PV detections by département, commune (INSEE code), estimated capacity range, and/or cross-validation confidence (min_vintages, cross_validated). Returns a bounded list of detection records plus a quality_summary for the returned sample (use get_detections_in_bbox instead for map/spatial queries with geometry). Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. In this server, quality_filter=true keeps only detections identified by 2 or more sources (see source_encoding in get_data_quality_reference). Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
| Argument | Type | Description |
|---|---|---|
| dpt | string | French département code, e.g. "33". |
| insee | string | INSEE commune code. |
| limit* | integer | Maximum number of records to return (max 200). |
| max_kwp | number | Maximum estimated installed capacity, in kWp. |
| min_kwp | number | Minimum estimated installed capacity, in kWp. |
| max_tilt | number | Maximum estimated tilt from horizontal, in degrees. |
| min_tilt | number | Minimum estimated tilt from horizontal, in degrees. |
| boolean |
| true = only detections matched to an RNB building identifier (rnb_id not null); false = only detections without one. |
| max_azimuth | number | Maximum estimated azimuth, degrees clockwise from true north (180 = south). |
| max_surface | number | Maximum estimated PV array area, in m². |
| min_azimuth | number | Minimum estimated azimuth, degrees clockwise from true north (180 = south). |
| min_surface | number | Minimum estimated PV array area, in m². |
| max_vintages | integer | Maximum number of imagery vintages (e.g. 1 = seen in a single year only). |
| min_vintages | integer | Minimum number of distinct imagery vintages (years) the installation was independently detected in. Use 2+ as a persistence/confidence signal, since a one-off detection in a single vintage is more likely to be a transient artifact. |
| max_last_seen | integer | Upper bound on last_seen imagery year. |
| min_last_seen | integer | Lower bound on last_seen imagery year. |
| has_frpv_proba | boolean | true = only detections that have an FRPV comparison (frpv_proba not null); false = only those without one. A null frpv_proba means "no comparison available", not probability 0. |
| max_first_seen | integer | Upper bound on first_seen imagery year. |
| min_first_seen | integer | Earliest imagery year of first detection, lower bound (e.g. 2018). Not an installation date. |
| min_frpv_proba | number | Minimum frpv_proba. The data contract recommends 0.1 as a precision/recall trade-off. Note: detections with a null frpv_proba (no FRPV comparison available) are excluded when this is set; null does not mean probability 0. |
| quality_filter* | boolean | If true, only include detections identified by 2 OR MORE sources(the `sources` field lists at least two codes, e.g. "0,1" = DeepPVMapper pipeline + FRPV reference, "0,2" = pipeline + OpenStreetMap). Default false: all detections are included, including those found by a single source (typically the automated pipeline alone). |
| cross_validated | boolean | Alias of quality_filter, kept for backward compatibility. |
| sources_include | array | Only include detections present in ALL of these sources. Accepts names or codes, case-insensitive: dpvm/deeppvmapper/kasmi (0), frpv/thebault (1), osm/openstreetmap (2), manual/annotation (3), recall (4). Examples: ["osm"] = detections that are in OpenStreetMap; ["dpvm","frpv"] = present in both DeepPVMapper and FRPV. See get_source_reference for what each source is and where it comes from. |
| breakdown_rnb_id* | boolean | If true, also return how many of the matching detections do / do not have an rnb_id (ignores has_rnb_id for this breakdown). |
| false_positive_status | string | flagged = false_positive is true; not_flagged = false_positive is false; unrecorded = false_positive is null (no status recorded — NOT a confirmed true positive). |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"quality_filter",
"breakdown_rnb_id"
],
"properties": {
"dpt": {
"type": "string",
"description": "French département code, e.g. \"33\"."
},
"insee": {
"type": "string",
"description": "INSEE commune code."
},
"max_kwp": {
"type": "number",
"description": "Maximum estimated installed capacity, in kWp."
},
"min_kwp": {
"type": "number",
"description": "Minimum estimated installed capacity, in kWp."
},
"max_tilt": {
"type": "number",
"description": "Maximum estimated tilt from horizontal, in degrees."
},
"min_tilt": {
"type": "number",
"description": "Minimum estimated tilt from horizontal, in degrees."
},
"has_rnb_id": {
"type": "boolean",
"description": "true = only detections matched to an RNB building identifier (rnb_id not null); false = only detections without one."
},
"max_azimuth": {
"type": "number",
"description": "Maximum estimated azimuth, degrees clockwise from true north (180 = south)."
},
"max_surface": {
"type": "number",
"description": "Maximum estimated PV array area, in m²."
},
"min_azimuth": {
"type": "number",
"description": "Minimum estimated azimuth, degrees clockwise from true north (180 = south)."
},
"min_surface": {
"type": "number",
"description": "Minimum estimated PV array area, in m²."
},
"max_vintages": {
"type": "integer",
"maximum": 9007199254740991,
"description": "Maximum number of imagery vintages (e.g. 1 = seen in a single year only).",
"exclusiveMinimum": 0
},
"min_vintages": {
"type": "integer",
"maximum": 9007199254740991,
"description": "Minimum number of distinct imagery vintages (years) the installation was independently detected in. Use 2+ as a persistence/confidence signal, since a one-off detection in a single vintage is more likely to be a transient artifact.",
"exclusiveMinimum": 0
},
"max_last_seen": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Upper bound on last_seen imagery year."
},
"min_last_seen": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Lower bound on last_seen imagery year."
},
"has_frpv_proba": {
"type": "boolean",
"description": "true = only detections that have an FRPV comparison (frpv_proba not null); false = only those without one. A null frpv_proba means \"no comparison available\", not probability 0."
},
"max_first_seen": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Upper bound on first_seen imagery year."
},
"min_first_seen": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Earliest imagery year of first detection, lower bound (e.g. 2018). Not an installation date."
},
"min_frpv_proba": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "Minimum frpv_proba. The data contract recommends 0.1 as a precision/recall trade-off. Note: detections with a null frpv_proba (no FRPV comparison available) are excluded when this is set; null does not mean probability 0."
},
"quality_filter": {
"type": "boolean",
"default": false,
"description": "If true, only include detections identified by 2 OR MORE sources(the `sources` field lists at least two codes, e.g. \"0,1\" = DeepPVMapper pipeline + FRPV reference, \"0,2\" = pipeline + OpenStreetMap). Default false: all detections are included, including those found by a single source (typically the automated pipeline alone)."
},
"cross_validated": {
"type": "boolean",
"description": "Alias of quality_filter, kept for backward compatibility."
},
"sources_include": {
"type": "array",
"items": {
"anyOf": [
{
"type": "integer",
"maximum": 4,
"minimum": 0
},
{
"type": "string"
}
]
},
"description": "Only include detections present in ALL of these sources. Accepts names or codes, case-insensitive: dpvm/deeppvmapper/kasmi (0), frpv/thebault (1), osm/openstreetmap (2), manual/annotation (3), recall (4). Examples: [\"osm\"] = detections that are in OpenStreetMap; [\"dpvm\",\"frpv\"] = present in both DeepPVMapper and FRPV. See get_source_reference for what each source is and where it comes from."
},
"breakdown_rnb_id": {
"type": "boolean",
"default": false,
"description": "If true, also return how many of the matching detections do / do not have an rnb_id (ignores has_rnb_id for this breakdown)."
},
"false_positive_status": {
"enum": [
"flagged",
"not_flagged",
"unrecorded"
],
"type": "string",
"description": "flagged = false_positive is true; not_flagged = false_positive is false; unrecorded = false_positive is null (no status recorded — NOT a confirmed true positive)."
}
},
"additionalProperties": false
}| recent_limit* | integer | Maximum number of matching items to return per category. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"scan_limit",
"recent_limit"
],
"properties": {
"dpt": {
"type": "string",
"description": "Filter pending edits/deletions of EXISTING detections (action=modify or delete) to this département. Does not apply to proposed new additions (action=add), which have no département recorded on the pending item itself — use the bbox parameters for those."
},
"max_lat": {
"type": "number"
},
"max_lon": {
"type": "number"
},
"min_lat": {
"type": "number"
},
"min_lon": {
"type": "number"
},
"scan_limit": {
"type": "integer",
"default": 500,
"maximum": 2000,
"description": "How many recent proposed additions (action=add) to scan for a bbox match. Only relevant when all four bbox parameters are given — there is no server-side spatial index on pending items, so matching is done by fetching this many of the most recent ones and checking their centroid against the box.",
"exclusiveMinimum": 0
},
"recent_limit": {
"type": "integer",
"default": 30,
"maximum": 100,
"description": "Maximum number of matching items to return per category.",
"exclusiveMinimum": 0
}
},
"additionalProperties": false
}{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"field",
"quality_filter"
],
"properties": {
"dpt": {
"type": "string",
"description": "French département code. Omit for all of France."
},
"field": {
"enum": [
"kwp",
"surface",
"tilt",
"azimuth",
"n_vintages",
"first_seen",
"last_seen"
],
"type": "string",
"description": "Numeric field to describe."
},
"max_year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "For first_seen / last_seen: last year to count."
},
"min_year": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "For first_seen / last_seen: first year to count."
},
"bin_edges": {
"type": "array",
"items": {
"type": "number"
},
"maxItems": 25,
"minItems": 2,
"description": "Custom ascending bin edges; each bin is [edge_i, edge_i+1) and the last is closed. Ignored for first_seen / last_seen, which are counted per year (use min_year / max_year)."
},
"quality_filter": {
"type": "boolean",
"default": false,
"description": "If true, restrict to detections identified by 2+ sources."
}
},
"additionalProperties": false
}| has_rnb_id | boolean | true = only detections matched to an RNB building identifier (rnb_id not null); false = only detections without one. |
| max_azimuth | number | Maximum estimated azimuth, degrees clockwise from true north (180 = south). |
| max_surface | number | Maximum estimated PV array area, in m². |
| min_azimuth | number | Minimum estimated azimuth, degrees clockwise from true north (180 = south). |
| min_surface | number | Minimum estimated PV array area, in m². |
| max_vintages | integer | Maximum number of imagery vintages (e.g. 1 = seen in a single year only). |
| min_vintages | integer | Minimum number of distinct imagery vintages (years) the installation was independently detected in. Use 2+ as a persistence/confidence signal, since a one-off detection in a single vintage is more likely to be a transient artifact. |
| max_last_seen | integer | Upper bound on last_seen imagery year. |
| min_last_seen | integer | Lower bound on last_seen imagery year. |
| has_frpv_proba | boolean | true = only detections that have an FRPV comparison (frpv_proba not null); false = only those without one. A null frpv_proba means "no comparison available", not probability 0. |
| max_first_seen | integer | Upper bound on first_seen imagery year. |
| min_first_seen | integer | Earliest imagery year of first detection, lower bound (e.g. 2018). Not an installation date. |
| min_frpv_proba | number | Minimum frpv_proba. The data contract recommends 0.1 as a precision/recall trade-off. Note: detections with a null frpv_proba (no FRPV comparison available) are excluded when this is set; null does not mean probability 0. |
| quality_filter* | boolean | If true, only include detections identified by 2 OR MORE sources(the `sources` field lists at least two codes, e.g. "0,1" = DeepPVMapper pipeline + FRPV reference, "0,2" = pipeline + OpenStreetMap). Default false: all detections are included, including those found by a single source (typically the automated pipeline alone). |
| cross_validated | boolean | Alias of quality_filter, kept for backward compatibility. |
| sources_include | array | Only include detections present in ALL of these sources. Accepts names or codes, case-insensitive: dpvm/deeppvmapper/kasmi (0), frpv/thebault (1), osm/openstreetmap (2), manual/annotation (3), recall (4). Examples: ["osm"] = detections that are in OpenStreetMap; ["dpvm","frpv"] = present in both DeepPVMapper and FRPV. See get_source_reference for what each source is and where it comes from. |
| false_positive_status | string | flagged = false_positive is true; not_flagged = false_positive is false; unrecorded = false_positive is null (no status recorded — NOT a confirmed true positive). |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"quality_filter",
"limit"
],
"properties": {
"dpt": {
"type": "string",
"description": "French département code, e.g. \"33\"."
},
"insee": {
"type": "string",
"description": "INSEE commune code."
},
"limit": {
"type": "integer",
"default": 20,
"maximum": 200,
"description": "Maximum number of records to return (max 200).",
"exclusiveMinimum": 0
},
"max_kwp": {
"type": "number",
"description": "Maximum estimated installed capacity, in kWp."
},
"min_kwp": {
"type": "number",
"description": "Minimum estimated installed capacity, in kWp."
},
"max_tilt": {
"type": "number",
"description": "Maximum estimated tilt from horizontal, in degrees."
},
"min_tilt": {
"type": "number",
"description": "Minimum estimated tilt from horizontal, in degrees."
},
"has_rnb_id": {
"type": "boolean",
"description": "true = only detections matched to an RNB building identifier (rnb_id not null); false = only detections without one."
},
"max_azimuth": {
"type": "number",
"description": "Maximum estimated azimuth, degrees clockwise from true north (180 = south)."
},
"max_surface": {
"type": "number",
"description": "Maximum estimated PV array area, in m²."
},
"min_azimuth": {
"type": "number",
"description": "Minimum estimated azimuth, degrees clockwise from true north (180 = south)."
},
"min_surface": {
"type": "number",
"description": "Minimum estimated PV array area, in m²."
},
"max_vintages": {
"type": "integer",
"maximum": 9007199254740991,
"description": "Maximum number of imagery vintages (e.g. 1 = seen in a single year only).",
"exclusiveMinimum": 0
},
"min_vintages": {
"type": "integer",
"maximum": 9007199254740991,
"description": "Minimum number of distinct imagery vintages (years) the installation was independently detected in. Use 2+ as a persistence/confidence signal, since a one-off detection in a single vintage is more likely to be a transient artifact.",
"exclusiveMinimum": 0
},
"max_last_seen": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Upper bound on last_seen imagery year."
},
"min_last_seen": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Lower bound on last_seen imagery year."
},
"has_frpv_proba": {
"type": "boolean",
"description": "true = only detections that have an FRPV comparison (frpv_proba not null); false = only those without one. A null frpv_proba means \"no comparison available\", not probability 0."
},
"max_first_seen": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Upper bound on first_seen imagery year."
},
"min_first_seen": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Earliest imagery year of first detection, lower bound (e.g. 2018). Not an installation date."
},
"min_frpv_proba": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "Minimum frpv_proba. The data contract recommends 0.1 as a precision/recall trade-off. Note: detections with a null frpv_proba (no FRPV comparison available) are excluded when this is set; null does not mean probability 0."
},
"quality_filter": {
"type": "boolean",
"default": false,
"description": "If true, only include detections identified by 2 OR MORE sources(the `sources` field lists at least two codes, e.g. \"0,1\" = DeepPVMapper pipeline + FRPV reference, \"0,2\" = pipeline + OpenStreetMap). Default false: all detections are included, including those found by a single source (typically the automated pipeline alone)."
},
"cross_validated": {
"type": "boolean",
"description": "Alias of quality_filter, kept for backward compatibility."
},
"sources_include": {
"type": "array",
"items": {
"anyOf": [
{
"type": "integer",
"maximum": 4,
"minimum": 0
},
{
"type": "string"
}
]
},
"description": "Only include detections present in ALL of these sources. Accepts names or codes, case-insensitive: dpvm/deeppvmapper/kasmi (0), frpv/thebault (1), osm/openstreetmap (2), manual/annotation (3), recall (4). Examples: [\"osm\"] = detections that are in OpenStreetMap; [\"dpvm\",\"frpv\"] = present in both DeepPVMapper and FRPV. See get_source_reference for what each source is and where it comes from."
},
"false_positive_status": {
"enum": [
"flagged",
"not_flagged",
"unrecorded"
],
"type": "string",
"description": "flagged = false_positive is true; not_flagged = false_positive is false; unrecorded = false_positive is null (no status recorded — NOT a confirmed true positive)."
}
},
"additionalProperties": false
}