Koskamo

inaturalist-mcp-server

An MCP server that provides tools to search iNaturalist's 387M+ georeferenced citizen-science observations. It allows agents to resolve names, find places, search sightings, fetch observation details with identification threads, rank taxa by area, chart phenology, and find similar species. It supports STDIO and Streamable HTTP transports and requires no API key.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

inaturalist-mcp-server logo, by cyanheadsCommunity listingStreamable HTTPNo sign-inEndpoint checked 2026-11-07Published by cyanheads
MCP endpoint (Streamable HTTP)
https://inaturalist.caseyjhand.com/mcp
Vendor documentation

What its tools do

10 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

10 of 10 have a description · 10 of 10 declare behavior hints · 10 of 10 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Search wildlife sightings by area, date, and taxon
  • Read identification threads for specific observations
  • Chart phenology data for specific taxa
  • Find look-alike species based on shared identifications

Source and maintenance

Community listingRegistry 0.3.2
Maintenance checked

Protocol and capabilities

Server
inaturalist-mcp-server 0.3.2
MCP protocol negotiated in check
2025-11-25
Tools
10 advertised
Resources
1 advertised
Resource templates
3 advertised
Prompts
0 advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  },
  "logging": {},
  "prompts": {
    "listChanged": true
  },
  "resources": {
    "subscribe": true,
    "listChanged": true
  },
  "extensions": {
    "io.modelcontextprotocol/skills": {
      "directoryRead": true
    }
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Citizen-science wildlife observations from iNaturalist — sightings with photos, community identification threads, phenology, look-alike species, places, and annotations. Keyless and read-only. Identifiers are integers and are not names: resolve an organism name to a taxon id, and an observer or project name to its id, with inaturalist_resolve_name, and a place name or map area to a place id with inaturalist_find_places before searching, since an unrecognised filter value silently returns either the whole global index or nothing at all. Every area filter takes exactly one form — a place_id, a lat/lng/radius triple in kilometres, or a four-corner bounding box. inaturalist_search_observations defaults to research-grade, wild-only records and echoes those defaults in every response. captive false selects wild records only and true selects captive or cultivated records only. Its page parameter walks the first 10,000 results under any ordering; past 10,000, order by id descending and pass each page's next_cursor as cursor — the only ordering a cursor continues. Search returns whole records within its 50,000-byte serialized reply budget; retrieve its ordered deferred IDs through inaturalist_get_observation using the same include before following the full upstream page's continuation. By-id lookup accepts up to 100 submitted IDs by default, attempts the first ten distinct IDs, and returns the remainder as deferred; re-call with those IDs and the same include. Detail strings remain complete without a universal byte ceiling. inaturalist_list_reference decodes every controlled vocabulary the other tools accept. Records carry their own licence: a null license_code means all rights reserved, photo attribution strings are relayed verbatim and must be reproduced with any image, photos are linked rather than proxied, and an obscured coordinate is a locality, not a sighting position. The upstream asks clients to stay under 60 requests a minute, so this server paces its own traffic and may queue a burst.

Tools

10 advertised

inaturalist_list_reference — Inaturalist List Reference
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Look up annotation attributes/values, quality grades, licences, ranks, iconic taxa, and conservation codes before filtering; unknown values can silently return nothing. Conservation codes are the normalised csi filter, distinct from authority-specific taxon status text. With topic controlled_terms and taxon_id, also return observed annotation usage and counts.

inaturalist_list_reference input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "topic"
  ],
  "properties": {
    "topic": {
      "enum": [
        "controlled_terms",
        "quality_grades",
        "licenses",
        "ranks",
        "iconic_taxa",
        "conservation_status_codes"
      ],
      "type": "string",
      "description": "Vocabulary to decode; controlled_terms is live/cached, the rest static."
    },
    "taxon_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Add annotation usage counts, most-used first; only with controlled_terms. Get the id from inaturalist_resolve_name."
    }
  },
  "additionalProperties": false
}
inaturalist_list_reference output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "topic",
        "source",
        "entries"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "taxon_id_not_applicable",
                "unknown_taxon_id"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `taxon_id_not_applicable`: taxon_id was supplied with a topic other than controlled_terms. `unknown_taxon_id`: iNaturalist answered 422 because the taxon_id does not exist. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "topic": {
      "enum": [
        "controlled_terms",
        "quality_grades",
        "licenses",
        "ranks",
        "iconic_taxa",
        "conservation_status_codes"
      ],
      "type": "string",
      "description": "The vocabulary that was decoded."
    },
    "notice": {
      "type": "string",
      "description": "Guidance when the requested taxon has no recorded annotations yet."
    },
    "source": {
      "enum": [
        "upstream",
        "static"
      ],
      "type": "string",
      "description": "\"upstream\" for fetched data, \"static\" for spec-derived tables."
    },
    "entries": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "label"
        ],
        "properties": {
          "id": {
            "type": "number",
            "description": "Numeric attribute id, on the controlled_terms topic. Pass it as term_id."
          },
          "code": {
            "type": "string",
            "description": "Static filter value, e.g. \"needs_id\", \"cc0\", \"Aves\"."
          },
          "label": {
            "type": [
              "string",
              "null"
            ],
            "description": "Human-readable name for the entry."
          },
          "notes": {
            "type": "string",
            "description": "What the entry means, or how it is used, when it needs saying."
          },
          "values": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "label",
                "blocking"
              ],
              "properties": {
                "id": {
                  "type": "number",
                  "description": "Value id. Pass it as term_value_id alongside the attribute id."
                },
                "label": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Human-readable value name, e.g. \"Larva\"."
                },
                "blocking": {
                  "type": "boolean",
                  "description": "True when this value blocks other values of the same attribute."
                }
              },
              "description": "One value of an annotation attribute.",
              "additionalProperties": false
            },
            "description": "Values this annotation attribute accepts, on the controlled_terms topic."
          },
          "multivalued": {
            "type": "boolean",
            "description": "True when one observation may carry several values of this attribute."
          }
        },
        "description": "One vocabulary entry — an annotation attribute, or a static filter code.",
        "additionalProperties": false
      },
      "description": "The vocabulary, one entry per code or attribute."
    },
    "observed_usage": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "attribute",
          "term_id",
          "value",
          "term_value_id",
          "count"
        ],
        "properties": {
          "count": {
            "type": "number",
            "description": "How many observations of this taxon carry the pair."
          },
          "value": {
            "type": [
              "string",
              "null"
            ],
            "description": "Value label; use ids for filtering because labels can repeat."
          },
          "term_id": {
            "type": [
              "number",
              "null"
            ],
            "description": "Attribute id for term_id on search, species counts, or histogram; null when omitted upstream."
          },
          "attribute": {
            "type": [
              "string",
              "null"
            ],
            "description": "Annotation attribute label."
          },
          "term_value_id": {
            "type": [
              "number",
              "null"
            ],
            "description": "Value id for term_value_id alongside term_id; null when omitted upstream."
          }
        },
        "description": "One attribute/value pair and how often it has been recorded.",
        "additionalProperties": false
      },
      "description": "Annotation usage, most-used first; present with taxon_id."
    }
  },
  "additionalProperties": false
}
inaturalist_list_reference annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
inaturalist_resolve_name — Inaturalist Resolve Name
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Resolve organism, place, project, or observer names to identifiers. Taxon lookup matches word starts within a name, not only its beginning; other types use cross-kind search with limited spelling tolerance. Without page, candidates retain relevance order. Explicit taxon pages browse name matches in ascending taxon-ID order; this can differ from autocomplete matching across languages. A miss returns found false with recovery guidance.

inaturalist_resolve_name input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "q"
  ],
  "properties": {
    "q": {
      "type": "string",
      "maxLength": 100,
      "minLength": 1,
      "description": "The name to resolve. Taxon queries match word starts within a name or an exact numeric taxon id; other types match record text with limited spelling tolerance."
    },
    "page": {
      "type": "integer",
      "maximum": 9007199254740991,
      "description": "Optional page for browsing beyond relevance-ranked suggestions. Taxon name pages use ascending taxon-ID order from page 1; numeric taxon IDs have only one page. Keep limit unchanged while paging. page × applied limit must not exceed 10,000.",
      "exclusiveMinimum": 0
    },
    "rank": {
      "enum": [
        "stateofmatter",
        "kingdom",
        "phylum",
        "subphylum",
        "superclass",
        "class",
        "subclass",
        "infraclass",
        "subterclass",
        "superorder",
        "order",
        "suborder",
        "infraorder",
        "parvorder",
        "zoosection",
        "zoosubsection",
        "superfamily",
        "epifamily",
        "family",
        "subfamily",
        "supertribe",
        "tribe",
        "subtribe",
        "genus",
        "genushybrid",
        "subgenus",
        "section",
        "subsection",
        "complex",
        "species",
        "hybrid",
        "subspecies",
        "variety",
        "form",
        "infrahybrid"
      ],
      "type": "string",
      "description": "Restrict taxon candidates to one rank. Honoured only on type \"taxon\" — the cross-kind search has no rank filter."
    },
    "type": {
      "enum": [
        "taxon",
        "place",
        "project",
        "user",
        "any"
      ],
      "type": "string",
      "default": "taxon",
      "description": "Which kind of record to resolve. \"taxon\" uses autocomplete unless an explicit page browses name matches in taxon-ID order; numeric taxon IDs always use autocomplete. Other types use scored cross-kind search, and \"any\" searches all kinds. For place geometry and containment, use inaturalist_find_places."
    },
    "limit": {
      "type": "integer",
      "default": 10,
      "maximum": 9007199254740991,
      "description": "Maximum candidates to return, applied to every type. Ceiling: 30; oversized values are clamped.",
      "exclusiveMinimum": 0
    }
  },
  "additionalProperties": false
}
inaturalist_resolve_name output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "found",
        "candidates",
        "totalCount",
        "truncated",
        "shown",
        "cap"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "number",
      "description": "Applied candidate limit."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "result_window_exceeded",
                "rank_not_applicable"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `result_window_exceeded`: An explicit page multiplied by the applied limit exceeds 10,000. `rank_not_applicable`: rank was supplied with a type other than taxon. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "found": {
      "type": "boolean",
      "description": "True when candidates matched, including an empty explicit page past an existing match set."
    },
    "shown": {
      "type": "number",
      "description": "Number of candidates returned on this slice."
    },
    "notice": {
      "type": "string",
      "description": "Composed clamp, continuation, or empty-page guidance."
    },
    "guidance": {
      "type": "string",
      "description": "Why nothing matched and what to try instead. Present only when found is false — this is the primary result of a miss."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when further matching candidates remain beyond this slice."
    },
    "candidates": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "kind",
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "number",
            "description": "The identifier to pass onward — taxon_id, place_id, project id, or user id."
          },
          "kind": {
            "enum": [
              "taxon",
              "place",
              "project",
              "user"
            ],
            "type": "string",
            "description": "Which record kind this candidate is."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Scientific name on taxa, place name, project title, or an observer’s display name — which falls back to the login when the observer set none."
          },
          "rank": {
            "type": "string",
            "description": "Taxonomic rank, on taxa."
          },
          "slug": {
            "type": "string",
            "description": "URL slug, on places and projects."
          },
          "login": {
            "type": "string",
            "description": "Observer login, on users only — the value inaturalist_get_leaderboard entries and an observation’s observer carry."
          },
          "photo": {
            "type": "object",
            "required": [
              "square_url",
              "attribution",
              "license_code",
              "open"
            ],
            "properties": {
              "open": {
                "type": "boolean",
                "description": "True when served from the open-licence host at fetch time; licences can change."
              },
              "medium_url": {
                "type": "string",
                "description": "Medium image URL; derived from the size path if needed. Absent when no variant is available."
              },
              "square_url": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "75px square variant, exactly as upstream published it. Null when absent."
              },
              "attribution": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Verbatim attribution; reproduce with any use of the image."
              },
              "license_code": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Photo licence code. Null means all rights reserved, independent of the record."
              }
            },
            "description": "Representative photo, when the record carries one.",
            "additionalProperties": false
          },
          "score": {
            "type": "number",
            "description": "Relevance score, on the cross-kind search only. No fixed range — meaningful only relative to other candidates in this response, which are already sorted best match first."
          },
          "common_name": {
            "type": "string",
            "description": "Preferred common name, on taxa."
          },
          "display_name": {
            "type": "string",
            "description": "Place name with its administrative context, on places."
          },
          "matched_term": {
            "type": "string",
            "description": "The name variant that actually matched the query."
          },
          "observations_count": {
            "type": "number",
            "description": "How many observations the record covers."
          }
        },
        "description": "One ranked candidate.",
        "additionalProperties": false
      },
      "description": "Candidates in relevance order, or ascending taxon-ID order on explicit taxon name pages."
    },
    "totalCount": {
      "type": "number",
      "description": "Total candidates upstream matched, before the limit was applied."
    }
  },
  "additionalProperties": false
}
inaturalist_resolve_name annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
inaturalist_find_places — Inaturalist Find Places
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Resolve a place name to a place id, or list places covering a map area. Pass q to match a display-name prefix or all analyzed query terms within it, or all four of nelat, nelng, swlat and swlng for a map area — exactly one of the two, never both. Each result carries its bounding box, place type, and containment chain. Upstream serves at most 20 places per list and may omit more.

inaturalist_find_places input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "q": {
      "type": "string",
      "maxLength": 100,
      "minLength": 1,
      "description": "Place text to search. Matches the beginning of the display name or all analyzed query terms within it. Try whole words or the beginning of the official name. Mutually exclusive with the bounding box."
    },
    "nelat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "North-east corner latitude of the map area, at or north of swlat. All four corners or none."
    },
    "nelng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "North-east corner longitude of the map area. All four corners or none. West of swlng is accepted: it describes a box crossing the antimeridian."
    },
    "swlat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "South-west corner latitude of the map area. All four corners or none."
    },
    "swlng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "South-west corner longitude of the map area. All four corners or none."
    },
    "per_page": {
      "type": "integer",
      "default": 10,
      "maximum": 9007199254740991,
      "description": "Maximum places per list, applied to name queries and to standard and community lists separately on map queries. Served ceiling: 20; requests above it are reduced to 20. Positive safe integer requests are accepted.",
      "exclusiveMinimum": 0
    }
  },
  "additionalProperties": false
}
inaturalist_find_places output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "totalCount",
        "truncated",
        "shown",
        "cap"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "number",
      "description": "The applied per_page on name queries, or twice the applied per_page on map queries where it bounds each list separately."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "invalid_geography"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `invalid_geography`: Neither q nor a complete bounding box was given, both were, or the box has nelat south of swlat. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "shown": {
      "type": "number",
      "description": "How many places this response carries."
    },
    "notice": {
      "type": "string",
      "description": "Guidance when nothing matched, or when the page capped the result set."
    },
    "places": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "name",
          "display_name",
          "place_type",
          "admin_level",
          "bbox",
          "ancestor_place_ids",
          "location",
          "slug"
        ],
        "properties": {
          "id": {
            "type": "number",
            "description": "Place id — pass it as place_id to any area-scoped tool."
          },
          "bbox": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "swlat",
                  "swlng",
                  "nelat",
                  "nelng"
                ],
                "properties": {
                  "nelat": {
                    "type": "number",
                    "description": "North-east corner latitude."
                  },
                  "nelng": {
                    "type": "number",
                    "description": "North-east corner longitude."
                  },
                  "swlat": {
                    "type": "number",
                    "description": "South-west corner latitude."
                  },
                  "swlng": {
                    "type": "number",
                    "description": "South-west corner longitude."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "Corner pair computed from the place’s bounding polygon, ready to pass as a bounding box. Relayed as computed: a place crossing the antimeridian genuinely has a degenerate box upstream and it is not repaired here."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Place name as iNaturalist records it."
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "URL slug. The place record publishes no URL of its own."
          },
          "location": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "lat",
                  "lng"
                ],
                "properties": {
                  "lat": {
                    "type": "number",
                    "description": "Centre latitude."
                  },
                  "lng": {
                    "type": "number",
                    "description": "Centre longitude."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "Centre point of the place."
          },
          "place_type": {
            "type": [
              "number",
              "null"
            ],
            "description": "Raw place-type integer. iNaturalist publishes no code table for it, so no label is invented — display_name carries the meaning."
          },
          "admin_level": {
            "type": [
              "number",
              "null"
            ],
            "description": "Raw administrative-level integer. No published code table; often null."
          },
          "display_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Place name with its administrative context, e.g. \"Seattle CCD, US, WA\"."
          },
          "ancestor_place_ids": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "description": "Containment chain, outermost first. Empty when upstream records none."
          }
        },
        "description": "One place, with the bounding box and containment chain an area search needs.",
        "additionalProperties": false
      },
      "description": "Place-name matches. Present on the q arm."
    },
    "standard": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "name",
          "display_name",
          "place_type",
          "admin_level",
          "bbox",
          "ancestor_place_ids",
          "location",
          "slug"
        ],
        "properties": {
          "id": {
            "type": "number",
            "description": "Place id — pass it as place_id to any area-scoped tool."
          },
          "bbox": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "swlat",
                  "swlng",
                  "nelat",
                  "nelng"
                ],
                "properties": {
                  "nelat": {
                    "type": "number",
                    "description": "North-east corner latitude."
                  },
                  "nelng": {
                    "type": "number",
                    "description": "North-east corner longitude."
                  },
                  "swlat": {
                    "type": "number",
                    "description": "South-west corner latitude."
                  },
                  "swlng": {
                    "type": "number",
                    "description": "South-west corner longitude."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "Corner pair computed from the place’s bounding polygon, ready to pass as a bounding box. Relayed as computed: a place crossing the antimeridian genuinely has a degenerate box upstream and it is not repaired here."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Place name as iNaturalist records it."
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "URL slug. The place record publishes no URL of its own."
          },
          "location": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "lat",
                  "lng"
                ],
                "properties": {
                  "lat": {
                    "type": "number",
                    "description": "Centre latitude."
                  },
                  "lng": {
                    "type": "number",
                    "description": "Centre longitude."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "Centre point of the place."
          },
          "place_type": {
            "type": [
              "number",
              "null"
            ],
            "description": "Raw place-type integer. iNaturalist publishes no code table for it, so no label is invented — display_name carries the meaning."
          },
          "admin_level": {
            "type": [
              "number",
              "null"
            ],
            "description": "Raw administrative-level integer. No published code table; often null."
          },
          "display_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Place name with its administrative context, e.g. \"Seattle CCD, US, WA\"."
          },
          "ancestor_place_ids": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "description": "Containment chain, outermost first. Empty when upstream records none."
          }
        },
        "description": "One place, with the bounding box and containment chain an area search needs.",
        "additionalProperties": false
      },
      "description": "Curated administrative places covering the area. Present on the bounding-box arm."
    },
    "community": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "name",
          "display_name",
          "place_type",
          "admin_level",
          "bbox",
          "ancestor_place_ids",
          "location",
          "slug"
        ],
        "properties": {
          "id": {
            "type": "number",
            "description": "Place id — pass it as place_id to any area-scoped tool."
          },
          "bbox": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "swlat",
                  "swlng",
                  "nelat",
                  "nelng"
                ],
                "properties": {
                  "nelat": {
                    "type": "number",
                    "description": "North-east corner latitude."
                  },
                  "nelng": {
                    "type": "number",
                    "description": "North-east corner longitude."
                  },
                  "swlat": {
                    "type": "number",
                    "description": "South-west corner latitude."
                  },
                  "swlng": {
                    "type": "number",
                    "description": "South-west corner longitude."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "Corner pair computed from the place’s bounding polygon, ready to pass as a bounding box. Relayed as computed: a place crossing the antimeridian genuinely has a degenerate box upstream and it is not repaired here."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Place name as iNaturalist records it."
          },
          "slug": {
            "type": [
              "string",
              "null"
            ],
            "description": "URL slug. The place record publishes no URL of its own."
          },
          "location": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "lat",
                  "lng"
                ],
                "properties": {
                  "lat": {
                    "type": "number",
                    "description": "Centre latitude."
                  },
                  "lng": {
                    "type": "number",
                    "description": "Centre longitude."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "Centre point of the place."
          },
          "place_type": {
            "type": [
              "number",
              "null"
            ],
            "description": "Raw place-type integer. iNaturalist publishes no code table for it, so no label is invented — display_name carries the meaning."
          },
          "admin_level": {
            "type": [
              "number",
              "null"
            ],
            "description": "Raw administrative-level integer. No published code table; often null."
          },
          "display_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Place name with its administrative context, e.g. \"Seattle CCD, US, WA\"."
          },
          "ancestor_place_ids": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "description": "Containment chain, outermost first. Empty when upstream records none."
          }
        },
        "description": "One place, with the bounding box and containment chain an area search needs.",
        "additionalProperties": false
      },
      "description": "Member-created places covering the area. Present on the bounding-box arm."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when more places may exist than were returned — on the bounding-box arm, when the standard or community list reached per_page."
    },
    "totalCount": {
      "type": "number",
      "description": "Places upstream reports. On name queries, every match before the applied size; on map queries, only returned standard plus community places, not an exhaustive match count."
    }
  },
  "additionalProperties": false
}
inaturalist_find_places annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
inaturalist_search_observations — Inaturalist Search Observations
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Search georeferenced wildlife sightings by area, date, taxon, quality grade, annotation, conservation status, observer, project, and licence. Returns a projected record per sighting with coordinates, licence, first photo, and identification counts. An area is given in exactly one form — place_id, the lat/lng/radius triple in kilometres, or a four-corner bounding box — and defaults to research-grade, wild-only records, which are echoed back on every call. Identifications and comments are deliberately not expandable here (one thread is 28 KB); fetch them for specific records with inaturalist_get_observation. page walks the first 10,000 results under any ordering; past 10,000, order by id descending (order_by "id", order "desc") and pass each page’s next_cursor as cursor.

inaturalist_search_observations input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "q": {
      "type": "string",
      "minLength": 1,
      "description": "Free text matched across observation properties."
    },
    "d1": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2."
    },
    "d2": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Latest observation date, YYYY-MM-DD. Inclusive."
    },
    "csi": {
      "type": "array",
      "items": {
        "enum": [
          "LC",
          "NT",
          "VU",
          "EN",
          "CR",
          "EW",
          "EX"
        ],
        "type": "string"
      },
      "description": "IUCN-normalised conservation status codes. Matches global statuses plus statuses listed at exactly place_id, excluding ancestor-place listings; decode with inaturalist_list_reference topic conservation_status_codes."
    },
    "lat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius."
    },
    "lng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius."
    },
    "page": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Page number within the first 10,000 results, under any ordering. Defaults to 1. Mutually exclusive with cursor."
    },
    "hrank": {
      "enum": [
        "stateofmatter",
        "kingdom",
        "phylum",
        "subphylum",
        "superclass",
        "class",
        "subclass",
        "infraclass",
        "subterclass",
        "superorder",
        "order",
        "suborder",
        "infraorder",
        "parvorder",
        "zoosection",
        "zoosubsection",
        "superfamily",
        "epifamily",
        "family",
        "subfamily",
        "supertribe",
        "tribe",
        "subtribe",
        "genus",
        "genushybrid",
        "subgenus",
        "section",
        "subsection",
        "complex",
        "species",
        "hybrid",
        "subspecies",
        "variety",
        "form",
        "infrahybrid"
      ],
      "type": "string",
      "description": "Highest (coarsest) identification rank level to accept. Must be at or above lrank."
    },
    "lrank": {
      "enum": [
        "stateofmatter",
        "kingdom",
        "phylum",
        "subphylum",
        "superclass",
        "class",
        "subclass",
        "infraclass",
        "subterclass",
        "superorder",
        "order",
        "suborder",
        "infraorder",
        "parvorder",
        "zoosection",
        "zoosubsection",
        "superfamily",
        "epifamily",
        "family",
        "subfamily",
        "supertribe",
        "tribe",
        "subtribe",
        "genus",
        "genushybrid",
        "subgenus",
        "section",
        "subsection",
        "complex",
        "species",
        "hybrid",
        "subspecies",
        "variety",
        "form",
        "infrahybrid"
      ],
      "type": "string",
      "description": "Lowest (finest) identification rank level to accept. Equal bounds select a level, including ranks sharing that level such as species and hybrid."
    },
    "month": {
      "type": "array",
      "items": {
        "type": "integer",
        "maximum": 12,
        "minimum": 1
      },
      "description": "Observed calendar months, 1–12, matched as alternatives."
    },
    "nelat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none."
    },
    "nelng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "North-east corner longitude of the bounding box. All four corners or none. West of swlng is accepted: it describes a box crossing the antimeridian."
    },
    "order": {
      "enum": [
        "asc",
        "desc"
      ],
      "type": "string",
      "default": "desc",
      "description": "Sort direction."
    },
    "swlat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "South-west corner latitude of the bounding box. All four corners or none."
    },
    "swlng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "South-west corner longitude of the bounding box. All four corners or none."
    },
    "cursor": {
      "type": "string",
      "pattern": "^[1-9]\\d*$",
      "description": "next_cursor from a previous id-descending page, to continue past the 10,000-result window — a positive integer observation id, sent upstream as id_below. Mutually exclusive with page, and forces order_by \"id\", order \"desc\"."
    },
    "native": {
      "type": "boolean",
      "description": "Filter the observation’s indexed taxon as native at its location."
    },
    "radius": {
      "type": "number",
      "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice."
    },
    "sounds": {
      "type": "boolean",
      "description": "True selects observations with sounds; false selects those without. Omit for either. Use include: [\"sounds\"] to expand sound metadata; no media is downloaded."
    },
    "captive": {
      "type": "boolean",
      "default": false,
      "description": "True returns captive and cultivated records only — zoo animals, garden plantings; false returns wild records only. Defaults to false."
    },
    "endemic": {
      "type": "boolean",
      "description": "Filter the observation’s indexed taxon as endemic at its location."
    },
    "include": {
      "type": "array",
      "items": {
        "enum": [
          "photos",
          "annotations",
          "sounds"
        ],
        "type": "string"
      },
      "description": "Embedded arrays to expand per record. Check photo_count and sound_count first — expanding costs context."
    },
    "license": {
      "type": "array",
      "items": {
        "enum": [
          "cc-by",
          "cc-by-nc",
          "cc-by-nd",
          "cc-by-sa",
          "cc-by-nc-nd",
          "cc-by-nc-sa",
          "cc0"
        ],
        "type": "string"
      },
      "description": "Restrict to records whose own license_code is one of these, e.g. [\"cc-by\",\"cc0\"] for reuse with attribution only. Decode the codes with inaturalist_list_reference topic licenses; all-rights-reserved records have no code to pass."
    },
    "term_id": {
      "type": "array",
      "items": {
        "type": "integer",
        "maximum": 9007199254740991,
        "minimum": 1
      },
      "description": "Annotation attribute ids, from inaturalist_list_reference topic controlled_terms — e.g. 1 for Life Stage. Multiple ids match any one annotation, not all annotations; arrays are membership sets, not positional pairs."
    },
    "user_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login."
    },
    "licensed": {
      "type": "boolean",
      "description": "Restrict to records whose own license_code is not null — any licence, NonCommercial and NoDerivatives variants included. For specific licences, use license."
    },
    "order_by": {
      "enum": [
        "created_at",
        "geo_score",
        "id",
        "observed_on",
        "random",
        "species_guess",
        "updated_at",
        "votes"
      ],
      "type": "string",
      "default": "observed_on",
      "description": "Sort field. Set \"id\" with order \"desc\" to walk past 10,000 results: that is the one ordering next_cursor continues, so it is the only one that issues a next_cursor. A cursor forces it."
    },
    "per_page": {
      "type": "integer",
      "default": 10,
      "maximum": 9007199254740991,
      "description": "Records fetched per page. Complete records may be deferred to keep the response within its byte budget; retrieve deferred ids through inaturalist_get_observation with the same include values. Ceiling: 25; oversized values are clamped.",
      "exclusiveMinimum": 0
    },
    "place_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Numeric iNaturalist place id from inaturalist_find_places. Mutually exclusive with the lat/lng/radius triple and the bounding box. A non-numeric value answers HTTP 500 upstream."
    },
    "taxon_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name."
    },
    "acc_below": {
      "type": "number",
      "maximum": 2147483647,
      "description": "Measured positional accuracy strictly below this positive threshold in metres, up to 2147483647; fractional metres are accepted. Records without measured accuracy are excluded.",
      "exclusiveMinimum": 0
    },
    "search_on": {
      "enum": [
        "names",
        "tags",
        "description",
        "place"
      ],
      "type": "string",
      "description": "Narrow what q matches against. Requires q."
    },
    "created_d1": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Earliest upload date, YYYY-MM-DD. Inclusive. Must be on or before created_d2."
    },
    "created_d2": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Latest upload date, YYYY-MM-DD. Inclusive."
    },
    "introduced": {
      "type": "boolean",
      "description": "Filter the observation’s indexed taxon as introduced at its location."
    },
    "project_id": {
      "type": "integer",
      "maximum": 2147483647,
      "minimum": 1,
      "description": "Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project."
    },
    "threatened": {
      "type": "boolean",
      "description": "Filter the observation’s indexed taxon as threatened at its location."
    },
    "user_login": {
      "type": "string",
      "minLength": 1,
      "description": "Restrict to one observer, by login — the login on an inaturalist_resolve_name user candidate, a leaderboard entry, or an observation’s observer. Mutually exclusive with user_id."
    },
    "iconic_taxa": {
      "type": "array",
      "items": {
        "enum": [
          "Actinopterygii",
          "Amphibia",
          "Animalia",
          "Arachnida",
          "Aves",
          "Chromista",
          "Fungi",
          "Insecta",
          "Mammalia",
          "Mollusca",
          "Plantae",
          "Protozoa",
          "Reptilia",
          "unknown"
        ],
        "type": "string"
      },
      "description": "Broad organism groups, by their scientific iconic-taxon name. A common-name value such as \"Birds\" matches nothing upstream, so only the listed values are accepted."
    },
    "obscuration": {
      "type": "array",
      "items": {
        "enum": [
          "obscured",
          "private",
          "none"
        ],
        "type": "string"
      },
      "description": "Observer or taxon geoprivacy values to include; none requires both to be open or unset. Multiple values match alternatives."
    },
    "photo_license": {
      "type": "array",
      "items": {
        "enum": [
          "cc-by",
          "cc-by-nc",
          "cc-by-nd",
          "cc-by-sa",
          "cc-by-nc-nd",
          "cc-by-nc-sa",
          "cc0"
        ],
        "type": "string"
      },
      "description": "Restrict to records carrying at least one photo under one of these licence codes. Matched independently of the record’s own license_code, so check each photo’s license_code before reusing it."
    },
    "quality_grade": {
      "type": "array",
      "items": {
        "enum": [
          "research",
          "needs_id",
          "casual"
        ],
        "type": "string"
      },
      "default": [
        "research"
      ],
      "minItems": 1,
      "description": "Identification confidence tiers to include, normalized to unique values in first-appearance order. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence."
    },
    "term_value_id": {
      "type": "array",
      "items": {
        "type": "integer",
        "maximum": 9007199254740991,
        "minimum": 1
      },
      "description": "Annotation value ids, from the same attribute listing — e.g. 6 for Larva. Requires term_id; sent alone it is ignored upstream and the unfiltered corpus comes back. Multiple ids match any one annotation with an attribute in term_id and a value in this set, not both annotations."
    },
    "updated_since": {
      "anyOf": [
        {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        {
          "type": "string",
          "format": "date-time",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
        }
      ],
      "description": "Records updated since this calendar date (YYYY-MM-DD) or ISO datetime with timezone, e.g. 2026-10-30T12:00:00Z."
    },
    "photo_licensed": {
      "type": "boolean",
      "description": "Restrict to records with at least one licensed photo, under any licence. For specific licences, use photo_license."
    },
    "identifications": {
      "enum": [
        "most_agree",
        "some_agree",
        "most_disagree"
      ],
      "type": "string",
      "description": "Filter community identification agreement using one agreement category."
    }
  },
  "additionalProperties": false
}
inaturalist_search_observations output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "total_results",
        "observations",
        "deferred",
        "has_more",
        "applied_filters",
        "truncated",
        "shown",
        "cap"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "number",
      "description": "The per_page that was applied."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "unknown_place_id",
                "invalid_geography",
                "inverted_date_range",
                "inverted_rank_range",
                "result_window_exceeded",
                "conflicting_pagination",
                "unpaired_annotation_value",
                "search_on_without_query",
                "conflicting_observer",
                "unknown_taxon_id",
                "unknown_user",
                "unknown_project_id"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `unknown_place_id`: iNaturalist answered 422 because place_id does not exist. `invalid_geography`: An area was given partially, in two forms at once, with a radius of 0 or less, or with nelat south of swlat. `inverted_date_range`: d1 is after d2, or created_d1 is after created_d2. `inverted_rank_range`: hrank is a finer rank than lrank. `result_window_exceeded`: page multiplied by per_page would reach past the upstream 10,000-result window. `conflicting_pagination`: Both page and cursor were supplied. `unpaired_annotation_value`: term_value_id was supplied without term_id. `search_on_without_query`: search_on was supplied without q. `conflicting_observer`: user_id and user_login were both supplied. `unknown_taxon_id`: iNaturalist answered 422 because the taxon_id does not exist. `unknown_user`: iNaturalist answered 422 because the user_id or user_login names no observer. `unknown_project_id`: iNaturalist answered 422 because the project_id does not exist. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "shown": {
      "type": "number",
      "description": "How many records this page carries."
    },
    "notice": {
      "type": "string",
      "description": "Composed guidance for applied limits, ignored filters, empty pages, deferred ids and pagination."
    },
    "deferred": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "observation_id"
        ],
        "properties": {
          "observation_id": {
            "type": "number",
            "description": "Observation id to retrieve through inaturalist_get_observation with the same include values."
          }
        },
        "description": "One fetched observation deferred for a by-id call.",
        "additionalProperties": false
      },
      "description": "Ordered ids of the fetched-page suffix omitted from observations to meet the response budget. Empty when the whole page fits; independent of has_more."
    },
    "has_more": {
      "type": "boolean",
      "description": "True when the fetched page filled the applied per_page and more records follow, independent of deferred ids. On the page path an exactly full final page is false; under a cursor, where the offset is unknown, every full page is true."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when records were deferred or more pages follow."
    },
    "next_cursor": {
      "type": "string",
      "description": "Pass back as cursor to continue past this page. Present only when has_more is true and the page was ordered by id descending; under any other ordering, raise page instead."
    },
    "observations": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "uuid",
          "url",
          "observed_on",
          "observed_at",
          "created_at",
          "updated_at",
          "taxon",
          "place_guess",
          "coordinate",
          "obscured",
          "geoprivacy",
          "taxon_geoprivacy",
          "quality_grade",
          "license_code",
          "captive",
          "photo",
          "photo_count",
          "sound_count",
          "observer",
          "identifications_count",
          "agreements",
          "disagreements",
          "community_taxon_id"
        ],
        "properties": {
          "id": {
            "type": "number",
            "description": "Observation id. Also the cursor value for deep pagination."
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Canonical iNaturalist page for the record."
          },
          "uuid": {
            "type": [
              "string",
              "null"
            ],
            "description": "Stable UUID, independent of the id sequence."
          },
          "photo": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "square_url",
                  "attribution",
                  "license_code",
                  "open"
                ],
                "properties": {
                  "open": {
                    "type": "boolean",
                    "description": "True when served from the open-licence host at fetch time; licences can change."
                  },
                  "medium_url": {
                    "type": "string",
                    "description": "Medium image URL; derived from the size path if needed. Absent when no variant is available."
                  },
                  "square_url": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "75px square variant, exactly as upstream published it. Null when absent."
                  },
                  "attribution": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Verbatim attribution; reproduce with any use of the image."
                  },
                  "license_code": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Photo licence code. Null means all rights reserved, independent of the record."
                  }
                },
                "description": "A photo with the attribution and licence that must travel with it.",
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "First photo on the record. Null when there are none."
          },
          "taxon": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "id",
                  "name",
                  "rank",
                  "common_name",
                  "iconic_taxon_name"
                ],
                "properties": {
                  "id": {
                    "type": "number",
                    "description": "Taxon id — the identifier every taxon-scoped filter takes."
                  },
                  "name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Scientific name."
                  },
                  "rank": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Taxonomic rank, e.g. \"species\"."
                  },
                  "common_name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Preferred common name, when one is recorded."
                  },
                  "iconic_taxon_name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Broad organism group, e.g. \"Insecta\". Usable as an iconic_taxa filter value."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "Current identification. Null when nobody has identified the record."
          },
          "photos": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "square_url",
                "attribution",
                "license_code",
                "open"
              ],
              "properties": {
                "open": {
                  "type": "boolean",
                  "description": "True when served from the open-licence host at fetch time; licences can change."
                },
                "medium_url": {
                  "type": "string",
                  "description": "Medium image URL; derived from the size path if needed. Absent when no variant is available."
                },
                "square_url": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "75px square variant, exactly as upstream published it. Null when absent."
                },
                "attribution": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Verbatim attribution; reproduce with any use of the image."
                },
                "license_code": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Photo licence code. Null means all rights reserved, independent of the record."
                }
              },
              "description": "A photo with the attribution and licence that must travel with it.",
              "additionalProperties": false
            },
            "description": "Every photo on the record. Present when \"photos\" was included."
          },
          "sounds": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "url",
                "attribution",
                "license_code"
              ],
              "properties": {
                "url": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Audio file URL. Null when upstream published none."
                },
                "attribution": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Attribution string, verbatim."
                },
                "license_code": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Sound licence code. Null means all rights reserved."
                }
              },
              "description": "An audio recording with its attribution and licence.",
              "additionalProperties": false
            },
            "description": "Audio recordings. Present when \"sounds\" was included."
          },
          "captive": {
            "type": "boolean",
            "description": "True for a zoo animal, a garden planting, or other cultivation."
          },
          "obscured": {
            "type": "boolean",
            "description": "True when the true coordinate is withheld; the public point is a locality."
          },
          "observer": {
            "type": [
              "string",
              "null"
            ],
            "description": "Observer login."
          },
          "agreements": {
            "type": "number",
            "description": "How many identifications currently agree with the community taxon."
          },
          "coordinate": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "lat",
                  "lng",
                  "accuracy_m"
                ],
                "properties": {
                  "lat": {
                    "type": "number",
                    "description": "Latitude in decimal degrees."
                  },
                  "lng": {
                    "type": "number",
                    "description": "Longitude in decimal degrees."
                  },
                  "accuracy_m": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "Public accuracy radius, metres. An obscured point is a locality, not a sighting position."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "Public coordinate. Null when the record carries none."
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Record creation timestamp, verbatim from upstream. Null when absent."
          },
          "geoprivacy": {
            "type": [
              "string",
              "null"
            ],
            "description": "Observer-set coordinate privacy: obscured, obscured_private, open, or private."
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Record update timestamp, verbatim from upstream. Null when absent."
          },
          "annotations": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "attribute",
                "value",
                "attribute_id",
                "value_id",
                "by"
              ],
              "properties": {
                "by": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Login of the member who added the annotation."
                },
                "value": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Value label, e.g. \"Larva\"; null for an unknown id."
                },
                "value_id": {
                  "type": "number",
                  "description": "Value id, usable as term_value_id on the search tools."
                },
                "attribute": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Attribute label, e.g. \"Life Stage\"; null for an unknown id."
                },
                "attribute_id": {
                  "type": "number",
                  "description": "Attribute id, usable as term_id on the search tools."
                }
              },
              "description": "One decoded annotation on the record.",
              "additionalProperties": false
            },
            "description": "Decoded annotations. Present when \"annotations\" was included."
          },
          "observed_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Observation timestamp with offset, ISO 8601."
          },
          "observed_on": {
            "type": [
              "string",
              "null"
            ],
            "description": "Observation date, YYYY-MM-DD. Null when the observer recorded no date."
          },
          "photo_count": {
            "type": "number",
            "description": "Photo count; include \"photos\" for every photo."
          },
          "place_guess": {
            "type": [
              "string",
              "null"
            ],
            "description": "Locality text written by the observer. Third-party free text."
          },
          "sound_count": {
            "type": "number",
            "description": "How many audio recordings the record carries."
          },
          "license_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "Licence of the observation record itself. Null means all rights reserved."
          },
          "disagreements": {
            "type": "number",
            "description": "How many identifications currently disagree with the community taxon."
          },
          "quality_grade": {
            "enum": [
              "research",
              "needs_id",
              "casual"
            ],
            "type": "string",
            "description": "Identification confidence tier: research, needs_id, or casual."
          },
          "taxon_geoprivacy": {
            "type": [
              "string",
              "null"
            ],
            "description": "Coordinate privacy applied automatically for a threatened taxon. Same vocabulary."
          },
          "community_taxon_id": {
            "type": [
              "number",
              "null"
            ],
            "description": "Consensus taxon id. Differs from taxon.id while a thread is contested."
          },
          "identifications_count": {
            "type": "number",
            "description": "Tally against the community taxon: agreements + disagreements. Excludes the observer and neutral/withdrawn ids; thread size is identifications_total on inaturalist_get_observation."
          }
        },
        "description": "One complete projected search record, with requested media expansions.",
        "additionalProperties": false
      },
      "description": "The matching sightings, projected."
    },
    "total_results": {
      "type": "number",
      "description": "How many records upstream reports as matching. An estimate over a live index — it drifts between calls seconds apart."
    },
    "applied_filters": {
      "type": "object",
      "required": [
        "quality_grade",
        "captive",
        "order_by",
        "order",
        "ordering_forced_by_cursor"
      ],
      "properties": {
        "order": {
          "type": "string",
          "description": "Sort direction actually sent upstream."
        },
        "captive": {
          "type": "boolean",
          "description": "Captive-only when true, wild-only when false."
        },
        "order_by": {
          "type": "string",
          "description": "Sort field actually sent upstream."
        },
        "quality_grade": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Identification tiers actually searched, normalized to unique values in first-appearance order."
        },
        "ordering_forced_by_cursor": {
          "type": "boolean",
          "description": "True when a cursor overrode the requested ordering."
        }
      },
      "description": "The server-applied defaults and overrides that determine what this answer means.",
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}
inaturalist_search_observations annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
inaturalist_get_observation — Inaturalist Get Observation
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Fetch up to 10 distinct observations by id with their community identification thread — who identified what, whether each identification agrees, and the consensus taxon the community landed on. The whole attempted batch costs one upstream request. Records come back in requested order; remaining distinct ids are deferred for another call with the same include. Missing attempted ids appear in unresolved; the call fails only when nothing resolved and no deferred work remains. Long threads and observation-field lists share a response budget across resolved records — up to 40 entries per array for one record, 4 for a full batch — and every record reports the size of each array beside what it kept.

inaturalist_get_observation input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "observation_id"
  ],
  "properties": {
    "include": {
      "type": "array",
      "items": {
        "enum": [
          "identifications",
          "comments",
          "photos",
          "annotations",
          "sounds"
        ],
        "type": "string"
      },
      "default": [
        "identifications"
      ],
      "description": "Embedded arrays to expand per record. identifications is the default and is what carries the thread; the others cost context, so check photo_count and sound_count first. identifications and comments — like the observation_fields every record carries — share a 40-entry budget across the batch: each record keeps at most 40 ÷ records returned entries per array (never fewer than 4), and reports identifications_total, comments_total, and observation_fields_total beside what it kept — request one id alone for the 40-entry view."
    },
    "observation_id": {
      "type": "array",
      "items": {
        "type": "integer",
        "maximum": 9007199254740991,
        "minimum": 1
      },
      "maxItems": 100,
      "minItems": 1,
      "description": "Observation ids to fetch, 1 to 100 submitted ids. The first 10 distinct ids are attempted; any remaining distinct ids are deferred to another call. Find current ids for an area with inaturalist_search_observations."
    }
  },
  "additionalProperties": false
}
inaturalist_get_observation output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "observations",
        "unresolved",
        "deferred"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "not_found"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `not_found`: None of the attempted ids resolved to an observation and no deferred ids remain. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "notice": {
      "type": "string",
      "description": "Guidance when part of the batch did not resolve, or when a thread or observation-field list was cut to fit the response."
    },
    "deferred": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "observation_id"
        ],
        "properties": {
          "observation_id": {
            "type": "number",
            "description": "An id not attempted in this call."
          }
        },
        "description": "One id to request in a subsequent call.",
        "additionalProperties": false
      },
      "description": "Distinct ids beyond the attempted batch, in requested order. Empty when no work remains."
    },
    "unresolved": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "observation_id"
        ],
        "properties": {
          "observation_id": {
            "type": "number",
            "description": "A requested id upstream returned no record for."
          }
        },
        "description": "One id that did not resolve.",
        "additionalProperties": false
      },
      "description": "Requested ids upstream returned nothing for. They may have been deleted, or never existed."
    },
    "observations": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "uuid",
          "url",
          "observed_on",
          "observed_at",
          "created_at",
          "updated_at",
          "taxon",
          "place_guess",
          "coordinate",
          "obscured",
          "geoprivacy",
          "taxon_geoprivacy",
          "quality_grade",
          "license_code",
          "captive",
          "photo",
          "photo_count",
          "sound_count",
          "observer",
          "identifications_count",
          "agreements",
          "disagreements",
          "community_taxon_id"
        ],
        "properties": {
          "id": {
            "type": "number",
            "description": "Observation id. Also the cursor value for deep pagination."
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Canonical iNaturalist page for the record."
          },
          "uuid": {
            "type": [
              "string",
              "null"
            ],
            "description": "Stable UUID, independent of the id sequence."
          },
          "photo": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "square_url",
                  "attribution",
                  "license_code",
                  "open"
                ],
                "properties": {
                  "open": {
                    "type": "boolean",
                    "description": "True when served from the open-licence host at fetch time; licences can change."
                  },
                  "medium_url": {
                    "type": "string",
                    "description": "Medium image URL; derived from the size path if needed. Absent when no variant is available."
                  },
                  "square_url": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "75px square variant, exactly as upstream published it. Null when absent."
                  },
                  "attribution": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Verbatim attribution; reproduce with any use of the image."
                  },
                  "license_code": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Photo licence code. Null means all rights reserved, independent of the record."
                  }
                },
                "description": "A photo with the attribution and licence that must travel with it.",
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "First photo on the record. Null when there are none."
          },
          "taxon": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "id",
                  "name",
                  "rank",
                  "common_name",
                  "iconic_taxon_name"
                ],
                "properties": {
                  "id": {
                    "type": "number",
                    "description": "Taxon id — the identifier every taxon-scoped filter takes."
                  },
                  "name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Scientific name."
                  },
                  "rank": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Taxonomic rank, e.g. \"species\"."
                  },
                  "common_name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Preferred common name, when one is recorded."
                  },
                  "iconic_taxon_name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Broad organism group, e.g. \"Insecta\". Usable as an iconic_taxa filter value."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "Current identification. Null when nobody has identified the record."
          },
          "photos": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "square_url",
                "attribution",
                "license_code",
                "open"
              ],
              "properties": {
                "open": {
                  "type": "boolean",
                  "description": "True when served from the open-licence host at fetch time; licences can change."
                },
                "medium_url": {
                  "type": "string",
                  "description": "Medium image URL; derived from the size path if needed. Absent when no variant is available."
                },
                "square_url": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "75px square variant, exactly as upstream published it. Null when absent."
                },
                "attribution": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Verbatim attribution; reproduce with any use of the image."
                },
                "license_code": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Photo licence code. Null means all rights reserved, independent of the record."
                }
              },
              "description": "A photo with the attribution and licence that must travel with it.",
              "additionalProperties": false
            },
            "description": "Every photo on the record. Present when \"photos\" was included."
          },
          "sounds": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "url",
                "attribution",
                "license_code"
              ],
              "properties": {
                "url": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Audio file URL. Null when upstream published none."
                },
                "attribution": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Attribution string, verbatim."
                },
                "license_code": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Sound licence code. Null means all rights reserved."
                }
              },
              "description": "An audio recording with its attribution and licence.",
              "additionalProperties": false
            },
            "description": "Audio recordings. Present when \"sounds\" was included."
          },
          "captive": {
            "type": "boolean",
            "description": "True for a zoo animal, a garden planting, or other cultivation."
          },
          "comments": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "by",
                "body",
                "created_at"
              ],
              "properties": {
                "by": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Login of the commenter."
                },
                "id": {
                  "type": "number",
                  "description": "Comment id."
                },
                "body": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Free-text comment body."
                },
                "created_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "When the comment was posted, ISO 8601."
                }
              },
              "description": "One discussion comment on the record.",
              "additionalProperties": false
            },
            "description": "Requested comments, first entries in upstream order (not strictly chronological), sharing a 40-entry budget across records."
          },
          "obscured": {
            "type": "boolean",
            "description": "True when the true coordinate is withheld; the public point is a locality."
          },
          "observer": {
            "type": [
              "string",
              "null"
            ],
            "description": "Observer login."
          },
          "agreements": {
            "type": "number",
            "description": "How many identifications currently agree with the community taxon."
          },
          "coordinate": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "lat",
                  "lng",
                  "accuracy_m"
                ],
                "properties": {
                  "lat": {
                    "type": "number",
                    "description": "Latitude in decimal degrees."
                  },
                  "lng": {
                    "type": "number",
                    "description": "Longitude in decimal degrees."
                  },
                  "accuracy_m": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "Public accuracy radius, metres. An obscured point is a locality, not a sighting position."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "Public coordinate. Null when the record carries none."
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Record creation timestamp, verbatim from upstream. Null when absent."
          },
          "geoprivacy": {
            "type": [
              "string",
              "null"
            ],
            "description": "Observer-set coordinate privacy: obscured, obscured_private, open, or private."
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Record update timestamp, verbatim from upstream. Null when absent."
          },
          "annotations": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "attribute",
                "value",
                "attribute_id",
                "value_id",
                "by"
              ],
              "properties": {
                "by": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Login of the member who added the annotation."
                },
                "value": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Value label, e.g. \"Larva\"; null for an unknown id."
                },
                "value_id": {
                  "type": "number",
                  "description": "Value id, usable as term_value_id on the search tools."
                },
                "attribute": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Attribute label, e.g. \"Life Stage\"; null for an unknown id."
                },
                "attribute_id": {
                  "type": "number",
                  "description": "Attribute id, usable as term_id on the search tools."
                }
              },
              "description": "One decoded annotation on the record.",
              "additionalProperties": false
            },
            "description": "Decoded annotations. Present when \"annotations\" was included."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Verbatim observer note on detail records; null when none was written, distinct from an empty string."
          },
          "observed_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Observation timestamp with offset, ISO 8601."
          },
          "observed_on": {
            "type": [
              "string",
              "null"
            ],
            "description": "Observation date, YYYY-MM-DD. Null when the observer recorded no date."
          },
          "photo_count": {
            "type": "number",
            "description": "Photo count; include \"photos\" for every photo."
          },
          "place_guess": {
            "type": [
              "string",
              "null"
            ],
            "description": "Locality text written by the observer. Third-party free text."
          },
          "sound_count": {
            "type": "number",
            "description": "How many audio recordings the record carries."
          },
          "license_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "Licence of the observation record itself. Null means all rights reserved."
          },
          "disagreements": {
            "type": "number",
            "description": "How many identifications currently disagree with the community taxon."
          },
          "quality_grade": {
            "enum": [
              "research",
              "needs_id",
              "casual"
            ],
            "type": "string",
            "description": "Identification confidence tier: research, needs_id, or casual."
          },
          "comments_shown": {
            "type": "number",
            "description": "Comment entries returned; below comments_total when capped."
          },
          "comments_total": {
            "type": "number",
            "description": "Comment count before the cap; present with \"comments\"."
          },
          "community_taxon": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "id",
                  "name",
                  "rank",
                  "common_name",
                  "iconic_taxon_name"
                ],
                "properties": {
                  "id": {
                    "type": "number",
                    "description": "Taxon id — the identifier every taxon-scoped filter takes."
                  },
                  "name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Scientific name."
                  },
                  "rank": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Taxonomic rank, e.g. \"species\"."
                  },
                  "common_name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Preferred common name, when one is recorded."
                  },
                  "iconic_taxon_name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Broad organism group, e.g. \"Insecta\". Usable as an iconic_taxa filter value."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "Resolved consensus taxon on detail records; null without consensus."
          },
          "identifications": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "taxon",
                "by",
                "current",
                "category",
                "disagreement",
                "from_vision",
                "body",
                "created_at"
              ],
              "properties": {
                "by": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Login of the identifier."
                },
                "id": {
                  "type": "number",
                  "description": "Identification id."
                },
                "body": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Free-text note written by the identifier."
                },
                "taxon": {
                  "anyOf": [
                    {
                      "type": "object",
                      "required": [
                        "id",
                        "name",
                        "rank",
                        "common_name",
                        "iconic_taxon_name"
                      ],
                      "properties": {
                        "id": {
                          "type": "number",
                          "description": "Taxon id — the identifier every taxon-scoped filter takes."
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Scientific name."
                        },
                        "rank": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Taxonomic rank, e.g. \"species\"."
                        },
                        "common_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Preferred common name, when one is recorded."
                        },
                        "iconic_taxon_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Broad organism group, e.g. \"Insecta\". Usable as an iconic_taxa filter value."
                        }
                      },
                      "additionalProperties": false
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Taxon this identification proposes."
                },
                "current": {
                  "type": "boolean",
                  "description": "True when this is the identifier’s current identification on the record."
                },
                "category": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "How this identification moved the thread: improving, supporting, leading, or maverick."
                },
                "created_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "When the identification was added, ISO 8601."
                },
                "from_vision": {
                  "type": "boolean",
                  "description": "True when the identification came from the upstream image classifier."
                },
                "disagreement": {
                  "type": [
                    "boolean",
                    "null"
                  ],
                  "description": "True when the identifier explicitly disagreed with the preceding taxon."
                }
              },
              "description": "One identification in the community thread.",
              "additionalProperties": false
            },
            "description": "Requested identification thread, first entries in upstream order (not strictly chronological), sharing a 40-entry budget across records."
          },
          "taxon_geoprivacy": {
            "type": [
              "string",
              "null"
            ],
            "description": "Coordinate privacy applied automatically for a threatened taxon. Same vocabulary."
          },
          "community_taxon_id": {
            "type": [
              "number",
              "null"
            ],
            "description": "Consensus taxon id. Differs from taxon.id while a thread is contested."
          },
          "observation_fields": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "name",
                "value"
              ],
              "properties": {
                "name": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Verbatim field name, e.g. \"Habitat_Description\"."
                },
                "value": {
                  "type": "string",
                  "description": "The value filled in, verbatim."
                }
              },
              "description": "One filled observation field.",
              "additionalProperties": false
            },
            "description": "Filled fields on detail records, verbatim; blanks omitted. First entries in upstream order, sharing a 40-entry budget across records."
          },
          "identifications_count": {
            "type": "number",
            "description": "Tally against the community taxon: agreements + disagreements. Excludes the observer and neutral/withdrawn ids; thread size is identifications_total on inaturalist_get_observation."
          },
          "identifications_shown": {
            "type": "number",
            "description": "Identification entries returned; below identifications_total when capped."
          },
          "identifications_total": {
            "type": "number",
            "description": "Thread size before the cap; present with \"identifications\"."
          },
          "observation_fields_shown": {
            "type": "number",
            "description": "Filled fields returned; below observation_fields_total when capped."
          },
          "observation_fields_total": {
            "type": "number",
            "description": "Filled field count before the cap on detail records."
          },
          "identification_disagreements_count": {
            "type": "number",
            "description": "Upstream disagreement count on detail records."
          }
        },
        "description": "One projected observation record.",
        "additionalProperties": false
      },
      "description": "The observations that resolved, in the requested order with unresolved ids left out, carrying the expansions that were requested."
    }
  },
  "additionalProperties": false
}
inaturalist_get_observation annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true
}
inaturalist_get_species_counts — Inaturalist Get Species Counts
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Rank leaf taxa recorded in an area and period, most-observed first. Includes hybrids and coarser identifications; subspecies roll up to their species. An area is given in exactly one form: place_id, the lat/lng/radius triple in kilometres, or a four-corner bounding box. Narrow to a clade by passing taxon_id, e.g. the birds of a park, or to one observer or one project by user_id, user_login, or project_id. Defaults to research-grade, wild-only records and echoes those defaults back. For the most active people rather than the most recorded taxa, use inaturalist_get_leaderboard.

inaturalist_get_species_counts input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "d1": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2."
    },
    "d2": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Latest observation date, YYYY-MM-DD. Inclusive."
    },
    "csi": {
      "type": "array",
      "items": {
        "enum": [
          "LC",
          "NT",
          "VU",
          "EN",
          "CR",
          "EW",
          "EX"
        ],
        "type": "string"
      },
      "description": "IUCN-normalised conservation status codes. Matches global statuses plus statuses listed at exactly place_id, excluding ancestor-place listings; decode with inaturalist_list_reference topic conservation_status_codes."
    },
    "lat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius."
    },
    "lng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius."
    },
    "page": {
      "type": "integer",
      "default": 1,
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Page number. Defaults to 1."
    },
    "rank": {
      "enum": [
        "stateofmatter",
        "kingdom",
        "phylum",
        "subphylum",
        "superclass",
        "class",
        "subclass",
        "infraclass",
        "subterclass",
        "superorder",
        "order",
        "suborder",
        "infraorder",
        "parvorder",
        "zoosection",
        "zoosubsection",
        "superfamily",
        "epifamily",
        "family",
        "subfamily",
        "supertribe",
        "tribe",
        "subtribe",
        "genus",
        "genushybrid",
        "subgenus",
        "section",
        "subsection",
        "complex",
        "species",
        "hybrid",
        "subspecies",
        "variety",
        "form",
        "infrahybrid"
      ],
      "type": "string",
      "description": "Exact identification rank. Unlike hrank/lrank, species does not also select hybrid."
    },
    "hrank": {
      "enum": [
        "stateofmatter",
        "kingdom",
        "phylum",
        "subphylum",
        "superclass",
        "class",
        "subclass",
        "infraclass",
        "subterclass",
        "superorder",
        "order",
        "suborder",
        "infraorder",
        "parvorder",
        "zoosection",
        "zoosubsection",
        "superfamily",
        "epifamily",
        "family",
        "subfamily",
        "supertribe",
        "tribe",
        "subtribe",
        "genus",
        "genushybrid",
        "subgenus",
        "section",
        "subsection",
        "complex",
        "species",
        "hybrid",
        "subspecies",
        "variety",
        "form",
        "infrahybrid"
      ],
      "type": "string",
      "description": "Highest (coarsest) identification rank level to accept. Must be at or above lrank."
    },
    "lrank": {
      "enum": [
        "stateofmatter",
        "kingdom",
        "phylum",
        "subphylum",
        "superclass",
        "class",
        "subclass",
        "infraclass",
        "subterclass",
        "superorder",
        "order",
        "suborder",
        "infraorder",
        "parvorder",
        "zoosection",
        "zoosubsection",
        "superfamily",
        "epifamily",
        "family",
        "subfamily",
        "supertribe",
        "tribe",
        "subtribe",
        "genus",
        "genushybrid",
        "subgenus",
        "section",
        "subsection",
        "complex",
        "species",
        "hybrid",
        "subspecies",
        "variety",
        "form",
        "infrahybrid"
      ],
      "type": "string",
      "description": "Lowest (finest) identification rank level to accept. Equal bounds select a level, including ranks sharing that level such as species and hybrid."
    },
    "month": {
      "type": "array",
      "items": {
        "type": "integer",
        "maximum": 12,
        "minimum": 1
      },
      "description": "Observed calendar months, 1–12, matched as alternatives."
    },
    "nelat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none."
    },
    "nelng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "North-east corner longitude of the bounding box. All four corners or none. West of swlng is accepted: it describes a box crossing the antimeridian."
    },
    "swlat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "South-west corner latitude of the bounding box. All four corners or none."
    },
    "swlng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "South-west corner longitude of the bounding box. All four corners or none."
    },
    "native": {
      "type": "boolean",
      "description": "Filter the observation’s indexed taxon as native at its location."
    },
    "radius": {
      "type": "number",
      "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice."
    },
    "captive": {
      "type": "boolean",
      "default": false,
      "description": "True returns captive and cultivated records only — zoo animals, garden plantings; false returns wild records only. Defaults to false."
    },
    "endemic": {
      "type": "boolean",
      "description": "Filter the observation’s indexed taxon as endemic at its location."
    },
    "term_id": {
      "type": "array",
      "items": {
        "type": "integer",
        "maximum": 9007199254740991,
        "minimum": 1
      },
      "description": "Annotation attribute ids, from inaturalist_list_reference topic controlled_terms — e.g. 1 for Life Stage. Multiple ids match any one annotation, not all annotations; arrays are membership sets, not positional pairs."
    },
    "user_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login."
    },
    "per_page": {
      "type": "integer",
      "default": 25,
      "maximum": 9007199254740991,
      "description": "Taxa per page. Raise page to continue the ranking. Ceiling: 50; oversized values are clamped.",
      "exclusiveMinimum": 0
    },
    "place_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Numeric iNaturalist place id from inaturalist_find_places. Mutually exclusive with the lat/lng/radius triple and the bounding box. A non-numeric value answers HTTP 500 upstream."
    },
    "taxon_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name."
    },
    "introduced": {
      "type": "boolean",
      "description": "Filter the observation’s indexed taxon as introduced at its location."
    },
    "project_id": {
      "type": "integer",
      "maximum": 2147483647,
      "minimum": 1,
      "description": "Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project."
    },
    "threatened": {
      "type": "boolean",
      "description": "Filter the observation’s indexed taxon as threatened at its location."
    },
    "user_login": {
      "type": "string",
      "minLength": 1,
      "description": "Restrict to one observer, by login — the login on an inaturalist_resolve_name user candidate, a leaderboard entry, or an observation’s observer. Mutually exclusive with user_id."
    },
    "iconic_taxa": {
      "type": "array",
      "items": {
        "enum": [
          "Actinopterygii",
          "Amphibia",
          "Animalia",
          "Arachnida",
          "Aves",
          "Chromista",
          "Fungi",
          "Insecta",
          "Mammalia",
          "Mollusca",
          "Plantae",
          "Protozoa",
          "Reptilia",
          "unknown"
        ],
        "type": "string"
      },
      "description": "Broad organism groups, by their scientific iconic-taxon name. A common-name value such as \"Birds\" matches nothing upstream, so only the listed values are accepted."
    },
    "quality_grade": {
      "type": "array",
      "items": {
        "enum": [
          "research",
          "needs_id",
          "casual"
        ],
        "type": "string"
      },
      "default": [
        "research"
      ],
      "minItems": 1,
      "description": "Identification confidence tiers to include, normalized to unique values in first-appearance order. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence."
    },
    "term_value_id": {
      "type": "array",
      "items": {
        "type": "integer",
        "maximum": 9007199254740991,
        "minimum": 1
      },
      "description": "Annotation value ids, from the same attribute listing — e.g. 6 for Larva. Requires term_id; sent alone it is ignored upstream and the unfiltered corpus comes back. Multiple ids match any one annotation with an attribute in term_id and a value in this set, not both annotations."
    }
  },
  "additionalProperties": false
}
inaturalist_get_species_counts output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "total_results",
        "species",
        "applied_filters",
        "truncated",
        "shown",
        "cap"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "number",
      "description": "The per_page that was applied."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "inverted_rank_range",
                "unknown_place_id",
                "invalid_geography",
                "inverted_date_range",
                "unpaired_annotation_value",
                "conflicting_observer",
                "unknown_taxon_id",
                "unknown_user",
                "unknown_project_id"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `inverted_rank_range`: hrank is a finer rank level than lrank. `unknown_place_id`: iNaturalist answered 422 because place_id does not exist. `invalid_geography`: An area was given partially, in two forms at once, with a radius of 0 or less, or with nelat south of swlat. `inverted_date_range`: d1 is after d2. `unpaired_annotation_value`: term_value_id was supplied without term_id. `conflicting_observer`: user_id and user_login were both supplied. `unknown_taxon_id`: iNaturalist answered 422 because the taxon_id does not exist. `unknown_user`: iNaturalist answered 422 because the user_id or user_login names no observer. `unknown_project_id`: iNaturalist answered 422 because the project_id does not exist. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "shown": {
      "type": "number",
      "description": "How many taxa this page carries."
    },
    "notice": {
      "type": "string",
      "description": "Guidance when nothing matched, when the page is past the last one holding taxa, or how to reach the taxa beyond this page."
    },
    "species": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "position",
          "taxon_id",
          "name",
          "common_name",
          "rank",
          "iconic_taxon_name",
          "observation_count"
        ],
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Scientific name."
          },
          "rank": {
            "type": [
              "string",
              "null"
            ],
            "description": "Taxonomic rank, e.g. \"species\"."
          },
          "photo": {
            "type": "object",
            "required": [
              "square_url",
              "attribution",
              "license_code",
              "open"
            ],
            "properties": {
              "open": {
                "type": "boolean",
                "description": "True when served from the open-licence host at fetch time; licences can change."
              },
              "medium_url": {
                "type": "string",
                "description": "Medium image URL; derived from the size path if needed. Absent when no variant is available."
              },
              "square_url": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "75px square variant, exactly as upstream published it. Null when absent."
              },
              "attribution": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Verbatim attribution; reproduce with any use of the image."
              },
              "license_code": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Photo licence code. Null means all rights reserved, independent of the record."
              }
            },
            "description": "Representative photo, when the taxon carries one.",
            "additionalProperties": false
          },
          "position": {
            "type": "number",
            "description": "Absolute place in this ranking, counted from page 1 — 7 is the seventh most-observed taxon. Not the taxonomic rank, which is rank."
          },
          "taxon_id": {
            "type": "number",
            "description": "Taxon id — pass it as taxon_id to any taxon-scoped tool or to inaturalist_get_taxon."
          },
          "common_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Preferred common name, when one is recorded."
          },
          "iconic_taxon_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Broad organism group, e.g. \"Aves\". Usable as an iconic_taxa filter value."
          },
          "observation_count": {
            "type": "number",
            "description": "How many matching observations record this taxon. The ranking key."
          }
        },
        "description": "One leaf taxon and how often it was recorded in the requested area and period.",
        "additionalProperties": false
      },
      "description": "The taxa, ranked by observation_count, most-observed first, each at its absolute position."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when the page filled per_page and more taxa follow."
    },
    "total_results": {
      "type": "number",
      "description": "How many taxa match. An estimate over a live index — it drifts between calls seconds apart."
    },
    "applied_filters": {
      "type": "object",
      "required": [
        "quality_grade",
        "captive"
      ],
      "properties": {
        "captive": {
          "type": "boolean",
          "description": "Captive-only when true, wild-only when false."
        },
        "quality_grade": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Identification tiers actually searched."
        }
      },
      "description": "The server-applied defaults that determine what this answer means.",
      "additionalProperties": false
    },
    "truncationCeiling": {
      "type": "number",
      "description": "Observation count of the last taxon shown. The ranking is descending, so no taxon left off this page exceeds it."
    }
  },
  "additionalProperties": false
}
inaturalist_get_species_counts annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
inaturalist_get_histogram — Inaturalist Get Histogram
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Build a phenology histogram for a taxon in an area — which months, weeks, or years it is recorded in. The default month_of_year interval answers "when does this bloom or appear here" in twelve buckets; absolute intervals (year, month, week, day, hour) bucket real dates and disclose their window start. An area is given in exactly one form: place_id, the lat/lng/radius triple in kilometres, or a four-corner bounding box. Omit taxon_id to chart every taxon in the area. Narrow to one life stage or reproductive state with an annotation pair (term_id and term_value_id, e.g. Life Stage = Larva, or Flowers and Fruits = Flowers), or to broad groups with iconic_taxa. Defaults to research-grade, wild-only records and echoes those defaults back.

inaturalist_get_histogram input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "d1": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2. For absolute observed-date intervals, a missing d1 is derived from d2 or today UTC and disclosed as window_start. Wide ranges can exceed the 25000-bucket cap; continuation names d1, or created_d1 for upload-date bucketing."
    },
    "d2": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Latest observation date, YYYY-MM-DD. Inclusive."
    },
    "lat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius."
    },
    "lng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius."
    },
    "nelat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none."
    },
    "nelng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "North-east corner longitude of the bounding box. All four corners or none. West of swlng is accepted: it describes a box crossing the antimeridian."
    },
    "swlat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "South-west corner latitude of the bounding box. All four corners or none."
    },
    "swlng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "South-west corner longitude of the bounding box. All four corners or none."
    },
    "radius": {
      "type": "number",
      "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice."
    },
    "captive": {
      "type": "boolean",
      "default": false,
      "description": "True returns captive and cultivated records only — zoo animals, garden plantings; false returns wild records only. Defaults to false."
    },
    "term_id": {
      "type": "array",
      "items": {
        "type": "integer",
        "maximum": 9007199254740991,
        "minimum": 1
      },
      "description": "Annotation attribute ids, from inaturalist_list_reference topic controlled_terms — e.g. 1 for Life Stage. Multiple ids match any one annotation, not all annotations; arrays are membership sets, not positional pairs."
    },
    "user_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login."
    },
    "interval": {
      "enum": [
        "year",
        "month",
        "week",
        "day",
        "hour",
        "month_of_year",
        "week_of_year"
      ],
      "type": "string",
      "default": "month_of_year",
      "description": "Bucketing. month_of_year and week_of_year fold every year together into a seasonal curve. Absolute intervals default the selected date family's missing lower bound from its upper bound, otherwise today UTC: year/month subtract 100 calendar years, week 10 years, day one year, hour seven days. The start is disclosed; no upper bound is added. At most 25000 buckets are returned, oldest first, with continuation guidance when cut."
    },
    "place_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Numeric iNaturalist place id from inaturalist_find_places. Mutually exclusive with the lat/lng/radius triple and the bounding box. A non-numeric value answers HTTP 500 upstream."
    },
    "taxon_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Restrict to this taxon and its descendants. Omit to chart every taxon in the area. Resolve a name to an id with inaturalist_resolve_name."
    },
    "created_d1": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Earliest upload date, YYYY-MM-DD. Inclusive. Must be on or before created_d2."
    },
    "created_d2": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Latest upload date, YYYY-MM-DD. Inclusive."
    },
    "date_field": {
      "enum": [
        "observed",
        "created"
      ],
      "type": "string",
      "default": "observed",
      "description": "Which date to bucket by: when the organism was observed, or when the record was uploaded."
    },
    "project_id": {
      "type": "integer",
      "maximum": 2147483647,
      "minimum": 1,
      "description": "Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project."
    },
    "user_login": {
      "type": "string",
      "minLength": 1,
      "description": "Restrict to one observer, by login — the login on an inaturalist_resolve_name user candidate, a leaderboard entry, or an observation’s observer. Mutually exclusive with user_id."
    },
    "iconic_taxa": {
      "type": "array",
      "items": {
        "enum": [
          "Actinopterygii",
          "Amphibia",
          "Animalia",
          "Arachnida",
          "Aves",
          "Chromista",
          "Fungi",
          "Insecta",
          "Mammalia",
          "Mollusca",
          "Plantae",
          "Protozoa",
          "Reptilia",
          "unknown"
        ],
        "type": "string"
      },
      "description": "Broad organism groups, by their scientific iconic-taxon name. A common-name value such as \"Birds\" matches nothing upstream, so only the listed values are accepted."
    },
    "quality_grade": {
      "type": "array",
      "items": {
        "enum": [
          "research",
          "needs_id",
          "casual"
        ],
        "type": "string"
      },
      "default": [
        "research"
      ],
      "minItems": 1,
      "description": "Identification confidence tiers to include, normalized to unique values in first-appearance order. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence."
    },
    "term_value_id": {
      "type": "array",
      "items": {
        "type": "integer",
        "maximum": 9007199254740991,
        "minimum": 1
      },
      "description": "Annotation value ids, from the same attribute listing — e.g. 6 for Larva. Requires term_id; sent alone it is ignored upstream and the unfiltered corpus comes back. Multiple ids match any one annotation with an attribute in term_id and a value in this set, not both annotations."
    }
  },
  "additionalProperties": false
}
inaturalist_get_histogram output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "interval",
        "buckets",
        "total",
        "applied_filters",
        "truncated",
        "shown",
        "cap"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "number",
      "description": "The bucket cap that was applied."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "conflicting_observer",
                "unknown_user",
                "unknown_project_id",
                "unknown_place_id",
                "invalid_geography",
                "inverted_date_range",
                "unpaired_annotation_value",
                "unknown_taxon_id"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `conflicting_observer`: user_id and user_login were both supplied. `unknown_user`: iNaturalist answered 422 because the user_id or user_login names no observer. `unknown_project_id`: iNaturalist answered 422 because the project_id does not exist. `unknown_place_id`: iNaturalist answered 422 because place_id does not exist. `invalid_geography`: An area was given partially, in two forms at once, with a radius of 0 or less, or with nelat south of swlat. `inverted_date_range`: d1 is after d2, or created_d1 is after created_d2. `unpaired_annotation_value`: term_value_id was supplied without term_id. `unknown_taxon_id`: iNaturalist answered 422 because the taxon_id does not exist. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "shown": {
      "type": "number",
      "description": "How many buckets this response carries."
    },
    "total": {
      "type": "number",
      "description": "Observations in the upstream histogram window: sum of every returned bucket count, including buckets past the cap; not an all-time taxon count."
    },
    "notice": {
      "type": "string",
      "description": "Generated window start, filter guidance, and continuation when buckets are cut."
    },
    "buckets": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "key",
          "count"
        ],
        "properties": {
          "key": {
            "type": "string",
            "description": "Bucket label, in upstream order — \"1\"…\"12\" for month_of_year, a date for the absolute intervals."
          },
          "count": {
            "type": "number",
            "description": "Matching observations in this bucket."
          }
        },
        "description": "One histogram bucket.",
        "additionalProperties": false
      },
      "description": "Every bucket upstream returned, in order, including the zero ones — up to 25000, the first in upstream key order. See the truncated/shown/cap enrichment when more exist."
    },
    "interval": {
      "enum": [
        "year",
        "month",
        "week",
        "day",
        "hour",
        "month_of_year",
        "week_of_year"
      ],
      "type": "string",
      "description": "The bucketing that was applied."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when upstream returned more than 25000 buckets."
    },
    "applied_filters": {
      "type": "object",
      "required": [
        "quality_grade",
        "captive",
        "date_field"
      ],
      "properties": {
        "captive": {
          "type": "boolean",
          "description": "Captive-only when true, wild-only when false."
        },
        "date_field": {
          "type": "string",
          "description": "Which date the buckets were built from."
        },
        "window_start": {
          "type": "string",
          "description": "Inclusive lower bound on the bucketed date for absolute intervals; absent for seasonal intervals."
        },
        "quality_grade": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Identification tiers actually searched."
        }
      },
      "description": "Effective cohort defaults, bucketed date family, and absolute window start.",
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}
inaturalist_get_histogram annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
inaturalist_get_leaderboard — Inaturalist Get Leaderboard
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Rank the most active observers or identifiers for an area, period, and taxon — who knows this place or this group. kind selects which: observers are ranked by how many observations they recorded, identifiers by how many identifications they made. An area is given in exactly one form: place_id, the lat/lng/radius triple in kilometres, or a four-corner bounding box. Both endpoints rank only the top 500 entries, so page multiplied by per_page must stay at or below 500 — narrow the area, period, or taxon to bring someone further down into reach. For the most-recorded species rather than the most active people, use inaturalist_get_species_counts.

inaturalist_get_leaderboard input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "kind"
  ],
  "properties": {
    "d1": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2."
    },
    "d2": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Latest observation date, YYYY-MM-DD. Inclusive."
    },
    "lat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius."
    },
    "lng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius."
    },
    "kind": {
      "enum": [
        "observers",
        "identifiers"
      ],
      "type": "string",
      "description": "Which leaderboard: \"observers\" ranks by observations recorded, \"identifiers\" by identifications made. user_id or user_login scopes observation ownership: observers selects that observer’s own row; identifiers selects people who identified that observer’s observations, not identifications authored by that observer. project_id scopes observations to one project."
    },
    "page": {
      "type": "integer",
      "default": 1,
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Page number. Defaults to 1."
    },
    "nelat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none."
    },
    "nelng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "North-east corner longitude of the bounding box. All four corners or none. West of swlng is accepted: it describes a box crossing the antimeridian."
    },
    "swlat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "South-west corner latitude of the bounding box. All four corners or none."
    },
    "swlng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "South-west corner longitude of the bounding box. All four corners or none."
    },
    "radius": {
      "type": "number",
      "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice."
    },
    "user_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login."
    },
    "per_page": {
      "type": "integer",
      "default": 25,
      "maximum": 9007199254740991,
      "description": "Entries per page. Two ceiling-sized pages cover the 500-entry window. Ceiling: 250; oversized values are clamped.",
      "exclusiveMinimum": 0
    },
    "place_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Numeric iNaturalist place id from inaturalist_find_places. Mutually exclusive with the lat/lng/radius triple and the bounding box. A non-numeric value answers HTTP 500 upstream."
    },
    "taxon_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name."
    },
    "project_id": {
      "type": "integer",
      "maximum": 2147483647,
      "minimum": 1,
      "description": "Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project."
    },
    "user_login": {
      "type": "string",
      "minLength": 1,
      "description": "Restrict to one observer, by login — the login on an inaturalist_resolve_name user candidate, a leaderboard entry, or an observation’s observer. Mutually exclusive with user_id."
    },
    "quality_grade": {
      "type": "array",
      "items": {
        "enum": [
          "research",
          "needs_id",
          "casual"
        ],
        "type": "string"
      },
      "default": [
        "research"
      ],
      "minItems": 1,
      "description": "Identification confidence tiers to include, normalized to unique values in first-appearance order. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence."
    }
  },
  "additionalProperties": false
}
inaturalist_get_leaderboard output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "kind",
        "count_metric",
        "total_results",
        "entries",
        "applied_filters",
        "truncated",
        "shown",
        "cap"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "number",
      "description": "The per_page that was applied."
    },
    "kind": {
      "enum": [
        "observers",
        "identifiers"
      ],
      "type": "string",
      "description": "Which leaderboard was ranked."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "conflicting_observer",
                "unknown_user",
                "unknown_project_id",
                "unknown_place_id",
                "invalid_geography",
                "inverted_date_range",
                "leaderboard_window_exceeded",
                "unknown_taxon_id"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `conflicting_observer`: user_id and user_login were both supplied. `unknown_user`: iNaturalist answered 422 because the user_id or user_login names no observer. `unknown_project_id`: iNaturalist answered 422 because the project_id does not exist. `unknown_place_id`: iNaturalist answered 422 because place_id does not exist. `invalid_geography`: An area was given partially, in two forms at once, with a radius of 0 or less, or with nelat south of swlat. `inverted_date_range`: d1 is after d2. `leaderboard_window_exceeded`: page multiplied by per_page would reach past the 500 entries these endpoints rank. `unknown_taxon_id`: iNaturalist answered 422 because the taxon_id does not exist. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "shown": {
      "type": "number",
      "description": "How many entries this page carries."
    },
    "notice": {
      "type": "string",
      "description": "Guidance when nobody matched, when the page is past the last one holding entries, or how to reach further down the ranking."
    },
    "entries": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "rank",
          "login",
          "count"
        ],
        "properties": {
          "rank": {
            "type": "number",
            "description": "Absolute rank across the leaderboard, counted from page 1."
          },
          "count": {
            "type": "number",
            "description": "Observations recorded, or identifications made — see count_metric."
          },
          "login": {
            "type": [
              "string",
              "null"
            ],
            "description": "The member’s login. No other profile field is relayed."
          },
          "species_count": {
            "type": "number",
            "description": "Distinct species this observer recorded. Present on the observers arm only; the identifiers endpoint publishes none."
          }
        },
        "description": "One ranked member.",
        "additionalProperties": false
      },
      "description": "The ranked members, most active first."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when the page filled per_page and more entries follow."
    },
    "count_metric": {
      "enum": [
        "observations",
        "identifications"
      ],
      "type": "string",
      "description": "What the count on each entry measures."
    },
    "total_results": {
      "type": "number",
      "description": "How many people upstream reports as matching. Far larger than the 500 this leaderboard can actually address."
    },
    "applied_filters": {
      "type": "object",
      "required": [
        "quality_grade"
      ],
      "properties": {
        "quality_grade": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Identification tiers actually searched."
        }
      },
      "description": "The server-applied default that determines what this answer means.",
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}
inaturalist_get_leaderboard annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
inaturalist_get_similar_species — Inaturalist Get Similar Species
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

List related taxa ranked by observations carrying current identifications of both taxa. This is co-identification evidence, not a directional correction count or an exhaustive list of visually similar organisms. Scope it to an area in exactly one form (place_id, the lat/lng/radius triple in kilometres, or a four-corner bounding box), or leave the area off for global results. The taxon must be a genus or finer (genus, species, or below). Resolve the organism name to a taxon id with inaturalist_resolve_name first.

inaturalist_get_similar_species input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "taxon_id"
  ],
  "properties": {
    "d1": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2."
    },
    "d2": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Latest observation date, YYYY-MM-DD. Inclusive."
    },
    "lat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius."
    },
    "lng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius."
    },
    "limit": {
      "type": "integer",
      "default": 20,
      "maximum": 9007199254740991,
      "description": "Maximum related taxa to return. Served ceiling: 24; requests above it are reduced to 24. Positive safe integer requests are accepted.",
      "exclusiveMinimum": 0
    },
    "nelat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none."
    },
    "nelng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "North-east corner longitude of the bounding box. All four corners or none. West of swlng is accepted: it describes a box crossing the antimeridian."
    },
    "swlat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "South-west corner latitude of the bounding box. All four corners or none."
    },
    "swlng": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "South-west corner longitude of the bounding box. All four corners or none."
    },
    "radius": {
      "type": "number",
      "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice."
    },
    "captive": {
      "type": "boolean",
      "default": false,
      "description": "True returns captive and cultivated records only — zoo animals, garden plantings; false returns wild records only. Defaults to false."
    },
    "place_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Numeric iNaturalist place id from inaturalist_find_places. Mutually exclusive with the lat/lng/radius triple and the bounding box. A non-numeric value answers HTTP 500 upstream."
    },
    "taxon_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Numeric taxon id to find look-alikes for, at genus or finer — a genus, species, or subspecies; a family or anything coarser is refused. Resolve a name to an id with inaturalist_resolve_name."
    },
    "quality_grade": {
      "type": "array",
      "items": {
        "enum": [
          "research",
          "needs_id",
          "casual"
        ],
        "type": "string"
      },
      "default": [
        "research"
      ],
      "minItems": 1,
      "description": "Identification confidence tiers to include, normalized to unique values in first-appearance order. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence."
    }
  },
  "additionalProperties": false
}
inaturalist_get_similar_species output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "taxon_id",
        "similar_species",
        "totalCount",
        "truncated",
        "shown",
        "cap"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "number",
      "description": "The limit that was applied."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "unknown_place_id",
                "invalid_geography",
                "inverted_date_range",
                "unknown_taxon_id",
                "taxon_rank_too_coarse"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `unknown_place_id`: iNaturalist answered 422 because place_id does not exist. `invalid_geography`: An area was given partially, in two forms at once, with a radius of 0 or less, or with nelat south of swlat. `inverted_date_range`: d1 is after d2. `unknown_taxon_id`: iNaturalist answered 422 because the taxon_id does not exist. `taxon_rank_too_coarse`: iNaturalist answered 422 because the taxon is coarser than genus, such as a family, order, or class. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "shown": {
      "type": "number",
      "description": "How many look-alikes this response carries."
    },
    "notice": {
      "type": "string",
      "description": "Guidance when no look-alikes are recorded, or when the limit cut the set."
    },
    "taxon_id": {
      "type": "number",
      "description": "The taxon the look-alikes were found for."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when the local limit cut the list or upstream reached its ceiling, so more related taxa may exist."
    },
    "totalCount": {
      "type": "number",
      "description": "How many look-alikes upstream returned, before the limit was applied."
    },
    "similar_species": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "taxon_id",
          "name",
          "common_name",
          "rank",
          "observations_count",
          "misidentification_count"
        ],
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Scientific name."
          },
          "rank": {
            "type": [
              "string",
              "null"
            ],
            "description": "Taxonomic rank, e.g. \"species\"."
          },
          "photo": {
            "type": "object",
            "required": [
              "square_url",
              "attribution",
              "license_code",
              "open"
            ],
            "properties": {
              "open": {
                "type": "boolean",
                "description": "True when served from the open-licence host at fetch time; licences can change."
              },
              "medium_url": {
                "type": "string",
                "description": "Medium image URL; derived from the size path if needed. Absent when no variant is available."
              },
              "square_url": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "75px square variant, exactly as upstream published it. Null when absent."
              },
              "attribution": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Verbatim attribution; reproduce with any use of the image."
              },
              "license_code": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Photo licence code. Null means all rights reserved, independent of the record."
              }
            },
            "description": "Representative photo, when the taxon carries one.",
            "additionalProperties": false
          },
          "taxon_id": {
            "type": "number",
            "description": "Taxon id of the look-alike — pass it to inaturalist_get_taxon for its profile."
          },
          "common_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Preferred common name, when one is recorded."
          },
          "observations_count": {
            "type": [
              "number",
              "null"
            ],
            "description": "How many observations this look-alike has overall. Null when upstream published none."
          },
          "misidentification_count": {
            "type": "number",
            "description": "Observations identified as both taxa under the call’s filters: a symmetric count of current, non-hidden identifications, including finer taxa through their ancestors. Withdrawn identifications are excluded. The ranking key."
          }
        },
        "description": "One look-alike and how often it is confused with the queried taxon.",
        "additionalProperties": false
      },
      "description": "Look-alikes ranked by misidentification_count, most-confused first."
    },
    "truncationCeiling": {
      "type": "number",
      "description": "Misidentification count of the last look-alike shown. The ranking is descending, so no omitted look-alike exceeds it."
    }
  },
  "additionalProperties": false
}
inaturalist_get_similar_species annotations
{
  "readOnlyHint": true,
  "openWorldHint": true
}
inaturalist_get_taxon — Inaturalist Get Taxon
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Fetch a taxon profile: the taxonomic path, per-authority conservation listings, the encyclopedia summary, the photo gallery, immediate children, and observation counts. Resolve a name to a taxon id with inaturalist_resolve_name first. The upstream record is 95 KB for a common species, so it is projected before anything else happens; a taxon that still overflows comes back as an outline of its sections with their byte sizes, and naming those sections in a re-call returns only those. The valid section names are summary, taxonomy, children, conservation, photos, and encyclopedia.

inaturalist_get_taxon input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "taxon_id"
  ],
  "properties": {
    "sections": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "description": "Sections to return: summary, taxonomy, children, conservation, photos, encyclopedia. Omit for the whole profile, or an outline of it when it overflows. A selection returns whatever it names, at whatever size, so sum the byte sizes from the outline before asking for several."
    },
    "taxon_id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Numeric taxon id. A non-numeric value answers HTTP 422 with an empty message upstream, so the integer is enforced here. Resolve a name to an id with inaturalist_resolve_name."
    }
  },
  "additionalProperties": false
}
inaturalist_get_taxon output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "kind",
        "sections_applied"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "id": {
      "type": "number",
      "description": "Taxon id."
    },
    "kind": {
      "enum": [
        "full",
        "outline"
      ],
      "type": "string",
      "description": "\"full\" when the profile itself is returned, \"outline\" when it overflowed and only the section list came back."
    },
    "name": {
      "type": [
        "string",
        "null"
      ],
      "description": "Scientific name."
    },
    "rank": {
      "type": [
        "string",
        "null"
      ],
      "description": "Taxonomic rank, e.g. \"species\"."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "not_found",
                "unknown_section"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `not_found`: iNaturalist answered with an empty results array for that taxon id. `unknown_section`: sections named a key the projected document does not carry. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "notice": {
      "type": "string",
      "description": "How to re-call for specific sections. Present on the outline."
    },
    "photos": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "square_url",
          "attribution",
          "license_code",
          "open"
        ],
        "properties": {
          "open": {
            "type": "boolean",
            "description": "True when served from the open-licence host at fetch time; licences can change."
          },
          "large_url": {
            "type": "string",
            "description": "Upstream large image URL; absent when unpublished, never derived."
          },
          "medium_url": {
            "type": "string",
            "description": "Medium image URL; derived from the size path if needed. Absent when no variant is available."
          },
          "square_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "75px square variant, exactly as upstream published it. Null when absent."
          },
          "attribution": {
            "type": [
              "string",
              "null"
            ],
            "description": "Verbatim attribution; reproduce with any use of the image."
          },
          "license_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "Photo licence code. Null means all rights reserved, independent of the record."
          }
        },
        "description": "A taxon gallery photo with the attribution and licence that must travel with it.",
        "additionalProperties": false
      },
      "description": "Gallery photos, each with its own licence."
    },
    "vision": {
      "type": "boolean",
      "description": "True when the taxon is covered by the upstream image classifier."
    },
    "extinct": {
      "type": "boolean",
      "description": "True when the taxon is recorded as extinct."
    },
    "children": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "name",
          "rank",
          "common_name",
          "observations_count"
        ],
        "properties": {
          "id": {
            "type": "number",
            "description": "Taxon id of this ancestor — usable as taxon_id on any tool."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Scientific name."
          },
          "rank": {
            "type": [
              "string",
              "null"
            ],
            "description": "Taxonomic rank, e.g. \"family\"."
          },
          "common_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Preferred common name, when one is recorded."
          },
          "observations_count": {
            "type": [
              "number",
              "null"
            ],
            "description": "How many observations this child taxon has. Null when upstream published none."
          }
        },
        "description": "One immediate child taxon.",
        "additionalProperties": false
      },
      "description": "Immediate children of this taxon."
    },
    "sections": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name",
          "bytes"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Section identifier — pass in `sections` to retrieve it"
          },
          "bytes": {
            "type": "integer",
            "maximum": 9007199254740991,
            "minimum": 0,
            "description": "Serialized byte size of the section"
          }
        },
        "description": "One section that can be named in a re-call, and what it costs.",
        "additionalProperties": false
      },
      "description": "Available sections and their byte sizes, largest first. Present on the outline."
    },
    "taxonomy": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "name",
          "rank",
          "common_name"
        ],
        "properties": {
          "id": {
            "type": "number",
            "description": "Taxon id of this ancestor — usable as taxon_id on any tool."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Scientific name."
          },
          "rank": {
            "type": [
              "string",
              "null"
            ],
            "description": "Taxonomic rank, e.g. \"family\"."
          },
          "common_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Preferred common name, when one is recorded."
          }
        },
        "description": "One rung of the taxonomic path, outermost first.",
        "additionalProperties": false
      },
      "description": "Ancestors from the root of the tree down to the taxon’s parent."
    },
    "is_active": {
      "type": "boolean",
      "description": "False for a taxon superseded by a taxonomic change; its id still resolves."
    },
    "rank_level": {
      "type": [
        "number",
        "null"
      ],
      "description": "Numeric rank level — 70 kingdom, 30 family, 10 species, 5 subspecies."
    },
    "common_name": {
      "type": [
        "string",
        "null"
      ],
      "description": "Preferred common name, when one is recorded."
    },
    "conservation": {
      "type": "object",
      "required": [
        "statuses",
        "global_status"
      ],
      "properties": {
        "statuses": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "status",
              "authority",
              "iucn",
              "place",
              "url"
            ],
            "properties": {
              "url": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Source page for the listing, when published."
              },
              "iucn": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "IUCN-normalised level upstream assigns this listing, on its own numeric scale."
              },
              "place": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Place the listing applies to. Null for a listing with global scope."
              },
              "status": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Authority-specific status, e.g. \"Special Concern\" or \"G4\"; distinct from the normalised csi filter."
              },
              "authority": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The body that published this listing."
              }
            },
            "description": "One conservation listing, by authority and place.",
            "additionalProperties": false
          },
          "description": "Every listing upstream records, one per authority and place."
        },
        "global_status": {
          "anyOf": [
            {
              "type": "object",
              "required": [
                "status",
                "authority",
                "iucn",
                "place",
                "url"
              ],
              "properties": {
                "url": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Source page for the listing, when published."
                },
                "iucn": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "description": "IUCN-normalised level upstream assigns this listing, on its own numeric scale."
                },
                "place": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Place the listing applies to. Null for a listing with global scope."
                },
                "status": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Authority-specific status, e.g. \"Special Concern\" or \"G4\"; distinct from the normalised csi filter."
                },
                "authority": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "The body that published this listing."
                }
              },
              "description": "One conservation listing, by authority and place.",
              "additionalProperties": false
            },
            {
              "type": "null"
            }
          ],
          "description": "Upstream global listing; null when none is recorded."
        }
      },
      "description": "Conservation listings for the taxon.",
      "additionalProperties": false
    },
    "encyclopedia": {
      "type": "object",
      "required": [
        "wikipedia_summary",
        "wikipedia_url"
      ],
      "properties": {
        "wikipedia_url": {
          "type": [
            "string",
            "null"
          ],
          "description": "Wikipedia page for the taxon."
        },
        "wikipedia_summary": {
          "type": [
            "string",
            "null"
          ],
          "description": "Verbatim encyclopedia text, including literal HTML tags."
        }
      },
      "description": "The encyclopedia text and link upstream carries for the taxon.",
      "additionalProperties": false
    },
    "sections_applied": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Sections this response carries. Empty when the whole profile came back, so an absent section means the taxon has none rather than that it was never asked for."
    },
    "iconic_taxon_name": {
      "type": [
        "string",
        "null"
      ],
      "description": "Broad organism group, e.g. \"Insecta\". Usable as an iconic_taxa filter value."
    },
    "listed_taxa_count": {
      "type": [
        "number",
        "null"
      ],
      "description": "Number of place checklists containing this taxon."
    },
    "observations_count": {
      "type": [
        "number",
        "null"
      ],
      "description": "How many observations carry this taxon or a descendant of it."
    }
  },
  "additionalProperties": false
}
inaturalist_get_taxon annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true
}

Prompts

0 advertised

No prompt definitions available.

Resources

1 advertised

inaturalist-guide

Advertised by the server during the last successful anonymous check.

Use inaturalist_* tools to compare local wildlife records, chart annotated life stages, or assess community identification evidence. Resolve identifiers across calls and check cohort, annotation, and coverage gates before drawing conclusions.

inaturalist-guide URI
skill://inaturalist-guide/SKILL.md

MIME type: text/markdown

inaturalist-taxon — inaturalist-taxon

Advertised by the server during the last successful anonymous check.

Taxon profile by numeric iNaturalist taxon id — taxonomic path, per-authority conservation listings, encyclopedia summary, photo gallery, immediate children, and observation counts. The whole projected document, whatever its size: a resource read has no way to name sections, so use inaturalist_get_taxon when the outline-and-sections path matters.

inaturalist-taxon URI template
inaturalist://taxa/{taxon_id}

MIME type: application/json

inaturalist-observation — inaturalist-observation

Advertised by the server during the last successful anonymous check.

One iNaturalist observation by numeric id, with its community identification thread expanded — who identified what, whether each identification agrees, and the consensus taxon — plus the observer’s description and filled observation fields. The thread keeps its first 40 identifications and the list its first 40 filled fields, both in upstream order; identifications_total beside identifications_shown, and observation_fields_total beside observation_fields_shown, say whether either was cut, and the record’s url opens the full record. An obscured coordinate is a locality with an accuracy radius, never a sighting position, and a null license_code means all rights reserved.

inaturalist-observation URI template
inaturalist://observations/{observation_id}

MIME type: application/json

io.modelcontextprotocol/skills

Advertised by the server during the last successful anonymous check.

io.modelcontextprotocol/skills URI template
skill://{+path}

90-day uptime

A lightweight connection check about every six hours, sampled on hosts with many listings. It shows the server answered, not that its tools work.

Too few checks for a percentage yet (1 of 1 answered).

  1. 2026-11-07: 1 of 1 checks answered

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
604 ms
95th percentile latency
604 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 604 ms · metadata changed · 10 tool(s), 1 resource(s), 3 resource template(s), 0 prompt(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http inaturalist-mcp-server https://inaturalist.caseyjhand.com/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add inaturalist-mcp-server --url https://inaturalist.caseyjhand.com/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable inaturalist-mcp-server in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "inaturalist-mcp-server": {
      "url": "https://inaturalist.caseyjhand.com/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "inaturalist-mcp-server": {
      "type": "streamableHttp",
      "url": "https://inaturalist.caseyjhand.com/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start inaturalist-mcp-server and inspect its tools.
VS Code configuration
{
  "servers": {
    "inaturalist-mcp-server": {
      "type": "http",
      "url": "https://inaturalist.caseyjhand.com/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http inaturalist-mcp-server https://inaturalist.caseyjhand.com/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://inaturalist.caseyjhand.com/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "inaturalist-mcp-server": {
      "serverUrl": "https://inaturalist.caseyjhand.com/mcp"
    }
  }
}

Let your agent find its tools

Find servers like inaturalist-mcp-server from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.