Hosted MCP coming soon. v1 data: mazowieckie.Join the waitlist

API and docs

One envelope.
REST and MCP.

Six read operations, each one request, each taking the text as typed, an id or a point. The MCP tools return the same JSON as the REST endpoints.

curl · check by free text
curl -sS "https://api.landfeed.pl/v1/check?q=Lesnowola%2025%2F18" \
  -H "X-Api-Key: $LANDFEED_API_KEY"
public API host not live yet · placeholdercost 1 request

Conventions

  • Every read takes exactly one of q (free text as typed: "pogorzelec dziłaka 284/5", "Lesnowola 25/18", "Marcinowice 221"), id (EGiB id in slash or dash form: 146501_1.0101.12/3 or 146501_1.0101.12-3) or point (lat,lng, or lat and lng). You never need to resolve first.
  • Ambiguous input returns HTTP 200, status: "ambiguous" and candidates with confidence. needs_obreb: true means ask which obręb.
  • Plans carry status draft | adopted | in_force | none and effective_from. Drafts are shown and labelled.
  • Ids we return are canonical (slash form). Field names are snake_case.
  • Auth: an X-Api-Key header; OAuth for the hosted MCP is planned at release.

The six tools

One MCP tool per endpoint. Six tools keep tools/list small.

ToolEndpointAnswers
checkGET /v1/checkCan you build on this parcel? Verdict, named checks with sources and basis, record embedded.
parcelGET /v1/parcel, POST /v1/parcel/batchThe full sourced record; layers narrows it, geometry=full adds the polygon. Batch up to 1,000 items.
layerGET /v1/layer/{layer}One layer for one parcel; planning answers plan ogólny, MPZP, WZ and gmina status at once.
resolveGET /v1/resolveCandidates with confidence and corpus_coverage; fuzzy locality matching.
searchGET or POST /v1/searchParcels at an address, within up to 2,000 m, or in a bbox up to 4 km²; cursor pagination.
eventsGET /v1/eventsChanges since a date, newest first, each with before, after, source and as_of.

Also: GET /v1/gminy/{teryt}/planning and GET /v1/gminy/planning for a gmina's planning status, and GET /v1/sources for sources, licences and freshness.

Costs

Cost is in requests per call, declared as x-request-cost on every operation in the OpenAPI.

OperationRequests
GET /v1/check1

verdict, named checks and the full record in one call

GET /v1/parcel1
POST /v1/parcel/batch1per item, up to 1,000
GET /v1/layer/{layer}1
GET /v1/resolve1
GET or POST /v1/search1
GET /v1/events1
GET /v1/gminy/…/planning1
GET /v1/sources0
GET /v1/openapi.json0

Coverage states

Every layer answer has coverage, note, source (with attribution) and as_of.

StateMeaningvalue
coveredThe source holds a record here.the record
covered_no_dataThe source covers this place and records nothing. A real negative, and it is charged.the empty answer: false, 0, [], "none"
not_coveredThe state does not publish it, or we hold no data here. Say so; do not infer.null
not_computedWe hold the source but have not computed it here yet.null

Billing and refunds

Every response carries billing {cost, charged, refunded, rule} and the headers X-Request-Cost, X-Credits-Charged and X-Credits-Refunded.

Charged

Answers, informative negatives (covered_no_data) and candidate lists (ambiguous).

Free

Invalid input (HTTP 400, free_invalid_input), a missing or wrong key (401), a matching If-None-Match (304), and operations that cost 0.

Refunded

Not found (404), other 4xx, every 5xx, status: not_covered, and a single-layer answer that is not_covered or not_computed.

Batch counts per item (rule: batch_mixed when items differ).

Errors

Every error body has code, message, hint and docs; example_id when the input was a parcel; signup_url on 401.

invalid_input 400unauthorized 401not_found 404rate_limited 429source_unavailable 503internal 500

Caching

GET by id returns an ETag; send it as If-None-Match to get 304, free. Authenticated responses are Cache-Control: private. Caching, embedding and keeping answers in session memory are allowed with attribution.

More examples

The planning layer by id

curl · one request
curl -sS "https://api.landfeed.pl/v1/layer/planning?id=141803_2.0006.25/18" \
  -H "X-Api-Key: $LANDFEED_API_KEY"

Sources and freshness, free

curl · cost 0
curl -sS "https://api.landfeed.pl/v1/sources" \
  -H "X-Api-Key: $LANDFEED_API_KEY"

Invalid input is free

HTTP 400 · body excerpt
{
  "status": "error",
  "result": null,
  "error": { "code": "invalid_input", "hint": "Pass exactly one of q, id or point",
             "example_id": "146501_1.0101.12/3", "docs": "…", … },
  "billing": { "cost": 1, "charged": 0, "refunded": 0, "rule": "free_invalid_input" }
}

The generated reference (operations, layer schemas, tool pages, the envelope) lives in the docs site, built from these contracts. Docs for agents: llms.txt.