{
  "openapi": "3.1.0",
  "info": {
    "title": "IsoGentiX Flora Portal public API",
    "version": "1.0.0",
    "summary": "Read the CC BY 4.0 Flora record without signing in.",
    "description": "National plant checklists for Madagascar and nine other floras, reconciled to the World Checklist of Vascular Plants. Every response carries layer, license, attribution and provenance fields; cite with the attribution field. Only the Flora record (CC BY 4.0) is served here. Layers IsoGentiX generates (genomic, chemical, site-assessment) are not, and fall under https://isogentix.com/policies/data-ip-licensing-ethics/. No coordinates are returned; locality-sensitive species (CITES-listed or IUCN threatened) have their regions withheld and are never listed in site queries. Rate-limited per IP; HTTP 429 means slow down. An MCP server over the same functions is at /public/mcp (Streamable HTTP, stateless).",
    "contact": {"name": "IsoGentiX", "email": "info@isogentix.com", "url": "https://isogentix.com/"},
    "license": {"name": "CC BY 4.0 (Flora record data)", "identifier": "CC-BY-4.0"}
  },
  "servers": [{"url": "https://portal.isogentix.com"}],
  "paths": {
    "/public/counts": {
      "get": {
        "summary": "Headline counts with definitions",
        "description": "Live figures for Madagascar and totals and per-flora figures for all ten floras, with generated_at, definitions and licence fields. Cached for 15 minutes.",
        "operationId": "getCounts",
        "responses": {"200": {"description": "Counts", "content": {"application/json": {"schema": {"type": "object"}}}}}
      }
    },
    "/public/datasets": {
      "get": {
        "summary": "National flora datasets (HTML)",
        "description": "Readable-without-JavaScript catalogue page with schema.org DataCatalog JSON-LD.",
        "operationId": "listDatasets",
        "responses": {"200": {"description": "HTML page", "content": {"text/html": {}}}}
      }
    },
    "/public/datasets/{cc}": {
      "get": {
        "summary": "One flora's Dataset page (HTML)",
        "description": "Live counts, coverage, last refresh and licence, with schema.org Dataset JSON-LD.",
        "operationId": "getDataset",
        "parameters": [{"$ref": "#/components/parameters/cc"}],
        "responses": {"200": {"description": "HTML page", "content": {"text/html": {}}}, "404": {"description": "Unknown flora"}}
      }
    },
    "/public/species": {
      "get": {
        "summary": "Search species",
        "operationId": "searchSpecies",
        "parameters": [
          {"name": "q", "in": "query", "required": true, "description": "2 to 100 characters: scientific name, genus, family or common name", "schema": {"type": "string", "minLength": 2, "maxLength": 100}},
          {"name": "country", "in": "query", "description": "Flora code, default mg", "schema": {"$ref": "#/components/schemas/Country"}},
          {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 50, "default": 20}},
          {"name": "offset", "in": "query", "schema": {"type": "integer", "minimum": 0, "default": 0}}
        ],
        "responses": {
          "200": {"description": "Matching species", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SearchResult"}}}},
          "400": {"$ref": "#/components/responses/Problem"},
          "429": {"$ref": "#/components/responses/Problem"}
        }
      }
    },
    "/public/species/{ref}": {
      "get": {
        "summary": "One species' public record",
        "operationId": "getSpecies",
        "parameters": [{"name": "ref", "in": "path", "required": true, "description": "IGX reference, e.g. IGX-MG-0000756", "schema": {"type": "string", "pattern": "^IGX-[A-Za-z]{2}-[0-9]+$"}}],
        "responses": {
          "200": {"description": "Species record", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Species"}}}},
          "404": {"$ref": "#/components/responses/Problem"},
          "429": {"$ref": "#/components/responses/Problem"}
        }
      }
    },
    "/public/site-query": {
      "post": {
        "summary": "Species recorded inside a polygon (Madagascar)",
        "description": "Live GBIF records inside one polygon, annotated with the IsoGentiX checklist. Names and counts only; sensitive species never listed. One query per 10 seconds per IP.",
        "operationId": "siteQuery",
        "requestBody": {"required": true, "content": {"application/json": {"schema": {
          "type": "object",
          "properties": {
            "country": {"$ref": "#/components/schemas/Country"},
            "geometry": {"type": "object", "description": "GeoJSON Polygon (or a Feature holding one), coordinates as [lng, lat]"},
            "polygon": {"type": "array", "description": "Alternative: a bare ring of [lng, lat] pairs", "items": {"type": "array", "items": {"type": "number"}, "minItems": 2, "maxItems": 2}}
          }
        }, "example": {"country": "MG", "geometry": {"type": "Polygon", "coordinates": [[[46.6, -24.9], [46.9, -24.9], [46.9, -24.6], [46.6, -24.6], [46.6, -24.9]]]}}}}},
        "responses": {
          "200": {"description": "Species list", "content": {"application/json": {"schema": {"type": "object"}}}},
          "400": {"$ref": "#/components/responses/Problem"},
          "429": {"$ref": "#/components/responses/Problem"},
          "502": {"$ref": "#/components/responses/Problem"}
        }
      }
    },
    "/public/access-request": {
      "post": {
        "summary": "Request access beyond the public tier",
        "description": "Records the request and emails the IsoGentiX team, who reply by email. Grants nothing by itself. Public access needs no request: register free at https://portal.isogentix.com/.",
        "operationId": "requestAccess",
        "requestBody": {"required": true, "content": {"application/json": {"schema": {
          "type": "object",
          "required": ["name", "email", "purpose"],
          "properties": {
            "name": {"type": "string", "maxLength": 120},
            "organisation": {"type": "string", "maxLength": 160},
            "email": {"type": "string", "format": "email"},
            "purpose": {"type": "string", "minLength": 10, "maxLength": 2000}
          }
        }}}},
        "responses": {"201": {"description": "Request received"}, "400": {"$ref": "#/components/responses/Problem"}, "429": {"$ref": "#/components/responses/Problem"}}
      }
    },
    "/public/mcp": {
      "post": {
        "summary": "MCP server (Streamable HTTP, stateless)",
        "description": "Model Context Protocol endpoint. POST one JSON-RPC 2.0 message per request. Tools: search_species, get_species, site_query, get_counts, request_access.",
        "operationId": "mcp",
        "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object"}}}},
        "responses": {"200": {"description": "JSON-RPC response"}, "202": {"description": "Notification accepted"}}
      }
    }
  },
  "components": {
    "parameters": {
      "cc": {"name": "cc", "in": "path", "required": true, "schema": {"$ref": "#/components/schemas/Country"}}
    },
    "schemas": {
      "Country": {"type": "string", "enum": ["mg", "mu", "mv", "sc", "nc", "fj", "re", "km", "so", "ec", "MG", "MU", "MV", "SC", "NC", "FJ", "RE", "KM", "SO", "EC"]},
      "Licence": {
        "type": "object",
        "properties": {
          "layer": {"type": "string", "const": "flora_record"},
          "license": {"type": "string", "format": "uri"},
          "attribution": {"type": "string"},
          "terms_for_other_layers": {"type": "string", "format": "uri"},
          "provenance": {"type": "array", "items": {"type": "object", "properties": {"source": {"type": "string"}, "url": {"type": "string", "format": "uri"}}}}
        }
      },
      "SpeciesSummary": {
        "type": "object",
        "properties": {
          "ref": {"type": "string"}, "name": {"type": "string"}, "authorship": {"type": ["string", "null"]},
          "family": {"type": ["string", "null"]}, "genus": {"type": ["string", "null"]}, "rank": {"type": ["string", "null"]},
          "country": {"type": "string"}, "endemic": {"type": ["boolean", "null"]},
          "iucn_category": {"type": ["object", "null"], "properties": {"code": {"type": "string"}, "label": {"type": "string"}}},
          "cites_appendix": {"type": ["string", "null"]},
          "genome_assembly": {"type": ["object", "null"], "properties": {"level": {"type": "string"}, "repository": {"type": "string"}}},
          "portal_url": {"type": "string", "format": "uri"}, "api_url": {"type": "string", "format": "uri"}
        }
      },
      "SearchResult": {
        "allOf": [{"$ref": "#/components/schemas/Licence"}, {"type": "object", "properties": {
          "query": {"type": "string"}, "country": {"type": "string"}, "count": {"type": "integer"}, "shown": {"type": "integer"},
          "results": {"type": "array", "items": {"$ref": "#/components/schemas/SpeciesSummary"}}
        }}]
      },
      "Species": {
        "allOf": [{"$ref": "#/components/schemas/Licence"}, {"$ref": "#/components/schemas/SpeciesSummary"}, {"type": "object", "properties": {
          "scientific_name": {"type": ["string", "null"]}, "taxonomic_status": {"type": ["string", "null"]},
          "native_range": {"type": ["array", "null"], "items": {"type": "string"}},
          "eu_annex": {"type": ["string", "null"]}, "name_published_year": {"type": ["integer", "null"]},
          "common_names": {"type": "array"}, "locality_sensitive": {"type": "boolean"},
          "regions": {"type": ["array", "null"], "items": {"type": "string"}}, "regions_note": {"type": "string"}
        }}]
      }
    },
    "responses": {
      "Problem": {"description": "RFC 9457 problem details", "content": {"application/problem+json": {"schema": {"type": "object"}}}}
    }
  }
}