# Can this car enter a French ZFE? Its Crit'Air class, computed offline > Crit'Air class and in-force ZFE restrictions, computed offline from declared fuel plus Euro norm or first-registration date. No account, pay per call. Published 2026-07-11 · Updated 2026-08-15 · HTML version: https://invoket.com/blog/can-this-car-enter-a-french-low-emission-zone --- Whether a car may enter a French **low-emission zone** (*ZFE*) comes down to its **Crit'Air class** — a deterministic function of vehicle category, fuel and Euro emission standard, fixed by French regulation. That means an agent does not need a registry lookup to answer it: one offline call, [`GET /vehicle/critair`](/docs/api/vehicle-critair), computes the class from declared characteristics and returns the ZFE restrictions **currently in force** for that class. Pure calculation, no store, no network, no account — one x402 settlement per answer. ## The problem: access rules an agent cannot guess A purchase-assistant agent comparing used cars, a trip planner routing through Lyon, a fleet-compliance agent auditing vans: all of them hit the same question — *is this vehicle allowed where it needs to go?* The answer is regulatory, not observational. France classifies vehicles into Crit'Air classes under the [Arrêté du 21 juin 2016](https://www.legifrance.gouv.fr/loda/id/JORFTEXT000032749723) (art. R. 318-2 of the *code de la route*), and each ZFE restricts entry by class. The rules are also **moving**. The 2025 simplification law voted to abolish the ZFE mandate; in May 2026 the Conseil constitutionnel [struck that repeal down on procedural grounds](https://theconversation.com/zfe-de-la-suppression-au-sursis-une-saga-juridique-qui-na-pas-encore-dit-son-dernier-mot-284844), leaving the zones in force. An agent that hardcodes last year's understanding of ZFE schedules gets this wrong; an endpoint that models **only restrictions actually in force**, from a dated snapshot, does not. ## A calculation, not a lookup [`GET /vehicle/critair`](/docs/api/vehicle-critair) takes **declared** inputs — values the agent typically already holds from a registration document, a listing, or a [VIN decode](/docs/api/vehicle-vin-decode): - `fuel` — always required (`electric`, `hydrogen`, `petrol`, `diesel`, `petrol_hybrid`, `diesel_hybrid`; a hybrid is classified by its combustion engine). - At least one of `euro_norm` (`pre_euro`, `euro2`..`euro6`) or `first_registration` (`YYYY-MM-DD`, used to derive the norm). When both are given, the explicit `euro_norm` wins. ```http GET /vehicle/critair?fuel=diesel&first_registration=2009-05-01 ``` The response gives the computed `critair_class` (`"0"`, `"1"`..`"5"` or `"non_classe"`), the list of modelled zones that **restrict** that class — each with a stable `zone_id`, its perimeter description and the date the restriction took effect — and a `derivation` block reporting which input path produced the effective Euro norm. The calculation is **auditable**: the agent can always see whether the class came from the declared norm or was derived from the registration date, and `regulation.reference` names the grid it was computed against. Because the core is a pure function over embedded reference tables, there is no store to miss and no staleness error to hit: the answer always computes, in milliseconds. ## Reading the result honestly The endpoint sells a regulatory verdict, and it is precise about what that verdict covers: - **`non_classe` is a successful answer.** A vehicle too old to qualify for any sticker is exactly the fact a purchase or compliance agent is paying to learn — a **200**, billed, per the x402 golden rule. - **An empty `zfe_restrictions` list is a successful answer too.** A clean sticker that no modelled zone restricts is the verdict, not a miss. - **Input is declared, not verified.** The class is exact *for the characteristics given*; the service does not check that the vehicle really has them. Garbage in, wrong class out — which is why feeding it from a [VIN decode](/docs/api/vehicle-vin-decode) or a registration document beats trusting a listing's prose. - **Only permanent, in-force restrictions are modelled.** Local, time-based and sector exemptions (protected axes, low-mileage permits, day passes) are explicitly out of scope, and the response says so in `notes`. Tightening schedules revised by the 2025 law are only included once actually in force. - **Scope is M1/N1 only** (passenger cars and light vans) in v1, and there is **no lookup by licence plate**. The ZFE perimeters come from a dated snapshot; `provenance.freshness.as_of` carries the oldest of the two embedded references, never a fresher-looking date. ## Where it sits in the x402 loop The call follows the same loop as every Invoket endpoint — no signup precedes it: 1. **Discover** the endpoint via the live catalog and call it; receive the `402` challenge. 2. **Pay** — sign the chosen rail and replay the request. 3. **Read** — `critair_class`, the `derivation` audit trail, and the zones restricting that class. 4. **Branch** — clear the vehicle for its route, flag it in a purchase comparison, or mark the fleet unit for replacement. The [Quickstart](/docs/quickstart) walks the full discover → `402` → pay → replay cycle with runnable snippets. Price and accepted rails are not pinned here — they are served live by the [catalog](https://api.invoket.com/catalog); see the [endpoint reference](/docs/api/vehicle-critair) for the current figure. ## Chain it: decode, then classify The Crit'Air call slots naturally after a VIN decode: model year from [`GET /vehicle/vin/decode`](/docs/api/vehicle-vin-decode) helps pin the first-registration era, and the decoded facts keep the declared inputs honest. For recall exposure on the same vehicle, add [`GET /vehicle/recalls`](/docs/api/vehicle-recalls); for all three answers in a single settlement, use the composite [`GET /vehicle/report`](/docs/api/vehicle-report). Used for what it is — an offline, auditable regulatory calculation with an honestly-bounded ZFE model — `/vehicle/critair` lets an agent answer "can this car go there?" before anyone buys, routes or dispatches it. For the full field reference and error codes, see the [`GET /vehicle/critair` documentation](/docs/api/vehicle-critair); for how agents discover and call Invoket endpoints, see [For agents](/docs/for-agents).