openapi: 3.1.0 info: title: MobilityOps API version: 0.1.0 description: Contract baseline for the MobilityOps proof of concept. servers: - url: http://localhost:8128 paths: /health: get: operationId: health responses: '200': description: Healthy content: application/json: schema: $ref: '#/components/schemas/Health' /api/v1/dashboard: get: operationId: getDashboard responses: '200': description: Persisted operational summary content: application/json: schema: $ref: '#/components/schemas/Dashboard' /api/v1/vehicles: get: operationId: listVehicles parameters: - in: query name: status schema: type: string - in: query name: attention_only schema: type: boolean default: false responses: '200': description: Vehicle list /api/v1/vehicles/{public_ref}: get: operationId: getVehicle parameters: - $ref: '#/components/parameters/PublicRef' responses: '200': description: Vehicle detail '404': $ref: '#/components/responses/NotFound' /api/v1/bookings: get: operationId: listBookings responses: '200': description: Booking list /api/v1/bookings/{public_ref}: get: operationId: getBooking parameters: - $ref: '#/components/parameters/PublicRef' responses: '200': description: Booking detail /api/v1/bookings/{public_ref}/return: post: operationId: registerVehicleReturn parameters: - $ref: '#/components/parameters/PublicRef' - in: header name: Idempotency-Key required: true schema: type: string minLength: 8 maxLength: 128 requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RegisterReturnRequest' responses: '200': description: Existing idempotent result replayed '201': description: Return registered '409': description: State or concurrency conflict /api/v1/data-quality/issues: get: operationId: listDataQualityIssues responses: '200': description: Quality issues /api/v1/data-quality/issues/{public_ref}/merge-customers: post: operationId: mergeDuplicateCustomers parameters: - $ref: '#/components/parameters/PublicRef' responses: '200': description: Merge completed '409': description: Issue no longer mergeable /api/v1/knowledge/questions: post: operationId: askKnowledgeQuestion requestBody: required: true content: application/json: schema: type: object required: [question] properties: question: type: string minLength: 3 maxLength: 1000 responses: '200': description: Grounded, insufficient or unavailable answer content: application/json: schema: $ref: '#/components/schemas/GroundedAnswer' /api/v1/integrations/mcp/operations-summary: get: operationId: mcpOperationsSummary security: - serviceToken: [] responses: '200': description: Read-only operational summary components: securitySchemes: serviceToken: type: http scheme: bearer parameters: PublicRef: in: path name: public_ref required: true schema: type: string responses: NotFound: description: Not found schemas: Health: type: object required: [status, service] properties: status: const: ok service: const: mobilityops-api Dashboard: type: object required: [metrics, attention_items] properties: metrics: type: object additionalProperties: type: integer attention_items: type: array items: type: object RegisterReturnRequest: type: object required: [end_odometer_km, fuel_level_percent, cleanliness_ok, damage_reported, technical_warning] properties: end_odometer_km: type: integer minimum: 0 fuel_level_percent: type: integer minimum: 0 maximum: 100 cleanliness_ok: type: boolean damage_reported: type: boolean technical_warning: type: boolean notes: type: string maxLength: 2000 GroundedAnswer: type: object required: [answer, evidence_state, sources, provider, correlation_id] properties: answer: type: string evidence_state: enum: [grounded, insufficient, unavailable] sources: type: array items: type: object required: [document_id, title, version, section, excerpt] properties: document_id: {type: string} title: {type: string} version: {type: string} section: {type: string} excerpt: {type: string} provider: type: string correlation_id: type: string