{
  "openapi": "3.1.1",
  "info": {
    "title": "GISela API",
    "version": "1.0.0",
    "summary": "Deterministic tools for people and AI agents.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://gisela.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/tools": {
      "get": {
        "operationId": "listTools",
        "summary": "Catalog of all tools",
        "responses": {
          "200": {
            "description": "Tool list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/{id}": {
      "get": {
        "operationId": "getTool",
        "summary": "Definition of one tool",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "gisela-reproject",
                "gisela-buffer",
                "gisela-shapefile-to-geojson",
                "gisela-area-length"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/gisela-reproject/calculate": {
      "post": {
        "operationId": "calculateGiselaReproject",
        "summary": "Convert GeoJSON, KML, GPX, CSV or shapefiles between WGS 84, UTM, LV95, British Grid and more.",
        "description": "Reprojects vector data between coordinate systems with GISela’s own projection maths: WGS 84, ETRS89, Web Mercator, every UTM zone, ETRS89-LAEA, German Gauss–Krüger zones, Swiss LV95/LV03 and the British National Grid. Reads the coordinate system from .prj files and GeoJSON, and shows sample coordinates before and after.\n\nMethodology:\n- The data is read into WGS 84 longitude/latitude, then projected to the target system. Readers: GeoJSON (also the old “crs” member), TopoJSON (arcs decoded with the transform), KML/KMZ, GPX, CSV with coordinate or WKT columns, WKT and zipped shapefiles with .prj detection by EPSG authority, name or Transverse Mercator parameters.\n- Transverse Mercator (UTM, Gauss–Krüger, British National Grid) uses Karney’s 6th-order Krüger series on the system’s own ellipsoid; ETRS89-LAEA uses the ellipsoidal Lambert azimuthal equal-area formulas of IOGP Guidance Note 7-2; LV95/LV03 use swisstopo’s rigorous oblique Mercator formulas; Web Mercator uses the spherical formulas on the WGS 84 radius.\n- Datum changes (OSGB 1936, DHDN, CH1903/CH1903+) go through geocentric coordinates with a published 7-parameter Helmert transformation. ETRS89 is treated as equal to WGS 84 (well under 1 m in Europe).\n- Outputs are rounded to 8 decimals for degrees and 3 decimals (millimetres) for metres.\n\nHelmert datum shifts are good to about 1–5 m. For survey work use the national grid transformations (OSTN15, BeTA2007, FINELTRA).",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "gisela_reproject",
        "x-owner-app": "gisela",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GiselaReprojectInput"
              },
              "examples": {
                "example1": {
                  "summary": "Tram stops (WGS 84) to Swiss LV95",
                  "value": {
                    "data": "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[7.992,47.1215]},\"properties\":{\"name\":\"Weiher\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[7.999,47.126]},\"properties\":{\"name\":\"Altstadt\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[8.006,47.129]},\"properties\":{\"name\":\"Marktplatz\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[8.012,47.1335]},\"properties\":{\"name\":\"Bahnhof\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[8.018,47.137]},\"properties\":{\"name\":\"Nordring\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[8.025,47.14]},\"properties\":{\"name\":\"Rebhalde\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[8.031,47.1405]},\"properties\":{\"name\":\"Endstation Ost\"}}]}",
                    "to": "EPSG:2056"
                  }
                },
                "example2": {
                  "summary": "Five bus stops in LV95 (CSV with E/N columns) to WGS 84",
                  "value": {
                    "data": "stop;E;N;boardings\nBus Seefeld;2643240;1219692;640\nBus Moosmatt;2643899;1219730;410\nBus Nordwest;2642892;1220545;380\nBus Industrie;2643559;1220628;720\nBus Rebhalde;2644031;1220442;290\n",
                    "from": "2056",
                    "to": "EPSG:4326",
                    "format": "csv"
                  }
                },
                "example3": {
                  "summary": "District polygons to ETRS89-LAEA (equal-area Europe)",
                  "value": {
                    "data": "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[7.99,47.12],[8.004,47.1205],[8.0052,47.1303],[7.9891,47.131],[7.99,47.12]]]},\"properties\":{\"name\":\"Altstadt\",\"population\":4820,\"households\":2410,\"zone\":\"mixed\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[8.004,47.1205],[8.019,47.1205],[8.0181,47.1303],[8.0052,47.1303],[8.004,47.1205]]]},\"properties\":{\"name\":\"Seefeld\",\"population\":3150,\"households\":1490,\"zone\":\"residential\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[8.019,47.1205],[8.033,47.12],[8.0342,47.131],[8.0181,47.1303],[8.019,47.1205]]]},\"properties\":{\"name\":\"Moosmatt\",\"population\":2280,\"households\":1010,\"zone\":\"residential\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[7.9891,47.131],[8.0052,47.1303],[8.004,47.1425],[7.99,47.142],[7.9891,47.131]]]},\"properties\":{\"name\":\"Bahnhof\",\"population\":3900,\"households\":2050,\"zone\":\"mixed\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[8.0052,47.1303],[8.0181,47.1303],[8.019,47.1425],[8.004,47.1425],[8.0052,47.1303]]]},\"properties\":{\"name\":\"Industrie Nord\",\"population\":640,\"households\":210,\"zone\":\"industrial\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[8.0181,47.1303],[8.0342,47.131],[8.033,47.142],[8.019,47.1425],[8.0181,47.1303]]]},\"properties\":{\"name\":\"Rebhalde\",\"population\":1720,\"households\":760,\"zone\":\"residential\"}}]}",
                    "to": "EPSG:3035"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GiselaReprojectResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/gisela-buffer/calculate": {
      "post": {
        "operationId": "calculateGiselaBuffer",
        "summary": "Buffer zones around points, lines or polygons at a distance in metres, merged or one per feature.",
        "description": "Creates buffer polygons at a true distance in metres around every feature of GeoJSON, KML, GPX, CSV or shapefile data: circles around points, corridors around lines, grown or shrunk polygons. Overlapping zones can be merged into one area. Returns GeoJSON, the ellipsoidal area of each zone and a map preview.\n\nMethodology:\n- Each feature (or all features when merging) is projected to a local Transverse Mercator plane centred on the data, so distances are in metres with a scale error below 0.03 % within 250 km of the centre.\n- Points become circles; every line segment and polygon edge becomes a stadium (two half circles joined by straight sides); the stadiums are merged with GISela’s polygon overlay (exact edge splitting on a snapped grid, even-odd classification). A positive polygon buffer is the polygon united with its edge band, a negative one the polygon minus the band.\n- Results are converted back to WGS 84. Areas and perimeters are ellipsoidal (Karney’s geodesic polygon algorithm on WGS 84).\n\nCircles are polygons with the chosen number of segments, so the area is slightly smaller than the true disc (0.6 % at 32 segments).",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "gisela_buffer",
        "x-owner-app": "gisela",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GiselaBufferInput"
              },
              "examples": {
                "example1": {
                  "summary": "300 m around seven tram stops, merged",
                  "value": {
                    "data": "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[7.992,47.1215]},\"properties\":{\"name\":\"Weiher\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[7.999,47.126]},\"properties\":{\"name\":\"Altstadt\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[8.006,47.129]},\"properties\":{\"name\":\"Marktplatz\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[8.012,47.1335]},\"properties\":{\"name\":\"Bahnhof\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[8.018,47.137]},\"properties\":{\"name\":\"Nordring\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[8.025,47.14]},\"properties\":{\"name\":\"Rebhalde\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[8.031,47.1405]},\"properties\":{\"name\":\"Endstation Ost\"}}]}",
                    "distance": 300,
                    "dissolve": true
                  }
                },
                "example2": {
                  "summary": "150 m corridor along the tram line",
                  "value": {
                    "data": "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"geometry\":{\"type\":\"LineString\",\"coordinates\":[[7.992,47.1215],[7.999,47.126],[8.006,47.129],[8.012,47.1335],[8.018,47.137],[8.025,47.14],[8.031,47.1405]]},\"properties\":{\"name\":\"Line 1\"}}]}",
                    "distance": 150
                  }
                },
                "example3": {
                  "summary": "District polygons shrunk by 100 m",
                  "value": {
                    "data": "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[7.99,47.12],[8.004,47.1205],[8.0052,47.1303],[7.9891,47.131],[7.99,47.12]]]},\"properties\":{\"name\":\"Altstadt\",\"population\":4820,\"households\":2410,\"zone\":\"mixed\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[8.004,47.1205],[8.019,47.1205],[8.0181,47.1303],[8.0052,47.1303],[8.004,47.1205]]]},\"properties\":{\"name\":\"Seefeld\",\"population\":3150,\"households\":1490,\"zone\":\"residential\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[8.019,47.1205],[8.033,47.12],[8.0342,47.131],[8.0181,47.1303],[8.019,47.1205]]]},\"properties\":{\"name\":\"Moosmatt\",\"population\":2280,\"households\":1010,\"zone\":\"residential\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[7.9891,47.131],[8.0052,47.1303],[8.004,47.1425],[7.99,47.142],[7.9891,47.131]]]},\"properties\":{\"name\":\"Bahnhof\",\"population\":3900,\"households\":2050,\"zone\":\"mixed\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[8.0052,47.1303],[8.0181,47.1303],[8.019,47.1425],[8.004,47.1425],[8.0052,47.1303]]]},\"properties\":{\"name\":\"Industrie Nord\",\"population\":640,\"households\":210,\"zone\":\"industrial\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[8.0181,47.1303],[8.0342,47.131],[8.033,47.142],[8.019,47.1425],[8.0181,47.1303]]]},\"properties\":{\"name\":\"Rebhalde\",\"population\":1720,\"households\":760,\"zone\":\"residential\"}}]}",
                    "distance": -100,
                    "segments": 16
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GiselaBufferResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/gisela-shapefile-to-geojson/calculate": {
      "post": {
        "operationId": "calculateGiselaShapefileToGeojson",
        "summary": "Turn a zipped shapefile (.shp, .dbf, .prj) into GeoJSON in WGS 84 or another coordinate system.",
        "description": "Reads a zipped ESRI shapefile with GISela’s own parser — points, lines, polygons with holes, multipoints, Z/M records flattened to 2-D — with its attribute table (dBASE, code page from .cpg or the header) and the coordinate system from the .prj file, and writes GeoJSON. Several shapefiles in one ZIP give several files.\n\nMethodology:\n- The ZIP is unpacked in memory (stored and DEFLATE entries). Files with the same base name form one shapefile.\n- .shp records are read after the ESRI technical description: Point, MultiPoint, PolyLine and Polygon with their Z and M variants (Z and M are dropped). Polygon rings are sorted into outer rings (clockwise) and holes (counter-clockwise) and nested by point-in-polygon tests.\n- .dbf: dBASE III field types C, N/F, L and D; text decoded with the .cpg code page, else the header’s language driver id, else UTF-8 when it decodes cleanly, else Windows-1252.\n- .prj: EPSG AUTHORITY codes first, then well-known ESRI names (UTM, ETRS89, Gauss–Krüger, LV95, British National Grid, Web Mercator), then Transverse Mercator parameters.\n\nMultiPatch (3-D surfaces) and coordinate systems outside GISela’s list are not supported; such files are reported, not guessed.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "gisela_shapefile_to_geojson",
        "x-owner-app": "gisela",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GiselaShapefileToGeojsonInput"
              },
              "examples": {
                "example1": {
                  "summary": "Districts of a sample town (LV95 shapefile) to WGS 84",
                  "value": {
                    "file": {
                      "filename": "districts.zip",
                      "contentType": "application/zip",
                      "contentBase64": "UEsDBBQAAAgIAAAAIQAkLKwiTAEAAJQDAAANAAAAZGlzdHJpY3RzLnNocGNgUOdiwAoYT71gZmBgBbLOnjmjs0ndxdHY2Hhy7kwjxzUyUSyJei6O6oYcZ5wWGzli149qGBA7YDPr/PdgY1EtF0dDjjV/jOcZOYIUgtSBAEwtTA6mtnzf/Fvv5ho5zpo5c+ZrTRdHyy0ntq0BmvVh+bHZN5DMRtcPNJIJ5g50vfamcbtUdFwc3wTu+PcVaDayO9Dt1d00t/+fNkItTO/jpbNZtgLNQjcbXT/QSGDIQtwBM2vZ7CMJrUhhKxBh+cUHLTzQ7UVXe7Jsn7wFkA8zC91d6PqBRrKgxwvMjTA3R6VY11sB4xjZHZMlWNguANX+qsuK+b3IyLE75/npR0D/wtSi+xc9HtD1Q40GuwNmFkwv0C8bpIF+gKU1ZHeg24uuFt2/6O5C1w80kg09XtDDGps70O2ttTe9pwdU69Kdoy4M5KPHE7rZ6PoBUEsDBBQAAAgIAAAAIQAJMKFYSQAAAJQAAAANAAAAZGlzdHJpY3RzLnNoeGNgUOdiwA68XjAzMLACGWfPnNHZpO7iaGxsPDl3ppHjGpkolkQ9F0d1Q44zTouNHHHoRwZGQOwAxGVQeheU/gehGZ2gdBuIBgBQSwMEFAAACAgAAAAhAGUNE3zMAAAAbgEAAA0AAABkaXN0cmljdHMuZGJmY65jZGRjYGBYyKAEJDFBXmJuKpTpDCL40OQL8gtKcxJLMvPzGPxAfBY0+Yz80uLUjPyclGLs8lX5eSjmc6PJ8yo45pQUlySmlCiAgYmFkYGRiaFBbmZFagpESCE4NTUtNQfGMzY0NTA0sTQoSi3OTEnNK8lMzFHwzc8vzk0sgZphZGRhYAiEyCqcEjPyMvLTYGZYGhgYGZii2OKZl1JaXFKUmargl1+UomBmYqBgZGiQCRUFGqEQlJqUkZiTkgpRb2huZKBgboZsixQAUEsDBBQAAAgIAAAAIQCKJg5jOgEAANgBAAANAAAAZGlzdHJpY3RzLnByagsI8vdyDo5WcvYwtDQw1o73CbM0VdJxd/V3B4kCiXiojJKOi2NIqG+0kgtCJDjAwzXI39MlWskptbg4NSfe0MLEUEnHzNjc3NjSXM/Q1FTHyNISSBtZGBpZxMbqBAR5+roCzXAvSk3NK89MzlDSMdAziNUJ9fMMAZqcmg4UBwsZmpuYGhtZGpkaWlqaGBuDtfp7uTqHePr7RSt55Jdk5qXG+yflZBaWpsb7phYlJ5bkF8U7VmXmlpZkxDun5pWkFikBNTkGOfq6hrgGRSu5JeYUp8a7JhYDtaYr6RiZGYAAyHIMRX75RSUZYFWGRthUBScn5qTGuyUmA+0EqkGThTpCSccSXZ9Pfl56ZklpCtDlaTA36pjrmRhbmloYwwGqlsQSDB0mZnqWpkYmBqZQYAYLP99UsDzIQbEAUEsDBBQAAAgIAAAAIQBQPIEOBwAAAAUAAAANAAAAZGlzdHJpY3RzLmNwZwsNcdO1AABQSwECFAAUAAAICAAAACEAJCysIkwBAACUAwAADQAAAAAAAAAAAAAAAAAAAAAAZGlzdHJpY3RzLnNocFBLAQIUABQAAAgIAAAAIQAJMKFYSQAAAJQAAAANAAAAAAAAAAAAAAAAAHcBAABkaXN0cmljdHMuc2h4UEsBAhQAFAAACAgAAAAhAGUNE3zMAAAAbgEAAA0AAAAAAAAAAAAAAAAA6wEAAGRpc3RyaWN0cy5kYmZQSwECFAAUAAAICAAAACEAiiYOYzoBAADYAQAADQAAAAAAAAAAAAAAAADiAgAAZGlzdHJpY3RzLnByalBLAQIUABQAAAgIAAAAIQBQPIEOBwAAAAUAAAANAAAAAAAAAAAAAAAAAEcEAABkaXN0cmljdHMuY3BnUEsFBgAAAAAFAAUAJwEAAHkEAAAAAA=="
                    }
                  }
                },
                "example2": {
                  "summary": "Same shapefile kept in LV95",
                  "value": {
                    "file": {
                      "filename": "districts.zip",
                      "contentType": "application/zip",
                      "contentBase64": "UEsDBBQAAAgIAAAAIQAkLKwiTAEAAJQDAAANAAAAZGlzdHJpY3RzLnNocGNgUOdiwAoYT71gZmBgBbLOnjmjs0ndxdHY2Hhy7kwjxzUyUSyJei6O6oYcZ5wWGzli149qGBA7YDPr/PdgY1EtF0dDjjV/jOcZOYIUgtSBAEwtTA6mtnzf/Fvv5ho5zpo5c+ZrTRdHyy0ntq0BmvVh+bHZN5DMRtcPNJIJ5g50vfamcbtUdFwc3wTu+PcVaDayO9Dt1d00t/+fNkItTO/jpbNZtgLNQjcbXT/QSGDIQtwBM2vZ7CMJrUhhKxBh+cUHLTzQ7UVXe7Jsn7wFkA8zC91d6PqBRrKgxwvMjTA3R6VY11sB4xjZHZMlWNguANX+qsuK+b3IyLE75/npR0D/wtSi+xc9HtD1Q40GuwNmFkwv0C8bpIF+gKU1ZHeg24uuFt2/6O5C1w80kg09XtDDGps70O2ttTe9pwdU69Kdoy4M5KPHE7rZ6PoBUEsDBBQAAAgIAAAAIQAJMKFYSQAAAJQAAAANAAAAZGlzdHJpY3RzLnNoeGNgUOdiwA68XjAzMLACGWfPnNHZpO7iaGxsPDl3ppHjGpkolkQ9F0d1Q44zTouNHHHoRwZGQOwAxGVQeheU/gehGZ2gdBuIBgBQSwMEFAAACAgAAAAhAGUNE3zMAAAAbgEAAA0AAABkaXN0cmljdHMuZGJmY65jZGRjYGBYyKAEJDFBXmJuKpTpDCL40OQL8gtKcxJLMvPzGPxAfBY0+Yz80uLUjPyclGLs8lX5eSjmc6PJ8yo45pQUlySmlCiAgYmFkYGRiaFBbmZFagpESCE4NTUtNQfGMzY0NTA0sTQoSi3OTEnNK8lMzFHwzc8vzk0sgZphZGRhYAiEyCqcEjPyMvLTYGZYGhgYGZii2OKZl1JaXFKUmargl1+UomBmYqBgZGiQCRUFGqEQlJqUkZiTkgpRb2huZKBgboZsixQAUEsDBBQAAAgIAAAAIQCKJg5jOgEAANgBAAANAAAAZGlzdHJpY3RzLnByagsI8vdyDo5WcvYwtDQw1o73CbM0VdJxd/V3B4kCiXiojJKOi2NIqG+0kgtCJDjAwzXI39MlWskptbg4NSfe0MLEUEnHzNjc3NjSXM/Q1FTHyNISSBtZGBpZxMbqBAR5+roCzXAvSk3NK89MzlDSMdAziNUJ9fMMAZqcmg4UBwsZmpuYGhtZGpkaWlqaGBuDtfp7uTqHePr7RSt55Jdk5qXG+yflZBaWpsb7phYlJ5bkF8U7VmXmlpZkxDun5pWkFikBNTkGOfq6hrgGRSu5JeYUp8a7JhYDtaYr6RiZGYAAyHIMRX75RSUZYFWGRthUBScn5qTGuyUmA+0EqkGThTpCSccSXZ9Pfl56ZklpCtDlaTA36pjrmRhbmloYwwGqlsQSDB0mZnqWpkYmBqZQYAYLP99UsDzIQbEAUEsDBBQAAAgIAAAAIQBQPIEOBwAAAAUAAAANAAAAZGlzdHJpY3RzLmNwZwsNcdO1AABQSwECFAAUAAAICAAAACEAJCysIkwBAACUAwAADQAAAAAAAAAAAAAAAAAAAAAAZGlzdHJpY3RzLnNocFBLAQIUABQAAAgIAAAAIQAJMKFYSQAAAJQAAAANAAAAAAAAAAAAAAAAAHcBAABkaXN0cmljdHMuc2h4UEsBAhQAFAAACAgAAAAhAGUNE3zMAAAAbgEAAA0AAAAAAAAAAAAAAAAA6wEAAGRpc3RyaWN0cy5kYmZQSwECFAAUAAAICAAAACEAiiYOYzoBAADYAQAADQAAAAAAAAAAAAAAAADiAgAAZGlzdHJpY3RzLnByalBLAQIUABQAAAgIAAAAIQBQPIEOBwAAAAUAAAANAAAAAAAAAAAAAAAAAEcEAABkaXN0cmljdHMuY3BnUEsFBgAAAAAFAAUAJwEAAHkEAAAAAA=="
                    },
                    "to": "EPSG:2056"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GiselaShapefileToGeojsonResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/gisela-area-length/calculate": {
      "post": {
        "operationId": "calculateGiselaAreaLength",
        "summary": "True area, perimeter and length of polygons and lines on the WGS 84 ellipsoid, per feature.",
        "description": "Measures every polygon and line of GeoJSON, KML, GPX, CSV/WKT or shapefile data on the WGS 84 ellipsoid with Karney’s geodesic algorithms — the same numbers as GISela’s measure tool and attribute fields. Holes are subtracted; results in metric or imperial units.\n\nMethodology:\n- Polygon area and perimeter: Karney’s geodesic polygon algorithm (edges are geodesics on WGS 84), outer rings minus holes. Line length: sum of geodesic distances (Karney inverse problem).\n- Input in a projected coordinate system is first converted to WGS 84 longitude/latitude, so the result does not depend on the map projection.\n- Units: 1 ha = 10,000 m², 1 acre = 4046.8564224 m², 1 mi = 1609.344 m, 1 ft = 0.3048 m.\n\nAreas are on the ellipsoid surface (sea level), not along the terrain.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "gisela_area_length",
        "x-owner-app": "gisela",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GiselaAreaLengthInput"
              },
              "examples": {
                "example1": {
                  "summary": "Six districts of a sample town",
                  "value": {
                    "data": "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[7.99,47.12],[8.004,47.1205],[8.0052,47.1303],[7.9891,47.131],[7.99,47.12]]]},\"properties\":{\"name\":\"Altstadt\",\"population\":4820,\"households\":2410,\"zone\":\"mixed\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[8.004,47.1205],[8.019,47.1205],[8.0181,47.1303],[8.0052,47.1303],[8.004,47.1205]]]},\"properties\":{\"name\":\"Seefeld\",\"population\":3150,\"households\":1490,\"zone\":\"residential\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[8.019,47.1205],[8.033,47.12],[8.0342,47.131],[8.0181,47.1303],[8.019,47.1205]]]},\"properties\":{\"name\":\"Moosmatt\",\"population\":2280,\"households\":1010,\"zone\":\"residential\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[7.9891,47.131],[8.0052,47.1303],[8.004,47.1425],[7.99,47.142],[7.9891,47.131]]]},\"properties\":{\"name\":\"Bahnhof\",\"population\":3900,\"households\":2050,\"zone\":\"mixed\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[8.0052,47.1303],[8.0181,47.1303],[8.019,47.1425],[8.004,47.1425],[8.0052,47.1303]]]},\"properties\":{\"name\":\"Industrie Nord\",\"population\":640,\"households\":210,\"zone\":\"industrial\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[8.0181,47.1303],[8.0342,47.131],[8.033,47.142],[8.019,47.1425],[8.0181,47.1303]]]},\"properties\":{\"name\":\"Rebhalde\",\"population\":1720,\"households\":760,\"zone\":\"residential\"}}]}"
                  }
                },
                "example2": {
                  "summary": "Tram line length in miles",
                  "value": {
                    "data": "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"geometry\":{\"type\":\"LineString\",\"coordinates\":[[7.992,47.1215],[7.999,47.126],[8.006,47.129],[8.012,47.1335],[8.018,47.137],[8.025,47.14],[8.031,47.1405]]},\"properties\":{\"name\":\"Line 1\"}}]}",
                    "units": "imperial"
                  }
                },
                "example3": {
                  "summary": "A WKT triangle of about 76 hectares",
                  "value": {
                    "data": "POLYGON ((8 47, 8.0132 47, 8.0066 47.0136, 8 47))"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GiselaAreaLengthResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/workflows": {
      "get": {
        "operationId": "listWorkflows",
        "summary": "Multi-tool workflows",
        "responses": {
          "200": {
            "description": "Workflow list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "GiselaReprojectInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "data": {
            "title": "Data",
            "description": "GeoJSON, TopoJSON, KML, GPX, CSV (lat/lon, x/y or a WKT column) or WKT lines. Or upload a file below.",
            "type": "string",
            "maxLength": 5000000,
            "default": ""
          },
          "file": {
            "title": "File (optional)",
            "description": "Used instead of the pasted text. Shapefiles: put .shp, .dbf and .prj into one ZIP. Upload as {filename, contentType?, contentBase64}. Max 19531 KiB. Accepts .geojson,.json,.topojson,.kml,.kmz,.gpx,.csv,.txt,.wkt,.zip.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "from": {
            "title": "Coordinate system of the data",
            "description": "“auto” reads it from the file (.prj, GeoJSON crs); otherwise an EPSG code such as 2056, 25832 or 27700. Without information the data is read as WGS 84 longitude/latitude.",
            "type": "string",
            "maxLength": 20,
            "default": "auto"
          },
          "to": {
            "title": "Convert to",
            "description": "Other zones: type the code below.",
            "type": "string",
            "enum": [
              "EPSG:4326",
              "EPSG:4258",
              "EPSG:3857",
              "EPSG:3035",
              "EPSG:2056",
              "EPSG:21781",
              "EPSG:27700",
              "EPSG:31466",
              "EPSG:31467",
              "EPSG:31468",
              "EPSG:31469",
              "EPSG:25831",
              "EPSG:25832",
              "EPSG:25833"
            ],
            "default": "EPSG:4326"
          },
          "toOther": {
            "title": "Or another EPSG code",
            "description": "For example 32633 (WGS 84 / UTM 33N) or 25831. Overrides the list when filled.",
            "type": "string",
            "maxLength": 20,
            "default": ""
          },
          "format": {
            "title": "Output format",
            "type": "string",
            "enum": [
              "geojson",
              "csv",
              "wkt"
            ],
            "default": "geojson"
          }
        },
        "required": []
      },
      "GiselaReprojectResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object"
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "GiselaBufferInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "data": {
            "title": "Data",
            "description": "GeoJSON, TopoJSON, KML, GPX, CSV (lat/lon, x/y or a WKT column) or WKT lines. Or upload a file below.",
            "type": "string",
            "maxLength": 5000000,
            "default": ""
          },
          "file": {
            "title": "File (optional)",
            "description": "Used instead of the pasted text. Shapefiles: put .shp, .dbf and .prj into one ZIP. Upload as {filename, contentType?, contentBase64}. Max 19531 KiB. Accepts .geojson,.json,.topojson,.kml,.kmz,.gpx,.csv,.txt,.wkt,.zip.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "from": {
            "title": "Coordinate system of the data",
            "description": "“auto” reads it from the file (.prj, GeoJSON crs); otherwise an EPSG code such as 2056, 25832 or 27700. Without information the data is read as WGS 84 longitude/latitude.",
            "type": "string",
            "maxLength": 20,
            "default": "auto"
          },
          "distance": {
            "title": "Distance (metres)",
            "description": "Negative values shrink polygons.",
            "type": "number",
            "minimum": -100000,
            "maximum": 1000000,
            "default": 300,
            "x-unit": "m"
          },
          "segments": {
            "title": "Segments per circle",
            "description": "More segments = rounder curves, bigger files.",
            "type": "integer",
            "minimum": 8,
            "maximum": 128,
            "default": 32
          },
          "dissolve": {
            "title": "Merge overlapping zones into one",
            "type": "boolean",
            "default": false
          }
        },
        "required": []
      },
      "GiselaBufferResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object"
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "GiselaShapefileToGeojsonInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "file": {
            "title": "Shapefile (ZIP)",
            "description": "A ZIP with at least the .shp file; .dbf (attributes), .prj (coordinate system) and .cpg (text encoding) are read when present. Upload as {filename, contentType?, contentBase64}. Max 19531 KiB. Accepts .zip,application/zip.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "from": {
            "title": "Coordinate system of the shapefile",
            "description": "“auto” = from the .prj file. Without a .prj the coordinates are read as WGS 84 unless you give an EPSG code.",
            "type": "string",
            "maxLength": 20,
            "default": "auto"
          },
          "to": {
            "title": "Write GeoJSON in",
            "description": "RFC 7946 GeoJSON is WGS 84; other systems are written with the older “crs” member.",
            "type": "string",
            "enum": [
              "EPSG:4326",
              "EPSG:4258",
              "EPSG:3857",
              "EPSG:3035",
              "EPSG:2056",
              "EPSG:21781",
              "EPSG:27700",
              "EPSG:31466",
              "EPSG:31467",
              "EPSG:31468",
              "EPSG:31469",
              "EPSG:25831",
              "EPSG:25832",
              "EPSG:25833"
            ],
            "default": "EPSG:4326"
          }
        },
        "required": []
      },
      "GiselaShapefileToGeojsonResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object"
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "GiselaAreaLengthInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "data": {
            "title": "Data",
            "description": "GeoJSON, TopoJSON, KML, GPX, CSV (lat/lon, x/y or a WKT column) or WKT lines. Or upload a file below.",
            "type": "string",
            "maxLength": 5000000,
            "default": ""
          },
          "file": {
            "title": "File (optional)",
            "description": "Used instead of the pasted text. Shapefiles: put .shp, .dbf and .prj into one ZIP. Upload as {filename, contentType?, contentBase64}. Max 19531 KiB. Accepts .geojson,.json,.topojson,.kml,.kmz,.gpx,.csv,.txt,.wkt,.zip.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "from": {
            "title": "Coordinate system of the data",
            "description": "“auto” reads it from the file (.prj, GeoJSON crs); otherwise an EPSG code such as 2056, 25832 or 27700. Without information the data is read as WGS 84 longitude/latitude.",
            "type": "string",
            "maxLength": 20,
            "default": "auto"
          },
          "units": {
            "title": "Units",
            "type": "string",
            "enum": [
              "metric",
              "imperial"
            ],
            "default": "metric"
          }
        },
        "required": []
      },
      "GiselaAreaLengthResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object"
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}