Changelog
Every change, dated by the day it reached production
The wire contract is additive forever, so nothing here breaks a client that was written before it. What a dated list gives you is the other half: whether the value you are seeing in production is one your mapping table predates.
Only one of these four scopes can reach your code
Entries marked wire contract change what a client parses — additively, always — and each one states the action it implies. The other three are the service, the account surface and the reference; none of them requires anything of an integration.
- wire contract
- platform
- console
- documentation
Five new event types: police checks, speed cameras, closures, faults, roadworks
wire contract`type` goes from eight values to thirteen — `police_check`, `speed_camera`, `road_closure`, `infrastructure_fault` and `roadworks` — each with its own fine vocabulary and its own default lifetime. They divide the way a driver reports rather than the way a standard models: officers at the roadside are a police check, an unattended camera car is a speed camera, and works here means the crew you just ran into, never the ones published weeks ahead.
What to do: Nothing breaks: a type you do not recognise means the event is opaque, so skip it. But a client that enumerated the eight will silently drop the five, so refresh your mapping from GET /v1/meta/event-types and decide what each one draws.
Two visibility subtypes, and infrastructure damage from the French feed
wire contract`smoke` and `low_visibility` join `weather_hazard`: both connectors were resolving smoke, smog and reduced visibility to the coarse type alone for want of an id. The French connector also began mapping infrastructure damage — damaged surfaces and struck barriers — which it had been dropping while the Spanish connector published the same element.
What to do: Subtypes gain values without announcement; filter on type and refine on subtype, never the other way round.
A canary publishes into the sandbox every five minutes
platformA scheduled job publishes one event into each of three watched areas, reads each back through the area query at a subscriber's own radius, and confirms one of them from two more vehicles so the reporter quorum promotes it. It exercises the deployed revision — authentication, metering, the geohash write, the cell query and both analytical mirrors — rather than the code in a repository.
Leaving an organisation, and resending an invitation
consoleTwo routes that were missing. Leaving is its own audit action rather than a removal recorded against you — “X removed Y” and “Y left” are the same row shape and opposite facts. Resending an invitation rotates the token, so a filtered first message can never leave two live doors open for one seat.
Renaming an organisation, account language, recovery-code count
consoleThree capabilities that existed in the API and had no hand on them: a typo at sign-up no longer names an organisation forever, the language of your sign-in mail is yours to set, and the number of unused recovery codes is visible on your account page — on a passwordless account that number is the only escape from a lost authenticator.
The public demo no longer accepts free text
platformThe publish form on the home page is anonymous, so the two free-text fields on the contract are refused at that boundary rather than merely omitted from the form. Both fields remain on the contract and the national feed connector still populates them: what changed is who may write them, which is a credentialed publisher.
Reference clients to copy, in place of SDKs
documentationThe streaming guide carries complete JavaScript and Python clients — the ordering guard, the silent-expiry rule, reconnection with a fresh ticket — written to be pasted rather than versioned. A package is a product maintained for life, and the first ten minutes an SDK was going to buy is a documentation problem: the delta is an envelope, and mistaking it for the event is the single most expensive mistake in this API.
What to do: Nothing. The REST and SSE surfaces are unchanged.
The public reference is live
documentationThirteen pages: getting started, authentication, publishing, consuming, streaming, the sandbox, the trust model, and the reference for event types, the event object, compatibility, errors and privacy.
Signals are recorded with their organisation
platformEvery confirmation and denial is mirrored with both organisations, the reporter, the action and the action it replaced. A confirmation is therefore attributable to the organisation that made it, and not only to the event it landed on.
An hourly ceiling on signalling
platformSignals are bounded per organisation, per environment, per hour, enforced on the signal route and returned as a 429. Publishing has no such ceiling and will not get one — friction on the publish path starves the network.
What to do: Back off on 429 and retry; the budget is per organisation, so sharding across keys does not help.
Schema version 2 — the quorum counts vehicles
wire contractPromotion and clearing count distinct reporters rather than distinct organisations, so a four-hundred-vehicle fleet is four hundred voices and not one. Consequence on the wire: confirm_count and deny_count are much larger for the same reality, and the organisation-granular tallies were removed rather than left publishing a frozen number.
What to do: Threshold on verification or confidence, never on the raw counts. Do not read org_count, confirm_org_count or deny_org_count — they are gone.
No publisher identity on the wire at all
wire contractThe organisation left the contract first, replaced by a stable pseudonym; the pseudonym then left too. A forever-stable pseudonym is a fleet-coverage map missing only its label — one known incident attaches it, and grouping over a few kilometres gives relative fleet density per publisher. We attribute internally, for trust and for billing, and nobody on the network can.
What to do: A client that needs “is this event mine” uses its own client_event_id.
A second level of vocabulary: subtype
wire contractEvery event carries an optional finer subtype beside its coarse type — filter on the type, refine on the subtype. The coarse list grows rarely and on purpose, because adding one is an event every existing integrator silently drops; the fine list is designed to grow without notice. Both are served by GET /v1/meta/taxonomy with every time to live.
What to do: Treat subtype as presentation, never as a filter. It may be null on any event, and a value you do not recognise is a label you do not have.
Two event types added: road damage, people on road
wire contractRoad damage is the one type in the table that is not really ephemeral — it lasts until somebody repairs it, so it carries a far longer time to live and is the type a suspension sensor reports with no driver involved. People on road recovered a value the national feed publishes and we had nowhere honest to put: rendering “object on road” over a human being is indefensible.
What to do: Both are new coarse values. A client that skips values it does not recognise handles them correctly and receives them the day it adds a label.
Live and sandbox environments
platformEvery credential carries its environment from the first key issued, and an event inherits the environment of the credential that published it. A live consumer is served live events only; a sandbox consumer is served both, so testing never starts against an empty network. The write half is what makes the read half safe: a sandbox key cannot signal a live event.
What to do: Read environment on the event if you render sandbox and live side by side.
Self-service organisations and keys
consoleSign in with a one-time code by email — no password, deliberately, because in any system with a reset link the inbox already grants account control. Create an organisation, invite colleagues, issue and revoke keys yourself behind a second-factor step-up, and read per-day usage and an append-only audit log.
Consumption metered at the authentication boundary
platformEvery read, publish, signal and stream connect is counted per organisation, per environment, per day, next to the identity that made it. Reads were previously recorded nowhere and were not backfillable.
The French national road network feed
platformIncidents published by the national road operator in DATEX II under Licence Ouverte 2.0 are polled continuously and mapped into the Relay vocabulary, carrying their licence and the moment the source last revised them. The first request an integrator makes returns real events on real roads.
The rules that make an additive contract safe to consume — ignore fields you do not recognise, skip values you do not recognise, never map an unknown value onto one you know — are in the compatibility reference, with the failure each one prevents.