{"openapi":"3.0.0","paths":{"/api/v1/user/context":{"get":{"description":"Retrieves the user context including role, permissions, leadership status, and experience types. Optionally filter by Canvas account ID.","operationId":"getUserContext","parameters":[{"name":"accountId","required":false,"in":"query","description":"Optional Canvas account ID to filter the user context","schema":{"type":"string"}}],"responses":{"200":{"description":"User context retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserContextDTO"}}}},"400":{"description":"Bad Request - Invalid accountId format"},"401":{"description":"Unauthorized - Invalid or missing JWT token"}},"security":[{"bearer":[]}],"summary":"Get user context information","tags":["v1/user"]}},"/api/v1/skills":{"post":{"operationId":"createSkills","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSkillsDTO"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SkillDTO"}}}}}},"security":[{"bearer":[]}],"summary":"","tags":["v1/skills"]}},"/api/v1/skills/resume":{"post":{"operationId":"extractSkillsFromResume","parameters":[],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"","tags":["v1/skills"]}},"/api/v1/skills/taxonomy-source":{"post":{"operationId":"extractSkillsFromTaxonomySource","parameters":[],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"","tags":["v1/skills"]}},"/api/v1/programs/enroll/{baseUrl}/{courseId}":{"post":{"operationId":"V1ProgramController_enrollUserToRequirement","parameters":[{"name":"baseUrl","required":true,"in":"path","description":"Base URL of the Canvas instance (e.g., \"canvas.instructure.com\").","schema":{"type":"string"}},{"name":"courseId","required":true,"in":"path","description":"The Canvas ID of the course.","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"tags":["v1/programs"]}},"/api/v1/collections/{collectionId}/file":{"post":{"operationId":"addFileToCollection","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LearningLibraryCourseMembershipDTO"}}}}},"security":[{"bearer":[]}],"summary":"","tags":["v1/collections"]}},"/api/v1/prism/conversations":{"get":{"operationId":"PrismConversationController_listConversations","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["v1/prism/conversations"]},"post":{"operationId":"PrismConversationController_createOrAppendMessage","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateConversationMessageDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"tags":["v1/prism/conversations"]},"delete":{"operationId":"PrismConversationController_deleteConversations","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteConversationsDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["v1/prism/conversations"]}},"/api/v1/prism/conversations/sse":{"post":{"operationId":"PrismConversationController_createOrAppendMessageSSE","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateConversationMessageDto"}}}},"responses":{"200":{"description":"SSE stream of solver events (DidDecodeIntent, DidSolve, DidVisualize, etc.) followed by a final DidConverse or DidFail event"}},"security":[{"bearer":[]}],"summary":"Create or append a conversation message with SSE streaming","tags":["v1/prism/conversations"]}},"/api/v1/prism/conversations/{id}":{"get":{"operationId":"PrismConversationController_getConversation","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["v1/prism/conversations"]}},"/api/v1/prism/conversations/{id}/regenerate":{"post":{"operationId":"PrismConversationController_regenerateQuery","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"x-request-id","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegenerateQueryDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"tags":["v1/prism/conversations"]}},"/api/v1/prism/queries":{"get":{"operationId":"PrismQueryController_getBulkQueries","parameters":[{"name":"id","required":true,"in":"query","description":"Array of query UUIDs to retrieve","schema":{"example":["uuid-1","uuid-2","uuid-3"],"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["v1/prism/queries"]}},"/api/v1/prism/queries/{id}/settings":{"get":{"operationId":"PrismQueryController_getUserSettings","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["v1/prism/queries"]},"put":{"operationId":"PrismQueryController_updateUserSettings","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePrismQuerySettingsDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["v1/prism/queries"]}},"/api/v1/prism/widget-library":{"get":{"operationId":"WidgetLibraryController_getWidgetLibrary","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["v1/prism/widget-library"]}},"/api/v1/prism/widget-library/add":{"put":{"operationId":"WidgetLibraryController_assignQueryToLibrary","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignQueryToLibraryDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["v1/prism/widget-library"]}},"/api/v1/prism/widget-library/remove":{"post":{"operationId":"WidgetLibraryController_removeQueryFromLibrary","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveQueryFromLibraryDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"tags":["v1/prism/widget-library"]}},"/api/v1/hris/sync-status":{"get":{"operationId":"HrisController_getSyncStatus","parameters":[],"responses":{"200":{"description":""}},"tags":["v1/hris"]}},"/api/v1/hris/create-stackone-connect-session":{"post":{"operationId":"HrisController_createConnectSession","parameters":[],"responses":{"201":{"description":""}},"tags":["v1/hris"]}},"/api/v1/hris/trigger-sync":{"post":{"operationId":"HrisController_triggerSync","parameters":[],"responses":{"201":{"description":""}},"tags":["v1/hris"]}},"/api/v1/hris/account":{"delete":{"operationId":"HrisController_removeAccount","parameters":[],"responses":{"204":{"description":""}},"tags":["v1/hris"]}},"/api/v1/import":{"post":{"operationId":"UserImportController_import","parameters":[],"responses":{"201":{"description":""}},"tags":["v1/import"]}},"/api/v1/import/org-chart":{"get":{"operationId":"UserImportController_getOrgChart","parameters":[{"name":"accountId","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["v1/import"]}},"/api/v1/navigation/items":{"get":{"description":"Retrieves fully-formed navigation items based on user context, experience type, and Canvas data. Journey fetches Canvas tabs, applies permissions, and builds complete navigation with all metadata server-side.","operationId":"getNavigationItems","parameters":[{"name":"accountId","required":false,"in":"query","description":"Canvas account ID for Learning Provider admin/instructor context","schema":{"example":"123","type":"string"}},{"name":"userId","required":false,"in":"query","description":"Canvas user ID for Learner app context","schema":{"example":"456","type":"string"}},{"name":"courseId","required":false,"in":"query","description":"Canvas course ID for course-specific navigation (future)","schema":{"example":"789","type":"string"}},{"name":"experienceType","required":true,"in":"query","description":"Experience type determining navigation structure","schema":{"example":"career_learning_provider","type":"string","enum":["academic","career_learner","career_learning_provider","unknown"]}},{"name":"basePath","required":false,"in":"query","description":"Client routing base path for URL generation (e.g., \"/career\" for production)","schema":{"example":"/career","type":"string"}},{"name":"features","required":true,"in":"query","description":"Optional feature flags for navigation customization","schema":{"additionalProperties":true,"example":{"catalog_enabled":true,"dashboard_enabled":true,"analytics_enabled":false},"type":"object"}},{"name":"role","required":false,"in":"query","description":"Optional role override for intra-app switching (e.g., admin, course_facilitator). When provided, overrides the auto-determined role for navigation template selection.","schema":{"example":"admin","type":"string"}}],"responses":{"200":{"description":"Navigation items retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NavigationResponseDto"}}}},"400":{"description":"Bad Request - Invalid request parameters"},"401":{"description":"Unauthorized - Invalid or missing JWT token"}},"security":[{"bearer":[]}],"summary":"Get navigation items","tags":["v1/navigation"]}}},"info":{"title":"Skill Service API","description":"API documentation of the Skill Service","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"Experience":{"type":"object","properties":{"currentApp":{"type":"string","description":"Current application/experience type the user is accessing","enum":["academic","career_learner","career_learning_provider","unknown"],"example":"career_learner"},"availableApps":{"type":"array","description":"Experience types the user has access to","example":["career_learner","academic"],"items":{"type":"string","enum":["academic","career_learner","career_learning_provider","unknown"]}},"availableRoles":{"type":"array","description":"Career roles the user has in the current root account context (e.g. admin, course_facilitator, learner)","items":{"type":"string"},"example":["admin","course_facilitator","learner"]},"currentRole":{"type":"string","description":"Canvas-persisted preferred role. Null when the user has not made an explicit choice; otherwise one of 'admin', 'course_facilitator', 'learning_provider', 'learner'.","nullable":true,"example":"course_facilitator"}},"required":["currentApp","availableApps","availableRoles","currentRole"]},"UserContextDTO":{"type":"object","properties":{"userId":{"type":"string","description":"Internal user ID","example":"123e4567-e89b-12d3-a456-426614174000"},"canvasUserId":{"type":"string","description":"Canvas user ID (external)","example":"123e4567-e89b-12d3-a456-426614174000"},"role":{"type":"string","description":"User role within the system","enum":["admin","instructor","ta","observer","designer","learner","root_admin","unknown","course_facilitator"],"example":"learner"},"isLeader":{"type":"boolean","description":"Indicates whether the user has leadership responsibilities","example":false},"isRootAccount":{"type":"boolean","description":"Whether the account this context was resolved for is a root account rather than a sub-account","example":true},"isCareerRootAccount":{"type":"boolean","description":"Whether the domain root of this tenant has Career enabled. True: pure-Career tenant. False: mixed tenant (inherited root-admin access). Null: domain root could not be classified — treat as unknown.","example":false,"nullable":true},"isSubaccountAdmin":{"type":"boolean","description":"Whether the user was explicitly assigned as an admin to the specific Career sub-account in this request (Canvas is_subaccount_admin). Distinguishes an explicit Career admin assignment from a role inherited purely from being a root admin on an academic root account.","example":false},"canAdministerAccount":{"type":"boolean","description":"Whether the user may administer the account this context was resolved for. Null when Canvas could not be reached, which is distinct from false: a client must not treat null as a refusal.","nullable":true,"example":true},"defaultAccountId":{"type":"string","description":"The account this user should operate in when none is specified: the Career account they administer that sorts first by name, or the domain root for a root admin of a tenant that has Career enabled on the root itself. Always an account under the root account of the requesting domain. Null when they administer no Career account here, or when the lookup failed. Identical across every value of the accountId query parameter.","nullable":true,"example":"85"},"permissions":{"type":"object","description":"Map of permission keys to boolean values indicating granted permissions","additionalProperties":{"type":"boolean"},"example":{"can_view_analytics":true,"can_manage_courses":false}},"experience":{"description":"Experience context (current app, available apps, available career roles and current role preference)","allOf":[{"$ref":"#/components/schemas/Experience"}]},"enrollmentTypes":{"type":"array","description":"List of enrollment types associated with the user","items":{"type":"string"},"example":["TeacherEnrollment","DesignerEnrollment"]}},"required":["userId","canvasUserId","role","isLeader","isRootAccount","isCareerRootAccount","isSubaccountAdmin","canAdministerAccount","defaultAccountId","permissions","experience"]},"CreateSkillDTO":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"CreateSkillsDTO":{"type":"object","properties":{"skills":{"type":"array","items":{"$ref":"#/components/schemas/CreateSkillDTO"}},"skillExtractionId":{"type":"string","nullable":true}},"required":["skills","skillExtractionId"]},"SkillDTO":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"proficiencyLevel":{"type":"string","enum":["beginner","proficient","advanced","expert"]},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","name","proficiencyLevel","createdAt","updatedAt"]},"CanvasCourseInfoDTO":{"type":"object","properties":{"courseId":{"type":"string"},"canvasUrl":{"type":"string"},"courseName":{"type":"string","nullable":true},"courseImageUrl":{"type":"string","nullable":true},"moduleCount":{"type":"number"},"moduleItemCount":{"type":"number"},"estimatedDurationMinutes":{"type":"number","nullable":true}},"required":["courseId","canvasUrl","courseName","courseImageUrl","moduleCount","moduleItemCount","estimatedDurationMinutes"]},"LearningLibraryCourseMembershipDTO":{"type":"object","properties":{"id":{"type":"string"},"libraryId":{"type":"string"},"itemType":{"type":"string","enum":["course","page","assignment","quiz","external_url","external_tool","file","program"]},"displayOrder":{"type":"number"},"canvasCourse":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/CanvasCourseInfoDTO"}]},"programId":{"type":"string","nullable":true},"programCourseId":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","libraryId","itemType","displayOrder","canvasCourse","programId","programCourseId","createdAt","updatedAt"]},"CreateConversationMessageDto":{"type":"object","properties":{"conversationId":{"type":"string","description":"Existing conversation ID to append to, omit to create new"},"message":{"type":"string","description":"User message content"},"canvasAccountId":{"type":"string"}},"required":["message"]},"RegenerateQueryDto":{"type":"object","properties":{"queryId":{"type":"string","description":"ID of the query to regenerate"},"error":{"type":"string","description":"Error message from failed query execution"},"canvasAccountId":{"type":"string"}},"required":["queryId","error"]},"DeleteConversationsDto":{"type":"object","properties":{"conversationIds":{"description":"Array of conversation IDs to delete","type":"array","items":{"type":"string"}}},"required":["conversationIds"]},"UpdatePrismQuerySettingsDto":{"type":"object","properties":{"parameters":{"type":"object","description":"User specific query parameter values"},"title":{"type":"string","description":"User specific title for the query"},"style":{"type":"object","description":"User specific style object for the query"}}},"AssignQueryToLibraryDto":{"type":"object","properties":{"queryId":{"type":"string","description":"Query id which needs to be added to widget library"}},"required":["queryId"]},"RemoveQueryFromLibraryDto":{"type":"object","properties":{"queryId":{"type":"string","description":"Query id which needs to be removed from widget library"}},"required":["queryId"]},"NavigationItem":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the navigation item","example":"home"},"type":{"type":"string","description":"Type of navigation item: local (Horizon SPA route mapped by frontend), route (Canvas full-page navigation), parent (container with sub-items), click (action handler), external (external URL)","enum":["local","route","parent","click","external"],"example":"local"},"title":{"type":"string","description":"Display title for the navigation item","example":"Home"},"route":{"type":"string","description":"Route path for route/external navigation. Not present for local items (frontend maps route by id)","example":"/conversations"},"isActiveIdentifier":{"type":"string","description":"Identifier for matching active routes","example":"/programs/123"},"subNavigationItems":{"description":"Sub-navigation items for parent navigation","type":"array","items":{"$ref":"#/components/schemas/NavigationItem"}},"isBottomItem":{"type":"boolean","description":"Whether this item should be displayed at the bottom","example":false},"canvasTabId":{"type":"string","description":"Canvas tab ID reference for audit/debugging","example":"context_external_tool_456"},"canvasTabType":{"type":"string","description":"Canvas tab type for external tool tracking","enum":["internal","external"],"example":"external"},"defaultOpen":{"type":"boolean","description":"Whether this parent group should be open by default on app load, independent of the current route","example":true}},"required":["id","type","title"]},"NavigationResponseDto":{"type":"object","properties":{"items":{"description":"Array of navigation items with complete metadata","example":[{"id":"home","type":"local","title":"Home"},{"id":"inbox","type":"route","title":"Inbox","route":"/conversations"},{"id":"learn","type":"parent","title":"Learn","subNavigationItems":[{"id":"program-123","type":"local","title":"Leadership Program"},{"id":"course-456","type":"local","title":"Standalone Course","isActiveIdentifier":"/courses/456"}]},{"id":"external-tool-1","type":"external","title":"External Tool","route":"https://external.example.com/tool","canvasTabId":"context_external_tool_123","canvasTabType":"external"},{"id":"report_bug","type":"click","title":"Report a Bug","isBottomItem":true}],"type":"array","items":{"$ref":"#/components/schemas/NavigationItem"}},"degraded":{"type":"boolean","description":"True when at least one upstream call failed and the items below were built from fallback data, so the navigation may be incomplete. Lets clients distinguish a genuinely empty or partial navigation from one degraded by an upstream outage. Absent or false means the response is complete.","example":false}},"required":["items"]}}}}