Base URL and authentication
Every endpoint below lives under https://e-vignettes.eu/api/v1 and needs no credential, no account and no header. CORS is open, so a browser can call them directly.
Issuing a vignette is a different API on a different host: https://api.vignette.id, with https://sandbox-api.vignette.id for testing, authenticated with a partner API key. Nothing below can place an order, and an Authorization header sent to these endpoints is ignored.
Errors
Every failure returns JSON, never an HTML error page, including an unmatched URL anywhere under /api. The body is always the same shape: a stable code to branch on, a human message to show, a hint naming what to change, the HTTP status, and a documentation_url. Show the message, act on the hint — for not_found the hint lists the valid values.
Branch on the code rather than on a message string, which may be reworded. There are six, they carry one status each, and they are never renamed: not_found (404) for an unknown country code or path; invalid_parameter (400) for a parameter outside its allowed values; method_not_allowed (405), since every endpoint here is read-only; rate_limited (429), with Retry-After carrying the seconds to wait; upstream_unavailable (502) when the live catalogue could not be reached, which is worth retrying and does not affect country rules; and internal_error (500).
Rate limits
Requests are counted per IP address, not per client, under two policies: public-read allows 240 requests per 60 seconds across /api/v1, and mcp allows 120 requests per 60 seconds on the MCP endpoint, which is lower because a single tool call can fan out to nine upstream requests.
Every response says where you stand, so you never have to discover the limit with a 429. RateLimit-Policy and RateLimit follow draft-ietf-httpapi-ratelimit-headers-09 — for example RateLimit-Policy: public-read;q=240;w=60 alongside RateLimit: public-read;r=239;t=43, where r is the requests left and t the seconds until the window resets. The older RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset fields are sent as well, for clients that read only those.
Going over the quota returns 429 with Retry-After in seconds and the usual JSON error body, code rate_limited. Responses are also edge-cached, so honour Cache-Control rather than polling: country data changes a few times a year, and prices change when a national operator changes a tariff.
Versioning and deprecation
The API is versioned in the URL path. /api/v1 is the current version, and a breaking change gets a new path rather than altering v1 underneath you. Additive changes — a new field, a new endpoint, a new enum member — are not breaking, so parse defensively and ignore fields you do not recognise.
Retirement is announced in the responses themselves, not only in a blog post. From the moment a version is deprecated, every response from it carries Deprecation with the date the deprecation was announced, Sunset with the date it stops answering, and a Link header with rel=deprecation pointing at the developer portal and rel=successor-version pointing at the replacement. While a version is current it carries none of these, so their absence is itself the signal that nothing is scheduled.
A deprecated version keeps answering for at least 12 months after the announcement, and a published Sunset date is never moved closer.
Beyond REST
The same catalogue is available as MCP tools at https://e-vignettes.eu/mcp, with no credential, for agents that would rather call tools than construct URLs. Any page of this site also answers Accept: text/markdown with Markdown at its own URL.
Endpoints
List every country Vignette ID sells tolls for
get /api/v1/countries
Returns the nine covered countries with their ISO code, the national toll operator, a one-paragraph summary of the toll system and links to the human page and to that country's products. Use this first to discover valid country values for listProducts.
Responses
200— The full country list. Never paginated: the list is nine items long.405— The endpoint is read-only; only GET and OPTIONS are supported.429— The per-IP quota for this policy is exhausted.Retry-Aftergives the seconds to wait; the RateLimit fields carry the same reset.
Example
curl -sS "https://e-vignettes.eu/api/v1/countries"Get the toll rules for one country
get /api/v1/countries/{code}
Returns everything the country guide states: which roads are tolled, vehicle categories and validity periods, activation and plate registration, fines and enforcement, tolls not covered by the vignette, a country FAQ, and the official sources each fact was checked against. Prices are not included here — call listProducts for those.
Parameters
code(path, required, string) — ISO 3166-1 alpha-2 country code, lower case. One of: at, ch, cz, sk, hu, si, ro, bg, md.
Responses
200— The country guide.404— No country with that code.error.hintlists the valid codes.405— The endpoint is read-only; only GET and OPTIONS are supported.429— The per-IP quota for this policy is exhausted.Retry-Aftergives the seconds to wait; the RateLimit fields carry the same reset.
Example
curl -sS "https://e-vignettes.eu/api/v1/countries/at"List vignette and section-toll products with live prices
get /api/v1/products
Returns the active catalogue. Each product is one country plus one vehicle type; its offers array holds one entry per validity period, with the total customer price, the underlying government price and the partner fee stated separately. Omit country to get every country in one call.
Parameters
country(query, optional, string) — Restrict to one country, by ISO 3166-1 alpha-2 code (lower case). Omit for all nine. One of: at, ch, cz, sk, hu, si, ro, bg, md.type(query, optional, string) —vignettefor ordinary motorway vignettes,tunnelfor the Alpine section tolls that a vignette does not cover. One of: vignette, tunnel. Defaults tovignette.
Responses
200— Matching products. An emptydataarray means the filter matched nothing.400— A query parameter was not one of the allowed values.405— The endpoint is read-only; only GET and OPTIONS are supported.429— The per-IP quota for this policy is exhausted.Retry-Aftergives the seconds to wait; the RateLimit fields carry the same reset.502— The upstream catalogue could not be reached. Retry shortly.
Example
curl -sS "https://e-vignettes.eu/api/v1/products?country=at&type=vignette"