{"openapi":"3.1.0","info":{"title":"Cainer API","version":"0.1.0","summary":"에이전트 연결·작업·승인·감사 제어면의 HTTP 계약.","description":"계정은 Supabase Auth가 검증하고, Cainer는 인증 후 자체 DB 세션(`acs_…`)을 발급한다.\n\n모든 테넌트 경로는 요청 단위 워크스페이스 스코프와 RLS로 격리되며, 비멤버·없는 테넌트는 구분 없이 403을 돌려준다.\n\nMCP(`/mcp`)는 JSON-RPC 2.0 프로토콜이라 이 문서의 REST 경로에 포함하지 않는다 — `docs/connect/mcp.md`가 정본이다.\n\n지원 상태는 `GET /api/support-matrix`가 정본이며 랜딩·문서·앱이 같은 값을 소비한다.","license":{"name":"Private"}},"servers":[{"url":"http://cainer.jjongguet.com"}],"security":[],"tags":[{"name":"health","description":"상태·빌드 확인"},{"name":"auth","description":"계정 인증·세션"},{"name":"tenants","description":"워크스페이스·멤버·초대"},{"name":"agent-work","description":"테넌트 스코프 에이전트 작업내역"},{"name":"support","description":"지원 매트릭스"},{"name":"meta","description":"문서·디스커버리"}],"paths":{"/api/health":{"get":{"tags":["health"],"operationId":"getHealth","summary":"liveness","responses":{"200":{"description":"프로세스가 살아 있음(워크스페이스 지표는 포함하지 않는다)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}},"/api/version":{"get":{"tags":["health"],"operationId":"getVersion","summary":"배포된 커밋","responses":{"200":{"description":"배포 커밋 SHA","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Version"}}}}}}},"/api/support-matrix":{"get":{"tags":["support"],"operationId":"getSupportMatrix","summary":"클라이언트·경로별 지원 상태 정본","responses":{"200":{"description":"지원 매트릭스","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportMatrix"}}}}}}},"/openapi.json":{"get":{"tags":["meta"],"operationId":"getOpenApi","summary":"이 문서","responses":{"200":{"description":"OpenAPI 3.1 문서","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/auth/signup":{"post":{"tags":["auth"],"operationId":"signup","summary":"계정 등록 요청(확인 메일 단계로 끝난다)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":10,"maxLength":72}},"additionalProperties":false}}}},"responses":{"201":{"description":"provider가 자동 확인으로 설정된 경우 즉시 세션 발급","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSession"}}}},"202":{"description":"확인 메일이 필요한 상태(이미 가입한 주소도 같은 응답)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupPending"}}}},"422":{"description":"입력이 정책에 맞지 않음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"레이트 리밋","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"메일 발송·provider 사용 불가","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/login":{"post":{"tags":["auth"],"operationId":"login","summary":"이메일/비밀번호 로그인(provider 검증)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"}},"additionalProperties":false}}}},"responses":{"200":{"description":"세션 발급","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSession"}}}},"401":{"description":"자격 증명 불일치","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"이메일 미확인 또는 2단계 인증 필요(Bearer 클라이언트는 대화형 2단계를 마칠 수 없다)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"레이트 리밋","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"provider 사용 불가","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/logout":{"post":{"tags":["auth"],"operationId":"logout","summary":"현재 세션 폐기","security":[{"userSession":[]}],"responses":{"204":{"description":"폐기됨"},"401":{"description":"자격 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/me":{"get":{"tags":["auth"],"operationId":"me","summary":"내 계정과 멤버십","security":[{"userSession":[]}],"responses":{"200":{"description":"계정 + 테넌트 목록","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"description":"자격 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/tenants":{"get":{"tags":["tenants"],"operationId":"listTenants","summary":"내 워크스페이스 목록","security":[{"userSession":[]}],"responses":{"200":{"description":"멤버십 목록","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantList"}}}},"401":{"description":"자격 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["tenants"],"operationId":"createTenant","summary":"워크스페이스 생성(생성자는 owner)","security":[{"userSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":120}},"additionalProperties":false}}}},"responses":{"201":{"description":"생성됨","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantCreated"}}}},"401":{"description":"자격 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"이메일 미확인 계정의 추가 워크스페이스","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"이름이 유효하지 않음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/tenants/{tenantId}":{"get":{"tags":["tenants"],"operationId":"getTenant","summary":"워크스페이스 정보와 내 역할","security":[{"userSession":[]}],"parameters":[{"$ref":"#/components/parameters/TenantId"}],"responses":{"200":{"description":"테넌트","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantWithRole"}}}},"403":{"description":"비멤버","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"없는 테넌트","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/tenants/{tenantId}/members":{"get":{"tags":["tenants"],"operationId":"listMembers","summary":"멤버 목록","security":[{"userSession":[]}],"parameters":[{"$ref":"#/components/parameters/TenantId"}],"responses":{"200":{"description":"멤버","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberList"}}}},"403":{"description":"비멤버","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/tenants/{tenantId}/invites":{"post":{"tags":["tenants"],"operationId":"createInvite","summary":"이메일 귀속 1회용 초대 링크 생성(owner)","security":[{"userSession":[]}],"parameters":[{"$ref":"#/components/parameters/TenantId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","role"],"properties":{"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["owner","member"]}},"additionalProperties":false}}}},"responses":{"201":{"description":"초대 링크","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invite"}}}},"403":{"description":"owner가 아님 또는 이메일 미확인","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"플랜 멤버 한도","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/tenants/{tenantId}/agent-work":{"get":{"tags":["agent-work"],"operationId":"listAgentWork","summary":"작업 항목 목록","security":[{"userSession":[]}],"parameters":[{"$ref":"#/components/parameters/TenantId"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"작업 목록","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkList"}}}},"403":{"description":"비멤버","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["agent-work"],"operationId":"startAgentWork","summary":"작업 시작(start 이벤트)","security":[{"userSession":[]}],"parameters":[{"$ref":"#/components/parameters/TenantId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["agentId","title"],"properties":{"agentId":{"type":"string"},"title":{"type":"string","minLength":1,"maxLength":200},"summary":{"type":"string"}},"additionalProperties":false}}}},"responses":{"201":{"description":"시작됨","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkItem"}}}},"403":{"description":"비멤버/다른 에이전트","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"없는 에이전트","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"입력 오류","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/tenants/{tenantId}/agent-work/{workId}":{"get":{"tags":["agent-work"],"operationId":"getAgentWork","summary":"작업과 이벤트 이력","security":[{"userSession":[]}],"parameters":[{"$ref":"#/components/parameters/TenantId"},{"$ref":"#/components/parameters/WorkId"}],"responses":{"200":{"description":"작업 + 이벤트","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkDetail"}}}},"404":{"description":"없는 작업","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/tenants/{tenantId}/agent-work/{workId}/events":{"post":{"tags":["agent-work"],"operationId":"appendAgentWorkEvent","summary":"checkpoint/result 추가(result 이후 추가는 409)","security":[{"userSession":[]}],"parameters":[{"$ref":"#/components/parameters/TenantId"},{"$ref":"#/components/parameters/WorkId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["kind","summary"],"properties":{"kind":{"type":"string","enum":["checkpoint","result"]},"summary":{"type":"string","minLength":1,"maxLength":2000},"payload":{"type":"object"}},"additionalProperties":false}}}},"responses":{"201":{"description":"추가됨","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkEvent"}}}},"404":{"description":"없는 작업","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"이미 result가 있음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/.well-known/oauth-protected-resource":{"get":{"tags":["meta"],"operationId":"getProtectedResourceMetadata","summary":"MCP 리소스 메타데이터(RFC 9728)","responses":{"200":{"description":"리소스·인가 서버","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtectedResource"}}}}}}},"/.well-known/oauth-authorization-server":{"get":{"tags":["meta"],"operationId":"getAuthorizationServerMetadata","summary":"인가 서버 메타데이터(RFC 8414)","responses":{"200":{"description":"엔드포인트·그랜트","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthorizationServer"}}}}}}}},"components":{"securitySchemes":{"userSession":{"type":"http","scheme":"bearer","description":"Cainer DB 세션 토큰(`acs_…`). 계정 로그인 응답의 `session.token`."},"consoleToken":{"type":"http","scheme":"bearer","description":"운영자 콘솔 토큰(`ACP_CONSOLE_TOKEN`). 콘솔·운영 전용 표면에만 사용한다."},"agentToken":{"type":"http","scheme":"bearer","description":"워크스페이스에 결속된 agent 토큰. MCP·HTTP 에이전트 경로가 쓴다."}},"parameters":{"TenantId":{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},"WorkId":{"name":"workId","in":"path","required":true,"schema":{"type":"string"}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}},"additionalProperties":false},"Health":{"type":"object","required":["status"],"properties":{"status":{"type":"string","const":"ok"}},"additionalProperties":false},"Version":{"type":"object","required":["commit"],"properties":{"commit":{"type":"string"}},"additionalProperties":false},"SignupPending":{"type":"object","required":["status"],"properties":{"status":{"type":"string","const":"confirmation_required"}},"additionalProperties":false},"Session":{"type":"object","required":["token","expiresAt"],"properties":{"token":{"type":"string"},"expiresAt":{"type":"string"}},"additionalProperties":false},"User":{"type":"object","required":["id","email"],"properties":{"id":{"type":"string"},"email":{"type":"string"},"displayName":{"type":["string","null"]},"emailVerifiedAt":{"type":["string","null"]},"disabledAt":{"type":["string","null"]},"deletedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"additionalProperties":false},"TenantMembership":{"type":"object","required":["tenant","role"],"properties":{"tenant":{"$ref":"#/components/schemas/Tenant"},"role":{"type":"string","enum":["owner","member"]},"joinedAt":{"type":"string"}},"additionalProperties":false},"Tenant":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"additionalProperties":false},"AuthSession":{"type":"object","required":["user","session"],"properties":{"status":{"type":"string","const":"signed_in"},"user":{"$ref":"#/components/schemas/User"},"tenants":{"type":"array","items":{"$ref":"#/components/schemas/TenantMembership"}},"session":{"$ref":"#/components/schemas/Session"}},"additionalProperties":false},"Me":{"type":"object","required":["user","tenants"],"properties":{"user":{"$ref":"#/components/schemas/User"},"tenants":{"type":"array","items":{"$ref":"#/components/schemas/TenantMembership"}}},"additionalProperties":false},"TenantList":{"type":"object","required":["tenants"],"properties":{"tenants":{"type":"array","items":{"$ref":"#/components/schemas/TenantMembership"}}},"additionalProperties":false},"TenantCreated":{"type":"object","required":["tenant","role"],"properties":{"tenant":{"$ref":"#/components/schemas/Tenant"},"role":{"type":"string","const":"owner"}},"additionalProperties":false},"TenantWithRole":{"type":"object","required":["tenant","role"],"properties":{"tenant":{"$ref":"#/components/schemas/Tenant"},"role":{"type":"string","enum":["owner","member"]}},"additionalProperties":false},"Member":{"type":"object","required":["userId","role"],"properties":{"userId":{"type":"string"},"email":{"type":["string","null"]},"role":{"type":"string","enum":["owner","member"]},"createdAt":{"type":"string"}},"additionalProperties":false},"MemberList":{"type":"object","required":["members"],"properties":{"members":{"type":"array","items":{"$ref":"#/components/schemas/Member"}}},"additionalProperties":false},"Invite":{"type":"object","required":["invite"],"properties":{"invite":{"type":"object","required":["url","expiresAt","role","email","emailStatus"],"properties":{"url":{"type":"string"},"expiresAt":{"type":"string"},"role":{"type":"string","enum":["owner","member"]},"email":{"type":"string"},"emailStatus":{"type":"string","enum":["sent","not_configured","failed"]}},"additionalProperties":false}},"additionalProperties":false},"WorkItem":{"type":"object","required":["work"],"properties":{"work":{"$ref":"#/components/schemas/Work"}},"additionalProperties":false},"Work":{"type":"object","required":["id","agentId","title","status"],"properties":{"id":{"type":"string"},"agentId":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","enum":["started","completed"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"additionalProperties":false},"WorkList":{"type":"object","required":["work"],"properties":{"work":{"type":"array","items":{"$ref":"#/components/schemas/Work"}}},"additionalProperties":false},"WorkEvent":{"type":"object","required":["id","kind","summary"],"properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["start","checkpoint","result"]},"summary":{"type":"string"},"createdAt":{"type":"string"}},"additionalProperties":false},"WorkDetail":{"type":"object","required":["work","events"],"properties":{"work":{"$ref":"#/components/schemas/Work"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WorkEvent"}}},"additionalProperties":false},"SupportMatrix":{"type":"object","required":["updatedAt","paths","entries"],"properties":{"updatedAt":{"type":"string"},"paths":{"type":"array","items":{"type":"object","required":["id","name","entry"],"properties":{"id":{"type":"string","enum":["mcp","http-pull","webhook"]},"name":{"type":"string"},"entry":{"type":"string"},"summary":{"type":"string"},"credential":{"type":"string"},"docs":{"type":"string"}},"additionalProperties":false}},"entries":{"type":"array","items":{"type":"object","required":["id","name","transport","auth","status","capabilities","upgradeRequires","evidence","limits"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"summary":{"type":"string"},"transport":{"type":"string","enum":["mcp-streamable-http","http-pull","http-push-webhook","mcp-events"]},"auth":{"type":"string","enum":["oauth-pkce-dcr","agent-bearer","webhook-signature","none"]},"status":{"type":"string","enum":["live-verified","mock-verified","implemented-unverified","planned","unsupported"]},"capabilities":{"type":"array","items":{"type":"string"}},"upgradeRequires":{"type":"array","items":{"type":"string"}},"evidence":{"type":"array","items":{"type":"string"}},"verifiedAt":{"type":["string","null"]},"limits":{"type":"array","items":{"type":"string"}}},"additionalProperties":false}},"statusLabels":{"type":"object"}},"additionalProperties":false},"ProtectedResource":{"type":"object","required":["resource","authorization_servers"],"properties":{"resource":{"type":"string"},"authorization_servers":{"type":"array","items":{"type":"string"}},"scopes_supported":{"type":"array","items":{"type":"string"}},"bearer_methods_supported":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"AuthorizationServer":{"type":"object","required":["issuer","authorization_endpoint","token_endpoint"],"properties":{"issuer":{"type":"string"},"authorization_endpoint":{"type":"string"},"token_endpoint":{"type":"string"},"registration_endpoint":{"type":"string"},"grant_types_supported":{"type":"array","items":{"type":"string"}},"code_challenge_methods_supported":{"type":"array","items":{"type":"string"}}},"additionalProperties":true}}}}