{"openapi":"3.0.0","info":{"title":"StudyFetch API","description":"API documentation for StudyFetch","version":"1.0","contact":{}},"paths":{"/api/v1/materials":{"get":{"operationId":"findAll","summary":"Get all materials for organization","parameters":[{"name":"folderId","required":false,"in":"query","description":"Filter by folder ID","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number (default: 1)","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page (default: 20, max: 200)","schema":{"type":"string"}},{"name":"search","required":false,"in":"query","description":"Search materials by name","schema":{"type":"string"}}],"responses":{"200":{"description":"Materials retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"materials":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}},"totalCount":{"type":"number"},"page":{"type":"number"},"totalPages":{"type":"number"}}}}}}},"tags":["Materials"],"security":[{"x-api-key":[]}]},"post":{"operationId":"createMaterial","summary":"Create a new material","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"Chapter 1 - Introduction","description":"Name of the material"},"content":{"description":"Content details","allOf":[{"type":"object","properties":{"type":{"type":"string","enum":["text","pdf","video","audio","url"],"description":"Type of content"},"text":{"type":"string","description":"Text content (for text type)"},"url":{"type":"string","description":"URL to the content (for url type)"},"sourceUrl":{"type":"string","description":"URL to fetch content from"}},"required":["type"]}]},"folderId":{"type":"string","description":"Folder ID to place the material in"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}}},"required":["name","content"]}}}},"responses":{"201":{"description":"Material created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}}}},"403":{"description":"Insufficient permissions"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/generate":{"post":{"operationId":"generate","summary":"Generate material from a topic","description":"Uses AI to generate study materials like outlines, notes, summaries, etc. from a given topic. Returns immediately without waiting for processing.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"topic":{"type":"string","description":"Topic or context to generate material from","example":"Photosynthesis in plants"},"context":{"type":"string","description":"Additional context or details about the topic","example":"Focus on light-dependent and light-independent reactions"},"type":{"type":"string","description":"Type of material to generate","enum":["outline","overview","notes","summary"],"example":"notes"},"name":{"type":"string","description":"Name for the generated material","example":"Photosynthesis Study Plan"},"folderId":{"type":"string","description":"Target folder ID"},"length":{"type":"string","description":"Length of the generated content","enum":["short","medium","long"],"default":"medium"},"level":{"type":"string","description":"Target education level","enum":["high_school","college","professional"],"example":"college"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}}},"required":["topic","type","name"]}}}},"responses":{"201":{"description":"Material generated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"},"generationMetadata":{"type":"object","description":"Generation metadata"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}}}},"400":{"description":"Invalid parameters or generation failed"},"403":{"description":"Insufficient permissions"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/generate-and-process":{"post":{"operationId":"generateAndProcess","summary":"Generate and process material from a topic","description":"Uses AI to generate study materials like outlines, notes, summaries, etc. from a given topic and waits for processing to complete","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"topic":{"type":"string","description":"Topic or context to generate material from","example":"Photosynthesis in plants"},"context":{"type":"string","description":"Additional context or details about the topic","example":"Focus on light-dependent and light-independent reactions"},"type":{"type":"string","description":"Type of material to generate","enum":["outline","overview","notes","summary"],"example":"notes"},"name":{"type":"string","description":"Name for the generated material","example":"Photosynthesis Study Plan"},"folderId":{"type":"string","description":"Target folder ID"},"length":{"type":"string","description":"Length of the generated content","enum":["short","medium","long"],"default":"medium"},"level":{"type":"string","description":"Target education level","enum":["high_school","college","professional"],"example":"college"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"timeoutMs":{"type":"number","default":300000,"description":"Maximum time to wait for processing in milliseconds (default: 5 minutes)"},"pollIntervalMs":{"type":"number","default":2000,"description":"Polling interval in milliseconds (default: 2 seconds)"}},"required":["topic","type","name"]}}}},"responses":{"201":{"description":"Material generated and processed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"},"generationMetadata":{"type":"object","description":"Generation metadata"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}}}},"400":{"description":"Invalid parameters, generation failed, or processing timed out"},"403":{"description":"Insufficient permissions"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/upload":{"post":{"operationId":"uploadMaterial","summary":"Upload a material file","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"name":{"type":"string","description":"Material name"},"folderId":{"type":"string","description":"Folder ID (optional). If folderPath is provided, folderId will be ignored."},"folderPath":{"type":"string","description":"Relative folder path (e.g., \"folder1/folder2\"). Folders will be created if they don't exist. The filename can be included (e.g., \"folder1/folder2/image1.png\") and will be extracted automatically."},"extractImages":{"type":"string","description":"Whether to extract images from files (true/false, default: true)","default":"true"},"references":{"type":"string","description":"JSON string of references array (optional)"}},"required":["file","name"]}}}},"responses":{"201":{"description":"Material uploaded successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}}}},"400":{"description":"Invalid file or parameters"},"500":{"description":"Internal server error"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/upload/url":{"post":{"operationId":"uploadFromUrl","summary":"Upload material from URL","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"URL to fetch content from"},"name":{"type":"string","description":"Material name"},"folderId":{"type":"string","description":"Folder ID (optional). If folderPath is provided, folderId will be ignored."},"folderPath":{"type":"string","description":"Relative folder path (e.g., \"folder1/folder2\"). Folders will be created if they don't exist. The filename can be included (e.g., \"folder1/folder2/image1.png\") and will be extracted automatically."}},"required":["url","name"]}}}},"responses":{"201":{"description":"Material uploaded from URL successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}}}}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/upload-and-process":{"post":{"operationId":"createMaterialSync","summary":"Create material and wait for processing to complete","description":"Creates a material and waits for processing to finish before returning. Useful for synchronous API usage.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"Chapter 1 - Introduction","description":"Name of the material"},"content":{"description":"Content details","allOf":[{"type":"object","properties":{"type":{"type":"string","enum":["text","pdf","video","audio","url"],"description":"Type of content"},"text":{"type":"string","description":"Text content (for text type)"},"url":{"type":"string","description":"URL to the content (for url type)"},"sourceUrl":{"type":"string","description":"URL to fetch content from"}},"required":["type"]}]},"folderId":{"type":"string","description":"Folder ID to place the material in"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"timeoutMs":{"type":"number","default":300000,"description":"Maximum time to wait for processing in milliseconds (default: 5 minutes)"},"pollIntervalMs":{"type":"number","default":2000,"description":"Polling interval in milliseconds (default: 2 seconds)"}},"required":["name","content"]}}}},"responses":{"201":{"description":"Material created and processed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}}}},"400":{"description":"Processing failed or timed out"},"403":{"description":"Insufficient permissions"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/upload/file-and-process":{"post":{"operationId":"uploadMaterialSync","summary":"Upload material file and wait for processing to complete","description":"Uploads a file and waits for processing to finish before returning. Useful for synchronous API usage.","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"name":{"type":"string","description":"Material name"},"folderId":{"type":"string","description":"Folder ID (optional). If folderPath is provided, folderId will be ignored."},"folderPath":{"type":"string","description":"Relative folder path (e.g., \"folder1/folder2\"). Folders will be created if they don't exist. The filename can be included (e.g., \"folder1/folder2/image1.png\") and will be extracted automatically."},"timeoutMs":{"type":"number","description":"Processing timeout in milliseconds (default: 300000 - 5 minutes)"},"pollIntervalMs":{"type":"number","description":"Polling interval in milliseconds (default: 2000)"},"extractImages":{"type":"string","description":"Whether to extract images from files (true/false, default: true)","default":"true"}},"required":["file","name"]}}}},"responses":{"201":{"description":"Material uploaded and processed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}}}},"400":{"description":"Invalid file, processing failed, or timed out"},"500":{"description":"Internal server error"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/upload/url-and-process":{"post":{"operationId":"uploadFromUrlSync","summary":"Upload material from URL and wait for processing to complete","description":"Fetches content from URL and waits for processing to finish before returning. Useful for synchronous API usage.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","example":"https://example.com/document.pdf","description":"URL to fetch content from"},"name":{"type":"string","example":"My Document","description":"Material name"},"folderId":{"type":"string","description":"Folder ID (optional). If folderPath is provided, folderId will be ignored."},"folderPath":{"type":"string","description":"Relative folder path (e.g., \"folder1/folder2\"). Folders will be created if they don't exist. The filename can be included (e.g., \"folder1/folder2/image1.png\") and will be extracted automatically."},"timeoutMs":{"type":"number","default":300000,"description":"Maximum time to wait for processing in milliseconds (default: 5 minutes)"},"pollIntervalMs":{"type":"number","default":2000,"description":"Polling interval in milliseconds (default: 2 seconds)"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}}},"required":["url","name"]}}}},"responses":{"201":{"description":"Material uploaded from URL and processed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}}}},"400":{"description":"Invalid URL, processing failed, or timed out"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/upload/presigned-url":{"post":{"operationId":"getPresignedUploadUrl","summary":"Get presigned URL for direct S3 upload","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"filename":{"type":"string","example":"document.pdf","description":"Filename to upload"},"contentType":{"type":"string","example":"application/pdf","description":"MIME type of the file"},"name":{"type":"string","example":"Chapter 1 Notes","description":"Display name for the material"},"folderId":{"type":"string","description":"Folder ID to place the material in"},"extractImages":{"type":"boolean","description":"Whether to extract images from files","example":true,"default":true},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}}},"required":["filename","contentType","name"]}}}},"responses":{"200":{"description":"Presigned URL generated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"uploadUrl":{"type":"string","description":"Presigned URL for direct S3 upload"},"s3Key":{"type":"string","description":"S3 key for the file"},"materialId":{"type":"string","description":"Material ID to use for completion"}},"required":["uploadUrl","s3Key","materialId"]}}}},"400":{"description":"Invalid parameters"},"403":{"description":"Insufficient permissions"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/upload/complete":{"post":{"operationId":"completeUpload","summary":"Complete upload after using presigned URL","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"materialId":{"type":"string","description":"Material ID from presigned URL response"},"s3Key":{"type":"string","description":"S3 key from presigned URL response"}},"required":["materialId","s3Key"]}}}},"responses":{"200":{"description":"Upload completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}}}},"403":{"description":"Insufficient permissions"},"404":{"description":"Material not found"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/batch":{"post":{"operationId":"createBatch","summary":"Create batch upload URLs for multiple materials","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"materials":{"description":"Array of materials to create","type":"array","items":{"type":"object","properties":{"name":{"type":"string","example":"Chapter 1","description":"Material name"},"filename":{"type":"string","example":"document.pdf","description":"Filename"},"contentType":{"type":"string","example":"application/pdf","description":"MIME type"},"folderId":{"type":"string","description":"Folder ID"}},"required":["name","filename","contentType"]}}},"required":["materials"]}}}},"responses":{"201":{"description":"Batch upload URLs created successfully","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Material name"},"uploadUrl":{"type":"string","description":"Presigned upload URL"},"s3Key":{"type":"string","description":"S3 key"},"materialId":{"type":"string","description":"Material ID"}},"required":["name","uploadUrl","s3Key","materialId"]}}}}},"400":{"description":"Invalid parameters"},"403":{"description":"Insufficient permissions"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/{id}":{"get":{"operationId":"findOne","summary":"Get material by ID","parameters":[{"name":"id","required":true,"in":"path","description":"Material ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Material retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}}}},"404":{"description":"Material not found"}},"tags":["Materials"],"security":[{"x-api-key":[]}]},"patch":{"operationId":"updateMaterial","summary":"Update a material","parameters":[{"name":"id","required":true,"in":"path","description":"Material ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"references":{"type":"array","description":"Array of references to update (optional)","items":{"type":"object","properties":{"title":{"type":"string","description":"Reference title"},"url":{"type":"string","description":"Reference URL (optional)"}},"required":["title"]}}}}}}},"responses":{"200":{"description":"Material updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}}}},"403":{"description":"Insufficient permissions"},"404":{"description":"Material not found"}},"tags":["Materials"],"security":[{"x-api-key":[]}]},"delete":{"operationId":"remove","summary":"Delete material","parameters":[{"name":"id","required":true,"in":"path","description":"Material ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Material deleted successfully"},"404":{"description":"Material not found"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/{id}/download-url":{"get":{"operationId":"getDownloadUrl","summary":"Get temporary download URL for material","parameters":[{"name":"id","required":true,"in":"path","description":"Material ID","schema":{"type":"string"}},{"name":"expiresIn","required":false,"in":"query","description":"URL expiration time in seconds (default: 3600)","schema":{"type":"number"}}],"responses":{"200":{"description":"Download URL generated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"downloadUrl":{"type":"string","description":"Temporary download URL"}},"required":["downloadUrl"]}}}},"400":{"description":"Material not stored in S3"},"404":{"description":"Material not found"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/bulk/move":{"post":{"operationId":"bulkMoveMaterials","summary":"Bulk move materials to a different folder","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"materialIds":{"description":"Array of material IDs to move","type":"array","items":{"type":"string"}},"folderId":{"type":"string","description":"Target folder ID (null for root)","nullable":true}},"required":["materialIds","folderId"]}}}},"responses":{"200":{"description":"Materials moved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Operation success status"},"movedCount":{"type":"number","description":"Number of materials moved"}},"required":["success","movedCount"]}}}},"403":{"description":"Insufficient permissions"},"404":{"description":"Folder not found"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/{id}/move":{"post":{"operationId":"moveMaterial","summary":"Move material to a different folder","parameters":[{"name":"id","required":true,"in":"path","description":"Material ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"folderId":{"type":"string","description":"Target folder ID (null for root)","nullable":true}},"required":["folderId"]}}}},"responses":{"200":{"description":"Material moved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}}}},"403":{"description":"Insufficient permissions"},"404":{"description":"Material or folder not found"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/{id}/rename":{"post":{"operationId":"renameMaterial","summary":"Rename a material","parameters":[{"name":"id","required":true,"in":"path","description":"Material ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"New Material Name","description":"New name for the material"}},"required":["name"]}}}},"responses":{"200":{"description":"Material renamed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}}}},"400":{"description":"Invalid name"},"403":{"description":"Insufficient permissions"},"404":{"description":"Material not found"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/{id}/reprocess":{"post":{"operationId":"reprocessMaterial","summary":"Reprocess material to regenerate embeddings and extract content","parameters":[{"name":"id","required":true,"in":"path","description":"Material ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Material reprocessing started","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}}}},"400":{"description":"Material does not have an S3 key"},"403":{"description":"Insufficient permissions"},"404":{"description":"Material not found"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/{id}/debug":{"get":{"operationId":"getDebugContent","summary":"Get debug information for a material including extracted content","parameters":[{"name":"id","required":true,"in":"path","description":"Material ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Debug content retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"materialId":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"contentType":{"type":"string","description":"Content type"},"status":{"type":"string","description":"Processing status"},"content":{"type":"object","description":"Content details"},"images":{"type":"array","description":"Processed images","items":{"type":"object","properties":{"id":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"description":{"type":"string"},"pageIndex":{"type":"number"}}}},"metadata":{"type":"object","description":"Material metadata"},"transcriptStructure":{"type":"object","description":"Transcript structure for videos","nullable":true}},"required":["materialId","name","contentType","status","content","images","metadata","transcriptStructure"]}}}},"404":{"description":"Material not found"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/search":{"post":{"operationId":"searchMaterials","summary":"Search materials using RAG (Retrieval-Augmented Generation)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","example":"What is photosynthesis?","description":"Search query"},"topK":{"type":"number","default":5,"description":"Number of results to return"},"materialIds":{"description":"Limit search to specific material IDs","type":"array","items":{"type":"string"}},"folderIds":{"description":"Limit search to materials within specific folders (includes subfolders)","type":"array","items":{"type":"string"}}},"required":["query"]}}}},"responses":{"200":{"description":"Search completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"Original search query"},"results":{"description":"Search results","type":"array","items":{"type":"object","properties":{"score":{"type":"number","description":"Relevance score (0-1)"},"text":{"type":"string","description":"Matched text chunk"},"chunkIndex":{"type":"number","description":"Chunk index within the material"},"material":{"type":"object","description":"Material information","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string"},"contentType":{"type":"string"}}}},"required":["score","text","chunkIndex","material"]}},"totalResults":{"type":"number","description":"Total number of results"},"filtered":{"type":"boolean","description":"Whether results were filtered by scope"},"scope":{"type":"object","description":"Search scope","properties":{"materialIds":{"type":"array","items":{"type":"string"}},"folderIds":{"type":"array","items":{"type":"string"}}}}},"required":["query","results","totalResults","filtered","scope"]}}}},"400":{"description":"Invalid query"},"404":{"description":"Folder not found (if folder filter used)"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/{id}/job-status":{"get":{"operationId":"getJobStatus","summary":"Get processing job status for a material","description":"Returns the current status of a PDF processing job including progress information","parameters":[{"name":"id","required":true,"in":"path","description":"Material ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Job status retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"jobId":{"type":"string","description":"Unique job identifier"},"status":{"type":"string","enum":["pending","running","completed","failed","cancelled"],"description":"Current job status"},"startedAt":{"type":"string","format":"date-time","description":"Job start time"},"completedAt":{"type":"string","format":"date-time","description":"Job completion time"},"progress":{"type":"object","properties":{"totalImages":{"type":"number","description":"Total images to process"},"processedImages":{"type":"number","description":"Images processed so far"},"currentBatch":{"type":"number","description":"Current batch being processed"},"totalBatches":{"type":"number","description":"Total number of batches"},"percentage":{"type":"number","description":"Completion percentage (0-100)"}}},"error":{"type":"string","description":"Error message if job failed"},"resultSummary":{"type":"object","properties":{"textExtracted":{"type":"boolean","description":"Whether text was extracted"},"textLength":{"type":"number","description":"Length of extracted text"},"imagesProcessed":{"type":"number","description":"Number of images processed"},"processingTimeMs":{"type":"number","description":"Total processing time in milliseconds"}}}}}}}},"404":{"description":"Material not found"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/materials/{id}/cancel-job":{"post":{"operationId":"cancelJob","summary":"Cancel a running processing job","description":"Attempts to cancel a currently running PDF processing job","parameters":[{"name":"id","required":true,"in":"path","description":"Material ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Job cancellation requested successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"404":{"description":"Material or job not found"}},"tags":["Materials"],"security":[{"x-api-key":[]}]}},"/api/v1/folders":{"get":{"operationId":"findAll","summary":"Get all folders","parameters":[{"name":"parentFolderId","required":false,"in":"query","description":"Filter by parent folder","schema":{"type":"string"}}],"responses":{"200":{"description":"Folders retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string","description":"Folder ID"},"name":{"type":"string","description":"Folder name"},"organizationId":{"type":"string","description":"Organization ID"},"parentFolderId":{"type":"string","description":"Parent folder ID","nullable":true},"description":{"type":"string","description":"Folder description"},"status":{"type":"string","description":"Folder status","enum":["active","deleted"]},"metadata":{"description":"Folder metadata","allOf":[{"type":"object","properties":{"color":{"type":"string","description":"Folder color"},"icon":{"type":"string","description":"Folder icon"},"materialCount":{"type":"number","description":"Number of materials in folder"},"totalSize":{"type":"number","description":"Total size of materials in folder"},"lastActivity":{"format":"date-time","type":"string","description":"Last activity date"}}}]},"createdAt":{"format":"date-time","type":"string","description":"Creation date"},"updatedAt":{"format":"date-time","type":"string","description":"Last update date"}},"required":["_id","name","organizationId","status","createdAt","updatedAt"]}}}}}},"tags":["Folders"],"security":[{"x-api-key":[]}]},"post":{"operationId":"create","summary":"Create a new folder","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Folder name"},"parentFolderId":{"type":"string","description":"Parent folder ID"},"description":{"type":"string","description":"Folder description"},"metadata":{"type":"object","description":"Additional metadata"}},"required":["name"]}}}},"responses":{"201":{"description":"Folder created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Folder ID"},"name":{"type":"string","description":"Folder name"},"organizationId":{"type":"string","description":"Organization ID"},"parentFolderId":{"type":"string","description":"Parent folder ID","nullable":true},"description":{"type":"string","description":"Folder description"},"status":{"type":"string","description":"Folder status","enum":["active","deleted"]},"metadata":{"description":"Folder metadata","allOf":[{"type":"object","properties":{"color":{"type":"string","description":"Folder color"},"icon":{"type":"string","description":"Folder icon"},"materialCount":{"type":"number","description":"Number of materials in folder"},"totalSize":{"type":"number","description":"Total size of materials in folder"},"lastActivity":{"format":"date-time","type":"string","description":"Last activity date"}}}]},"createdAt":{"format":"date-time","type":"string","description":"Creation date"},"updatedAt":{"format":"date-time","type":"string","description":"Last update date"}},"required":["_id","name","organizationId","status","createdAt","updatedAt"]}}}}},"tags":["Folders"],"security":[{"x-api-key":[]}]}},"/api/v1/folders/tree":{"get":{"operationId":"getFolderTree","summary":"Get folder tree structure","parameters":[],"responses":{"200":{"description":"Folder tree retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"object","description":"Folder ID"},"name":{"type":"string","description":"Folder name"},"organizationId":{"type":"string","description":"Organization ID"},"parentFolderId":{"type":"string","description":"Parent folder ID","nullable":true},"description":{"type":"string","description":"Folder description"},"status":{"type":"string","description":"Folder status","enum":["active","deleted"]},"metadata":{"description":"Folder metadata","allOf":[{"type":"object","properties":{"color":{"type":"string","description":"Folder color"},"icon":{"type":"string","description":"Folder icon"},"materialCount":{"type":"number","description":"Number of materials in folder"},"totalSize":{"type":"number","description":"Total size of materials in folder"},"lastActivity":{"format":"date-time","type":"string","description":"Last activity date"}}}]},"createdAt":{"type":"object","description":"Creation date"},"updatedAt":{"type":"object","description":"Last update date"},"subfolders":{"type":"array","description":"Nested subfolders"}},"required":["_id","name","organizationId","status","subfolders"]}}}}}},"tags":["Folders"],"security":[{"x-api-key":[]}]}},"/api/v1/folders/by-name/{name}":{"get":{"operationId":"getFolderIdByName","summary":"Get folder ID by folder name","parameters":[{"name":"name","required":true,"in":"path","description":"Folder name","schema":{"type":"string"}},{"name":"parentFolderId","required":false,"in":"query","description":"Parent folder ID for accurate matching (optional)","schema":{"type":"string"}}],"responses":{"200":{"description":"Folder ID retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"folderId":{"type":"string","description":"Folder ID"}}}}}},"404":{"description":"Folder not found"}},"tags":["Folders"],"security":[{"x-api-key":[]}]}},"/api/v1/folders/{id}":{"get":{"operationId":"findOne","summary":"Get folder by ID","parameters":[{"name":"id","required":true,"in":"path","description":"Folder ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Folder retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"object","description":"Folder ID"},"name":{"type":"string","description":"Folder name"},"organizationId":{"type":"string","description":"Organization ID"},"parentFolderId":{"type":"string","description":"Parent folder ID","nullable":true},"description":{"type":"string","description":"Folder description"},"status":{"type":"string","description":"Folder status","enum":["active","deleted"]},"metadata":{"description":"Folder metadata","allOf":[{"type":"object","properties":{"color":{"type":"string","description":"Folder color"},"icon":{"type":"string","description":"Folder icon"},"materialCount":{"type":"number","description":"Number of materials in folder"},"totalSize":{"type":"number","description":"Total size of materials in folder"},"lastActivity":{"format":"date-time","type":"string","description":"Last activity date"}}}]},"createdAt":{"type":"object","description":"Creation date"},"updatedAt":{"type":"object","description":"Last update date"},"subfolders":{"type":"array","description":"Subfolders","items":{"type":"object"}},"materialCount":{"type":"number","description":"Total number of materials"}},"required":["_id","name","organizationId","status","subfolders","materialCount"]}}}}},"tags":["Folders"],"security":[{"x-api-key":[]}]},"patch":{"operationId":"update","summary":"Update folder","parameters":[{"name":"id","required":true,"in":"path","description":"Folder ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"New folder name"},"parentFolderId":{"type":"string","description":"New parent folder ID"},"description":{"type":"string","description":"New folder description"},"metadata":{"type":"object","description":"Updated metadata"}}}}}},"responses":{"200":{"description":"Folder updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Folder ID"},"name":{"type":"string","description":"Folder name"},"organizationId":{"type":"string","description":"Organization ID"},"parentFolderId":{"type":"string","description":"Parent folder ID","nullable":true},"description":{"type":"string","description":"Folder description"},"status":{"type":"string","description":"Folder status","enum":["active","deleted"]},"metadata":{"description":"Folder metadata","allOf":[{"type":"object","properties":{"color":{"type":"string","description":"Folder color"},"icon":{"type":"string","description":"Folder icon"},"materialCount":{"type":"number","description":"Number of materials in folder"},"totalSize":{"type":"number","description":"Total size of materials in folder"},"lastActivity":{"format":"date-time","type":"string","description":"Last activity date"}}}]},"createdAt":{"format":"date-time","type":"string","description":"Creation date"},"updatedAt":{"format":"date-time","type":"string","description":"Last update date"}},"required":["_id","name","organizationId","status","createdAt","updatedAt"]}}}}},"tags":["Folders"],"security":[{"x-api-key":[]}]},"delete":{"operationId":"remove","summary":"Delete folder","parameters":[{"name":"id","required":true,"in":"path","description":"Folder ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Folder deleted successfully"}},"tags":["Folders"],"security":[{"x-api-key":[]}]}},"/api/v1/folders/{id}/materials":{"get":{"operationId":"getAllMaterialsInFolder","summary":"Get all materials in folder","parameters":[{"name":"id","required":true,"in":"path","description":"Folder ID","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number (default: 1)","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page (default: 20, max: 200)","schema":{"type":"string"}},{"name":"search","required":false,"in":"query","description":"Search materials by name","schema":{"type":"string"}}],"responses":{"200":{"description":"Materials retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"materials":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string","description":"Material ID"},"name":{"type":"string","description":"Material name"},"organizationId":{"type":"string","description":"Organization ID"},"folderId":{"type":"string","description":"Folder ID","nullable":true},"contentType":{"type":"string","description":"Content type","enum":["text","pdf","video","audio","image","epub"]},"content":{"type":"object","description":"Material content","properties":{"text":{"type":"string"},"url":{"type":"string"},"s3Key":{"type":"string"},"s3Url":{"type":"string"},"filename":{"type":"string"},"fileSize":{"type":"number"},"mimeType":{"type":"string"}}},"metadata":{"type":"object","description":"Material metadata"},"status":{"type":"string","description":"Material status","enum":["active","processing","pending_upload","error","deleted"]},"usage":{"type":"object","description":"Usage information"},"references":{"description":"References that this material cites","type":"array","items":{"type":"object","properties":{"title":{"type":"string","example":"Understanding Photosynthesis","description":"Reference title"},"url":{"type":"string","example":"https://example.com/article","description":"Reference URL"}},"required":["title"]}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","name","organizationId","folderId","contentType","content","status","createdAt","updatedAt"]}},"totalCount":{"type":"number"},"page":{"type":"number"},"totalPages":{"type":"number"}}}}}}},"tags":["Folders"],"security":[{"x-api-key":[]}]}},"/api/v1/folders/{id}/move":{"patch":{"operationId":"move","summary":"Move folder to new parent","parameters":[{"name":"id","required":true,"in":"path","description":"Folder ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"parentFolderId":{"type":"string","description":"New parent folder ID or null for root level","nullable":true}},"required":["parentFolderId"]}}}},"responses":{"200":{"description":"Folder moved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Folder ID"},"name":{"type":"string","description":"Folder name"},"organizationId":{"type":"string","description":"Organization ID"},"parentFolderId":{"type":"string","description":"Parent folder ID","nullable":true},"description":{"type":"string","description":"Folder description"},"status":{"type":"string","description":"Folder status","enum":["active","deleted"]},"metadata":{"description":"Folder metadata","allOf":[{"type":"object","properties":{"color":{"type":"string","description":"Folder color"},"icon":{"type":"string","description":"Folder icon"},"materialCount":{"type":"number","description":"Number of materials in folder"},"totalSize":{"type":"number","description":"Total size of materials in folder"},"lastActivity":{"format":"date-time","type":"string","description":"Last activity date"}}}]},"createdAt":{"format":"date-time","type":"string","description":"Creation date"},"updatedAt":{"format":"date-time","type":"string","description":"Last update date"}},"required":["_id","name","organizationId","status","createdAt","updatedAt"]}}}}},"tags":["Folders"],"security":[{"x-api-key":[]}]}},"/api/v1/components":{"get":{"operationId":"findAll","summary":"Get all components","parameters":[{"name":"type","required":false,"in":"query","description":"Filter by component type","schema":{"enum":["chat","data_analyst","flashcards","scenarios","practice_test","audio_recap","tutor_me","explainers","uploads","chat_analytics","video_generation","performance_insights"],"type":"string"}}],"responses":{"200":{"description":"Components retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string","description":"Component ID (MongoDB ObjectId)"},"componentId":{"type":"string","description":"Unique component identifier"},"type":{"type":"string","description":"Component type","enum":["chat","data_analyst","flashcards","scenarios","practice_test","audio_recap","tutor_me","explainers","uploads","chat_analytics","video_generation","performance_insights"]},"name":{"type":"string","description":"Component name"},"description":{"type":"string","description":"Component description"},"organization":{"type":"string","description":"Organization ID"},"config":{"type":"object","description":"Component configuration"},"status":{"type":"string","description":"Component status","enum":["active","inactive","draft"]},"usage":{"type":"object","description":"Usage statistics"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","componentId","type","name","organization","config","status","usage","createdAt","updatedAt"]}}}}}},"tags":["Components"],"security":[{"x-api-key":[]}]},"post":{"operationId":"create","summary":"Create a new component","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["chat","data_analyst","flashcards","scenarios","practice_test","audio_recap","tutor_me","explainers","uploads","chat_analytics","video_generation","performance_insights"],"description":"Type of component to create"},"name":{"type":"string","example":"My Study Component","description":"Name of the component"},"description":{"type":"string","example":"A component for studying biology","description":"Component description"},"config":{"description":"Component-specific configuration","oneOf":[{"type":"object","properties":{"materials":{"description":"Material IDs","type":"array","items":{"type":"string"}},"folders":{"description":"Folder IDs","type":"array","items":{"type":"string"}},"model":{"type":"string","example":"gpt-4o-mini-2024-07-18","description":"AI model to use"},"systemPrompt":{"type":"string","description":"System prompt for the chat"},"temperature":{"type":"number","minimum":0,"maximum":2,"description":"Temperature for response generation"},"maxTokens":{"type":"number","description":"Maximum tokens for response"},"enableWebSearch":{"type":"boolean","description":"Enable web search"},"enableRAGSearch":{"type":"boolean","description":"Enable RAG search"},"enableHistory":{"type":"boolean","description":"Enable conversation history"},"enableVoice":{"type":"boolean","description":"Enable voice interactions"},"enableFollowUps":{"type":"boolean","description":"Enable follow-up questions"},"enableComponentCreation":{"type":"boolean","description":"Enable component creation"},"maxSteps":{"type":"number","description":"Maximum steps for multi-step tool calls"},"enableGuardrails":{"type":"boolean","description":"Enable guardrails for content moderation"},"enableMessageGrading":{"type":"boolean","description":"Enable message grading for prompt improvement suggestions","default":true},"guardrailRules":{"description":"Guardrail rules for content moderation","example":[{"id":"rule-1","description":"No direct homework answers","condition":"The AI response provides direct answers to homework","action":"block","message":"I cannot provide direct answers to homework questions."}],"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the rule"},"description":{"type":"string","description":"Description of the rule"},"condition":{"type":"string","description":"Condition to check"},"action":{"type":"string","enum":["block","warn","modify"],"description":"Action to take when rule is triggered"},"message":{"type":"string","description":"Message to show when rule is triggered"}},"required":["id","description","condition","action"]}},"enableReferenceMode":{"type":"boolean","description":"Enable reference mode - show references instead of source content"},"enableFeedback":{"type":"boolean","description":"Enable thumbs up/down feedback with reason","default":true},"hideTitle":{"type":"boolean","description":"Hide the chat title and avatar in the embedded component"},"emptyStateHtml":{"type":"string","description":"Custom HTML to show in empty state instead of default icon and text"},"hideEmptyState":{"type":"boolean","description":"Hide the default empty state (icon and text)"}},"required":["model"]},{"type":"object","properties":{"materials":{"description":"Material IDs","type":"array","items":{"type":"string"}},"folders":{"description":"Folder IDs","type":"array","items":{"type":"string"}},"model":{"type":"string","example":"gpt-4o-mini-2024-07-18","description":"AI model to use"},"systemPrompt":{"type":"string","description":"System prompt for the data analyst"},"temperature":{"type":"number","minimum":0,"maximum":2,"description":"Temperature for response generation"},"maxTokens":{"type":"number","description":"Maximum tokens for response"},"enableWebSearch":{"type":"boolean","description":"Enable web search"},"enableRAGSearch":{"type":"boolean","description":"Enable RAG search"},"enableHistory":{"type":"boolean","description":"Enable conversation history"},"enableVoice":{"type":"boolean","description":"Enable voice interactions"},"enableFollowUps":{"type":"boolean","description":"Enable follow-up questions"},"enableComponentCreation":{"type":"boolean","description":"Enable component creation"},"maxSteps":{"type":"number","description":"Maximum steps for multi-step tool calls"},"groupIds":{"description":"Group IDs to filter data","type":"array","items":{"type":"string"}}},"required":["model"]},{"type":"object","properties":{"materials":{"description":"Material IDs","type":"array","items":{"type":"string"}},"folders":{"description":"Folder IDs","type":"array","items":{"type":"string"}},"model":{"type":"string","description":"AI model to use for flashcard generation","example":"gpt-4o-mini-2024-07-18"},"difficulty":{"type":"string","enum":["easy","medium","hard","mixed"],"description":"Difficulty level"},"totalFlashcards":{"type":"number","description":"Total number of flashcards to generate"},"viewMode":{"type":"string","enum":["spaced_repetition","normal"],"description":"View mode for flashcards"},"cardTypes":{"description":"Types of flashcards","type":"array","items":{"type":"string"}},"maxReviewInterval":{"type":"number","description":"Maximum review interval in days"},"learningSteps":{"type":"string","description":"Learning steps configuration"}}},{"type":"object","properties":{"materials":{"description":"Material IDs","type":"array","items":{"type":"string"}},"folders":{"description":"Folder IDs","type":"array","items":{"type":"string"}},"model":{"type":"string","description":"AI model to use for scenario generation","example":"gpt-4o-mini-2024-07-18"},"context":{"type":"string","description":"Scenario context"},"goal":{"type":"string","description":"Scenario goal"},"format":{"type":"string","description":"Scenario format"},"greetingMessage":{"type":"string","description":"Greeting message"},"greetingCharacterId":{"type":"string","description":"Character ID for greeting"},"requiresFinalAnswer":{"type":"boolean","description":"Requires final answer"},"finalAnswerPrompt":{"type":"string","description":"Final answer prompt"},"characters":{"description":"Scenario characters","type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Character ID"},"name":{"type":"string","description":"Character name"},"role":{"type":"string","description":"Character role"},"description":{"type":"string","description":"Character description"}},"required":["id","name","role"]}},"tools":{"description":"Available tools","type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Tool ID"},"name":{"type":"string","description":"Tool name"},"description":{"type":"string","description":"Tool description (what it does / shows)"},"type":{"type":"string","description":"Tool type (e.g. Database, Document)"},"dataFormat":{"type":"string","description":"Data format provided by the tool"}},"required":["id","name","description","type"]}},"criteria":{"description":"Authored evaluation criteria. If omitted/empty at create time, the AI will generate criteria.","type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Stable identifier for this criterion"},"description":{"type":"string","description":"What this criterion measures"},"weight":{"type":"number","description":"Importance weight 1-10","minimum":1,"maximum":10}},"required":["id","description","weight"]}},"enableHistory":{"type":"boolean","description":"Enable history"},"enableVoice":{"type":"boolean","description":"Enable voice"},"placeholderText":{"type":"string","description":"Placeholder text"}}},{"type":"object","properties":{"materials":{"description":"Material IDs","type":"array","items":{"type":"string"}},"folders":{"description":"Folder IDs","type":"array","items":{"type":"string"}},"model":{"type":"string","description":"AI model to use for question generation and grading","example":"gpt-4o-mini-2024-07-18"},"questionTypes":{"description":"Question types","example":["multiplechoice","truefalse"],"type":"array","items":{"type":"string"}},"questionsPerTest":{"type":"number","description":"Number of questions per test"},"difficulty":{"type":"string","enum":["easy","medium","hard","mixed"],"description":"Difficulty level"},"timeLimit":{"type":"number","description":"Time limit in minutes"},"allowRetakes":{"type":"boolean","description":"Allow retakes"},"showCorrectAnswers":{"type":"boolean","description":"Show correct answers after submission"},"randomizeQuestions":{"type":"boolean","description":"Randomize question order"},"randomizeAnswers":{"type":"boolean","description":"Randomize answer order"},"maxAttempts":{"type":"number","description":"Maximum attempts allowed"},"passingScore":{"type":"number","description":"Passing score percentage"},"showExplanations":{"type":"boolean","description":"Show explanations for answers"},"aiGenerationMode":{"type":"string","enum":["balanced","comprehensive","focused","adaptive"],"description":"AI generation mode"},"questionDistribution":{"description":"Distribution of question types","allOf":[{"type":"object","properties":{"multiplechoice":{"type":"number","description":"Number of multiple choice questions"},"truefalse":{"type":"number","description":"Number of true/false questions"},"shortanswer":{"type":"number","description":"Number of short answer questions"},"frq":{"type":"number","description":"Number of free response questions"},"fillinblank":{"type":"number","description":"Number of fill in the blank questions"}}}]}},"required":["questionTypes"]},{"type":"object","properties":{"materials":{"description":"Material IDs","type":"array","items":{"type":"string"}},"folders":{"description":"Folder IDs","type":"array","items":{"type":"string"}},"duration":{"type":"number","description":"Duration of audio recap in minutes","example":10},"numParts":{"type":"number","description":"Number of parts to split the audio into","example":5},"isMultiVoice":{"type":"boolean","description":"Enable multi-voice conversation mode"},"voice1":{"type":"string","description":"Secondary voice for multi-voice mode. Public names: Alex, Morgan, Riley, Jordan, Sparky, Taylor.","enum":["Alex","Morgan","Riley","Jordan","Sparky","Taylor"]},"voice2":{"type":"string","description":"Secondary voice for multi-voice mode. Public names: Alex, Morgan, Riley, Jordan, Sparky, Taylor.","enum":["Alex","Morgan","Riley","Jordan","Sparky","Taylor"]},"topic":{"type":"string","description":"Specific topic to focus on"},"theme":{"type":"string","description":"Theme or style for the audio recap"},"model":{"type":"string","description":"AI model to use for generation","example":"gpt-4.1-2025-04-14"},"recapType":{"type":"string","enum":["SUMMARY","LECTURE","PODCAST","AUDIO_BOOK"],"description":"Type of audio recap"},"excludedMaterialIds":{"description":"Material IDs to exclude when expanding selected folders. Has no effect on materials picked directly via `materials`.","type":"array","items":{"type":"string"}}}},{"type":"object","properties":{"materials":{"description":"Material IDs","type":"array","items":{"type":"string"}},"folders":{"description":"Folder IDs","type":"array","items":{"type":"string"}},"title":{"type":"string","description":"Video title (defaults to component name if not provided)"},"model":{"type":"string","description":"AI model to use for generation","example":"gpt-4o-mini-2024-07-18"},"style":{"type":"string","description":"Video style","example":"professional"},"targetLength":{"type":"number","description":"Target length in seconds","minimum":15,"maximum":1200},"webSearch":{"type":"boolean","description":"Enable web search for additional content"},"imageSearch":{"type":"boolean","description":"Enable image search for visuals"},"verticalVideo":{"type":"boolean","description":"Create vertical video format (9:16)"}}},{"type":"object","properties":{"materials":{"description":"Material IDs","type":"array","items":{"type":"string"}},"folders":{"description":"Folder IDs","type":"array","items":{"type":"string"}},"folderId":{"type":"string","description":"Folder ID where uploads will be stored"}},"required":["folderId"]},{"type":"object","properties":{"materials":{"description":"Material IDs","type":"array","items":{"type":"string"}},"folders":{"description":"Folder IDs","type":"array","items":{"type":"string"}},"tutorPersonality":{"type":"string","description":"Tutor personality"},"sessionDuration":{"type":"number","description":"Session duration in minutes"},"enableVideo":{"type":"boolean","description":"Enable video"},"enableVoice":{"type":"boolean","description":"Enable voice"}}},{"type":"object","properties":{"chatComponentId":{"type":"string","description":"ID of the chat component to analyze"},"dateRange":{"type":"number","description":"Default date range in days","default":30},"autoRefresh":{"type":"boolean","description":"Enable auto-refresh"},"refreshInterval":{"type":"number","description":"Refresh interval in minutes","minimum":1,"maximum":60},"showUserStats":{"type":"boolean","description":"Show user statistics section","default":true},"showSummary":{"type":"boolean","description":"Show summary section","default":true},"showTopics":{"type":"boolean","description":"Show top topics","default":true},"enableExport":{"type":"boolean","description":"Enable CSV export functionality","default":true}},"required":["chatComponentId"]}]},"metadata":{"type":"object","description":"Additional metadata"}},"required":["type","name","config"]}}}},"responses":{"201":{"description":"Component created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Component ID (MongoDB ObjectId)"},"componentId":{"type":"string","description":"Unique component identifier"},"type":{"type":"string","description":"Component type","enum":["chat","data_analyst","flashcards","scenarios","practice_test","audio_recap","tutor_me","explainers","uploads","chat_analytics","video_generation","performance_insights"]},"name":{"type":"string","description":"Component name"},"description":{"type":"string","description":"Component description"},"organization":{"type":"string","description":"Organization ID"},"config":{"type":"object","description":"Component configuration"},"status":{"type":"string","description":"Component status","enum":["active","inactive","draft"]},"usage":{"type":"object","description":"Usage statistics"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","componentId","type","name","organization","config","status","usage","createdAt","updatedAt"]}}}}},"tags":["Components"],"security":[{"x-api-key":[]}]}},"/api/v1/components/{id}":{"get":{"operationId":"findOne","summary":"Get component by ID","parameters":[{"name":"id","required":true,"in":"path","description":"Component ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Component retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Component ID (MongoDB ObjectId)"},"componentId":{"type":"string","description":"Unique component identifier"},"type":{"type":"string","description":"Component type","enum":["chat","data_analyst","flashcards","scenarios","practice_test","audio_recap","tutor_me","explainers","uploads","chat_analytics","video_generation","performance_insights"]},"name":{"type":"string","description":"Component name"},"description":{"type":"string","description":"Component description"},"organization":{"type":"string","description":"Organization ID"},"config":{"type":"object","description":"Component configuration"},"status":{"type":"string","description":"Component status","enum":["active","inactive","draft"]},"usage":{"type":"object","description":"Usage statistics"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","componentId","type","name","organization","config","status","usage","createdAt","updatedAt"]}}}},"404":{"description":"Component not found"}},"tags":["Components"],"security":[{"x-api-key":[]}]},"patch":{"operationId":"update","summary":"Update component","parameters":[{"name":"id","required":true,"in":"path","description":"Component ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["draft","active","inactive","processing","error"],"description":"Component status"}}}}}},"responses":{"200":{"description":"Component updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Component ID (MongoDB ObjectId)"},"componentId":{"type":"string","description":"Unique component identifier"},"type":{"type":"string","description":"Component type","enum":["chat","data_analyst","flashcards","scenarios","practice_test","audio_recap","tutor_me","explainers","uploads","chat_analytics","video_generation","performance_insights"]},"name":{"type":"string","description":"Component name"},"description":{"type":"string","description":"Component description"},"organization":{"type":"string","description":"Organization ID"},"config":{"type":"object","description":"Component configuration"},"status":{"type":"string","description":"Component status","enum":["active","inactive","draft"]},"usage":{"type":"object","description":"Usage statistics"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["_id","componentId","type","name","organization","config","status","usage","createdAt","updatedAt"]}}}}},"tags":["Components"],"security":[{"x-api-key":[]}]},"delete":{"operationId":"remove","summary":"Delete component","parameters":[{"name":"id","required":true,"in":"path","description":"Component ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Component deleted successfully"}},"tags":["Components"],"security":[{"x-api-key":[]}]}},"/api/v1/components/{id}/activate":{"post":{"operationId":"activate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Components"],"security":[{"x-api-key":[]}]}},"/api/v1/components/{id}/deactivate":{"post":{"operationId":"deactivate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Components"],"security":[{"x-api-key":[]}]}},"/api/v1/components/{id}/interact":{"post":{"operationId":"interact","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Components"],"security":[{"x-api-key":[]}]}},"/api/v1/components/{id}/embed":{"post":{"operationId":"generateEmbed","summary":"Generate embed code for component","parameters":[{"name":"id","required":true,"in":"path","description":"Component ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"userId":{"type":"string","description":"User ID for tracking"},"studentName":{"type":"string","description":"Student name for display and tracking"},"groupIds":{"description":"Group IDs for collaboration","example":["class-101","class-102"],"type":"array","items":{"type":"string"}},"sessionId":{"type":"string","description":"Session ID for continuity"},"theme":{"description":"Theme customization","allOf":[{"type":"object","properties":{"primaryColor":{"type":"string","description":"Primary color (hex)"},"secondaryColor":{"type":"string","description":"Secondary color (hex)"},"backgroundColor":{"type":"string","description":"Background color (hex)"},"textColor":{"type":"string","description":"Text color (hex)"},"fontFamily":{"type":"string","description":"Font family"},"fontSize":{"type":"string","description":"Font size"},"borderRadius":{"type":"string","description":"Border radius"},"padding":{"type":"string","description":"Padding"},"logoUrl":{"type":"string","description":"Logo URL"},"hideBranding":{"type":"boolean","description":"Hide branding"}}}]},"features":{"description":"Feature toggles","allOf":[{"type":"object","properties":{"enableWebSearch":{"type":"boolean","description":"Enable web search"},"enableHistory":{"type":"boolean","description":"Enable history"},"enableVoice":{"type":"boolean","description":"Enable voice input"},"enableFollowUps":{"type":"boolean","description":"Enable follow-up questions"},"enableComponentCreation":{"type":"boolean","description":"Enable component creation"},"placeholderText":{"type":"string","description":"Placeholder text"},"enableWebSearchSources":{"type":"boolean","description":"Enable web search sources"},"enableImageSources":{"type":"boolean","description":"Enable image sources"},"enableTranscript":{"type":"boolean","description":"Enable transcript"},"enableOutline":{"type":"boolean","description":"Enable outline"},"enableBadWordsFilter":{"type":"boolean","description":"Enable bad words filter"},"enableGuardrails":{"type":"boolean","description":"Enable guardrails"},"enablePromptingScore":{"type":"boolean","description":"Enable prompting quality score","default":true},"enableResponsibilityScore":{"type":"boolean","description":"Enable learning responsibility score","default":true},"enableReferenceMode":{"type":"boolean","description":"Enable reference mode - show references instead of source content"},"enableFeedback":{"type":"boolean","description":"Enable thumbs up/down feedback with reason","default":true},"hideTitle":{"type":"boolean","description":"Hide the chat title and avatar in the embedded component"},"emptyStateHtml":{"type":"string","description":"Custom HTML to show in empty state instead of default icon and text"},"hideEmptyState":{"type":"boolean","description":"Hide the default empty state (icon and text)"}},"required":["enableBadWordsFilter"]}]},"width":{"type":"string","description":"Embed width (e.g., \"100%\", \"600px\")"},"height":{"type":"string","description":"Embed height (e.g., \"400px\", \"100vh\")"},"expiryHours":{"type":"number","description":"Token expiry time in hours","default":1}}}}}},"responses":{"200":{"description":"Embed code generated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"embedUrl":{"type":"string","description":"The embed URL for iframe integration"},"token":{"type":"string","description":"JWT token for authentication"},"expiresAt":{"format":"date-time","type":"string","description":"Token expiration timestamp"},"componentId":{"type":"string","description":"Component ID"},"componentType":{"type":"string","description":"Component type"},"options":{"type":"object","description":"Embed options","properties":{"width":{"type":"string","description":"Embed width"},"height":{"type":"string","description":"Embed height"}}}},"required":["embedUrl","token","expiresAt","componentId","componentType","options"]}}}}},"tags":["Components"],"security":[{"x-api-key":[]}]}},"/api/v1/usage/events":{"get":{"operationId":"getUsageEvents","summary":"Get usage events","parameters":[{"name":"startDate","required":false,"in":"query","description":"Start date for filtering (ISO 8601)","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"End date for filtering (ISO 8601)","schema":{"type":"string"}},{"name":"eventType","required":false,"in":"query","description":"Filter by event type","schema":{"enum":["material_created","material_uploaded","material_processed","material_deleted","component_created","component_accessed","component_deleted","component_usage","chat_message_sent","chat_session_started","chat_session_ended","chat_feedback","test_created","test_started","test_completed","test_question_answered","test_retaken","audio_recap_create","audio_recap_progress","audio_recap_feedback","assignment_grader_create","video_generation_created","video_generation_completed","video_generation_failed","api_call","cache_hit","sso_login","sso_logout","student_performance"],"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Filter by user ID","schema":{"type":"string"}},{"name":"groupId","required":false,"in":"query","description":"Filter by group ID","schema":{"type":"string"}},{"name":"resourceId","required":false,"in":"query","description":"Filter by resource ID","schema":{"type":"string"}},{"name":"componentType","required":false,"in":"query","description":"Filter by component type","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Number of results to return","schema":{"minimum":1,"maximum":1000,"default":100,"type":"number"}},{"name":"offset","required":false,"in":"query","description":"Offset for pagination","schema":{"minimum":0,"default":0,"type":"number"}}],"responses":{"200":{"description":"Usage events retrieved"}},"tags":["Usage Tracking"],"security":[{"x-api-key":[]}]}},"/api/v1/usage/events/export":{"get":{"operationId":"exportUsageEvents","summary":"Export usage events matching the given filters as CSV","parameters":[{"name":"startDate","required":false,"in":"query","description":"Start date for filtering (ISO 8601)","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"End date for filtering (ISO 8601)","schema":{"type":"string"}},{"name":"eventType","required":false,"in":"query","description":"Filter by event type","schema":{"enum":["material_created","material_uploaded","material_processed","material_deleted","component_created","component_accessed","component_deleted","component_usage","chat_message_sent","chat_session_started","chat_session_ended","chat_feedback","test_created","test_started","test_completed","test_question_answered","test_retaken","audio_recap_create","audio_recap_progress","audio_recap_feedback","assignment_grader_create","video_generation_created","video_generation_completed","video_generation_failed","api_call","cache_hit","sso_login","sso_logout","student_performance"],"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Filter by user ID","schema":{"type":"string"}},{"name":"groupId","required":false,"in":"query","description":"Filter by group ID","schema":{"type":"string"}},{"name":"resourceId","required":false,"in":"query","description":"Filter by resource ID","schema":{"type":"string"}},{"name":"componentType","required":false,"in":"query","description":"Filter by component type","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Restrict the export to a single page of results","schema":{"minimum":1,"maximum":1000,"type":"number"}},{"name":"offset","required":false,"in":"query","description":"Offset of the page to export, used with limit","schema":{"minimum":0,"type":"number"}}],"responses":{"200":{"description":"CSV export of usage events","content":{"text/csv":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Result set exceeds the export row limit"}},"tags":["Usage Tracking"],"security":[{"x-api-key":[]}]}},"/api/v1/usage/summary":{"get":{"operationId":"getUsageSummary","summary":"Get usage summary","parameters":[{"name":"period","required":true,"in":"query","description":"Summary period","schema":{"enum":["hourly","daily","monthly"],"type":"string"}},{"name":"startDate","required":true,"in":"query","description":"Start date for summary (ISO 8601)","schema":{"type":"string"}},{"name":"endDate","required":true,"in":"query","description":"End date for summary (ISO 8601)","schema":{"type":"string"}},{"name":"groupBy","required":false,"in":"query","description":"Group results by","schema":{"enum":["user","group","model","endpoint"],"type":"string"}}],"responses":{"200":{"description":"Usage summary retrieved"}},"tags":["Usage Tracking"],"security":[{"x-api-key":[]}]}},"/api/v1/usage/stats":{"get":{"operationId":"getUsageStats","summary":"Get usage statistics","parameters":[{"name":"startDate","required":false,"in":"query","description":"Start date for stats (ISO 8601)","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"End date for stats (ISO 8601)","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Filter by user ID","schema":{"type":"string"}},{"name":"groupId","required":false,"in":"query","description":"Filter by group ID","schema":{"type":"string"}},{"name":"componentType","required":false,"in":"query","description":"Filter by component type","schema":{"type":"string"}},{"name":"resourceId","required":false,"in":"query","description":"Filter by resource ID (component ID)","schema":{"type":"string"}}],"responses":{"200":{"description":"Usage statistics retrieved"}},"tags":["Usage Tracking"],"security":[{"x-api-key":[]}]}},"/api/v1/usage-analyst/events":{"get":{"operationId":"getAllEvents","summary":"Get all events based on filters","parameters":[{"name":"eventType","required":true,"in":"query","description":"Type of usage event to filter","schema":{"enum":["material_created","material_uploaded","material_processed","material_deleted","component_created","component_accessed","component_deleted","component_usage","chat_message_sent","chat_session_started","chat_session_ended","chat_feedback","test_created","test_started","test_completed","test_question_answered","test_retaken","audio_recap_create","audio_recap_progress","audio_recap_feedback","assignment_grader_create","video_generation_created","video_generation_completed","video_generation_failed","api_call","cache_hit","sso_login","sso_logout","student_performance"],"type":"string"}},{"name":"startDate","required":true,"in":"query","description":"Start date for filtering (ISO 8601)","schema":{"type":"string"}},{"name":"endDate","required":true,"in":"query","description":"End date for filtering (ISO 8601)","schema":{"type":"string"}},{"name":"userIds","required":false,"in":"query","description":"Array of user IDs to filter","schema":{"example":["user123","user456"],"type":"array","items":{"type":"string"}}},{"name":"groupIds","required":false,"in":"query","description":"Array of group IDs to filter","schema":{"example":["class-101","class-102"],"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"Events retrieved successfully"}},"tags":["Usage Analyst"],"security":[{"x-api-key":[]}]}},"/api/v1/usage-analyst/test-questions":{"get":{"operationId":"getTestQuestions","summary":"Get test results with full question data for user or group","parameters":[{"name":"userId","required":false,"in":"query","description":"User ID to get test results for","schema":{"type":"string"}},{"name":"groupIds","required":false,"in":"query","description":"Array of group IDs to filter","schema":{"example":["class-101","class-102"],"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"Test results with questions retrieved successfully"}},"tags":["Usage Analyst"],"security":[{"x-api-key":[]}]}},"/api/v1/usage-analyst/chat-messages":{"get":{"operationId":"getChatMessages","summary":"Get all chat messages from sessions for user or group","parameters":[{"name":"userId","required":false,"in":"query","description":"User ID to get chat messages for","schema":{"type":"string"}},{"name":"groupIds","required":false,"in":"query","description":"Array of group IDs to filter","schema":{"example":["class-101","class-102"],"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"Chat messages retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","items":{"type":"object","properties":{"sessionId":{"type":"string"},"userId":{"type":"string"},"componentId":{"type":"string"},"role":{"type":"string","enum":["user","assistant","system"]},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"metadata":{"type":"object"}}}},"total":{"type":"number"},"sessionCount":{"type":"number"}}}}}}},"tags":["Usage Analyst"],"security":[{"x-api-key":[]}]}},"/api/v1/embed/verify":{"get":{"operationId":"verifyToken","summary":"Verify embed token","parameters":[{"name":"token","required":true,"in":"query","description":"Embed token to verify","schema":{"type":"string"}}],"responses":{"200":{"description":"Token is valid"},"401":{"description":"Invalid token"}},"tags":["Embed"]}},"/api/v1/embed/refresh-token":{"post":{"operationId":"refreshToken","summary":"Refresh an embed token","description":"Re-issues an embed token with a fresh expiry while preserving its payload (including the host-supplied userContextJwt). Powers a sliding session so a long-running embed does not die when the 1-hour token lapses. Bounded by a total session-lifetime cap and a post-expiry grace window.","parameters":[],"requestBody":{"required":true,"description":"Current embed token to refresh","content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"The current (possibly recently expired) embed token"}},"required":["token"]}}}},"responses":{"200":{"description":"Refreshed embed token"},"401":{"description":"Token cannot be refreshed; re-authentication required"}},"tags":["Embed"]}},"/api/v1/embed/theme":{"get":{"operationId":"getThemeCSS","summary":"Get theme CSS for embed","parameters":[{"name":"token","required":true,"in":"query","description":"Embed token","schema":{"type":"string"}}],"responses":{"200":{"description":"Theme CSS retrieved"}},"tags":["Embed"]}},"/api/v1/embed/health":{"get":{"operationId":"health","summary":"Health check endpoint","parameters":[],"responses":{"200":{"description":"Service is healthy"}},"tags":["Embed"]}},"/api/v1/embed/component/{componentId}":{"get":{"operationId":"getComponent","summary":"Get component data for embed","parameters":[{"name":"componentId","required":true,"in":"path","description":"Component ID or MongoDB _id","schema":{"type":"string"}},{"name":"token","required":true,"in":"query","description":"Embed token","schema":{"type":"string"}}],"responses":{"200":{"description":"Component data retrieved"},"400":{"description":"Invalid token or component ID"}},"tags":["Embed"]}},"/api/v1/embed/component/{componentId}/interact":{"post":{"operationId":"interact","summary":"Process embed interaction","parameters":[{"name":"componentId","required":true,"in":"path","description":"Component ID or MongoDB _id","schema":{"type":"string"}},{"name":"token","required":true,"in":"query","description":"Embed token","schema":{"type":"string"}},{"name":"x-embed-token","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Interaction data","content":{"application/json":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"Interaction processed"},"400":{"description":"Invalid request"}},"tags":["Embed"]}},"/api/v1/embed/component/{componentId}/transcribe":{"post":{"operationId":"transcribe","summary":"Transcribe audio for an embed (token-authenticated)","parameters":[{"name":"componentId","required":true,"in":"path","description":"Component ID or MongoDB _id","schema":{"type":"string"}},{"name":"token","required":true,"in":"query","description":"Embed token","schema":{"type":"string"}}],"responses":{"200":{"description":"Audio transcribed"}},"tags":["Embed"]}},"/api/v1/embed/context/push":{"post":{"operationId":"pushContext","summary":"Push context to embed instance","parameters":[{"name":"token","required":true,"in":"query","description":"Embed token","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Context to push","content":{"application/json":{"schema":{"type":"object","properties":{"context":{"type":"string","description":"Context string to add","example":"User is viewing question 1 about the lungs"}},"required":["context"]}}}},"responses":{"200":{"description":"Context pushed successfully"},"400":{"description":"Invalid token or missing context"}},"tags":["Embed"]}},"/api/v1/embed/context/clear":{"post":{"operationId":"clearContext","summary":"Clear context for embed instance","parameters":[{"name":"token","required":true,"in":"query","description":"Embed token","schema":{"type":"string"}}],"responses":{"200":{"description":"Context cleared successfully"},"400":{"description":"Invalid token"}},"tags":["Embed"]}},"/api/v1/embed/context":{"get":{"operationId":"getContext","summary":"Get current context for embed instance","parameters":[{"name":"token","required":true,"in":"query","description":"Embed token","schema":{"type":"string"}}],"responses":{"200":{"description":"Context retrieved successfully"},"400":{"description":"Invalid token"}},"tags":["Embed"]}},"/api/v1/chat/transcribe":{"post":{"operationId":"transcribeAudio","summary":"Transcribe audio to text","description":"Transcribes audio file to text using OpenAI Whisper. Supports various audio formats.","parameters":[],"responses":{"200":{"description":"Successfully transcribed audio","content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","description":"Transcribed text"}}}}}},"400":{"description":"No audio file provided"},"500":{"description":"Transcription failed"}},"tags":["Chat"],"security":[{"x-api-key":[]}]}},"/api/v1/chat/stream":{"post":{"operationId":"streamChat","summary":"Stream chat response","description":"Streams a chat response in real-time using server-sent events (SSE). Supports both AI SDK format (with messages array) and custom format (with message object).","parameters":[{"name":"x-component-id","required":false,"in":"header","description":"Optional component ID for component-specific chat context","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"description":"Messages array for AI SDK format - list of conversation messages with roles","example":[{"role":"user","content":"Hello"},{"role":"assistant","content":"Hi there!"},{"role":"user","content":[{"type":"text","text":"What is in this image?"},{"type":"image","image_url":{"url":"https://example.com/image.jpg"}}]}],"type":"array","items":{"type":"string"}},"message":{"description":"Single message for custom format - contains text and optional images","allOf":[{"type":"object","properties":{"text":{"type":"string","description":"Text content of the message"},"images":{"description":"Images attached to the message","type":"array","items":{"type":"object","properties":{"url":{"type":"string","description":"URL of the image"},"base64":{"type":"string","description":"Base64 encoded image data"},"mimeType":{"type":"string","description":"MIME type of the image"},"caption":{"type":"string","description":"Caption for the image"}}}}}}]},"componentId":{"type":"string","description":"Component ID"},"userId":{"type":"string","description":"User ID"},"groupIds":{"description":"Group IDs for access control","type":"array","items":{"type":"string"}},"sessionId":{"type":"string","description":"Session ID"},"id":{"type":"string","description":"Session ID (AI SDK uses \"id\")"},"timezone":{"type":"string","description":"IANA timezone string (e.g. \"America/New_York\")"},"context":{"type":"object","description":"Additional context"},"trigger":{"type":"string","description":"Trigger for AI SDK (what triggered the message)"}}}}}},"responses":{"200":{"description":"Successful streaming response (SSE format)"},"400":{"description":"Bad request - Invalid message format"},"401":{"description":"Unauthorized - Missing or invalid authentication"},"500":{"description":"Internal server error"}},"tags":["Chat"],"security":[{"x-api-key":[]}]}},"/api/v1/chat/prompts/export":{"get":{"operationId":"exportPrompts","summary":"Export user prompts as CSV","description":"Streams every question users asked a chat component, as CSV. Scope it with componentId and a date range. Reads the captured prompt projection; run the backfill once to include conversations from before capture shipped.","parameters":[{"name":"componentId","required":false,"in":"query","description":"Restrict to a single chat component (the identifier stored on the session — the component _id for embed traffic)","schema":{"type":"string"}},{"name":"sessionId","required":false,"in":"query","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","schema":{"type":"string"}},{"name":"groupId","required":false,"in":"query","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","description":"ISO 8601","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"ISO 8601","schema":{"type":"string"}}],"responses":{"200":{"description":"CSV export of user prompts","content":{"text/csv":{"schema":{"type":"string","format":"binary"}}}}},"tags":["Chat"],"security":[{"x-api-key":[]}]}},"/api/v1/chat/session/{sessionId}/export":{"get":{"operationId":"exportSessionPrompts","summary":"Export one conversation's user prompts as CSV","description":"Streams the questions asked in a single chat session, read from the stored GCS transcript. Works for conversations that predate prompt capture.","parameters":[{"name":"sessionId","required":true,"in":"path","description":"Chat session ID","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Session owner (used when authenticating via API key)","schema":{"type":"string"}}],"responses":{"200":{"description":"CSV export of the session's prompts","content":{"text/csv":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Conversation not found"}},"tags":["Chat"],"security":[{"x-api-key":[]}]}},"/api/v1/chat/feedback":{"get":{"operationId":"getFeedback","summary":"Get feedback data","description":"Retrieves feedback data for the organization with optional filtering","parameters":[{"name":"componentId","required":false,"in":"query","description":"Filter by component ID","schema":{"type":"string"}},{"name":"feedbackType","required":false,"in":"query","description":"Filter by feedback type","schema":{"enum":["thumbsUp","thumbsDown"],"type":"string"}},{"name":"userId","required":false,"in":"query","description":"Filter by user ID","schema":{"type":"string"}},{"name":"groupId","required":false,"in":"query","description":"Filter by group ID","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","description":"Filter by start date (ISO string)","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"Filter by end date (ISO string)","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Number of records to return (default: 100)","schema":{"type":"string"}},{"name":"skip","required":false,"in":"query","description":"Number of records to skip (default: 0)","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved feedback data"}},"tags":["Chat"],"security":[{"x-api-key":[]}]}},"/api/v1/chat/feedback/{feedbackId}/context":{"get":{"operationId":"getFeedbackContext","summary":"Get feedback context with message and conversation","description":"Retrieves the specific message and full conversation for a feedback item","parameters":[{"name":"feedbackId","required":true,"in":"path","description":"Feedback ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved feedback context"}},"tags":["Chat"],"security":[{"x-api-key":[]}]}},"/api/v1/chat-analytics/analyze":{"get":{"operationId":"getChatAnalytics","summary":"Get chat analytics and user statistics","parameters":[{"name":"componentId","required":false,"in":"query","description":"Component ID to analyze","schema":{"type":"string"}},{"name":"organizationId","required":false,"in":"query","description":"Organization ID to filter by","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"User ID to filter by","schema":{"type":"string"}},{"name":"groupIds","required":false,"in":"query","description":"Group IDs to filter by","schema":{"type":"array","items":{"type":"string"}}},{"name":"startDate","required":false,"in":"query","description":"Start date for analysis","schema":{"format":"date-time","type":"string"}},{"name":"endDate","required":false,"in":"query","description":"End date for analysis","schema":{"format":"date-time","type":"string"}},{"name":"modelKey","required":false,"in":"query","description":"AI model to use for analysis","schema":{"example":"gpt-4o-mini","type":"string"}}],"responses":{"200":{"description":"Chat analytics data","content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"description":"Analytics summary","allOf":[{"type":"object","properties":{"summary":{"type":"string","description":"Natural language summary of chat usage"},"totalUsers":{"type":"number","description":"Total unique users"},"totalSessions":{"type":"number","description":"Total chat sessions"},"totalMessages":{"type":"number","description":"Total messages"},"topTopics":{"description":"Top topics discussed","type":"array","items":{"type":"string"}},"averageMessagesPerUser":{"type":"number","description":"Average messages per user"},"engagement":{"type":"object","description":"Engagement metrics"},"overallAveragePromptingScore":{"type":"number","description":"Overall average prompting score (1-4 scale)"},"overallAverageResponsibilityScore":{"type":"number","description":"Overall average responsibility score (1-4 scale)"},"overallPromptingDistribution":{"type":"object","description":"Overall prompting score distribution"},"overallResponsibilityDistribution":{"type":"object","description":"Overall responsibility score distribution"}},"required":["summary","totalUsers","totalSessions","totalMessages","topTopics","averageMessagesPerUser","engagement"]}]},"userStats":{"description":"User statistics","type":"array","items":{"type":"object","properties":{"userId":{"type":"string","description":"User ID"},"email":{"type":"string","description":"User email"},"name":{"type":"string","description":"User name"},"totalMessages":{"type":"number","description":"Total messages sent by user"},"totalSessions":{"type":"number","description":"Total chat sessions"},"averageMessagesPerSession":{"type":"number","description":"Average messages per session"},"topTopics":{"description":"Top topics discussed","type":"array","items":{"type":"string"}},"lastActive":{"format":"date-time","type":"string","description":"Last active date"},"firstActive":{"format":"date-time","type":"string","description":"First active date"},"averageSessionDuration":{"type":"number","description":"Average session duration in minutes"},"groupIds":{"description":"Group IDs associated with the user","type":"array","items":{"type":"string"}},"averagePromptingScore":{"type":"number","description":"Average prompting score (1-4 scale)"},"averageResponsibilityScore":{"type":"number","description":"Average responsibility score (1-4 scale)"},"totalGradedMessages":{"type":"number","description":"Total messages graded"},"promptingDistribution":{"type":"object","description":"Prompting score distribution"},"responsibilityDistribution":{"type":"object","description":"Responsibility score distribution"}},"required":["userId","totalMessages","totalSessions","averageMessagesPerSession","topTopics","lastActive","firstActive","averageSessionDuration"]}},"generatedAt":{"format":"date-time","type":"string","description":"Date when analytics were generated"}},"required":["summary","userStats","generatedAt"]}}}}},"tags":["Chat Analytics"],"security":[{"x-api-key":[]}]}},"/api/v1/chat-analytics/component/{componentId}":{"get":{"operationId":"getComponentChatAnalytics","summary":"Get chat analytics for a specific component","parameters":[{"name":"componentId","required":true,"in":"path","description":"Component ID","schema":{"type":"string"}},{"name":"organizationId","required":false,"in":"query","description":"Organization ID to filter by","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"User ID to filter by","schema":{"type":"string"}},{"name":"groupIds","required":false,"in":"query","description":"Group IDs to filter by","schema":{"type":"array","items":{"type":"string"}}},{"name":"startDate","required":false,"in":"query","description":"Start date for analysis","schema":{"format":"date-time","type":"string"}},{"name":"endDate","required":false,"in":"query","description":"End date for analysis","schema":{"format":"date-time","type":"string"}},{"name":"modelKey","required":false,"in":"query","description":"AI model to use for analysis","schema":{"example":"gpt-4o-mini","type":"string"}}],"responses":{"200":{"description":"Component-specific chat analytics","content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"description":"Analytics summary","allOf":[{"type":"object","properties":{"summary":{"type":"string","description":"Natural language summary of chat usage"},"totalUsers":{"type":"number","description":"Total unique users"},"totalSessions":{"type":"number","description":"Total chat sessions"},"totalMessages":{"type":"number","description":"Total messages"},"topTopics":{"description":"Top topics discussed","type":"array","items":{"type":"string"}},"averageMessagesPerUser":{"type":"number","description":"Average messages per user"},"engagement":{"type":"object","description":"Engagement metrics"},"overallAveragePromptingScore":{"type":"number","description":"Overall average prompting score (1-4 scale)"},"overallAverageResponsibilityScore":{"type":"number","description":"Overall average responsibility score (1-4 scale)"},"overallPromptingDistribution":{"type":"object","description":"Overall prompting score distribution"},"overallResponsibilityDistribution":{"type":"object","description":"Overall responsibility score distribution"}},"required":["summary","totalUsers","totalSessions","totalMessages","topTopics","averageMessagesPerUser","engagement"]}]},"userStats":{"description":"User statistics","type":"array","items":{"type":"object","properties":{"userId":{"type":"string","description":"User ID"},"email":{"type":"string","description":"User email"},"name":{"type":"string","description":"User name"},"totalMessages":{"type":"number","description":"Total messages sent by user"},"totalSessions":{"type":"number","description":"Total chat sessions"},"averageMessagesPerSession":{"type":"number","description":"Average messages per session"},"topTopics":{"description":"Top topics discussed","type":"array","items":{"type":"string"}},"lastActive":{"format":"date-time","type":"string","description":"Last active date"},"firstActive":{"format":"date-time","type":"string","description":"First active date"},"averageSessionDuration":{"type":"number","description":"Average session duration in minutes"},"groupIds":{"description":"Group IDs associated with the user","type":"array","items":{"type":"string"}},"averagePromptingScore":{"type":"number","description":"Average prompting score (1-4 scale)"},"averageResponsibilityScore":{"type":"number","description":"Average responsibility score (1-4 scale)"},"totalGradedMessages":{"type":"number","description":"Total messages graded"},"promptingDistribution":{"type":"object","description":"Prompting score distribution"},"responsibilityDistribution":{"type":"object","description":"Responsibility score distribution"}},"required":["userId","totalMessages","totalSessions","averageMessagesPerSession","topTopics","lastActive","firstActive","averageSessionDuration"]}},"generatedAt":{"format":"date-time","type":"string","description":"Date when analytics were generated"}},"required":["summary","userStats","generatedAt"]}}}}},"tags":["Chat Analytics"],"security":[{"x-api-key":[]}]}},"/api/v1/chat-analytics/export":{"get":{"operationId":"exportChatAnalytics","summary":"Export chat analytics data as CSV","parameters":[{"name":"componentId","required":false,"in":"query","description":"Component ID to analyze","schema":{"type":"string"}},{"name":"organizationId","required":false,"in":"query","description":"Organization ID to filter by","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","description":"User ID to filter by","schema":{"type":"string"}},{"name":"groupIds","required":false,"in":"query","description":"Group IDs to filter by","schema":{"type":"array","items":{"type":"string"}}},{"name":"startDate","required":false,"in":"query","description":"Start date for analysis","schema":{"format":"date-time","type":"string"}},{"name":"endDate","required":false,"in":"query","description":"End date for analysis","schema":{"format":"date-time","type":"string"}},{"name":"modelKey","required":false,"in":"query","description":"AI model to use for analysis","schema":{"example":"gpt-4o-mini","type":"string"}}],"responses":{"200":{"description":"CSV export of chat analytics","content":{"text/csv":{"schema":{"type":"string","format":"binary"}}}}},"tags":["Chat Analytics"],"security":[{"x-api-key":[]}]}},"/api/v1/audio-recaps/components/{componentId}":{"get":{"operationId":"retrieveGenerationStatus","summary":"Retrieve audio recap generation status","description":"Returns script-generation status for the recap and audio-generation status for each section. Accepts the public component id or the component Mongo _id. recap is null until generation has created the recap row.","parameters":[{"name":"componentId","required":true,"in":"path","description":"Public component id (audio_recap_…) or the component Mongo _id","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"recap":{"nullable":true,"description":"Null until the recap row exists. Poll until it is present.","allOf":[{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"generationCompleted":{"type":"boolean","description":"True once section scripts have been written."},"generationStatus":{"type":"string","enum":["pending","completed","failed"],"description":"Script generation for the recap. pending, completed, or failed."},"generationError":{"type":"string","description":"Present when generationStatus is failed."}},"required":["id","title","generationCompleted","generationStatus"]}]},"sections":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"order":{"type":"number"},"generated":{"type":"boolean","description":"Audio for this section is ready."},"generating":{"type":"boolean","description":"Text-to-speech for this section is in progress."},"errorMsg":{"type":"string","description":"Set when audio generation failed for this section."}},"required":["id","order","generated","generating"]}}},"required":["recap","sections"]}}}},"404":{"description":"Audio recap component not found in this organization"}},"tags":["Audio Recaps"],"security":[{"x-api-key":[]}]}},"/api/v1/audio-recaps/users/{userId}/progress":{"get":{"operationId":"listUserProgress","summary":"List a user's progress across audio recaps","description":"Returns recap-level progress for one user on each requested audio recap component: completion, approximate length, listened and remaining seconds. Pass componentIds (public component ids or component Mongo _ids, up to 100) as a comma-separated list or repeated parameter. When componentIds is omitted, every recap the user has progress on is returned. Ids that are not audio recap components in this organization are listed in notFound.","parameters":[{"name":"userId","required":true,"in":"path","description":"Embed-token userId","schema":{"type":"string"}},{"name":"componentIds","required":false,"in":"query","description":"Audio recap component ids (max 100). Omit to return every recap the user has started.","schema":{"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"userId":{"type":"string"},"recaps":{"description":"One entry per resolved component, in request order.","type":"array","items":{"type":"object","properties":{"componentId":{"type":"string","description":"Public component id (audio_recap_…)."},"generationStatus":{"type":"string","enum":["pending","completed","failed"],"description":"Script generation for the recap."},"completionPct":{"type":"number","description":"sectionsCompleted / totalSections, 0–100."},"totalSections":{"type":"number","description":"Number of sections in the recap."},"sectionsCompleted":{"type":"number","description":"Sections this user has completed."},"durationSeconds":{"type":"number","description":"Approximate length of the recap in seconds. Uses the generated audio length per section, or an estimate from the script while audio is not ready."},"listenedSeconds":{"type":"number","description":"Approximate seconds the user has listened to."},"remainingSeconds":{"type":"number","description":"durationSeconds - listenedSeconds."},"lastActivityAt":{"type":"string","format":"date-time","nullable":true,"description":"Most recent progress update from this user. Null if the user has not started."}},"required":["componentId","generationStatus","completionPct","totalSections","sectionsCompleted","durationSeconds","listenedSeconds","remainingSeconds","lastActivityAt"]}},"notFound":{"description":"Requested ids that are not audio recap components in this organization.","type":"array","items":{"type":"string"}}},"required":["userId","recaps","notFound"]}}}},"400":{"description":"More than 100 componentIds"}},"tags":["Audio Recaps"],"security":[{"x-api-key":[]}]}},"/api/v1/assignment-grader/create":{"post":{"operationId":"createAssignmentGrader","summary":"Grade a new assignment","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"Title of the assignment"},"materialId":{"type":"string","description":"Material ID to grade"},"textToGrade":{"type":"string","description":"Text content to grade"},"userId":{"type":"string","description":"User ID for tracking"},"model":{"type":"string","description":"AI model to use"},"rubric":{"description":"Grading rubric","allOf":[{"type":"object","properties":{"criteria":{"description":"Grading criteria","type":"array","items":{"type":"object","properties":{"title":{"type":"string","description":"Title of the criterion"},"description":{"type":"string","description":"Description of the criterion"},"pointsPossible":{"type":"number","description":"Points possible for this criterion"}},"required":["title","pointsPossible"]}},"assignmentContent":{"type":"string","description":"Additional context for the assignment such as a reading passage, source material, or instructions that students were given. The AI grader will use this to evaluate submissions more accurately."}},"required":["criteria"]}]},"rubricTemplateId":{"type":"string","description":"Rubric template ID to use"},"assignmentId":{"type":"string","description":"Assignment ID for grouping submissions"},"studentIdentifier":{"type":"string","description":"Student identifier (email or ID)"},"assignmentContent":{"type":"string","description":"Additional context for the assignment such as a reading passage, source material, or instructions that students were given. The AI grader will use this to evaluate submissions more accurately."},"gradingPromptVersion":{"type":"string","description":"Grading prompt version to use. Pass \"QA\" to test the updated lenient prompt. Defaults to the current production prompt.","example":"QA"}},"required":["title"]}}}},"responses":{"201":{"description":"Assignment grading completed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"gradedAssignment":{"type":"object","properties":{"_id":{"type":"string","description":"Assignment grader ID"},"title":{"type":"string","description":"Assignment title"},"grade":{"type":"number","description":"Overall grade percentage"},"rubric":{"type":"object","description":"Grading results"},"organizationId":{"type":"string","description":"Organization ID"},"userId":{"type":"string","description":"User ID"},"materialId":{"type":"string","description":"Material ID"},"textToGrade":{"type":"string","description":"Text that was graded"},"rubricTemplateId":{"type":"string","description":"Rubric template ID"},"assignmentId":{"type":"string","description":"Assignment ID for grouping"},"studentIdentifier":{"type":"string","description":"Student identifier"},"assignmentContent":{"type":"string","description":"Assignment content/context provided for grading"},"gradingPromptVersion":{"type":"string","description":"Grading prompt version used for this submission","example":"default"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Update timestamp"},"__v":{"type":"number","description":"Version key"}},"required":["_id","title","grade","rubric","organizationId","createdAt","updatedAt","__v"]}}}}}}},"tags":["Assignment Grader"],"security":[{"x-api-key":[]}]}},"/api/v1/assignment-grader/get":{"get":{"operationId":"getAllAssignmentGraders","summary":"Get all assignment graders","parameters":[],"responses":{"200":{"description":"All assignment graders retrieved","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string","description":"Assignment grader ID"},"title":{"type":"string","description":"Assignment title"},"grade":{"type":"number","description":"Overall grade percentage"},"rubric":{"type":"object","description":"Grading results"},"organizationId":{"type":"string","description":"Organization ID"},"userId":{"type":"string","description":"User ID"},"materialId":{"type":"string","description":"Material ID"},"textToGrade":{"type":"string","description":"Text that was graded"},"rubricTemplateId":{"type":"string","description":"Rubric template ID"},"assignmentId":{"type":"string","description":"Assignment ID for grouping"},"studentIdentifier":{"type":"string","description":"Student identifier"},"assignmentContent":{"type":"string","description":"Assignment content/context provided for grading"},"gradingPromptVersion":{"type":"string","description":"Grading prompt version used for this submission","example":"default"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Update timestamp"},"__v":{"type":"number","description":"Version key"}},"required":["_id","title","grade","rubric","organizationId","createdAt","updatedAt","__v"]}}}}}},"tags":["Assignment Grader"],"security":[{"x-api-key":[]}]}},"/api/v1/assignment-grader/get/{id}":{"get":{"operationId":"getAssignmentGrader","summary":"Get an assignment grader by ID","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Assignment grader retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Assignment grader ID"},"title":{"type":"string","description":"Assignment title"},"grade":{"type":"number","description":"Overall grade percentage"},"rubric":{"type":"object","description":"Grading results"},"organizationId":{"type":"string","description":"Organization ID"},"userId":{"type":"string","description":"User ID"},"materialId":{"type":"string","description":"Material ID"},"textToGrade":{"type":"string","description":"Text that was graded"},"rubricTemplateId":{"type":"string","description":"Rubric template ID"},"assignmentId":{"type":"string","description":"Assignment ID for grouping"},"studentIdentifier":{"type":"string","description":"Student identifier"},"assignmentContent":{"type":"string","description":"Assignment content/context provided for grading"},"gradingPromptVersion":{"type":"string","description":"Grading prompt version used for this submission","example":"default"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Update timestamp"},"__v":{"type":"number","description":"Version key"}},"required":["_id","title","grade","rubric","organizationId","createdAt","updatedAt","__v"]}}}}},"tags":["Assignment Grader"],"security":[{"x-api-key":[]}]}},"/api/v1/assignment-grader/delete/{id}":{"delete":{"operationId":"deleteAssignmentGrader","summary":"Delete an assignment grader by ID","parameters":[{"name":"id","required":true,"in":"path","description":"Assignment grader ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Assignment grader deleted successfully"}},"tags":["Assignment Grader"],"security":[{"x-api-key":[]}]}},"/api/v1/assignment-grader/rubric-templates":{"get":{"operationId":"getRubricTemplates","summary":"Get all rubric templates","parameters":[],"responses":{"200":{"description":"All rubric templates retrieved","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string","description":"Template ID"},"name":{"type":"string","description":"Template name"},"description":{"type":"string","description":"Template description"},"assignmentContent":{"type":"string","description":"Assignment content/context provided for grading"},"criteria":{"description":"Grading criteria","type":"array","items":{"type":"object","properties":{"title":{"type":"string","description":"Title of the criterion"},"description":{"type":"string","description":"Description of the criterion"},"pointsPossible":{"type":"number","description":"Points possible for this criterion"}},"required":["title","pointsPossible"]}},"organizationId":{"type":"string","description":"Organization ID"},"createdBy":{"type":"string","description":"Created by user ID"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Update timestamp"}},"required":["_id","name","criteria","organizationId","createdBy","createdAt","updatedAt"]}}}}}},"tags":["Assignment Grader"],"security":[{"x-api-key":[]}]},"post":{"operationId":"createRubricTemplate","summary":"Create a new rubric template","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Name of the rubric template"},"description":{"type":"string","description":"Description of the rubric template"},"assignmentContent":{"type":"string","description":"Additional context for the assignment such as a reading passage, source material, or instructions that students were given. The AI grader will use this to evaluate submissions more accurately."},"criteria":{"description":"Grading criteria","type":"array","items":{"type":"object","properties":{"title":{"type":"string","description":"Title of the criterion"},"description":{"type":"string","description":"Description of the criterion"},"pointsPossible":{"type":"number","description":"Points possible for this criterion"}},"required":["title","pointsPossible"]}}},"required":["name","criteria"]}}}},"responses":{"201":{"description":"Rubric template created","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Template ID"},"name":{"type":"string","description":"Template name"},"description":{"type":"string","description":"Template description"},"assignmentContent":{"type":"string","description":"Assignment content/context provided for grading"},"criteria":{"description":"Grading criteria","type":"array","items":{"type":"object","properties":{"title":{"type":"string","description":"Title of the criterion"},"description":{"type":"string","description":"Description of the criterion"},"pointsPossible":{"type":"number","description":"Points possible for this criterion"}},"required":["title","pointsPossible"]}},"organizationId":{"type":"string","description":"Organization ID"},"createdBy":{"type":"string","description":"Created by user ID"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Update timestamp"}},"required":["_id","name","criteria","organizationId","createdBy","createdAt","updatedAt"]}}}}},"tags":["Assignment Grader"],"security":[{"x-api-key":[]}]}},"/api/v1/assignment-grader/rubric-templates/{id}":{"get":{"operationId":"getRubricTemplate","summary":"Get a rubric template by ID","parameters":[{"name":"id","required":true,"in":"path","description":"Rubric template ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Rubric template retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"Template ID"},"name":{"type":"string","description":"Template name"},"description":{"type":"string","description":"Template description"},"assignmentContent":{"type":"string","description":"Assignment content/context provided for grading"},"criteria":{"description":"Grading criteria","type":"array","items":{"type":"object","properties":{"title":{"type":"string","description":"Title of the criterion"},"description":{"type":"string","description":"Description of the criterion"},"pointsPossible":{"type":"number","description":"Points possible for this criterion"}},"required":["title","pointsPossible"]}},"organizationId":{"type":"string","description":"Organization ID"},"createdBy":{"type":"string","description":"Created by user ID"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Update timestamp"}},"required":["_id","name","criteria","organizationId","createdBy","createdAt","updatedAt"]}}}}},"tags":["Assignment Grader"],"security":[{"x-api-key":[]}]},"delete":{"operationId":"deleteRubricTemplate","summary":"Delete a rubric template by ID","parameters":[{"name":"id","required":true,"in":"path","description":"Rubric template ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Rubric template deleted successfully"}},"tags":["Assignment Grader"],"security":[{"x-api-key":[]}]}},"/api/v1/assignment-grader/educator-report/{assignmentId}":{"get":{"operationId":"generateEducatorReport","summary":"Generate educator report for an assignment","parameters":[{"name":"assignmentId","required":true,"in":"path","description":"Assignment ID to generate report for","schema":{"type":"string"}}],"responses":{"200":{"description":"Educator report generated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"assignmentId":{"type":"string","description":"Assignment ID"},"title":{"type":"string","description":"Assignment title"},"totalSubmissions":{"type":"number","description":"Total number of submissions"},"statistics":{"description":"Grade statistics","allOf":[{"type":"object","properties":{"averageGrade":{"type":"string","description":"Average grade"},"minGrade":{"type":"string","description":"Minimum grade"},"maxGrade":{"type":"string","description":"Maximum grade"},"standardDeviation":{"type":"string","description":"Standard deviation"}},"required":["averageGrade","minGrade","maxGrade","standardDeviation"]}]},"gradeDistribution":{"description":"Grade distribution","allOf":[{"type":"object","properties":{"A":{"type":"number","description":"Number of A grades (90-100)"},"B":{"type":"number","description":"Number of B grades (80-89)"},"C":{"type":"number","description":"Number of C grades (70-79)"},"D":{"type":"number","description":"Number of D grades (60-69)"},"F":{"type":"number","description":"Number of F grades (0-59)"}},"required":["A","B","C","D","F"]}]},"criteriaAnalysis":{"description":"Analysis per criterion","type":"array","items":{"type":"object","properties":{"title":{"type":"string","description":"Criterion title"},"avgScore":{"type":"number","description":"Average score for this criterion"},"maxPossible":{"type":"number","description":"Maximum possible points"},"submissionCount":{"type":"number","description":"Number of submissions graded"}},"required":["title","avgScore","maxPossible","submissionCount"]}},"strengths":{"description":"Top performing criteria","type":"array","items":{"type":"object","properties":{"title":{"type":"string","description":"Criterion title"},"avgScore":{"type":"string","description":"Average score"},"maxPossible":{"type":"number","description":"Maximum possible points"},"performanceRatio":{"type":"string","description":"Performance ratio as percentage"}},"required":["title","avgScore","maxPossible","performanceRatio"]}},"weaknesses":{"description":"Criteria needing improvement","type":"array","items":{"type":"object","properties":{"title":{"type":"string","description":"Criterion title"},"avgScore":{"type":"string","description":"Average score"},"maxPossible":{"type":"number","description":"Maximum possible points"},"performanceRatio":{"type":"string","description":"Performance ratio as percentage"}},"required":["title","avgScore","maxPossible","performanceRatio"]}},"submissions":{"description":"List of all submissions","type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Submission ID"},"studentIdentifier":{"type":"string","description":"Student identifier"},"grade":{"type":"number","description":"Grade percentage"},"createdAt":{"format":"date-time","type":"string","description":"Submission date"}},"required":["id","studentIdentifier","grade","createdAt"]}}},"required":["assignmentId","title","totalSubmissions","statistics","gradeDistribution","criteriaAnalysis","strengths","weaknesses","submissions"]}}}}},"tags":["Assignment Grader"],"security":[{"x-api-key":[]}]}},"/api/v1/pdf-generator/create":{"post":{"operationId":"createPdf","summary":"Generate a new PDF presentation","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"topic":{"type":"string","description":"The topic for the PDF presentation"},"numberOfSlides":{"type":"number","description":"Number of slides to generate","minimum":1,"maximum":50},"locale":{"type":"string","description":"Locale/language for the presentation (e.g., en-US, es-ES, fr-FR)"},"imageMode":{"type":"string","description":"Image handling mode: search (auto-search), generate (AI-generated images), provide-own (use custom images), none (no images, use icons)","enum":["search","generate","provide-own","none"],"default":"search"},"customImages":{"description":"Custom images to use (required when imageMode is \"provide-own\")","type":"array","items":{"type":"object","properties":{"url":{"type":"string","description":"Image URL to download and use (provide either url or base64)"},"base64":{"type":"string","description":"Base64-encoded image data (provide either url or base64)"},"description":{"type":"string","description":"Description of what this image shows"}},"required":["description"]}},"logoUrl":{"type":"string","description":"Custom logo URL to use (optional, falls back to default StudyFetch logo)"}},"required":["topic","numberOfSlides","locale"]}}}},"responses":{"201":{"description":"PDF presentation generated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"presentation":{"type":"object","properties":{"_id":{"type":"string","description":"PDF presentation ID"},"topic":{"type":"string","description":"Topic of the presentation"},"numberOfSlides":{"type":"number","description":"Number of slides"},"locale":{"type":"string","description":"Locale of the presentation"},"url":{"type":"string","description":"URL to the generated PDF on S3"},"pptxUrl":{"type":"string","description":"URL to the generated PowerPoint (PPTX) on S3"},"transcript":{"description":"Transcript of each slide","type":"array","items":{"type":"object","properties":{"pageNum":{"type":"number","description":"Page number of the slide"},"descriptionOfPage":{"type":"string","description":"Description of the slide content and OCR text"}},"required":["pageNum","descriptionOfPage"]}},"organizationId":{"type":"string","description":"Organization ID"},"userId":{"type":"string","description":"User ID"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Update timestamp"}},"required":["_id","topic","numberOfSlides","locale","url","transcript","organizationId","createdAt","updatedAt"]}}}}}}},"tags":["PDF Generator"],"security":[{"x-api-key":[]}]}},"/api/v1/pdf-generator/get":{"get":{"operationId":"getAllPdfs","summary":"Get all PDF presentations","parameters":[],"responses":{"200":{"description":"All PDF presentations retrieved","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string","description":"PDF presentation ID"},"topic":{"type":"string","description":"Topic of the presentation"},"numberOfSlides":{"type":"number","description":"Number of slides"},"locale":{"type":"string","description":"Locale of the presentation"},"url":{"type":"string","description":"URL to the generated PDF on S3"},"pptxUrl":{"type":"string","description":"URL to the generated PowerPoint (PPTX) on S3"},"transcript":{"description":"Transcript of each slide","type":"array","items":{"type":"object","properties":{"pageNum":{"type":"number","description":"Page number of the slide"},"descriptionOfPage":{"type":"string","description":"Description of the slide content and OCR text"}},"required":["pageNum","descriptionOfPage"]}},"organizationId":{"type":"string","description":"Organization ID"},"userId":{"type":"string","description":"User ID"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Update timestamp"}},"required":["_id","topic","numberOfSlides","locale","url","transcript","organizationId","createdAt","updatedAt"]}}}}}},"tags":["PDF Generator"],"security":[{"x-api-key":[]}]}},"/api/v1/pdf-generator/get/{id}":{"get":{"operationId":"getPdf","summary":"Get a PDF presentation by ID","parameters":[{"name":"id","required":true,"in":"path","description":"PDF presentation ID","schema":{"type":"string"}}],"responses":{"200":{"description":"PDF presentation retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"PDF presentation ID"},"topic":{"type":"string","description":"Topic of the presentation"},"numberOfSlides":{"type":"number","description":"Number of slides"},"locale":{"type":"string","description":"Locale of the presentation"},"url":{"type":"string","description":"URL to the generated PDF on S3"},"pptxUrl":{"type":"string","description":"URL to the generated PowerPoint (PPTX) on S3"},"transcript":{"description":"Transcript of each slide","type":"array","items":{"type":"object","properties":{"pageNum":{"type":"number","description":"Page number of the slide"},"descriptionOfPage":{"type":"string","description":"Description of the slide content and OCR text"}},"required":["pageNum","descriptionOfPage"]}},"organizationId":{"type":"string","description":"Organization ID"},"userId":{"type":"string","description":"User ID"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Update timestamp"}},"required":["_id","topic","numberOfSlides","locale","url","transcript","organizationId","createdAt","updatedAt"]}}}}},"tags":["PDF Generator"],"security":[{"x-api-key":[]}]}},"/api/v1/pdf-generator/delete/{id}":{"delete":{"operationId":"deletePdf","summary":"Delete a PDF presentation by ID","parameters":[{"name":"id","required":true,"in":"path","description":"PDF presentation ID","schema":{"type":"string"}}],"responses":{"200":{"description":"PDF presentation deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"PDF presentation deleted successfully"}}}}}}},"tags":["PDF Generator"],"security":[{"x-api-key":[]}]}},"/api/v1/pdf-generator/v3/create":{"post":{"operationId":"createPdf","summary":"Generate a new PDF presentation using the SVG/PDF v3 pipeline","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"topic":{"type":"string","description":"The topic for the PDF presentation"},"pages":{"type":"number","description":"Number of pages to generate. Alias: numberOfSlides.","minimum":1,"maximum":50},"numberOfSlides":{"type":"number","description":"Number of slides to generate. Kept for compatibility with the existing PDF API.","minimum":1,"maximum":50},"locale":{"type":"string","description":"Locale or language code (e.g. \"en\", \"es\", \"ko\", \"es-ES\"). When non-English, drives language-aware AI prompts so the generated deck text is produced in the requested language. Note: non-Latin scripts (Hindi, Korean, Chinese, Japanese, Arabic, Hebrew, Thai) require additional font registration in the SVG render pipeline before glyphs render correctly in the final PDF.","example":"en-US"},"model":{"type":"string","description":"Backend AI model key from utils/ai-models.ts","example":"gemini-3-flash-preview"},"concurrency":{"type":"number","description":"Max in-flight slide SVG generations","minimum":1,"maximum":20}},"required":["topic"]}}}},"responses":{"201":{"description":"PDF v3 presentation generated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"presentation":{"type":"object","properties":{"_id":{"type":"string","description":"PDF presentation ID"},"topic":{"type":"string","description":"Topic of the generated presentation"},"numberOfSlides":{"type":"number","description":"Number of generated slides/pages"},"locale":{"type":"string","description":"Locale stored with the generated presentation"},"url":{"type":"string","description":"Signed GCS URL for the generated PDF"},"transcript":{"type":"array","items":{"type":"object","properties":{"pageNum":{"type":"number","description":"Page number of the slide"},"descriptionOfPage":{"type":"string","description":"Human-readable slide transcript generated from the v3 outline"}},"required":["pageNum","descriptionOfPage"]}},"rawSlides":{"type":"object","properties":{"generatorVersion":{"type":"string","example":"v3"},"model":{"type":"string","example":"gemini-3-flash-preview"},"outline":{"type":"object","description":"Structured outline used to render the SVG slides"},"svgs":{"description":"Raw SVG source for each generated slide","type":"array","items":{"type":"string"}}},"required":["generatorVersion","model","outline","svgs"]},"organizationId":{"type":"string","description":"Organization ID"},"userId":{"type":"string","description":"User ID"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Update timestamp"}},"required":["_id","topic","numberOfSlides","locale","url","transcript","rawSlides","organizationId","createdAt","updatedAt"]}},"required":["success","presentation"]}}}}},"tags":["PDF Generator V3"],"security":[{"x-api-key":[]}]}},"/api/v1/pdf-generator/v3/get":{"get":{"operationId":"getAllPdfs","summary":"Get all PDF v3 presentations","parameters":[],"responses":{"200":{"description":"PDF v3 presentations retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string","description":"PDF presentation ID"},"topic":{"type":"string","description":"Topic of the generated presentation"},"numberOfSlides":{"type":"number","description":"Number of generated slides/pages"},"locale":{"type":"string","description":"Locale stored with the generated presentation"},"url":{"type":"string","description":"Signed GCS URL for the generated PDF"},"transcript":{"type":"array","items":{"type":"object","properties":{"pageNum":{"type":"number","description":"Page number of the slide"},"descriptionOfPage":{"type":"string","description":"Human-readable slide transcript generated from the v3 outline"}},"required":["pageNum","descriptionOfPage"]}},"rawSlides":{"type":"object","properties":{"generatorVersion":{"type":"string","example":"v3"},"model":{"type":"string","example":"gemini-3-flash-preview"},"outline":{"type":"object","description":"Structured outline used to render the SVG slides"},"svgs":{"description":"Raw SVG source for each generated slide","type":"array","items":{"type":"string"}}},"required":["generatorVersion","model","outline","svgs"]},"organizationId":{"type":"string","description":"Organization ID"},"userId":{"type":"string","description":"User ID"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Update timestamp"}},"required":["_id","topic","numberOfSlides","locale","url","transcript","rawSlides","organizationId","createdAt","updatedAt"]}}}}}},"tags":["PDF Generator V3"],"security":[{"x-api-key":[]}]}},"/api/v1/pdf-generator/v3/get/{id}":{"get":{"operationId":"getPdf","summary":"Get a PDF v3 presentation by ID","parameters":[{"name":"id","required":true,"in":"path","description":"PDF presentation ID","schema":{"type":"string"}}],"responses":{"200":{"description":"PDF v3 presentation retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"_id":{"type":"string","description":"PDF presentation ID"},"topic":{"type":"string","description":"Topic of the generated presentation"},"numberOfSlides":{"type":"number","description":"Number of generated slides/pages"},"locale":{"type":"string","description":"Locale stored with the generated presentation"},"url":{"type":"string","description":"Signed GCS URL for the generated PDF"},"transcript":{"type":"array","items":{"type":"object","properties":{"pageNum":{"type":"number","description":"Page number of the slide"},"descriptionOfPage":{"type":"string","description":"Human-readable slide transcript generated from the v3 outline"}},"required":["pageNum","descriptionOfPage"]}},"rawSlides":{"type":"object","properties":{"generatorVersion":{"type":"string","example":"v3"},"model":{"type":"string","example":"gemini-3-flash-preview"},"outline":{"type":"object","description":"Structured outline used to render the SVG slides"},"svgs":{"description":"Raw SVG source for each generated slide","type":"array","items":{"type":"string"}}},"required":["generatorVersion","model","outline","svgs"]},"organizationId":{"type":"string","description":"Organization ID"},"userId":{"type":"string","description":"User ID"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Update timestamp"}},"required":["_id","topic","numberOfSlides","locale","url","transcript","rawSlides","organizationId","createdAt","updatedAt"]}}}}},"tags":["PDF Generator V3"],"security":[{"x-api-key":[]}]}},"/api/v1/pdf-generator/v3/delete/{id}":{"delete":{"operationId":"deletePdf","summary":"Delete a PDF v3 presentation by ID","parameters":[{"name":"id","required":true,"in":"path","description":"PDF presentation ID","schema":{"type":"string"}}],"responses":{"200":{"description":"PDF v3 presentation deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"PDF v3 presentation deleted successfully"}},"required":["success","message"]}}}}},"tags":["PDF Generator V3"],"security":[{"x-api-key":[]}]}},"/api/v1/video-generator/create":{"post":{"operationId":"createVideo","summary":"Generate educational video","description":"\n    Create a new educational video generation job.\n    \n    **Modes:**\n    - `async`: Fire and forget. Returns immediately with runId. Poll status endpoint to track progress.\n    - `sync`: Waits for video generation to complete before returning. May take 8-15 minutes.\n    \n    **Webhook Support (async mode - optional):**\n    Provide a `webhookUrl` to receive ONE notification when generation completes or fails.\n    Use status polling (`GET /status/:runId`) for real-time progress updates during generation.\n    ","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"topic":{"type":"string","description":"Topic for the educational video","example":"The American Revolution"},"length":{"type":"number","description":"Video length in seconds (must be multiple of 8, default: 120)","example":120,"minimum":8,"maximum":320},"aspectRatio":{"type":"string","description":"Aspect ratio for the video","enum":["16:9","9:16"],"default":"16:9"},"veoModel":{"type":"string","description":"Video generation model (fast for quicker results, standard for best quality)","enum":["veo-3.1-generate-001","veo-3.1-generate-preview","veo-3.1-fast-generate-preview"],"default":"veo-3.1-fast-generate-preview"},"educationLevel":{"type":"string","description":"Target education level","example":"high school level","default":"high school level"},"language":{"type":"string","description":"Language for the video dialogue. Accepts language codes (e.g., \"en\", \"es\", \"fr\", \"de\", \"zh\", \"ja\", \"ko\") or full names (e.g., \"English\", \"Spanish\")","example":"es","default":"en"},"continuityMode":{"type":"string","description":"Continuity mode for frame generation","enum":["scene-by-scene","continuous-flow"],"default":"continuous-flow"},"enableSpeechBubbles":{"type":"boolean","description":"Enable speech bubbles with character tracking","default":true},"visualStyle":{"type":"string","description":"Visual style for the video (art/aesthetic style)","example":"bright colorful educational animation with cartoon characters"},"visualStyleReferenceUrl":{"type":"string","description":"URL to a sample frame/image that defines the visual style. Used only for the first frame to establish the aesthetic.","example":"https://example.com/my-style-reference.png"},"visualStyleIncludesCharacters":{"type":"boolean","description":"When true and visualStyleReferenceUrl is provided, skips including separate character reference images (use when your style reference already contains the characters)","default":false},"narrativeStyle":{"type":"string","description":"Narrative style for the video (storytelling/teaching approach). Defaults to visualStyle if not provided.","example":"engaging educational conversation, story-driven narrative, Q&A format"},"additionalPrompt":{"type":"string","description":"Additional context or instructions for script generation","example":"Focus on key battles and important figures. Make it exciting!"},"customOutline":{"type":"string","description":"Custom outline/script structure. When provided, skips AI outline generation and uses this outline exactly. The AI will follow your structure 100% when generating the detailed script.","example":"Scene 1: Introduction to photosynthesis - explain what it is and why it matters\nScene 2: The role of sunlight - explain how plants capture light energy\nScene 3: Water and CO2 - explain the inputs plants need\n..."},"mainCharacter":{"description":"Custom main character (defaults to Sparky)","allOf":[{"type":"object","properties":{"id":{"type":"string","description":"Character ID"},"name":{"type":"string","description":"Character name"},"role":{"type":"string","description":"Character role"},"description":{"type":"string","description":"Character description"}},"required":["id","name","role"]}]},"secondaryCharacter":{"description":"Custom secondary character (defaults to Tiger)","allOf":[{"type":"object","properties":{"id":{"type":"string","description":"Character ID"},"name":{"type":"string","description":"Character name"},"role":{"type":"string","description":"Character role"},"description":{"type":"string","description":"Character description"}},"required":["id","name","role"]}]},"mode":{"type":"string","description":"Generation mode: async (returns immediately with webhook) or sync (waits for completion)","enum":["async","sync"],"default":"async"},"webhookUrl":{"type":"string","description":"Webhook URL for async updates (only used in async mode)","example":"https://yourapp.com/webhooks/video-generation"}},"required":["topic"]}}}},"responses":{"201":{"description":"Video generation job created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"runId":{"type":"string","example":"2025-11-15T12-30-45-abc123"},"status":{"type":"string","enum":["pending","script_generation","frame_generation","video_prompt_generation","video_generation","video_stitching","completed","failed"],"example":"pending"},"mode":{"type":"string","enum":["async","sync"],"example":"async"},"message":{"type":"string","example":"Video generation started. Use /status/:runId to check progress."},"result":{"type":"object","properties":{"scriptUri":{"type":"string"},"frameUris":{"type":"array","items":{"type":"string"}},"videoUris":{"type":"array","items":{"type":"string"}},"finalVideoUri":{"type":"string"},"finalVideoSignedUrl":{"type":"string"},"duration":{"type":"number"}}}}}}}},"400":{"description":"Invalid input parameters"}},"tags":["Video Generator"],"security":[{"x-api-key":[]}]}},"/api/v1/video-generator/status/{runId}":{"get":{"operationId":"getStatus","summary":"Get video generation status","description":"\n    Check the current status and progress of a video generation job.\n    \n    Returns:\n    - Current status (pending, script_generation, frame_generation, etc.)\n    - Progress percentage (0-100)\n    - Estimated time remaining (if available)\n    - Final result (when completed)\n    - Error message (if failed)\n    ","parameters":[{"name":"runId","required":true,"in":"path","description":"Video generation run ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Status retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"runId":{"type":"string","example":"2025-11-15T12-30-45-abc123"},"status":{"type":"string","enum":["pending","script_generation","frame_generation","video_prompt_generation","video_generation","video_stitching","completed","failed"],"example":"video_generation"},"progress":{"type":"object","properties":{"current":{"type":"number","example":3},"total":{"type":"number","example":5},"percentage":{"type":"number","example":60}}},"result":{"type":"object","nullable":true,"description":"Available when status is \"completed\""},"error":{"type":"string","nullable":true,"description":"Error message if status is \"failed\""},"estimatedTimeRemaining":{"type":"number","nullable":true,"description":"Estimated milliseconds until completion"}}}}}},"404":{"description":"Video generation not found"}},"tags":["Video Generator"],"security":[{"x-api-key":[]}]}},"/api/v1/video-generator/get/{runId}":{"get":{"operationId":"getVideo","summary":"Get full video generation details","parameters":[{"name":"runId","required":true,"in":"path","description":"Video generation run ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Video generation retrieved successfully"},"404":{"description":"Video generation not found"}},"tags":["Video Generator"],"security":[{"x-api-key":[]}]}},"/api/v1/video-generator/list":{"get":{"operationId":"listVideos","summary":"List all video generations for organization","parameters":[{"name":"limit","required":false,"in":"query","description":"Number of results to return (default: 50)","schema":{"type":"number"}},{"name":"offset","required":false,"in":"query","description":"Number of results to skip (default: 0)","schema":{"type":"number"}}],"responses":{"200":{"description":"List of video generations","content":{"application/json":{"schema":{"type":"object","properties":{"videos":{"type":"array","items":{"type":"object"}},"total":{"type":"number"},"limit":{"type":"number"},"offset":{"type":"number"}}}}}}},"tags":["Video Generator"],"security":[{"x-api-key":[]}]}},"/api/v1/video-generator/delete/{runId}":{"delete":{"operationId":"deleteVideo","summary":"Delete a video generation job","parameters":[{"name":"runId","required":true,"in":"path","description":"Video generation run ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Video generation deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Video generation deleted successfully"}}}}}},"404":{"description":"Video generation not found"}},"tags":["Video Generator"],"security":[{"x-api-key":[]}]}},"/api/v1/video-generator/character-image/upload-url":{"post":{"operationId":"getCharacterImageUploadUrl","summary":"Get presigned URL for character image upload","description":"Generate a presigned URL to upload a character reference image directly to cloud storage","parameters":[],"responses":{"201":{"description":"Presigned URL generated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"uploadUrl":{"type":"string","description":"Presigned URL to upload the image (PUT request)"},"publicUrl":{"type":"string","description":"Public URL of the uploaded image"}}}}}}},"tags":["Video Generator"],"security":[{"x-api-key":[]}]}},"/api/v1/video-generator/visual-styles":{"get":{"operationId":"getVisualStyles","summary":"Get available visual style presets","description":"Returns a list of pre-configured visual style presets that can be used for video generation","parameters":[],"responses":{"200":{"description":"List of visual style presets","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"classic-comic-strip"},"title":{"type":"string","example":"Classic Comic Strip"},"description":{"type":"string"},"referenceUrl":{"type":"string"}}}}}}}},"tags":["Video Generator"],"security":[{"x-api-key":[]}]}},"/api/v1/video-generator/visual-styles/{id}":{"get":{"operationId":"getVisualStyleById","summary":"Get a specific visual style preset by ID","parameters":[{"name":"id","required":true,"in":"path","description":"Visual style preset ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Visual style preset details"},"404":{"description":"Visual style not found"}},"tags":["Video Generator"],"security":[{"x-api-key":[]}]}},"/api/v1/video-generator/default-characters":{"get":{"operationId":"getDefaultCharacters","summary":"Get default character presets","description":"Returns the default character configurations that can be used for video generation","parameters":[],"responses":{"200":{"description":"Default character presets","content":{"application/json":{"schema":{"type":"object","properties":{"mainCharacter":{"type":"object"},"secondaryCharacter":{"type":"object"},"alternativeCharacters":{"type":"array"}}}}}}},"tags":["Video Generator"],"security":[{"x-api-key":[]}]}},"/api/v1/performance-insights/stream":{"post":{"operationId":"streamAnalytics","summary":"Stream analytics response","description":"Streams an AI-powered analytics response using server-sent events (SSE). The AI can query TrueLearn data, generate charts, and provide insights about learner performance.","parameters":[{"name":"x-user-id","in":"header","description":"User ID (used when authenticating via API key)","required":false,"schema":{"type":"string"}},{"name":"x-embed-token","in":"header","description":"Embed token containing the TrueLearn userContextJwt","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"description":"Messages array for AI SDK format - list of conversation messages with roles","example":[{"role":"user","content":"Hello"},{"role":"assistant","content":"Hi there!"},{"role":"user","content":[{"type":"text","text":"What is in this image?"},{"type":"image","image_url":{"url":"https://example.com/image.jpg"}}]}],"type":"array","items":{"type":"string"}},"message":{"description":"Single message for custom format - contains text and optional images","allOf":[{"type":"object","properties":{"text":{"type":"string","description":"Text content of the message"},"images":{"description":"Images attached to the message","type":"array","items":{"type":"object","properties":{"url":{"type":"string","description":"URL of the image"},"base64":{"type":"string","description":"Base64 encoded image data"},"mimeType":{"type":"string","description":"MIME type of the image"},"caption":{"type":"string","description":"Caption for the image"}}}}}}]},"componentId":{"type":"string","description":"Component ID"},"userId":{"type":"string","description":"User ID"},"groupIds":{"description":"Group IDs for access control","type":"array","items":{"type":"string"}},"sessionId":{"type":"string","description":"Session ID"},"id":{"type":"string","description":"Session ID (AI SDK uses \"id\")"},"timezone":{"type":"string","description":"IANA timezone string (e.g. \"America/New_York\")"},"context":{"type":"object","description":"Additional context"},"trigger":{"type":"string","description":"Trigger for AI SDK (what triggered the message)"}}}}}},"responses":{"200":{"description":"SSE stream of analytics response (text/plain)"},"400":{"description":"Messages array is required"}},"tags":["Performance Insights"],"security":[{"x-api-key":[]}]}},"/api/v1/performance-insights/embed":{"post":{"operationId":"generateEmbed","summary":"Generate performance insights embed","description":"Creates an embeddable URL and token for the Performance Insights dashboard. Requires a TrueLearn userContextJwt to authenticate data access.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"userId":{"type":"string","description":"User ID for tracking"},"studentName":{"type":"string","description":"Student name for display and tracking"},"groupIds":{"description":"Group IDs for collaboration","example":["class-101","class-102"],"type":"array","items":{"type":"string"}},"sessionId":{"type":"string","description":"Session ID for continuity"},"theme":{"description":"Theme customization","allOf":[{"type":"object","properties":{"primaryColor":{"type":"string","description":"Primary color (hex)"},"secondaryColor":{"type":"string","description":"Secondary color (hex)"},"backgroundColor":{"type":"string","description":"Background color (hex)"},"textColor":{"type":"string","description":"Text color (hex)"},"fontFamily":{"type":"string","description":"Font family"},"fontSize":{"type":"string","description":"Font size"},"borderRadius":{"type":"string","description":"Border radius"},"padding":{"type":"string","description":"Padding"},"logoUrl":{"type":"string","description":"Logo URL"},"hideBranding":{"type":"boolean","description":"Hide branding"}}}]},"features":{"description":"Feature toggles","allOf":[{"type":"object","properties":{"enableWebSearch":{"type":"boolean","description":"Enable web search"},"enableHistory":{"type":"boolean","description":"Enable history"},"enableVoice":{"type":"boolean","description":"Enable voice input"},"enableFollowUps":{"type":"boolean","description":"Enable follow-up questions"},"enableComponentCreation":{"type":"boolean","description":"Enable component creation"},"placeholderText":{"type":"string","description":"Placeholder text"},"enableWebSearchSources":{"type":"boolean","description":"Enable web search sources"},"enableImageSources":{"type":"boolean","description":"Enable image sources"},"enableTranscript":{"type":"boolean","description":"Enable transcript"},"enableOutline":{"type":"boolean","description":"Enable outline"},"enableBadWordsFilter":{"type":"boolean","description":"Enable bad words filter"},"enableGuardrails":{"type":"boolean","description":"Enable guardrails"},"enablePromptingScore":{"type":"boolean","description":"Enable prompting quality score","default":true},"enableResponsibilityScore":{"type":"boolean","description":"Enable learning responsibility score","default":true},"enableReferenceMode":{"type":"boolean","description":"Enable reference mode - show references instead of source content"},"enableFeedback":{"type":"boolean","description":"Enable thumbs up/down feedback with reason","default":true},"hideTitle":{"type":"boolean","description":"Hide the chat title and avatar in the embedded component"},"emptyStateHtml":{"type":"string","description":"Custom HTML to show in empty state instead of default icon and text"},"hideEmptyState":{"type":"boolean","description":"Hide the default empty state (icon and text)"}},"required":["enableBadWordsFilter"]}]},"width":{"type":"string","description":"Embed width (e.g., \"100%\", \"600px\")"},"height":{"type":"string","description":"Embed height (e.g., \"400px\", \"100vh\")"},"expiryHours":{"type":"number","description":"Token expiry time in hours","default":1}}}}}},"responses":{"201":{"description":"Embed URL and token generated","content":{"application/json":{"schema":{"type":"object","properties":{"embedUrl":{"type":"string","description":"Full embed URL for iframe integration"},"token":{"type":"string","description":"JWT embed token"},"expiresAt":{"format":"date-time","type":"string","description":"Token expiration timestamp (1 hour from creation)"},"componentId":{"type":"string","description":"Resolved component id backing this embed. Stable across calls sharing the same organization + label, so it can be passed back as componentId on a later call to target the same record explicitly."}},"required":["embedUrl","token","expiresAt","componentId"]}}}},"400":{"description":"userContextJwt is required"}},"tags":["Performance Insights"],"security":[{"x-api-key":[]}]}},"/api/v1/performance-insights/feedback":{"get":{"operationId":"getFeedback","summary":"Get message feedback (dashboard)","description":"Lists PI message feedback for the organization. Requires API key auth.","parameters":[{"name":"feedbackType","required":false,"in":"query","schema":{"enum":["thumbsUp","thumbsDown"],"type":"string"}},{"name":"componentId","required":false,"in":"query","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","schema":{"type":"string"}},{"name":"groupId","required":false,"in":"query","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}},{"name":"skip","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Performance Insights"],"security":[{"x-api-key":[]}]},"post":{"operationId":"submitFeedback","summary":"Submit message feedback","description":"Upserts or deletes a thumbs-up / thumbs-down rating for a PI assistant message. Send feedback: null to remove an existing rating.","parameters":[{"name":"x-user-id","in":"header","required":false,"schema":{"type":"string"}},{"name":"x-embed-token","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Performance Insights"],"security":[{"x-api-key":[]}]}},"/api/v1/performance-insights/feedback/{feedbackId}/context":{"get":{"operationId":"getFeedbackContext","summary":"Get feedback context","description":"Returns the rated message and surrounding conversation for a feedback item.","parameters":[{"name":"feedbackId","required":true,"in":"path","description":"Feedback document ID","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Performance Insights"],"security":[{"x-api-key":[]}]}},"/api/v1/performance-insights/prompts/export":{"get":{"operationId":"exportPrompts","summary":"Export user prompts as CSV","description":"Streams every question users asked, as CSV. Scope it with componentId and a date range.","parameters":[{"name":"componentId","required":false,"in":"query","description":"Restrict to a single Performance Insights component","schema":{"type":"string"}},{"name":"sessionId","required":false,"in":"query","schema":{"type":"string"}},{"name":"userId","required":false,"in":"query","schema":{"type":"string"}},{"name":"groupId","required":false,"in":"query","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","description":"ISO 8601","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"ISO 8601","schema":{"type":"string"}}],"responses":{"200":{"description":"CSV export of user prompts","content":{"text/csv":{"schema":{"type":"string","format":"binary"}}}}},"tags":["Performance Insights"],"security":[{"x-api-key":[]}]}},"/api/v1/performance-insights/session/{sessionId}/export":{"get":{"operationId":"exportSessionPrompts","summary":"Export one conversation's prompts as CSV","description":"Streams the questions asked in a single session, read from the stored GCS transcript.","parameters":[{"name":"sessionId","required":true,"in":"path","description":"Conversation / session ID","schema":{"type":"string"}},{"name":"x-user-id","in":"header","description":"User ID (used when authenticating via API key)","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"CSV export of the session's prompts","content":{"text/csv":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Conversation not found"}},"tags":["Performance Insights"],"security":[{"x-api-key":[]}]}},"/api/v1/performance-insights/sessions":{"get":{"operationId":"listSessions","summary":"List conversations","description":"Returns a summary list of all Performance Insights conversations for the current user, ordered by most recent.","parameters":[{"name":"limit","required":false,"in":"query","description":"Maximum number of conversations to return (default 50)","schema":{"type":"string"}},{"name":"x-user-id","in":"header","description":"User ID (used when authenticating via API key)","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of conversation summaries","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Conversation / session ID"},"userId":{"type":"string","description":"Owner user ID"},"organizationId":{"type":"string","description":"Organization ID"},"groupId":{"type":"string","description":"Group ID composite key (sorted, comma-separated) when sessions are scoped to a group"},"title":{"type":"string","description":"Conversation title"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"},"messageCount":{"type":"number","description":"Total number of messages in the conversation"}},"required":["id","userId","organizationId","title","createdAt","updatedAt","messageCount"]}}}}}},"tags":["Performance Insights"],"security":[{"x-api-key":[]}]}},"/api/v1/performance-insights/sessions/create":{"post":{"operationId":"createSession","summary":"Create conversation","description":"Creates a new Performance Insights conversation. A session ID is auto-generated if not provided.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sessionId":{"type":"string","description":"Custom session ID. Auto-generated if omitted."},"title":{"type":"string","description":"Conversation title","default":"New Chat"},"suggestionContext":{"type":"string","description":"Report-page suggestion context to stamp onto this conversation only (e.g. low_answer_confidence_correct_individual). Omit on New Chat so later conversations do not inherit the landing page chips.","example":"low_answer_confidence_correct_individual"}}}}}},"responses":{"201":{"description":"Conversation created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Conversation / session ID"},"userId":{"type":"string","description":"Owner user ID"},"organizationId":{"type":"string","description":"Organization ID"},"groupId":{"type":"string","description":"Group ID composite key (sorted, comma-separated) when sessions are scoped to a group"},"title":{"type":"string","description":"Conversation title"},"messages":{"description":"AI SDK UIMessage array with hydrated image URLs","type":"array","items":{"type":"object"}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"},"suggestionContext":{"type":"string","description":"Report-page suggestion context stamped on this conversation, if any"}},"required":["id","userId","organizationId","title","messages","createdAt","updatedAt"]}}}}},"tags":["Performance Insights"],"security":[{"x-api-key":[]}]}},"/api/v1/performance-insights/session/{sessionId}":{"get":{"operationId":"getSession","summary":"Retrieve conversation","description":"Returns a single conversation with its full message history. Image references are hydrated with signed URLs.","parameters":[{"name":"sessionId","required":true,"in":"path","description":"Conversation / session ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Conversation with messages","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Conversation / session ID"},"userId":{"type":"string","description":"Owner user ID"},"organizationId":{"type":"string","description":"Organization ID"},"groupId":{"type":"string","description":"Group ID composite key (sorted, comma-separated) when sessions are scoped to a group"},"title":{"type":"string","description":"Conversation title"},"messages":{"description":"AI SDK UIMessage array with hydrated image URLs","type":"array","items":{"type":"object"}},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"},"suggestionContext":{"type":"string","description":"Report-page suggestion context stamped on this conversation, if any"}},"required":["id","userId","organizationId","title","messages","createdAt","updatedAt"]}}}},"404":{"description":"Conversation not found"}},"tags":["Performance Insights"],"security":[{"x-api-key":[]}]},"delete":{"operationId":"deleteSession","summary":"Delete conversation","description":"Permanently deletes a conversation and its associated data from storage.","parameters":[{"name":"sessionId","required":true,"in":"path","description":"Conversation / session ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Conversation deleted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the operation succeeded","example":true},"messageCount":{"type":"number","description":"Number of messages saved (only on push)"}},"required":["success"]}}}}},"tags":["Performance Insights"],"security":[{"x-api-key":[]}]}},"/api/v1/performance-insights/session/{sessionId}/messages":{"put":{"operationId":"saveMessages","summary":"Push messages to conversation","description":"Persists messages to a conversation. Creates the conversation if it does not exist. Image data is stripped before storage.","parameters":[{"name":"sessionId","required":true,"in":"path","description":"Conversation / session ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"description":"Array of AI SDK UIMessage objects to persist","type":"array","items":{"type":"object"}},"title":{"type":"string","description":"Update the conversation title"},"suggestionContext":{"type":"string","description":"Stamp suggestionContext onto the conversation if it does not already have one. Ignored when the session already stores a value (including an explicit empty New Chat)."}},"required":["messages"]}}}},"responses":{"200":{"description":"Messages saved","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the operation succeeded","example":true},"messageCount":{"type":"number","description":"Number of messages saved (only on push)"}},"required":["success"]}}}}},"tags":["Performance Insights"],"security":[{"x-api-key":[]}]}},"/api/v1/performance-insights/session/{sessionId}/title":{"patch":{"operationId":"renameSession","summary":"Rename conversation","description":"Updates the title of an existing conversation.","parameters":[{"name":"sessionId","required":true,"in":"path","description":"Conversation / session ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"New conversation title"}},"required":["title"]}}}},"responses":{"200":{"description":"Conversation renamed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the operation succeeded","example":true},"messageCount":{"type":"number","description":"Number of messages saved (only on push)"}},"required":["success"]}}}},"404":{"description":"Conversation not found"}},"tags":["Performance Insights"],"security":[{"x-api-key":[]}]}},"/api/v1/test-mongodb":{"get":{"operationId":"testMongodb","summary":"Test MongoDB connection and get outbound IP","parameters":[],"responses":{"200":{"description":"Test successful"},"500":{"description":"Test failed"}},"tags":["Test"]}}},"servers":[],"components":{"securitySchemes":{"x-api-key":{"type":"apiKey","in":"header","name":"x-api-key","description":"API Key for authentication"}}}}