NASA's API gives you access to satellite imagery, Mars rover photos, asteroid tracking, and astronomy picture of the day. Completely free. No credit card. 1,000 requests/hour.
Get Your API Key (30 Seconds)
Go to api.nasa.gov → enter email → instant API key.
Or use DEMO_KEY for testing (30 req/hr).
1. Astronomy Picture of the Day
import httpx
API_KEY = 'your_key_or_DEMO_KEY'
def apod(date=None):
params = {'api_key': API_KEY}
if date:
params['date'] = date # YYYY-MM-DD
r = httpx.get('https://api.nasa.gov/planetary/apod', params=params)
data = r.json()
return {
'title': data['title'],
'explanation': data['explanation'][:200],
'url': data['url'],
'media_type': data['media_type']
}
today = apod()
print(f"{today['title']}\n{today['url']}")
2. Mars Rover Photos
def mars_photos(rover='curiosity', sol=1000, camera='NAVCAM'):
"""Get photos from Mars rovers.
Rovers: curiosity, opportunity, spirit
Cameras: FHAZ, RHAZ, MAST, CHEMCAM, NAVCAM
"""
r = httpx.get(f'https://api.nasa.gov/mars-photos/api/v1/rovers/{rover}/photos',
params={'sol': sol, 'camera': camera, 'api_key': API_KEY}
)
photos = r.json()['photos']
return [{
'id': p['id'],
'url': p['img_src'],
'earth_date': p['earth_date'],
'camera': p['camera']['full_name']
} for p in photos[:10]]
photos = mars_photos(sol=3000)
for p in photos:
print(f"Sol 3000 | {p['camera']} | {p['url']}")
3. Near-Earth Asteroids
def asteroids(start_date, end_date):
r = httpx.get('https://api.nasa.gov/neo/rest/v1/feed', params={
'start_date': start_date,
'end_date': end_date,
'api_key': API_KEY
})
data = r.json()
dangerous = []
for date, neos in data['near_earth_objects'].items():
for neo in neos:
if neo['is_potentially_hazardous_asteroid']:
dangerous.append({
'name': neo['name'],
'date': date,
'diameter_m': neo['estimated_diameter']['meters']['estimated_diameter_max'],
'velocity_kmh': float(neo['close_approach_data'][0]['relative_velocity']['kilometers_per_hour']),
'miss_km': float(neo['close_approach_data'][0]['miss_distance']['kilometers'])
})
return dangerous
hazardous = asteroids('2026-03-25', '2026-03-31')
for a in hazardous:
print(f"⚠️ {a['name']} — {a['diameter_m']:.0f}m @ {a['velocity_kmh']:.0f} km/h — miss by {a['miss_km']:,.0f} km")
4. Earth Satellite Imagery
def earth_image(lat, lon, date='2025-01-01', dim=0.1):
"""Get satellite image of any location."""
r = httpx.get('https://api.nasa.gov/planetary/earth/imagery', params={
'lat': lat, 'lon': lon, 'date': date,
'dim': dim, 'api_key': API_KEY
})
if r.status_code == 200:
with open(f'earth_{lat}_{lon}.png', 'wb') as f:
f.write(r.content)
return f'Saved earth_{lat}_{lon}.png'
return 'No image available'
# Central Park, NYC
earth_image(40.785091, -73.968285)
Rate Limits
| Key Type | Limit |
|---|---|
| DEMO_KEY | 30/hour, 50/day |
| Free API key | 1,000/hour |
Build Ideas
- Daily space fact bot (Telegram/Discord)
- Asteroid proximity alert system
- Mars photo gallery with filtering
- Satellite before/after comparison tool
- Space weather dashboard
More API Tutorials
What would you build with NASA's data? Space is fascinating — I'd love to see what ideas you have. 👇
API tutorials at dev.to/0012303
Top comments (0)