DEV Community

Alex Spinov
Alex Spinov

Posted on

NASA API: Get Satellite Images and Mars Rover Photos (Free, No Credit Card)

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']}")
Enter fullscreen mode Exit fullscreen mode

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']}")
Enter fullscreen mode Exit fullscreen mode

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")
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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)