# EU Trade Explorer -- REST API

HTTP REST API for the EU Trade Explorer, serving Eurostat Comext (customs trade) and
PRODCOM (industrial production) statistics for the Combined Nomenclature.

> Bridge to the tradedashboard.eu EU Trade Explorer — access the same data via REST endpoints or, for LLM agents, via the MCP bridge at mcp.tradedashboard.eu.

## Typical Workflow

1. **Resolve the product**: If you don't already know the right Combined Nomenclature (CN) product code, use `/api/resolve_product_code` with a keyword (e.g. "glass jars") or a candidate code. Note that CN nomenclature is often coarser than a colloquial product name. For example, there is no code for "glass jars" alone, only a heading (7010) that bundles jars with bottles and closures; check `has_subcodes` and the returned hierarchy before assuming a code is a clean match.

2. **Choose your path**:
   - **Short path**: Call `/api/get_full_report` for a rundown of the most important stats. If you want something quick and simple, you can already stop there, analyse that data, and write your report.
   - **Long path**: There are close to 28 endpoints you can call iteratively depending on your angle. Start with `/api/get_overview` for headline totals, then drill into `/api/get_partner_detail`, `/api/get_reporter_detail`, `/api/get_concentration`, `/api/get_specialisation`, `/api/get_net_import_reliance`, etc. as needed.

## Request Model

Every analytical endpoint takes the same `DashboardQuery` JSON body:
- `product`: Combined Nomenclature code(s)
- `reporter`: Declaring entity (EU member state, etc.)
- `partner_set`: Named partner preset or custom list
- `period_start`, `period_end`: Analysis window (YYYY-MM format)
- `frequency`: 'month', 'quarter', or 'year'
- Plus endpoint-specific query parameters (`entity_level`, `flow`, `partner`, detection thresholds, ...)

## Streaming Responses

The analytical endpoints under `/api/descriptive`, `/api/concentration`, `/api/volatility` and `/api/vulnerability` do not return a single JSON object. They stream newline-delimited JSON (`application/x-ndjson`): zero or more `{"type": "progress", "message": ...}` lines while Eurostat data loads, then exactly one terminal frame — either `{"type": "result", "data": ...}` or `{"type": "error", "detail": ..., "status": ...}`.

Many endpoints also accept a `compact=true` query parameter to condense long numeric time series into summary statistics (first/last/min/max/mean/pct_change) instead of full series. Use this when you just want main trends; omit it when identifying shocks and outliers.

## Authentication & Access

The Overview endpoint (`/api/get_overview`) and everything under `/api/reference` and `/api/auth` are public.

All other analytical endpoints require one of:
- A signed-in session cookie (from the dashboard UI)
- A personal API key sent as `Authorization: Bearer ...` or `X-API-Key`
- OAuth 2.1 authentication (for programmatic/headless clients)

See `/.well-known/oauth-authorization-server` for OAuth setup details. LLM agents and MCP clients should use the MCP bridge at mcp.tradedashboard.eu instead.

Requests are rate-limited per client IP at the edge (Caddy), ahead of this application.

## Dashboard Navigation

You typically do not need to construct these API calls yourself if you're using the interactive dashboard. Instead, refer to the relevant menu item/tab on the website. For programmatic access, the dashboard structure is:

| Menu | Name | Tab | Typical API endpoints |
|------|------|-----|----------------------|
| `overview` | Overview | `overview`, `partners`, `reporters`, `map-imports`, `map-exports` | `/api/get_overview`, `/api/get_partner_detail`, `/api/get_reporter_detail`, `/api/get_map_data` |
| `concentration` | Market structure | `concentration`, `concentration-map`, `specialisation`, `production-volumes` | `/api/get_concentration`, `/api/get_concentration_map`, `/api/get_specialisation`, `/api/get_production_series` |
| `cross-section` | Cross-section | `compare`, `product-volatility`, `product-concentration` | `/api/get_product_compare`, `/api/get_volatility`, `/api/get_concentration_compare` |
| `volatility` | Volatility & shocks | `volatility`, `supply-shocks`, `price-shocks`, `pattern-shifts` | `/api/get_volatility`, `/api/get_supply_shocks`, `/api/get_price_shocks`, `/api/get_pattern_shift` |
| `vulnerability` | Strategic autonomy | `net-import-reliance`, `trade-intensity`, `export-propensity`, `subcontracting-*` | `/api/get_net_import_reliance`, `/api/get_trade_intensity`, `/api/get_export_propensity`, `/api/get_subcontracting_intensity`, `/api/get_subcontracting_members` |

## Methodological Notes

These notes are reproduced here so figures can be interpreted and cited correctly:

- **Concentration (HHI)**: The Herfindahl-Hirschman Index measures how concentrated trade is across partners or EU Member States. For each period, it sums the squared market shares of each entity, producing a score from 0 (perfectly spread across many partners) to 10,000 (one partner holds 100% of the market).

- **Specialisation (RSCA)**: Intra-EU revealed symmetric comparative advantage per member state: whether a member state's share of intra-EU exports for a specific product is larger than its share of intra-EU exports overall. The Balassa index (RCA) compares a member state's export share of the product against its export share of all products (both measured within the EU); RSCA rescales RCA symmetrically onto [-1, 1]: RCA = (x_p / x_total) / (X_p / X_total), RSCA = (RCA - 1) / (RCA + 1), where x is the member state's intra-EU exports and X is the EU total (p = this product, total = all products). -1 is under-specialised, 0 is the EU average, +1 is strongly specialised. Intra-EU flows are distorted by the Rotterdam/Antwerp effect, so read the index with caution.

- **Volatility (CV)**: Each value is the coefficient of variation (CV): standard deviation divided by the mean, for a single partner × product pair over the selected period. Inactive periods (zero quantity) are excluded so they don't distort the result. A higher CV means the flow swings more relative to its typical level. Only the most active partners by volume are selected for volatility analysis.

- **Supply shocks**: Detects abnormal collapses in trade volumes. For each partner/product pair with enough sustained activity, the algorithm flags periods where volume drops well below that pair's historical average. To surface more (weaker) shocks: lower the minimum-deviation threshold, raise the cumulative trade share considered, extend tolerated gaps, lower the minimum number of stable years required, or treat any small drop (even ~5%) as a shock.

- **Price shocks**: Detects sudden price variations while accounting for each flow's usual volatility. The algorithm compares each period's price against a retrospective reference window, then flags regime changes whose amplitude exceeds a configurable multiple of the coefficient of variation.

- **Pattern shifts**: Suggested workflow: note the usual volatility of the entities that interest you (via volatility endpoints), check for significant volume/price variations there, use supply/price shock endpoints to identify the dates where these are most pronounced, then use one of those dates as `query.midpoint` in `/api/get_pattern_shift`.

- **Net import reliance (NIR)**: Expresses net imports (imports minus exports) as a share of domestic consumption in the Union: NIR = (Imports - Exports) / Apparent consumption, where Apparent consumption = Production + Imports - Exports. E.g., 40% means 40% of EU consumption of the product is met by imports; negative means the EU is a net exporter (not import-dependent). Used by the European Commission to determine whether a sector should get particular monitoring or support.

- **Trade intensity (TI)**: Measures how open EU27 production is to international trade, following the European Commission's CEEAG methodology (used for State-aid eligibility of sectors at risk of carbon leakage): TI = (Imports + Exports) / (Imports + Production). Close to 1 = highly trade-exposed; near 0 = predominantly domestic.

- **Export propensity**: The share of EU27 production sold abroad: Export propensity = Exports / Production. E.g., 60% means 60% of the value produced in the Union is exported; re-exports or stock drawdown can push values above 100%.

- **Subcontracting intensity**: The share of EU production manufactured for someone other than the factory's owner: Intensity = Sub-contracted production / Total sold production. Near 100% signals a processing hub with little own R&D; near 0% marks an autonomous industrial base. The own/sub split only exists from 2021 onward in the PRODCOM database.

- **PRODCOM-backed endpoints**: For production volumes and all vulnerability endpoints—when a customs code maps to several PRODCOM codes, figures are aggregated across them, or, if Eurostat suppresses detail at that level, sourced from the nearest available higher aggregate. Use `prodcom_code` query parameters to pin one specific mapping instead of relying on that default.

- **Rotterdam/Antwerp caveat**: Whenever Belgium or the Netherlands appear as the main trading importer or exporter of a product, beware: it might just be that the bulk of the trade for that product is transiting through Antwerp or Rotterdam.

## reference

Public reference data: country lists, UI language detection, customs-code validation/search and nomenclature trees.

- `GET /api/reference/countries` — Get Countries
- `GET /api/reference/language` — Get Language
- `GET /api/reference/validate-code/{code}` — Validate Code
- `GET /api/reference/data-range` — Get Data Range
- `GET /api/reference/chapters` — Get Chapters
- `GET /api/reference/subtree/{code}` — Get Subtree
- `GET /api/reference/search` — Search Codes

## dashboard

Descriptive statistics for the main dashboard: overview totals, partner/reporter breakdowns, the map view, entity tables and member-state PRODCOM production series.

- `POST /api/descriptive/overview` — Get Overview
- `POST /api/descriptive/partner-detail` — Get Partner Detail
- `POST /api/descriptive/reporter-detail` — Get Reporter Detail
- `POST /api/descriptive/map-data` — Get Map Data
- `POST /api/descriptive/top-entities` — Get Top Entities
- `POST /api/descriptive/production` — Get Production Series

## products

Cross-section views comparing sub-products or several codes side by side.

- `POST /api/descriptive/product-compare` — Get Product Compare

## concentration

Concentration analysis via the Herfindahl-Hirschman Index (HHI): trade concentration across partners/member states (overall, per sub-product and on the map), intra-EU specialisation, and PRODCOM production concentration across member states.

- `POST /api/concentration/concentration` — Get Concentration
- `POST /api/concentration/concentration-compare` — Get Concentration Compare
- `POST /api/concentration/concentration-map` — Get Concentration Map
- `POST /api/concentration/specialisation` — Get Specialisation
- `POST /api/concentration/production` — Get Production Concentration

## volatility

Volatility and shock detection: coefficient-of-variation grids, sudden volume collapses, rapid price shifts and pattern shifts.

- `POST /api/volatility/volatility` — Get Volatility
- `POST /api/volatility/pattern-shift` — Get Pattern Shift
- `POST /api/volatility/supply-shocks` — Get Volatility Supply Shocks
- `POST /api/volatility/price-shocks` — Get Volatility Price Shocks

## vulnerability

Industrial-exposure indicators that join PRODCOM production with Comext trade data: Net Import Reliance, Trade Intensity and Export Propensity.

- `POST /api/vulnerability/net-import-reliance` — Get Net Import Reliance
- `POST /api/vulnerability/trade-intensity` — Get Trade Intensity
- `POST /api/vulnerability/export-propensity` — Get Export Propensity

## autonomy

Industrial-autonomy indicators built on the PRODCOM sub-contracting / own-account split: how much of EU (and member-state) sold production is toll manufacturing for others.

- `POST /api/autonomy/subcontracting` — Get Subcontracting Intensity
- `POST /api/autonomy/subcontracting-members` — Get Subcontracting Members

## auth

Account lifecycle: register, email verification, login/logout, password reset and per-user preferences.

- `POST /api/auth/register` — Auth Register
- `GET /api/auth/verify` — Auth Verify
- `POST /api/auth/login` — Auth Login
- `POST /api/auth/logout` — Auth Logout
- `GET /api/auth/me` — Auth Me
- `POST /api/auth/resend-verification` — Auth Resend
- `POST /api/auth/request-password-reset` — Auth Request Reset
- `POST /api/auth/reset-password` — Auth Reset Password
- `POST /api/auth/set-lang` — Auth Set Lang
- `POST /api/auth/delete-account` — Auth Delete Account
- `POST /api/auth/recent-codes` — Auth Add Recent Code

## api-key

Self-service personal API key management: generate, rotate and revoke the Bearer credential used for headless/programmatic REST access.

- `POST /api/api-key/generate` — Auth Generate Api Key
- `POST /api/api-key/revoke` — Auth Revoke Api Key

## oauth

OAuth 2.1 authorization server backing MCP-client logins (e.g. an editor): dynamic client registration, the authorize/token/ revoke endpoints, and the account panel's connected-apps list/revoke.

- `GET /.well-known/oauth-authorization-server` — Oauth Server Metadata
- `POST /oauth/register` — Oauth Register Client
- `GET /oauth/authorize` — Oauth Authorize Get
- `POST /oauth/token` — Oauth Token
- `POST /oauth/revoke` — Oauth Revoke
- `GET /api/oauth/client-info` — Api Oauth Client Info
- `POST /api/oauth/decision` — Api Oauth Decision
- `GET /api/oauth/grants` — Api Oauth List Grants
- `POST /api/oauth/grants/revoke` — Api Oauth Revoke Grant

## Docs

- [OpenAPI schema](https://tradedashboard.eu/openapi.json)
- [Interactive API docs](https://tradedashboard.eu/openapi.html)
- [FAQ](https://tradedashboard.eu/faq-en.html)

## Agent / MCP access

The same underlying data is also exposed as MCP tools for LLM agents over Streamable HTTP, at a *different* surface (tool names, a single `query` argument, a `compact` summarisation mode, and a couple of helper tools this REST API doesn't have). Its own auto-generated manifest -- kept in sync with its actual tool registry, not with this file -- is at https://mcp.tradedashboard.eu/llms.txt.

## Additional Resources

- [Dashboard](https://tradedashboard.eu/)
- [Sitemap](https://tradedashboard.eu/sitemap.xml)
