Skip to content

Cudatus Relay

Relay is one HTTP API where any mobility actor publishes road events and any mobility actor consumes them. A fleet reports an accident; a carmaker's head unit hears about it under a second later. Same contract in both directions, same JSON, no per-partner integration.

It is infrastructure, not an application. There is no map, no routing, no navigation. You send events, you read events, you subscribe to a live stream of events.

The whole API

This is the complete surface. There is nothing else.

MethodPathWhat it doesKey?
POST/v1/eventsPublish a road eventyes
GET/v1/eventsActive events around a pointyes
GET/v1/events/{event_id}One event by idyes
POST/v1/events/{event_id}/signalsConfirm or deny an eventyes
GET/v1/streamLive SSE feed for an areayes
POST/v1/stream/ticketsMint a browser stream credentialyes
GET/v1/meta/event-typesThe live event-type vocabularyno
GET/v1/meta/taxonomyThe two-level vocabulary, with each type's lifetimeno
GET/v1/meta/limitsHard query limitsno
GET/healthLivenessno
GET/, /docs, /openapi.jsonBanner, Swagger UI, generated schemano

Reads are authenticated, not just writes. Consuming is the metered side of the business model, and authentication cannot be added to a public endpoint after partners have pinned integrations to it — so it is there from day one.

Base URL

The production host is https://api.cudatus.com. Issue a key from the Console and point at it:

export RELAY=https://api.cudatus.com
export RELAY_KEY=<your key>

Every example on these pages uses those two shell variables, so nothing here is tied to one host. https://api.cudatus.com is where a partner starts; a contributor stack exists for working on Relay itself — see Getting started.

Four things that define the product

Events are ephemeral, and that is the point. Every event carries an expires_at. Relay serves what is live now; it is not a history database. A wrong_way_vehicle lives 20 minutes by default, an accident two hours. Confirmations from other vehicles extend an event's life — with one deliberate exception, and it is the type just named: see Trust.

Publishing is cheap, consuming is the product. There is no friction on the publish path — one POST, no negotiation, no schema registration. Consuming is where the value and the bill are.

Trust is a quorum, in both directions. Your event lands unverified and stays there until enough other vehicles confirm it. The publishing vehicle is excluded from its own evidence; your own fleet corroborating counts — the quorum counts reporters, not organisations. Clearing an event is never cheaper than promoting one. See Trust — this is the single thing publishers most often mistake for a bug.

The wire contract is forever. Fields are added, never renamed, re-typed or removed. A carmaker that integrates once ships that integration into vehicles that stay on the road for fifteen years. See Compatibility for the two obligations that places on your client.

Contract boundaries

These are properties of the contract, not omissions from it:

  • No fleet simulator, by design — and your sandbox is not empty. A sandbox key reads the live network too, so you develop against real national traffic from the first request; the traffic you control is a twenty-line publish loop you own, not a product component. See The sandbox.
  • No SDKs, by design. The API is REST + SSE against any HTTP library, and the docs carry complete copy-pasteable clients — nothing between your code and the wire to version or fall behind. See Streaming.
  • Subscriptions are discs. An area query or subscription is a disc capped at 9 780 m; a route is covered by tiling discs along it — see Consuming.
  • Each report is its own event. Two organisations reporting the same accident produce two events. merged and merged_into are reserved in the contract for cross-report merging and are null on every event.
  • Events are immutable observations. A publisher does not delete or update its own event. It expires.
  • One rate limit, metered consumption. Every read, publish, signal and stream connect is counted per organisation, per environment, per day; plan allowances are settled commercially rather than enforced by refusal. The one 429 in the API is the hourly per-organisation ceiling on signals, a guard on the trust model rather than a quota. Do not build on the absence of a limit — see Errors and limits.
  • No Last-Event-ID or replay log on the stream, deliberately. Reconnecting gets a fresh snapshot instead.
  • No roadworks. Planned works are known weeks ahead and are out of this contract.

Where to go next

You want toRead
Get a key and see a real eventGetting started
Understand the two credential typesAuthentication
Send your first event correctlyPublishing
Poll an areaConsuming
Subscribe to the live feedStreaming
Test without a fleetThe sandbox
Know why your event says unverifiedTrust
Look up a fieldThe event object
Every change to the wire contract, the vocabulary and the platform, datedChangelog