# Nakordoni Developer API — Reference

> Source: https://nakordoni.eu/api/v1/docs.md
> Human docs: https://nakordoni.eu/en/developers/docs
> Sign up for a free key: https://nakordoni.eu/en/developers/signup

## Overview

| | |
|---|---|
| Base URL | `https://nakordoni.eu/api/v1/data/` |
| Format | JSON, UTF-8 |
| Auth | `Authorization: Bearer NKD-DEV-XXXX-XXXX-XXXX` |
| Versioning | Path-versioned (v1). Breaking changes only with a new version. |

All responses use this envelope:

```json
{
  "ok": true,
  "api_version": "1",
  "product": "queue",
  "attribution": "Data by nakordoni.eu",
  "data": [ ... ],
  "snapshot": { ... },
  "usage": { "requests_today": 12, "limit_today": 200, "remaining": 188 }
}
```

Errors return `ok: false` with `error.code` (missing_api_key, invalid_api_key, qps_exceeded, quota_exceeded, unknown_product, bad_request, internal_error) and HTTP 401/403/404/429/500.

## Plans & Quotas

| Plan | Daily calls | QPS | Notes |
|---|---|---|---|
| Explorer (free) | 200 standard / 50 forecast+stats | 2 | Instant key after email verification |
| Pay As You Grow | Custom | 10 | Manual invoice, request from dashboard |

## Authentication

```bash
curl "https://nakordoni.eu/api/v1/data/queue?ppid=id_13" \
  -H "Authorization: Bearer NKD-DEV-XXXX-XXXX-XXXX"
```

## Code Samples

**JavaScript (fetch)**
```js
const res = await fetch('https://nakordoni.eu/api/v1/data/forecast?ppid=id_13&prediction_steps=24', {
  headers: { 'Authorization': 'Bearer NKD-DEV-XXXX-XXXX-XXXX' }
});
const { data, snapshot } = await res.json();
```

**Python (requests)**
```python
import os, requests
KEY = os.environ["NKD_DEV_KEY"]
r = requests.get("https://nakordoni.eu/api/v1/data/queue",
                  params={"ppid": "id_13"},
                  headers={"Authorization": f"Bearer {KEY}"})
print(r.json()["snapshot"])
```

## Products

### API Status
Live health of every Developer-API product: online / degraded / offline, response latency and last-checked time, plus an overall rollup. Public — no API key required, never counts against your quota. Refreshed every 5 minutes. Mirrors the human status page at nakordoni.eu/{lang}/status.
**Endpoint:** `GET /api/v1/data/status`
**Example:** `/api/v1/data/status`

### Checkpoints Directory API
Directory of all monitored border checkpoints: IDs, names, countries, coordinates and status. Use it to discover ppid values for the other APIs.
**Endpoint:** `GET /api/v1/data/checkpoints`

| Parameter | Description |
|---|---|
| `country` | Filter by numeric country code (1=UA, 2=PL, 3=SK, 4=HU, 5=RO, 6=MD, 7=BY, 8=LT, 9=LV, …) |
| `lang` | Language for checkpoint names (default en) |
**Example:** `/api/v1/data/checkpoints`

### Multi-Checkpoint API
Fetch live queue status and/or data freshness for up to 20 checkpoints in a single request. Designed for dashboard builders who poll many PPIDs simultaneously — reduces 20+ individual calls to one. Quota counts as ⌈(N PPIDs × sub-products) / 2⌉ — 50% cheaper than the equivalent individual calls. Use include=queue,update-info to get both datasets at once.
**Endpoint:** `GET /api/v1/data/multi?ppids=id_2,id_13,id_15&include=queue,update-info&lang=en`

| Parameter | Description |
|---|---|
| `ppids` | Comma-separated list of checkpoint IDs (required, max 20) — e.g. id_2,id_13,id_15,id_59 |
| `include` | Comma-separated sub-products to include: queue, update-info (default: queue,update-info) |
| `lang` | Language code for checkpoint names in queue responses (default: en) |
**Example:** `/api/v1/data/multi?ppids=id_2,id_13,id_15&include=queue,update-info&lang=en`

### Border Queue API
All checkpoints on a given border + vehicle type in one call — live queue, wait estimate, and data freshness for every crossing point. Supports single destination, comma-separated list, or "all" to query all neighbours at once. Results sorted by queue length ascending, each checkpoint tagged with its border country.
**Endpoint:** `GET /api/v1/data/border/1/all/4`

| Parameter | Description |
|---|---|
| `origin` | Origin country code (URL path segment): 1=Ukraine, 2=Poland, 3=Slovakia, 4=Hungary, 5=Romania, 6=Moldova, 7=Belarus, 8=Lithuania, 9=Latvia, 11=Slovenia, 12=Bulgaria, 13=Serbia, 14=Turkey, 15=North Macedonia, 16=Croatia, 17=Bosnia, 18=Germany, 19=Greece, 20=Italy, 21=Albania, 22=Montenegro, 23=Kosovo |
| `destination` | Destination (URL path segment): single country code, comma-separated list (e.g. 2,3,5), or "all" to expand to all neighbours with monitored data |
| `crossing_type` | Vehicle type (URL path segment): 4=car, 5=taxfree car, 6=bus, 7=pedestrian, 8=truck<7.5t, 9=truck |
| `lang` | Language for checkpoint names in the response (default en) |
**Example:** `/api/v1/data/border/1/all/4`

### Checkpoint Search API
Find checkpoint PPIDs by name. Pass a single name or a comma-separated list (up to 20). Searches all translation languages; returns all PPIDs at that location grouped by vehicle type (4=car, 5=taxfree car, 6=bus, 7=pedestrian, 8=truck<7.5t, 9=truck). Use this to quickly discover the right ppid before calling the queue or forecast APIs.
**Endpoint:** `GET /api/v1/data/search?name=Krakovets,Shehyni&lang=en`

| Parameter | Description |
|---|---|
| `name` | Checkpoint name or comma-separated names, in any language (e.g. Krakovets, Краківець, Krakivets) |
| `lang` | Language for returned names (default en) |
**Example:** `/api/v1/data/search?name=Krakovets,Shehyni&lang=en`

### Live Border Queue API
Real-time queue length, wait estimate and status for any monitored checkpoint, plus hourly/daily aggregates.
**Endpoint:** `GET /api/v1/data/queue?ppid=id_13`

| Parameter | Description |
|---|---|
| `ppid` | Checkpoint ID, e.g. id_13 (see /api/v1/data/checkpoints) |
| `section` | Data section (optional) |
| `origin` | Origin country code (optional) |
| `destination` | Destination country code (optional) |
**Example:** `/api/v1/data/queue?ppid=id_13`

### Advanced Wait Time API
Wait time adjusted for live traffic flow and weather, with a full breakdown of each adjustment, plus the same wait_status/trend fields as border and multi. Billed at 1.5x a normal heavy-class call, reflecting the extra traffic/weather/driver-report lookups. Granted on request.
**Endpoint:** `GET /api/v1/data/queue-advanced?ppid=id_13`

| Parameter | Description |
|---|---|
| `ppid` | Checkpoint ID, e.g. id_13 (see /api/v1/data/checkpoints) |
**Example:** `/api/v1/data/queue-advanced?ppid=id_13`

### Checkpoint Hourly Statistics API
Hourly historical queue stats per checkpoint and date: 24 hourly values, daily avg/min/max, peak and quietest hours, day-over-day comparison.
**Endpoint:** `GET /api/v1/data/stats?ppid=id_15&date=2026-06-01&compare=1`

| Parameter | Description |
|---|---|
| `ppid` | Checkpoint ID |
| `date` | YYYY-MM-DD (default: yesterday) |
| `compare` | 1 = include previous day + delta |
| `lang` | Language code (default uk) |
**Example:** `/api/v1/data/stats?ppid=id_15&date=2026-06-01&compare=1`

### Best Time to Cross API
Typical-week load statistics per checkpoint: 7×24 day-of-week × hour matrix (median + p25/p75 band), quietest/busiest day, best/worst 2-hour windows. Precomputed daily from ~60 days of real observations.
**Endpoint:** `GET /api/v1/data/day-stats?ppid=id_13&lang=en`

| Parameter | Description |
|---|---|
| `ppid` | Checkpoint ID, e.g. id_13 |
| `lang` | Language for weekday/unit labels (default uk) |
**Example:** `/api/v1/data/day-stats?ppid=id_13&lang=en`

### Queue Forecast API
ML ensemble forecast of queue levels: 24-hour and 7-day (168h) horizons with confidence bounds. The same model that powers nakordoni.eu predictions.
**Endpoint:** `GET /api/v1/data/forecast?ppid=id_13&prediction_steps=24`

| Parameter | Description |
|---|---|
| `ppid` | Checkpoint ID |
| `prediction_steps` | 24 (default) or 168 for 7-day |
**Example:** `/api/v1/data/forecast?ppid=id_13&prediction_steps=24`

### Checkpoint Alternatives API
Nearby alternative checkpoints on the same border with current queues and distance deltas. By default filters to the same vehicle type as the requested ppid. Use crossing_type to override — e.g. crossing_type=4 for cars, crossing_type=7 for pedestrians.
**Endpoint:** `GET /api/v1/data/alternatives?ppid=id_13&crossing_type=4`

| Parameter | Description |
|---|---|
| `ppid` | Checkpoint ID (e.g. id_13) |
| `lang` | Language code (default uk) |
| `crossing_type` | Optional vehicle type override: 4=car, 5=taxfree car, 6=bus, 7=pedestrian, 8=truck<7.5t, 9=truck. Defaults to same type as the requested ppid. |
| `limit` | Max results (1–10, default 5) |
**Example:** `/api/v1/data/alternatives?ppid=id_13&crossing_type=4`

### Live Queue & Freshness API
Current queue length for one checkpoint plus how fresh that reading is — returns queue_now, freshness, age_minutes, is_realtime, status, timestamp and timezone. This is the STANDARD-class way to poll live queue data: use it for frequent refreshes and keep the heavy quota for /queue, /multi and /forecast, which return the fuller payload (wait_min, trend, history).
**Endpoint:** `GET /api/v1/data/update-info?ppid=id_13`

| Parameter | Description |
|---|---|
| `ppid` | Checkpoint ID |
| `lang` | Language code |
**Example:** `/api/v1/data/update-info?ppid=id_13`

### EU Fuel Prices API
Fuel prices across EU countries — country averages, nearest stations by coordinates, or stations near a border checkpoint. Aggregated from official national sources (tankerkoenig for DE, petrol.pl for PL, fuelo.net for HU/SK/RO, EU bulletin for others).
**Endpoint:** `GET /api/v1/data/fuel?country=PL`

| Parameter | Description |
|---|---|
| `mode` | country (default) | nearest | border. country = national average; nearest = stations near lat/lon; border = stations near a checkpoint |
| `country` | ISO country code for mode=country (PL, DE, AT, FR, ES, IT, PT, SI, LU, RO, DK, HR, HU, SK, UA, …) |
| `lat` | Latitude for mode=nearest |
| `lon` | Longitude for mode=nearest (alias: lng) |
| `radius_km` | Search radius km for mode=nearest (default 30) |
| `ppid` | Checkpoint ID for mode=border (e.g. id_13) |
| `fuel_type` | diesel | e5 | e10 | lpg | petrol (optional, for mode=nearest) |
| `lang` | Language code for labels |
| `limit` | Max stations returned for mode=nearest/border (default 5) |
**Example:** `/api/v1/data/fuel?country=PL`

### Fuel Prices by City API
Per-city fuel price summary for a country: cheapest station price and average across the top 5 stations in each major city. Covers the same countries as the nakordoni.eu fuel pages (AT, DE, FR, ES, IT, PT, SI, LU, RO, DK, HR).
**Endpoint:** `GET /api/v1/data/fuel-cities?country=hr&fuel_type=diesel&lang=en`

| Parameter | Description |
|---|---|
| `country` | ISO-2 country code (required). Supported: at, de, fr, es, it, pt, si, lu, ro, dk, hr |
| `fuel_type` | diesel (default) | e5 | e10 | lpg — see available_fuel_types in the response for what each country supports |
| `lang` | Language code for city names (default en) |
**Example:** `/api/v1/data/fuel-cities?country=hr&fuel_type=diesel&lang=en`

### Driver POIs API
Truck parkings (14k+), free showers, services and supermarkets across Europe with coordinates.
**Endpoint:** `GET /api/v1/data/pois?type=parking&lat=50.7&lon=23.9&radius=50`

| Parameter | Description |
|---|---|
| `type` | parking|shower|supermarket|industrial |
| `lat` | Latitude |
| `lon` | Longitude |
| `radius` | Radius km |
**Example:** `/api/v1/data/pois?type=parking&lat=50.7&lon=23.9&radius=50`

### Currency Exchange Rates API
EUR-based exchange rates for PLN, CZK, HUF, USD, GBP, CHF, NOK and UAH — sourced from Frankfurter (ECB), cached 6h. No parameters; always returns the full rate table. Powers the nakordoni.eu currency calculator and fuel-cost pages.
**Endpoint:** `GET /api/v1/data/currency`
**Example:** `/api/v1/data/currency`

### Truck Driving Bans API
European truck driving restrictions by country and date, including seasonal and holiday bans. Each country carries a live status computed in its own timezone (active_window / next_window), plus a covered_countries list.
**Endpoint:** `GET /api/v1/data/truck-bans?country=PL`

| Parameter | Description |
|---|---|
| `country` | ISO country code (optional) |
| `date` | YYYY-MM-DD (optional) |
**Example:** `/api/v1/data/truck-bans?country=PL`

### Trading Sundays API
Sunday retail-opening regulations and upcoming trading Sundays per regulated EU country.
**Endpoint:** `GET /api/v1/data/trading-sundays?country=PL`

| Parameter | Description |
|---|---|
| `country` | ISO country code (optional) |
**Example:** `/api/v1/data/trading-sundays?country=PL`

### Holiday Calendar API
Official public holidays per European country — dates, local names and type, each country's full holiday list included. Backed by the same Nager.Date / OpenHolidaysAPI service (7-day cache, locally-computed Kosovo calendar) that powers the nakordoni.eu holiday calendar page and the prediction system's calendar factors. One country -> a flat object; several -> the same shape wrapped in a list. upcoming=1 switches to a flat, date-sorted cross-country feed; compare_to switches to a same-vs-different comparison across countries — useful for checking whether a date is a holiday on both sides of a border crossing or just one.
**Endpoint:** `GET /api/v1/data/holiday-calendar?country=PL&compare_to=UA&year=2026&lang=en`

| Parameter | Description |
|---|---|
| `country` | ISO-2 country code, or comma-separated list of up to 15, e.g. PL or PL,DE,UA. Omit for the default core set (UA,PL,SK,HU,RO,MD,DE,CZ,BG,AT). One resolved country returns a flat object; several return a list. |
| `compare_to` | ISO-2 country code, or comma-separated list, to compare against `country`. Switches to compare mode: returns which holiday dates are shared by ALL selected countries (`same`) vs only some of them (`different`, with per-date in/not_in lists) |
| `year` | YYYY (default: current year) |
| `upcoming` | 1 = switch to a flat, date-sorted list of upcoming holidays across the selected countries within `days` (optional) |
| `days` | Horizon in days for upcoming mode, 1-180. Omitted or 0 = no limit (everything the underlying service can see: this year + next) |
| `lang` | Language(s) for the localized `name` field (default en) — same 24-language translator as the nakordoni.eu holiday calendar page. Falls back to the local/English name for anything not yet cached. Comma-separated for several, up to 10, e.g. lang=en,uk,pl — `name` stays the first requested language; every holiday also gets a `names` object keyed by language code with all of them. |
**Example:** `/api/v1/data/holiday-calendar?country=PL&compare_to=UA&year=2026&lang=en`

### Bus Carrier Border Stats API
Border-crossing performance per bus carrier: crossings, average/median/min/max wait minutes — built from our own plate-matched crossing records.
**Endpoint:** `GET /api/v1/data/bus-carriers?ppid=all&days=30`

| Parameter | Description |
|---|---|
| `ppid` | Checkpoint ID or "all" for aggregated |
| `days` | Period 1-90 (default 30) |
| `min_crossings` | Minimum crossings to include a carrier (default 3) |
| `limit` | Max carriers returned (default 20) |
**Example:** `/api/v1/data/bus-carriers?ppid=all&days=30`

### Road Conditions API
Approved road condition reports near borders and on major corridors: potholes, roadworks, closures, ice, hazards — combining driver reports with automatic accelerometer detections from our navigation app.
**Endpoint:** `GET /api/v1/data/road-conditions?country=UA&severity=major`

| Parameter | Description |
|---|---|
| `country` | ISO country code (optional) |
| `condition_type` | pothole|speed_bump|roadwork|closure|hazard|ice|… (optional) |
| `severity` | low|moderate|major|critical (optional) |
| `lat` | Latitude (optional) |
| `lng` | Longitude (optional) |
| `radius` | Radius km (default 50) |
| `limit` | Max results (default 100, cap 500) |
**Example:** `/api/v1/data/road-conditions?country=UA&severity=major`

### Border AI Assistant API
Ask our production AI assistant any border-crossing question (queues, forecasts, rules, fuel, routes) and get the same grounded answer that powers the nakordoni.eu widget — in 24 languages. Already used in production by yaknakordoni.com.ua.
**Endpoint:** `GET /api/v1/data/assistant?q=How long is the queue at Krakovets now?&lang=en&ppid=id_13`

| Parameter | Description |
|---|---|
| `q` | The question (plain text) |
| `lang` | Answer language (default en) |
| `ppid` | Checkpoint context, e.g. id_13 (optional) |
**Example:** `/api/v1/data/assistant?q=How long is the queue at Krakovets now?&lang=en&ppid=id_13`

### Personalised AI Assistant API
Your own AI assistant, grounded on YOUR content plus OUR live border data. Point it at your markdown files or let us fetch the pages you name — we index them and answer from them. Choose which of our data feeds it may use (queue, forecast, alternatives, fuel, truck bans, holidays, road conditions…), choose the model tier (that is what sets the price), write your own instructions with {{feed.slug}} placeholders saying exactly where our data goes in the answer, and add a closing sentence of your own that is appended to every reply. Build it and test it at /{lang}/developers/studio, then call it here. Price per answer = model tier units + 1 unit per enabled feed (shown in the studio and in X-Devapi-Units).
**Endpoint:** `GET /api/v2/data/assistant-custom?assistant_id=1&q=Should I cross tonight or in the morning?&ppid=id_13&lang=uk`

| Parameter | Description |
|---|---|
| `assistant_id` | Your assistant id from Developers → AI Studio (required) |
| `q` | The end-user question, plain text, max 1000 chars (required) |
| `lang` | Answer language code — overrides the assistant default (optional) |
| `ppid` | Checkpoint context for queue/forecast/alternatives feeds, e.g. id_13 (optional) |
| `origin` | Origin country code for the border feed (optional) |
| `destination` | Destination country code for the border feed (optional) |
| `crossing_type` | Vehicle type for border/alternatives feeds: 4=car, 6=bus, 8=truck<7.5t, 9=truck (optional) |
| `country` | Country context for fuel / truck-bans / holidays / road-conditions feeds (optional) |
| `lat` | Latitude for the POI feed (optional) |
| `lon` | Longitude for the POI feed (optional) |
**Example:** `/api/v2/data/assistant-custom?assistant_id=1&q=Should I cross tonight or in the morning?&ppid=id_13&lang=uk`

### Travel Matrix API
Travel time + border queue data for all checkpoints from a given origin. Returns drive time, current queue, total estimated journey time, and distance for every relevant crossing — sorted from fastest. Supports multi-leg routes (e.g. Germany → Poland → Ukraine border). Powers the nakordoni.eu navigator "Choose a crossing" feature.
**Endpoint:** `GET /api/v1/data/travel-matrix?origin_lat=50.06&origin_lon=19.94&type=4&dest=all&lang=en`

| Parameter | Description |
|---|---|
| `origin_lat` | Origin latitude (required) |
| `origin_lon` | Origin longitude (required) |
| `type` | Crossing type: 4=car UA→EU (default), 5=car EU→UA, 6=bus, 7=pedestrian, 8=truck<7.5t, 9=truck |
| `dest` | Destination country code (1=UA, 2=PL, 3=SK, 4=HU, 5=RO, 6=MD) or "all" (default) |
| `origin_country` | ISO-2 origin country (e.g. DE, PL, CZ). Enables multi-leg route calculation for non-border countries |
| `lang` | Language code for checkpoint names (default uk) |
**Example:** `/api/v1/data/travel-matrix?origin_lat=50.06&origin_lon=19.94&type=4&dest=all&lang=en`

### Route Planner API
A door-to-door plan for a border trip, not just a driving time. Returns the route, the crossings actually on it with their live or arrival-time-forecast queue, and the stops a driver really makes — rest breaks, a meal, refuelling — laid out on one timeline. The border is part of that timeline: a long queue satisfies the break that was coming up and resets the driving clock, so a 3-hour wait is never reported as 3 hours PLUS a full set of breaks nobody took. Car stops follow a driving-hygiene model; bus and truck stops respect the mandatory EU 561/2006 rest, and the bus service overhead is calibrated on 1000+ licensed international coach schedules. Set stop_places=1 to name a real rest area or fuel station for each stop.
**Endpoint:** `GET /api/v2/data/route-plan?origin_lat=50.4501&origin_lon=30.5234&dest_lat=52.2297&dest_lon=21.0122&vehicle=car&stop_places=1&lang=en`

| Parameter | Description |
|---|---|
| `origin_lat` | Origin latitude (required) |
| `origin_lon` | Origin longitude (required) |
| `dest_lat` | Destination latitude (required) |
| `dest_lon` | Destination longitude (required) |
| `vehicle` | car (default), bus or truck — picks both the routing profile and the stop model |
| `depart` | ISO-8601 departure time, up to 14 days ahead (default: now). Drives the arrival-time queue forecast |
| `via` | Optional waypoints as lat,lon;lat,lon (max 3) — e.g. to route through a different crossing |
| `forecast` | 1 (default) = forecast the queue for your arrival time at each crossing; 0 = use the current queue |
| `stop_places` | 1 = name a real rest area / fuel station for each stop (default 0) |
| `overnight` | 1 = add an advisory overnight stop when the drive exceeds 11 h (default 0) |
| `geometry` | 1 = include the full route geometry (default 0) |
| `alternatives` | 1 (default) = include nearby alternative crossings with their queues |
| `preference` | recommended (default), fastest or shortest |
| `lang` | Language code for checkpoint names (default en) |
**Example:** `/api/v2/data/route-plan?origin_lat=50.4501&origin_lon=30.5234&dest_lat=52.2297&dest_lon=21.0122&vehicle=car&stop_places=1&lang=en`


## Attribution

All Explorer-plan integrations must display a visible "Data by nakordoni.eu" link on the page where data is shown.

Acceptable placements:
- Web: `<a href="https://nakordoni.eu" rel="noopener">Data by nakordoni.eu</a>` near the data
- Apps: tappable link on the data screen or the info/about screen

Pay As You Grow customers may omit attribution.

## MCP Server

Prefer tool-calling over REST? `https://nakordoni.eu/mcp` is a real MCP server (Streamable
HTTP transport, spec 2025-06-18/2025-03-26) exposing a safe read-only subset of this API as
MCP tools — same API key and quota as above, just a different transport. Server card:
`https://nakordoni.eu/.well-known/mcp/server-card.json`.

Tools: `get_api_status` (no key needed), `list_checkpoints`, `get_border_queue`,
`get_live_queue`, `get_queue_forecast`.

```json
{
  "mcpServers": {
    "nakordoni": {
      "url": "https://nakordoni.eu/mcp",
      "headers": { "Authorization": "Bearer NKD-DEV-XXXX-XXXX-XXXX" }
    }
  }
}
```

## Useful Links

- Developer portal: https://nakordoni.eu/en/developers
- Full docs: https://nakordoni.eu/en/developers/docs
- API changelog: https://nakordoni.eu/en/developers/changelog
- Support tickets: https://nakordoni.eu/en/developers/tickets
- Live status: https://nakordoni.eu/en/status
