Implemented API success response audit
Source: registered handlers and generated api/openapi.yaml, audited 2026-10-23. Includes the staged professional catalog routes. The before column records the working tree at the start of this change.
155 Huma operations with implemented handlers (150 business API operations, including partially secured organization creation, and 5 development operations), 4 implemented legacy organization operations, and 7 partial notification operations are covered below. Another 73 Huma operations remain 501 stubs and are not included as implemented successes. Health and API document endpoints retain their protocol formats.
Standard response contract
Every implemented JSON success contains message (a route-appropriate string), status_code (the actual HTTP status), and data (an object or array). Paginated list queries additionally contain pagination; it is absent on other successes. Existing resource fields, authentication headers, and error responses retain their contracts.
{
"message": "Profile retrieved successfully.",
"status_code": 200,
"data": { "id": "..." }
}{
"message": "Advice suggestions retrieved successfully.",
"status_code": 200,
"data": [{ "id": "...", "label": "Rest" }],
"pagination": { "next_cursor": "..." }
}- Resource creation returns 201. Login, retrieval, updates, lifecycle actions, and deletion acknowledgments return 200. Email verification/recovery requests retain 202 and their account-independent message.
- Former 204 actions return 200 with
data: {}. Organization soft deletion retains its existing organization object. - Unpaginated collections, including active sessions and professional catalogs, use
data: []and no pagination. Empty lists contain[]. - Full pagination retains
next_cursor,current_page,per_page,total_pages, andtotal_items. Cursor-only queries expose onlynext_cursor; no totals are invented.next_cursoris an empty string on the last page. - Error responses remain unchanged (Huma problem details or the existing legacy errors). The 73 unimplemented operations retain their existing documentation-first contracts.
Client migration: read login tokens from data.access_token / data.refresh_token; read raw objects from data; replace items and sessions wrappers with the data array; read continuation from pagination.next_cursor; accept 200 JSON acknowledgments instead of 204. The checked-in Bruno clients follow this contract.
Route inventory
Every row's new outer structure is { message, status_code, data }, plus pagination when listed. The data column names the concrete schema in OpenAPI, whose definitions include nested fields, required fields, formats, and nullability. HTTP shows before → after where changed.
Authentication
| Method | Route | HTTP | Previous outer structure | New data schema | Pagination fields |
|---|---|---|---|---|---|
| POST | /api/v1/auth/email-verification | 202 | { message } | {} | — |
| POST | /api/v1/auth/email-verification/confirm | 204 → 200 | (empty body) | {} | — |
| POST | /api/v1/auth/login | 200 | { access_token, expires_in, refresh_token, token_type } | TokenPair | — |
| POST | /api/v1/auth/logout | 204 → 200 | (empty body) | {} | — |
| POST | /api/v1/auth/logout-all | 204 → 200 | (empty body) | {} | — |
| GET | /api/v1/auth/me | 200 | { avatar_url, created_at, email, email_verified, id, name, phone, status, updated_at } | User | — |
| PUT | /api/v1/auth/me | 200 | { avatar_url, created_at, email, email_verified, id, name, phone, status, updated_at } | User | — |
| PUT | /api/v1/auth/password | 204 → 200 | (empty body) | {} | — |
| POST | /api/v1/auth/password/forgot | 202 | { message } | {} | — |
| POST | /api/v1/auth/password/reset | 204 → 200 | (empty body) | {} | — |
| POST | /api/v1/auth/refresh | 200 | { access_token, expires_in, refresh_token, token_type } | TokenPair | — |
| POST | /api/v1/auth/register | 201 | { avatar_url, created_at, email, email_verified, id, name, phone, status, updated_at } | User | — |
| GET | /api/v1/auth/sessions | 200 | { sessions } | Session[] | — |
| DELETE | /api/v1/auth/sessions/{sessionId} | 204 → 200 | (empty body) | {} | — |
Admin
| Method | Route | HTTP | Previous outer structure | New data schema | Pagination fields |
|---|---|---|---|---|---|
| GET | /api/v1/admin/audit-events | 200 | { items, next_cursor } | AuditEventSummary[] | next_cursor |
| GET | /api/v1/admin/audit-events/{eventId} | 200 | { actor, changes, id, ip_address, metadata, name, occurred_at, operation_id, organization_id, reason, recorded_at, request_id, resource_id, resource_type, scope, source, user_agent, version } | AuditEvent | — |
| POST | /api/v1/admin/auth/login | 200 | { access_token, expires_in, refresh_token, token_type } | TokenPair | — |
| GET | /api/v1/admin/auth/verify | 200 | { admin_user_id, user_id } | AdminPrincipalDto | — |
| GET | /api/v1/admin/authorization/me | 200 | { effective_permissions, overrides, roles, scope, user_id, version } | MemberAuthorization | — |
| GET | /api/v1/admin/authorization/members/{userId} | 200 | { effective_permissions, overrides, roles, scope, user_id, version } | MemberAuthorization | — |
| DELETE | /api/v1/admin/authorization/members/{userId}/permissions/{permission}/{access} | 200 | { effective_permissions, overrides, roles, scope, user_id, version } | MemberAuthorization | — |
| PUT | /api/v1/admin/authorization/members/{userId}/permissions/{permission}/{access} | 200 | { effective_permissions, overrides, roles, scope, user_id, version } | MemberAuthorization | — |
| DELETE | /api/v1/admin/authorization/members/{userId}/roles/{roleId} | 200 | { effective_permissions, overrides, roles, scope, user_id, version } | MemberAuthorization | — |
| PUT | /api/v1/admin/authorization/members/{userId}/roles/{roleId} | 200 | { effective_permissions, overrides, roles, scope, user_id, version } | MemberAuthorization | — |
| GET | /api/v1/admin/authorization/permissions | 200 | Permission[] | Permission[] | — |
| GET | /api/v1/admin/authorization/roles | 200 | Role[] | Role[] | — |
| POST | /api/v1/admin/authorization/roles | 201 | { description, id, name, permissions, protected, slug, version } | Role | — |
| DELETE | /api/v1/admin/authorization/roles/{roleId} | 204 → 200 | (empty body) | {} | — |
| GET | /api/v1/admin/authorization/roles/{roleId} | 200 | { description, id, name, permissions, protected, slug, version } | Role | — |
| PUT | /api/v1/admin/authorization/roles/{roleId} | 200 | { description, id, name, permissions, protected, slug, version } | Role | — |
| PUT | /api/v1/admin/authorization/roles/{roleId}/permissions | 200 | { description, id, name, permissions, protected, slug, version } | Role | — |
| GET | /api/v1/admin/doctor-qualifications | 200 | { data, message, status_code } | CatalogEntry[] | — |
| POST | /api/v1/admin/doctor-qualifications | 201 | { data, message, status_code } | CatalogEntry | — |
| DELETE | /api/v1/admin/doctor-qualifications/{id} | 204 → 200 | (empty body) | {} | — |
| GET | /api/v1/admin/doctor-qualifications/{id} | 200 | { data, message, status_code } | CatalogEntry | — |
| PUT | /api/v1/admin/doctor-qualifications/{id} | 200 | { data, message, status_code } | CatalogEntry | — |
| GET | /api/v1/admin/doctor-specialties | 200 | { data, message, status_code } | CatalogEntry[] | — |
| POST | /api/v1/admin/doctor-specialties | 201 | { data, message, status_code } | CatalogEntry | — |
| DELETE | /api/v1/admin/doctor-specialties/{id} | 204 → 200 | (empty body) | {} | — |
| GET | /api/v1/admin/doctor-specialties/{id} | 200 | { data, message, status_code } | CatalogEntry | — |
| PUT | /api/v1/admin/doctor-specialties/{id} | 200 | { data, message, status_code } | CatalogEntry | — |
| GET | /api/v1/admin/doctor-specializations | 200 | { data, message, status_code } | CatalogEntry[] | — |
| POST | /api/v1/admin/doctor-specializations | 201 | { data, message, status_code } | CatalogEntry | — |
| DELETE | /api/v1/admin/doctor-specializations/{id} | 204 → 200 | (empty body) | {} | — |
| GET | /api/v1/admin/doctor-specializations/{id} | 200 | { data, message, status_code } | CatalogEntry | — |
| PUT | /api/v1/admin/doctor-specializations/{id} | 200 | { data, message, status_code } | CatalogEntry | — |
| GET | /api/v1/admin/doctors | 200 | { data, message, pagination, status_code } | DoctorListItemDto[] | current_page, next_cursor, per_page, total_items, total_pages |
| GET | /api/v1/admin/doctors/{doctorId} | 200 | { data, message, status_code } | DoctorGetDataDto | — |
| POST | /api/v1/admin/doctors/{doctorId}/activate | 200 | { data, message, status_code } | DoctorActivateDataDto | — |
| GET | /api/v1/admin/doctors/{doctorId}/organizations | 200 | { data, message, pagination, status_code } | DoctorOrganizationDataDto[] | current_page, next_cursor, per_page, total_items, total_pages |
| POST | /api/v1/admin/doctors/{doctorId}/suspend | 200 | { data, message, status_code } | DoctorSuspendDataDto | — |
| GET | /api/v1/admin/medicines/brands | 200 | { data, message, pagination, status_code } | AdminMedicineBrandListItemDto[] | current_page, next_cursor, per_page, total_items, total_pages |
| POST | /api/v1/admin/medicines/brands | 201 | { data, message, status_code } | AdminMedicineBrandCreateDataDto | — |
| DELETE | /api/v1/admin/medicines/brands/{id} | 204 → 200 | (empty body) | {} | — |
| GET | /api/v1/admin/medicines/brands/{id} | 200 | { data, message, status_code } | AdminMedicineBrandGetDataDto | — |
| PATCH | /api/v1/admin/medicines/brands/{id} | 200 | { data, message, status_code } | AdminMedicineBrandPatchDataDto | — |
| POST | /api/v1/admin/medicines/brands/{id}/restore | 200 | { data, message, status_code } | AdminMedicineBrandRestoreDataDto | — |
| GET | /api/v1/admin/medicines/drugs | 200 | { data, message, pagination, status_code } | AdminMedicineDrugListItemDto[] | current_page, next_cursor, per_page, total_items, total_pages |
| POST | /api/v1/admin/medicines/drugs | 201 | { data, message, status_code } | AdminMedicineDrugCreateDataDto | — |
| DELETE | /api/v1/admin/medicines/drugs/{id} | 204 → 200 | (empty body) | {} | — |
| GET | /api/v1/admin/medicines/drugs/{id} | 200 | { data, message, status_code } | AdminMedicineDrugGetDataDto | — |
| PATCH | /api/v1/admin/medicines/drugs/{id} | 200 | { data, message, status_code } | AdminMedicineDrugPatchDataDto | — |
| POST | /api/v1/admin/medicines/drugs/{id}/restore | 200 | { data, message, status_code } | AdminMedicineDrugRestoreDataDto | — |
| GET | /api/v1/admin/medicines/generics | 200 | { data, message, pagination, status_code } | AdminMedicineGenericListItemDto[] | current_page, next_cursor, per_page, total_items, total_pages |
| POST | /api/v1/admin/medicines/generics | 201 | { data, message, status_code } | AdminMedicineGenericCreateDataDto | — |
| DELETE | /api/v1/admin/medicines/generics/{id} | 204 → 200 | (empty body) | {} | — |
| GET | /api/v1/admin/medicines/generics/{id} | 200 | { data, message, status_code } | AdminMedicineGenericGetDataDto | — |
| PATCH | /api/v1/admin/medicines/generics/{id} | 200 | { data, message, status_code } | AdminMedicineGenericPatchDataDto | — |
| POST | /api/v1/admin/medicines/generics/{id}/restore | 200 | { data, message, status_code } | AdminMedicineGenericRestoreDataDto | — |
| GET | /api/v1/admin/medicines/manufacturers | 200 | { data, message, pagination, status_code } | AdminMedicineManufacturerListItemDto[] | current_page, next_cursor, per_page, total_items, total_pages |
| POST | /api/v1/admin/medicines/manufacturers | 201 | { data, message, status_code } | AdminMedicineManufacturerCreateDataDto | — |
| DELETE | /api/v1/admin/medicines/manufacturers/{id} | 204 → 200 | (empty body) | {} | — |
| GET | /api/v1/admin/medicines/manufacturers/{id} | 200 | { data, message, status_code } | AdminMedicineManufacturerGetDataDto | — |
| PATCH | /api/v1/admin/medicines/manufacturers/{id} | 200 | { data, message, status_code } | AdminMedicineManufacturerPatchDataDto | — |
| POST | /api/v1/admin/medicines/manufacturers/{id}/restore | 200 | { data, message, status_code } | AdminMedicineManufacturerRestoreDataDto | — |
| GET | /api/v1/admin/organizations | 200 | { data, message, pagination, status_code } | OrgListItemDto[] | current_page, next_cursor, per_page, total_items, total_pages |
| POST | /api/v1/admin/organizations | 201 | { data, message, status_code } | OrgCreateDataDto | — |
| DELETE | /api/v1/admin/organizations/{organizationId} | 200 | { data, message, status_code } | OrgDeleteDataDto | — |
| GET | /api/v1/admin/organizations/{organizationId} | 200 | { data, message, status_code } | OrgGetDataDto | — |
| PUT | /api/v1/admin/organizations/{organizationId} | 200 | { data, message, status_code } | OrgUpdateDataDto | — |
| POST | /api/v1/admin/organizations/{organizationId}/activate | 200 | { data, message, status_code } | OrgActivateDataDto | — |
| POST | /api/v1/admin/organizations/{organizationId}/doctors | 200 | { data, message, status_code } | DoctorAffiliationDataDto[] | — |
| POST | /api/v1/admin/organizations/{organizationId}/members | 201 | { data, message, status_code } | OrgCreateMemberDataDto | — |
| POST | /api/v1/admin/organizations/{organizationId}/restore | 200 | { data, message, status_code } | OrgRestoreDataDto | — |
| GET | /api/v1/admin/organizations/{organizationId}/summary | 200 | { data, message, status_code } | OrganizationSummaryDataDto | — |
| POST | /api/v1/admin/organizations/{organizationId}/suspend | 200 | { data, message, status_code } | OrgSuspendDataDto | — |
| GET | /api/v1/admin/profile | 200 | { data, message, status_code } | AdminProfileDto | — |
| GET | /api/v1/admin/users | 200 | { items, next_cursor } | AdminUserDto[] | next_cursor |
| POST | /api/v1/admin/users | 201 | { created_at, email, email_verified, id, identity_status, name, status, updated_at, user_id } | AdminUserDto | — |
| GET | /api/v1/admin/users/{adminUserId} | 200 | { created_at, email, email_verified, id, identity_status, name, status, updated_at, user_id } | AdminUserDto | — |
| POST | /api/v1/admin/verifications | 201 | { data, message, status_code } | DoctorVerificationDataDto | — |
| GET | /api/v1/admin/verifications/pending | 200 | { data, message, pagination, status_code } | DoctorVerificationDataDto[] | next_cursor |
| GET | /api/v1/admin/verifications/{verificationId} | 200 | { data, message, status_code } | DoctorVerificationDataDto | — |
| POST | /api/v1/admin/verifications/{verificationId}/approve | 200 | { data, message, status_code } | DoctorVerificationDataDto | — |
| POST | /api/v1/admin/verifications/{verificationId}/reject | 200 | { data, message, status_code } | DoctorVerificationDataDto | — |
Doctor
| Method | Route | HTTP | Previous outer structure | New data schema | Pagination fields |
|---|---|---|---|---|---|
| POST | /api/v1/doctors/auth/login | 200 | { access_token, expires_in, refresh_token, token_type } | TokenPair | — |
| GET | /api/v1/doctors/auth/verify | 200 | { doctor, identity } | DoctorAuthVerifyDataDto | — |
| GET | /api/v1/doctors/profile | 200 | { data, message, status_code } | DoctorProfileDto | — |
| PUT | /api/v1/doctors/profile/professional-details | 200 | { data, message, status_code } | DoctorProfileDto | — |
| GET | /api/v1/doctors/qualifications | 200 | { items } | CatalogEntry[] | — |
| POST | /api/v1/doctors/register | 201 | { data, message, status_code } | RegistrationResult | — |
| GET | /api/v1/doctors/specialties | 200 | { items } | CatalogEntry[] | — |
| GET | /api/v1/doctors/specializations | 200 | { items } | CatalogEntry[] | — |
Organization
| Method | Route | HTTP | Previous outer structure | New data schema | Pagination fields |
|---|---|---|---|---|---|
| POST | /api/v1/organizations/auth/login | 200 | { access_token, expires_in, refresh_token, token_type } | TokenPair | — |
| GET | /api/v1/organizations/auth/verify | 200 | { data, message, status_code } | OrgAuthVerifyDataDto | — |
| GET | /api/v1/organizations/profile | 200 | { data, message, status_code } | OrgProfileDto | — |
| GET | /api/v1/organizations/{organizationId}/audit-events | 200 | { items, next_cursor } | AuditEventSummary[] | next_cursor |
| GET | /api/v1/organizations/{organizationId}/audit-events/{eventId} | 200 | { actor, changes, id, ip_address, metadata, name, occurred_at, operation_id, organization_id, reason, recorded_at, request_id, resource_id, resource_type, scope, source, user_agent, version } | AuditEvent | — |
| GET | /api/v1/organizations/{organizationId}/authorization/me | 200 | { effective_permissions, overrides, roles, scope, user_id, version } | MemberAuthorization | — |
| GET | /api/v1/organizations/{organizationId}/authorization/members/{userId} | 200 | { effective_permissions, overrides, roles, scope, user_id, version } | MemberAuthorization | — |
| DELETE | /api/v1/organizations/{organizationId}/authorization/members/{userId}/permissions/{permission}/{access} | 200 | { effective_permissions, overrides, roles, scope, user_id, version } | MemberAuthorization | — |
| PUT | /api/v1/organizations/{organizationId}/authorization/members/{userId}/permissions/{permission}/{access} | 200 | { effective_permissions, overrides, roles, scope, user_id, version } | MemberAuthorization | — |
| DELETE | /api/v1/organizations/{organizationId}/authorization/members/{userId}/roles/{roleId} | 200 | { effective_permissions, overrides, roles, scope, user_id, version } | MemberAuthorization | — |
| PUT | /api/v1/organizations/{organizationId}/authorization/members/{userId}/roles/{roleId} | 200 | { effective_permissions, overrides, roles, scope, user_id, version } | MemberAuthorization | — |
| GET | /api/v1/organizations/{organizationId}/authorization/permissions | 200 | Permission[] | Permission[] | — |
| GET | /api/v1/organizations/{organizationId}/authorization/roles | 200 | Role[] | Role[] | — |
| POST | /api/v1/organizations/{organizationId}/authorization/roles | 201 | { description, id, name, permissions, protected, slug, version } | Role | — |
| DELETE | /api/v1/organizations/{organizationId}/authorization/roles/{roleId} | 204 → 200 | (empty body) | {} | — |
| GET | /api/v1/organizations/{organizationId}/authorization/roles/{roleId} | 200 | { description, id, name, permissions, protected, slug, version } | Role | — |
| PUT | /api/v1/organizations/{organizationId}/authorization/roles/{roleId} | 200 | { description, id, name, permissions, protected, slug, version } | Role | — |
| PUT | /api/v1/organizations/{organizationId}/authorization/roles/{roleId}/permissions | 200 | { description, id, name, permissions, protected, slug, version } | Role | — |
| GET | /api/v1/organizations/{organizationId}/doctors | 200 | { data, message, pagination, status_code } | OrganizationDoctorItem[] | current_page, next_cursor, per_page, total_items, total_pages |
Medicine
| Method | Route | HTTP | Previous outer structure | New data schema | Pagination fields |
|---|---|---|---|---|---|
| GET | /api/v1/medicines/brands | 200 | { data, message, pagination, status_code } | MedicineBrandListItemDto[] | current_page, next_cursor, per_page, total_items, total_pages |
| GET | /api/v1/medicines/brands/{id} | 200 | { data, message, status_code } | MedicineBrandGetDataDto | — |
| GET | /api/v1/medicines/drugs | 200 | { data, message, pagination, status_code } | MedicineDrugListItemDto[] | current_page, next_cursor, per_page, total_items, total_pages |
| GET | /api/v1/medicines/drugs/{id} | 200 | { data, message, status_code } | MedicineDrugGetDataDto | — |
| GET | /api/v1/medicines/generics | 200 | { data, message, pagination, status_code } | MedicineGenericListItemDto[] | current_page, next_cursor, per_page, total_items, total_pages |
| GET | /api/v1/medicines/generics/{id} | 200 | { data, message, status_code } | MedicineGenericGetDataDto | — |
| GET | /api/v1/medicines/manufacturers | 200 | { data, message, pagination, status_code } | MedicineManufacturerListItemDto[] | current_page, next_cursor, per_page, total_items, total_pages |
| GET | /api/v1/medicines/manufacturers/{id} | 200 | { data, message, status_code } | MedicineManufacturerGetDataDto | — |
Prescription suggestions
| Method | Route | HTTP | Previous outer structure | New data schema | Pagination fields |
|---|---|---|---|---|---|
| GET | /api/v1/prescriptions/suggestions/advice | 200 | { items, next_cursor } | SuggestionAdvice[] | next_cursor |
| POST | /api/v1/prescriptions/suggestions/advice | 201 | { id, label } | SuggestionAdvice | — |
| DELETE | /api/v1/prescriptions/suggestions/advice/{suggestionAdviceId} | 204 → 200 | (empty body) | {} | — |
| GET | /api/v1/prescriptions/suggestions/advice/{suggestionAdviceId} | 200 | { id, label } | SuggestionAdvice | — |
| PATCH | /api/v1/prescriptions/suggestions/advice/{suggestionAdviceId} | 200 | { id, label } | SuggestionAdvice | — |
| GET | /api/v1/prescriptions/suggestions/diagnosis | 200 | { items, next_cursor } | SuggestionDiagnosis[] | next_cursor |
| POST | /api/v1/prescriptions/suggestions/diagnosis | 201 | { id, label } | SuggestionDiagnosis | — |
| DELETE | /api/v1/prescriptions/suggestions/diagnosis/{suggestionDiagnosisId} | 204 → 200 | (empty body) | {} | — |
| GET | /api/v1/prescriptions/suggestions/diagnosis/{suggestionDiagnosisId} | 200 | { id, label } | SuggestionDiagnosis | — |
| PATCH | /api/v1/prescriptions/suggestions/diagnosis/{suggestionDiagnosisId} | 200 | { id, label } | SuggestionDiagnosis | — |
| GET | /api/v1/prescriptions/suggestions/investigation | 200 | { items, next_cursor } | SuggestionInvestigation[] | next_cursor |
| POST | /api/v1/prescriptions/suggestions/investigation | 201 | { id, label } | SuggestionInvestigation | — |
| DELETE | /api/v1/prescriptions/suggestions/investigation/{suggestionInvestigationId} | 204 → 200 | (empty body) | {} | — |
| GET | /api/v1/prescriptions/suggestions/investigation/{suggestionInvestigationId} | 200 | { id, label } | SuggestionInvestigation | — |
| PATCH | /api/v1/prescriptions/suggestions/investigation/{suggestionInvestigationId} | 200 | { id, label } | SuggestionInvestigation | — |
Development
| Method | Route | HTTP | Previous outer structure | New data schema | Pagination fields |
|---|---|---|---|---|---|
| POST | /development/clean | 200 | { message } | {} | — |
| POST | /development/migrations/apply-all | 200 | { message } | {} | — |
| GET | /development/migrations/status | 200 | { migrations } | MigrationStatus[] | — |
| POST | /development/reset-database | 200 | { message } | {} | — |
| POST | /development/seed | 200 | { accounts, items } | SeedResult | — |
Legacy organization handlers
These handlers are mounted outside Huma and do not appear in its generated OpenAPI document. Paths below are the API server paths.
| Method | Route | HTTP | Previous body | New data | Pagination |
|---|---|---|---|---|---|
| DELETE | /api/v1/organizations/{organizationId}/members/{memberId} | 204 → 200 | Empty | {} | — |
| POST | /api/v1/organizations/{organizationId}/activate | 200 | { status: "active_context_set" } | { status: "active_context_set" } | — |
| POST | /api/v1/organizations/{organizationId}/teams | 201 | Team object | Team object | — |
| GET | /api/v1/organizations/{organizationId}/teams | 200 | Team array | Team array | — |
Team fields: id, organization_id, name, description, created_at, updated_at.
Partial notification handlers
All have the standard success envelope in their service HTTP adapter. Existing limitations remain: in-memory storage, no authentication, stub delivery, and the API mount does not strip its prefix. This prevents intended dispatch to nested handlers; these are not reported as fully working API-server routes.
| Method | Intended API path | HTTP | Previous body / new data | Pagination |
|---|---|---|---|---|
| POST | /api/v1/notifications/send | 201 | Notification object | — |
| GET | /api/v1/notifications/ | 200 | Notification array | — |
| GET | /api/v1/notifications/{id} | 200 | Notification object | — |
| POST | /api/v1/notifications/templates | 201 | Template object | — |
| GET | /api/v1/notifications/templates | 200 | Template array | — |
| GET | /api/v1/notifications/templates/{id} | 200 | Template object | — |
| PUT | /api/v1/notifications/templates/{id} | 200 | Template object | — |
Notification fields: id, channel, recipient, template_id, subject, body, variables?, status, error?, created_at, sent_at?.
Template fields: id, name, channel, subject, body, variables, is_active, created_at, updated_at.
Data object field reference
Fields marked ? are optional. Types and nested definitions are in OpenAPI. Each array in the route inventory contains the corresponding object below. Empty acknowledgement data is {}.
| Data object schema | Fields |
|---|---|
AdminMedicineBrandCreateDataDto | created_at: string, deleted_at?: string, description?: string, generic_id: string, id: string, manufacturer_id: string, name: string, status: string, updated_at: string |
AdminMedicineBrandGetDataDto | created_at: string, deleted_at?: string, description?: string, generic_id: string, id: string, manufacturer_id: string, name: string, status: string, updated_at: string |
AdminMedicineBrandListItemDto | created_at: string, deleted_at?: string, description?: string, generic_id: string, id: string, manufacturer_id: string, name: string, status: string, updated_at: string |
AdminMedicineBrandPatchDataDto | created_at: string, deleted_at?: string, description?: string, generic_id: string, id: string, manufacturer_id: string, name: string, status: string, updated_at: string |
AdminMedicineBrandRestoreDataDto | created_at: string, deleted_at?: string, description?: string, generic_id: string, id: string, manufacturer_id: string, name: string, status: string, updated_at: string |
AdminMedicineDrugCreateDataDto | brand: AdminMedicineDrugCreateSummaryDto, brand_id: string, created_at: string, deleted_at?: string, description?: string, form: string, generic: AdminMedicineDrugCreateSummaryDto, id: string, manufacturer: AdminMedicineDrugCreateSummaryDto, status: string, strength: string, updated_at: string |
AdminMedicineDrugGetDataDto | brand: AdminMedicineDrugGetSummaryDto, brand_id: string, created_at: string, deleted_at?: string, description?: string, form: string, generic: AdminMedicineDrugGetSummaryDto, id: string, manufacturer: AdminMedicineDrugGetSummaryDto, status: string, strength: string, updated_at: string |
AdminMedicineDrugListItemDto | brand: AdminMedicineDrugListSummaryDto, brand_id: string, created_at: string, deleted_at?: string, description?: string, form: string, generic: AdminMedicineDrugListSummaryDto, id: string, manufacturer: AdminMedicineDrugListSummaryDto, status: string, strength: string, updated_at: string |
AdminMedicineDrugPatchDataDto | brand: AdminMedicineDrugPatchSummaryDto, brand_id: string, created_at: string, deleted_at?: string, description?: string, form: string, generic: AdminMedicineDrugPatchSummaryDto, id: string, manufacturer: AdminMedicineDrugPatchSummaryDto, status: string, strength: string, updated_at: string |
AdminMedicineDrugRestoreDataDto | brand: AdminMedicineDrugRestoreSummaryDto, brand_id: string, created_at: string, deleted_at?: string, description?: string, form: string, generic: AdminMedicineDrugRestoreSummaryDto, id: string, manufacturer: AdminMedicineDrugRestoreSummaryDto, status: string, strength: string, updated_at: string |
AdminMedicineGenericCreateDataDto | created_at: string, deleted_at?: string, description?: string, id: string, name: string, status: string, updated_at: string |
AdminMedicineGenericGetDataDto | created_at: string, deleted_at?: string, description?: string, id: string, name: string, status: string, updated_at: string |
AdminMedicineGenericListItemDto | created_at: string, deleted_at?: string, description?: string, id: string, name: string, status: string, updated_at: string |
AdminMedicineGenericPatchDataDto | created_at: string, deleted_at?: string, description?: string, id: string, name: string, status: string, updated_at: string |
AdminMedicineGenericRestoreDataDto | created_at: string, deleted_at?: string, description?: string, id: string, name: string, status: string, updated_at: string |
AdminMedicineManufacturerCreateDataDto | created_at: string, deleted_at?: string, description?: string, id: string, name: string, status: string, updated_at: string |
AdminMedicineManufacturerGetDataDto | created_at: string, deleted_at?: string, description?: string, id: string, name: string, status: string, updated_at: string |
AdminMedicineManufacturerListItemDto | created_at: string, deleted_at?: string, description?: string, id: string, name: string, status: string, updated_at: string |
AdminMedicineManufacturerPatchDataDto | created_at: string, deleted_at?: string, description?: string, id: string, name: string, status: string, updated_at: string |
AdminMedicineManufacturerRestoreDataDto | created_at: string, deleted_at?: string, description?: string, id: string, name: string, status: string, updated_at: string |
AdminPrincipalDto | admin_user_id: string, user_id: string |
AdminProfileDto | created_at: string, email: string, email_verified: boolean, id: string, name: string, permissions: EffectivePermission[], profile: AdminProfileDetailsDto, roles: AdminProfileRoleDto[], status: string, updated_at: string |
AdminUserDto | created_at: string, email: string, email_verified: boolean, id: string, identity_status: string, name: string, status: string, updated_at: string, user_id: string |
AuditEvent | actor: AuditActor, changes: object, id: string, ip_address?: string, metadata: {}, name: string, occurred_at: string, operation_id: string, organization_id?: string, reason?: string, recorded_at: string, request_id: string, resource_id: string, resource_type: string, scope: AuditScope, source: string, user_agent?: string, version: integer |
AuditEventSummary | actor: AuditActor, id: string, name: string, occurred_at: string, operation_id: string, organization_id?: string, recorded_at: string, request_id: string, resource_id: string, resource_type: string, scope: AuditScope, source: string, version: integer |
CatalogEntry | created_at: string, description: string, id: string, name: string, speciality_id?: string, updated_at: string |
DoctorActivateDataDto | account_status: string, chambers: DoctorChamberDto[], created_at: string, email: string, email_verified: boolean, id: string, ineligible_reason?: string/null, is_assigned?: boolean, is_eligible?: boolean, license_number: string, name: string, organizations: DoctorAffiliationDataDto[], qualification: string, qualifications: CatalogEntry[], speciality: CatalogEntry, specialization: CatalogEntry[], updated_at: string, user_id: string, verification?: DoctorVerificationDataDto, verification_status: string |
DoctorAffiliationDataDto | assigned_at: string, assigned_by_user_id: string/null, assignment_source: string, created_at: string, doctor_id: string, id: string, joined_at: string, organization_id: string, organization_name: string, organization_slug: string, organization_status: string, organization_type: string/null, status: string, updated_at: string |
DoctorAuthVerifyDataDto | doctor: Profile, identity: Account |
DoctorGetDataDto | account_status: string, chambers: DoctorChamberDto[], created_at: string, email: string, email_verified: boolean, id: string, ineligible_reason?: string/null, is_assigned?: boolean, is_eligible?: boolean, license_number: string, name: string, organizations: DoctorAffiliationDataDto[], qualification: string, qualifications: CatalogEntry[], speciality: CatalogEntry, specialization: CatalogEntry[], updated_at: string, user_id: string, verification?: DoctorVerificationDataDto, verification_status: string |
DoctorListItemDto | account_status: string, chambers: DoctorChamberDto[], created_at: string, email: string, email_verified: boolean, id: string, ineligible_reason?: string/null, is_assigned?: boolean, is_eligible?: boolean, license_number: string, name: string, organizations: DoctorAffiliationDataDto[], qualification: string, qualifications: CatalogEntry[], speciality: CatalogEntry, specialization: CatalogEntry[], updated_at: string, user_id: string, verification?: DoctorVerificationDataDto, verification_status: string |
DoctorOrganizationDataDto | assigned_at: string, assigned_by_user_id: string/null, assignment_source: string, billing_is_mock: boolean, created_at: string, doctor_id: string, id: string, joined_at: string, organization_id: string, organization_name: string, organization_slug: string, organization_status: string, organization_type: string/null, plan: CompactPlan, status: string, subscription_status: string/null, updated_at: string |
DoctorProfileDto | created_at: string, email: string, email_verified: boolean, id: string, name: string, profile: DoctorProfileDetailsDto, status: string, updated_at: string |
DoctorSuspendDataDto | account_status: string, chambers: DoctorChamberDto[], created_at: string, email: string, email_verified: boolean, id: string, ineligible_reason?: string/null, is_assigned?: boolean, is_eligible?: boolean, license_number: string, name: string, organizations: DoctorAffiliationDataDto[], qualification: string, qualifications: CatalogEntry[], speciality: CatalogEntry, specialization: CatalogEntry[], updated_at: string, user_id: string, verification?: DoctorVerificationDataDto, verification_status: string |
DoctorVerificationDataDto | created_at: string, doctor_id: string, doctor_name: string, documents: string[], id: string, license_number: string, notes: string, rejection_reason?: string, reviewed_at?: string, reviewed_by?: string, specialization: string, status: string, updated_at: string, user_id: string |
MedicineBrandGetDataDto | created_at: string, deleted_at?: string, description?: string, generic_id: string, id: string, manufacturer_id: string, name: string, status: string, updated_at: string |
MedicineBrandListItemDto | created_at: string, deleted_at?: string, description?: string, generic_id: string, id: string, manufacturer_id: string, name: string, status: string, updated_at: string |
MedicineDrugGetDataDto | brand: MedicineDrugGetSummaryDto, brand_id: string, created_at: string, deleted_at?: string, description?: string, form: string, generic: MedicineDrugGetSummaryDto, id: string, manufacturer: MedicineDrugGetSummaryDto, status: string, strength: string, updated_at: string |
MedicineDrugListItemDto | brand: MedicineDrugListSummaryDto, brand_id: string, created_at: string, deleted_at?: string, description?: string, form: string, generic: MedicineDrugListSummaryDto, id: string, manufacturer: MedicineDrugListSummaryDto, status: string, strength: string, updated_at: string |
MedicineGenericGetDataDto | created_at: string, deleted_at?: string, description?: string, id: string, name: string, status: string, updated_at: string |
MedicineGenericListItemDto | created_at: string, deleted_at?: string, description?: string, id: string, name: string, status: string, updated_at: string |
MedicineManufacturerGetDataDto | created_at: string, deleted_at?: string, description?: string, id: string, name: string, status: string, updated_at: string |
MedicineManufacturerListItemDto | created_at: string, deleted_at?: string, description?: string, id: string, name: string, status: string, updated_at: string |
MemberAuthorization | effective_permissions: EffectivePermission[], overrides: PermissionOverride[], roles: Role[], scope: Scope, user_id: string, version: integer |
MigrationStatus | path: string, service: string, state: string, version: integer |
OrgActivateDataDto | address: string, created_at: string, description: string, email: string, id: string, name: string, phone: string, slug: string, status: string, updated_at: string |
OrgAuthVerifyDataDto | identity: OrgAuthVerifyIdentityDto, member: OrgAuthVerifyMemberDto, organization: OrgAuthVerifyOrganizationDto |
OrgCreateDataDto | address: string, billing_cycle: string/null, billing_is_mock: boolean, created_at: string, description: string, doctor_count: integer, doctor_limit: integer/null, email: string, id: string, name: string, phone: string, plan: CompactPlan, seat_limit: integer/null, slug: string, status: string, subscription_status: string/null, type: string/null, updated_at: string, used_seats: integer |
OrgCreateMemberDataDto | identity: OrgCreateMemberIdentityDto, member: OrgCreateMemberMemberDto |
OrgDeleteDataDto | address: string, created_at: string, description: string, email: string, id: string, name: string, phone: string, slug: string, status: string, updated_at: string |
OrgGetDataDto | address: string, billing_cycle: string/null, billing_is_mock: boolean, created_at: string, description: string, doctor_count: integer, doctor_limit: integer/null, email: string, id: string, name: string, phone: string, plan: CompactPlan, seat_limit: integer/null, slug: string, status: string, subscription_status: string/null, type: string/null, updated_at: string, used_seats: integer |
OrgListItemDto | address: string, billing_cycle: string/null, billing_is_mock: boolean, created_at: string, description: string, doctor_count: integer, doctor_limit: integer/null, email: string, id: string, name: string, phone: string, plan: CompactPlan, seat_limit: integer/null, slug: string, status: string, subscription_status: string/null, type: string/null, updated_at: string, used_seats: integer |
OrgProfileDto | created_at: string, email: string, email_verified: boolean, id: string, name: string, organization: Organization, permissions: EffectivePermission[], profile: OrgProfileDetailsDto, roles: OrgProfileRoleDto[], status: string, updated_at: string |
OrgRestoreDataDto | address: string, created_at: string, description: string, email: string, id: string, name: string, phone: string, slug: string, status: string, updated_at: string |
OrgSuspendDataDto | address: string, created_at: string, description: string, email: string, id: string, name: string, phone: string, slug: string, status: string, updated_at: string |
OrgUpdateDataDto | address: string, billing_cycle: string/null, billing_is_mock: boolean, created_at: string, description: string, doctor_count: integer, doctor_limit: integer/null, email: string, id: string, name: string, phone: string, plan: CompactPlan, seat_limit: integer/null, slug: string, status: string, subscription_status: string/null, type: string/null, updated_at: string, used_seats: integer |
OrganizationDoctorItem | assigned_at: string, assigned_by_user_id: string/null, assignment_source: string, created_at: string, doctor: OrganizationDoctor, doctor_id: string, id: string, joined_at: string, organization_id: string, organization_name: string, organization_slug: string, organization_status: string, organization_type: string/null, status: string, updated_at: string |
OrganizationSummaryDataDto | billing_is_mock: boolean, organization: OrganizationDataDto, subscription: Subscription, summary: OrganizationUsage |
Permission | action: string, key: string, resource: string, scope_type: string, supports_own: boolean |
RegistrationResult | affiliation?: DoctorAffiliation, doctor: Profile |
Role | description: string, id: string, name: string, permissions: PermissionGrant[], protected: boolean, slug: string, version: integer |
SeedResult | accounts: string[], items: string[] |
Session | created_at: string, current: boolean, device_name: string, device_type: string, expires_at: string, id: string, ip_address: string, last_active_at: string, user_agent: string |
SuggestionAdvice | id: string, label: string |
SuggestionDiagnosis | id: string, label: string |
SuggestionInvestigation | id: string, label: string |
TokenPair | access_token: string, expires_in: integer, refresh_token: string, token_type: string |
User | avatar_url: string, created_at: string, email: string, email_verified: boolean, id: string, name: string, phone: string, status: string, updated_at: string |
Protocol endpoints
| Method | Path | Success format |
|---|---|---|
| GET | /healthz | 200, plain text Ok |
| GET | /openapi.json, /openapi-3.0.json | OpenAPI JSON document |
| GET | /openapi.yaml, /openapi-3.0.yaml | OpenAPI YAML document |
| GET | /schemas/{schema} | JSON Schema document |
The standalone services/openapi documentation server serves Scalar HTML and the OpenAPI YAML asset directly. These endpoints are protocol documents, so the JSON application envelope does not apply.
Clinical input suggestions
Doctor requires an active doctor session; Admin requires clinical suggestion read/manage grants.
| Method | Path | Success |
|---|---|---|
| GET | /api/v1/doctors/suggestions/chief-complaints | 200, non-null choice array |
| GET | /api/v1/admin/suggestions/chief-complaints | 200, management page |
| GET | /api/v1/admin/suggestions/chief-complaints/{id} | 200, record |
| POST | /api/v1/admin/suggestions/chief-complaints | 201, record |
| PATCH | /api/v1/admin/suggestions/chief-complaints/{id} | 200, record |
| DELETE | /api/v1/admin/suggestions/chief-complaints/{id} | 200, empty object |
| GET | /api/v1/doctors/suggestions/history | 200, non-null choice array |
| GET | /api/v1/admin/suggestions/history | 200, management page |
| GET | /api/v1/admin/suggestions/history/{id} | 200, record |
| POST | /api/v1/admin/suggestions/history | 201, record |
| PATCH | /api/v1/admin/suggestions/history/{id} | 200, record |
| DELETE | /api/v1/admin/suggestions/history/{id} | 200, empty object |