Skip to content

Proxy Usage Patterns

Use ICDC by calling a proxy hostname for the data source and including your ICDC token.

  • Vendor: https://developer.nps.gov/api/v1/parks?...
  • ICDC: https://nps.api.10xicdc.com/api/v1/parks?...

Only the hostname changes. Paths and query parameters remain the same.

  • X-Api-Key: <icdc-token> — required

See the end‑to‑end example: National Park Service

Minimal cURL:

Terminal window
curl -H "X-Api-Key: $ICDC_TOKEN" "https://$ICDC_PROXY_HOST/api/v1/parks?limit=3"

Node.js:

const url = `https://${process.env.ICDC_PROXY_HOST}/api/v1/parks?limit=3`;
const res = await fetch(url, { headers: { 'X-Api-Key': process.env.ICDC_TOKEN } });

Python:

import os, requests
url = f"https://{os.environ['ICDC_PROXY_HOST']}/api/v1/parks"
resp = requests.get(url, headers={"X-Api-Key": os.environ['ICDC_TOKEN']}, timeout=30)
resp.raise_for_status()
  • Do not send your ICDC token to the vendor hostname; it will not work.
  • Rate limits and scopes are enforced by ICDC at the proxy.

Set environment variables, then make a minimal request.

Terminal window
export ICDC_PROXY_HOST="<proxy-host>" # e.g., nps.api.10xicdc.com
export ICDC_TOKEN="<your-icdc-token>"
Terminal window
curl -s -H "X-Api-Key: $ICDC_TOKEN" \
"https://$ICDC_PROXY_HOST/api/v1/parks?limit=3"
const proxy = process.env.ICDC_PROXY_HOST;
const token = process.env.ICDC_TOKEN;
const url = `https://${proxy}/api/v1/parks?limit=3`;
const res = await fetch(url, { headers: { 'X-Api-Key': token } });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
console.log(await res.json());
import os, requests
url = f"https://{os.environ['ICDC_PROXY_HOST']}/api/v1/parks"
resp = requests.get(url, params={"limit": 3}, headers={"X-Api-Key": os.environ['ICDC_TOKEN']}, timeout=30)
resp.raise_for_status()
print(resp.json())

Pass through vendor query parameters; iterate pages until complete.

Terminal window
curl -s -H "X-Api-Key: $ICDC_TOKEN" \
"https://$ICDC_PROXY_HOST/api/v1/parks?stateCode=CA&limit=50&start=0"
const proxy = process.env.ICDC_PROXY_HOST;
const token = process.env.ICDC_TOKEN;
async function listAll() {
let start = 0;
const pageSize = 50;
const results = [];
while (true) {
const url = `https://${proxy}/api/v1/parks?stateCode=CA&limit=${pageSize}&start=${start}`;
const res = await fetch(url, { headers: { 'X-Api-Key': token } });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
results.push(...(data.data ?? data));
if (!data.nextStart && (!data.total || results.length >= data.total)) break;
start = data.nextStart ?? (start + pageSize);
}
return results;
}
import os, requests
def list_all():
start = 0
page_size = 50
results = []
while True:
url = f"https://{os.environ['ICDC_PROXY_HOST']}/api/v1/parks"
params = {"stateCode": "CA", "limit": page_size, "start": start}
resp = requests.get(url, params=params, headers={"X-Api-Key": os.environ['ICDC_TOKEN']}, timeout=30)
resp.raise_for_status()
data = resp.json()
results.extend(data.get('data', data))
next_start = data.get('nextStart')
total = data.get('total')
if next_start is None and (total is None or len(results) >= total):
break
start = next_start if next_start is not None else start + page_size
return results

Use bounded concurrency to improve throughput while respecting limits.

const token = process.env.ICDC_TOKEN;
const host = process.env.ICDC_PROXY_HOST;
async function worker(queue, results) {
while (queue.length) {
const id = queue.shift();
const url = `https://${host}/api/v1/parks?parkCode=${id}`;
const res = await fetch(url, { headers: { 'X-Api-Key': token } });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
results.push(await res.json());
}
}
async function run(ids, concurrency = 5) {
const queue = [...ids];
const results = [];
await Promise.all(Array.from({ length: concurrency }, () => worker(queue, results)));
return results;
}
import os, requests
from concurrent.futures import ThreadPoolExecutor, as_completed
def fetch(id):
url = f"https://{os.environ['ICDC_PROXY_HOST']}/api/v1/parks"
resp = requests.get(url, params={"parkCode": id}, headers={"X-Api-Key": os.environ['ICDC_TOKEN']}, timeout=30)
resp.raise_for_status()
return resp.json()
def run(ids, max_workers=5):
results = []
with ThreadPoolExecutor(max_workers=max_workers) as ex:
futures = [ex.submit(fetch, i) for i in ids]
for f in as_completed(futures):
results.append(f.result())
return results

Combine with retry strategies in Error Handling.


Drop‑in helpers for your projects.

export async function icdcGet(path, params = {}) {
const host = process.env.ICDC_PROXY_HOST;
const token = process.env.ICDC_TOKEN;
const url = new URL(`https://${host}${path}`);
for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
const res = await fetch(url, { headers: { 'X-Api-Key': token } });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
import os, requests
def icdc_get(path, params=None, timeout=30):
url = f"https://{os.environ['ICDC_PROXY_HOST']}{path}"
headers = {"X-Api-Key": os.environ['ICDC_TOKEN']}
resp = requests.get(url, params=params, headers=headers, timeout=timeout)
resp.raise_for_status()
return resp.json()