Skip to content

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.

what your driver sees

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.

--:--
high5.8 km

Accident

A14

via Cudatus Relay15 in range
  • 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.

what you get on day one

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

national feed, read while this page rendered

13
kinds of hazard

filter on the type, refine on the subtype

1 s
delivery commitment

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.

what you build

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.

GET /v1/stream
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.

the other direction

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.

The community layer, with the code

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.

The structural argument

what it costs

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.

10,000 reads a month, free, no cardPaid plans from 24.90 a monthSee the plans