# Quickstart in 3 minutes

Use an account API key and an EGiB parcel identifier to read one layer. The API origin is `https://mcp.agentdzialek.pl`; remote MCP uses `/mcp`. This read costs 1 credit and returns its data and billing together.

## 1. Prepare a key

Open Konto (account) at `https://app.agentdzialek.pl` and use an issued account API key. Set `LANDFEED_API_KEY` through your secret manager or terminal environment. Keep it out of project files and URLs. If the account has no key or credits, obtain them in the console first.

## 2. Read a layer

The parcel id and dates are from a recorded contract fixture, not a promise that this parcel is available live. Replace the id with your parcel. Choose one client.

### curl

<!-- example:quickstart.sh -->
```sh
curl --silent --show-error --get 'https://mcp.agentdzialek.pl/v1/parcel' \
  -H "X-Api-Key: ${LANDFEED_API_KEY}" \
  --data-urlencode 'id=146501_1.0101.12/3' \
  --data-urlencode 'layers=flood'
```


### Python 3.10+

Save as `quickstart.py` and run `python3 quickstart.py`. Only the standard library is needed.

<!-- example:quickstart.py -->
```python
import json
import os
import urllib.parse
import urllib.request

query = urllib.parse.urlencode({"id": "146501_1.0101.12/3", "layers": "flood"})
request = urllib.request.Request(
    "https://mcp.agentdzialek.pl/v1/parcel?" + query,
    headers={"X-Api-Key": os.environ["LANDFEED_API_KEY"]},
)
with urllib.request.urlopen(request, timeout=30) as response:
    body = json.load(response)
# A 200 can still be ambiguous or uncovered. Never assume it means usable data.
if body["status"] == "ambiguous":
    print(json.dumps({"candidates": body["candidates"]}, ensure_ascii=False))
elif body["status"] != "ok":
    print(json.dumps({"status": body["status"], "error": body["error"]}, ensure_ascii=False))
else:
    print(json.dumps({"layers": body["result"]["layers"], "billing": body["billing"]}, ensure_ascii=False))
```


### TypeScript, Node.js 22.18+

Save as `quickstart.ts` and run `node quickstart.ts`. This example needs no extra package.

<!-- example:quickstart.ts -->
```typescript
const key = process.env.LANDFEED_API_KEY;
if (!key) throw new Error("Set LANDFEED_API_KEY");
const url = new URL("https://mcp.agentdzialek.pl/v1/parcel");
url.search = new URLSearchParams({ id: "146501_1.0101.12/3", layers: "flood" }).toString();
const response = await fetch(url, {
  headers: { "X-Api-Key": key },
  signal: AbortSignal.timeout(30_000),
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
const body = await response.json();
// Keep ambiguity, unavailable data and successful answers distinct.
if (body.status === "ambiguous") {
  console.log(JSON.stringify({ candidates: body.candidates }));
} else if (body.status !== "ok") {
  console.log(JSON.stringify({ status: body.status, error: body.error }));
} else {
  console.log(JSON.stringify({ layers: body.result.layers, billing: body.billing }));
}
export {};
```


## 3. Interpret the response

Read `status` first. On `ambiguous`, show `candidates` and ask the user to identify the parcel; HTTP 200 does not authorize a silent choice. On `ok`, inspect `result.layers.flood.coverage`, `note`, `source`, `as_of` and `scope` when present. Never turn `not_covered` or `not_computed` into a statement that there is no flood hazard.

```json
{
  "status": "ok",
  "query": {
    "kind": "id",
    "input": {
      "id": "146501_1.0101.12/3"
    },
    "resolved": null
  },
  "result": {
    "id": "146501_1.0101.12/3",
    "admin": {
      "voivodeship": "14",
      "gmina_teryt": "1465011",
      "gmina_name": "Warszawa",
      "obreb_id": "146501_1.0101",
      "number": "12/3"
    },
    "area": {
      "official_m2": null,
      "geometry_m2": 500,
      "source": "computed",
      "provenance": {
        "id": "egib_parcels",
        "title": "egib_parcels",
        "attribution": "Źródło: Główny Urząd Geodezji i Kartografii (GUGiK), Ewidencja Gruntów i Budynków (EGiB)",
        "as_of": "2026-10-01"
      },
      "note": "Powierzchnię obliczono z geometrii działki; powierzchnia urzędowa EGiB jest niedostępna."
    },
    "layers": {
      "flood": {
        "layer": "flood",
        "coverage": "covered_no_data",
        "value": {
          "q10": false,
          "q100": false,
          "q500": false
        },
        "note": "Według map zagrożenia powodziowego działka leży poza wskazanymi na nich obszarami zagrożenia w sprawdzonym zakresie. Nie wyklucza to powodzi.",
        "source": {
          "id": "mzp_flood",
          "title": "mzp_flood",
          "attribution": "Źródło: Państwowe Gospodarstwo Wodne Wody Polskie, mapy zagrożenia powodziowego (ISOK), licencja CC BY 4.0",
          "as_of": "2026-10-01"
        },
        "as_of": "2026-10-01",
        "layer_version": "flood-national-20261016",
        "licence": {
          "position": "cc_by_4_0",
          "attribution": "Źródło: Państwowe Gospodarstwo Wodne Wody Polskie, mapy zagrożenia powodziowego (ISOK), licencja CC BY 4.0",
          "terms_url": "https://creativecommons.org/licenses/by/4.0/",
          "review_ref": "seed/attribution_review_2026-10-13.sql#mzp_flood"
        },
        "scope": "parcel_polygon",
        "method": "official"
      }
    },
    "record_hash": null,
    "display_geometry": {
      "type": "MultiPolygon",
      "coordinates": [
        [
          [
            [
              21.0,
              52.0
            ],
            [
              21.001,
              52.0
            ],
            [
              21.001,
              52.001
            ],
            [
              21.0,
              52.001
            ],
            [
              21.0,
              52.0
            ]
          ]
        ]
      ]
    },
    "display_simplified": true,
    "adjacent_parcel_ids": [
      "146501_1.0101.12/4"
    ],
    "adjacent_parcel_ids_truncated": false
  },
  "candidates": [],
  "sources": [],
  "billing": {
    "cost": 1,
    "charged": 1,
    "refunded": 0,
    "rule": "charged",
    "credits": 1
  },
  "error": null,
  "meta": {
    "request_id": "fixture",
    "api_version": "v1",
    "contract_version": "2.0.0",
    "operation": "parcel",
    "generated_at": "2026-10-16T12:00:00Z",
    "calls": 1
  },
  "auth": {
    "kind": "api_key"
  },
  "plan": "free"
}
```


This fixture demonstrates v2. Some serving reads retain the compatible v1 shape without `meta.contract_version`; do not invent absent fields. `billing`, `X-Credits-Charged` and `X-Credits-Refunded` report settlement. Python and TypeScript stop on HTTP errors; inspect the error body before replay.

Next: [coverage](coverage.md), [authentication](authentication.md), [parcel reference](../../operations/parcel.md).
