šŸŒ™ Lunar Landing Site API v1.0.0

Complete Documentation - Query 1.18M Pre-Analyzed Landing Sites

šŸ“– Overview

Query 1.18M pre-analyzed lunar landing sites across the lunar south pole with intelligent mission planning support.

1.18M Analyzed Sites
60+ Features per Site
<100ms Query Response
99.98% Data Completeness
Base URL: https://lunarlandingsiteapi.up.railway.app
API Version: 1.0.0
Status: Public Beta

šŸš€ Quick Start

Step 1: Get API Access

  1. Sign up at ldp-api-beta.vercel.app for free beta access
  2. Check your email for your API key (starts with ldp_live_...)
  3. Make your first request using the examples below

Step 2: Your First Query (30 seconds)

Get intelligent landing site recommendations near the lunar south pole:

Python

import requests API_KEY = "ldp_live_YOUR_KEY_HERE" headers = {"X-API-Key": API_KEY} response = requests.get( "https://lunarlandingsiteapi.up.railway.app/api/v1/recommendations", headers=headers, params={ "lat": -89.5, "lon": 45, "mission_type": "artemis", "top_n": 5 } ) data = response.json() print(data["recommendations"][0]["reasoning"]) print(f"Requests remaining: {data['user']['requests_remaining']}")

JavaScript

const API_KEY = "ldp_live_YOUR_KEY_HERE"; const response = await fetch( 'https://lunarlandingsiteapi.up.railway.app/api/v1/recommendations?lat=-89.5&lon=45&mission_type=artemis&top_n=5', { headers: { 'X-API-Key': API_KEY } } ); const data = await response.json(); console.log(data.recommendations[0].reasoning); console.log(`Requests remaining: ${data.user.requests_remaining}`);

cURL

curl -H "X-API-Key: ldp_live_YOUR_KEY_HERE" \ "https://lunarlandingsiteapi.up.railway.app/api/v1/recommendations?lat=-89.5&lon=45&mission_type=artemis&top_n=5"

šŸ“Š Data Overview

This API provides access to 1.18M pre-analyzed landing sites across the lunar south pole, derived from authoritative NASA datasets:

Each site includes 60+ features analyzed at multiple radii up to 100m radius: terrain metrics (slope, roughness, hazard index), illumination patterns (visibility percentage over lunar year), and data quality indicators.

āœ… Why Trust This Data?
  • Built on NASA Planetary Data System (PDS) archives
  • Research-grade processing pipeline with PostGIS spatial analysis
  • Validated against published lunar science literature
  • Same data sources used by Artemis mission planning teams

šŸ” Authentication

Most endpoints require an API key in the X-API-Key header:

X-API-Key: ldp_live_YOUR_KEY_HERE

Public Endpoints (No Authentication)

These endpoints are accessible without an API key:

Endpoint Purpose
GET / API welcome and endpoint listing
GET /health Health check and database status
GET /docs Interactive Swagger documentation
GET /openapi.json OpenAPI specification

Protected Endpoints (Authentication Required)

All data and decision support endpoints require a valid API key:

Endpoint Purpose
GET /api/v1/sites/search Search for landing sites (optional auth for full results)
POST /api/v1/sites/batch Bulk site retrieval
GET /api/v1/recommendations Get AI-powered recommendations
POST /api/v1/compare Compare multiple sites

API Key Management

Where to Find Your Key:
Check the welcome email: "Welcome to Lunar Landing API - Your Access Details"
Key format: ldp_live_ followed by 32 alphanumeric characters
āš ļø Security Best Practices:
  • Never share your API key publicly (GitHub, forums, etc.)
  • Never commit keys to version control
  • Use environment variables: API_KEY = os.getenv("LUNAR_API_KEY")
  • Rotate keys if accidentally exposed
Lost Your Key?
1. Check your email inbox and spam folder
2. Search for emails from Lunar Landing Site API
3. Contact support: info@irisdatalabs.com

šŸ“Š Rate Limits & Usage

Current Limits

Tier Daily Limit Status
Beta 100 requests/day Free during beta period
Premium Coming soon Coming soon

Monitor Your Usage

Every authenticated API response includes your current usage statistics:

{ "user": { "email": "your.email@example.com", "name": "Your Name", "tier": "beta", "requests_today": 45, "requests_remaining": 55, "rate_limit": 100 }, "recommendations": [...] }

Usage Monitoring Best Practice

data = response.json() remaining = data['user']['requests_remaining'] if remaining < 100: print(f"āš ļø Warning: Only {remaining} requests remaining today!")

āš ļø Error Handling

HTTP Status Codes

Code Meaning Description
200 Success Request completed successfully
400 Bad Request Invalid parameters
401 Unauthorized Missing API key
403 Forbidden Invalid or inactive API key
404 Not Found Resource doesn't exist
422 Validation Error Parameter validation failed
429 Too Many Requests Rate limit exceeded
500 Server Error Internal server error
503 Service Unavailable Database connection failed

Error Response Format

{ "detail": { "error": "Invalid API key", "message": "The provided API key is not valid or has been deactivated", "help": "Sign up at https://ldp-api-beta.vercel.app to get a valid API key" } }

Common Errors & Solutions

Error Cause Solution
Missing API key No X-API-Key header Add header to your request
Invalid API key Key doesn't exist or is inactive Check welcome email for correct key
Rate limit exceeded 100 requests/day limit hit Wait until tomorrow (resets at midnight UTC)
Invalid parameters Coordinates out of range Verify lat (-90 to 90), lon (-180 to 180)
Site not found Invalid site_id Use /search to find valid site IDs

Graceful Error Handling Example

import requests try: response = requests.get(url, headers=headers, params=params) response.raise_for_status() data = response.json() except requests.exceptions.HTTPError as e: if e.response.status_code == 401: print("āŒ Missing API key!") elif e.response.status_code == 403: print("āŒ Invalid API key!") elif e.response.status_code == 429: print("āš ļø Rate limit exceeded - try again tomorrow") else: print(f"Error {e.response.status_code}: {e.response.text}") except Exception as e: print(f"Request failed: {str(e)}")

šŸ”Œ Endpoints Overview

Status Endpoints

Data Endpoints

Decision Support Endpoints

GET /api/v1/sites/search

Description: Search for landing sites within a radius of target coordinates

Authentication: Optional (limited to 10 results without API key, 100 with key)

Parameters

Parameter Type Required Default Range Description
lat float āœ… - -90 to 90 Target latitude
lon float āœ… - -180 to 180 Target longitude
radius_m int āŒ 50000 1000-500000 Search radius in meters
limit int āŒ 100 1-100 Max results
min_visibility float āŒ - 0-100 Minimum visibility % filter
max_hazard float āŒ - 0-3 Maximum hazard index filter
max_slope float āŒ - 0-90 Maximum slope filter (degrees)

Example Request

curl -H "X-API-Key: ldp_live_YOUR_KEY" \ "https://lunarlandingsiteapi.up.railway.app/api/v1/sites/search?lat=-89.5&lon=45.0&radius_m=50000&max_hazard=1.5&limit=10"

Python Example

import requests API_KEY = "ldp_live_YOUR_KEY_HERE" headers = {"X-API-Key": API_KEY} response = requests.get( "https://lunarlandingsiteapi.up.railway.app/api/v1/sites/search", headers=headers, params={ "lat": -89.5, "lon": 45.0, "radius_m": 50000, "max_hazard": 1.5, "min_visibility": 70.0, "limit": 10 } ) data = response.json() print(f"Found {data['results_found']} sites") for site in data['sites']: print(f"Site {site['site_id']}: Hazard {site['terrain_100m']['hazard_index']:.2f}")

Response Example

{ "query": { "location": {"lat": -89.5, "lon": 45.0}, "search_radius_m": 50000, "filters": { "max_hazard": 1.5, "min_visibility": 70.0 } }, "results_found": 10, "sites": [ { "site_id": 928913, "location": {"lat": -89.947, "lon": 51.466}, "distance_m": 5012.3, "terrain_100m": { "slope_mean_deg": 16.5, "slope_max_deg": 32.6, "hazard_index": 3.0, "roughness_rms_m": 9.73 }, "illumination_100m": { "visibility_pct": 75.2 } } ] }

GET /api/v1/recommendations

Description: Get AI-powered landing site recommendations with mission-specific scoring and plain English reasoning

Authentication: Required

Parameters

Parameter Type Required Default Options Description
lat float āœ… - -90 to 90 Target latitude
lon float āœ… - -180 to 180 Target longitude
mission_type string āŒ artemis artemis, robotic, rover, custom Mission profile
radius_m int āŒ 50000 10000-500000 Search radius in meters
top_n int āŒ 5 1-20 Number of recommendations

Mission Types

Type Description Priorities
artemis Human landing mission - prioritizes crew safety 50% safety, 30% illumination, 20% proximity
robotic Robotic lander - balances safety and power 40% safety, 40% illumination, 20% proximity
rover Rover traverse - prioritizes accessibility 30% safety, 20% illumination, 50% accessibility
custom Balanced multi-criteria profile 40% safety, 30% illumination, 30% proximity

Example Request

curl -H "X-API-Key: ldp_live_YOUR_KEY" \ "https://lunarlandingsiteapi.up.railway.app/api/v1/recommendations?lat=-89.5&lon=45.0&mission_type=artemis&top_n=5"

Python Example

import requests API_KEY = "ldp_live_YOUR_KEY_HERE" headers = {"X-API-Key": API_KEY} response = requests.get( "https://lunarlandingsiteapi.up.railway.app/api/v1/recommendations", headers=headers, params={ "lat": -89.5, "lon": 45.0, "mission_type": "artemis", "top_n": 5 } ) data = response.json() print(f"Mission: {data['mission_profile']['description']}") print(f"\nTop {len(data['recommendations'])} Recommendations:") for rec in data['recommendations']: print(f"\n{rec['rank']}. Site {rec['site_id']} (Score: {rec['overall_score']:.1f}/10)") print(f" {rec['reasoning']}") print(f" Strengths: {', '.join(rec['strengths'])}") if rec['warnings']: print(f" Warnings: {', '.join(rec['warnings'])}")

Response Example

{ "mission_profile": { "type": "artemis", "description": "Artemis human landing mission - prioritizes crew safety", "priorities": { "safety": 0.5, "illumination": 0.3, "proximity": 0.2 } }, "recommendations": [ { "rank": 1, "site_id": 928913, "location": {"lat": -89.947, "lon": 51.466}, "overall_score": 4.646, "reasoning": "Moderate safety concerns with good visibility (75.2%)...", "warnings": ["Steep slopes present (mean 16.5°)"], "strengths": ["Meets baseline mission requirements"] } ] }

POST /api/v1/compare

Description: Compare multiple landing sites side-by-side with trade-off analysis

Authentication: Required

Limits: Minimum 2 sites, maximum 10 sites

Request Body

{ "site_ids": [928913, 928914, 929072] }

Example Request

curl -X POST https://lunarlandingsiteapi.up.railway.app/api/v1/compare \ -H "X-API-Key: ldp_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"site_ids": [928913, 928914, 929072]}'

Python Example

import requests API_KEY = "ldp_live_YOUR_KEY_HERE" headers = {"X-API-Key": API_KEY} response = requests.post( "https://lunarlandingsiteapi.up.railway.app/api/v1/compare", headers=headers, json={"site_ids": [928913, 928914, 929072]} ) data = response.json() print(f"Overall Winner: Site {data['winner_by_category']['overall']}") print(f"Safest: Site {data['winner_by_category']['safety']}") print(f"Best Illumination: Site {data['winner_by_category']['illumination']}") print(f"\nRecommendation: {data['recommendation']['reasoning']}")

Use Cases

šŸ’» Complete Code Examples

Python: Complete Mission Planning Workflow

import requests import json API_KEY = "ldp_live_YOUR_KEY_HERE" BASE_URL = "https://lunarlandingsiteapi.up.railway.app" headers = {"X-API-Key": API_KEY} def complete_mission_planning_workflow(): """Complete workflow: Search → Recommend → Compare → Select""" target_lat, target_lon = -89.5, 45.0 # Step 1: Get initial recommendations print("Step 1: Getting recommendations near target...") recs_response = requests.get( f"{BASE_URL}/api/v1/recommendations", headers=headers, params={ "lat": target_lat, "lon": target_lon, "mission_type": "artemis", "top_n": 5 } ) recs = recs_response.json() print(f"Found {len(recs['recommendations'])} recommendations") print(f"Requests remaining: {recs['user']['requests_remaining']}\n") # Step 2: Print top recommendations print("Step 2: Top 5 Sites:") for rec in recs['recommendations']: print(f"\n{rec['rank']}. Site {rec['site_id']} - Score: {rec['overall_score']:.1f}/10") print(f" {rec['reasoning']}") # Step 3: Compare top 3 candidates print("\n\nStep 3: Comparing top 3 finalists...") top_3_ids = [rec['site_id'] for rec in recs['recommendations'][:3]] compare_response = requests.post( f"{BASE_URL}/api/v1/compare", headers=headers, json={"site_ids": top_3_ids} ) comparison = compare_response.json() print(f"\nWinner: Site {comparison['winner_by_category']['overall']}") print(f"Recommendation: {comparison['recommendation']['reasoning']}") # Save results with open('mission_planning_results.json', 'w') as f: json.dump({"recommendations": recs, "comparison": comparison}, f, indent=2) print(f"\nāœ… Complete! Results saved.") if __name__ == "__main__": complete_mission_planning_workflow()

JavaScript: React Site Search Component

import React, { useState } from 'react'; const API_KEY = "ldp_live_YOUR_KEY_HERE"; const BASE_URL = "https://lunarlandingsiteapi.up.railway.app"; function LunarSiteExplorer() { const [sites, setSites] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const searchSites = async (lat, lon, missionType = 'artemis') => { setLoading(true); setError(null); try { const params = new URLSearchParams({ lat, lon, mission_type: missionType, top_n: 5 }); const response = await fetch( `${BASE_URL}/api/v1/recommendations?${params}`, { headers: { 'X-API-Key': API_KEY } } ); if (!response.ok) throw new Error(`API Error: ${response.status}`); const data = await response.json(); setSites(data.recommendations); } catch (err) { setError(err.message); } finally { setLoading(false); } }; return ( <div className="lunar-explorer"> <h2>Lunar Landing Site Explorer</h2> <button onClick={() => searchSites(-89.5, 0, 'artemis')}> Search Near South Pole </button> {loading && <p>Searching...</p>} {error && <p style={{color: 'red'}}>Error: {error}</p>} {sites.map(site => ( <div key={site.site_id}> <h3>Rank {site.rank}: Site {site.site_id}</h3> <p>Score: {site.overall_score.toFixed(1)}/10</p> <p>{site.reasoning}</p> </div> ))} </div> ); } export default LunarSiteExplorer;

šŸŽÆ Best Practices

1. Search Strategy Workflow

Step 1: Start Broad
• Large radius (100km)
• Relaxed filters
• Goal: Overview of available sites

Step 2: Refine
• Decrease radius (50km)
• Tighten filters (max_hazard, min_visibility)
• Goal: Focus on most promising areas

Step 3: Get Recommendations
• Use /recommendations endpoint
• Specify mission_type
• Goal: Mission-specific intelligent ranking

Step 4: Compare Finalists
• Use /compare on top 3-5 candidates
• Goal: Understand trade-offs

Step 5: Verify
• Get full details with /batch
• Goal: Final validation

2. Filter Guidelines

Conservative (High-stakes crewed missions)

params = { "max_hazard": 1.5, "min_visibility": 70.0, "max_slope": 10.0 } # Use case: Artemis landing sites

Moderate (Standard robotic missions)

params = { "max_hazard": 2.0, "min_visibility": 50.0, "max_slope": 15.0 } # Use case: Commercial landers, science missions

Exploratory (Scouting/contingency sites)

params = { "max_hazard": 2.5, "min_visibility": 30.0, "max_slope": 20.0 } # Use case: Rover traverses, backup sites

3. Performance Optimization

Operation Typical Latency Notes
/search (10 results) 40-60ms Most common query
/batch (10 sites) 15-25ms Optimized bulk retrieval
/recommendations 80-120ms Complex multi-site scoring
/compare 30-50ms Side-by-side analysis
For Fast Queries (<50ms):
  • Apply stricter filters to reduce result processing
  • Use batch endpoint for multiple site lookups
  • Cache results when querying repeatedly

šŸ“” Data Sources & Methodology

Terrain Data

Illumination Data

Processing Pipeline

  1. Download NASA PDS data archives (polar projection)
  2. Generate 1.18M candidate landing sites from source rasters
  3. Extract terrain and illumination metrics at each site
  4. Store in PostGIS database as WGS84 coordinates (EPSG:4326)
  5. Calculate composite hazard index
  6. Create spatial indexes (GiST) for fast queries

Feature Analysis Scales

All terrain and illumination features are computed at three analysis radii:

The API returns 100m radius data by default as it provides the most reliable and comprehensive metrics.

Hazard Index Scale

The hazard index is a composite metric (0-3) combining slope, roughness, and relief:

Data Quality

šŸ’¬ Support

Documentation & Resources

Contact & Help

Beta Program

āœ… Free access during beta (100 requests/day)
āœ… Your feedback helps shape the product
āœ… Direct influence on future features
āš ļø Breaking changes possible (with email notification)

Citation

If you use this API in research, please cite:

Iris Data Labs (2025). Lunar Landing Site API: Intelligent site selection powered by NASA terrain and illumination data. https://lunarlandingsiteapi.up.railway.app

šŸ“ Changelog

v1.0.0 (October 30, 2025) - Current

šŸš€ Initial Public Beta Release

Authentication

Data

Endpoints

Features

Known Limitations

Coming Soon