The real-time road event network
The hazards your users report, and everyone else’s, on one stream.
Relay is the road event network your app publishes to and reads from. The French national operator’s feed is already on it. Publishing is free, always. Reading starts free.
- 50
- events on the wire
- 13
- kinds of hazard
- 1 s
- delivery commitment
8 live · 42 sandbox
one vocabulary, served by the API
p95, publication to reception
Every point on the plate is an event live on the network, read from the API while this page rendered.
Every event has a lifetime
Publish one and watch it distributed. Each clip runs from the moment the event was created to the moment it expires, so its length is the life it has left.
GET /v1/stream?lat=48.8698&lon=2.3078&radius=8000Publish an event and the round trip is timed in this browser — one clock, from the click to the moment it returns down the open stream.
1 000 ms · the published commitment
This publishes with the site’s own sandbox key — a real event on the test network every integrator gets, never served to a live consumer. The incidents already on the tape are live, from the French national road feed. Open the Explorer for the map and every field on the envelope.
One call to publish, one stream to consume
Both halves are plain HTTP, so anything that speaks it can subscribe — including an embedded client that will never take a cloud vendor’s SDK.
Publish
Free, always. We never ask for a trajectory — only the point event you already derived.
curl -X POST https://api.cudatus.com/v1/events \
-H "Authorization: Bearer $RELAY_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "congestion",
"lat": 45.7300,
"lon": 4.8400,
"severity": "medium",
"road_ref": "A7",
"description": "Queue building southbound"
}'Subscribe
Reading is authenticated too, and EventSource cannot set a header — so your server mints a 300-second ticket and hands the browser only that.
const API = "https://api.cudatus.com";
// on your server — the key stays here
const { ticket } = await fetch(`${API}/v1/stream/tickets`, {
method: "POST",
headers: { Authorization: `Bearer ${process.env.RELAY_KEY}` },
}).then((r) => r.json());
// in the browser — a ticket, never the key
const stream = new EventSource(
`${API}/v1/stream?lat=48.8698&lon=2.3078&radius=8000&ticket=${ticket}`,
);
stream.addEventListener("snapshot", (e) => replaceAll(JSON.parse(e.data).events));
stream.addEventListener("event", (e) => {
// the delta is an envelope: created | updated | expired
const { change, event } = JSON.parse(e.data);
change === "expired" ? drop(event.event_id) : upsert(event);
});
// we always close on schedule; the ticket died long before
stream.addEventListener("bye", () => reconnectWithAFreshTicket());A correct client owes the wire three things — treat every delta as an upsert, drop an event yourself when its deadline passes, and mint a fresh ticket after a bye. The streaming contract states each of them.
Free to start, and the prices are published
Publishing never costs anything, on any plan. What you pay for is reading the network, metered in reads.
A community layer, in two calls
An operator publishes what it has dispatched a crew to. A pothole before that dispatch is in nobody’s system — and these 10 values are what no public feed we ingest can produce.
- Police check
police_check - Speed camera · Mobile camera
mobile_camera - Infrastructure fault
infrastructure_fault - Roadworks · Emergency works
emergency_works - Road damage · Pothole
pothole - Road damage · Sinkhole
sinkhole - Object on road · Debris
debris - People on road · Road worker
road_worker - People on road · Traffic officer
traffic_officer - People on road · Cyclist
cyclist
And on everything the feed does carry, your users are earlier: an operator publishes when the operator knows, and somebody in the third car back knows first.
Report, then confirm
A driver taps an icon — one POST /v1/events. The next driver answers “still there” or “gone” — one POST /v1/events/{id}/signals. Markers expire on their own and promotion needs distinct vehicles, so you write neither a moderation queue nor a stale-hazard sweep.
Relay is the layer inside somebody else's product
Three products of the kind that embed Relay, drawn as specimens on one sheet and subscribed to the same stream as the instrument above. Publish an event up there and it arrives in all three on the same tick.
Road events on your operating area
via Cudatus Relay| Road | Event | From base | Clears in |
|---|---|---|---|
| A86 | Congestion | 6.8 km | — |
| A14 | Accident | 5.8 km | — |
| A14 | Accident | 5.8 km | — |
| A14 | Accident | 5.8 km | — |
Accident
A14
Accident
5.8 km · A14
- Accident5.8 km
- Accident5.8 km
A fleet operations console
The platform owns the vehicles, the routes and the customers. Relay supplies one panel: what is on the roads they run, queues first, because a queue is what turns into a missed delivery slot.
A driver-facing app
The app owns the map and the route. Relay supplies what is on it — what is next, how far, how bad.
An in-vehicle display
Homologation, functional safety and cybersecurity review run in years — which is exactly the timescale a frozen wire contract is designed to survive. An integration programme rather than an API key.
Cudatus builds none of these. All three are drawn in deliberately anonymous grey, so the only coloured thing inside any of them is the data Relay puts there — which is exactly the shape of what we sell. All three — and the instrument above — are rendering the same 15 events right now. © MapTiler · © OpenStreetMap contributors
Where you plug in
Find your row, and read how you connect.
Telematics platform editors
One POST, one streamYou run the platform a few hundred fleets log into, you have an API and you have developers.
Your boxes already detect what Relay wants — harsh braking, prolonged immobilisation outside a delivery stop, impact detection. The raw material is on your servers; what it costs you is one HTTP call. We never ask for trajectories, only the point events you already derive.
Navigation and mobility apps
Subscribe and apply deltasYou put a route in front of a driver, and a hazard on it is worth more the earlier it lands.
Subscribe to a disc around a position and apply the deltas — one stream, one contract, no per-source integration. An itinerary is covered by subscribing discs along it, each one the same call.
Road operators and public authorities
DATEX II in, JSON outYou already publish DATEX II, and you already asked whether we speak it.
DATEX II in, JSON out. We consume the European standard and serve a real-time developer API over it — we are not replacing it and not competing with it. Your feed is brought up as a connector; the French national feed runs on one already.
Fleet managers
Through your platformA truck stuck behind an accident is a missed delivery slot, and a detour is not trivial at 40 tonnes.
Through the telematics platform you already use, not through us. A fifty-truck haulier has no development team and should not need one: when your platform integrates Relay, your fleet gets the network with nothing to build on your side.
Carmakers
Integration programmeYou have millions of connected vehicles giving data to a supplier who competes with you on navigation.
The reciprocity is the argument: what your fleet publishes comes back as every other participant's events, instead of funding a service you then buy back. Homologation, functional safety and cybersecurity review set this cycle in years — an integration programme rather than an API key, and the wire contract is frozen precisely to survive that timescale.
What arrives, and how fast
Both numbers here are served by the API rather than written on this page, so a client that reads them at runtime never disagrees with the network.
13 event types, served by the API
Each carries an optional finer subtype — filter on the type, refine on the subtype. A type you do not recognise means the event is opaque to you, so skip it, and never map it onto one you do know.
- Congestion
congestion - Stopped vehicle
stopped_vehicle - Accident
accident - Object on road
object_on_road - Weather hazard
weather_hazard - Road damage
road_damage - People on road
people_on_road - Police check
police_check - Road closure
road_closure - Roadworks
roadworks - Infrastructure fault
infrastructure_fault - Speed camera
speed_camera - Wrong-way vehicle
wrong_way_vehicle
Five of them arrive from a windscreen and from nowhere else today — police checks, speed cameras, closures, infrastructure faults and roadworks a driver ran into. That is what the community layer is for. The reference carries every time to live and the full fine vocabulary.
A p95 under one second, published rather than promised
The rail inside the instrument above is measuring the deployed stack in your own browser, round trip included. On the reference stack the same measurement is p95 73 ms against the 1 000 ms commitment.
A subscription is a disc, capped at 9.78 km. An itinerary is covered by subscribing discs along it, and a national picture is an assembly of them — the plate at the top is 16 such queries, run concurrently.