Developers

One API call. A decision back.

A REST API you call server-to-server from your quote flow, policy system or bots. Pass an address; get a score, a verdict and a bind clearance.

Base URL

All endpoints are served over HTTPS from the live host. A branded domain (api.perilintel.ai) is on the roadmap.

https://perilintel-api-production.up.railway.app

Authentication

Machine clients send the API key as a header. Missing or invalid keys return 401. Responses set Cache-Control: no-store (gate answers are time-sensitive) and a per-key rate limit applies (429 + Retry-After when exceeded). Every response carries an X-Request-ID you can quote in support.

X-API-Key: your_api_key

Primary endpoint

GET/api/underwrite

Address (or coordinates) → score + triage verdict + pre-bind clearance, in one response.

ParamRequiredNotes
qq or lat+lngAddress string, e.g. 6607 Main St, Penticton BC. Geocoded server-side.
lat, lngq or lat+lngUse if you already have coordinates (skips geocoding).
programoptionalAppetite profile, e.g. farm, home, commercial.
fireKmoptionalOverride the wildfire clearance radius (default 50 km).
# request
GET /api/underwrite?q=Penticton, BC
Header: X-API-Key: ••••••••

# response
{
  "location": { "lat": 49.50, "lng": -119.59, "address": "Penticton, BC" },
  "score": { "value": 42, "grade": "C", "dominant": "fire" },
  "triage": { "verdict": "REVIEW", "reasons": [ … ] },
  "clearance": { "clearToBind": false, "status": "BLOCKED",
    "blocks": [ "active wildfire 28 km away (within 50 km)" ] }
}

verdict: REFER · REVIEW · CLEAR  |  status: CLEAR (ok to bind) · BLOCKED (active hazard) · VERIFY (feed gap — never a silent clear)  |  grade: A–E

Other endpoints

EndpointReturns
GET /api/underwrite?…&detail=1Adds a perils block — per-peril history, frequency & trend (wildfire, flood, hail/storm).
GET /api/assess?lat=&lng=Full triage + score + per-peril proximity detail.
GET /api/clearance?lat=&lng=Just the bind-clearance object.
GET /api/peril-history?lat=&lng=Per-peril last-yr / 5-yr / 10-yr frequency + trend + freshness stamps.
GET /api/claimcheck?q=&date=&peril=Claims-time verification → CONSISTENT / INCONSISTENT / INCONCLUSIVE with findings.
POST /api/bindcheckFresh clearance at bind time; echoes policyRef, audited. The bind webhook.
POST /api/exitcheckExit gate — holds a non-renewal if an active event is in range (fail-to-hold).
POST /api/renewalcheckBatch re-screen of a book of locations; per-location status + summary.
GET /api/geocode?q={ lat, lng, label, source }
GET /api/exposureWhole-book exposure (verdict per insured location).
GET /api/statsPublic aggregate national collection counts (no auth, no PII).
GET /healthz{ "ok": true } — public health check.

Call it from anywhere

# Python
r = requests.get("https://perilintel-api-production.up.railway.app/api/underwrite",
  params={"q": addr}, headers={"X-API-Key": KEY})
verdict = r.json()["triage"]["verdict"]

// Node
const r = await fetch(`https://perilintel-api-production.up.railway.app/api/underwrite?q=${enc(addr)}`,
  { headers: { "X-API-Key": KEY } });

Errors

CodeMeaning & how to handle
400Bad input — missing q and lat/lng, or out-of-range coordinates.
401Missing / invalid API key.
404Address genuinely not found (a real no-match — do not retry blindly; pass a fuller address).
422Location is outside Canada coverage. Surface it — never treat as a clear.
429Rate limit exceeded. Back off and retry after the Retry-After header.
502Upstream geocoder / hazard feed is transiently down. Retry. Distinct from 404.
500Internal error. On the gate, clearance fails safe to VERIFY — never a false clear.

Fail-safe contract: a missing feed or error never yields a silent CLEAR — it returns VERIFY (or holds the gate). Branch on 404 (real no-match) vs 502 (retryable outage).

Outputs are advisory — not a peril determination, rating, or underwriting decision.

Get an API key.

We'll set you up with a sandbox key and walk your team through the integration.