# API contract summary The machine-readable baseline is `contracts/openapi.yaml`. ## Authentication The demo may use signed server-issued sessions or short-lived JWTs. Demo-role buttons create an authenticated session; they do not bypass authorization middleware. ## Required routes ### System and demo - `GET /health` - `GET /api/v1/demo/manifest` — unauthenticated; demo org name/description, synthetic-data flag, reset allowance and timestamp, guide availability, the 5 named scenarios (with live readiness derived from actual records, not hardcoded), and plain-language integration summaries. Single source of truth for the demo-entry screen, the permanent demo badge, the scenario overview and the About page — avoids duplicating this logic per surface. - `POST /api/v1/demo/login` - `GET /api/v1/demo/session` — confirms the current session; `Cache-Control: no-store` - `POST /api/v1/demo/logout` — safe to call without a session - `POST /api/v1/demo/reset` — Operations Manager only; invalidates the caller's own session; returns 403 if `DEMO_ALLOW_RESET=false` ### Dashboard - `GET /api/v1/dashboard` ### Vehicles - `GET /api/v1/vehicles` - `GET /api/v1/vehicles/{public_ref}` ### Bookings and return - `GET /api/v1/bookings` - `GET /api/v1/bookings/{public_ref}` - `POST /api/v1/bookings/{public_ref}/return-preview` — non-mutating; shares its domain evaluation with the commit endpoint below so the two cannot drift apart - `POST /api/v1/bookings/{public_ref}/return` Return commands require an `Idempotency-Key` header. Concurrency safety is row-lock based (`SELECT ... FOR UPDATE` on the booking and vehicle); no optimistic-version field is accepted or needed on top of that. ### Data quality All Operations Manager only. - `GET /api/v1/data-quality/issues` - `GET /api/v1/data-quality/issues/{public_ref}` - `POST /api/v1/data-quality/scan` — manual trigger for the deterministic five-rule scan - `POST /api/v1/data-quality/issues/{public_ref}/defer` - `POST /api/v1/data-quality/issues/{public_ref}/reject` - `POST /api/v1/data-quality/issues/{public_ref}/merge-customers` — possible_duplicate_customer - `POST /api/v1/data-quality/issues/{public_ref}/provide-fields` — missing_required_field - `POST /api/v1/data-quality/issues/{public_ref}/resolve-odometer-regression` — odometer_regression - `POST /api/v1/data-quality/issues/{public_ref}/resolve-overlap` — booking_overlap - `POST /api/v1/data-quality/issues/{public_ref}/apply-recommended-status` — vehicle_status_conflict Each of the five rule types has exactly one bounded resolution path above (plus defer/reject, which apply to any open issue). ### Search - `GET /api/v1/search?q=...` — bounded typed results (vehicle, booking, data_quality_issue, section); role-filtered server-side; customers are never returned (no customer detail route exists in this PoC) ### Knowledge - `POST /api/v1/knowledge/questions` - `GET /api/v1/knowledge/status` ### Automation and audit - `GET /api/v1/workflows` — Operations Manager only - `POST /api/v1/workflows/{event_id}/retry` — Operations Manager only - `GET /api/v1/audit` — Operations Manager only; each event includes `before`/`after` plus a resolved `entity_ref`/`entity_link` where the entity type supports one - `GET /api/v1/integrations/status` — Operations Manager only; truthful aggregate n8n state from outbox delivery counts (not just the most recent event), and the actual MCP Hub `registration_enabled` setting ### n8n-service endpoints Service-token protected (`X-Service-Token`, same shared secret as the return callback): - `POST /api/v1/integrations/n8n/return-callback` - `POST /api/v1/integrations/n8n/scheduled-scan` — triggered by the scheduled quality-scan workflow; runs the same domain scan the manual UI action uses ### MCP-provider endpoints Service-token protected: - `GET /api/v1/integrations/mcp/operations-summary` - `GET /api/v1/integrations/mcp/attention-vehicles` - `GET /api/v1/integrations/mcp/vehicles/{public_ref}` Knowledge search may be routed by the Hub directly to RAGcore or through a narrowly scoped MobilityOps façade. Use the contract chosen in `docs/10-mcp-hub-integration.md`. ## Error shape ```json { "error": { "code": "ODOMETER_REGRESSION", "message": "The submitted reading is below the current canonical odometer.", "correlation_id": "...", "details": {} } } ```