{"openapi":"3.0.0","paths":{"/":{"get":{"operationId":"AppController_getRoot","parameters":[],"responses":{"200":{"description":""}},"tags":["App"]}},"/api/tenants":{"post":{"operationId":"TenantsController_createTenant","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTenantDto"}}}},"responses":{"201":{"description":"Tenant created successfully"}},"summary":"Create a new tenant workspace","tags":["Tenants"]}},"/api/tenants/{slug}":{"get":{"operationId":"TenantsController_getTenantBranding","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Tenant found"},"404":{"description":"Tenant not found"}},"summary":"Get tenant by slug (branding/bootstrap endpoint)","tags":["Tenants"]}},"/api/users":{"get":{"operationId":"UsersController_listUsers","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Users list returned"}},"security":[{"bearer":[]}],"summary":"List users in current tenant","tags":["Users"]}},"/api/auth/register":{"post":{"operationId":"AuthController_register","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for auth operations","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDto"}}}},"responses":{"201":{"description":"User registered and tokens issued"}},"summary":"Register a user in the current tenant","tags":["Authentication"]}},"/api/auth/login":{"post":{"operationId":"AuthController_login","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for auth operations","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginDto"}}}},"responses":{"200":{"description":"Login successful and tokens issued"},"401":{"description":"Invalid credentials"}},"summary":"Login with tenant-scoped credentials","tags":["Authentication"]}},"/api/auth/refresh":{"post":{"operationId":"AuthController_refresh","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for auth operations","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshTokenDto"}}}},"responses":{"200":{"description":"Tokens refreshed"}},"security":[{"bearer":[]}],"summary":"Rotate access/refresh tokens","tags":["Authentication"]}},"/api/auth/logout":{"post":{"operationId":"AuthController_logout","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for auth operations","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Logout successful"}},"security":[{"bearer":[]}],"summary":"Logout and invalidate refresh token","tags":["Authentication"]}},"/api/auth/password-reset/request":{"post":{"operationId":"AuthController_requestPasswordReset","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for auth operations","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestPasswordResetDto"}}}},"responses":{"200":{"description":"Password reset request accepted"}},"summary":"Request password reset token","tags":["Authentication"]}},"/api/auth/password-reset/confirm":{"post":{"operationId":"AuthController_resetPassword","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for auth operations","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordDto"}}}},"responses":{"200":{"description":"Password reset complete"}},"summary":"Reset password with token","tags":["Authentication"]}},"/api/auth/email-verification/request":{"post":{"operationId":"AuthController_requestEmailVerification","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for auth operations","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Email verification request accepted"}},"security":[{"bearer":[]}],"summary":"Request email verification token for current user","tags":["Authentication"]}},"/api/auth/email-verification/confirm":{"post":{"operationId":"AuthController_verifyEmail","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for auth operations","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailDto"}}}},"responses":{"200":{"description":"Email verified"}},"summary":"Verify email with token","tags":["Authentication"]}},"/api/auth/sso/start":{"post":{"operationId":"AuthController_startSso","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for auth operations","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartSsoDto"}}}},"responses":{"201":{"description":"OIDC authorization URL generated"}},"summary":"Start OIDC login and return provider authorize URL (Phase 1 skeleton)","tags":["Authentication"]}},"/api/auth/sso/callback":{"post":{"operationId":"AuthController_completeSso","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for auth operations","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteSsoDto"}}}},"responses":{"201":{"description":"SSO completed; tokens issued"}},"summary":"Complete OIDC code exchange, resolve user in tenant, and issue API tokens","tags":["Authentication"]}},"/api/admin/api-keys":{"post":{"operationId":"AdminApiKeysController_create","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyDto"}}}},"responses":{"201":{"description":"API key created"}},"security":[{"bearer":[]}],"summary":"Create API key (secret returned once; store securely)","tags":["Admin — API keys"]},"get":{"operationId":"AdminApiKeysController_list","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"List active API keys (no secrets)","tags":["Admin — API keys"]}},"/api/admin/api-keys/{apiKeyId}":{"delete":{"operationId":"AdminApiKeysController_revoke","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"apiKeyId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Revoke an API key","tags":["Admin — API keys"]}},"/api/courses":{"post":{"operationId":"CoursesController_create","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCourseDto"}}}},"responses":{"201":{"description":"Course created"}},"security":[{"bearer":[]}],"summary":"Create a course with lessons","tags":["Courses"]},"get":{"operationId":"CoursesController_list","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Courses returned"}},"security":[{"bearer":[]}],"summary":"List courses for current tenant","tags":["Courses"]}},"/api/courses/{courseId}/enrollments":{"get":{"operationId":"CoursesController_listEnrollments","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"courseId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"List enrollments (roster) for a course","tags":["Courses"]}},"/api/courses/{courseId}/files":{"get":{"operationId":"CoursesController_listCourseFiles","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"courseId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"List uploaded course files (staff: any course; learners: published + active enrollment)","tags":["Courses"]},"post":{"description":"Optional query: lessonId (UUID) to associate the asset with a lesson in this course.","operationId":"CoursesController_uploadCourseFile","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"courseId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Upload a course material file (multipart field: file)","tags":["Courses"]}},"/api/courses/{courseId}/files/{fileId}":{"get":{"operationId":"CoursesController_downloadCourseFile","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"courseId","required":true,"in":"path","schema":{"type":"string"}},{"name":"fileId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Download a course file (same access rules as list)","tags":["Courses"]},"delete":{"operationId":"CoursesController_deleteCourseFile","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"courseId","required":true,"in":"path","schema":{"type":"string"}},{"name":"fileId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"File removed"}},"security":[{"bearer":[]}],"summary":"Remove a course file from storage and the catalog","tags":["Courses"]}},"/api/courses/{courseId}":{"get":{"operationId":"CoursesController_getOne","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"courseId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Get one course with ordered lessons","tags":["Courses"]},"patch":{"operationId":"CoursesController_update","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"courseId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCourseDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Update course title and/or description","tags":["Courses"]},"delete":{"operationId":"CoursesController_deletePermanent","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"courseId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Permanently delete a course (tenant admin only; must be archived first)","tags":["Courses"]}},"/api/courses/{courseId}/archive":{"patch":{"operationId":"CoursesController_archive","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"courseId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Archive a course","tags":["Courses"]}},"/api/courses/{courseId}/lessons":{"post":{"operationId":"CoursesController_addLesson","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"courseId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddLessonDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Add a lesson to a course","tags":["Courses"]}},"/api/courses/{courseId}/lessons/{lessonId}":{"patch":{"operationId":"CoursesController_updateLesson","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"courseId","required":true,"in":"path","schema":{"type":"string"}},{"name":"lessonId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLessonDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Update lesson title and/or content","tags":["Courses"]},"delete":{"operationId":"CoursesController_deleteLesson","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"courseId","required":true,"in":"path","schema":{"type":"string"}},{"name":"lessonId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Delete a lesson from a course","tags":["Courses"]}},"/api/courses/{courseId}/publish":{"patch":{"operationId":"CoursesController_publish","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"courseId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Course published"}},"security":[{"bearer":[]}],"summary":"Publish a draft course","tags":["Courses"]}},"/api/enrollments":{"post":{"operationId":"EnrollmentsController_enroll","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrollUserDto"}}}},"responses":{"201":{"description":"Enrollment created or reactivated"}},"security":[{"bearer":[]}],"summary":"Enroll a user in a course","tags":["Enrollments"]}},"/api/enrollments/me":{"get":{"operationId":"EnrollmentsController_myEnrollments","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Enrollments returned"}},"security":[{"bearer":[]}],"summary":"Get current user enrollments","tags":["Enrollments"]}},"/api/enrollments/{enrollmentId}":{"delete":{"operationId":"EnrollmentsController_drop","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"enrollmentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Drop enrollment (DROPPED). Learners only their own; staff any in tenant.","tags":["Enrollments"]}},"/api/enrollments/{enrollmentId}/complete":{"patch":{"operationId":"EnrollmentsController_markCompleted","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"enrollmentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Mark enrollment as completed (instructor or tenant admin)","tags":["Enrollments"]}},"/api/admin/webhooks/endpoints":{"post":{"operationId":"AdminWebhooksController_createEndpoint","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookEndpointDto"}}}},"responses":{"201":{"description":"Endpoint created"}},"security":[{"bearer":[]}],"summary":"Register an outbound webhook URL (signing secret returned once)","tags":["Admin — Webhooks"]},"get":{"operationId":"AdminWebhooksController_listEndpoints","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"List webhook endpoints for the tenant","tags":["Admin — Webhooks"]}},"/api/admin/webhooks/endpoints/{endpointId}":{"get":{"operationId":"AdminWebhooksController_getEndpoint","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"endpointId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Get one webhook endpoint (no secret)","tags":["Admin — Webhooks"]},"patch":{"operationId":"AdminWebhooksController_updateEndpoint","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"endpointId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookEndpointDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Update webhook endpoint","tags":["Admin — Webhooks"]},"delete":{"operationId":"AdminWebhooksController_deleteEndpoint","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"endpointId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Delete webhook endpoint","tags":["Admin — Webhooks"]}},"/api/admin/webhooks/deliveries":{"get":{"operationId":"AdminWebhooksController_listDeliveries","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"skip","required":true,"in":"query","schema":{"type":"number"}},{"name":"take","required":true,"in":"query","schema":{"type":"number"}},{"name":"status","required":true,"in":"query","schema":{"type":"string"}},{"name":"eventType","required":true,"in":"query","schema":{"type":"string"}},{"name":"endpointId","required":true,"in":"query","schema":{"type":"string"}},{"name":"from","required":true,"in":"query","schema":{"type":"string"}},{"name":"to","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"List webhook delivery attempts (paginated; optional filters)","tags":["Admin — Webhooks"]}},"/api/progress/lessons":{"post":{"operationId":"ProgressController_completeLesson","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteLessonDto"}}}},"responses":{"201":{"description":"Progress upserted"}},"security":[{"bearer":[]}],"summary":"Mark lesson completion state for current user","tags":["Progress"]}},"/api/progress/me":{"get":{"operationId":"ProgressController_myProgress","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Progress records returned"}},"security":[{"bearer":[]}],"summary":"Get current user lesson progress","tags":["Progress"]}},"/api/assessments":{"post":{"operationId":"AssessmentsController_create","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAssessmentDto"}}}},"responses":{"201":{"description":"Assessment created"}},"security":[{"bearer":[]}],"summary":"Create quiz assessment for a course","tags":["Assessments"]}},"/api/assessments/submit":{"post":{"operationId":"AssessmentsController_submit","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitAssessmentDto"}}}},"responses":{"201":{"description":"Attempt scored and stored"}},"security":[{"bearer":[]}],"summary":"Submit quiz answers and calculate score","tags":["Assessments"]}},"/api/certifications/me":{"get":{"operationId":"CertificationsController_myCertifications","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Certifications returned"}},"security":[{"bearer":[]}],"summary":"List certifications for current user","tags":["Certifications"]}},"/api/admin/groups":{"post":{"operationId":"AdminGroupsController_create","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLearnerGroupDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Create a learner cohort / group","tags":["Admin — Learner groups"]},"get":{"operationId":"AdminGroupsController_list","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"List learner groups (with member counts)","tags":["Admin — Learner groups"]}},"/api/admin/groups/{groupId}":{"get":{"operationId":"AdminGroupsController_getOne","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"groupId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Get one learner group","tags":["Admin — Learner groups"]},"patch":{"operationId":"AdminGroupsController_update","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"groupId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLearnerGroupDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Update learner group name or description","tags":["Admin — Learner groups"]},"delete":{"operationId":"AdminGroupsController_remove","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"groupId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Delete learner group and all memberships","tags":["Admin — Learner groups"]}},"/api/admin/groups/{groupId}/members":{"get":{"operationId":"AdminGroupsController_listMembers","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"groupId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"List members of a learner group","tags":["Admin — Learner groups"]},"post":{"operationId":"AdminGroupsController_addMember","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"groupId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddLearnerGroupMemberDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Add a tenant user to the group","tags":["Admin — Learner groups"]}},"/api/admin/groups/{groupId}/members/{userId}":{"delete":{"operationId":"AdminGroupsController_removeMember","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"groupId","required":true,"in":"path","schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Remove a user from the group","tags":["Admin — Learner groups"]}},"/api/admin/learning-paths":{"post":{"operationId":"AdminLearningPathsController_create","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLearningPathDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Create a learning path (optional ordered courseIds)","tags":["Admin — Learning paths"]},"get":{"operationId":"AdminLearningPathsController_list","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"List learning paths (with course counts)","tags":["Admin — Learning paths"]}},"/api/admin/learning-paths/{pathId}":{"get":{"operationId":"AdminLearningPathsController_getOne","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"pathId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Get one learning path with ordered courses","tags":["Admin — Learning paths"]},"patch":{"operationId":"AdminLearningPathsController_update","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"pathId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLearningPathDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Update learning path name or description","tags":["Admin — Learning paths"]},"delete":{"operationId":"AdminLearningPathsController_remove","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"pathId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Delete learning path and its course links","tags":["Admin — Learning paths"]}},"/api/admin/learning-paths/{pathId}/courses":{"put":{"operationId":"AdminLearningPathsController_setCourses","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"pathId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetLearningPathCoursesDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Replace ordered courses in the path (full list each time)","tags":["Admin — Learning paths"]}},"/api/scim/v2/ServiceProviderConfig":{"get":{"operationId":"ScimController_getServiceProviderConfig","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for SCIM provisioning","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"SCIM service provider capabilities","tags":["SCIM"]}},"/api/scim/v2/ResourceTypes":{"get":{"operationId":"ScimController_getResourceTypes","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for SCIM provisioning","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"SCIM resource types supported by this service","tags":["SCIM"]}},"/api/scim/v2/Schemas":{"get":{"operationId":"ScimController_getSchemas","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for SCIM provisioning","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"SCIM schemas supported by this service","tags":["SCIM"]}},"/api/scim/v2/Users":{"get":{"operationId":"ScimController_listUsers","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for SCIM provisioning","required":true,"schema":{"type":"string"}},{"name":"startIndex","required":true,"in":"query","schema":{"type":"string"}},{"name":"count","required":true,"in":"query","schema":{"type":"string"}},{"name":"filter","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"SCIM list users (tenant scoped)","tags":["SCIM"]},"post":{"operationId":"ScimController_createUser","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for SCIM provisioning","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"SCIM user created"}},"summary":"SCIM create user (tenant scoped)","tags":["SCIM"]}},"/api/scim/v2/Users/{userId}":{"get":{"operationId":"ScimController_getUser","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for SCIM provisioning","required":true,"schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"SCIM get user by id","tags":["SCIM"]},"patch":{"operationId":"ScimController_patchUser","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for SCIM provisioning","required":true,"schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"SCIM patch user","tags":["SCIM"]},"delete":{"operationId":"ScimController_deleteUser","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for SCIM provisioning","required":true,"schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"SCIM deactivate user (soft delete)","tags":["SCIM"]}},"/api/scim/v2/Groups":{"get":{"operationId":"ScimController_listGroups","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for SCIM provisioning","required":true,"schema":{"type":"string"}},{"name":"startIndex","required":true,"in":"query","schema":{"type":"string"}},{"name":"count","required":true,"in":"query","schema":{"type":"string"}},{"name":"filter","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"SCIM list groups (tenant scoped)","tags":["SCIM"]},"post":{"operationId":"ScimController_createGroup","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for SCIM provisioning","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"SCIM create group (tenant scoped)","tags":["SCIM"]}},"/api/scim/v2/Groups/{groupId}":{"get":{"operationId":"ScimController_getGroup","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for SCIM provisioning","required":true,"schema":{"type":"string"}},{"name":"groupId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"SCIM get group by id","tags":["SCIM"]},"patch":{"operationId":"ScimController_patchGroup","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for SCIM provisioning","required":true,"schema":{"type":"string"}},{"name":"groupId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"SCIM patch group (displayName/members)","tags":["SCIM"]},"delete":{"operationId":"ScimController_deleteGroup","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context for SCIM provisioning","required":true,"schema":{"type":"string"}},{"name":"groupId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"SCIM delete group","tags":["SCIM"]}},"/api/health":{"get":{"operationId":"HealthController_check","parameters":[],"responses":{"200":{"description":"The Health Check is successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}},"503":{"description":"The Health Check is not successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"error"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"},"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}}},"summary":"Readiness and health check endpoint","tags":["Health"]}},"/api/admin/users/bulk":{"post":{"operationId":"AdminController_bulkCreateUsers","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminBulkUsersDto"}}}},"responses":{"201":{"description":"Bulk import result"}},"security":[{"bearer":[]}],"summary":"Bulk create users (max 100; skips duplicates with reasons)","tags":["Admin"]}},"/api/admin/export/users":{"get":{"operationId":"AdminController_exportUsers","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Export tenant users as CSV download","tags":["Admin"]}},"/api/admin/users":{"post":{"operationId":"AdminController_createUser","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCreateUserDto"}}}},"responses":{"201":{"description":"User created"}},"security":[{"bearer":[]}],"summary":"Admin create user in tenant","tags":["Admin"]}},"/api/admin/users/{userId}/role":{"patch":{"operationId":"AdminController_updateUserRole","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminUpdateUserRoleDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Admin change user role","tags":["Admin"]}},"/api/admin/users/{userId}/status":{"patch":{"operationId":"AdminController_updateUserStatus","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminUpdateUserStatusDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Admin activate or deactivate user","tags":["Admin"]}},"/api/admin/tenant/settings":{"patch":{"operationId":"AdminController_updateTenantSettings","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminUpdateTenantSettingsDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Admin update tenant profile settings","tags":["Admin"]}},"/api/admin/audit-logs":{"get":{"operationId":"AdminController_listAuditLogs","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"skip","required":true,"in":"query","schema":{"type":"number"}},{"name":"take","required":true,"in":"query","schema":{"type":"number"}},{"name":"action","required":true,"in":"query","schema":{"type":"string"}},{"name":"entityType","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Admin list tenant audit logs (paginated; optional action & entityType filters)","tags":["Admin"]}},"/api/admin/notifications/deliveries":{"get":{"operationId":"AdminController_listNotificationDeliveries","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}},{"name":"skip","required":true,"in":"query","schema":{"type":"number"}},{"name":"take","required":true,"in":"query","schema":{"type":"number"}},{"name":"status","required":true,"in":"query","schema":{"type":"string"}},{"name":"type","required":true,"in":"query","schema":{"type":"string"}},{"name":"provider","required":true,"in":"query","schema":{"type":"string"}},{"name":"recipient","required":true,"in":"query","schema":{"type":"string"}},{"name":"from","required":true,"in":"query","schema":{"type":"string"}},{"name":"to","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"List notification delivery audit rows (paginated; optional status, type, provider, recipient, date range)","tags":["Admin"]}},"/api/admin/dashboard/summary":{"get":{"operationId":"AdminController_dashboardSummary","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Admin get high-level dashboard metrics","tags":["Admin"]}},"/api/admin/reports/enrollments":{"get":{"operationId":"AdminController_enrollmentReport","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Enrollment breakdown by status and top courses by volume","tags":["Admin"]}},"/api/admin/reports/learning":{"get":{"operationId":"AdminController_learningOverview","parameters":[{"name":"x-tenant-slug","in":"header","description":"Tenant slug context","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Learning overview (enrolled users, completions, lesson progress)","tags":["Admin"]}}},"info":{"title":"Trex LMS API","description":"**Trex Learning** tenant-scoped HTTP API.\n\n### Before you try endpoints\n- Almost all routes need header **`x-tenant-slug`** (except Health and tenant discovery).\n- Protected routes: **`Authorization: Bearer`** plus JWT access token, or (where supported) a **`trex_sk_`** tenant API key.\n- Open **`GET /`** on this host for quick links (docs, OpenAPI JSON, health).\n\n### Doc layout\nTags are grouped **platform → learning → admin integrations** so related routes stay together.","version":"1.0.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CreateTenantDto":{"type":"object","properties":{"slug":{"type":"string","example":"acme-learning"},"companyName":{"type":"string","example":"Acme Corporation"},"logoUrl":{"type":"string","example":"https://cdn.example.com/logo.png"}},"required":["slug","companyName"]},"RegisterDto":{"type":"object","properties":{"email":{"type":"string","example":"learner@acme.com"},"password":{"type":"string","example":"StrongPassword123!"},"firstName":{"type":"string","example":"Taylor"},"lastName":{"type":"string","example":"Morgan"},"role":{"type":"string","enum":["TENANT_ADMIN","INSTRUCTOR","LEARNER"],"example":"LEARNER"}},"required":["email","password","firstName","lastName"]},"LoginDto":{"type":"object","properties":{"email":{"type":"string","example":"admin@trex.dev"},"password":{"type":"string","example":"ChangeMe123!"}},"required":["email","password"]},"RefreshTokenDto":{"type":"object","properties":{"refreshToken":{"type":"string","description":"Valid refresh token returned from login/register"}},"required":["refreshToken"]},"RequestPasswordResetDto":{"type":"object","properties":{"email":{"type":"string","example":"admin@trex.dev"}},"required":["email"]},"ResetPasswordDto":{"type":"object","properties":{"token":{"type":"string","description":"Password reset token from reset request response"},"newPassword":{"type":"string","example":"NewStrongPassword123!"}},"required":["token","newPassword"]},"VerifyEmailDto":{"type":"object","properties":{"token":{"type":"string","description":"Email verification token from verification request response"}},"required":["token"]},"StartSsoDto":{"type":"object","properties":{"redirectPath":{"type":"string","description":"Optional app-relative return path after successful SSO, e.g. /dashboard.","example":"/dashboard"}}},"CompleteSsoDto":{"type":"object","properties":{"code":{"type":"string","description":"Authorization code from the identity provider callback."},"state":{"type":"string","description":"Opaque state value received from /auth/sso/start."}},"required":["code","state"]},"CreateApiKeyDto":{"type":"object","properties":{"name":{"type":"string","example":"HRIS nightly sync"},"role":{"type":"string","enum":["TENANT_ADMIN","INSTRUCTOR","LEARNER"],"description":"Effective role for RBAC (TENANT_ADMIN or INSTRUCTOR only)"}},"required":["name"]},"CreateLessonDto":{"type":"object","properties":{"title":{"type":"string","example":"Welcome and Orientation"},"content":{"type":"string","example":"Lesson content in markdown or rich text format."},"position":{"type":"number","example":1}},"required":["title","content","position"]},"CreateCourseDto":{"type":"object","properties":{"title":{"type":"string","example":"Enterprise Onboarding 101"},"description":{"type":"string","example":"A foundational onboarding journey for new hires."},"lessons":{"type":"array","items":{"$ref":"#/components/schemas/CreateLessonDto"}}},"required":["title","description","lessons"]},"UpdateCourseDto":{"type":"object","properties":{"title":{"type":"string","example":"Onboarding 102"},"description":{"type":"string","example":"Updated course description text."}}},"AddLessonDto":{"type":"object","properties":{"title":{"type":"string","example":"Security basics"},"content":{"type":"string","example":"Lesson body content."},"position":{"type":"number","description":"Optional position; if omitted, appends after the last lesson.","example":2}},"required":["title","content"]},"UpdateLessonDto":{"type":"object","properties":{"title":{"type":"string","example":"Renamed lesson"},"content":{"type":"string","example":"Updated lesson content."}}},"EnrollUserDto":{"type":"object","properties":{"userId":{"type":"string","example":"user_uuid_here"},"courseId":{"type":"string","example":"course_uuid_here"}},"required":["userId","courseId"]},"CreateWebhookEndpointDto":{"type":"object","properties":{"url":{"type":"string","example":"https://integrations.example.com/hooks/trex"},"description":{"type":"string","example":"Production Zapier hook"},"eventFilter":{"example":["enrollment.activated","certification.issued"],"type":"array","items":{"type":"string"}}},"required":["url"]},"UpdateWebhookEndpointDto":{"type":"object","properties":{"url":{"type":"string"},"description":{"type":"string"},"isActive":{"type":"boolean"},"eventFilter":{"type":"array","items":{"type":"string"}}}},"CompleteLessonDto":{"type":"object","properties":{"lessonId":{"type":"string","example":"lesson_uuid_here"},"completed":{"type":"boolean","example":true}},"required":["lessonId","completed"]},"QuestionOptionDto":{"type":"object","properties":{"text":{"type":"string","example":"Option text"}},"required":["text"]},"QuestionDto":{"type":"object","properties":{"prompt":{"type":"string","example":"What is microlearning?"},"options":{"type":"array","items":{"$ref":"#/components/schemas/QuestionOptionDto"}},"correctOptionIndex":{"type":"number","example":1}},"required":["prompt","options","correctOptionIndex"]},"CreateAssessmentDto":{"type":"object","properties":{"title":{"type":"string","example":"Onboarding Quiz - Week 1"},"courseId":{"type":"string","example":"course_uuid_here"},"passingScore":{"type":"number","example":70},"questions":{"type":"array","items":{"$ref":"#/components/schemas/QuestionDto"}}},"required":["title","courseId","passingScore","questions"]},"SubmitAssessmentDto":{"type":"object","properties":{"assessmentId":{"type":"string","example":"assessment_uuid_here"},"answers":{"example":[1,0,2],"type":"array","items":{"type":"string"}}},"required":["assessmentId","answers"]},"CreateLearnerGroupDto":{"type":"object","properties":{"name":{"type":"string","example":"Q1 Sales onboarding"},"description":{"type":"string"}},"required":["name"]},"UpdateLearnerGroupDto":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"}}},"AddLearnerGroupMemberDto":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"}},"required":["userId"]},"CreateLearningPathDto":{"type":"object","properties":{"name":{"type":"string","example":"Engineering onboarding track"},"description":{"type":"string"},"courseIds":{"type":"array","items":{"type":"string"}}},"required":["name"]},"UpdateLearningPathDto":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"}}},"SetLearningPathCoursesDto":{"type":"object","properties":{"courseIds":{"description":"Course IDs in display order (first = start of path). Empty array clears the path.","type":"array","items":{"type":"string"}}},"required":["courseIds"]},"AdminCreateUserDto":{"type":"object","properties":{"email":{"type":"string","example":"learner@acme.com"},"password":{"type":"string","example":"StrongPassword123!"},"firstName":{"type":"string","example":"Jordan"},"lastName":{"type":"string","example":"Lee"},"role":{"type":"string","enum":["TENANT_ADMIN","INSTRUCTOR","LEARNER"],"example":"LEARNER"}},"required":["email","password","firstName","lastName"]},"AdminBulkUsersDto":{"type":"object","properties":{"users":{"maxItems":100,"type":"array","items":{"$ref":"#/components/schemas/AdminCreateUserDto"}}},"required":["users"]},"AdminUpdateUserRoleDto":{"type":"object","properties":{"role":{"type":"string","enum":["TENANT_ADMIN","INSTRUCTOR","LEARNER"],"example":"INSTRUCTOR"}},"required":["role"]},"AdminUpdateUserStatusDto":{"type":"object","properties":{"isActive":{"type":"boolean","example":false}},"required":["isActive"]},"AdminUpdateTenantSettingsDto":{"type":"object","properties":{"companyName":{"type":"string","example":"Acme Corporation"},"logoUrl":{"type":"string","example":"https://cdn.example.com/logo.png"}},"required":["companyName"]}}}}