Proxy Usage Patterns
Use ICDC by calling a proxy hostname for the data source and including your ICDC token.
Hostname swap
Section titled “Hostname swap”- 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.
Headers
Section titled “Headers”X-Api-Key: <icdc-token>— required
Examples
Section titled “Examples”See the end‑to‑end example: National Park Service
Minimal cURL:
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, requestsurl = 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.
Quickstart
Section titled “Quickstart”Set environment variables, then make a minimal request.
export ICDC_PROXY_HOST="<proxy-host>" # e.g., nps.api.10xicdc.comexport ICDC_TOKEN="<your-icdc-token>"curl -s -H "X-Api-Key: $ICDC_TOKEN" \ "https://$ICDC_PROXY_HOST/api/v1/parks?limit=3"JavaScript (Node 18+)
Section titled “JavaScript (Node 18+)”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());Python
Section titled “Python”import os, requestsurl = 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())Pagination & Filtering
Section titled “Pagination & Filtering”Pass through vendor query parameters; iterate pages until complete.
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 resultsConcurrency & Batching
Section titled “Concurrency & Batching”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, requestsfrom 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 resultsCombine with retry strategies in Error Handling.
Node & Python Templates
Section titled “Node & Python Templates”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()