parcelpump
Sign in

Display

DOCS / API REFERENCE

parcelpump — API reference (generated)

This file is generated from src/api/route-registry.ts by npm run docs:api. Do not edit by hand — edit the registry and regenerate.

Narrative documentation, examples, type definitions, and worked consumer flows live in docs/api.md.

Endpoints at a glance

Method Path Cap Summary
GET /health public Liveness check
GET /openapi.json public OpenAPI 3.0 spec for this API
GET /docs public Swagger UI for human browsing
GET /llms.txt public LLM-friendly summary + pointers (markdown)
GET /.well-known/ai-plugin.json public ChatGPT-plugin manifest pointing at /openapi.json
GET /tiles/manifest.json public Active PMTiles archive pointer
GET /v1/sources read List every wired (source, vendor) tuple
PATCH /v1/sources/{source} admin Toggle source.active or update vendor_config
PATCH /v1/source-refresh-policies/{source} admin Adjust cadence / next_due_at / agricultural_only
GET /v1/parcels/{source}/{id} read Single parcel with full Scrape jsonb
GET /v1/parcels read Bbox query — lightweight rows
POST /v1/parcels/{source}/{id}/scrape-now enqueue Synchronously scrape a parcel via its vendor adapter
GET /v1/search read Fuzzy typeahead across parcels + sos_entities
GET /v1/findings/{source}/{id} read Review-engine findings for a parcel
GET /v1/scrape-jobs read List/filter scrape jobs
GET /v1/scrape-jobs/{id} read Single scrape-job detail
POST /scrape-jobs enqueue Enqueue per-parcel scrape jobs
POST /v1/scrape-jobs/enqueue-ag-county enqueue Bulk-enqueue every is_agricultural parcel in a source
DELETE /scrape-jobs/{id} admin Cancel a queued/running job
GET /v1/admin/concurrency read Per-vendor concurrency configs
GET /v1/admin/tuning-log read Recent tuner decisions
PATCH /v1/admin/concurrency/{vendor} admin Update bounds / mode / target / thresholds for one vendor
POST /v1/admin/concurrency/run-tuner admin Run one tuner cycle synchronously
GET /v1/admin/sources/health read Per-source aggregates (parcel count, queue depth, last success/error)

system

GET /health

Capability: public (no auth) · Tag: system

Liveness check

Responses:

  • 200 — Service is up
{
  "status": "ok",
  "time": "2026-05-05T03:16:22.038Z"
}

GET /openapi.json

Capability: public (no auth) · Tag: system

OpenAPI 3.0 spec for this API

Generated from src/api/route-registry.ts. Use to feed code generators (openapi-typescript, openapi-generator-cli, etc.).

Responses:

  • 200 — OpenAPI document

GET /docs

Capability: public (no auth) · Tag: system

Swagger UI for human browsing

Responses:

  • 200 — HTML — Swagger UI rendered against /openapi.json

GET /llms.txt

Capability: public (no auth) · Tag: system

LLM-friendly summary + pointers (markdown)

Emerging convention (similar to robots.txt). Tells Claude / Grok / GPT etc. what parcelpump is and where to find machine-readable specs. Tuned for LLM context windows.

Responses:

  • 200 — text/plain markdown

GET /.well-known/ai-plugin.json

Capability: public (no auth) · Tag: system

ChatGPT-plugin manifest pointing at /openapi.json

Responses:

  • 200 — Plugin manifest JSON

tiles

GET /tiles/manifest.json

Capability: public (no auth) · Tag: tiles

Active PMTiles archive pointer

Returns the URL + pmtiles:// URL of the most recent parcels archive. Public so map clients can fetch without auth. Cached 5 min at the edge.

Responses:

  • 200 — Manifest
{
  "parcels": {
    "url": "https://api.parcelpump.io/tiles/parcels/a43955359b44b9e4.pmtiles",
    "pmtiles_url": "pmtiles://https://api.parcelpump.io/tiles/parcels/a43955359b44b9e4.pmtiles",
    "updated_at": "2026-05-04T18:07:39.546Z",
    "size_bytes": 51420430
  }
}

sources

GET /v1/sources

Capability: read (any valid key) · Tag: sources

List every wired (source, vendor) tuple

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.

Responses:

  • 200 — Source rows + cadence
{
  "count": 922,
  "sources": []
}

PATCH /v1/sources/{source}

Capability: admin · Tag: sources

Toggle source.active or update vendor_config

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.
source path yes Source slug e.g. franklin-county-wa

Request body: Partial update

{
  "active": false,
  "vendor_config": {
    "pacsCid": 12
  }
}

Responses:

  • 200 — Updated row
  • 404 — source not found

PATCH /v1/source-refresh-policies/{source}

Capability: admin · Tag: sources

Adjust cadence / next_due_at / agricultural_only

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.
source path yes Source slug

Request body: Any subset of cadence|next_due_at|agricultural_only

{
  "cadence": "monthly",
  "agricultural_only": true
}

Responses:

  • 200 — Updated policy
  • 404 — policy not found

parcels

GET /v1/parcels/{source}/{id}

Capability: read (any valid key) · Tag: parcels

Single parcel with full Scrape jsonb

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.
source path yes Source slug
id path yes source_parcel_id

Responses:

  • 200 — ParcelpumpParcel
{
  "id": "...",
  "source": "franklin-county-wa",
  "source_parcel_id": "123290284",
  "owner_name": "ROUNDABOUT FARM LLC"
}
  • 404 — not found

GET /v1/parcels

Capability: read (any valid key) · Tag: parcels

Bbox query — lightweight rows

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.
bbox query yes west,south,east,north (EPSG:4326)
source query no Optional source filter
limit query no max rows (default 500, cap 5000)

Responses:

  • 200 — Lightweight parcel rows
  • 400 — bbox missing or non-numeric

POST /v1/parcels/{source}/{id}/scrape-now

Capability: enqueue · Tag: parcels

Synchronously scrape a parcel via its vendor adapter

Dispatches the adapter immediately, waits for the result (5–15s typical), upserts to RDS, returns the full parcel record. Path used by the 'user clicked an unknown parcel' flow. Playwright vendors auto-enqueue and return 503 with enqueued:true.

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.
source path yes Source slug
id path yes source_parcel_id

Request body: Optional vendor-key overrides

{}

Responses:

  • 200 — Full parcel record after scrape
  • 404 — unknown source
  • 502 — vendor / network error
  • 503 — vendor requires Playwright; auto-enqueued
{
  "enqueued": true,
  "error": "vendor helion-pso requires async path"
}

search

GET /v1/search

Capability: read (any valid key) · Tag: search

Fuzzy typeahead across parcels + sos_entities

pg_trgm-based; tolerates typos. Owner name match weighted 3×, situs address 2×, mailing/agent 1×; exact-prefix bonus +0.3 to +0.5; exact parcel-ID match +5.0.

Proximity ranking (Google-Maps-style) — when lat and lon are supplied, parcels closer to that point get a score bonus that decays linearly over proximity_km (default 50). This re-ranks but never filters — a uniquely-named distant match still wins on text alone.

Query-term parsing — when state is not supplied, a trailing state name or 2-letter code is extracted from the query. So q="smith florida" is equivalent to q="smith"&state=FL.

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.
q query yes Search query, min 2 chars. May contain a trailing state token ("jackass WA", "smith florida") which is auto-extracted into the state filter.
limit query no max rows (default 20, cap 100)
types query no Comma-separated subset
state query no 2-letter state code. Hard filter when supplied (overrides query-term extraction).
source query no Source slug to narrow search (e.g. 'franklin-county-wa'). Parcels-only filter; doesn't apply to entities.
lat query no Latitude in degrees for proximity ranking. Pair with lon. Re-ranks results, never filters.
lon query no Longitude in degrees. Pair with lat.
proximity_km query no Decay radius for the proximity bonus (default 50). At distance=0 bonus is +1.5; at proximity_km bonus is 0.
zoning query no Zoning filter — prefix-matches zoning_code, zoning_description, or land_use_class. e.g. 'R-1', 'agricultural', 'commercial'.
group query no Set to 'owner' to merge parcels with the same owner_name into a single kind: "owner-group" entry with a members array + bbox. Useful for Google-Maps-style highlight of all parcels owned by a single entity.

Responses:

  • 200 — Ranked hits
{
  "count": 14,
  "results": [
    {
      "kind": "parcel",
      "source": "franklin-county-wa",
      "source_parcel_id": "123300017",
      "owner_name": "HAYDEN FARMS INC",
      "score": 1.58
    }
  ]
}
  • 400 — q < 2 chars

findings

GET /v1/findings/{source}/{id}

Capability: read (any valid key) · Tag: findings

Review-engine findings for a parcel

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.
source path yes Source slug
id path yes source_parcel_id

Responses:

  • 200 — Findings array (often empty in v0)

scrape-jobs

GET /v1/scrape-jobs

Capability: read (any valid key) · Tag: scrape-jobs

List/filter scrape jobs

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.
status query no queued
source query no Source slug filter
limit query no default 100, cap 500

Responses:

  • 200 — Job rows

GET /v1/scrape-jobs/{id}

Capability: read (any valid key) · Tag: scrape-jobs

Single scrape-job detail

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.
id path yes Job UUID

Responses:

  • 200 — Job row
  • 404 — not found

POST /scrape-jobs

Capability: enqueue · Tag: scrape-jobs

Enqueue per-parcel scrape jobs

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.

Request body: Single object or array

[
  {
    "source": "franklin-county-wa",
    "source_parcel_id": "113110106"
  }
]

Responses:

  • 200 — Inserted job IDs

POST /v1/scrape-jobs/enqueue-ag-county

Capability: enqueue · Tag: scrape-jobs

Bulk-enqueue every is_agricultural parcel in a source

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.

Request body: Source + optional limit + skip_existing flag

{
  "source": "franklin-county-wa",
  "skip_existing": true
}

Responses:

  • 200 — Enqueue summary
  • 404 — unknown source

DELETE /scrape-jobs/{id}

Capability: admin · Tag: scrape-jobs

Cancel a queued/running job

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.
id path yes Job UUID

Responses:

  • 200 — Cancelled
  • 404 — not found or terminal

concurrency

GET /v1/admin/concurrency

Capability: read (any valid key) · Tag: concurrency

Per-vendor concurrency configs

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.

Responses:

  • 200 — Vendor rows

GET /v1/admin/tuning-log

Capability: read (any valid key) · Tag: concurrency

Recent tuner decisions

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.
vendor query no Vendor filter
limit query no default 50, cap 500

Responses:

  • 200 — Log rows

PATCH /v1/admin/concurrency/{vendor}

Capability: admin · Tag: concurrency

Update bounds / mode / target / thresholds for one vendor

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.
vendor path yes Vendor name

Request body: Any subset of min/max/target/mode/threshold fields

{
  "mode": "manual",
  "target_concurrency": 2
}

Responses:

  • 200 — Updated config
  • 404 — vendor not found

POST /v1/admin/concurrency/run-tuner

Capability: admin · Tag: concurrency

Run one tuner cycle synchronously

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.

Responses:

  • 200 — Per-vendor decisions

admin

GET /v1/admin/sources/health

Capability: read (any valid key) · Tag: admin

Per-source aggregates (parcel count, queue depth, last success/error)

Parameters:

Name In Required Description
X-Parcelpump-Key header yes API key. See docs/secrets-and-keys.md.

Responses:

  • 200 — Health rows
{
  "count": 922,
  "sources": []
}