# Getting Started with the NIMS Imagery API
Canonical URL: https://api.waterdata.usgs.gov/docs/nims/
> Learn how the NIMS API lists cameras at USGS gaging stations and how to build full image URLs from the filenames it returns.


# Getting started with the National Imagery Management System (NIMS) API

The National Imagery Management System (NIMS) collects, stores, processes, and delivers imagery from USGS gaging stations for public consumption. The NIMS API provides programmatic access to camera metadata and image file listings.

This page outlines the structure of these endpoints, shows how to construct full image URLs from returned filenames, and provides guidance on API keys and rate limits. For comprehensive reference information, including schemas and parameters, see the [Swagger UI documentation for this API](https://api.waterdata.usgs.gov/nims/v0/docs).

---

## Base URL and versioning
- Base URL (v0): https://api.waterdata.usgs.gov/nims/v0
- Version note: v0 endpoints are fully supported but are legacy and do not strictly follow RESTful best practices. Future versions (v1+) will adopt REST conventions for improved consistency. Users are encouraged to migrate to v1 once it becomes available for improved compatibility and adherence to REST standards.

---

## The two core endpoints

### 1) `/cameras` — discover cameras and base paths

Use this endpoint to list cameras, filter by camera ID (`camId`) or NWIS site (`siteId`), and read the base path fields you’ll need to construct full image URLs.

**Example (all cameras):** 
```
https://api.waterdata.usgs.gov/nims/v0/cameras
```
**Filter by camera ID:** 
```
https://api.waterdata.usgs.gov/nims/v0/cameras?camId=WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire
```
**Filter by site ID:** 
```
https://api.waterdata.usgs.gov/nims/v0/cameras?siteId=05366800
```
**Return specific fields:** 
```
https://api.waterdata.usgs.gov/nims/v0/cameras?returnFields=camName,newestImageDT
```

**Key fields for image access (returned per camera):**
- `overlayDir` — base URL for full‑size images  
- `thumbDir` — base URL for thumbnail images (approximately 300px wide by 200px high, maintaining aspect ratio)
- `smallDir` — base URL for 720px images (scaled so the largest dimension is 720px, maintaining aspect ratio)
- `tlDir` — base URL for time-lapse videos

*The full image URL is formed by concatenating a base path with a filename returned by `/listFiles` (see below).

---

### 2) `/listFiles` — get image filenames (and optional raw items)

Use this endpoint to retrieve filenames for a given `camId`. You can control item count and time windows.

**Required parameter:**
- `camId` — camera ID (e.g., `WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire`)

**Optional parameters:**
- `limit` — max items to return (default `1000`, max `50000`)
- `recent` — `true` returns the most recent files; set to literal `false` for oldest-first
- `after` / `before` — filter by date/time ([ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) or NIMS-standard string (YYYY-MM-DDThh:mm:ssZ), inclusive)
- `rawItem` — literal `true` to return raw item objects (includes `filename`, `timestamp`, `fs`)

**Examples:**

Latest filenames for a camera (default recent=true):
```
https://api.waterdata.usgs.gov/nims/v0/listFiles?camId=WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire&limit=10
```
Oldest-first and date-windowed:
```
https://api.waterdata.usgs.gov/nims/v0/listFiles?camId=WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire&recent=false&after=2025-12-31T00:00:00.000&before=2026-01-01T00:00:00.000
```
Raw items:
```
https://api.waterdata.usgs.gov/nims/v0/listFiles?camId=WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire&rawItem=true&limit=5
```

---

## Constructing full image URLs

The strings returned by `/listFiles` are filenames, not full URLs. To fetch the actual image:

1. Query `/cameras` to read the appropriate base path for that camera (`overlayDir`, `thumbDir`, or `smallDir`).
2. Query `/listFiles` to get the filenames.
3. Concatenate base path + filename.

**Full-size image example:**
```
GET /cameras?camId=WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire 
overlayDir = https://usgs-nims-images.s3.amazonaws.com/overlay/WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire/

GET /listFiles?camId=WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire
["WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire___2026-01-01T12-00-02Z.jpg"]

Full URL:
https://usgs-nims-images.s3.amazonaws.com/overlay/WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire/WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire___2026-01-01T12-00-02Z.jpg
```

**Other sizes:**
- Thumbnail: `thumbDir + filename` (~300-200px,  aspect ratio preserved)
- 720px image: `smallDir + filename` (longest side = 720px, aspect ratio preserved)

---

### Additional Image Products

- **Time-lapse video:**
  There is only one time-lapse video per camera, composed of the most recent imagery collected by that camera. It uses the images in the `smallDir`.

  You can access the time-lapse video for a camera by appending: `tlDir + camId + '_720.mp4'` 
  *(time-lapse filenames are not listed by `/listFiles`).

  **Example URL:** 
  ```
  https://usgs-nims-images.s3.amazonaws.com/timelapse/WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire/WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire_720.mp4
  ```

- **Most recent image:**  
  You can also access the most recent image for a camera in any available size by appending: `{base path} + camId + '_newest.jpg'`

  **Example URL:** 
  ```
  https://usgs-nims-images.s3.amazonaws.com/720/WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire/WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire_newest.jpg
  ```

---

## Quick start with curl

List cameras at a site:
```
curl "https://api.waterdata.usgs.gov/nims/v0/cameras?siteId=05366800"
```
Get the 25 most recent filenames:
```
curl "https://api.waterdata.usgs.gov/nims/v0/listFiles?camId=WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire&rawItem=true&recent=false&after=2025-12-31T00-00-00Z&before=2026-01-01T00-00-00Z"
```

---

## Quick start with Python (Requests)

```
import requests

BASE = "https://api.waterdata.usgs.gov/nims/v0"

# 1) Read camera base paths
cam_id = "WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire"
cam_resp = requests.get(f"{BASE}/cameras", params={"camId": cam_id})
cam_resp.raise_for_status()
camera = cam_resp.json()[0]
overlay_dir = camera["overlayDir"]

# 2) List recent filenames
files_resp = requests.get(f"{BASE}/listFiles", params={"camId": cam_id, "limit": 5})
files_resp.raise_for_status()
filenames = files_resp.json()

# 3) Construct full URLs
full_urls = [overlay_dir + fn for fn in filenames]
for url in full_urls:
    print(url)
```

---

## Authentication, API Keys, and Rate Limits

The NIMS API uses the same API key system as the USGS Water Data OGC APIs, managed by https://api.data.gov/. Providing your own key allows you to make more requests per hour before hitting rate limits (HTTP 429 “Too Many Requests”).

### How to Get an API Key
- Sign up for a key at: https://apiwaterdata.usgs.gov/signup. 
  - The key will be emailed to the address you provide.

### How to Use Your API Key
You can attach your key in two ways:

1. **Query parameter**:
```
https://api.waterdata.usgs.gov/nims/v0/listFiles?camId=WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire&api_key=YOUR_KEY
```
2. **HTTP header**:
```
curl -H "X-Api-Key: YOUR_KEY" "https://api.waterdata.usgs.gov/nims/v0/listFiles?camId=WI_Chippewa_River_at_Grand_Ave_at_Eau_Claire"
```

Both approaches authenticate your requests and grant higher rate limits.
```
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 998
```

### Learn More
For additional details on API keys and rate limits, see:  
https://api.waterdata.usgs.gov/docs/ogcapi/keys/

---

## Error responses & troubleshooting
Common HTTP status codes returned by NIMS:
- `400` Bad Request — parameter formatting issues (e.g., non-integer limit, invalid recent literal).
- `403` Forbidden — missing or unauthorized API key.
- `404` Not Found — unknown camId or no cameras for a siteId.
- `422` Unprocessable Content — invalid date window (e.g., before earlier than after).
- `429` Too Many Requests — rate limit exceeded.
- `500` Internal Server Error — unexpected server-side error; try again later.

Tips:
- Always validate dates (ISO 8601 or NIMS-standard) and use inclusive after/before windows.
- Use `limit` to avoid unnecessarily large responses.
- Set `recent=false` when you need the earliest files first (e.g., building complete timelines).
