A living city.
An API to build with.
Bring a live view of San Francisco into your application. Read street-activity aggregates, forecasts and AI review activity with no key, or build on camera observations and insights through the authenticated API.
Open data needs no key or sign-in. It is aggregates only: no imagery, tracks or camera positions. Inference runs on our servers.
Ready for web, iPhone, Apple Watch, Vision Pro, and Mac.
Connectingloading the pulse
GET /api/public/pulse
- Cameras counting
- —
- People in view, per camera
- —
- Vehicles in view, per camera
- —
- Cameras reviewed by AI in 5 min
- —
Loading the current pulse…
Response excerpt
City aggregates anyone can read
These routes need no key and no sign-in. Each returns plain JSON without the API envelope, is cached at the edge, and can be read from any website (Access-Control-Allow-Origin: *). They carry aggregates only: no camera locations, imagery, tracks or model descriptions. Every figure has its unit and an as-of time; a section without data is null or a 503 with a state, never a zero.
| Route | What it holds | Refresh | Edge cache | Try it |
|---|---|---|---|---|
/api/public/pulsecity-pulse-v1 | Per-camera average people and vehicles for the city and for neighborhoods with at least three counting cameras; the city forecast series; AI review activity; possible-incident screening per Pacific day. | Every 10 s | 10 s fresh · 24 h if the origin fails | |
/api/public/forecast-accuracyforecast-accuracy-v1 | Forecasts saved 24 h ahead against later measurements, over complete hours on matched cameras, against same-hour-yesterday and seasonal baselines. Figures appear only from 72 matched hours. | Every 30 min | 5 min fresh · 24 h | |
/api/public/city-forecastcity-forecast-v1 | Hourly per-camera means: measured history, saved day-ahead forecasts and the forecast up to 30 days out with approximate, uncalibrated ±1σ bands. Optional start, end and neighborhood. | Every minute | 60 s fresh · 24 h | |
/api/public/counts/cameraspublic-counts-v2 | Counting cameras by ID and neighborhood, with their observation history span. No addresses, coordinates or counting geometry. | Every 5 min | 60 s fresh · 24 h | |
/api/public/counts/CAM-01public-counts-v2 | One camera's visible counts, forecasts and forecast checks. Optional start, end and stepMinutes. | On request, shared 20 s | 30 s fresh · 1 h | |
/api/public/city-insightscity-insights-v1 | Model-written findings that compare counts with their forecasts or across neighborhoods. Model-written; may be wrong. | Hourly | 2 min fresh · 2 h | |
/api/public/observationsneighborhood-observations-v1 | Sampled machine estimates of apparent age, visible skin lightness, apparent presentation and vehicle value. Not census data; no identity or race is inferred. Small samples are withheld. | About every 30 min | 5 min fresh · 24 h | |
/api/public/alertsincident-alerts-v1 | Current possible incidents confirmed by two automated reviews, not by a person. | Live | 5 s fresh · never after a failure | |
/api/public/machinePublicMachine | What the GPU machine is doing now: each GPU’s role, utilization and memory in use, live detection frames per second and cameras, scene reviews in the last complete hour and the motion-model trainer’s state. A figure that cannot be read is null. | On request, at most every 30 s | 15 s fresh · 2 min | |
/api/public/modelsPublicModels | What our two world models are doing: Cosmos 3 Nano’s routine screens and possible incidents, its fine-tuning runs with held-out loss against machine labels, and V-JEPA 2.1’s training state and motion-puzzle accuracy per round beside each puzzle’s chance level. Totals only; a figure that cannot be read is null. | On request, at most every 30 s | 30 s fresh · 10 min | |
/api/public/computePublicCompute | Four GPUs’ utilization, memory, temperature and power, plus recorded training, validation and test losses for local models. Each series keeps its run boundary; cumulative mean snapshots are labeled. Missing measurements stay null or empty. Machine-label loss is not incident accuracy. | Every 5 s | 5 s fresh · 2 min |
Choose a route above. Requests go from your browser without credentials.
The response will appear here.
Rules the data follows
- Counts are average people or vehicles in view per camera, never totals: overlapping views can see the same person.
- Neighborhood figures need at least three counting cameras; other cameras count only toward the city. Possible incidents are counted citywide and per day.
- Use each payload's own times (
counts.asOf,takenAt,window.end) for freshness, not the time you fetched it. - Forecast bands are approximate and uncalibrated. Counts come from an object detector and are estimates, not ground truth.
curl --fail-with-body https://orchestra.money/api/public/pulse
const pulse = await fetch('https://orchestra.money/api/public/pulse', {credentials: 'omit'}).then(r => r.json());
console.log(pulse.counts?.city.people.perCamera ?? 'unavailable');
Schemas, parameters and cache policies for every route are in the OpenAPI contract under the Public data tag, and in the explorer below.
Your first live insight
- Contact the operator. Ask for a machine key for your integration.
- Store your key securely. Keep it in a server environment variable or device keychain. Use Google sign-in for this website.
- Call the API. Every JSON data response includes
dataand request metadata.
export ORCHESTRA_API_KEY='your_approved_key'
curl --fail-with-body https://orchestra.money/api/v1/insights \
-H "Authorization: Bearer $ORCHESTRA_API_KEY"{
"data": {
"now": 1789257600000,
"insights": [{
"id": "scene-example", "cameraId": "CAM-01",
"title": "Traffic moving through the intersection",
"detail": "A sampled view shows vehicles and pedestrians.",
"type": "scene", "priority": 0,
"observedAt": 1789257580000, "expiresAt": 1789257700000
}],
"inference": { "location": "server", "state": "ready" },
"refreshAfterMs": 10000
},
"meta": { "apiVersion": "1.1.0", "requestId": "…", "generatedAt": 1789257600000 }
}Your workspace, with Google sign-in
Verified orchestraos.com accounts and the owner can sign in automatically. Other Google accounts can request access by signing in; the owner must approve them first. Contact the operator for a machine API key.
Machine keys are managed on the server. Browser access uses your sign-in session.
Build with what’s happening.
These need approved access: a machine key from the operator or an approved Google sign-in. Detections, camera geometry, imagery and tracks are never part of the open data.
Live insights
Approved accessFind the most interesting current observation, with its capture time and source.
GET /insights →A world in motion
Approved accessPut detections, camera geometry, and estimated tracks on your own map.
GET /world/native →Context you can review
Approved accessGo from a possible incident to its source footage, frames, and camera view.
GET /incidents →Reference & explorer
Choose an endpoint to see its contract and make a real request. Public data, status and contract requests work without signing in. Sign in for camera data and other private resources. Your browser uses your session; machine integrations use a bearer key.
Your response will appear here.
Response schema
The downloadable OpenAPI contract includes every resource, parameter, body schema, and authentication requirement. Media endpoints return raw bytes; SSE returns events.
Data you can trust to expire
| Resource | Meaning | Freshness |
|---|---|---|
| Insights | Ranked findings, scene descriptions, or observed activity. The first entry is the featured insight. | Use expiresAt. Scene captures live for at most two minutes; activity uses the detector deadline. |
| Native world / map vehicles | Server-computed positions. Predicted tracks are estimates between real observations. | Remove expired tracks. Reject snapshots older than staleAfterMs. |
| Observations / objects | Detector output tied to a camera, session, generation, and capture time. | Check fresh and source timestamps. Do not carry tracks across session resets. |
| Jobs | Recent analysis requests and results. Poll the job ID after a 202 response. | Bounded server memory. The recent list contains up to eight jobs; this is not a history API. |
| Incidents | Automated possible incidents with source footage for review. | Clips are retained for up to 14 days; storage limits can remove them sooner. The live camera is not the historical clip. |
All timestamps are Unix milliseconds. Compare source times to the response’s server clock, then advance with a monotonic local timer. Camera exposure clocks are unverified. An insight may be an AI estimate; it is not a verified event.
When no fresh finding exists, the feed returns observed activity or an explicit waiting status. Keep that status visible instead of showing an old finding as live. Video, frames, and playback links require authentication. Website actions use your sign-in session.
Predictable limits. Useful errors.
On HTTP 429, honor Retry-After. Missing or invalid keys return HTTP 401. Cookie-authenticated writes require a CSRF token and an allowed Origin.
Processing writes require an Idempotency-Key. Exact-body replays return the saved result for up to 24 hours, within the current process lifetime. A changed body returns 409. Server restarts clear this memory; inspect recent jobs before retrying uncertain writes.
Errors include error.code, error.message, and error.requestId. Include the request ID when reporting a problem. Pagination supports limit (1–100) and cursor. Never include a credential in a URL.
Live updates without busy loops
Use GET /runtime for the suggested world polling interval. Poll insights according to refreshAfterMs, honor capture expiry, and stop background requests when your app is inactive. Apple clients share this behavior in OrchestraCore.
GET /events offers world snapshot and delta events when the processing connection supports streaming. Send your bearer key with a streaming fetch client. The website uses session cookies with EventSource; machine clients send a bearer header with a streaming HTTP client. Do not put a key in the URL.
Streams reconnect after at most 110 seconds to recheck authorization. Two concurrent streams are allowed per key. Events are not replayable and have no historical resume cursor. On 503, use /world polling. On reconnect, rebuild state from the next snapshot.
Small SDKs. No extra runtime.
Download the source clients directly. They use native HTTP libraries, preserve API errors, and retry transient reads. Processing writes are never silently retried.
JavaScript / TypeScript
Node 18+ and browsers. Fetch-based ES module, with TypeScript declarations.
JavaScript ↓ Types ↓import { Orchestra } from './orchestra.mjs';
const api = new Orchestra({ apiKey: process.env.ORCHESTRA_API_KEY });
const { insights } = await api.insights();
console.log(insights[0]);import os
from orchestra import Orchestra
api = Orchestra(api_key=os.environ['ORCHESTRA_API_KEY'])
print(api.insights()['insights'][0])Apple apps use the same Swift package, OrchestraCore, for API transport, Keychain storage, data models, polling, and insight state. iPhone, Mac, and Vision Pro also share their main SwiftUI screens.
Changelog
October 20, 2026
Public data routes are documented under a Public data tag with their own server, schemas and cache policies, and the explorer can call them without signing in. /status now reports operational or degraded from live checks, with a reasons list and checkedAt. Additive; no breaking changes.
September 12, 2026
Initial versioned API. Authenticated camera observations, world data, server-generated insights, and idempotent processing requests.
Additive fields may appear within v1. Ignore fields you do not recognize. Breaking contract changes will use a new major path; any announced deprecation will appear here.
Service & support
Service health is available without signing in.
GET /api/v1/status reports degraded with one or more reasons: counts-stale (no count data in 15 minutes), catalog-stale (no camera catalog in 30 minutes), perception-stopped (the detector is not running), no-fresh-cameras (no camera frame in the last minute) or ai-review-stalled (no AI scene review in 10 minutes). It never returns raw errors.
Camera decoding and inference run on the Orchestra processing server. Camera imagery and per-object live data require authentication; the open data above is aggregate only.
For access changes or integration support, contact the operator with your request ID. Never share a full API key.