Skip to main content

GET /api/discover

Filter locations by score thresholds across all metros. Query parameters
NameTypeRequiredDefaultDescription
metrostringMetro slug filter.
compositeMinintMinimum composite score.
businessMinintMinimum Business Vitality.
safetyMinintMinimum Safety score.
limitint50Max results.
Example
curl "https://axiomlocus.io/api/discover?metro=sf&compositeMin=60&safetyMin=50"
Response
{ "total": 12, "results": [{ "h3_index": "...", "metro_slug": "sf", "location_name": "Mission District", "composite": 74 }] }
FieldTypeDescription
totalnumberNumber of matching locations
results[].compositenumberComposite score 0-100
results[].location_namestringNeighborhood name

GET /api/nearby

Everything we know near a location — permits, POIs, schools, clinical trials, FDA events, zoning. Query parameters
NameTypeRequiredDefaultDescription
latfloatLatitude.
lngfloatLongitude.
Example
curl "https://axiomlocus.io/api/nearby?lat=37.7749&lng=-122.4194"
Response
{ "summary": { "permits": 45, "pois": 120, "schools": 3, "clinical_trials": 8 }, "recent": { ... } }
FieldTypeDescription
summaryobjectCount of records per data type within ~1km
recentobjectRecent records from each data type

GET /api/metro-tier-distribution

Count of scored cells in each safety tier bucket for a given signal across a metro. Powers the tier-mix bar on the Explorer Intelligence Rail so you can see at a glance whether a metro is mostly safe or mostly elevated, without leaving the page. Buckets follow the standard composite score breakpoints: Prime ≥80, Strong 60–79, Solid 40–59, Watch 20–39, Elevated <20. Cells with a null value for the requested signal are excluded. Query parameters
NameTypeRequiredDefaultDescription
metrostringMetro slug (e.g. sf, nyc, denver).
signalstringsafety_environmentColumn to bucket on. One of composite, business_vitality, population_momentum, demographics, economic_strength, development_pipeline, accessibility, safety_environment, amenity_demand.
Example
curl "https://axiomlocus.io/api/metro-tier-distribution?metro=sf&signal=safety_environment"
Response
{
  "metro": "sf",
  "signal": "safety_environment",
  "total": 1284,
  "buckets": {
    "prime": 412,
    "strong": 537,
    "solid": 246,
    "watch": 71,
    "elevated": 18
  }
}
FieldTypeDescription
metrostringMetro slug echoed from the request.
signalstringSignal column the distribution is computed over.
totalnumberTotal scored cells included in the distribution (cells with null on the requested signal are excluded).
buckets.primenumberCells scoring ≥ 80.
buckets.strongnumberCells scoring 60–79.
buckets.solidnumberCells scoring 40–59.
buckets.watchnumberCells scoring 20–39.
buckets.elevatednumberCells scoring < 20.
The same endpoint backs distribution bars for any signal group — pass a different signal to render a development-pipeline mix, business-vitality mix, or composite mix without a separate route. Historical score trends for a metro or specific H3 cell. Pass metro for a metro-wide aggregate trend or h3_index for a per-cell time-series with all eight signal-group sub-scores. Exactly one of the two is required. The endpoint reads from the score_history table that the Railway scorer snapshots once per day, so a fresh row appears for every (h3_index, profile, snapshot_date) covered by that day’s scorer pass. Cells the scorer didn’t touch on a given day will be absent from the time-series for that date. Query parameters
NameTypeRequiredDefaultDescription
metrostringMetro slug for an aggregate metro-wide trend.
h3_indexstringSpecific H3 cell for a detailed per-cell trend with signal-group breakdowns.
daysint90Lookback period in days.
Metro aggregate example
curl "https://axiomlocus.io/api/score-trends?metro=sf&days=30"
{ "metro": "sf", "days": 30, "trend": [{ "date": "2026-03-30", "avg_composite": 42, "cells": 20 }] }
FieldTypeDescription
trend[].datestringSnapshot date (YYYY-MM-DD)
trend[].avg_compositenumberAverage composite score across the metro for that date
trend[].cellsnumberCells in the metro with a snapshot on that date
Per-cell example
curl "https://axiomlocus.io/api/score-trends?h3_index=882a1072d3fffff&days=90"
{
  "h3_index": "882a1072d3fffff",
  "days": 90,
  "snapshots": [
    {
      "snapshot_date": "2026-04-29",
      "composite": 71,
      "business_vitality": 68,
      "population_momentum": 74,
      "demographics": 65,
      "economic_strength": 80,
      "development_pipeline": 77,
      "accessibility": 62,
      "safety_environment": 70,
      "amenity_demand": 64
    }
  ]
}
FieldTypeDescription
snapshots[].snapshot_datestringSnapshot date (YYYY-MM-DD)
snapshots[].compositenumberCell composite score 0–100 on that date
snapshots[].business_vitalitysnapshots[].amenity_demandnumber | nullPer-group sub-score 0–100; null if the group could not be computed for that snapshot

GET /api/top-movers

Discover the cells whose composite score has changed the most over a 7-, 30-, 90-, or 180-day window. Each row reports the latest composite, the prior-window composite, and the delta between them, so you can surface neighborhoods that are heating up (or cooling off) without manually diffing snapshots from /api/score-trends. Deltas are computed against the freshest snapshot in score_history at or before the lookback boundary, not a fixed calendar date. This means partial scorer coverage on any given day does not bias the leaderboard — cells without a baseline snapshot inside the window are simply excluded. The same RPC powers the metro-overview “movement” rail in the Explorer and the standalone /movers page in the dashboard. Query parameters
NameTypeRequiredDefaultDescription
daysint30Lookback window. Must be one of 7, 30, 90, or 180.
directionstringupup for biggest gainers, down for biggest decliners, or all to rank by absolute delta.
metrostringMetro slug filter (e.g. sf, nyc, boston). Omit for cross-metro results.
limitint25Max results (1–100).
Example
curl "https://axiomlocus.io/api/top-movers?days=30&direction=up&metro=boston&limit=10"
Response
{
  "window_days": 30,
  "direction": "up",
  "metro": "boston",
  "movers": [
    {
      "h3_index": "882a306665fffff",
      "metro_slug": "boston",
      "location_name": "Seaport District",
      "latest_composite": 61,
      "prior_composite": 38,
      "delta": 23,
      "latest_snapshot_date": "2026-04-29",
      "prior_snapshot_date": "2026-03-30"
    }
  ]
}
FieldTypeDescription
window_daysintLookback window echoed from the request.
directionstringup, down, or all — echoed from the request.
metrostring | nullMetro slug filter, or null when the call was cross-metro.
moversarrayCells ranked by composite delta. Empty when the window has no eligible snapshot pairs yet.
movers[].h3_indexstringH3 cell index.
movers[].metro_slugstringMetro the cell belongs to.
movers[].location_namestringNeighborhood name.
movers[].latest_compositenumberComposite score 0–100 from the most recent snapshot.
movers[].prior_compositenumberComposite score 0–100 from the freshest snapshot at or before the lookback boundary.
movers[].deltanumberlatest_composite - prior_composite. Positive when the cell is improving, negative when declining.
movers[].latest_snapshot_datestringDate of the latest snapshot (YYYY-MM-DD).
movers[].prior_snapshot_datestringDate of the prior-side snapshot used as the baseline.
Daily snapshots accumulate from the moment a cell is first scored, so newer metros may return an empty movers array on longer windows until enough history has built up. Use a shorter window (days=7) to surface activity earlier.

GET /api/schools

Nearby school quality ratings (1-10 scale). Query parameters
NameTypeRequiredDefaultDescription
latfloatLatitude.
lngfloatLongitude.
radiusfloat2Radius in miles.
limitint10Max results.
Example
curl "https://axiomlocus.io/api/schools?lat=37.7749&lng=-122.4194&radius=1"
Response
{ "total": 5, "schools": [{ "name": "Lincoln Elementary", "rating": 8, "enrollment": 450 }] }
FieldTypeDescription
schools[].ratingnumberQuality score 1-10
schools[].enrollmentnumberStudent enrollment

GET /api/life-sciences

Clinical trials and FDA enforcement data by state or sponsor. Query parameters
NameTypeRequiredDefaultDescription
statestringUS state name.
sponsorstringSponsor name (partial match).
typestringallFilter: trials, fda, or all.
limitint50Max results.
Example
curl "https://axiomlocus.io/api/life-sciences?state=Massachusetts&type=trials&limit=10"
Response
{ "trials": { "total": 10, "data": [{ "nct_id": "NCT05754281", "sponsor": "Joslin Diabetes Center" }] } }
FieldTypeDescription
trials.data[].nct_idstringClinicalTrials.gov trial ID
trials.data[].sponsorstringLead sponsor organization

GET /api/zoning

Zoning district rules — allowed uses, height limits, FAR, setbacks. Query parameters
NameTypeRequiredDefaultDescription
metrostringMetro slug.
codestringSpecific district code.
categorystringFilter: residential, commercial, industrial, mixed_use.
Example
curl "https://axiomlocus.io/api/zoning?metro=denver&category=commercial"
Response
{ "metro": "denver", "total": 8, "districts": [{ "district_code": "C-MX-5", "max_height_ft": 65, "max_far": 3.0 }] }
FieldTypeDescription
districts[].district_codestringZoning designation code
districts[].max_height_ftnumberMaximum building height in feet
districts[].max_farnumberFloor area ratio

GET /api/port-risk

Surface upstream port disruption affecting a Locus metro’s economic catchment. Twenty-two metros are mapped to their primary and secondary ports by trucking corridor (e.g. phoenix → Long Beach via I-10, atlanta → Savannah via I-16). When an inbound port shows elevated wait times in Overwatch, the row appears here with a risk_level of watch, elevated, or severe, derived from p90 wait, median wait, and trend direction. Returns an empty risks array when no upstream port is currently disrupted — the PortRiskBadge on cell-detail panels uses that signal to hide itself. Use this to flag CRE locations whose tenants depend on container imports (industrial, logistics, big-box retail) before a soft port closure shows up in occupancy or rent comps. Query parameters
NameTypeRequiredDefaultDescription
metrostringMetro slug (e.g. houston, atlanta, chicago).
Example
curl "https://axiomlocus.io/api/port-risk?metro=atlanta"
Response
{
  "metro": "atlanta",
  "risks": [
    {
      "port_slug": "savannah",
      "port_name": "Port of Savannah",
      "tier": "primary",
      "trucking_km": 400,
      "median_wait_hours": 18,
      "p90_wait_hours": 84,
      "vessel_count": 23,
      "trend_direction": "worsening",
      "trend_consecutive_periods": 3,
      "risk_level": "severe",
      "measured_at": "2026-04-29T00:00:00Z"
    }
  ]
}
FieldTypeDescription
metrostringMetro slug echoed from the request.
risksarrayActive port-risk rows, ordered by risk_level then p90_wait_hours (highest first). Empty when no upstream port is disrupted.
risks[].port_slugstringStable port identifier (e.g. savannah, long-beach, ny-nj).
risks[].port_namestringHuman-readable port name.
risks[].tierstringprimary or secondary — the port’s role in the metro’s catchment.
risks[].trucking_kmnumberDriving distance from port to metro centroid (km).
risks[].median_wait_hoursnumberMedian vessel wait time at the port over the measurement window.
risks[].p90_wait_hoursnumber90th-percentile wait — the figure that drives most risk-level transitions.
risks[].vessel_countnumberVessels currently queued or anchored upstream.
risks[].trend_directionstringworsening, stable, or improving.
risks[].trend_consecutive_periodsnumberPeriods the trend has held — used to confirm sustained disruption vs. a single-day spike.
risks[].risk_levelstringwatch, elevated, or severe.
risks[].measured_atstringISO 8601 timestamp of the underlying Overwatch measurement.

GET /api/export

Requires Bearer token.
Export scored location data as CSV or JSON. Requires Pro or Team plan (bulk_export entitlement). Query parameters
NameTypeRequiredDefaultDescription
metrostringMetro slug filter (e.g. sf, nyc).
formatstringcsvcsv or json.
savedbooleanfalseWhen true, restricts the export to the caller’s saved cells (the cells in their monitored_locations portfolio). Composes with metro.
limitint1000Max rows (5000 max).
Portfolio export (saved=true) Set saved=true to export only the cells the authenticated user has saved into their portfolio (their monitored_locations). This is the intended workflow for analysts who track a curated set of cells across metros and want a CSV/JSON snapshot of just those rows rather than a full-metro or platform-wide pull.
  • The filter is applied as an IN over the caller’s saved h3_index list, so the result respects ordering by composite (descending) and the limit cap.
  • It composes with metro — combining saved=true&metro=sf returns only saved cells inside SF.
  • If the user has no saved cells, the endpoint short-circuits to an empty payload (200 OK) without scanning cell_scores. CSV responses return an empty body; JSON responses return { "total": 0, "data": [] }.
  • The download filename is tagged saved (e.g. axiom-locus-saved-2026-04-29.csv) instead of the metro slug or all, so portfolio exports are easy to identify on disk.
Examples Export all SF cells as CSV:
curl "https://axiomlocus.io/api/export?metro=sf&format=csv" -H "X-API-Key: al_xxx"
Export the caller’s saved cells (portfolio) as CSV:
curl "https://axiomlocus.io/api/export?saved=true&format=csv" -H "X-API-Key: al_xxx"
Export the caller’s saved cells inside one metro as JSON:
curl "https://axiomlocus.io/api/export?saved=true&metro=sf&format=json" -H "X-API-Key: al_xxx"
Response
h3_index,metro_slug,location_name,composite,...
88283082e7fffff,sf,Mission District,74,...

GET /api/bids

Search federal and government procurement opportunities sourced from SAM.gov. Filter by state, keyword, or NAICS code to find relevant contracts. Query parameters
NameTypeRequiredDefaultDescription
statestringTwo-letter state code (e.g. TX, CA).
keywordstringFull-text search across title and description.
naicsstringNAICS code filter (e.g. 236220 for commercial construction).
typestringBid type (partial match).
activestringtrueSet to false to include expired bids.
limitint50Max results (max 200).
Example
curl "https://axiomlocus.io/api/bids?state=TX&keyword=construction&limit=10"
Response
{
  "state": "TX",
  "keyword": "construction",
  "count": 10,
  "bids": [
    {
      "notice_id": "SAM-2026-001234",
      "title": "Renovation of Federal Building, Houston TX",
      "type": "Solicitation",
      "agency": "General Services Administration",
      "posted_date": "2026-04-10",
      "response_deadline": "2026-05-15",
      "description": "Full interior renovation of the federal courthouse...",
      "naics_code": "236220",
      "place_of_performance_city": "Houston",
      "place_of_performance_state": "TX",
      "estimated_value": 4500000,
      "url": "https://sam.gov/opp/abc123",
      "set_aside_type": "Small Business"
    }
  ]
}
FieldTypeDescription
countintNumber of matching bids returned.
bids[].notice_idstringSAM.gov notice identifier.
bids[].response_deadlinestringDeadline for bid submissions.
bids[].naics_codestringNAICS industry classification code.
bids[].estimated_valuenumberEstimated contract value in USD.
bids[].set_aside_typestringSet-aside designation (e.g. Small Business, 8(a), HUBZone).