Overview
Lynker Spatial exposes two complementary APIs for flood mapping applications.
FlowFabric API translates geographic queries (bounding box, NHD reach IDs,
flow thresholds) into lists of inundated polygon IDs (pgids).
The Tile Service serves pre-built vector tiles containing those same polygons
so clients can highlight them on a map without downloading the full geometry dataset.
Browser / App
│
├─ POST /v1/inundation-ids ──▶ FlowFabric API ──▶ returns pgid list
│
└─ GET /api/tiles/{source}/{z}/{x}/{y} ──▶ Tile Service ──▶ MVT tiles
Client filters tile features by pgid to highlight inundated polygons
Both services share the same Cognito user pool, so a single JWT or API key authenticates both.
Authentication
Every request to either API requires a Bearer token in the Authorization header.
Authorization: Bearer <your-jwt-or-api-key>
Check your quota
The /me endpoint returns your identity and current monthly quota consumption:
curl -H "Authorization: Bearer $TOKEN" \
https://tiles.lynker-spatial.com/me
{
"user": "alice@example.com",
"token_type": "cognito",
"quota_used_bytes": 52428800,
"quota_total_bytes": 3221225472,
"quota_remaining_bytes": 3168796672
}
Core Workflow
1Query inundated polygon IDs from FlowFabric API
Call the /v1/inundation-ids endpoint with a reach ID and flow value.
It returns the pgids of all NWM catchment polygons predicted to be inundated.
POST https://api.lynker-spatial.com/v1/inundation-ids
Content-Type: application/json
Authorization: Bearer $TOKEN
{
"reach_id": "2823932",
"flow_cfs": 4500
}
{
"reach_id": "2823932",
"flow_cfs": 4500,
"pgids": [101234, 101235, 101238, 102001, 102004]
}
pgids are integer feature IDs present in the hydrofabric tile source.
Each pgid maps to a unique catchment polygon geometry stored in the tile server.
2Load the catchment tile layer
Add huc-10190007 (or the relevant HUC-10 code) as a vector tile source.
The tile URL template is:
https://tiles.lynker-spatial.com/api/tiles/huc-10190007/{z}/{x}/{y}
Available sources and their bounding boxes are listed at
tiles.lynker-spatial.com/catalog.
Use
huc-10190007 for the Fort Collins / Cache la Poudre demonstration area,
or the full
hydrofabric source for national coverage.
3Filter and style inundated features
Use a MapLibre / Mapbox GL expression to highlight polygons whose pgid
property matches the list returned in step 1.
const TOKEN = '<your-token>';
const pgids = [101234, 101235, 101238, 102001, 102004]; // from FlowFabric API
map.addSource('catchments', {
type: 'vector',
tiles: [
`https://tiles.lynker-spatial.com/api/tiles/huc-10190007/{z}/{x}/{y}`
],
// Pass the token in the tile request header (MapLibre GL JS ≥ 3.x)
headers: { Authorization: `Bearer ${TOKEN}` },
minzoom: 0,
maxzoom: 14
});
// Base layer — all catchments, low opacity
map.addLayer({
id: 'catchments-base',
type: 'fill',
source: 'catchments',
'source-layer': 'default',
paint: {
'fill-color': '#1e40af',
'fill-opacity': 0.1,
'fill-outline-color': 'rgba(89,169,255,0.2)'
}
});
// Inundation layer — only highlighted pgids
map.addLayer({
id: 'catchments-inundated',
type: 'fill',
source: 'catchments',
'source-layer': 'default',
filter: ['in', ['get', 'pgid'], ['literal', pgids]],
paint: {
'fill-color': '#0ea5e9',
'fill-opacity': 0.75,
'fill-outline-color': '#38bdf8'
}
});
Complete Example (MapLibre GL JS)
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/maplibre-gl/dist/maplibre-gl.css" />
<script src="https://unpkg.com/maplibre-gl/dist/maplibre-gl.js"></script>
<style>
html, body, #map { margin: 0; height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
const TOKEN = localStorage.getItem('ls_token') || prompt('Enter your API token');
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json',
center: [-105.1, 40.6],
zoom: 9
});
map.on('load', async () => {
// 1. Fetch inundated pgids from FlowFabric API
const res = await fetch('https://api.lynker-spatial.com/v1/inundation-ids', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${TOKEN}`
},
body: JSON.stringify({ reach_id: '2823932', flow_cfs: 4500 })
});
const { pgids } = await res.json();
// 2. Add tile source
map.addSource('catchments', {
type: 'vector',
tiles: [`https://tiles.lynker-spatial.com/api/tiles/huc-10190007/{z}/{x}/{y}`],
headers: { Authorization: `Bearer ${TOKEN}` }
});
// 3. Base + inundation layers
map.addLayer({
id: 'catchments-base',
type: 'fill',
source: 'catchments',
'source-layer': 'default',
paint: { 'fill-color': '#1e40af', 'fill-opacity': 0.15 }
});
map.addLayer({
id: 'catchments-inundated',
type: 'fill',
source: 'catchments',
'source-layer': 'default',
filter: ['in', ['get', 'pgid'], ['literal', pgids]],
paint: { 'fill-color': '#0ea5e9', 'fill-opacity': 0.75 }
});
});
</script>
</body>
</html>
API Reference
| Endpoint |
Service |
Description |
POST /v1/inundation-ids |
FlowFabric API |
Given a reach ID and flow value, returns inundated pgids |
GET /api/tiles/{source}/{z}/{x}/{y} |
Tile Service |
Mapbox Vector Tile for the given source and coordinates |
GET /catalog |
Tile Service |
JSON list of all available tile sources with metadata |
GET /me |
Tile Service |
Current user identity and monthly quota usage |
GET /health |
Tile Service |
Health check — returns 200 OK |
Trusted Origins (No-Token Browser Access)
Requests from hydrofabric.lynker-spatial.com and floodfabric.lynker-spatial.com
automatically receive a viewer API key at the CloudFront edge — no Authorization header
is needed from those first-party apps. Third-party integrations always require a token.
Error Reference
| Status | Meaning | Action |
401 |
Missing or expired token |
Re-authenticate via Cognito or obtain a new API key |
403 |
Token valid but not authorized for this source |
Check your account tier and dataset access |
429 |
Monthly quota exceeded |
Check /me — upgrade tier or wait for monthly reset |
404 |
Tile or source not found |
Verify source name at /catalog |