L logiover
data · Jul 9, 2026 · 7 min read

How to Scrape iNaturalist Observations & Species Data (2026)

Extract iNaturalist wildlife observations by species, place or keyword — GPS, photos, quality grade, taxonomy — from the official open API. No API key needed.

iNaturalist holds over 200 million citizen-science wildlife observations — georeferenced, photographed, and community-verified across every taxonomic group. The data is genuinely open, which is the good news. The friction is volume: the web portal is built for browsing one observation at a time, not for pulling ten thousand research-grade lion records into a distribution model. If you’ve tried to assemble a species-occurrence dataset by clicking through the site, you already know the problem. This guide covers how to extract iNaturalist observations and taxonomy at scale through the official open API — what fields you get, how the three modes work, and where the real limits are.

What’s worth extracting

The scraper returns 14 structured fields per observation. Grouped by what they’re for:

  • Identityid (the unique iNaturalist observation ID), speciesGuess (the observer’s common name or guess), taxonName (the scientific name of the identified taxon), taxonRank (species, genus, family, …) and iconicTaxon (the high-level group: Mammalia, Aves, Insecta, Plantae, Fungi, …).
  • When & whereobservedOn (the date, YYYY-MM-DD), placeGuess (human-readable location text), and latitude / longitude (GPS coordinates).
  • Provenance & qualityuser (the observer’s username), qualityGrade (research, needs_id or casual), and license (the Creative Commons code, e.g. cc-by-nc).
  • Media & linkphotoUrl (a direct medium-size image URL) and uri (the canonical observation page on iNaturalist.org).

For range mapping you need taxonName, latitude, longitude and qualityGrade. For a checklist app you want speciesGuess, placeGuess and photoUrl. The qualityGrade field is the one that determines scientific usability — research-grade records are the ones that flow into GBIF and published studies.

How the source actually works

iNaturalist exposes an official, fully public open API at https://api.inaturalist.org/v1/. No registration, no key, no login. The scraper makes plain keyless HTTP GET requests against three endpoints and paginates with page and per_page=200 until your maxResults cap is hit. That maps to three modes:

  • observations — paginate observation records filtered by taxon name, place ID, quality grade or free-text query, hitting /observations.
  • taxa — search the species catalog via /taxa, returning taxonomy, photos and observation counts for matching taxa.
  • observationDetail — fetch a single observation by ID from /observations/{id} with full metadata.

A typical bulk observation pull — all research-grade lion records — is just:

{
  "mode": "observations",
  "taxonName": "Panthera leo",
  "qualityGrade": "research",
  "maxResults": 500
}

To scope a search to a country or protected area, add a placeId. You find these by browsing iNaturalist.org and reading the numeric ID out of the place URL — for example inaturalist.org/places/6986 is place ID 6986 for Kenya, 1 is the USA, 7082 is Germany:

{
  "mode": "observations",
  "taxonName": "Aquila chrysaetos",
  "placeId": 1,
  "qualityGrade": "research",
  "maxResults": 1000,
  "proxyConfig": { "useApifyProxy": true }
}

To discover the exact scientific name before a large scrape, run taxa mode first:

{
  "mode": "taxa",
  "query": "Panthera",
  "maxResults": 50
}

The workflow that avoids wasted runs is: use taxa mode to confirm the canonical taxonName, then use that exact name in an observations run scoped by placeId.

Run the iNaturalist Scraper on Apify — one run pulls thousands of research-grade observations with species, GPS, photos, quality grade and taxonomy. Keyless open API, no login. Export to JSON, CSV, Excel or XML.

The access reality

The API is open, but it isn’t unlimited, and biodiversity data has quirks the API deliberately enforces:

  • Rate limit is roughly 60 requests per minute per IP. That’s the practical ceiling. The actor handles 429 responses automatically with exponential back-off and retries, so a busy window slows down rather than failing.
  • maxResults caps at 10,000 per run. iNaturalist’s database is well over 200 million observations, so for anything larger you split the work — run multiple jobs with different placeId values or taxon filters and concatenate.
  • Obscured coordinates return null. iNaturalist lets observers hide precise GPS for sensitive or endangered species (geoprivacy set to obscured). When that’s the case, latitude and longitude come back null while placeGuess may still be populated. This is expected, not a bug — plan your spatial analysis to tolerate missing coordinates.
  • Datacenter proxies are fine. Unlike anti-bot-heavy commercial sites, the iNaturalist API doesn’t need residential IPs. The default useApifyProxy with datacenter works.
  • Not every record has a photo. Sound-only or text-only observations return a null photoUrl. Filter on it if your use case needs imagery.

The reason to use the API rather than scraping the website HTML is straightforward: the API is documented, designed for programmatic access, returns clean JSON, and paginates predictably. Scraping the rendered site would be slower, more fragile, and pointlessly hard when an open API exists.

Example output

One representative research-grade record:

{
  "id": "987654321",
  "speciesGuess": "Golden Eagle",
  "taxonName": "Aquila chrysaetos",
  "taxonRank": "species",
  "iconicTaxon": "Aves",
  "observedOn": "2024-06-01",
  "placeGuess": "Rocky Mountain National Park, Colorado, USA",
  "latitude": "40.3428",
  "longitude": "-105.6836",
  "user": "raptor_watcher",
  "qualityGrade": "research",
  "photoUrl": "https://inaturalist-open-data.s3.amazonaws.com/photos/99887/medium.jpg",
  "uri": "https://www.inaturalist.org/observations/987654321",
  "license": "cc-by-nc"
}

Use cases

What georeferenced biodiversity data at this scale supports:

  • Species distribution modeling — download all research-grade records for a taxon across a region to map current range and identify density hotspots.
  • Park & reserve checklists — extract observations by placeId for a protected area to power a visitor species-checklist app.
  • Taxonomy lookups — use taxa mode to get every species in a genus (e.g. all Panthera) with taxonomy, photos and observation counts.
  • Pollinator & invasion monitoring — pull recent insect observations tagged with a keyword to track pollinator activity or an invasion front across a region.
  • ML & informatics datasets — assemble large, labeled, georeferenced species datasets for biodiversity informatics, phylogenetics or image-classification training.
  • Science communication — explore climate-linked range shifts or endangered-species trends for data journalism, backed by real observation records.

Because the actor is MCP-compatible, an AI agent can call it directly — for example, “pull 1,000 research-grade owl observations in Europe and summarize the species distribution by country” — retrieve the dataset, and process the results without a manual download.

Build-it-yourself vs. managed actor

The API is open, so a requests loop over /observations is genuinely simple to start. What accumulates:

  • Pagination and rate-limit handling. Cycling page while respecting the ~60/min limit and backing off cleanly on 429 is the part that turns a 30-line script into something that survives a 10,000-record run.
  • Field normalization. The raw API response is nested; flattening it into 14 tidy columns (and handling the null-coordinate and null-photo cases) is repetitive glue.
  • Place-ID resolution. You’ll be looking up numeric place IDs by hand from the website regardless — the actor doesn’t remove that step, but it does keep the rest of the pipeline out of your code.
  • Scheduling & export. Wiring recurring runs and CSV/Sheets export.

The managed actor is pay-per-result at a fraction of a cent per observation, so a full 10,000-record pull is cents. If you’re a developer who wants the raw API in your own stack, build it — it’s a friendly API. If you want research-grade observations as a clean dataset without writing the pagination and back-off yourself, the managed path is the shortcut.

Common pitfalls

Specific gotchas with iNaturalist data:

  • Use scientific names, not common ones. taxonName: "Panthera leo" returns only lions; a free-text query: "lion" can match unrelated results (place names, sea-lions, user text). Verify the scientific name in taxa mode first.
  • Research grade is a filter, not a default guarantee. Only research-grade observations have a photo, date, coordinates and at least two agreeing community IDs — these are the ones used in publications and GBIF exports. If you leave the quality grade open, you’ll pull needs_id and casual records that aren’t validated.
  • Null coordinates are normal. Don’t drop records with missing GPS as errors — they’re often endangered species with obscured geoprivacy. Keep placeGuess as a coarse fallback.
  • Respect the license field before commercial use. Most records are cc-by-nc (non-commercial only). If you’re republishing or building a commercial product, filter and attribute per each observation’s license.
  • 10,000 is a per-run ceiling, not a database limit. For a full-taxon or full-country dataset, tile the work by placeId or by taxon and merge — a single run won’t return the whole 200-million-record corpus.
  • New records lag validation. Freshly submitted observations may sit at needs_id until the community confirms them. Re-running on a schedule captures them as they graduate to research grade.

Wrapping up

iNaturalist is one of the friendliest open data sources on the web — the challenge is purely getting bulk, clean, research-grade records out without hand-clicking the portal or reinventing pagination and rate-limit handling. If you want the raw API in your own code, it’s well worth learning. If you want the observations as a ready dataset for a distribution model, a checklist app or an ML pipeline, a managed actor that already handles the paging, back-off and field flattening will save you the plumbing.

Open the iNaturalist Scraper on Apify — reads the official iNaturalist open API in observations, taxa or observation-detail mode and returns species, GPS, photos, quality grade, taxonomy and license per record. No API key, no login, MCP-ready. Export to JSON, CSV, Excel or XML. Start on Apify’s free monthly credit.

Related guides