Skip to content

Repository files navigation

Meteorites Landings API:

A RESTful API built with Wrangler for querying and analyzing the NASA Meteorite Landings dataset.

The project has been designed to run on serverless infrastructure, with optimized processing and algorithms that require minimal resources. As a result, it performs well on small and medium-sized datasets and under moderate traffic volumes.

You can deploy your own instance by clicking the button below:

Deploy to Cloudflare

🚀 Key features:

  • CORS enabled: use the API directly from your website or any other project.

  • No sign-up required: no account creation, credit card, or personal data needed.

  • Privacy-focused: no user activity logs (logs only for debugging).

  • Rate limiting: protection against abuse with request throttling.

  • Compliant with the GDPR: IP addresses (used only for rate limiting) are hashed with SHA-256 using a salt.

  • Advanced search: multiple filters for precise queries.

  • Serverless optimized: lightweight, high-performance architecture.

🌐 API access:

EndpointRate limitMaintainerPrivacyDataset
https://meteorites.nde-code.workers.dev/1 req/IP/sMeprivacy.mdmeteorites_small.json

Check the status page if you experience latency or other issues while using my public online instance.

Configuration limits:

Here are the parameters in config.ts:

# Absolute upper limit; exceeding this value triggers an error:MAX_RANDOM_METEORITES: 1000# Maximum number of results the search system will return: MAX_RETURNED_SEARCH_RESULTS: 500# Smallest allowed radius for any computation or query:MIN_RADIUS: 1# Largest allowed radius to prevent overly broad or costly searches:MAX_RADIUS: 2500# Default number used when no 'count' value is provided:DEFAULT_RANDOM_NUMBER_OF_METEORITES: 100

Note: these limits may be updated, so check the repository regularly to stay informed.

📚 Available endpoints:

1. [GET]/search - Advanced search:

Search meteorites by multiple criteria: name, classification, date, mass, and geographic location.

Query parameters:

ParameterTypeDescription
recclassstringMeteorite classification
fallstringFall status: Fell or Found
yearnumberExact year of fall or discovery
minYearnumberMinimum year
maxYearnumberMaximum year
massnumberExact mass (grams)
minMassnumberMinimum mass (grams)
maxMassnumberMaximum mass (grams)
centerLatitudenumberCenter latitude (required with radius)
centerLongitudenumberCenter longitude (required with radius)
radiusnumberSearch radius in km (min: MIN_RADIUS, max: MAX_RADIUS) (required with coordinates)
limitnumberMaximum results (min: 1, max: MAX_RETURNED_SEARCH_RESULTS)

Note on geographic precision: distance calculation uses equirectangular approximation (optimized for performance). Highly accurate for local/regional queries (< 1000-1500 km). For larger radii, especially at high latitudes, minor distortions may occur compared to geodesic (Haversine) calculations.

Parameter behavior:

  • Unknown parameters: are ignored.

  • Invalid numeric parameters: are treated as absent (e.g., year=abc).

  • Conflicting filters: return 400 error (e.g., year with minYear/maxYear).

  • Geographic search: requires all three: centerLatitude, centerLongitude, and radius.

  • limit: is automatically capped at MAX_RETURNED_SEARCH_RESULTS.

Response codes:

CodeDescription
200Success (may return empty set)
400Missing or invalid parameters
429Rate limit exceeded
500Server error (config or environment)
503Service unavailable (cache empty/loading)

Example request:

curl "https://meteorites.nde-code.workers.dev/search?year=2013"

Example response:

{
"success": {
"count": 1,
"meteorites": [
{
"id": "57165",
"name": "Chelyabinsk",
"recclass": "LL5",
"mass": 100000,
"fall": "Fell",
"year": 2013,
"latitude": 54.81667,
"longitude": 61.11667
}
]
}
}

2. [GET]/get - Meteorite details:

Retrieve detailed information about a single meteorite by id or name.

Query parameters:

ParameterTypeDescription
idstringUnique meteorite identifier
namestringExact meteorite name (case-insensitive, normalized)

Note: provide eitheridorname, but not both. Providing neither will result in a 400 error.

Response codes:

CodeDescription
200Meteorite found
400Missing/invalid parameters or both provided
404No matching meteorite
429Rate limit exceeded
500Server error
503Service unavailable

Example requests:

By ID:

curl "https://meteorites.nde-code.workers.dev/get?id=12345"

By name:

curl "https://meteorites.nde-code.workers.dev/get?name=Kopjes%20Vlei"

Example response:

{
"success": {
"meteorite": {
"id": "12345",
"name": "Kopjes Vlei",
"recclass": "Iron, IIAB",
"mass": 13600,
"fall": "Found",
"year": 1914,
"latitude": -29.3,
"longitude": 21.15
}
}
}

3. [GET]/random - Random selection:

Get a random set of meteorites.

Query parameters:

ParameterTypeDescription
countnumberNumber of meteorites (default: DEFAULT_RANDOM_NUMBER_OF_METEORITES, max: MAX_RANDOM_METEORITES)

Note: invalid count returns the default number.

Response codes:

CodeDescription
200Success
400Invalid count parameter
429Rate limit exceeded
500Server error
503Service unavailable

Example request:

curl "https://meteorites.nde-code.workers.dev/random?count=3"

Example response:

{
"success": {
"count": 3,
"meteorites": [
{
"id": "14764",
"name": "Mabwe-Khoywa",
"recclass": "L5",
"mass": 540,
"fall": "Fell",
"year": 1937,
"latitude": 19,
"longitude": 97
},
{
"id": "11442",
"name": "Guibga",
"recclass": "L5",
"mass": 288,
"fall": "Fell",
"year": 1972,
"latitude": 13.5,
"longitude": -0.68333
},
{
"id": "8671",
"name": "Elephant Moraine 90262",
"recclass": "L6",
"mass": 9.2,
"fall": "Found",
"year": 1990,
"latitude": -76.28752,
"longitude": 156.44737
}
]
}
}

4. [GET]/stats - Dataset statistics:

Get aggregated statistics: year ranges, mass stats, classifications, and geolocation info.

Response fields:

FieldTypeDescription
meteorites_countnumberTotal number of meteorites
min_year, max_yearstringEarliest and latest year
min_mass_g, max_mass_gnumberMinimum/maximum mass (grams)
avg_mass_gnumberAverage mass (2 decimal places)
yearsstring[]Sorted list of all available years
years_distributionobjectFrequency by year
recclassesstring[]List of unique classifications
recclasses_distributionobjectFrequency by classification
geolocated_countnumberMeteorites with valid coordinates
fall_countsobjectBreakdown of fell vs found

Note: some meteorites have a mass of 0 grams. This reflects specific cases (extreme alteration, fossilization, missing fragments) and is not an error.

Response codes:

CodeDescription
200Success
429Rate limit exceeded
500Server error
503Service unavailable

Example request:

curl "https://meteorites.nde-code.workers.dev/stats"

Example response:

{"success": {"meteorites_count": 8500,"min_year": "860","max_year": "2013","min_mass_g": 0.1,"max_mass_g": 60000000,"avg_mass_g": 68231.78,"years": ["860","920","1399","1490","1491",
...
],"years_distribution": {"860": 1,"920": 1,"1399": 1,"1490": 1,"1491": 1,
...
}"recclasses": ["Acapulcoite","Achondrite-ung","Angrite","Aubrite",
...
],"recclasses_distribution": {"L6": 1616,"H5": 1461,"H6": 749,"L5": 653,"H4": 637,
...
},"geolocated_count": 8500,"fall_counts": {"fell": 1095,"found": 7405}}}

5. [GET]/health - Service status:

Check API integrity and status, including cache and indexes.

Response fields:

FieldTypeDescription
statusstringOverall status: "healthy" or "unhealthy"
timestampstringISO 8601 timestamp of check
checksobjectDetails of internal components
messagestringStatus summary message

Internal checks detail:

CheckDescription
cache_readyMain cache fully loaded
meteorites_countTotal meteorites in memory
shuffled_meteorites_countMeteorites available for /random
stats_availablePre-computed statistics ready
by_id_index_sizeEntries in ID lookup index
by_name_index_sizeEntries in name lookup index

Note: a 503 response indicates at least one check failed (cache not ready, empty indexes, etc.).

Response codes:

CodeDescription
200All systems operational
503One or more checks failed

Example request:

curl "https://meteorites.nde-code.workers.dev/health"

Example response (Healthy):

{
"status": "healthy",
"timestamp": "2026-04-23T12:14:49.107Z",
"checks": {
"cache_ready": true,
"meteorites_count": 8500,
"shuffled_meteorites_count": 8500,
"stats_available": true,
"by_id_index_size": 8500,
"by_name_index_size": 8500
},
"message": "All endpoints are functional."
}

🖥️ Developer documentation and datasets:

For setup, configuration, and deployment using Wrangler CLI, see the developer guide.

Available datasets:

The API is optimized for performance with limited resources. Choose datasets based on your needs:

DatasetSizeDescription
meteorites_complete.json~33k entriesComplete dataset (unfiltered)
meteorites_medium.json~15k entriesReduced via grid filtering
meteorites_small.json~8.5k entriesDefault, reduced via grid filtering

Note: these datasets have been cleaned up (see the CLI documentation and the --clean-up argument for details).

Medium dataset generated via:

python compiler.py --input "data/meteorites.csv" --output "data/meteorites_medium.json" \
--grid 0.00085 --limit 15000 --clean-up --minify

Small dataset generated via:

python compiler.py --input "data/meteorites.csv" --output "data/meteorites_small.json" \
--grid 0.014 --limit 8500 --clean-up --minify

>_ Python CLI for custom datasets:

Requires Python 3.10+ (no external dependencies).

Available options:

ArgumentDescription
--inputPath to meteorites.csv(required)
--outputPath to the output JSON file (required)
--gridGrid cell size in degrees. If > 0, keeps at most one meteorite per grid cell
--limitMaximum number of records. 0 = unlimited. Processing stops once the limit is reached
--clean-upRemove records with missing or invalid location data and normalize empty fields (recommended)
--minifyMinify the output JSON by removing unnecessary whitespace
--debugVerbosity level: 0 (silent), 1 (info), 2 (verbose)

Usage:

Navigate to the directory containing compiler.py and run:

python compiler.py --input "data/meteorites.csv" --output "data/my_db.json" --clean-up --debug 2

For help:

python compiler.py --help

Note: the --grid option creates visually optimized datasets (one meteorite per cell) but loses original statistical distribution.

⚖️ License:

This project is licensed under the Apache License v2.0.

🎯 Author:

Created and maintained by Nde-Code.

Don't hesitate to open an issue or a pull request if you have any questions or would like to contribute.