# GBIF Species & Occurrence Scraper - Biodiversity Data (`ninhothedev/gbif-scraper`) Actor

$0.3/1K 🔥 GBIF scraper! Species taxonomy & occurrence records with coordinates worldwide. No key. JSON, CSV, Excel or API in seconds. Power biodiversity & conservation research ⚡

- **URL**: https://apify.com/ninhothedev/gbif-scraper.md
- **Developed by:** [ninhothedev](https://apify.com/ninhothedev) (community)
- **Categories:** AI, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.30 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## GBIF Species & Occurrence Scraper

Export biodiversity data from **GBIF** (the Global Biodiversity Information Facility) — the world's largest open index of species records, backed by more than 100,000 datasets from museums, herbaria, research institutions and citizen-science platforms.

This actor turns any search term into clean, flat JSON/CSV/Excel:

- **Species mode** — taxonomic name records: scientific name, canonical name, rank, taxonomic status and the full hierarchy (kingdom → phylum → class → order → family → genus → species) plus authorship.
- **Occurrences mode** — individual observation and specimen records including **GPS latitude/longitude**, country, event date, year, basis of record, institution, dataset and collector.

No API key. No login. No proxy required.

### Features

- Two scrape modes: `species` (taxonomy) and `occurrences` (records with coordinates)
- Multiple search queries per run — scientific names, genera, families or common names
- Offset pagination handled automatically, with de-duplication across queries
- ISO-8601 normalisation of GBIF's messy `eventDate` values (date-only, datetime, ranges, plain years)
- Every field is nullable and every record is flat — no nested objects to unpack
- Browser-grade TLS fingerprint (curl\_cffi, Chrome 124) with an automatic stdlib fallback
- Runs on 512 MB, datacenter-clean, no proxy costs

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `species` | `species` for taxonomy records, `occurrences` for records with coordinates |
| `queries` | array | `["Puma concolor", "Quercus"]` | Free-text GBIF search terms |
| `maxItems` | integer | `100` | Total record cap across all queries (max 1000) |

```json
{
  "mode": "occurrences",
  "queries": ["Puma concolor", "Panthera onca"],
  "maxItems": 500
}
```

### Output

**Species record**

```json
{
  "type": "species",
  "key": 116892593,
  "scientific_name": "Puma concolor",
  "canonical_name": "Puma concolor",
  "rank": "SPECIES",
  "taxonomic_status": "ACCEPTED",
  "kingdom": "Animalia",
  "phylum": "Chordata",
  "class_name": "Mammalia",
  "order_name": "Carnivora",
  "family": "Felidae",
  "genus": "Puma",
  "species_name": "Puma concolor",
  "authorship": "(Linnaeus, 1771)",
  "num_descendants": 0,
  "url": "https://www.gbif.org/species/116892593",
  "source": "gbif",
  "scraped_at": "2026-07-28T11:37:02.247510+00:00"
}
```

**Occurrence record**

```json
{
  "type": "occurrence",
  "key": 5015469523,
  "scientific_name": "Puma concolor (Linnaeus, 1771)",
  "latitude": -19.588499,
  "longitude": -56.087017,
  "country": "Brazil",
  "country_code": "BR",
  "event_date": "2016-09-09T00:00:00",
  "year": 2016,
  "basis_of_record": "HUMAN_OBSERVATION",
  "institution": "NABU|naturgucker",
  "dataset": null,
  "kingdom": "Animalia",
  "family": "Felidae",
  "genus": "Puma",
  "elevation": null,
  "recorded_by": "105162832",
  "url": "https://www.gbif.org/occurrence/5015469523",
  "source": "gbif",
  "scraped_at": "2026-07-28T11:37:03.422709+00:00"
}
```

### Use cases

- **Biodiversity research** — assemble species checklists for a taxon or region and cross-reference them against your own field data.
- **Ecology** — pull georeferenced occurrence points to fit species distribution models (MaxEnt, ENMeval) or map ranges in QGIS.
- **Species datasets** — build training corpora for taxonomic name matching, fuzzy name resolution or ML classification of scientific names.
- **Conservation** — track where and when a threatened species has been recorded, by which institution, and how sampling effort changed over time.

### Pricing

Roughly **$0.5 per 1,000 records**. GBIF is free and public, so there are no proxy or API costs baked in — you only pay for compute. A 1,000-record run finishes in about a minute on 512 MB.

### Notes & limits

- GBIF's full-text search is fuzzy: broad terms like `Quercus` return every name usage across all source datasets, so the same binomial can appear from multiple checklists (each with its own `key`). De-duplication is by GBIF key, not by name.
- Not every occurrence has coordinates. GBIF stores records from herbarium sheets and old catalogues that were never georeferenced — `latitude`/`longitude` will be `null` for those. In a typical run 90 %+ of records carry coordinates.
- `dataset`, `elevation`, `authorship` and other optional Darwin Core terms are frequently empty upstream. That is source data, not scraper loss.
- Data is published by GBIF under open licences (mostly CC0 / CC-BY / CC-BY-NC). Check the licence of each contributing dataset before republishing, and cite GBIF in academic work.

### Related actors

- [iNaturalist Scraper](https://apify.com/ninhothedev/inaturalist-scraper) — citizen-science observations with photos
- [UniProt Scraper](https://apify.com/ninhothedev/uniprot-scraper) — protein sequences and annotations
- [Earthquake Scraper](https://apify.com/ninhothedev/earthquake-scraper) — global seismic events with coordinates
- [Air Quality Scraper](https://apify.com/ninhothedev/air-quality-scraper) — station-level pollution measurements

### Development

```bash
python -m py_compile src/*.py
python tests/test_smoke.py     # offline smoke tests, no network needed
```

# Actor input Schema

## `mode` (type: `string`):

What to scrape from GBIF. Choose 'species' to get taxonomic name records (scientific name, rank, kingdom/phylum/class/order/family/genus, authorship). Choose 'occurrences' to get individual observation and specimen records including GPS latitude/longitude, country, event date, collector and dataset.

## `queries` (type: `array`):

One or more free-text search terms sent to the GBIF full-text search. Accepts scientific names ('Puma concolor'), genera ('Quercus'), families ('Felidae'), common names ('oak') or any keyword. Each query is paginated separately until the item limit is reached.

## `maxItems` (type: `integer`):

Hard cap on the total number of records saved to the dataset across all queries. Use a small number for a quick test run and raise it for a full export. Minimum 1, maximum 1000.

## Actor input object example

```json
{
  "mode": "species",
  "queries": [
    "Puma concolor",
    "Quercus"
  ],
  "maxItems": 100
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "Puma concolor",
        "Quercus"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ninhothedev/gbif-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "queries": [
        "Puma concolor",
        "Quercus",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("ninhothedev/gbif-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "Puma concolor",
    "Quercus"
  ]
}' |
apify call ninhothedev/gbif-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ninhothedev/gbif-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/kLc25k8anUE5Ld69q/builds/oVWRvDgGxOlwZkq2V/openapi.json
