API preview

Developer docs

Lotmark exposes source-cited parcel enrichment records for the countywide Sonoma, CA dataset. Use this page to verify authentication, lookup behavior, response shape, provenance, and batch workflows before scheduling implementation time.

Base URLs

Parcel API: https://lotmark-parcel-api-production.up.railway.app

Public site and access requests: https://lotmark.io

The parcel API is a separate protected service. Use the parcel API base URL for every /v1 request, not the public landing page URL.

Interactive OpenAPI docs are available on the parcel service at https://lotmark-parcel-api-production.up.railway.app/docs. The machine-readable schema is available at https://lotmark-parcel-api-production.up.railway.app/openapi.json.

Current Coverage

Production currently serves the official Sonoma County bundle loaded on 2026-07-24.

Authentication

All /v1 endpoints require a bearer API key. Keep the key in server-side secrets and send it with each request:

Authorization: Bearer LOTMARK_API_KEY

GET /health is open and can be used before credentials are provisioned. API keys are issued for sandbox evaluation or through checkout, and are shown once at delivery.

Endpoint Table

Method Path Auth Purpose
GET /health No Checks that the parcel API service and database are configured.
GET /v1/parcels/:parcel_id Yes Returns one curated parcel enrichment record by Lotmark parcel ID.
GET /v1/parcels/by-apn/:apn Yes Looks up a parcel by county APN and returns the same enrichment shape.
GET /v1/parcels/search?address=...&limit=10 Yes Searches loaded parcel addresses. limit is clamped from 1 to 25.
POST /v1/parcels:batch-enrich Yes Resolves parcel IDs, APNs, and address queries in one request. Maximum 100 total lookups.
GET /v1/parcels/:parcel_id/qa Yes Returns the persisted QA report for a generated parcel response.
GET /v1/usage Yes Returns request counts for the current API key.

Curl Examples

Set the base URL and key once, then run the smoke tests below.

export LOTMARK_API_BASE="https://lotmark-parcel-api-production.up.railway.app"
export LOTMARK_API_KEY="ltm_live_..."

curl -s "$LOTMARK_API_BASE/health"

curl -s -H "Authorization: Bearer $LOTMARK_API_KEY" "$LOTMARK_API_BASE/v1/parcels/lm_ca_028-030-009"

curl -s -H "Authorization: Bearer $LOTMARK_API_KEY" "$LOTMARK_API_BASE/v1/parcels/by-apn/028-030-009"

curl -s -H "Authorization: Bearer $LOTMARK_API_KEY" "$LOTMARK_API_BASE/v1/parcels/search?address=FRANZ%20VALLEY&limit=5"

curl -s -X POST "$LOTMARK_API_BASE/v1/parcels:batch-enrich" -H "Authorization: Bearer $LOTMARK_API_KEY" -H "Content-Type: application/json" -d '{"parcel_ids":["lm_ca_028-030-009"],"apns":["028-040-023"],"addresses":["PORTER CREEK RD"]}'

curl -s -H "Authorization: Bearer $LOTMARK_API_KEY" "$LOTMARK_API_BASE/v1/parcels/lm_ca_028-030-009/qa"

curl -s -H "Authorization: Bearer $LOTMARK_API_KEY" "$LOTMARK_API_BASE/v1/usage"

Response Shape

Parcel responses are JSON objects with source blocks on major sections, compact per-field source references, and an LLM-ready narrative grounded in structured fields. Embedding vectors are not returned by default; the response exposes embedding metadata.

{
  "parcel_id": "lm_ca_001-011-004",
  "freshness_days": 0,
  "parcel": {
    "apn": "001-011-004",
    "address": "721 CLOVERDALE BLVD N",
    "county": "Sonoma",
    "state": "CA",
    "land_acres": 0.77,
    "source": {
      "agency": "County of Sonoma",
      "product": "Parcels Public",
      "accessed": "2026-07-24",
      "record_count": 189239
    }
  },
  "risk_features": {
    "fire": {
      "wildfire_hazard_potential_value": 4,
      "wildfire_hazard_potential_class": "high",
      "distance_to_burn_perimeter_m": 792.7,
      "last_burn_year_within_5km": 2021,
      "source": {
        "agency": "CAL FIRE",
        "product": "California Fire Perimeters public view nearest feature within 5 km"
      },
      "confidence": 0.8
    },
    "flood": {
      "fema_zone": "X",
      "in_sfha": false,
      "source": {
        "agency": "FEMA",
        "product": "National Flood Hazard Layer Flood Hazard Zones point intersect"
      },
      "confidence": 0.9
    }
  },
  "building": {
    "primary_year_built": 1952,
    "primary_size_sqft": 4705,
    "source": {
      "agency": "County of Sonoma",
      "product": "Parcels Public building attributes"
    },
    "confidence": 0.85
  },
  "terrain": {
    "elevation_ft": 1275.4,
    "local_relief_150m_ft": 429.8,
    "slope_degrees": 23.59,
    "aspect_degrees": 179.2,
    "source": {
      "agency": "USGS",
      "product": "3DEP Bare Earth DEM Dynamic service 30 m raster export sample"
    },
    "confidence": 0.9
  },
  "soil": {
    "mukey": "459841",
    "musym": "PcB",
    "mapunit_name": "Pajaro clay loam, overwash, 2 to 5 percent slopes",
    "hydrologic_group": "C/D",
    "drainage_class": "Somewhat poorly drained",
    "source": {
      "agency": "USDA NRCS",
      "product": "SSURGO mapunit polygon centroid intersect with SDA mapunit attributes"
    }
  },
  "vegetation": {
    "canopy": {
      "canopy_percent": 0,
      "year": 2023,
      "source": {
        "agency": "USDA Forest Service",
        "product": "NLCD Tree Canopy Cover 2023 raster export sample"
      }
    }
  },
  "narrative": {
    "text": "0.77 acre parcel, with a 1952 primary structure, at 1275.4 ft elevation.",
    "grounded_in": ["parcel", "building", "terrain", "risk.fire", "risk.flood"]
  },
  "embedding": {
    "dim": 1536,
    "model": "text-embedding-3-small",
    "status": "metadata_only"
  },
  "sources": {
    "parcel_boundaries": {
      "agency": "County of Sonoma",
      "source_file": "parcels.geojson"
    },
    "parcel_terrain_attributes": {
      "agency": "USGS",
      "source_file": "terrain.csv"
    },
    "soil_attributes": {
      "agency": "USDA NRCS",
      "source_file": "soil.csv"
    },
    "flood_hazard_zones": {
      "agency": "FEMA",
      "source_file": "flood_zones.geojson"
    }
  },
  "field_sources": {
    "parcel.apn": "parcel_boundaries",
    "terrain.elevation_ft": "parcel_terrain_attributes",
    "soil.mukey": "soil_attributes",
    "risk_features.flood.fema_zone": "flood_hazard_zones",
    "narrative.grounded_in": ["parcel_boundaries", "parcel_building_attributes", "parcel_terrain_attributes", "burn_perimeters", "flood_hazard_zones"]
  }
}

Error Responses

Errors use JSON bodies with ok: false and a short error string.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer

{"ok":false,"error":"Missing bearer token."}

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer

{"ok":false,"error":"Invalid API key."}

HTTP/1.1 400 Bad Request

{"ok":false,"error":"Provide an address query."}

HTTP/1.1 404 Not Found

{"ok":false,"error":"Parcel not found."}

HTTP/1.1 429 Too Many Requests
Retry-After: 60

{"ok":false,"error":"Too many requests. Try again later."}

Batch requests also return 400 when the body is empty or contains more than 100 total parcel IDs, APNs, and address queries.

Rate Limits

Sandbox access is intended for functional evaluation, integration tests, and response-shape validation. Coordinate before scripted load tests or bulk runs.

Test Parcels

Provisioned sandboxes and production API keys currently load the countywide Sonoma source bundle. These records are good smoke tests for APN lookup, direct parcel lookup, address search, and enrichment coverage.

Parcel ID APN Address Query
lm_ca_001-011-004 001-011-004 721 CLOVERDALE BLVD N
lm_ca_028-030-009 028-030-009 3225 FRANZ VALLEY RD
lm_ca_079-020-011 079-020-011 10275 LOCH HAVEN DR
lm_ca_091-340-003-112542 091-340-003 1830 BOXHEART DR

Some APNs have multiple county geometries. If a direct parcel ID misses or an APN has duplicates, retry with /v1/parcels/by-apn/:apn and inspect the returned parcel IDs.

Sandbox Access

To evaluate Lotmark, send the team a work email, company name, intended use case, expected test volume, and whether you need APN lookup, address search, batch enrichment, or QA reports. We will provision a sandbox bearer key and confirm the bundle loaded for your tests.

curl -s -X POST "https://lotmark.io/api/waitlist" -H "Content-Type: application/json" -d '{"email":"you@company.com","name":"Your Name","company":"Company","role":"proptech-ai","plan":"developer","message":"Please provision sandbox API access for APN lookup, address search, batch enrichment, and QA reports.","request_demo":false}'

After credentials are provisioned, start with /health, then run APN lookup and /v1/usage. Keep API keys out of client-side code and browser logs.