# 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, 10=Estonia, 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`

### 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`

### Data Freshness API
When a checkpoint was last updated, by which source, and a freshness rating.
**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`

### Truck Driving Bans API
European truck driving restrictions by country and date, including seasonal and holiday bans.
**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`

### 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`

### 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`


## 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.

## 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
