{"openapi":"3.0.1","info":{"title":"RAPID REACH APIs","description":"API documentation for the RAPID REACH Spring Boot application.","contact":{"name":"RAPID REACH","email":"virgile405@gmail.com"},"license":{"name":"Apache 2.0","url":"https://www.apache.org/licenses/LICENSE-2.0.html"},"version":"1.0.0"},"servers":[{"url":"http://rapidreachbn.nexvsoft.com","description":"Generated server url"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Authentication","description":"Login, signup, passwords, email verification"},{"name":"Telecom audit","description":"CAMARA / telecom request log"},{"name":"Overall dashboard","description":"Aggregated system KPIs for super-admin dashboards"},{"name":"Responders","description":"Field staff linked to users and optionally an ambulance"},{"name":"Dispatch (self)","description":"Responder session and position for mobile apps"},{"name":"Roles","description":"CRUD for organization-scoped roles (ADMIN, DISPATCHER, …)"},{"name":"Health","description":"Service health and availability"},{"name":"Dispatch","description":"Responder and ambulance assignment"},{"name":"Ambulances","description":"Fleet vehicles per organization"},{"name":"Organizations","description":"CRUD for emergency response organizations (hospitals, EMS, etc.)"},{"name":"Users","description":"Admin user provisioning and management (no self-signup here)"},{"name":"Emergency types","description":"Catalog of incident categories (Cardiac, Fire, …)"},{"name":"Emergency incidents","description":"SOS intake, incident lifecycle, routing, QoD"}],"paths":{"/api/users/{id}":{"get":{"tags":["Users"],"summary":"Get user by ID","operationId":"getById","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Users"],"summary":"Update user","operationId":"update","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Users"],"summary":"Soft-delete user (sets is_active = false and deactivates role links)","operationId":"delete","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"bearerAuth":[]}]}},"/api/users/{id}/roles":{"put":{"tags":["Users"],"summary":"Assign roles to user","description":"Replaces this user's active role assignments. Every role must belong to the user's organization. Send roleIds: [] to remove all roles.","operationId":"assignRoles","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignUserRolesRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"bearerAuth":[]}]}},"/api/roles/{id}":{"get":{"tags":["Roles"],"summary":"Get role by ID","operationId":"getById_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"put":{"tags":["Roles"],"summary":"Update role","operationId":"update_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"delete":{"tags":["Roles"],"summary":"Soft-delete role (sets is_active = false)","operationId":"delete_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/responders/{id}":{"get":{"tags":["Responders"],"summary":"Get responder by ID","operationId":"getById_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"put":{"tags":["Responders"],"summary":"Update responder","operationId":"update_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponderUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"delete":{"tags":["Responders"],"summary":"Soft-delete responder","operationId":"delete_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/organizations/{id}":{"get":{"tags":["Organizations"],"summary":"Get organization by ID","operationId":"getById_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"put":{"tags":["Organizations"],"summary":"Update organization","operationId":"update_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"delete":{"tags":["Organizations"],"summary":"Soft-delete organization (sets is_active = false)","operationId":"delete_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/emergency-types/{id}":{"get":{"tags":["Emergency types"],"summary":"Get emergency type by ID","operationId":"getById_4","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"put":{"tags":["Emergency types"],"summary":"Update emergency type","operationId":"update_4","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmergencyTypeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"delete":{"tags":["Emergency types"],"summary":"Soft-delete emergency type","operationId":"delete_4","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/dispatch/me/position":{"put":{"tags":["Dispatch (self)"],"summary":"Update GPS position for proximity alerts","operationId":"updatePosition","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponderPositionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/ambulances/{id}":{"get":{"tags":["Ambulances"],"summary":"Get ambulance by ID","operationId":"getById_5","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"put":{"tags":["Ambulances"],"summary":"Update ambulance","operationId":"update_5","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AmbulanceRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"delete":{"tags":["Ambulances"],"summary":"Soft-delete ambulance; clears ambulance assignment on responders","operationId":"delete_5","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/users":{"get":{"tags":["Users"],"summary":"Paginated list of users","operationId":"getPaged","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":10}},{"name":"sortColumn","in":"query","required":false,"schema":{"type":"string","default":"createdAt"}},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","default":"desc"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"organizationId","in":"query","description":"Only users in this organization","required":false,"schema":{"type":"string","description":"Only users in this organization","format":"uuid"}},{"name":"isActive","in":"query","description":"Omit or true: only active users (default). false: only inactive (soft-deleted) users.","required":false,"schema":{"type":"boolean","description":"Omit or true: only active users (default). false: only inactive (soft-deleted) users."}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Users"],"summary":"Create user (admin)","description":"Creates the user with a temporary password and emails instructions. Provide organizationId and roleIds for tenant users; omit organizationId (and roleIds) for platform-only accounts.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"bearerAuth":[]}]}},"/api/roles":{"get":{"tags":["Roles"],"summary":"Paginated list of roles","operationId":"getPaged_1","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":10}},{"name":"sortColumn","in":"query","required":false,"schema":{"type":"string","default":"createdAt"}},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","default":"desc"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"organizationId","in":"query","description":"Only roles for this organization","required":false,"schema":{"type":"string","description":"Only roles for this organization","format":"uuid"}},{"name":"isActive","in":"query","description":"Omit or true: only active roles (default). false: only inactive (soft-deleted) roles.","required":false,"schema":{"type":"boolean","description":"Omit or true: only active roles (default). false: only inactive (soft-deleted) roles."}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Roles"],"summary":"Create role","operationId":"create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/responders":{"get":{"tags":["Responders"],"summary":"Paginated list of responders","operationId":"getPaged_2","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":10}},{"name":"sortColumn","in":"query","required":false,"schema":{"type":"string","default":"createdAt"}},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","default":"desc"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"organizationId","in":"query","description":"Users belonging to this organization","required":false,"schema":{"type":"string","description":"Users belonging to this organization","format":"uuid"}},{"name":"isActive","in":"query","description":"Omit or true: active only (default). false: inactive only.","required":false,"schema":{"type":"boolean","description":"Omit or true: active only (default). false: inactive only."}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Responders"],"summary":"Create responder (one row per user; reactivates if previously soft-deleted)","operationId":"create_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponderCreateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/organizations":{"get":{"tags":["Organizations"],"summary":"Paginated list of organizations","operationId":"getPaged_3","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":10}},{"name":"sortColumn","in":"query","required":false,"schema":{"type":"string","default":"createdAt"}},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","default":"desc"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"country","in":"query","description":"Case-insensitive partial match on country","required":false,"schema":{"type":"string","description":"Case-insensitive partial match on country","example":"RW"},"example":"RW"},{"name":"city","in":"query","description":"Case-insensitive partial match on city","required":false,"schema":{"type":"string","description":"Case-insensitive partial match on city","example":"Kigali"},"example":"Kigali"},{"name":"isActive","in":"query","description":"Omit or true: only active rows. false: only inactive (soft-deleted) organizations.","required":false,"schema":{"type":"boolean","description":"Omit or true: only active rows. false: only inactive (soft-deleted) organizations."}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Organizations"],"summary":"Create organization","operationId":"create_2","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/health/ai":{"get":{"tags":["Health"],"summary":"Anthropic (Claude) reachability","description":"Sends one minimal completion to verify API key, model, and network. Safe for dev/staging; protect or disable in production if you do not want to expose connectivity details.","operationId":"aiReachability","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiReachabilityResponse"}}}}}},"post":{"tags":["Health"],"summary":"Anthropic prompt test","description":"Send your own user message to Claude; response shape matches GET /api/health/ai. `responsePreview` includes the assistant reply (up to ~16k chars; see `replyTruncated`). Dev/staging only — do not expose unauthenticated in production.","operationId":"aiReachabilityWithPrompt","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiHealthPromptRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiReachabilityResponse"}}}}}}},"/api/emergency/sos/intake":{"post":{"tags":["Emergency incidents"],"summary":"SOS intake with optional CAMARA verify/location and Claude assessment","operationId":"intake","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SosIntakeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SosIntakeResponse"}}}}}}},"/api/emergency/incidents/{id}/updates":{"get":{"tags":["Emergency incidents"],"summary":"List incident timeline updates","operationId":"listIncidentUpdates","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IncidentUpdateResponse"}}}}}}},"post":{"tags":["Emergency incidents"],"summary":"Add timeline / dispatcher update","operationId":"addIncidentUpdate","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentUpdateResponse"}}}}}}},"/api/emergency/incidents/{id}/route":{"get":{"tags":["Emergency incidents"],"summary":"Latest computed route (OSRM)","operationId":"getLatestRoute","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RouteResponse"}}}}}},"post":{"tags":["Emergency incidents"],"summary":"Compute and store route from ambulance to incident (OSRM)","operationId":"computeRoute","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RouteComputeRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RouteResponse"}}}}}}},"/api/emergency/incidents/{id}/device-reachability/subscriptions":{"post":{"tags":["Emergency incidents"],"summary":"Create device reachability subscription (CAMARA)","operationId":"createDeviceReachabilitySubscription","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceReachabilitySubscriptionRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"string"}}}}}}},"/api/emergency/incidents/{id}/calls/qod/start":{"post":{"tags":["Emergency incidents"],"summary":"Start QoD session (CAMARA)","operationId":"qodStart","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QodSessionRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QodCallResponse"}}}}}}},"/api/emergency/incidents/{id}/calls/qod/end":{"post":{"tags":["Emergency incidents"],"summary":"End active QoD session","operationId":"qodEnd","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QodCallResponse"}}}}}}},"/api/emergency/incidents/{id}/ai-dispatch-suggestion/refresh":{"post":{"tags":["Emergency incidents"],"summary":"Recompute AI dispatch suggestion (sync)","description":"Runs the fleet dispatch pipeline immediately and persists a new suggestion; also pushes a realtime update if configured.","operationId":"refreshDispatchSuggestion","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiDispatchSuggestionResponse"}}}}}}},"/api/emergency/incidents/{id}/ai-assessment/reassess":{"post":{"tags":["Emergency incidents"],"summary":"Re-run Claude assessment","operationId":"reassess","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAssessmentApiResponse"}}}}}}},"/api/emergency-types":{"get":{"tags":["Emergency types"],"summary":"Paginated list of emergency types","operationId":"getPaged_4","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":10}},{"name":"sortColumn","in":"query","required":false,"schema":{"type":"string","default":"createdAt"}},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","default":"desc"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"isActive","in":"query","description":"Omit or true: active only (default). false: inactive only.","required":false,"schema":{"type":"boolean","description":"Omit or true: active only (default). false: inactive only."}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Emergency types"],"summary":"Create emergency type","operationId":"create_3","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmergencyTypeRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/dispatch/override":{"post":{"tags":["Dispatch"],"summary":"Dispatcher override of AI / previous assignment","operationId":"overrideAssignment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DispatchOverrideRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponderAssignmentResponse"}}}}}}},"/api/dispatch/assign":{"post":{"tags":["Dispatch"],"summary":"Assign responder and ambulance to incident","operationId":"assign","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DispatchAssignRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponderAssignmentResponse"}}}}}}},"/api/auth/signup":{"post":{"tags":["Authentication"],"summary":"Self signup","description":"Registers as CITIZEN when that role exists on the organization.","operationId":"signup","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/auth/login":{"post":{"tags":["Authentication"],"summary":"Login","description":"Returns JWT. If mustChangePassword is true, call POST /api/auth/change-password.","operationId":"login","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/auth/forgot-password":{"post":{"tags":["Authentication"],"summary":"Forgot password","description":"Always returns success message; email is sent only if the address is registered.","operationId":"forgotPassword","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/auth/change-password":{"post":{"tags":["Authentication"],"summary":"Change password (authenticated)","description":"Requires Bearer JWT. Use after first login with a temporary password or to rotate password.","operationId":"changePassword","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/ambulances":{"get":{"tags":["Ambulances"],"summary":"Paginated list of ambulances","operationId":"getPaged_5","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":10}},{"name":"sortColumn","in":"query","required":false,"schema":{"type":"string","default":"createdAt"}},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","default":"desc"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"organizationId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"isActive","in":"query","description":"Omit or true: active only (default). false: inactive only.","required":false,"schema":{"type":"boolean","description":"Omit or true: active only (default). false: inactive only."}},{"name":"status","in":"query","description":"Exact status match, case-insensitive (e.g. AVAILABLE)","required":false,"schema":{"type":"string","description":"Exact status match, case-insensitive (e.g. AVAILABLE)"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Ambulances"],"summary":"Create ambulance","operationId":"create_4","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AmbulanceRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/emergency/incidents/{id}":{"get":{"tags":["Emergency incidents"],"summary":"Get incident by id","operationId":"getIncident","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentResponse"}}}}}},"patch":{"tags":["Emergency incidents"],"summary":"Update incident fields (status, priority, notes, device)","operationId":"patchIncident","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchIncidentRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentResponse"}}}}}}},"/api/users/profile":{"get":{"tags":["Users"],"summary":"Authenticated user profile","description":"JWT profile with role names aligned with login — refresh stale client-side session.","operationId":"getAuthenticatedProfile","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"bearerAuth":[]}]}},"/api/users/all":{"get":{"tags":["Users"],"summary":"List active users (non-paginated, optional search only)","operationId":"getAll","parameters":[{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"bearerAuth":[]}]}},"/api/telecom/requests":{"get":{"tags":["Telecom audit"],"summary":"List telecom requests and responses for an incident","operationId":"listByIncident","parameters":[{"name":"incidentId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TelecomRequestAuditResponse"}}}}}}}},"/api/roles/all":{"get":{"tags":["Roles"],"summary":"List all active roles (non-paginated, optional search only)","operationId":"getAll_1","parameters":[{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/responders/all":{"get":{"tags":["Responders"],"summary":"List active responders (non-paginated, search only)","operationId":"getAll_2","parameters":[{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/overall/dashboard":{"get":{"tags":["Overall dashboard"],"summary":"Get system KPI snapshot","description":"Returns total/active counts across major entities.","operationId":"getDashboard","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"bearerAuth":[]}]}},"/api/organizations/all":{"get":{"tags":["Organizations"],"summary":"List all active organizations (non-paginated, optional search only)","operationId":"getAll_3","parameters":[{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/health":{"get":{"tags":["Health"],"summary":"Health check","description":"Returns whether the API process is running","operationId":"health","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/health/integrations":{"get":{"tags":["Health"],"summary":"Integration liveness","description":"One snapshot each for Anthropic (Claude), Nokia CAMARA gateway, and S3/MinIO (HeadBucket). Nokia is checked with sandbox number-verification when possible. DOWN includes diagnostic messages; Nokia may be DISABLED when camara.nokia.enabled=false.","operationId":"integrations","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationHealthResponse"}}}}}}},"/api/emergency/incidents":{"get":{"tags":["Emergency incidents"],"summary":"Incident queue / list with filters","operationId":"listIncidents","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}},{"name":"organizationId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"from","in":"query","required":false,"schema":{"type":"string"}},{"name":"to","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageIncidentResponse"}}}}}}},"/api/emergency/incidents/{id}/verified-profiles":{"get":{"tags":["Emergency incidents"],"summary":"Verified caller profiles for an incident","operationId":"listVerifiedProfiles","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VerifiedProfileResponse"}}}}}}}},"/api/emergency/incidents/{id}/device-reachability/subscriptions/{subscriptionId}":{"get":{"tags":["Emergency incidents"],"summary":"Get device reachability subscription by ID (CAMARA)","operationId":"getDeviceReachabilitySubscription","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"subscriptionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"string"}}}}}}},"/api/emergency/incidents/{id}/ai-dispatch-suggestion":{"get":{"tags":["Emergency incidents"],"summary":"Latest AI fleet dispatch suggestion","description":"Returns the most recent background Claude recommendation (ambulance + ETA + rationale). If none yet, use POST .../refresh or wait for async enrichment after intake/reassess.","operationId":"getLatestDispatchSuggestion","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiDispatchSuggestionResponse"}}}}}}},"/api/emergency/incidents/{id}/ai-assessments":{"get":{"tags":["Emergency incidents"],"summary":"All AI assessments for an incident","operationId":"listAiAssessments","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AiAssessmentApiResponse"}}}}}}}},"/api/emergency/incidents/{id}/ai-assessment":{"get":{"tags":["Emergency incidents"],"summary":"Latest Claude assessment","operationId":"getLatestAiAssessment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAssessmentApiResponse"}}}}}}},"/api/emergency-types/all":{"get":{"tags":["Emergency types"],"summary":"List active emergency types (non-paginated, search only)","operationId":"getAll_4","parameters":[{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/dispatch/me/responder":{"get":{"tags":["Dispatch (self)"],"summary":"Responder profile for the authenticated user","operationId":"getMyResponder","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/dispatch/me/mobile-oauth-url":{"get":{"tags":["Dispatch (self)"],"summary":"Optional operator OAuth authorize URL for MSISDN flows","description":"When configured, mobile apps can open this URL in an in-app browser; CAMARA calls remain server-side.","operationId":"mobileOauthUrl","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/dispatch/assignments":{"get":{"tags":["Dispatch"],"summary":"List dispatch assignments for an incident","operationId":"listAssignments","parameters":[{"name":"incidentId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ResponderAssignmentResponse"}}}}}}}},"/api/auth/verify-email":{"get":{"tags":["Authentication"],"summary":"Verify email","description":"Called from the link sent after signup (browser GET).","operationId":"verifyEmail","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/ambulances/all":{"get":{"tags":["Ambulances"],"summary":"List active ambulances (non-paginated, search only)","operationId":"getAll_5","parameters":[{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}}},"components":{"schemas":{"UpdateUserRequest":{"type":"object","properties":{"name":{"maxLength":255,"minLength":0,"type":"string"},"phone":{"maxLength":50,"minLength":0,"type":"string"},"organizationId":{"type":"string","description":"Move user to another organization (must supply matching roleIds if roles should be kept)","format":"uuid"},"roleIds":{"type":"array","description":"When set, syncs role assignments: these roles must belong to the user's organization. Empty list removes all roles.","items":{"type":"string","description":"When set, syncs role assignments: these roles must belong to the user's organization. Empty list removes all roles.","format":"uuid"}}},"description":"Partial update; only non-null fields apply. roleIds replaces active assignments when set."},"AssignUserRolesRequest":{"required":["roleIds"],"type":"object","properties":{"roleIds":{"type":"array","description":"Role UUIDs; empty list removes all roles for this user.","items":{"type":"string","description":"Role UUIDs; empty list removes all roles for this user.","format":"uuid"}}},"description":"Replaces the user's active role assignments. Each role must belong to the user's organization. Send an empty list to remove all roles."},"RoleRequest":{"required":["name","organizationId"],"type":"object","properties":{"organizationId":{"type":"string","description":"Owning organization","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"},"name":{"maxLength":100,"minLength":0,"type":"string","example":"DISPATCHER"},"description":{"maxLength":500,"minLength":0,"type":"string"}},"description":"Create or update role payload"},"ResponderUpdateRequest":{"type":"object","properties":{"detachFromAmbulance":{"type":"boolean","description":"When true, clears ambulance assignment (ambulanceId is ignored)"},"ambulanceId":{"type":"string","description":"Assign this ambulance (same org as responder's user)","format":"uuid"},"licenseNumber":{"maxLength":100,"minLength":0,"type":"string"},"specialization":{"maxLength":255,"minLength":0,"type":"string"},"availabilityStatus":{"maxLength":50,"minLength":0,"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"lastSeen":{"type":"string","format":"date-time"}},"description":"Update responder; omit fields you do not want to change"},"OrganizationRequest":{"required":["name"],"type":"object","properties":{"name":{"maxLength":255,"minLength":0,"type":"string","description":"Organization display name","example":"City EMS"},"email":{"maxLength":320,"minLength":0,"type":"string","example":"contact@cityems.org"},"phone":{"maxLength":50,"minLength":0,"type":"string"},"country":{"maxLength":100,"minLength":0,"type":"string"},"city":{"maxLength":100,"minLength":0,"type":"string"},"address":{"maxLength":500,"minLength":0,"type":"string"}},"description":"Create or update organization payload"},"EmergencyTypeRequest":{"required":["name"],"type":"object","properties":{"name":{"maxLength":150,"minLength":0,"type":"string","example":"Cardiac arrest"},"description":{"maxLength":1000,"minLength":0,"type":"string"},"priorityDefault":{"type":"integer","description":"Default dispatch priority (interpretation is up to your ops)","format":"int32"}},"description":"Create or update emergency type"},"ResponderPositionRequest":{"required":["latitude","longitude"],"type":"object","properties":{"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"}}},"AmbulanceRequest":{"required":["organizationId","plateNumber"],"type":"object","properties":{"organizationId":{"type":"string","format":"uuid"},"plateNumber":{"maxLength":32,"minLength":0,"type":"string","example":"RAA 123 A"},"vehicleName":{"maxLength":255,"minLength":0,"type":"string"},"driverName":{"maxLength":255,"minLength":0,"type":"string"},"driverPhone":{"maxLength":50,"minLength":0,"type":"string"},"status":{"maxLength":50,"minLength":0,"type":"string","description":"Examples: AVAILABLE, DISPATCHED, OFFLINE","example":"AVAILABLE"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"lastSeen":{"type":"string","format":"date-time"},"deviceOnline":{"type":"boolean","description":"Whether the onboard device is connected"}},"description":"Create or update ambulance"},"CreateUserRequest":{"required":["email","name"],"type":"object","properties":{"organizationId":{"type":"string","description":"Tenant organization; omit for platform-only accounts (e.g. super admin).","format":"uuid"},"name":{"maxLength":255,"minLength":0,"type":"string"},"email":{"maxLength":320,"minLength":0,"type":"string"},"phone":{"maxLength":50,"minLength":0,"type":"string"},"roleIds":{"type":"array","description":"Role UUIDs when organizationId is set (required in that case); omit or empty when no organization.","items":{"type":"string","description":"Role UUIDs when organizationId is set (required in that case); omit or empty when no organization.","format":"uuid"}}},"description":"Admin: create user with temporary password (no self-signup). When organizationId is set, roleIds must be non-empty and every role must belong to that organization. When organizationId is omitted (platform user), roleIds must be empty."},"ResponderCreateRequest":{"required":["userId"],"type":"object","properties":{"userId":{"type":"string","description":"User must be active and belong to an organization","format":"uuid"},"ambulanceId":{"type":"string","description":"Optional ambulance in the same organization as the user","format":"uuid"},"licenseNumber":{"maxLength":100,"minLength":0,"type":"string"},"specialization":{"maxLength":255,"minLength":0,"type":"string"},"availabilityStatus":{"maxLength":50,"minLength":0,"type":"string","example":"AVAILABLE"}},"description":"Create responder (one per user)"},"AiHealthPromptRequest":{"required":["prompt"],"type":"object","properties":{"prompt":{"maxLength":200000,"minLength":0,"type":"string","description":"User message sent to Claude as a single turn","example":"In one sentence, what is 2+2?"},"maxTokens":{"maximum":8192,"minimum":16,"type":"integer","description":"max_tokens for the completion (default 1024)","format":"int32","example":1024,"default":1024}},"description":"Optional custom prompt for Anthropic test call (dev/staging)"},"AiReachabilityResponse":{"type":"object","properties":{"reachable":{"type":"boolean","description":"True if a minimal completion call succeeded"},"message":{"type":"string","description":"Human-readable status or error detail"},"model":{"type":"string","description":"Model id from configuration (may still be set when unreachable)"},"latencyMs":{"type":"integer","description":"Round-trip time in ms when reachable; null otherwise","format":"int64"},"responsePreview":{"type":"string","description":"Model reply when reachable: short for GET ping, longer for POST /api/health/ai (may be truncated; see replyTruncated)"},"replyTruncated":{"type":"boolean","description":"True if responsePreview was truncated; null when unreachable or full text fit the limit"}},"description":"Result of a live Anthropic API connectivity check"},"SosIntakeRequest":{"required":["emergencyTypeId"],"type":"object","properties":{"citizenId":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"emergencyTypeId":{"type":"string","format":"uuid"},"phoneNumber":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"address":{"type":"string"},"voiceTranscript":{"type":"string"},"emergencyText":{"type":"string"},"skipCamara":{"type":"boolean"},"idDocument":{"type":"string"},"name":{"type":"string"},"givenName":{"type":"string"},"familyName":{"type":"string"},"nameKanaHankaku":{"type":"string"},"nameKanaZenkaku":{"type":"string"},"middleNames":{"type":"string"},"familyNameAtBirth":{"type":"string"},"streetName":{"type":"string"},"streetNumber":{"type":"string"},"postalCode":{"type":"string"},"region":{"type":"string"},"locality":{"type":"string"},"country":{"type":"string"},"houseNumberExtension":{"type":"string"},"birthdate":{"type":"string"},"email":{"type":"string"},"gender":{"type":"string"}}},"SosIntakeResponse":{"type":"object","properties":{"incidentId":{"type":"string","format":"uuid"},"referenceNo":{"type":"string"},"status":{"type":"string"},"verifiedProfileId":{"type":"string","format":"uuid"},"aiPriorityScore":{"type":"number","format":"double"},"aiRiskLevel":{"type":"string"},"aiSummary":{"type":"string"}}},"IncidentUpdateRequest":{"type":"object","properties":{"status":{"type":"string"},"comment":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"updatedByUserId":{"type":"string","format":"uuid"}}},"IncidentUpdateResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"},"comment":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"createdAt":{"type":"string","format":"date-time"},"updatedByUserId":{"type":"string","format":"uuid"}}},"RouteComputeRequest":{"type":"object","properties":{"ambulanceId":{"type":"string","format":"uuid"}}},"RouteResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"incidentId":{"type":"string","format":"uuid"},"ambulanceId":{"type":"string","format":"uuid"},"distanceKm":{"type":"number","format":"double"},"etaMinutes":{"type":"number","format":"double"},"provider":{"type":"string"},"routePolyline":{"type":"string"},"trafficLevel":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"DeviceReachabilitySubscriptionRequest":{"type":"object","properties":{"payloadJson":{"type":"string"}}},"QodSessionRequest":{"type":"object","properties":{"payloadJson":{"type":"string"}}},"QodCallResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"},"startedAt":{"type":"string","format":"date-time"},"endedAt":{"type":"string","format":"date-time"}}},"AiDispatchSuggestionResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"incidentId":{"type":"string","format":"uuid"},"suggestedAmbulanceId":{"type":"string","format":"uuid"},"suggestedResponderId":{"type":"string","format":"uuid"},"etaMinutes":{"type":"number","format":"double"},"reason":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"AiAssessmentApiResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"provider":{"type":"string"},"priorityScore":{"type":"number","format":"double"},"riskLevel":{"type":"string"},"summary":{"type":"string"},"reasoning":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"DispatchOverrideRequest":{"required":["ambulanceId","incidentId","reason","responderId"],"type":"object","properties":{"incidentId":{"type":"string","format":"uuid"},"responderId":{"type":"string","format":"uuid"},"ambulanceId":{"type":"string","format":"uuid"},"reason":{"type":"string"}}},"ResponderAssignmentResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"incidentId":{"type":"string","format":"uuid"},"responderId":{"type":"string","format":"uuid"},"ambulanceId":{"type":"string","format":"uuid"},"status":{"type":"string"},"notes":{"type":"string"},"assignedAt":{"type":"string","format":"date-time"},"acceptedAt":{"type":"string","format":"date-time"},"arrivedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"}}},"DispatchAssignRequest":{"required":["ambulanceId","incidentId","responderId"],"type":"object","properties":{"incidentId":{"type":"string","format":"uuid"},"responderId":{"type":"string","format":"uuid"},"ambulanceId":{"type":"string","format":"uuid"},"notes":{"type":"string"}}},"SignupRequest":{"required":["confirmPassword","email","name","organizationId","password"],"type":"object","properties":{"organizationId":{"type":"string","format":"uuid"},"name":{"maxLength":255,"minLength":0,"type":"string"},"email":{"maxLength":320,"minLength":0,"type":"string"},"phone":{"maxLength":50,"minLength":0,"type":"string"},"password":{"maxLength":100,"minLength":8,"type":"string"},"confirmPassword":{"maxLength":100,"minLength":8,"type":"string"}}},"LoginRequest":{"required":["email","password"],"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string"}}},"ForgotPasswordRequest":{"required":["email"],"type":"object","properties":{"email":{"type":"string"}}},"ChangePasswordRequest":{"required":["confirmPassword","currentPassword","newPassword"],"type":"object","properties":{"currentPassword":{"type":"string"},"newPassword":{"maxLength":100,"minLength":8,"type":"string"},"confirmPassword":{"maxLength":100,"minLength":8,"type":"string"}}},"PatchIncidentRequest":{"type":"object","properties":{"status":{"type":"string"},"priority":{"type":"integer","format":"int32"},"notes":{"type":"string"},"deviceReachable":{"type":"boolean"},"deviceStatus":{"type":"string"}}},"IncidentResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"referenceNo":{"type":"string"},"status":{"type":"string"},"priority":{"type":"integer","format":"int32"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"address":{"type":"string"},"aiSummary":{"type":"string"},"organizationId":{"type":"string","format":"uuid"},"citizenId":{"type":"string","format":"uuid"},"emergencyTypeId":{"type":"string","format":"uuid"},"emergencyTypeName":{"type":"string"}}},"TelecomRequestAuditResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"apiName":{"type":"string"},"status":{"type":"string"},"requestPayload":{"type":"string"},"requestedAt":{"type":"string","format":"date-time"},"responsePayload":{"type":"string"},"responseHttpCode":{"type":"string"}}},"IntegrationHealthResponse":{"type":"object","properties":{"checkedAt":{"type":"string","description":"When the snapshot was taken","format":"date-time"},"anthropic":{"$ref":"#/components/schemas/IntegrationServiceStatus"},"nokiaCamara":{"$ref":"#/components/schemas/IntegrationServiceStatus"},"minio":{"$ref":"#/components/schemas/IntegrationServiceStatus"}},"description":"Live checks for Anthropic, Nokia CAMARA, and S3/MinIO"},"IntegrationServiceStatus":{"type":"object","properties":{"id":{"type":"string","description":"anthropic | nokiaCamara | minio","example":"anthropic"},"status":{"type":"string","description":"UP = healthy, DOWN = error or misconfiguration, DISABLED = turned off in config","example":"UP"},"message":{"type":"string","description":"Human-readable detail"},"latencyMs":{"type":"integer","description":"Round-trip ms when valid","format":"int64"}},"description":"Status of one external integration"},"PageIncidentResponse":{"type":"object","properties":{"totalPages":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"pageable":{"$ref":"#/components/schemas/PageableObject"},"numberOfElements":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"content":{"type":"array","items":{"$ref":"#/components/schemas/IncidentResponse"}},"number":{"type":"integer","format":"int32"},"sort":{"$ref":"#/components/schemas/SortObject"},"first":{"type":"boolean"},"last":{"type":"boolean"},"empty":{"type":"boolean"}}},"PageableObject":{"type":"object","properties":{"paged":{"type":"boolean"},"pageSize":{"type":"integer","format":"int32"},"pageNumber":{"type":"integer","format":"int32"},"unpaged":{"type":"boolean"},"offset":{"type":"integer","format":"int64"},"sort":{"$ref":"#/components/schemas/SortObject"}}},"SortObject":{"type":"object","properties":{"sorted":{"type":"boolean"},"unsorted":{"type":"boolean"},"empty":{"type":"boolean"}}},"VerifiedProfileResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"msisdn":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"ageYears":{"type":"integer","format":"int32"},"kycProvider":{"type":"string"},"verifiedAt":{"type":"string","format":"date-time"}}}},"securitySchemes":{"bearerAuth":{"type":"http","description":"Enter your JWT token. Obtain it via POST /api/auth/login.","name":"bearerAuth","scheme":"bearer","bearerFormat":"JWT"}}}}