Server definition
- Hash
- sha256:be756098a1d289f1127b36599d25c6d9bdfa22a47878650beea81db5c31b5a55
- What it is
- What a remote MCP server returned when asked what it offers: 10 tools
The blob, as servednamed by its sha256
{
"instructions": "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; widen them deliberately. 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. 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": [
{
"description": "Resolve a place name to a place id, or list the places containing a map area. Pass q to match a place-name PREFIX, or all four of nelat, nelng, swlat and swlng to list every place covering that box — exactly one of the two, never both. Each result carries the bounding box, place type, and containment chain an area search needs. Place geometry is stripped: a single nearby response carries 247 KB of boundary polygons upstream, none of which reaches the caller.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"nelat": {
"description": "North-east corner latitude of the map area, at or north of swlat. All four corners or none.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"nelng": {
"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.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"per_page": {
"default": 10,
"description": "Maximum places per list. Honoured on the bounding-box arm only, where it bounds the standard and community lists separately, so up to twice this many places come back. The name-prefix endpoint publishes no page size and returns a fixed page.",
"maximum": 30,
"minimum": 1,
"type": "integer"
},
"q": {
"description": "Place-name prefix to search. Matches the start of a name, not words inside it. Mutually exclusive with the bounding box.",
"maxLength": 100,
"minLength": 1,
"type": "string"
},
"swlat": {
"description": "South-west corner latitude of the map area. All four corners or none.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"swlng": {
"description": "South-west corner longitude of the map area. All four corners or none.",
"maximum": 180,
"minimum": -180,
"type": "number"
}
},
"type": "object"
},
"name": "inaturalist_find_places",
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"totalCount",
"truncated",
"shown",
"cap"
]
},
{
"required": [
"error"
]
}
],
"properties": {
"cap": {
"description": "The most places this response could carry — per_page × 2 on the bounding-box arm, where per_page bounds each list separately; the fixed page upstream served on the name-prefix arm.",
"type": "number"
},
"community": {
"description": "Member-created places covering the area. Present on the bounding-box arm.",
"items": {
"additionalProperties": false,
"description": "One place, with the bounding box and containment chain an area search needs.",
"properties": {
"admin_level": {
"description": "Raw administrative-level integer. No published code table; often null.",
"type": [
"number",
"null"
]
},
"ancestor_place_ids": {
"description": "Containment chain, outermost first. Empty when upstream records none.",
"items": {
"type": "number"
},
"type": "array"
},
"bbox": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"nelat": {
"description": "North-east corner latitude.",
"type": "number"
},
"nelng": {
"description": "North-east corner longitude.",
"type": "number"
},
"swlat": {
"description": "South-west corner latitude.",
"type": "number"
},
"swlng": {
"description": "South-west corner longitude.",
"type": "number"
}
},
"required": [
"swlat",
"swlng",
"nelat",
"nelng"
],
"type": "object"
},
{
"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."
},
"display_name": {
"description": "Place name with its administrative context, e.g. \"Seattle CCD, US, WA\".",
"type": [
"string",
"null"
]
},
"id": {
"description": "Place id — pass it as place_id to any area-scoped tool.",
"type": "number"
},
"location": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"lat": {
"description": "Centre latitude.",
"type": "number"
},
"lng": {
"description": "Centre longitude.",
"type": "number"
}
},
"required": [
"lat",
"lng"
],
"type": "object"
},
{
"type": "null"
}
],
"description": "Centre point of the place."
},
"name": {
"description": "Place name as iNaturalist records it.",
"type": [
"string",
"null"
]
},
"place_type": {
"description": "Raw place-type integer. iNaturalist publishes no code table for it, so no label is invented — display_name carries the meaning.",
"type": [
"number",
"null"
]
},
"slug": {
"description": "URL slug. The place record publishes no URL of its own.",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"name",
"display_name",
"place_type",
"admin_level",
"bbox",
"ancestor_place_ids",
"location",
"slug"
],
"type": "object"
},
"type": "array"
},
"error": {
"additionalProperties": {},
"description": "Present when the call failed. Absent on success.",
"properties": {
"code": {
"description": "JSON-RPC error code for this failure.",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"type": "integer"
},
"data": {
"additionalProperties": {},
"properties": {
"reason": {
"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.",
"examples": [
"invalid_geography"
],
"type": "string"
},
"recovery": {
"additionalProperties": {},
"description": "Actionable next step for the caller.",
"properties": {
"hint": {
"type": "string"
}
},
"required": [
"hint"
],
"type": "object"
},
"retryable": {
"description": "Whether retrying may succeed.",
"type": "boolean"
}
},
"type": "object"
},
"message": {
"description": "Human-readable description of what went wrong.",
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"notice": {
"description": "Guidance when nothing matched, or when the page capped the result set.",
"type": "string"
},
"places": {
"description": "Name-prefix matches. Present on the q arm.",
"items": {
"additionalProperties": false,
"description": "One place, with the bounding box and containment chain an area search needs.",
"properties": {
"admin_level": {
"description": "Raw administrative-level integer. No published code table; often null.",
"type": [
"number",
"null"
]
},
"ancestor_place_ids": {
"description": "Containment chain, outermost first. Empty when upstream records none.",
"items": {
"type": "number"
},
"type": "array"
},
"bbox": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"nelat": {
"description": "North-east corner latitude.",
"type": "number"
},
"nelng": {
"description": "North-east corner longitude.",
"type": "number"
},
"swlat": {
"description": "South-west corner latitude.",
"type": "number"
},
"swlng": {
"description": "South-west corner longitude.",
"type": "number"
}
},
"required": [
"swlat",
"swlng",
"nelat",
"nelng"
],
"type": "object"
},
{
"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."
},
"display_name": {
"description": "Place name with its administrative context, e.g. \"Seattle CCD, US, WA\".",
"type": [
"string",
"null"
]
},
"id": {
"description": "Place id — pass it as place_id to any area-scoped tool.",
"type": "number"
},
"location": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"lat": {
"description": "Centre latitude.",
"type": "number"
},
"lng": {
"description": "Centre longitude.",
"type": "number"
}
},
"required": [
"lat",
"lng"
],
"type": "object"
},
{
"type": "null"
}
],
"description": "Centre point of the place."
},
"name": {
"description": "Place name as iNaturalist records it.",
"type": [
"string",
"null"
]
},
"place_type": {
"description": "Raw place-type integer. iNaturalist publishes no code table for it, so no label is invented — display_name carries the meaning.",
"type": [
"number",
"null"
]
},
"slug": {
"description": "URL slug. The place record publishes no URL of its own.",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"name",
"display_name",
"place_type",
"admin_level",
"bbox",
"ancestor_place_ids",
"location",
"slug"
],
"type": "object"
},
"type": "array"
},
"shown": {
"description": "How many places this response carries.",
"type": "number"
},
"standard": {
"description": "Curated administrative places covering the area. Present on the bounding-box arm.",
"items": {
"additionalProperties": false,
"description": "One place, with the bounding box and containment chain an area search needs.",
"properties": {
"admin_level": {
"description": "Raw administrative-level integer. No published code table; often null.",
"type": [
"number",
"null"
]
},
"ancestor_place_ids": {
"description": "Containment chain, outermost first. Empty when upstream records none.",
"items": {
"type": "number"
},
"type": "array"
},
"bbox": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"nelat": {
"description": "North-east corner latitude.",
"type": "number"
},
"nelng": {
"description": "North-east corner longitude.",
"type": "number"
},
"swlat": {
"description": "South-west corner latitude.",
"type": "number"
},
"swlng": {
"description": "South-west corner longitude.",
"type": "number"
}
},
"required": [
"swlat",
"swlng",
"nelat",
"nelng"
],
"type": "object"
},
{
"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."
},
"display_name": {
"description": "Place name with its administrative context, e.g. \"Seattle CCD, US, WA\".",
"type": [
"string",
"null"
]
},
"id": {
"description": "Place id — pass it as place_id to any area-scoped tool.",
"type": "number"
},
"location": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"lat": {
"description": "Centre latitude.",
"type": "number"
},
"lng": {
"description": "Centre longitude.",
"type": "number"
}
},
"required": [
"lat",
"lng"
],
"type": "object"
},
{
"type": "null"
}
],
"description": "Centre point of the place."
},
"name": {
"description": "Place name as iNaturalist records it.",
"type": [
"string",
"null"
]
},
"place_type": {
"description": "Raw place-type integer. iNaturalist publishes no code table for it, so no label is invented — display_name carries the meaning.",
"type": [
"number",
"null"
]
},
"slug": {
"description": "URL slug. The place record publishes no URL of its own.",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"name",
"display_name",
"place_type",
"admin_level",
"bbox",
"ancestor_place_ids",
"location",
"slug"
],
"type": "object"
},
"type": "array"
},
"totalCount": {
"description": "Places upstream reports. On the name-prefix arm, every match before the fixed page; on the bounding-box arm, only the places returned (standard plus community), so it is bounded by the page size rather than a full count.",
"type": "number"
},
"truncated": {
"description": "True when more places may exist than were returned — on the bounding-box arm, when the standard or community list reached per_page.",
"type": "boolean"
}
},
"type": "object"
}
},
{
"description": "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; the absolute intervals (year, month, week, day, hour) bucket real dates and upstream applies a default start date to them. 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.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"captive": {
"default": false,
"description": "Whether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only.",
"type": "boolean"
},
"d1": {
"description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2. With interval set to day or hour, a wide range can exceed the 800-bucket cap — narrow d1/d2 to reach buckets past it.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"type": "string"
},
"d2": {
"description": "Latest observation date, YYYY-MM-DD. Inclusive.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"type": "string"
},
"date_field": {
"default": "observed",
"description": "Which date to bucket by: when the organism was observed, or when the record was uploaded.",
"enum": [
"observed",
"created"
],
"type": "string"
},
"iconic_taxa": {
"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.",
"items": {
"enum": [
"Actinopterygii",
"Amphibia",
"Animalia",
"Arachnida",
"Aves",
"Chromista",
"Fungi",
"Insecta",
"Mammalia",
"Mollusca",
"Plantae",
"Protozoa",
"Reptilia",
"unknown"
],
"type": "string"
},
"type": "array"
},
"interval": {
"default": "month_of_year",
"description": "Bucketing. month_of_year and week_of_year fold every year together into a seasonal curve; the rest bucket absolute dates. day and hour over a wide date range can generate thousands of buckets — the response is capped at 800, kept from the start of the range; narrow d1/d2 or use a coarser interval to see the rest.",
"enum": [
"year",
"month",
"week",
"day",
"hour",
"month_of_year",
"week_of_year"
],
"type": "string"
},
"lat": {
"description": "Latitude of the search centre, in decimal degrees. Requires lng and radius.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"lng": {
"description": "Longitude of the search centre, in decimal degrees. Requires lat and radius.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"nelat": {
"description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"nelng": {
"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.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"place_id": {
"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.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"quality_grade": {
"default": [
"research"
],
"description": "Identification confidence tiers to include. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence.",
"items": {
"enum": [
"research",
"needs_id",
"casual"
],
"type": "string"
},
"minItems": 1,
"type": "array"
},
"radius": {
"description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.",
"maximum": 500,
"type": "number"
},
"swlat": {
"description": "South-west corner latitude of the bounding box. All four corners or none.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"swlng": {
"description": "South-west corner longitude of the bounding box. All four corners or none.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"taxon_id": {
"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.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"term_id": {
"description": "Annotation attribute ids, from inaturalist_list_reference topic controlled_terms — e.g. 1 for Life Stage.",
"items": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"type": "array"
},
"term_value_id": {
"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.",
"items": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"type": "array"
}
},
"type": "object"
},
"name": "inaturalist_get_histogram",
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"interval",
"buckets",
"total",
"applied_filters",
"truncated",
"shown",
"cap"
]
},
{
"required": [
"error"
]
}
],
"properties": {
"applied_filters": {
"additionalProperties": false,
"description": "The server-applied defaults that determine what this answer means.",
"properties": {
"captive": {
"description": "Whether captive and cultivated records were included.",
"type": "boolean"
},
"date_field": {
"description": "Which date the buckets were built from.",
"type": "string"
},
"quality_grade": {
"description": "Identification tiers actually searched.",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"quality_grade",
"captive",
"date_field"
],
"type": "object"
},
"buckets": {
"description": "Every bucket upstream returned, in order, including the zero ones — up to 800, the first in upstream key order. See the truncated/shown/cap enrichment when more exist.",
"items": {
"additionalProperties": false,
"description": "One histogram bucket.",
"properties": {
"count": {
"description": "Matching observations in this bucket.",
"type": "number"
},
"key": {
"description": "Bucket label, in upstream order — \"1\"…\"12\" for month_of_year, a date for the absolute intervals.",
"type": "string"
}
},
"required": [
"key",
"count"
],
"type": "object"
},
"type": "array"
},
"cap": {
"description": "The bucket cap that was applied.",
"type": "number"
},
"error": {
"additionalProperties": {},
"description": "Present when the call failed. Absent on success.",
"properties": {
"code": {
"description": "JSON-RPC error code for this failure.",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"type": "integer"
},
"data": {
"additionalProperties": {},
"properties": {
"reason": {
"description": "Machine-readable failure mode. Declared by this tool: `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. `unknown_taxon_id`: iNaturalist answered 422 because the taxon_id does not exist. Other values are possible when a failure originates below the handler.",
"examples": [
"invalid_geography",
"inverted_date_range",
"unpaired_annotation_value",
"unknown_taxon_id"
],
"type": "string"
},
"recovery": {
"additionalProperties": {},
"description": "Actionable next step for the caller.",
"properties": {
"hint": {
"type": "string"
}
},
"required": [
"hint"
],
"type": "object"
},
"retryable": {
"description": "Whether retrying may succeed.",
"type": "boolean"
}
},
"type": "object"
},
"message": {
"description": "Human-readable description of what went wrong.",
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"interval": {
"description": "The bucketing that was applied.",
"enum": [
"year",
"month",
"week",
"day",
"hour",
"month_of_year",
"week_of_year"
],
"type": "string"
},
"notice": {
"description": "Guidance when every bucket came back zero, or when the cap was reached.",
"type": "string"
},
"shown": {
"description": "How many buckets this response carries.",
"type": "number"
},
"total": {
"description": "Sum of every bucket count upstream returned, including buckets past the cap that are not in the buckets array.",
"type": "number"
},
"truncated": {
"description": "True when upstream returned more than 800 buckets.",
"type": "boolean"
}
},
"type": "object"
}
},
{
"description": "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.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"d1": {
"description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"type": "string"
},
"d2": {
"description": "Latest observation date, YYYY-MM-DD. Inclusive.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"type": "string"
},
"kind": {
"description": "Which leaderboard: \"observers\" ranks by observations recorded, \"identifiers\" by identifications made.",
"enum": [
"observers",
"identifiers"
],
"type": "string"
},
"lat": {
"description": "Latitude of the search centre, in decimal degrees. Requires lng and radius.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"lng": {
"description": "Longitude of the search centre, in decimal degrees. Requires lat and radius.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"nelat": {
"description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"nelng": {
"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.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"page": {
"default": 1,
"description": "Page number. Defaults to 1.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"per_page": {
"default": 25,
"description": "Entries per page, maximum 250. An entry costs roughly 140 bytes across structuredContent and the rendered text together, so 250 is a full page near 34 KB — and two such pages cover the whole 500-entry window these endpoints rank.",
"maximum": 250,
"minimum": 1,
"type": "integer"
},
"place_id": {
"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.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"quality_grade": {
"default": [
"research"
],
"description": "Identification confidence tiers to include. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence.",
"items": {
"enum": [
"research",
"needs_id",
"casual"
],
"type": "string"
},
"minItems": 1,
"type": "array"
},
"radius": {
"description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.",
"maximum": 500,
"type": "number"
},
"swlat": {
"description": "South-west corner latitude of the bounding box. All four corners or none.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"swlng": {
"description": "South-west corner longitude of the bounding box. All four corners or none.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"taxon_id": {
"description": "Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
}
},
"required": [
"kind"
],
"type": "object"
},
"name": "inaturalist_get_leaderboard",
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"kind",
"count_metric",
"total_results",
"entries",
"applied_filters",
"truncated",
"shown",
"cap"
]
},
{
"required": [
"error"
]
}
],
"properties": {
"applied_filters": {
"additionalProperties": false,
"description": "The server-applied default that determines what this answer means.",
"properties": {
"quality_grade": {
"description": "Identification tiers actually searched.",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"quality_grade"
],
"type": "object"
},
"cap": {
"description": "The per_page that was applied.",
"type": "number"
},
"count_metric": {
"description": "What the count on each entry measures.",
"enum": [
"observations",
"identifications"
],
"type": "string"
},
"entries": {
"description": "The ranked members, most active first.",
"items": {
"additionalProperties": false,
"description": "One ranked member.",
"properties": {
"count": {
"description": "Observations recorded, or identifications made — see count_metric.",
"type": "number"
},
"login": {
"description": "The member’s login. No other profile field is relayed.",
"type": [
"string",
"null"
]
},
"rank": {
"description": "Absolute rank across the leaderboard, counted from page 1.",
"type": "number"
},
"species_count": {
"description": "Distinct species this observer recorded. Present on the observers arm only; the identifiers endpoint publishes none.",
"type": "number"
}
},
"required": [
"rank",
"login",
"count"
],
"type": "object"
},
"type": "array"
},
"error": {
"additionalProperties": {},
"description": "Present when the call failed. Absent on success.",
"properties": {
"code": {
"description": "JSON-RPC error code for this failure.",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"type": "integer"
},
"data": {
"additionalProperties": {},
"properties": {
"reason": {
"description": "Machine-readable failure mode. Declared by this tool: `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.",
"examples": [
"invalid_geography",
"inverted_date_range",
"leaderboard_window_exceeded",
"unknown_taxon_id"
],
"type": "string"
},
"recovery": {
"additionalProperties": {},
"description": "Actionable next step for the caller.",
"properties": {
"hint": {
"type": "string"
}
},
"required": [
"hint"
],
"type": "object"
},
"retryable": {
"description": "Whether retrying may succeed.",
"type": "boolean"
}
},
"type": "object"
},
"message": {
"description": "Human-readable description of what went wrong.",
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"kind": {
"description": "Which leaderboard was ranked.",
"enum": [
"observers",
"identifiers"
],
"type": "string"
},
"notice": {
"description": "Guidance when nobody matched, when the page is past the last one holding entries, or how to reach further down the ranking.",
"type": "string"
},
"shown": {
"description": "How many entries this page carries.",
"type": "number"
},
"total_results": {
"description": "How many people upstream reports as matching. Far larger than the 500 this leaderboard can actually address.",
"type": "number"
},
"truncated": {
"description": "True when the page filled per_page and more entries follow.",
"type": "boolean"
}
},
"type": "object"
}
},
{
"description": "Fetch up to 10 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 batch costs one upstream request, so resolving ten ids here is far cheaper than ten separate lookups. Records come back in the requested order. A missing id is reported per id in unresolved rather than failing the batch; the call fails only when nothing resolved. Long threads and long observation-field lists are cut to fit one response budget shared across the batch — up to 40 identifications, 40 comments, and 40 filled fields for a single id, 4 of each per record for ten — and every record reports the size of each array beside what it kept.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"include": {
"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.",
"items": {
"enum": [
"identifications",
"comments",
"photos",
"annotations",
"sounds"
],
"type": "string"
},
"type": "array"
},
"observation_id": {
"description": "Observation ids to fetch, 1 to 10. Find current ids for an area with inaturalist_search_observations.",
"items": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"maxItems": 10,
"minItems": 1,
"type": "array"
}
},
"required": [
"observation_id"
],
"type": "object"
},
"name": "inaturalist_get_observation",
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"observations",
"unresolved"
]
},
{
"required": [
"error"
]
}
],
"properties": {
"error": {
"additionalProperties": {},
"description": "Present when the call failed. Absent on success.",
"properties": {
"code": {
"description": "JSON-RPC error code for this failure.",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"type": "integer"
},
"data": {
"additionalProperties": {},
"properties": {
"reason": {
"description": "Machine-readable failure mode. Declared by this tool: `not_found`: None of the requested ids resolved to an observation. Other values are possible when a failure originates below the handler.",
"examples": [
"not_found"
],
"type": "string"
},
"recovery": {
"additionalProperties": {},
"description": "Actionable next step for the caller.",
"properties": {
"hint": {
"type": "string"
}
},
"required": [
"hint"
],
"type": "object"
},
"retryable": {
"description": "Whether retrying may succeed.",
"type": "boolean"
}
},
"type": "object"
},
"message": {
"description": "Human-readable description of what went wrong.",
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"notice": {
"description": "Guidance when part of the batch did not resolve, or when a thread or observation-field list was cut to fit the response.",
"type": "string"
},
"observations": {
"description": "The observations that resolved, in the requested order with unresolved ids left out, carrying the expansions that were requested.",
"items": {
"additionalProperties": false,
"description": "One projected observation record.",
"properties": {
"agreements": {
"description": "How many identifications currently agree with the community taxon.",
"type": "number"
},
"annotations": {
"description": "Decoded annotations. Present when \"annotations\" was included.",
"items": {
"additionalProperties": false,
"description": "One decoded annotation on the record.",
"properties": {
"attribute": {
"description": "Decoded attribute label, e.g. \"Life Stage\". Null when the id is not in the vocabulary.",
"type": [
"string",
"null"
]
},
"attribute_id": {
"description": "Attribute id, usable as term_id on the search tools.",
"type": "number"
},
"by": {
"description": "Login of the member who added the annotation.",
"type": [
"string",
"null"
]
},
"value": {
"description": "Decoded value label, e.g. \"Larva\". Null when the id is not in the vocabulary.",
"type": [
"string",
"null"
]
},
"value_id": {
"description": "Value id, usable as term_value_id on the search tools.",
"type": "number"
}
},
"required": [
"attribute",
"value",
"attribute_id",
"value_id",
"by"
],
"type": "object"
},
"type": "array"
},
"captive": {
"description": "True for a zoo animal, a garden planting, or other cultivation.",
"type": "boolean"
},
"comments": {
"description": "Discussion comments, cut to their first entries in upstream order (not strictly chronological) when they exceed the per-record share of a 40-entry budget. Present when \"comments\" was included.",
"items": {
"additionalProperties": false,
"description": "One discussion comment on the record.",
"properties": {
"body": {
"description": "Free-text comment body.",
"type": [
"string",
"null"
]
},
"by": {
"description": "Login of the commenter.",
"type": [
"string",
"null"
]
},
"created_at": {
"description": "When the comment was posted, ISO 8601.",
"type": [
"string",
"null"
]
},
"id": {
"description": "Comment id.",
"type": "number"
}
},
"required": [
"id",
"by",
"body",
"created_at"
],
"type": "object"
},
"type": "array"
},
"comments_shown": {
"description": "How many of them comments carries. Below comments_total when the thread was cut. Present when \"comments\" was included.",
"type": "number"
},
"comments_total": {
"description": "How many comments upstream holds on the record. Present when \"comments\" was included.",
"type": "number"
},
"community_taxon": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"common_name": {
"description": "Preferred common name, when one is recorded.",
"type": [
"string",
"null"
]
},
"iconic_taxon_name": {
"description": "Broad organism group, e.g. \"Insecta\". Usable as an iconic_taxa filter value.",
"type": [
"string",
"null"
]
},
"id": {
"description": "Taxon id — the identifier every taxon-scoped filter takes.",
"type": "number"
},
"name": {
"description": "Scientific name.",
"type": [
"string",
"null"
]
},
"rank": {
"description": "Taxonomic rank, e.g. \"species\".",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"name",
"rank",
"common_name",
"iconic_taxon_name"
],
"type": "object"
},
{
"type": "null"
}
],
"description": "Consensus taxon, resolved. Present on the by-id tool; null when the thread has reached none."
},
"community_taxon_id": {
"description": "Consensus taxon id. Differs from taxon.id while a thread is contested.",
"type": [
"number",
"null"
]
},
"coordinate": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"accuracy_m": {
"description": "Public positional accuracy radius in metres. On an obscured record this is tens of kilometres and the point is a locality, not a sighting position.",
"type": [
"number",
"null"
]
},
"lat": {
"description": "Latitude in decimal degrees.",
"type": "number"
},
"lng": {
"description": "Longitude in decimal degrees.",
"type": "number"
}
},
"required": [
"lat",
"lng",
"accuracy_m"
],
"type": "object"
},
{
"type": "null"
}
],
"description": "Public coordinate. Null when the record carries none."
},
"description": {
"description": "The observer’s own note on the sighting — host plant, behaviour, habitat, count. Third-party free text. Present on the by-id tool; null when the observer wrote none.",
"type": [
"string",
"null"
]
},
"disagreements": {
"description": "How many identifications currently disagree with the community taxon.",
"type": "number"
},
"geoprivacy": {
"description": "Observer-set coordinate privacy: obscured, obscured_private, open, or private.",
"type": [
"string",
"null"
]
},
"id": {
"description": "Observation id. Also the cursor value for deep pagination.",
"type": "number"
},
"identification_disagreements_count": {
"description": "Count of disagreeing identifications as upstream tallies it. Present on the by-id tool.",
"type": "number"
},
"identifications": {
"description": "The identification thread, cut to its first entries in upstream order (roughly but not strictly chronological) when it exceeds the per-record share of a 40-entry budget. Present when \"identifications\" was included.",
"items": {
"additionalProperties": false,
"description": "One identification in the community thread.",
"properties": {
"body": {
"description": "Free-text note written by the identifier.",
"type": [
"string",
"null"
]
},
"by": {
"description": "Login of the identifier.",
"type": [
"string",
"null"
]
},
"category": {
"description": "How this identification moved the thread: improving, supporting, leading, or maverick.",
"type": [
"string",
"null"
]
},
"created_at": {
"description": "When the identification was added, ISO 8601.",
"type": [
"string",
"null"
]
},
"current": {
"description": "True when this is the identifier’s current identification on the record.",
"type": "boolean"
},
"disagreement": {
"description": "True when the identifier explicitly disagreed with the preceding taxon.",
"type": [
"boolean",
"null"
]
},
"from_vision": {
"description": "True when the identification came from the upstream image classifier.",
"type": "boolean"
},
"id": {
"description": "Identification id.",
"type": "number"
},
"taxon": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"common_name": {
"description": "Preferred common name, when one is recorded.",
"type": [
"string",
"null"
]
},
"iconic_taxon_name": {
"description": "Broad organism group, e.g. \"Insecta\". Usable as an iconic_taxa filter value.",
"type": [
"string",
"null"
]
},
"id": {
"description": "Taxon id — the identifier every taxon-scoped filter takes.",
"type": "number"
},
"name": {
"description": "Scientific name.",
"type": [
"string",
"null"
]
},
"rank": {
"description": "Taxonomic rank, e.g. \"species\".",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"name",
"rank",
"common_name",
"iconic_taxon_name"
],
"type": "object"
},
{
"type": "null"
}
],
"description": "Taxon this identification proposes."
}
},
"required": [
"id",
"taxon",
"by",
"current",
"category",
"disagreement",
"from_vision",
"body",
"created_at"
],
"type": "object"
},
"type": "array"
},
"identifications_count": {
"description": "Upstream’s tally of identifications currently agreeing or disagreeing with the community taxon — agreements + disagreements. Not the thread size: it leaves out the observer’s own identification and any that neither agrees nor disagrees, such as a coarser or withdrawn one. The thread size is identifications_total, on inaturalist_get_observation.",
"type": "number"
},
"identifications_shown": {
"description": "How many of them identifications carries. Below identifications_total when the thread was cut. Present when \"identifications\" was included.",
"type": "number"
},
"identifications_total": {
"description": "How many identifications upstream holds on the record — the thread size. Present when \"identifications\" was included.",
"type": "number"
},
"license_code": {
"description": "Licence of the observation record itself. Null means all rights reserved.",
"type": [
"string",
"null"
]
},
"obscured": {
"description": "True when the true coordinate is withheld, typically for a threatened taxon. The point is never resolved or approximated.",
"type": "boolean"
},
"observation_fields": {
"description": "Observation-field values filled in on the record, usually by a project; fields left blank are dropped. Cut to the first filled fields in upstream order when they exceed the per-record share of a 40-entry budget. Present on the by-id tool.",
"items": {
"additionalProperties": false,
"description": "One filled observation field.",
"properties": {
"name": {
"description": "Field name, as its creator wrote it, e.g. \"Habitat_Description\".",
"type": [
"string",
"null"
]
},
"value": {
"description": "The value filled in, verbatim.",
"type": "string"
}
},
"required": [
"name",
"value"
],
"type": "object"
},
"type": "array"
},
"observation_fields_shown": {
"description": "How many of them observation_fields carries. Below observation_fields_total when the list was cut. Present on the by-id tool.",
"type": "number"
},
"observation_fields_total": {
"description": "How many filled observation fields the record carries. Present on the by-id tool.",
"type": "number"
},
"observed_at": {
"description": "Observation timestamp with offset, ISO 8601.",
"type": [
"string",
"null"
]
},
"observed_on": {
"description": "Observation date, YYYY-MM-DD. Null when the observer recorded no date.",
"type": [
"string",
"null"
]
},
"observer": {
"description": "Login of the observer. The rest of the upstream profile is not relayed.",
"type": [
"string",
"null"
]
},
"photo": {
"anyOf": [
{
"additionalProperties": false,
"description": "A photo with the attribution and licence that must travel with it.",
"properties": {
"attribution": {
"description": "Attribution string, verbatim and never reformatted. Reproduce it with any use of the image.",
"type": [
"string",
"null"
]
},
"license_code": {
"description": "Photo licence code. Null means all rights reserved, independent of the record.",
"type": [
"string",
"null"
]
},
"medium_url": {
"description": "Medium variant. Supplied by upstream where it publishes every size, otherwise derived by substituting the size qualifier in the path. Absent when the path did not match the documented shape.",
"type": "string"
},
"open": {
"description": "True when the photo is served from the host the upstream reserves for open licences. A photo can move hosts when its licence changes, so this reflects fetch time.",
"type": "boolean"
},
"square_url": {
"description": "75px square variant, exactly as upstream published it. Null when absent.",
"type": [
"string",
"null"
]
}
},
"required": [
"square_url",
"attribution",
"license_code",
"open"
],
"type": "object"
},
{
"type": "null"
}
],
"description": "First photo on the record. Null when there are none."
},
"photo_count": {
"description": "How many photos the record carries, so include \"photos\" can be spent knowingly.",
"type": "number"
},
"photos": {
"description": "Every photo on the record. Present when \"photos\" was included.",
"items": {
"additionalProperties": false,
"description": "A photo with the attribution and licence that must travel with it.",
"properties": {
"attribution": {
"description": "Attribution string, verbatim and never reformatted. Reproduce it with any use of the image.",
"type": [
"string",
"null"
]
},
"license_code": {
"description": "Photo licence code. Null means all rights reserved, independent of the record.",
"type": [
"string",
"null"
]
},
"medium_url": {
"description": "Medium variant. Supplied by upstream where it publishes every size, otherwise derived by substituting the size qualifier in the path. Absent when the path did not match the documented shape.",
"type": "string"
},
"open": {
"description": "True when the photo is served from the host the upstream reserves for open licences. A photo can move hosts when its licence changes, so this reflects fetch time.",
"type": "boolean"
},
"square_url": {
"description": "75px square variant, exactly as upstream published it. Null when absent.",
"type": [
"string",
"null"
]
}
},
"required": [
"square_url",
"attribution",
"license_code",
"open"
],
"type": "object"
},
"type": "array"
},
"place_guess": {
"description": "Locality text written by the observer. Third-party free text.",
"type": [
"string",
"null"
]
},
"quality_grade": {
"description": "Identification confidence tier: research, needs_id, or casual.",
"enum": [
"research",
"needs_id",
"casual"
],
"type": "string"
},
"sound_count": {
"description": "How many audio recordings the record carries.",
"type": "number"
},
"sounds": {
"description": "Audio recordings. Present when \"sounds\" was included.",
"items": {
"additionalProperties": false,
"description": "An audio recording with its attribution and licence.",
"properties": {
"attribution": {
"description": "Attribution string, verbatim.",
"type": [
"string",
"null"
]
},
"license_code": {
"description": "Sound licence code. Null means all rights reserved.",
"type": [
"string",
"null"
]
},
"url": {
"description": "Audio file URL. Null when upstream published none.",
"type": [
"string",
"null"
]
}
},
"required": [
"url",
"attribution",
"license_code"
],
"type": "object"
},
"type": "array"
},
"taxon": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"common_name": {
"description": "Preferred common name, when one is recorded.",
"type": [
"string",
"null"
]
},
"iconic_taxon_name": {
"description": "Broad organism group, e.g. \"Insecta\". Usable as an iconic_taxa filter value.",
"type": [
"string",
"null"
]
},
"id": {
"description": "Taxon id — the identifier every taxon-scoped filter takes.",
"type": "number"
},
"name": {
"description": "Scientific name.",
"type": [
"string",
"null"
]
},
"rank": {
"description": "Taxonomic rank, e.g. \"species\".",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"name",
"rank",
"common_name",
"iconic_taxon_name"
],
"type": "object"
},
{
"type": "null"
}
],
"description": "Current identification. Null when nobody has identified the record."
},
"taxon_geoprivacy": {
"description": "Coordinate privacy applied automatically for a threatened taxon. Same vocabulary.",
"type": [
"string",
"null"
]
},
"url": {
"description": "Canonical iNaturalist page for the record.",
"type": [
"string",
"null"
]
},
"uuid": {
"description": "Stable UUID, independent of the id sequence.",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"uuid",
"url",
"observed_on",
"observed_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"
],
"type": "object"
},
"type": "array"
},
"unresolved": {
"description": "Requested ids upstream returned nothing for. They may have been deleted, or never existed.",
"items": {
"additionalProperties": false,
"description": "One id that did not resolve.",
"properties": {
"observation_id": {
"description": "A requested id upstream returned no record for.",
"type": "number"
}
},
"required": [
"observation_id"
],
"type": "object"
},
"type": "array"
}
},
"type": "object"
}
},
{
"description": "List the taxa this one is most often misidentified as, ranked by how many times identifiers made the correction — the field-identification check before committing to a look-alike. Scope it to an area in exactly one form (place_id, the lat/lng/radius triple in kilometres, or a four-corner bounding box) to see the confusion set a specific region actually produces, or leave the area off for the global set. The taxon must be a genus or finer (genus, species, or below) — upstream keeps no confusion set for a family, order, or anything coarser. Resolve the organism name to a taxon id with inaturalist_resolve_name first.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"captive": {
"default": false,
"description": "Whether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only.",
"type": "boolean"
},
"d1": {
"description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"type": "string"
},
"d2": {
"description": "Latest observation date, YYYY-MM-DD. Inclusive.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"type": "string"
},
"lat": {
"description": "Latitude of the search centre, in decimal degrees. Requires lng and radius.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"limit": {
"default": 20,
"description": "Maximum look-alikes to return. Applied in-process — the upstream endpoint publishes no page size and returns its whole confusion set.",
"maximum": 50,
"minimum": 1,
"type": "integer"
},
"lng": {
"description": "Longitude of the search centre, in decimal degrees. Requires lat and radius.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"nelat": {
"description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"nelng": {
"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.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"place_id": {
"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.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"quality_grade": {
"default": [
"research"
],
"description": "Identification confidence tiers to include. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence.",
"items": {
"enum": [
"research",
"needs_id",
"casual"
],
"type": "string"
},
"minItems": 1,
"type": "array"
},
"radius": {
"description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.",
"maximum": 500,
"type": "number"
},
"swlat": {
"description": "South-west corner latitude of the bounding box. All four corners or none.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"swlng": {
"description": "South-west corner longitude of the bounding box. All four corners or none.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"taxon_id": {
"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.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
}
},
"required": [
"taxon_id"
],
"type": "object"
},
"name": "inaturalist_get_similar_species",
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"taxon_id",
"similar_species",
"totalCount",
"truncated",
"shown",
"cap"
]
},
{
"required": [
"error"
]
}
],
"properties": {
"cap": {
"description": "The limit that was applied.",
"type": "number"
},
"error": {
"additionalProperties": {},
"description": "Present when the call failed. Absent on success.",
"properties": {
"code": {
"description": "JSON-RPC error code for this failure.",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"type": "integer"
},
"data": {
"additionalProperties": {},
"properties": {
"reason": {
"description": "Machine-readable failure mode. Declared by this tool: `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.",
"examples": [
"invalid_geography",
"inverted_date_range",
"unknown_taxon_id",
"taxon_rank_too_coarse"
],
"type": "string"
},
"recovery": {
"additionalProperties": {},
"description": "Actionable next step for the caller.",
"properties": {
"hint": {
"type": "string"
}
},
"required": [
"hint"
],
"type": "object"
},
"retryable": {
"description": "Whether retrying may succeed.",
"type": "boolean"
}
},
"type": "object"
},
"message": {
"description": "Human-readable description of what went wrong.",
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"notice": {
"description": "Guidance when no look-alikes are recorded, or when the limit cut the set.",
"type": "string"
},
"shown": {
"description": "How many look-alikes this response carries.",
"type": "number"
},
"similar_species": {
"description": "Look-alikes ranked by misidentification_count, most-confused first.",
"items": {
"additionalProperties": false,
"description": "One look-alike and how often it is confused with the queried taxon.",
"properties": {
"common_name": {
"description": "Preferred common name, when one is recorded.",
"type": [
"string",
"null"
]
},
"misidentification_count": {
"description": "How many times identifiers corrected this taxon to the queried one. The ranking key.",
"type": "number"
},
"name": {
"description": "Scientific name.",
"type": [
"string",
"null"
]
},
"observations_count": {
"description": "How many observations this look-alike has overall. Null when upstream published none.",
"type": [
"number",
"null"
]
},
"photo": {
"additionalProperties": false,
"description": "Representative photo, when the taxon carries one.",
"properties": {
"attribution": {
"description": "Attribution string, verbatim and never reformatted. Reproduce it with any use of the image.",
"type": [
"string",
"null"
]
},
"license_code": {
"description": "Photo licence code. Null means all rights reserved, independent of the record.",
"type": [
"string",
"null"
]
},
"medium_url": {
"description": "Medium variant. Supplied by upstream where it publishes every size, otherwise derived by substituting the size qualifier in the path. Absent when the path did not match the documented shape.",
"type": "string"
},
"open": {
"description": "True when the photo is served from the host the upstream reserves for open licences. A photo can move hosts when its licence changes, so this reflects fetch time.",
"type": "boolean"
},
"square_url": {
"description": "75px square variant, exactly as upstream published it. Null when absent.",
"type": [
"string",
"null"
]
}
},
"required": [
"square_url",
"attribution",
"license_code",
"open"
],
"type": "object"
},
"rank": {
"description": "Taxonomic rank, e.g. \"species\".",
"type": [
"string",
"null"
]
},
"taxon_id": {
"description": "Taxon id of the look-alike — pass it to inaturalist_get_taxon for its profile.",
"type": "number"
}
},
"required": [
"taxon_id",
"name",
"common_name",
"rank",
"observations_count",
"misidentification_count"
],
"type": "object"
},
"type": "array"
},
"taxon_id": {
"description": "The taxon the look-alikes were found for.",
"type": "number"
},
"totalCount": {
"description": "How many look-alikes upstream returned, before the limit was applied.",
"type": "number"
},
"truncated": {
"description": "True when the limit cut the confusion set.",
"type": "boolean"
},
"truncationCeiling": {
"description": "Misidentification count of the last look-alike shown. The ranking is descending, so no omitted look-alike exceeds it.",
"type": "number"
}
},
"type": "object"
}
},
{
"description": "Rank the distinct species recorded in an area and period, most-observed first — the \"what lives here\" answer, without paging through individual sightings. 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 species, use inaturalist_get_leaderboard.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"captive": {
"default": false,
"description": "Whether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only.",
"type": "boolean"
},
"d1": {
"description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"type": "string"
},
"d2": {
"description": "Latest observation date, YYYY-MM-DD. Inclusive.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"type": "string"
},
"iconic_taxa": {
"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.",
"items": {
"enum": [
"Actinopterygii",
"Amphibia",
"Animalia",
"Arachnida",
"Aves",
"Chromista",
"Fungi",
"Insecta",
"Mammalia",
"Mollusca",
"Plantae",
"Protozoa",
"Reptilia",
"unknown"
],
"type": "string"
},
"type": "array"
},
"lat": {
"description": "Latitude of the search centre, in decimal degrees. Requires lng and radius.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"lng": {
"description": "Longitude of the search centre, in decimal degrees. Requires lat and radius.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"nelat": {
"description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"nelng": {
"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.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"page": {
"default": 1,
"description": "Page number. Defaults to 1.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"per_page": {
"default": 25,
"description": "Species per page, maximum 50. A ranked species costs roughly 860 bytes across structuredContent and the rendered text together, so 50 is a full page near 43 KB. Upstream would serve 500 in one page — raise page rather than asking for it.",
"maximum": 50,
"minimum": 1,
"type": "integer"
},
"place_id": {
"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.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"project_id": {
"description": "Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"quality_grade": {
"default": [
"research"
],
"description": "Identification confidence tiers to include. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence.",
"items": {
"enum": [
"research",
"needs_id",
"casual"
],
"type": "string"
},
"minItems": 1,
"type": "array"
},
"radius": {
"description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.",
"maximum": 500,
"type": "number"
},
"swlat": {
"description": "South-west corner latitude of the bounding box. All four corners or none.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"swlng": {
"description": "South-west corner longitude of the bounding box. All four corners or none.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"taxon_id": {
"description": "Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"term_id": {
"description": "Annotation attribute ids, from inaturalist_list_reference topic controlled_terms — e.g. 1 for Life Stage.",
"items": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"type": "array"
},
"term_value_id": {
"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.",
"items": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"type": "array"
},
"user_id": {
"description": "Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"user_login": {
"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.",
"minLength": 1,
"type": "string"
}
},
"type": "object"
},
"name": "inaturalist_get_species_counts",
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"total_results",
"species",
"applied_filters",
"truncated",
"shown",
"cap"
]
},
{
"required": [
"error"
]
}
],
"properties": {
"applied_filters": {
"additionalProperties": false,
"description": "The server-applied defaults that determine what this answer means.",
"properties": {
"captive": {
"description": "Whether captive and cultivated records were included.",
"type": "boolean"
},
"quality_grade": {
"description": "Identification tiers actually searched.",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"quality_grade",
"captive"
],
"type": "object"
},
"cap": {
"description": "The per_page that was applied.",
"type": "number"
},
"error": {
"additionalProperties": {},
"description": "Present when the call failed. Absent on success.",
"properties": {
"code": {
"description": "JSON-RPC error code for this failure.",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"type": "integer"
},
"data": {
"additionalProperties": {},
"properties": {
"reason": {
"description": "Machine-readable failure mode. Declared by this tool: `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.",
"examples": [
"invalid_geography",
"inverted_date_range",
"unpaired_annotation_value",
"conflicting_observer",
"unknown_taxon_id",
"unknown_user",
"unknown_project_id"
],
"type": "string"
},
"recovery": {
"additionalProperties": {},
"description": "Actionable next step for the caller.",
"properties": {
"hint": {
"type": "string"
}
},
"required": [
"hint"
],
"type": "object"
},
"retryable": {
"description": "Whether retrying may succeed.",
"type": "boolean"
}
},
"type": "object"
},
"message": {
"description": "Human-readable description of what went wrong.",
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"notice": {
"description": "Guidance when nothing matched, when the page is past the last one holding species, or how to reach the species beyond this page.",
"type": "string"
},
"shown": {
"description": "How many species this page carries.",
"type": "number"
},
"species": {
"description": "The species, ranked by observation_count, most-observed first, each at its absolute position.",
"items": {
"additionalProperties": false,
"description": "One species and how often it was recorded in the requested area and period.",
"properties": {
"common_name": {
"description": "Preferred common name, when one is recorded.",
"type": [
"string",
"null"
]
},
"iconic_taxon_name": {
"description": "Broad organism group, e.g. \"Aves\". Usable as an iconic_taxa filter value.",
"type": [
"string",
"null"
]
},
"name": {
"description": "Scientific name.",
"type": [
"string",
"null"
]
},
"observation_count": {
"description": "How many matching observations record this taxon. The ranking key.",
"type": "number"
},
"photo": {
"additionalProperties": false,
"description": "Representative photo, when the taxon carries one.",
"properties": {
"attribution": {
"description": "Attribution string, verbatim and never reformatted. Reproduce it with any use of the image.",
"type": [
"string",
"null"
]
},
"license_code": {
"description": "Photo licence code. Null means all rights reserved, independent of the record.",
"type": [
"string",
"null"
]
},
"medium_url": {
"description": "Medium variant. Supplied by upstream where it publishes every size, otherwise derived by substituting the size qualifier in the path. Absent when the path did not match the documented shape.",
"type": "string"
},
"open": {
"description": "True when the photo is served from the host the upstream reserves for open licences. A photo can move hosts when its licence changes, so this reflects fetch time.",
"type": "boolean"
},
"square_url": {
"description": "75px square variant, exactly as upstream published it. Null when absent.",
"type": [
"string",
"null"
]
}
},
"required": [
"square_url",
"attribution",
"license_code",
"open"
],
"type": "object"
},
"position": {
"description": "Absolute place in this ranking, counted from page 1 — 7 is the seventh most-observed species. Not the taxonomic rank, which is rank.",
"type": "number"
},
"rank": {
"description": "Taxonomic rank, e.g. \"species\".",
"type": [
"string",
"null"
]
},
"taxon_id": {
"description": "Taxon id — pass it as taxon_id to any taxon-scoped tool or to inaturalist_get_taxon.",
"type": "number"
}
},
"required": [
"position",
"taxon_id",
"name",
"common_name",
"rank",
"iconic_taxon_name",
"observation_count"
],
"type": "object"
},
"type": "array"
},
"total_results": {
"description": "How many distinct species match. An estimate over a live index — it drifts between calls seconds apart.",
"type": "number"
},
"truncated": {
"description": "True when the page filled per_page and more species follow.",
"type": "boolean"
},
"truncationCeiling": {
"description": "Observation count of the last species shown. The ranking is descending, so no species left off this page exceeds it.",
"type": "number"
}
},
"type": "object"
}
},
{
"description": "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.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"sections": {
"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.",
"items": {
"minLength": 1,
"type": "string"
},
"type": "array"
},
"taxon_id": {
"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.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
}
},
"required": [
"taxon_id"
],
"type": "object"
},
"name": "inaturalist_get_taxon",
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"kind",
"sections_applied"
]
},
{
"required": [
"error"
]
}
],
"properties": {
"children": {
"description": "Immediate children of this taxon.",
"items": {
"additionalProperties": false,
"description": "One immediate child taxon.",
"properties": {
"common_name": {
"description": "Preferred common name, when one is recorded.",
"type": [
"string",
"null"
]
},
"id": {
"description": "Taxon id of this ancestor — usable as taxon_id on any tool.",
"type": "number"
},
"name": {
"description": "Scientific name.",
"type": [
"string",
"null"
]
},
"observations_count": {
"description": "How many observations this child taxon has. Null when upstream published none.",
"type": [
"number",
"null"
]
},
"rank": {
"description": "Taxonomic rank, e.g. \"family\".",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"name",
"rank",
"common_name",
"observations_count"
],
"type": "object"
},
"type": "array"
},
"common_name": {
"description": "Preferred common name, when one is recorded.",
"type": [
"string",
"null"
]
},
"conservation": {
"additionalProperties": false,
"description": "Conservation listings for the taxon.",
"properties": {
"global_status": {
"anyOf": [
{
"additionalProperties": false,
"description": "One conservation listing, by authority and place.",
"properties": {
"authority": {
"description": "The body that published this listing.",
"type": [
"string",
"null"
]
},
"iucn": {
"description": "IUCN-normalised level upstream assigns this listing, on its own numeric scale.",
"type": [
"number",
"null"
]
},
"place": {
"description": "Place the listing applies to. Null for a listing with global scope.",
"type": [
"string",
"null"
]
},
"status": {
"description": "The authority’s own status text — \"Special Concern\", \"G4\", \"Sujeta a protección especial\" are all real values. Not the normalised csi filter vocabulary.",
"type": [
"string",
"null"
]
},
"url": {
"description": "Source page for the listing, when published.",
"type": [
"string",
"null"
]
}
},
"required": [
"status",
"authority",
"iucn",
"place",
"url"
],
"type": "object"
},
{
"type": "null"
}
],
"description": "The listing upstream marks as the taxon’s global status. Null when it records none."
},
"statuses": {
"description": "Every listing upstream records, one per authority and place.",
"items": {
"additionalProperties": false,
"description": "One conservation listing, by authority and place.",
"properties": {
"authority": {
"description": "The body that published this listing.",
"type": [
"string",
"null"
]
},
"iucn": {
"description": "IUCN-normalised level upstream assigns this listing, on its own numeric scale.",
"type": [
"number",
"null"
]
},
"place": {
"description": "Place the listing applies to. Null for a listing with global scope.",
"type": [
"string",
"null"
]
},
"status": {
"description": "The authority’s own status text — \"Special Concern\", \"G4\", \"Sujeta a protección especial\" are all real values. Not the normalised csi filter vocabulary.",
"type": [
"string",
"null"
]
},
"url": {
"description": "Source page for the listing, when published.",
"type": [
"string",
"null"
]
}
},
"required": [
"status",
"authority",
"iucn",
"place",
"url"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"statuses",
"global_status"
],
"type": "object"
},
"encyclopedia": {
"additionalProperties": false,
"description": "The encyclopedia text and link upstream carries for the taxon.",
"properties": {
"wikipedia_summary": {
"description": "Encyclopedia summary, verbatim and containing inline HTML tags. Third-party free text.",
"type": [
"string",
"null"
]
},
"wikipedia_url": {
"description": "Wikipedia page for the taxon.",
"type": [
"string",
"null"
]
}
},
"required": [
"wikipedia_summary",
"wikipedia_url"
],
"type": "object"
},
"error": {
"additionalProperties": {},
"description": "Present when the call failed. Absent on success.",
"properties": {
"code": {
"description": "JSON-RPC error code for this failure.",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"type": "integer"
},
"data": {
"additionalProperties": {},
"properties": {
"reason": {
"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.",
"examples": [
"not_found",
"unknown_section"
],
"type": "string"
},
"recovery": {
"additionalProperties": {},
"description": "Actionable next step for the caller.",
"properties": {
"hint": {
"type": "string"
}
},
"required": [
"hint"
],
"type": "object"
},
"retryable": {
"description": "Whether retrying may succeed.",
"type": "boolean"
}
},
"type": "object"
},
"message": {
"description": "Human-readable description of what went wrong.",
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"extinct": {
"description": "True when the taxon is recorded as extinct.",
"type": "boolean"
},
"iconic_taxon_name": {
"description": "Broad organism group, e.g. \"Insecta\". Usable as an iconic_taxa filter value.",
"type": [
"string",
"null"
]
},
"id": {
"description": "Taxon id.",
"type": "number"
},
"is_active": {
"description": "False for a taxon superseded by a taxonomic change; its id still resolves.",
"type": "boolean"
},
"kind": {
"description": "\"full\" when the profile itself is returned, \"outline\" when it overflowed and only the section list came back.",
"enum": [
"full",
"outline"
],
"type": "string"
},
"listed_taxa_count": {
"description": "How many place checklists include this taxon. The checklist entries themselves are not relayed.",
"type": [
"number",
"null"
]
},
"name": {
"description": "Scientific name.",
"type": [
"string",
"null"
]
},
"notice": {
"description": "How to re-call for specific sections. Present on the outline.",
"type": "string"
},
"observations_count": {
"description": "How many observations carry this taxon or a descendant of it.",
"type": [
"number",
"null"
]
},
"photos": {
"description": "Gallery photos, each with its own licence.",
"items": {
"additionalProperties": false,
"description": "A taxon gallery photo with the attribution and licence that must travel with it.",
"properties": {
"attribution": {
"description": "Attribution string, verbatim and never reformatted. Reproduce it with any use of the image.",
"type": [
"string",
"null"
]
},
"large_url": {
"description": "Large variant, as the taxon endpoint publishes it. Absent when upstream carried none; never derived here.",
"type": "string"
},
"license_code": {
"description": "Photo licence code. Null means all rights reserved, independent of the record.",
"type": [
"string",
"null"
]
},
"medium_url": {
"description": "Medium variant. Supplied by upstream where it publishes every size, otherwise derived by substituting the size qualifier in the path. Absent when the path did not match the documented shape.",
"type": "string"
},
"open": {
"description": "True when the photo is served from the host the upstream reserves for open licences. A photo can move hosts when its licence changes, so this reflects fetch time.",
"type": "boolean"
},
"square_url": {
"description": "75px square variant, exactly as upstream published it. Null when absent.",
"type": [
"string",
"null"
]
}
},
"required": [
"square_url",
"attribution",
"license_code",
"open"
],
"type": "object"
},
"type": "array"
},
"rank": {
"description": "Taxonomic rank, e.g. \"species\".",
"type": [
"string",
"null"
]
},
"rank_level": {
"description": "Numeric rank level — 70 kingdom, 30 family, 10 species, 5 subspecies.",
"type": [
"number",
"null"
]
},
"sections": {
"description": "Available sections and their byte sizes, largest first. Present on the outline.",
"items": {
"additionalProperties": false,
"description": "One section that can be named in a re-call, and what it costs.",
"properties": {
"bytes": {
"description": "Serialized byte size of the section",
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"name": {
"description": "Section identifier — pass in `sections` to retrieve it",
"type": "string"
}
},
"required": [
"name",
"bytes"
],
"type": "object"
},
"type": "array"
},
"sections_applied": {
"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.",
"items": {
"type": "string"
},
"type": "array"
},
"taxonomy": {
"description": "Ancestors from the root of the tree down to the taxon’s parent.",
"items": {
"additionalProperties": false,
"description": "One rung of the taxonomic path, outermost first.",
"properties": {
"common_name": {
"description": "Preferred common name, when one is recorded.",
"type": [
"string",
"null"
]
},
"id": {
"description": "Taxon id of this ancestor — usable as taxon_id on any tool.",
"type": "number"
},
"name": {
"description": "Scientific name.",
"type": [
"string",
"null"
]
},
"rank": {
"description": "Taxonomic rank, e.g. \"family\".",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"name",
"rank",
"common_name"
],
"type": "object"
},
"type": "array"
},
"vision": {
"description": "True when the taxon is covered by the upstream image classifier.",
"type": "boolean"
}
},
"type": "object"
}
},
{
"description": "Decode the vocabularies the other iNaturalist tools take as input: annotation attributes and values, quality grades, license codes, taxonomic ranks, iconic taxa, and IUCN conservation-status codes. An unrecognized filter value is not rejected upstream — it silently returns nothing — so read the codes here before filtering. Note that the conservation codes are the normalised csi search filter; a taxon record’s own conservation_statuses[].status is authority-specific free text and reads differently. With topic controlled_terms and a taxon_id, the response also carries which annotations identifiers have actually recorded for that taxon, with counts.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"taxon_id": {
"description": "Add observed annotation usage for this taxon, ranked by how often each attribute/value pair has been recorded. Valid only with topic controlled_terms. Resolve a name to an id with inaturalist_resolve_name.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"topic": {
"description": "Which vocabulary to decode. controlled_terms is fetched live and cached; the rest are spec-derived static tables.",
"enum": [
"controlled_terms",
"quality_grades",
"licenses",
"ranks",
"iconic_taxa",
"conservation_status_codes"
],
"type": "string"
}
},
"required": [
"topic"
],
"type": "object"
},
"name": "inaturalist_list_reference",
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"topic",
"source",
"entries"
]
},
{
"required": [
"error"
]
}
],
"properties": {
"entries": {
"description": "The vocabulary, one entry per code or attribute.",
"items": {
"additionalProperties": false,
"description": "One vocabulary entry — an annotation attribute, or a static filter code.",
"properties": {
"code": {
"description": "The literal filter value to pass, on the static topics — e.g. \"needs_id\", \"cc0\", \"Aves\".",
"type": "string"
},
"id": {
"description": "Numeric attribute id, on the controlled_terms topic. Pass it as term_id.",
"type": "number"
},
"label": {
"description": "Human-readable name for the entry.",
"type": [
"string",
"null"
]
},
"multivalued": {
"description": "True when one observation may carry several values of this attribute.",
"type": "boolean"
},
"notes": {
"description": "What the entry means, or how it is used, when it needs saying.",
"type": "string"
},
"values": {
"description": "Values this annotation attribute accepts, on the controlled_terms topic.",
"items": {
"additionalProperties": false,
"description": "One value of an annotation attribute.",
"properties": {
"blocking": {
"description": "True when this value blocks other values of the same attribute.",
"type": "boolean"
},
"id": {
"description": "Value id. Pass it as term_value_id alongside the attribute id.",
"type": "number"
},
"label": {
"description": "Human-readable value name, e.g. \"Larva\".",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"label",
"blocking"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"label"
],
"type": "object"
},
"type": "array"
},
"error": {
"additionalProperties": {},
"description": "Present when the call failed. Absent on success.",
"properties": {
"code": {
"description": "JSON-RPC error code for this failure.",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"type": "integer"
},
"data": {
"additionalProperties": {},
"properties": {
"reason": {
"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.",
"examples": [
"taxon_id_not_applicable",
"unknown_taxon_id"
],
"type": "string"
},
"recovery": {
"additionalProperties": {},
"description": "Actionable next step for the caller.",
"properties": {
"hint": {
"type": "string"
}
},
"required": [
"hint"
],
"type": "object"
},
"retryable": {
"description": "Whether retrying may succeed.",
"type": "boolean"
}
},
"type": "object"
},
"message": {
"description": "Human-readable description of what went wrong.",
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"notice": {
"description": "Guidance when the requested taxon has no recorded annotations yet.",
"type": "string"
},
"observed_usage": {
"description": "Observed annotation usage for taxon_id, most-used first. Present only when taxon_id was given.",
"items": {
"additionalProperties": false,
"description": "One attribute/value pair and how often it has been recorded.",
"properties": {
"attribute": {
"description": "Annotation attribute label.",
"type": [
"string",
"null"
]
},
"count": {
"description": "How many observations of this taxon carry the pair.",
"type": "number"
},
"term_id": {
"description": "Attribute id — pass it as term_id to filter search, species counts, or the histogram. Null when upstream omitted it.",
"type": [
"number",
"null"
]
},
"term_value_id": {
"description": "Value id — pass it as term_value_id alongside term_id. Null when upstream omitted it.",
"type": [
"number",
"null"
]
},
"value": {
"description": "Annotation value label. Labels repeat across attributes, so filter by the ids rather than the label.",
"type": [
"string",
"null"
]
}
},
"required": [
"attribute",
"term_id",
"value",
"term_value_id",
"count"
],
"type": "object"
},
"type": "array"
},
"source": {
"description": "\"upstream\" when the table was fetched from iNaturalist, \"static\" when spec-derived.",
"enum": [
"upstream",
"static"
],
"type": "string"
},
"topic": {
"description": "The vocabulary that was decoded.",
"enum": [
"controlled_terms",
"quality_grades",
"licenses",
"ranks",
"iconic_taxa",
"conservation_status_codes"
],
"type": "string"
}
},
"type": "object"
}
},
{
"description": "Resolve a common or scientific name to a taxon id, or a place, project, or observer name to its id. Returns ranked candidates carrying the identifiers every other tool takes. A miss is a result rather than a failure: found comes back false with guidance naming why. Taxon lookup matches a name PREFIX, not words inside a name, so \"monarch butterfly\" misses where \"monarch\" hits.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"limit": {
"default": 10,
"description": "Maximum candidates to return, applied to every type.",
"maximum": 30,
"minimum": 1,
"type": "integer"
},
"q": {
"description": "The name to resolve. On type \"taxon\" this is a name prefix or an exact taxon id; on the other types it is matched across the record text.",
"maxLength": 100,
"minLength": 1,
"type": "string"
},
"rank": {
"description": "Restrict taxon candidates to one rank. Honoured only on type \"taxon\" — the cross-kind search has no rank filter.",
"enum": [
"stateofmatter",
"kingdom",
"phylum",
"subphylum",
"superclass",
"class",
"subclass",
"superorder",
"order",
"suborder",
"infraorder",
"superfamily",
"epifamily",
"family",
"subfamily",
"supertribe",
"tribe",
"subtribe",
"genus",
"genushybrid",
"species",
"hybrid",
"subspecies",
"variety",
"form"
],
"type": "string"
},
"type": {
"default": "taxon",
"description": "Which kind of record to resolve. \"taxon\" uses the taxon autocomplete; the rest use the scored cross-kind search, and \"any\" searches every kind at once. For a place’s bounding box and containment chain rather than just its id, use inaturalist_find_places instead.",
"enum": [
"taxon",
"place",
"project",
"user",
"any"
],
"type": "string"
}
},
"required": [
"q"
],
"type": "object"
},
"name": "inaturalist_resolve_name",
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"found",
"candidates",
"totalCount"
]
},
{
"required": [
"error"
]
}
],
"properties": {
"candidates": {
"description": "Ranked candidates, best match first.",
"items": {
"additionalProperties": false,
"description": "One ranked candidate.",
"properties": {
"common_name": {
"description": "Preferred common name, on taxa.",
"type": "string"
},
"display_name": {
"description": "Place name with its administrative context, on places.",
"type": "string"
},
"id": {
"description": "The identifier to pass onward — taxon_id, place_id, project id, or user id.",
"type": "number"
},
"kind": {
"description": "Which record kind this candidate is.",
"enum": [
"taxon",
"place",
"project",
"user"
],
"type": "string"
},
"login": {
"description": "Observer login, on users only — the value inaturalist_get_leaderboard entries and an observation’s observer carry.",
"type": "string"
},
"matched_term": {
"description": "The name variant that actually matched the query.",
"type": "string"
},
"name": {
"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.",
"type": [
"string",
"null"
]
},
"observations_count": {
"description": "How many observations the record covers.",
"type": "number"
},
"photo": {
"additionalProperties": false,
"description": "Representative photo, when the record carries one.",
"properties": {
"attribution": {
"description": "Attribution string, verbatim and never reformatted. Reproduce it with any use of the image.",
"type": [
"string",
"null"
]
},
"license_code": {
"description": "Photo licence code. Null means all rights reserved, independent of the record.",
"type": [
"string",
"null"
]
},
"medium_url": {
"description": "Medium variant. Supplied by upstream where it publishes every size, otherwise derived by substituting the size qualifier in the path. Absent when the path did not match the documented shape.",
"type": "string"
},
"open": {
"description": "True when the photo is served from the host the upstream reserves for open licences. A photo can move hosts when its licence changes, so this reflects fetch time.",
"type": "boolean"
},
"square_url": {
"description": "75px square variant, exactly as upstream published it. Null when absent.",
"type": [
"string",
"null"
]
}
},
"required": [
"square_url",
"attribution",
"license_code",
"open"
],
"type": "object"
},
"rank": {
"description": "Taxonomic rank, on taxa.",
"type": "string"
},
"score": {
"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.",
"type": "number"
},
"slug": {
"description": "URL slug, on places and projects.",
"type": "string"
}
},
"required": [
"kind",
"id",
"name"
],
"type": "object"
},
"type": "array"
},
"error": {
"additionalProperties": {},
"description": "Present when the call failed. Absent on success.",
"properties": {
"code": {
"description": "JSON-RPC error code for this failure.",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"type": "integer"
},
"data": {
"additionalProperties": {},
"properties": {
"reason": {
"description": "Machine-readable failure mode. Declared by this tool: `rank_not_applicable`: rank was supplied with a type other than taxon. Other values are possible when a failure originates below the handler.",
"examples": [
"rank_not_applicable"
],
"type": "string"
},
"recovery": {
"additionalProperties": {},
"description": "Actionable next step for the caller.",
"properties": {
"hint": {
"type": "string"
}
},
"required": [
"hint"
],
"type": "object"
},
"retryable": {
"description": "Whether retrying may succeed.",
"type": "boolean"
}
},
"type": "object"
},
"message": {
"description": "Human-readable description of what went wrong.",
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"found": {
"description": "True when at least one candidate matched.",
"type": "boolean"
},
"guidance": {
"description": "Why nothing matched and what to try instead. Present only when found is false — this is the primary result of a miss.",
"type": "string"
},
"totalCount": {
"description": "Total candidates upstream matched, before the limit was applied.",
"type": "number"
}
},
"type": "object"
}
},
{
"description": "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.",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"captive": {
"default": false,
"description": "Whether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only.",
"type": "boolean"
},
"csi": {
"description": "IUCN-normalised conservation status codes to include, e.g. [\"EN\",\"CR\"]. Decode them with inaturalist_list_reference topic conservation_status_codes.",
"items": {
"enum": [
"LC",
"NT",
"VU",
"EN",
"CR",
"EW",
"EX"
],
"type": "string"
},
"type": "array"
},
"cursor": {
"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\".",
"pattern": "^[1-9]\\d*$",
"type": "string"
},
"d1": {
"description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"type": "string"
},
"d2": {
"description": "Latest observation date, YYYY-MM-DD. Inclusive.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"type": "string"
},
"endemic": {
"description": "Restrict to taxa endemic to the observation location.",
"type": "boolean"
},
"hrank": {
"description": "Highest (coarsest) taxonomic rank of the identification to accept. Must be at or above lrank; ranks compare by rank level.",
"enum": [
"stateofmatter",
"kingdom",
"phylum",
"subphylum",
"superclass",
"class",
"subclass",
"superorder",
"order",
"suborder",
"infraorder",
"superfamily",
"epifamily",
"family",
"subfamily",
"supertribe",
"tribe",
"subtribe",
"genus",
"genushybrid",
"species",
"hybrid",
"subspecies",
"variety",
"form"
],
"type": "string"
},
"iconic_taxa": {
"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.",
"items": {
"enum": [
"Actinopterygii",
"Amphibia",
"Animalia",
"Arachnida",
"Aves",
"Chromista",
"Fungi",
"Insecta",
"Mammalia",
"Mollusca",
"Plantae",
"Protozoa",
"Reptilia",
"unknown"
],
"type": "string"
},
"type": "array"
},
"include": {
"description": "Embedded arrays to expand per record. Check photo_count and sound_count first — expanding costs context.",
"items": {
"enum": [
"photos",
"annotations",
"sounds"
],
"type": "string"
},
"type": "array"
},
"introduced": {
"description": "Restrict to taxa introduced to the observation location.",
"type": "boolean"
},
"lat": {
"description": "Latitude of the search centre, in decimal degrees. Requires lng and radius.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"license": {
"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.",
"items": {
"enum": [
"cc-by",
"cc-by-nc",
"cc-by-nd",
"cc-by-sa",
"cc-by-nc-nd",
"cc-by-nc-sa",
"cc0"
],
"type": "string"
},
"type": "array"
},
"licensed": {
"description": "Restrict to records whose own license_code is not null — any licence, NonCommercial and NoDerivatives variants included. For specific licences, use license.",
"type": "boolean"
},
"lng": {
"description": "Longitude of the search centre, in decimal degrees. Requires lat and radius.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"lrank": {
"description": "Lowest (finest) taxonomic rank of the identification to accept. Equal to hrank for an exact-rank match.",
"enum": [
"stateofmatter",
"kingdom",
"phylum",
"subphylum",
"superclass",
"class",
"subclass",
"superorder",
"order",
"suborder",
"infraorder",
"superfamily",
"epifamily",
"family",
"subfamily",
"supertribe",
"tribe",
"subtribe",
"genus",
"genushybrid",
"species",
"hybrid",
"subspecies",
"variety",
"form"
],
"type": "string"
},
"native": {
"description": "Restrict to taxa native to the observation location.",
"type": "boolean"
},
"nelat": {
"description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"nelng": {
"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.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"order": {
"default": "desc",
"description": "Sort direction.",
"enum": [
"asc",
"desc"
],
"type": "string"
},
"order_by": {
"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.",
"enum": [
"created_at",
"geo_score",
"id",
"observed_on",
"random",
"species_guess",
"updated_at",
"votes"
],
"type": "string"
},
"page": {
"description": "Page number within the first 10,000 results, under any ordering. Defaults to 1. Mutually exclusive with cursor.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"per_page": {
"default": 10,
"description": "Records per page, maximum 25. A projected record costs roughly 1.9 KB across structuredContent and the rendered text together, so 25 is a full page near 49 KB and the default of 10 near 20 KB. Walk further with page or cursor rather than a larger page.",
"maximum": 25,
"minimum": 1,
"type": "integer"
},
"photo_license": {
"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.",
"items": {
"enum": [
"cc-by",
"cc-by-nc",
"cc-by-nd",
"cc-by-sa",
"cc-by-nc-nd",
"cc-by-nc-sa",
"cc0"
],
"type": "string"
},
"type": "array"
},
"photo_licensed": {
"description": "Restrict to records with at least one licensed photo, under any licence. For specific licences, use photo_license.",
"type": "boolean"
},
"place_id": {
"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.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"project_id": {
"description": "Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"q": {
"description": "Free text matched across observation properties.",
"minLength": 1,
"type": "string"
},
"quality_grade": {
"default": [
"research"
],
"description": "Identification confidence tiers to include. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence.",
"items": {
"enum": [
"research",
"needs_id",
"casual"
],
"type": "string"
},
"minItems": 1,
"type": "array"
},
"radius": {
"description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.",
"maximum": 500,
"type": "number"
},
"search_on": {
"description": "Narrow what q matches against. Requires q.",
"enum": [
"names",
"tags",
"description",
"place"
],
"type": "string"
},
"swlat": {
"description": "South-west corner latitude of the bounding box. All four corners or none.",
"maximum": 90,
"minimum": -90,
"type": "number"
},
"swlng": {
"description": "South-west corner longitude of the bounding box. All four corners or none.",
"maximum": 180,
"minimum": -180,
"type": "number"
},
"taxon_id": {
"description": "Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"term_id": {
"description": "Annotation attribute ids, from inaturalist_list_reference topic controlled_terms — e.g. 1 for Life Stage.",
"items": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"type": "array"
},
"term_value_id": {
"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.",
"items": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"type": "array"
},
"threatened": {
"description": "Restrict to taxa considered threatened where observed.",
"type": "boolean"
},
"user_id": {
"description": "Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login.",
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"user_login": {
"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.",
"minLength": 1,
"type": "string"
}
},
"type": "object"
},
"name": "inaturalist_search_observations",
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"anyOf": [
{
"not": {
"required": [
"error"
]
},
"required": [
"total_results",
"observations",
"has_more",
"applied_filters",
"truncated",
"shown",
"cap"
]
},
{
"required": [
"error"
]
}
],
"properties": {
"applied_filters": {
"additionalProperties": false,
"description": "The server-applied defaults and overrides that determine what this answer means.",
"properties": {
"captive": {
"description": "Whether captive and cultivated records were included.",
"type": "boolean"
},
"order": {
"description": "Sort direction actually sent upstream.",
"type": "string"
},
"order_by": {
"description": "Sort field actually sent upstream.",
"type": "string"
},
"ordering_forced_by_cursor": {
"description": "True when a cursor overrode the requested ordering.",
"type": "boolean"
},
"quality_grade": {
"description": "Identification tiers actually searched.",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"quality_grade",
"captive",
"order_by",
"order",
"ordering_forced_by_cursor"
],
"type": "object"
},
"cap": {
"description": "The per_page that was applied.",
"type": "number"
},
"error": {
"additionalProperties": {},
"description": "Present when the call failed. Absent on success.",
"properties": {
"code": {
"description": "JSON-RPC error code for this failure.",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"type": "integer"
},
"data": {
"additionalProperties": {},
"properties": {
"reason": {
"description": "Machine-readable failure mode. Declared by this tool: `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. `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.",
"examples": [
"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"
],
"type": "string"
},
"recovery": {
"additionalProperties": {},
"description": "Actionable next step for the caller.",
"properties": {
"hint": {
"type": "string"
}
},
"required": [
"hint"
],
"type": "object"
},
"retryable": {
"description": "Whether retrying may succeed.",
"type": "boolean"
}
},
"type": "object"
},
"message": {
"description": "Human-readable description of what went wrong.",
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"has_more": {
"description": "True when this page filled per_page and more records follow. On the page path an exactly full final page is false; under a cursor, where the offset is unknown, every full page is true.",
"type": "boolean"
},
"next_cursor": {
"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.",
"type": "string"
},
"notice": {
"description": "Guidance when nothing matched, when the page is past the last one holding results, or how to continue past a full page.",
"type": "string"
},
"observations": {
"description": "The matching sightings, projected.",
"items": {
"additionalProperties": false,
"description": "One projected observation record.",
"properties": {
"agreements": {
"description": "How many identifications currently agree with the community taxon.",
"type": "number"
},
"annotations": {
"description": "Decoded annotations. Present when \"annotations\" was included.",
"items": {
"additionalProperties": false,
"description": "One decoded annotation on the record.",
"properties": {
"attribute": {
"description": "Decoded attribute label, e.g. \"Life Stage\". Null when the id is not in the vocabulary.",
"type": [
"string",
"null"
]
},
"attribute_id": {
"description": "Attribute id, usable as term_id on the search tools.",
"type": "number"
},
"by": {
"description": "Login of the member who added the annotation.",
"type": [
"string",
"null"
]
},
"value": {
"description": "Decoded value label, e.g. \"Larva\". Null when the id is not in the vocabulary.",
"type": [
"string",
"null"
]
},
"value_id": {
"description": "Value id, usable as term_value_id on the search tools.",
"type": "number"
}
},
"required": [
"attribute",
"value",
"attribute_id",
"value_id",
"by"
],
"type": "object"
},
"type": "array"
},
"captive": {
"description": "True for a zoo animal, a garden planting, or other cultivation.",
"type": "boolean"
},
"comments": {
"description": "Discussion comments, cut to their first entries in upstream order (not strictly chronological) when they exceed the per-record share of a 40-entry budget. Present when \"comments\" was included.",
"items": {
"additionalProperties": false,
"description": "One discussion comment on the record.",
"properties": {
"body": {
"description": "Free-text comment body.",
"type": [
"string",
"null"
]
},
"by": {
"description": "Login of the commenter.",
"type": [
"string",
"null"
]
},
"created_at": {
"description": "When the comment was posted, ISO 8601.",
"type": [
"string",
"null"
]
},
"id": {
"description": "Comment id.",
"type": "number"
}
},
"required": [
"id",
"by",
"body",
"created_at"
],
"type": "object"
},
"type": "array"
},
"comments_shown": {
"description": "How many of them comments carries. Below comments_total when the thread was cut. Present when \"comments\" was included.",
"type": "number"
},
"comments_total": {
"description": "How many comments upstream holds on the record. Present when \"comments\" was included.",
"type": "number"
},
"community_taxon": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"common_name": {
"description": "Preferred common name, when one is recorded.",
"type": [
"string",
"null"
]
},
"iconic_taxon_name": {
"description": "Broad organism group, e.g. \"Insecta\". Usable as an iconic_taxa filter value.",
"type": [
"string",
"null"
]
},
"id": {
"description": "Taxon id — the identifier every taxon-scoped filter takes.",
"type": "number"
},
"name": {
"description": "Scientific name.",
"type": [
"string",
"null"
]
},
"rank": {
"description": "Taxonomic rank, e.g. \"species\".",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"name",
"rank",
"common_name",
"iconic_taxon_name"
],
"type": "object"
},
{
"type": "null"
}
],
"description": "Consensus taxon, resolved. Present on the by-id tool; null when the thread has reached none."
},
"community_taxon_id": {
"description": "Consensus taxon id. Differs from taxon.id while a thread is contested.",
"type": [
"number",
"null"
]
},
"coordinate": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"accuracy_m": {
"description": "Public positional accuracy radius in metres. On an obscured record this is tens of kilometres and the point is a locality, not a sighting position.",
"type": [
"number",
"null"
]
},
"lat": {
"description": "Latitude in decimal degrees.",
"type": "number"
},
"lng": {
"description": "Longitude in decimal degrees.",
"type": "number"
}
},
"required": [
"lat",
"lng",
"accuracy_m"
],
"type": "object"
},
{
"type": "null"
}
],
"description": "Public coordinate. Null when the record carries none."
},
"description": {
"description": "The observer’s own note on the sighting — host plant, behaviour, habitat, count. Third-party free text. Present on the by-id tool; null when the observer wrote none.",
"type": [
"string",
"null"
]
},
"disagreements": {
"description": "How many identifications currently disagree with the community taxon.",
"type": "number"
},
"geoprivacy": {
"description": "Observer-set coordinate privacy: obscured, obscured_private, open, or private.",
"type": [
"string",
"null"
]
},
"id": {
"description": "Observation id. Also the cursor value for deep pagination.",
"type": "number"
},
"identification_disagreements_count": {
"description": "Count of disagreeing identifications as upstream tallies it. Present on the by-id tool.",
"type": "number"
},
"identifications": {
"description": "The identification thread, cut to its first entries in upstream order (roughly but not strictly chronological) when it exceeds the per-record share of a 40-entry budget. Present when \"identifications\" was included.",
"items": {
"additionalProperties": false,
"description": "One identification in the community thread.",
"properties": {
"body": {
"description": "Free-text note written by the identifier.",
"type": [
"string",
"null"
]
},
"by": {
"description": "Login of the identifier.",
"type": [
"string",
"null"
]
},
"category": {
"description": "How this identification moved the thread: improving, supporting, leading, or maverick.",
"type": [
"string",
"null"
]
},
"created_at": {
"description": "When the identification was added, ISO 8601.",
"type": [
"string",
"null"
]
},
"current": {
"description": "True when this is the identifier’s current identification on the record.",
"type": "boolean"
},
"disagreement": {
"description": "True when the identifier explicitly disagreed with the preceding taxon.",
"type": [
"boolean",
"null"
]
},
"from_vision": {
"description": "True when the identification came from the upstream image classifier.",
"type": "boolean"
},
"id": {
"description": "Identification id.",
"type": "number"
},
"taxon": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"common_name": {
"description": "Preferred common name, when one is recorded.",
"type": [
"string",
"null"
]
},
"iconic_taxon_name": {
"description": "Broad organism group, e.g. \"Insecta\". Usable as an iconic_taxa filter value.",
"type": [
"string",
"null"
]
},
"id": {
"description": "Taxon id — the identifier every taxon-scoped filter takes.",
"type": "number"
},
"name": {
"description": "Scientific name.",
"type": [
"string",
"null"
]
},
"rank": {
"description": "Taxonomic rank, e.g. \"species\".",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"name",
"rank",
"common_name",
"iconic_taxon_name"
],
"type": "object"
},
{
"type": "null"
}
],
"description": "Taxon this identification proposes."
}
},
"required": [
"id",
"taxon",
"by",
"current",
"category",
"disagreement",
"from_vision",
"body",
"created_at"
],
"type": "object"
},
"type": "array"
},
"identifications_count": {
"description": "Upstream’s tally of identifications currently agreeing or disagreeing with the community taxon — agreements + disagreements. Not the thread size: it leaves out the observer’s own identification and any that neither agrees nor disagrees, such as a coarser or withdrawn one. The thread size is identifications_total, on inaturalist_get_observation.",
"type": "number"
},
"identifications_shown": {
"description": "How many of them identifications carries. Below identifications_total when the thread was cut. Present when \"identifications\" was included.",
"type": "number"
},
"identifications_total": {
"description": "How many identifications upstream holds on the record — the thread size. Present when \"identifications\" was included.",
"type": "number"
},
"license_code": {
"description": "Licence of the observation record itself. Null means all rights reserved.",
"type": [
"string",
"null"
]
},
"obscured": {
"description": "True when the true coordinate is withheld, typically for a threatened taxon. The point is never resolved or approximated.",
"type": "boolean"
},
"observation_fields": {
"description": "Observation-field values filled in on the record, usually by a project; fields left blank are dropped. Cut to the first filled fields in upstream order when they exceed the per-record share of a 40-entry budget. Present on the by-id tool.",
"items": {
"additionalProperties": false,
"description": "One filled observation field.",
"properties": {
"name": {
"description": "Field name, as its creator wrote it, e.g. \"Habitat_Description\".",
"type": [
"string",
"null"
]
},
"value": {
"description": "The value filled in, verbatim.",
"type": "string"
}
},
"required": [
"name",
"value"
],
"type": "object"
},
"type": "array"
},
"observation_fields_shown": {
"description": "How many of them observation_fields carries. Below observation_fields_total when the list was cut. Present on the by-id tool.",
"type": "number"
},
"observation_fields_total": {
"description": "How many filled observation fields the record carries. Present on the by-id tool.",
"type": "number"
},
"observed_at": {
"description": "Observation timestamp with offset, ISO 8601.",
"type": [
"string",
"null"
]
},
"observed_on": {
"description": "Observation date, YYYY-MM-DD. Null when the observer recorded no date.",
"type": [
"string",
"null"
]
},
"observer": {
"description": "Login of the observer. The rest of the upstream profile is not relayed.",
"type": [
"string",
"null"
]
},
"photo": {
"anyOf": [
{
"additionalProperties": false,
"description": "A photo with the attribution and licence that must travel with it.",
"properties": {
"attribution": {
"description": "Attribution string, verbatim and never reformatted. Reproduce it with any use of the image.",
"type": [
"string",
"null"
]
},
"license_code": {
"description": "Photo licence code. Null means all rights reserved, independent of the record.",
"type": [
"string",
"null"
]
},
"medium_url": {
"description": "Medium variant. Supplied by upstream where it publishes every size, otherwise derived by substituting the size qualifier in the path. Absent when the path did not match the documented shape.",
"type": "string"
},
"open": {
"description": "True when the photo is served from the host the upstream reserves for open licences. A photo can move hosts when its licence changes, so this reflects fetch time.",
"type": "boolean"
},
"square_url": {
"description": "75px square variant, exactly as upstream published it. Null when absent.",
"type": [
"string",
"null"
]
}
},
"required": [
"square_url",
"attribution",
"license_code",
"open"
],
"type": "object"
},
{
"type": "null"
}
],
"description": "First photo on the record. Null when there are none."
},
"photo_count": {
"description": "How many photos the record carries, so include \"photos\" can be spent knowingly.",
"type": "number"
},
"photos": {
"description": "Every photo on the record. Present when \"photos\" was included.",
"items": {
"additionalProperties": false,
"description": "A photo with the attribution and licence that must travel with it.",
"properties": {
"attribution": {
"description": "Attribution string, verbatim and never reformatted. Reproduce it with any use of the image.",
"type": [
"string",
"null"
]
},
"license_code": {
"description": "Photo licence code. Null means all rights reserved, independent of the record.",
"type": [
"string",
"null"
]
},
"medium_url": {
"description": "Medium variant. Supplied by upstream where it publishes every size, otherwise derived by substituting the size qualifier in the path. Absent when the path did not match the documented shape.",
"type": "string"
},
"open": {
"description": "True when the photo is served from the host the upstream reserves for open licences. A photo can move hosts when its licence changes, so this reflects fetch time.",
"type": "boolean"
},
"square_url": {
"description": "75px square variant, exactly as upstream published it. Null when absent.",
"type": [
"string",
"null"
]
}
},
"required": [
"square_url",
"attribution",
"license_code",
"open"
],
"type": "object"
},
"type": "array"
},
"place_guess": {
"description": "Locality text written by the observer. Third-party free text.",
"type": [
"string",
"null"
]
},
"quality_grade": {
"description": "Identification confidence tier: research, needs_id, or casual.",
"enum": [
"research",
"needs_id",
"casual"
],
"type": "string"
},
"sound_count": {
"description": "How many audio recordings the record carries.",
"type": "number"
},
"sounds": {
"description": "Audio recordings. Present when \"sounds\" was included.",
"items": {
"additionalProperties": false,
"description": "An audio recording with its attribution and licence.",
"properties": {
"attribution": {
"description": "Attribution string, verbatim.",
"type": [
"string",
"null"
]
},
"license_code": {
"description": "Sound licence code. Null means all rights reserved.",
"type": [
"string",
"null"
]
},
"url": {
"description": "Audio file URL. Null when upstream published none.",
"type": [
"string",
"null"
]
}
},
"required": [
"url",
"attribution",
"license_code"
],
"type": "object"
},
"type": "array"
},
"taxon": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"common_name": {
"description": "Preferred common name, when one is recorded.",
"type": [
"string",
"null"
]
},
"iconic_taxon_name": {
"description": "Broad organism group, e.g. \"Insecta\". Usable as an iconic_taxa filter value.",
"type": [
"string",
"null"
]
},
"id": {
"description": "Taxon id — the identifier every taxon-scoped filter takes.",
"type": "number"
},
"name": {
"description": "Scientific name.",
"type": [
"string",
"null"
]
},
"rank": {
"description": "Taxonomic rank, e.g. \"species\".",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"name",
"rank",
"common_name",
"iconic_taxon_name"
],
"type": "object"
},
{
"type": "null"
}
],
"description": "Current identification. Null when nobody has identified the record."
},
"taxon_geoprivacy": {
"description": "Coordinate privacy applied automatically for a threatened taxon. Same vocabulary.",
"type": [
"string",
"null"
]
},
"url": {
"description": "Canonical iNaturalist page for the record.",
"type": [
"string",
"null"
]
},
"uuid": {
"description": "Stable UUID, independent of the id sequence.",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"uuid",
"url",
"observed_on",
"observed_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"
],
"type": "object"
},
"type": "array"
},
"shown": {
"description": "How many records this page carries.",
"type": "number"
},
"total_results": {
"description": "How many records upstream reports as matching. An estimate over a live index — it drifts between calls seconds apart.",
"type": "number"
},
"truncated": {
"description": "True when the page filled per_page and more records follow.",
"type": "boolean"
}
},
"type": "object"
}
}
]
}Verify it yourself
curl -s https://api.teppi.xyz/v1/evidence/sha256:be756098a1d289f1127b36599d25c6d9bdfa22a47878650beea81db5c31b5a55 | sha256sum