For navigation and mobility apps
The hazard layer, without the network behind it
Your app already routes a driver. What it cannot build alone is the layer that says what is on the road ahead, because that needs a crowd. Relay is that crowd, shared: what your users report goes out to every other participant, and what theirs report comes back to you — on top of the French national operator’s feed, which is already on the wire.
A banner, and pins on your own map
This phone is subscribed to the deployed network right now, at a point in Paris. Everything inside the bracket is what Relay supplies; everything outside it is yours and stays yours.
Accident
A14
The banner
The next hazard on the driver’s road, not the most dramatic one in the area — its kind, its severity and how far ahead it is. One field each, already in the envelope.
The pins
Every active event inside the subscribed disc, as they arrive. No polling loop and no reconciliation: the stream sends a snapshot, then deltas.
Everything else
The map, the route, the ETA, the voice, the design. Relay supplies data and nothing else — there is no SDK to adopt and no component to render.
The first request already returns something
You do not start against an empty network. Relay ingests the French national road feed, published in DATEX II under Licence Ouverte 2.0, and serves it on the same contract as everything else.
- 8
- operator incidents live now
- 13
- kinds of hazard
- 1 s
- delivery commitment
national feed, read while this page rendered
filter on the type, refine on the subtype
p95, publication to reception
A subscription is a disc around a point. An itinerary is covered by subscribing discs along it — the same call, repeated — and a national picture is an assembly of them. What is on the wire right now.
One stream, three listeners
Plain HTTP and server-sent events. Your server mints a 300-second ticket with your key, the browser opens the stream with that ticket, and three listeners are the whole client.
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. The disc follows the driver.
const stream = new EventSource(
`${API}/v1/stream?lat=48.8698&lon=2.3078&radius=8000&ticket=${ticket}`,
);
// everything already live in the disc, once, on connect
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 once its expires_at passes, and mint a fresh ticket after a bye. Markers disappearing on their own is a property of the contract, so you write no stale-hazard sweep. The streaming contract states each of them.
Your users are the reason the next app joins
Publishing is free on every plan and always will be. A driver taps an icon, the next driver answers “still there” or “gone”, and both are one HTTP call. Promotion needs distinct vehicles and events expire on their own, so you write neither a moderation queue nor a cleanup job.
What your users see that no feed carries
A road authority publishes what it has dispatched a crew to. A pothole before that dispatch, a police check, an unattended camera, debris in the third lane — none of them is in anybody else’s system, and all of them are already in the vocabulary.
Why a neutral network and not a bigger one
We build no navigation application, which is a founding constraint rather than a stage. There is no product of ours for you to feed and then compete with, which is the only reason the other apps on this wire are willing to be on it with you.
Free to start, and the prices are published
You pay for reading the network, metered in reads. Publishing is free on every plan. No card to begin and nobody to talk to.