API changelog
Every schema-version bump. Additive changes are noted so
integrators can enable new features without a breaking-change
migration; removals happen only in a new v2 proto package
with the standard 12-month deprecation window per
docs/ROADMAP.md Phase 7 §"API discipline requirements."
1.3 — GetIncidentUnitMovement Layer 1 read method (2026-07-07)
What's new:
-
GET /v1/departments/{deptId}/incidents/{incidentId}/unit-movement— per-unit GPS movement trace summary for an incident. Response envelope:{"incident_id": "...", "unit_movement": [{...}]}. Each row:unit_id,designation,fix_count,first_fix_at,last_fix_at,approximate_distance_meters(haversine sum),average_accuracy_meters, bounding box (min_latitude/max_latitude/min_longitude/max_longitude), and optionalmax_speed_mps(omitted when no fix reported speed). Same 404 semantics asGetIncident(null → not found); emptyunit_movementlist when the log is non-empty but recorded noUnitLocationReportedevents.Wraps the pure
summarizeUnitMovementprojection from core_domain — same aggregation the after-action PDF's Section 9b renders. Gives integrators programmatic access without parsing the PDF. -
New capability
incident.unit_movement(sinceVersion: "1.3") exposed viaGetEffectiveCapabilities. -
GET /v1/departments/{deptId}/incidents/{incidentId}response envelope gains an optionalmovement_summaryfield — same row shape as the dedicated/unit-movementendpoint. Present when the incident recorded ≥1 GPS fix; omitted when empty. Additive convenience so integrators pollingGetIncidentdon't need to chain a second call. Pre-1.3 clients ignore the missing / new key cleanly (no wire-format break).
What's deprecated: None.
Wire-format breaks: None. Every change is additive.
1.2 — Integration registry LIST + DELETE + per-department authorization gate (2026-07-07)
What's new:
-
GET /v1/integrations— enumerate every registered integration. Response envelope:{"integrations": [...]}. Open to every api_read_v1 caller (integration metadata is not sensitive; enumeration is expected for the admin console + integrator directory pages). Wired inIntegrationRegistryFirestoreService.list(). -
DELETE /v1/integrations/{integration_id}— unregister an integration. Ownership check: JWT'ssubmust match the doc'sregistrant_sub. 403 on mismatch, 404 on missing. Response:{"deleted": true}. Wired inIntegrationRegistryFirestoreService.delete().Downstream effect. After delete, the producer-capability gate rejects every ingest row for the integration's api_keys because the registry lookup returns null (fail-closed). Active Layer 3 WebSocket subscriptions on the integration's JWT continue until the JWT expires.
-
Per-department integration authorization gate. Every request whose URL targets a department other than the JWT's scope now consults
departments/{deptId}/authorized_integrations/{integrationId}. Missing → 403 with actionable message pointing at the admin console. Revoked → 403 with the revocation timestamp. Active → allowed. Customer-scoped JWTs (JWT dept matches URL) skip the gate entirely. 1-minute TTL cache. See the Authentication guide §"Two-step onboarding" for the full model.
What's deprecated: None.
Wire-format breaks: None. Every change is additive.
1.1 — Layer 3 Firestore-backed live event stream (2026-07-06)
What's new:
- Live event tail on the
wss://…/subscribetransport now actually pushes new events, not just replays history and hangs idle. Implementation: a Firestore-poll adapter (FirestoreIncidentEventStream) polls the same collection the read path queries on a 2-second interval with a per-watch cursor. Latency: two-to-three seconds worst case. Multi-subscriber fan-out shares one upstream poll per (department, incident); broadcast controller emits to all attached subscribers.
What's deprecated: None.
Wire-format breaks: None. Additive substrate change; the subscribe transport's wire format is unchanged.
1.0 — Layer 1 read + Layer 2 write + Layer 3 subscribe (2026-07-06)
Inaugural release. All three layers now shipped:
- Layer 1 read — 8 methods across
IncidentReadService,TrustKeysService. - Layer 2 write ingest —
POST /v1/departments/{deptId}/eventswith producer-capability enforcement. - Layer 3 subscribe —
wss://…/subscribeWebSocket transport with history-replay + snapshot-end boundary + live tail.
Dart SDK published as muster_api_client on pub.dev.
Python + TypeScript + Go + Java SDKs generated from
the same proto files; publishing is manual per language
on customer demand (see PUBLIC_API_CLIENT_SDKS.md).
Format for future entries
## <schema-version> — <feature> (<date>)
**What's new:**
- (list of additive changes; every change references the
proto file + method or field)
**What's deprecated:**
- (endpoints or fields marked deprecated; Sunset date; 12-month
removal window applies)
**Wire-format breaks:** None. (Wire breaks require v2.)