━━ DEVELOPERS · DATA LAYER
Build with codriver. Open by default.
The community alerts, chargers, and cameras you see on the map ship behind an unauthenticated read endpoint. Provincial 511 integrations, partner traffic feeds, and hobby projects all land through the same two-endpoint surface: read what's there, push what you have. Open kinds catalog, documented contract, no proprietary lock-in.
━━ READ · NO ACCOUNT NEEDED
GET /v2/entities/nearby
Query a point and a radius, get back every entity (community alerts, chargers, cameras, feed entities) in JSON. No API key, no session — 60 requests/minute as a guest, 120 with an account.
curl 'https://app.codriver.io/v2/entities/nearby?lat=45.4699&lng=-73.5461&radius=3000'
# {
# "entities": [
# { "id": "...", "kind_id": "alert.police",
# "geom": { "type": "Point", "coordinates": [-73.54, 45.46] }, ... },
# { "id": "...", "kind_id": "charger.supercharger", ... }
# ],
# "sources": [ { "id": "chargers", "status": "online", ... } ]
# }Add sources[]= to narrow it to one source; the catalogue is at /v2/sources. CORS is not enabled, so call it server-side rather than from a browser. Full parameter reference on developer.codriver.io.
━━ WRITE · YOUR FEEDS, YOUR LAYER
POST /v2/feeds
Register a feed once, then either push entities (you POST when you have updates) or have us pull a URL you control on a cadence you set. Same payload shape either way. Feeds map to a layer you own; private by default.
Push feed
# 1. Register (sign in at codriver.io first so the session cookie is sent):
curl -X POST 'https://app.codriver.io/v2/feeds' \
-H 'Content-Type: application/json' \
--cookie /tmp/cookies.txt \
-d '{ "name": "My Traffic Feed", "direction": "push", "visibility": "private" }'
# → { "feed": { ... }, "push_ingest_token": "cdrf_..." } # store this NOW
# # (visible exactly once)
# 2. Push entities whenever you have updates:
TOKEN="cdrf_..."
curl -X POST "https://app.codriver.io/v2/feeds/$TOKEN/entities" \
-H 'Content-Type: application/json' \
-d '[
{ "external_id": "incident-2026-05-22-001",
"kind": "alert.road_closed",
"lat": 45.5017, "lng": -73.5673,
"properties": { "street": "René-Lévesque", "reason": "downed line" },
"ttl_seconds": 3600 }
]'
# → { "accepted": 1, "rejected": 0, "errors": [] }Pull feed
curl -X POST 'https://app.codriver.io/v2/feeds' \
-H 'Content-Type: application/json' \
--cookie /tmp/cookies.txt \
-d '{
"name": "MyCity 311 Feed",
"direction": "pull",
"pull_url": "https://api.mycity.example/311.json",
"pull_auth_header": "X-API-Key: your-key-here",
"pull_interval_seconds": 300
}'Pull interval is clamped to [30s, 3600s]. We auto-disable after 20 consecutive failures; re-enable with a PATCH to the feed. Backoff doubles on each failure, capped at 1 hour. The URL must be https on a public hostname.
━━ KINDS · PLATFORM-OWNED CATALOG
18 kinds today. New ones added on real demand.
Your payload's kind must be one of:
- Alerts:
alert.police,alert.accident,alert.road_closed,alert.construction,alert.hazardwith subtypes (.car_stopped,.object_on_road,.pothole,.animal,.fog,.ice,.flooding) - Cameras (persistent):
camera.speed,camera.red_light,camera.avg_speed - Chargers (persistent):
charger.supercharger,charger.destination - Traffic:
traffic.jam
Anything outside the catalog is rejected at ingest. New kinds are added when there's a real use case — email [email protected] with a request.
━━ STABILITY · v1 CONTRACT
Promises we keep.
- No breaking changes to
external_id,kind,lat,lng,properties,ttl_seconds, orobserved_atwithout a 90-day deprecation window announced via email to feed owners. - Additive fields and new kinds are non-breaking and may ship at any time.
- Existing kind ids never get renamed.
- EU data residency. All entities, feeds, and user data live on Hetzner Helsinki — GDPR coverage, out of reach of US data acts. We refuse non-justice-system requests for user data on principle.
━━ FULL SPEC + CONTACT
Going deeper.
The canonical reference wiki is at developer.codriver.io — deeper coverage of each kind, error code, integration pattern, and stability commitment beyond what this page summarises. The engineering source-of-truth markdown alongside the code lives in the driving-app repo at codriver.io/docs/EXTERNAL-FEEDS.md.
For feed-spec questions, layer-approval requests, or bugs, email [email protected].
━━ FAQ