{"openapi":"3.0.3","info":{"title":"OrgFlow API","version":"0.1.0","description":"Local development API. Email/password accounts: sign in via /api/auth/login (HttpOnly session cookie); all /api routes except /api/auth/* require a session. Accounts belong to organizations; workspace data is isolated per organization. Accounts without an organization use the shared demo workspace. Seed data is synthetic. Editing a published article creates a draft and preserves publishedContent until explicit publication."},"servers":[{"url":"/"}],"components":{"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"Category":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"Article":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"categoryId":{"type":"string"},"content":{"type":"object","properties":{"type":{"type":"string","enum":["doc"]},"content":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["type","content"]},"sources":{"type":"array","items":{"type":"object","additionalProperties":true}},"publishedSources":{"type":"array","items":{"type":"object","additionalProperties":true}},"status":{"type":"string","enum":["draft","published"]},"updatedAt":{"type":"string","format":"date-time"},"publishedContent":{"type":"object","properties":{"type":{"type":"string","enum":["doc"]},"content":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["type","content"]},"publishedTitle":{"type":"string"},"publishedCategoryId":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"publishedBy":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"reviewDueAt":{"type":"string","format":"date-time","nullable":true},"reviewedAt":{"type":"string","format":"date-time"},"reviewedBy":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"nullable":true},"ownerId":{"type":"string","nullable":true}},"required":["id","title","categoryId","content","status","updatedAt"]},"File":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string"},"originalPath":{"type":"string"},"orgflowPath":{"type":"string"},"url":{"type":"string","format":"uri"},"updatedAt":{"type":"string"},"type":{"type":"string"}},"required":["id","name","provider","originalPath","orgflowPath","url","updatedAt","type"]},"Event":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"},"kind":{"type":"string","enum":["meeting","deadline"]}},"required":["id","title","start","kind"]},"Integration":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"required":["id","name","status"]},"Person":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string"},"email":{"type":"string"},"status":{"type":"string","enum":["active","leaving","left"]},"leaveDate":{"type":"string"},"successorId":{"type":"string"},"handoffArticleId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","role","status","createdAt"]},"Run":{"type":"object","properties":{"id":{"type":"string"},"articleId":{"type":"string"},"title":{"type":"string"},"assigneeId":{"type":"string"},"dueAt":{"type":"string","format":"date-time"},"startedBy":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"nullable":true},"startedAt":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["active","completed"]},"completedAt":{"type":"string","format":"date-time"},"steps":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"},"done":{"type":"boolean"},"doneAt":{"type":"string","format":"date-time"},"doneBy":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"nullable":true},"note":{"type":"string"}},"required":["id","text","done"]}}},"required":["id","articleId","title","startedAt","status","steps"]},"Candidate":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"frequency":{"type":"string"},"evidence":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"provider":{"type":"string"},"url":{"type":"string"},"from":{"type":"string"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","title"]}},"status":{"type":"string","enum":["suggested","drafted","dismissed"]},"articleId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","title","summary","evidence","status","createdAt"]},"IndexedSource":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"provider":{"type":"string","enum":["Google Drive","Gmail"]},"url":{"type":"string"},"from":{"type":"string"},"updatedAt":{"type":"string","format":"date-time"},"indexedAt":{"type":"string","format":"date-time"},"chunkCount":{"type":"integer"},"preview":{"type":"string"}},"required":["id","title","provider","url","updatedAt","indexedAt","chunkCount","preview"]},"AuditEntry":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"actor":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"nullable":true},"action":{"type":"string","enum":["article.publish","article.review","run.start","run.complete","run.delete","person.update","transfer.handoff","discover.run","discover.draft","index.remove","index.clear","org.invite.rotate"]},"target":{"type":"object","additionalProperties":true}},"required":["id","at","actor","action"]},"Organization":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["admin","member"]},"inviteCode":{"type":"string","description":"Only returned to admins"},"members":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string","enum":["admin","member"]}},"required":["id","name","email","role"]}}},"required":["id","name","role","members"]},"Bootstrap":{"type":"object","properties":{"categories":{"type":"array","items":{"$ref":"#/components/schemas/Category"}},"articles":{"type":"array","items":{"$ref":"#/components/schemas/Article"}},"files":{"type":"array","items":{"$ref":"#/components/schemas/File"}},"events":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"integrations":{"type":"array","items":{"$ref":"#/components/schemas/Integration"}},"people":{"type":"array","items":{"$ref":"#/components/schemas/Person"}},"runs":{"type":"array","items":{"$ref":"#/components/schemas/Run"}},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/Candidate"}},"sources":{"type":"array","items":{"$ref":"#/components/schemas/IndexedSource"}},"meta":{"type":"object","properties":{"demo":{"type":"boolean"},"demoLabel":{"type":"string"},"storage":{"type":"string"},"authentication":{"type":"string"},"voice":{"type":"string"}},"required":[]}},"required":["categories","articles","files","events","integrations","people","runs","candidates","sources","meta"]}}},"paths":{"/health":{"get":{"summary":"Service health","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"storage":{"type":"string"}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/signup":{"post":{"summary":"Create account and start session","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string"},"name":{"type":"string"},"organization":{"type":"string","description":"Creates a new organization; the caller becomes its admin"},"inviteCode":{"type":"string","description":"Joins the organization with this invite code as a member"}},"required":["email","password"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"orgId":{"type":"string"},"role":{"type":"string","enum":["admin","member"]}},"required":[]}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/login":{"post":{"summary":"Sign in and start session","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string"}},"required":["email","password"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"orgId":{"type":"string"},"role":{"type":"string","enum":["admin","member"]}},"required":[]}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/logout":{"post":{"summary":"End session","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/me":{"get":{"summary":"Current user (null when signed out)","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"orgId":{"type":"string"},"role":{"type":"string","enum":["admin","member"]}}}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/bootstrap":{"get":{"summary":"Load workspace","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Bootstrap"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/categories":{"post":{"summary":"Create category","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Category"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/categories/{id}":{"patch":{"summary":"Rename category","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Category"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/articles":{"post":{"summary":"Create draft","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"categoryId":{"type":"string"},"content":{"type":"object","properties":{"type":{"type":"string","enum":["doc"]},"content":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["type","content"]}},"required":["title","categoryId","content"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Article"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/articles/{id}":{"patch":{"summary":"Autosave draft; preserve published version","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"categoryId":{"type":"string"},"content":{"type":"object","properties":{"type":{"type":"string","enum":["doc"]},"content":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["type","content"]},"ownerId":{"type":"string","nullable":true,"description":"Person id, or null to clear"},"reviewDueAt":{"type":"string","format":"date-time","nullable":true,"description":"ISO timestamp, or null to clear"}},"required":[]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Article"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/articles/{id}/publish":{"post":{"summary":"Human action: approve and publish draft","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Article"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/files/{id}":{"patch":{"summary":"Reorganize OrgFlow link; original file remains unchanged","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"orgflowPath":{"type":"string"}},"required":["orgflowPath"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/File"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agent":{"post":{"summary":"Chat or interview; Ask can cite email and document excerpts from the consented index (sourceType: email excerpt | document excerpt); may save draft, never publishes","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["ask","draft"]},"messages":{"type":"array","minItems":1,"maxItems":24,"items":{"type":"object","properties":{"role":{"type":"string","enum":["user","assistant"]},"content":{"type":"string"}},"required":["role","content"]}},"articleId":{"type":"string"},"categoryId":{"type":"string"},"sourcesConsent":{"type":"boolean"},"sources":{"type":"array","maxItems":8,"items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"text":{"type":"string"},"url":{"type":"string"}},"required":["id","title","text"]}}},"required":["mode","messages"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"draft":{"$ref":"#/components/schemas/Article"},"sources":{"type":"array","items":{"type":"object"}}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/voice/session-token":{"get":{"summary":"Create a short-lived WebRTC token for the private ElevenLabs voice agent","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"conversationToken":{"type":"string"},"conversationId":{"type":"string"},"agentId":{"type":"string"}},"required":["conversationToken","conversationId","agentId"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/uploads":{"post":{"summary":"Upload PNG/JPEG/GIF/WebP image (5 MB maximum)","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}},"required":[]}}}},"400":{"description":"Invalid image","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/auth/google/start":{"get":{"summary":"Start read-only Google OAuth connection (browser redirect)","responses":{"302":{"description":"Redirect to Google consent"},"503":{"description":"Google client not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/auth/google/callback":{"get":{"summary":"Google OAuth callback with cookie-bound state and PKCE","parameters":[{"name":"state","in":"query","required":true,"schema":{"type":"string"}},{"name":"code","in":"query","schema":{"type":"string"}}],"responses":{"302":{"description":"Connection complete; redirect to frontend"},"400":{"description":"Invalid or declined connection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Token exchange failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/integrations/google":{"get":{"summary":"Google session status (tokens never returned)","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"configured":{"type":"boolean"},"connected":{"type":"boolean"},"providers":{"type":"array","items":{"type":"string"}},"sessionStorage":{"type":"string"},"calendarConnected":{"type":"boolean"}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/integrations/google/disconnect":{"post":{"summary":"Forget local Google session","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"connected":{"type":"boolean"}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/integrations/google/sync":{"post":{"summary":"Index Drive file metadata; preserve OrgFlow link arrangement","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"indexed":{"type":"integer"},"limited":{"type":"boolean"},"notice":{"type":"string"}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Connect Google first","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Unsupported source format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Google request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/sources/google":{"get":{"summary":"List Drive files or Gmail subjects for explicit selection","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"sources":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"text":{"type":"string"},"url":{"type":"string"},"provider":{"type":"string"},"mimeType":{"type":"string"}},"required":["id","title"]}},"limited":{"type":"boolean"}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Connect Google first","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Unsupported source format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Google request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"provider","in":"query","schema":{"type":"string","enum":["drive","gmail"]}},{"name":"q","in":"query","schema":{"type":"string"}}]}},"/api/sources/google/{provider}/{id}":{"get":{"summary":"Read a selected Google Doc, text file, or plain-text email (12k character limit)","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"text":{"type":"string"},"url":{"type":"string"},"provider":{"type":"string"},"mimeType":{"type":"string"}},"required":["id","title"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Connect Google first","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Unsupported source format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Google request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","enum":["drive","gmail"]}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/uploads/{id}":{"get":{"summary":"Read a locally uploaded article image","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Image bytes"},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/org":{"get":{"summary":"Current organization, your role, and members (invite code for admins)","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/org/invite":{"post":{"summary":"Rotate the organization invite code (admins only)","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"inviteCode":{"type":"string"}},"required":["inviteCode"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Only admins can change the invite code","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/integrations/google/index":{"post":{"summary":"Index recent Google Docs and email text after explicit consent (about 30-60 s)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"consent":{"type":"boolean","description":"Must be true. Consent copy: Index the text of recent Google Docs and emails into OrgFlow. Indexed text stays in OrgFlow, is used to answer questions and suggest playbooks, and may be sent to OrgFlow's AI provider (Luminal) for those answers and drafts. You can remove it any time."},"drive":{"type":"boolean","default":true},"gmail":{"type":"boolean","default":true},"gmailQuery":{"type":"string"},"maxDocuments":{"type":"integer","maximum":80,"default":40},"maxEmails":{"type":"integer","maximum":150,"default":60}},"required":["consent"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"indexed":{"type":"object","properties":{"drive":{"type":"integer"},"gmail":{"type":"integer"}},"required":[]},"notice":{"type":"string"}},"required":[]}}}},"400":{"description":"Consent not confirmed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Connect Google first","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/sources":{"get":{"summary":"List indexed Gmail and Drive text (summaries, no full text)","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"sources":{"type":"array","items":{"$ref":"#/components/schemas/IndexedSource"}}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Clear the whole consented index","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"integer"}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/sources/{id}":{"delete":{"summary":"Remove one indexed source","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/discover":{"post":{"summary":"Find recurring workflows in the indexed sources (up to about 50 s)","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"candidates":{"type":"array","items":{"$ref":"#/components/schemas/Candidate"}}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Nothing indexed yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"AI key not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/candidates/{id}/draft":{"post":{"summary":"Draft a playbook from a candidate's evidence (saved as a draft)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"draft":{"$ref":"#/components/schemas/Article"},"sources":{"type":"array","items":{"type":"object","additionalProperties":true}},"candidate":{"$ref":"#/components/schemas/Candidate"}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/candidates/{id}/dismiss":{"post":{"summary":"Dismiss a suggested workflow","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/articles/{id}/review":{"post":{"summary":"Owner confirms the playbook is still accurate; sets a new reviewDueAt","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Article"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/articles/{id}/runs":{"post":{"summary":"Start a runnable checklist from the article's list items","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"assigneeId":{"type":"string"},"dueAt":{"type":"string","format":"date-time"}},"required":[]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Run"}}}},"400":{"description":"Article has no list to turn into steps","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs":{"get":{"summary":"List checklist runs","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"runs":{"type":"array","items":{"$ref":"#/components/schemas/Run"}}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/{id}":{"delete":{"summary":"Delete a checklist run","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/{id}/steps/{stepId}":{"patch":{"summary":"Mark a checklist step done or not done; the run completes when every step is done","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"done":{"type":"boolean"},"note":{"type":"string"}},"required":["done"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Run"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"stepId","in":"path","required":true,"schema":{"type":"string"}}]}},"/api/people":{"get":{"summary":"List people in the organization","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"people":{"type":"array","items":{"$ref":"#/components/schemas/Person"}}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Add a person","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"role":{"type":"string"},"email":{"type":"string"}},"required":["name","role"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Person"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/people/{id}":{"patch":{"summary":"Update a person's details, status, leave date, or successor","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"role":{"type":"string"},"email":{"type":"string"},"status":{"type":"string","enum":["active","leaving","left"]},"leaveDate":{"type":"string"},"successorId":{"type":"string"}},"required":[]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Person"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/people/{id}/handoff":{"post":{"summary":"AI drafts or revises the person's role handoff guide (saved as a draft; an active person becomes leaving)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"notes":{"type":"string"},"mode":{"type":"string","enum":["outline"],"description":"outline: facts only, no AI call"}},"required":[]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"draft":{"$ref":"#/components/schemas/Article"},"sources":{"type":"array","items":{"type":"object","additionalProperties":true}},"person":{"$ref":"#/components/schemas/Person"}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/people/{id}/onboarding":{"post":{"summary":"Start the successor's first-30-days checklist from the handoff guide","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"successorId":{"type":"string"}},"required":[]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Run"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Generate the handoff guide first","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/audit":{"get":{"summary":"Recent audit entries, newest first (up to 200)","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/AuditEntry"}}},"required":[]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/insights/health":{"get":{"summary":"Knowledge health: score, person risk, staleness, changed sources, recommended actions","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Sign in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/people/{id}/interview":{"post":{"summary":"Gap-driven interview plan and voice-agent brief for a person","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"gapCount":{"type":"integer"},"agentBrief":{"type":"string"},"questions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"},"origin":{"type":"string","enum":["gap","template"]}},"required":[]}}},"required":[]}}}},"404":{"description":"Person not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}