{"openapi":"3.1.0","info":{"title":"Pickle API","description":"부산대학교 클라우드 플랫폼 Pickle의 REST API. 인증은 JWT Bearer, 오류 응답은 RFC 9457 problem+json(Problem 스키마)을 따릅니다.","version":"0.82.0"},"servers":[{"url":"http://pickle.pusan.ac.kr","description":"Generated server url"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"gpu-access","description":"GPU 접근 권한 — 이 GPU에 누가 접근할 수 있는지를 정합니다."},{"name":"dns-domain-access","description":"도메인 접근 권한 — 이 도메인에 누가 접근할 수 있는지를 정합니다."},{"name":"dns-domain","description":"도메인 — VM 없이 이름만 발급받아 자기 서버로 연결합니다."},{"name":"vm-access","description":"VM 접근 권한 — 이 VM에 누가 접근할 수 있는지를 정합니다."},{"name":"admin","description":"관리자 API"},{"name":"llm-key-access","description":"LLM API 키 접근 권한 — 이 키에 누가 접근할 수 있는지를 정합니다."},{"name":"llm-keys","description":"LLM API 키 — 워크스페이스가 보유한 키의 목록과 상세입니다. 키 평문은 발급 시 한 번만 표시되며 여기서는 다시 볼 수 없습니다."}],"paths":{"/api/v1/me/profile":{"put":{"tags":["me-controller"],"operationId":"updateMyProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProfileRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserProfileResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/me/password":{"put":{"tags":["account-controller"],"operationId":"changePassword","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthTokenResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["account-controller"],"operationId":"setPassword","parameters":[{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetPasswordRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthTokenResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/dns-domains/{domainId}/records":{"get":{"tags":["dns-domain"],"summary":"레코드 세트 목록","operationId":"listDnsRecordSets","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecordSetView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"put":{"tags":["dns-domain"],"summary":"레코드 세트 저장","description":"이 이름이 가져야 할 레코드 세트 전체를 보냅니다. 서버가 차이를 계산하므로 같은 내용을 다시 보내면 아무것도 바뀌지 않습니다. 목록에서 빠진 세트는 존에서 지워집니다.","operationId":"replaceDnsRecordSets","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplaceDnsRecordSetsRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecordSetView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/users/{userId}/org-roles/{orgId}":{"put":{"tags":["admin-controller"],"operationId":"grantOrgRole","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"orgId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrantOrgRoleRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserSummaryResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["admin-controller"],"operationId":"revokeOrgRole","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"orgId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserSummaryResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/settings/{key}":{"put":{"tags":["admin-settings-controller"],"operationId":"updateSetting","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SettingView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/keys/{keyId}/limits":{"put":{"tags":["admin"],"summary":"관리자 LLM API 키 한도 교체","description":"아홉 한도 값을 한 번에 교체합니다. 시스템 운영자는 금액과 리셋 창, 모델 목록, 기능 권한을 바꿀 수 없습니다.","operationId":"replaceAdminLlmKeyLimits","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminLlmKeyLimitsRequest"}}},"required":true},"responses":{"200":{"description":"변경된 LLM API 키 상세","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminLlmKeyDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/workspaces":{"get":{"tags":["workspace-controller"],"operationId":"listWorkspaces","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceSummaryResponse"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["workspace-controller"],"operationId":"createWorkspace","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkspaceRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkspaceDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/workspaces/{workspaceId}/members":{"post":{"tags":["workspace-controller"],"operationId":"addWorkspaceMember","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddWorkspaceMemberRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkspaceMemberResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/terminal-sessions":{"post":{"tags":["terminal-controller"],"operationId":"createTerminalSession","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TerminalTicketResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/start":{"post":{"tags":["vm-controller"],"operationId":"startVm","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/ssh-key":{"get":{"tags":["vm-ssh-key-controller"],"operationId":"getVmSshKey","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmSshKeyStatus"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["vm-ssh-key-controller"],"operationId":"issueVmSshKey","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmSshKeyIssueResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["vm-ssh-key-controller"],"operationId":"deleteVmSshKey","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/ssh-key/reissue":{"post":{"tags":["vm-ssh-key-controller"],"operationId":"reissueVmSshKey","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmSshKeyIssueResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/shutdown":{"post":{"tags":["vm-controller"],"operationId":"shutdownVm","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/reboot":{"post":{"tags":["vm-controller"],"operationId":"rebootVm","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/port-forwardings":{"get":{"tags":["port-forwarding-controller"],"operationId":"listVmPortForwardings","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PortForwardingView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["port-forwarding-controller"],"operationId":"createVmPortForwarding","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePortForwardingRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PortForwardingView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/password/regenerate":{"post":{"tags":["vm-controller"],"operationId":"regenerateVmPassword","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmPasswordResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/force-stop":{"post":{"tags":["vm-controller"],"operationId":"forceStopVm","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/domains":{"post":{"tags":["publishing-controller"],"operationId":"createVmDomain","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVmDomainRequest"}}}},"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/campus-ip-requests":{"get":{"tags":["campus-ip-request-controller"],"operationId":"listVmCampusIpRequests","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CampusIpRequestView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["campus-ip-request-controller"],"operationId":"requestVmCampusIp","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCampusIpRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CampusIpRequestView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/access":{"get":{"tags":["vm-access"],"summary":"접근 권한 목록","description":"이 VM의 접근 권한 전체와, 그 목록이 어느 VM의 것인지 알려 주는 최소 정보입니다. VM 소유자와 워크스페이스 소유자만 볼 수 있습니다.","operationId":"listVmAccessGrants","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResourceAccessListResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["vm-access"],"summary":"접근 권한 부여","description":"지정한 사용자 또는 소유 워크스페이스 전체에 이 VM의 접근 권한을 부여합니다. 사용자는 이 VM을 소유한 워크스페이스의 구성원이어야 하고, 워크스페이스 전체에는 참여자·열람자까지만 부여할 수 있습니다.","operationId":"addVmAccessGrant","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddResourceAccessGrantRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResourceAccessGrantView"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/requests":{"get":{"tags":["request-controller"],"operationId":"listRequests","parameters":[{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/RequestStatus"}},{"name":"type","in":"query","required":false,"schema":{"$ref":"#/components/schemas/ResourceType"}},{"name":"workspaceId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseRequestDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["request-controller"],"operationId":"createRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRequestRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RequestDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/requests/{requestId}/cancel":{"post":{"tags":["request-controller"],"operationId":"cancelRequest","parameters":[{"name":"requestId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RequestDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/notifications/{notificationId}/read":{"post":{"tags":["notification-controller"],"operationId":"markNotificationRead","parameters":[{"name":"notificationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NotificationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/notifications/read-all":{"post":{"tags":["notification-controller"],"operationId":"markAllNotificationsRead","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReadAllResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/me/withdraw":{"post":{"tags":["account-controller"],"operationId":"withdraw","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WithdrawRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/me/mfa/totp":{"post":{"tags":["mfa-controller"],"operationId":"begin","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BeginMfaRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MfaSetupResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/me/mfa/totp/activate":{"post":{"tags":["mfa-controller"],"operationId":"activate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateMfaRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MfaRecoveryCodesResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/me/mfa/recovery-codes":{"post":{"tags":["mfa-controller"],"operationId":"regenerateRecoveryCodes","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegenerateRecoveryCodesRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MfaRecoveryCodesResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/me/mfa/disable":{"post":{"tags":["mfa-controller"],"operationId":"disable","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisableMfaRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/me/consents":{"get":{"tags":["consent-controller"],"operationId":"listMyConsents","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConsentView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["consent-controller"],"operationId":"acceptConsents","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConsentView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/llm-keys/{keyId}/token":{"post":{"tags":["llm-keys"],"summary":"LLM API 키 발급","description":"이 키의 평문을 만들어 **한 번만** 돌려줍니다. 서버에는 해시만 남으므로 다시 조회할 수 없고, 분실하면 이 호출을 다시 해서 재발급해야 합니다. 재발급하면 이전 값은 곧바로 쓸 수 없게 됩니다.","operationId":"issueLlmKeyToken","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/IssuedLlmKeyResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/llm-keys/{keyId}/revoke":{"post":{"tags":["llm-keys"],"summary":"LLM API 키 폐기","description":"이 키를 폐기합니다. 게이트웨이에는 폴링 주기 안에 반영되고, 이후 이 키로 보낸 요청은 '폐기된 키'로 거부됩니다. 사용 기록은 남습니다.","operationId":"revokeLlmKey","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/llm-keys/{keyId}/access":{"get":{"tags":["llm-key-access"],"summary":"접근 권한 목록","description":"이 키의 접근 권한 전체와, 그 목록이 어느 키의 것인지 알려 주는 최소 정보입니다. 키 소유자와 워크스페이스 소유자만 볼 수 있습니다.","operationId":"listLlmKeyAccessGrants","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResourceAccessListResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["llm-key-access"],"summary":"접근 권한 부여","description":"지정한 사용자 또는 소유 워크스페이스 전체에 이 키의 접근 권한을 부여합니다. 사용자는 이 키를 소유한 워크스페이스의 구성원이어야 하고, 워크스페이스 전체에는 참여자·열람자까지만 부여할 수 있습니다.","operationId":"addLlmKeyAccessGrant","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddResourceAccessGrantRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResourceAccessGrantView"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/gpu-allocations/{allocationId}/release":{"post":{"tags":["gpu-controller"],"summary":"GPU 반납","operationId":"releaseGpu","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmGpuActionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GpuAllocationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/gpu-allocations/{allocationId}/extend":{"post":{"tags":["gpu-controller"],"summary":"GPU 임대 연장","operationId":"extendGpuLease","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtendGpuLeaseRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GpuAllocationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/gpu-allocations/{allocationId}/detach":{"post":{"tags":["gpu-controller"],"summary":"GPU 연결 해제","description":"연결만 해제하며 GPU 점유와 임대 기간은 유지합니다.","operationId":"detachGpu","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmGpuActionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GpuAllocationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/gpu-allocations/{allocationId}/attach":{"post":{"tags":["gpu-controller"],"summary":"가상머신에 GPU 연결","description":"가상머신 중단에 동의한 뒤 연결합니다. 임대는 이미 시작되어 있으며 연결 실패로 초기화되지 않습니다.","operationId":"attachGpu","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachGpuRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GpuAllocationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/gpu-allocations/{allocationId}/access":{"get":{"tags":["gpu-access"],"summary":"접근 권한 목록","description":"이 GPU의 접근 권한 전체와, 그 목록이 어느 GPU의 것인지 알려 주는 최소 정보입니다. GPU 소유자와 워크스페이스 소유자만 볼 수 있습니다.","operationId":"listGpuAllocationAccessGrants","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResourceAccessListResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["gpu-access"],"summary":"접근 권한 부여","description":"지정한 사용자 또는 소유 워크스페이스 전체에 이 GPU의 접근 권한을 부여합니다. 사용자는 이 GPU를 소유한 워크스페이스의 구성원이어야 하고, 워크스페이스 전체에는 참여자·열람자까지만 부여할 수 있습니다.","operationId":"addGpuAllocationAccessGrant","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddResourceAccessGrantRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResourceAccessGrantView"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/domains/{domainId}/verify":{"post":{"tags":["publishing-controller"],"operationId":"verifyDomain","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DomainDetailView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/dns-domains/{domainId}/revive":{"post":{"tags":["dns-domain"],"summary":"해제한 도메인 되살리기","description":"예약 기간 동안 이 워크스페이스가 붙잡고 있는 이름을 되찾습니다. 새로 받는 것이 아니라 이미 가진 것을 되살리는 것이므로 승인을 거치지 않습니다. 레코드는 돌아오지 않으며 다시 넣어야 합니다.","operationId":"reviveDnsDomain","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DnsDomainView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/dns-domains/{domainId}/renew":{"post":{"tags":["dns-domain"],"summary":"사용 연장","description":"사용 기한을 지금부터 다시 전체 기간만큼으로 옮깁니다. 남은 기간에 더하는 것이 아니라 언제 눌러도 같은 기간을 받습니다.","operationId":"renewDnsDomain","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DnsDomainView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/dns-domains/{domainId}/access":{"get":{"tags":["dns-domain-access"],"summary":"접근 권한 목록","description":"이 도메인의 접근 권한 전체입니다. 도메인 소유자와 워크스페이스 소유자만 볼 수 있습니다.","operationId":"listDnsDomainAccessGrants","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResourceAccessListResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["dns-domain-access"],"summary":"접근 권한 부여","description":"지정한 사용자 또는 소유 워크스페이스 전체에 이 도메인의 접근 권한을 부여합니다.","operationId":"addDnsDomainAccessGrant","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddResourceAccessGrantRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResourceAccessGrantView"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/auth/verify-email":{"post":{"tags":["auth-controller"],"operationId":"verifyEmail","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/auth/signup":{"post":{"tags":["auth-controller"],"operationId":"signup","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/auth/reverify":{"post":{"tags":["auth-controller"],"operationId":"reverify","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReverifyRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReverifyResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/auth/resend-verification":{"post":{"tags":["auth-controller"],"operationId":"resendVerification","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendVerificationRequest"}}},"required":true},"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/auth/refresh":{"post":{"tags":["auth-controller"],"operationId":"refresh","parameters":[{"name":"__Host-pickle_refresh","in":"cookie","required":false,"schema":{"type":"string"}},{"name":"X-Pickle-Csrf","in":"header","description":"CSRF 이중 제출 토큰 — __Host-pickle_csrf 쿠키 값과 일치해야 합니다 (필터 강제)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthTokenResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/auth/password-reset":{"post":{"tags":["auth-controller"],"operationId":"requestPasswordReset","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/auth/password-reset/confirm":{"post":{"tags":["auth-controller"],"operationId":"confirmPasswordReset","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetConfirmRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/auth/oauth/google/start":{"post":{"tags":["google-oauth-controller"],"operationId":"startGoogleOauth","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OauthStartRequest"}}},"required":true},"responses":{"200":{"description":"인가 URL 발급","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OauthStartResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/auth/oauth/google/complete":{"post":{"tags":["google-oauth-controller"],"operationId":"completeGoogleOauthRegistration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OauthCompleteRequest"}}},"required":true},"responses":{"200":{"description":"계정 생성과 토큰 발급","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthTokenResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/auth/oauth/google/callback":{"post":{"tags":["google-oauth-controller"],"operationId":"completeGoogleOauthCallback","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OauthCallbackRequest"}}},"required":true},"responses":{"200":{"description":"토큰 발급 / 2FA 챌린지 / 가입 필요 / 재인증 토큰 / 연동 완료","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/AuthTokenResponse"},{"$ref":"#/components/schemas/MfaChallengeResponse"},{"$ref":"#/components/schemas/OauthRegistrationResponse"},{"$ref":"#/components/schemas/ReverifyResponse"},{"$ref":"#/components/schemas/OauthLinkedResponse"}]}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/auth/mfa":{"post":{"tags":["auth-controller"],"operationId":"completeMfa","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaLoginRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AuthTokenResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/auth/logout":{"post":{"tags":["auth-controller"],"operationId":"logout","parameters":[{"name":"__Host-pickle_refresh","in":"cookie","required":false,"schema":{"type":"string"}},{"name":"X-Pickle-Csrf","in":"header","description":"CSRF 이중 제출 토큰 — __Host-pickle_csrf 쿠키 값과 일치해야 합니다 (필터 강제)","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/auth/login":{"post":{"tags":["auth-controller"],"operationId":"login","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"로그인 성공(토큰 발급) 또는 2FA 챌린지","content":{"*/*":{"schema":{"oneOf":[{"$ref":"#/components/schemas/AuthTokenResponse"},{"$ref":"#/components/schemas/MfaChallengeResponse"}]}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/admin/vms/{vmId}/start":{"post":{"tags":["admin-vm-controller"],"operationId":"adminStartVm","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/vms/{vmId}/shutdown":{"post":{"tags":["admin-vm-controller"],"operationId":"adminShutdownVm","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/vms/{vmId}/schedule-delete":{"post":{"tags":["admin-vm-controller"],"operationId":"scheduleVmDeletion","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleVmDeletionRequest"}}},"required":true},"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmDeletionResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/vms/{vmId}/reboot":{"post":{"tags":["admin-vm-controller"],"operationId":"adminRebootVm","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/vms/{vmId}/force-stop":{"post":{"tags":["admin-vm-controller"],"operationId":"adminForceStopVm","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/vms/{vmId}/force-delete":{"post":{"tags":["admin-vm-controller"],"operationId":"forceDeleteVm","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForceDeleteVmRequest"}}},"required":true},"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/vms/{vmId}/cancel-scheduled-delete":{"post":{"tags":["admin-vm-controller"],"operationId":"cancelScheduledVmDeletion","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/vm-flavors":{"get":{"tags":["admin-vm-flavor-controller"],"operationId":"listAdminVmFlavors","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VmFlavorResponse"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["admin-vm-flavor-controller"],"operationId":"createAdminVmFlavor","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVmFlavorRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmFlavorResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/users/{userId}/mfa-reset":{"post":{"tags":["admin-user-controller"],"operationId":"resetUserMfa","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/users/{userId}/enable":{"post":{"tags":["admin-user-controller"],"operationId":"enableUser","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserAdminDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/users/{userId}/disable":{"post":{"tags":["admin-user-controller"],"operationId":"disableUser","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisableUserRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserAdminDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/terminal-sessions/{sessionId}/terminate":{"post":{"tags":["admin-terminal-controller"],"operationId":"terminateTerminalSession","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/tasks/{taskId}/retry":{"post":{"tags":["admin-task-controller"],"operationId":"retryAdminTask","parameters":[{"name":"taskId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/routes/{routeId}/apply":{"post":{"tags":["admin-publishing-controller"],"operationId":"applyAdminRoute","parameters":[{"name":"routeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/routes/resync":{"post":{"tags":["admin-publishing-controller"],"operationId":"resyncRoutes","responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/requests/{requestId}/reject":{"post":{"tags":["admin-request-controller"],"operationId":"rejectRequest","parameters":[{"name":"requestId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectRequestRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RequestDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/requests/{requestId}/approve":{"post":{"tags":["admin-request-controller"],"operationId":"approveRequest","parameters":[{"name":"requestId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApproveRequestRequest"}}},"required":true},"responses":{"200":{"description":"승인 완료","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/request-periods":{"get":{"tags":["admin-request-period-controller"],"operationId":"listAdminRequestPeriods","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminRequestPeriodResponse"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["admin-request-period-controller"],"operationId":"createAdminRequestPeriod","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRequestPeriodRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminRequestPeriodResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/relays/{relayId}/token":{"post":{"tags":["admin-relay-controller"],"operationId":"issueAdminRelayToken","parameters":[{"name":"relayId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RelayTokenResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/port-mappings/{mappingId}/unsuspend":{"post":{"tags":["admin-port-mapping-controller"],"operationId":"unsuspendAdminPortMapping","parameters":[{"name":"mappingId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPortMappingResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/port-mappings/{mappingId}/suspend":{"post":{"tags":["admin-port-mapping-controller"],"operationId":"suspendAdminPortMapping","parameters":[{"name":"mappingId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuspendPortMappingRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPortMappingResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/orgs":{"get":{"tags":["admin-controller"],"operationId":"listAdminOrgs","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrgDetailResponse"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["admin-controller"],"operationId":"createOrg","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrgRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OrgDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/notifications/{notificationId}/resend":{"post":{"tags":["admin-notification-controller"],"operationId":"resendAdminNotification","parameters":[{"name":"notificationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/notices":{"get":{"tags":["admin-notice-controller"],"operationId":"listAdminNotices","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseAdminNoticeView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["admin-notice-controller"],"operationId":"createAdminNotice","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoticeCreateRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNoticeView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/notices/{noticeId}/images":{"post":{"tags":["admin-notice-controller"],"operationId":"uploadAdminNoticeImage","parameters":[{"name":"noticeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NoticeImageView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/keys/{keyId}/suspend":{"post":{"tags":["admin"],"summary":"관리자 LLM API 키 정지","description":"활성 키를 정지합니다. 사유는 감사 기록에 남고 평문 요청 본문은 기록하지 않습니다.","operationId":"suspendAdminLlmKey","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuspendAdminLlmKeyRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminLlmKeyDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/keys/{keyId}/resume":{"post":{"tags":["admin"],"summary":"관리자 LLM API 키 재개","description":"정지된 키를 다시 활성화합니다.","operationId":"resumeAdminLlmKey","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminLlmKeyDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/accounts":{"get":{"tags":["admin"],"summary":"OpenRouter 사업 계정 목록","description":"관리 범위의 사업별 OpenRouter account와 credential 상태를 조회합니다. 인증 정보와 vendor 내부 식별자는 반환하지 않습니다.","operationId":"listAdminLlmAccounts","parameters":[{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OpenRouterAccountResponse"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["admin"],"summary":"OpenRouter 사업 계정 등록","description":"기관에 사업별 account metadata를 등록합니다. 재인증과 이름 확인이 필요하며 management credential은 별도 stage 작업으로 검증합니다.","operationId":"createAdminLlmAccount","parameters":[{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOpenRouterAccountRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OpenRouterAccountResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/accounts/{accountId}/credentials/staged":{"post":{"tags":["admin"],"summary":"OpenRouter 관리 credential 검증 및 대기 등록","description":"재인증과 account 이름 확인 뒤 management 전용 권한과 vendor workspace를 disposable key로 검증하고 STAGED 상태로 저장합니다. 평문과 credential 조각은 응답하지 않습니다.","operationId":"stageAdminLlmAccountCredential","parameters":[{"name":"accountId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StageOpenRouterCredentialRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OpenRouterAccountResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/accounts/{accountId}/credentials/staged/cancel":{"post":{"tags":["admin"],"summary":"대기 중 OpenRouter credential 취소","description":"재인증과 이름 확인 뒤 아직 활성화하지 않은 STAGED credential 암호문을 삭제합니다. ACTIVE credential에는 영향을 주지 않습니다.","operationId":"cancelAdminLlmAccountCredential","parameters":[{"name":"accountId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmOpenRouterAccountRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OpenRouterAccountResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/accounts/{accountId}/credentials/staged/activate":{"post":{"tags":["admin"],"summary":"대기 중 OpenRouter credential 활성화","description":"재인증과 이름 확인 뒤 STAGED credential을 다시 검증합니다. 교체 시 기존 ACTIVE가 만든 disposable key를 새 credential로 조회·수정·삭제한 뒤 두 상태를 원자적으로 ACTIVE와 RETIRING으로 전환합니다.","operationId":"activateAdminLlmAccountCredential","parameters":[{"name":"accountId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmOpenRouterAccountRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OpenRouterAccountResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/accounts/{accountId}/credentials/retiring/rollback":{"post":{"tags":["admin"],"summary":"OpenRouter credential 교체 되돌리기","description":"재인증과 이름 확인 뒤 현재 ACTIVE를 STAGED로, 이전 RETIRING을 ACTIVE로 원자적으로 되돌립니다. Vendor credential은 API가 폐기하지 않습니다.","operationId":"rollbackAdminLlmAccountCredential","parameters":[{"name":"accountId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmOpenRouterAccountRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OpenRouterAccountResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/accounts/{accountId}/credentials/retiring/finalize":{"post":{"tags":["admin"],"summary":"이전 OpenRouter credential 정리","description":"새 ACTIVE credential로 key reconciliation이 성공하고 운영자가 vendor console에서 이전 management key를 폐기했음을 확인한 뒤 RETIRING 암호문을 삭제합니다.","operationId":"finalizeAdminLlmAccountCredential","parameters":[{"name":"accountId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinalizeOpenRouterCredentialRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OpenRouterAccountResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/accounts/{accountId}/credentials/active/delete":{"post":{"tags":["admin"],"summary":"사용하지 않는 OpenRouter credential 삭제","description":"연결된 key와 rotation이 없고 운영자가 vendor console 폐기를 확인한 경우에만 ACTIVE 암호문을 삭제합니다. API는 vendor management key 자체를 폐기하지 않습니다.","operationId":"deleteActiveAdminLlmAccountCredential","parameters":[{"name":"accountId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinalizeOpenRouterCredentialRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OpenRouterAccountResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/gpu-reclaim-reviews/{reviewId}/decision":{"post":{"tags":["admin-gpu-controller"],"summary":"GPU 회수 검토 결정","operationId":"decideGpuReclaimReview","parameters":[{"name":"reviewId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecideGpuReviewRequest"}}},"required":true},"responses":{"204":{"description":"No Content"},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/gpu-allocations/{allocationId}/reconcile":{"post":{"tags":["admin-gpu-controller"],"summary":"GPU 연결 상태 재확인","description":"전원과 장치 설정을 변경하지 않고 실제 상태가 확인된 작업의 잠금만 정리합니다. GPU 점유와 회수 의도는 유지합니다.","operationId":"reconcileGpu","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GpuReasonRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GpuAllocationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/gpu-allocations/{allocationId}/reclaim":{"post":{"tags":["admin-gpu-controller"],"summary":"관리자 GPU 회수","operationId":"reclaimGpu","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GpuReasonRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GpuAllocationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/gpu-allocations/{allocationId}/priority":{"post":{"tags":["admin-gpu-controller"],"summary":"GPU 대기 우선순위 변경","operationId":"updateGpuPriority","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateGpuPriorityRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GpuAllocationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/gpu-allocations/{allocationId}/extend":{"post":{"tags":["admin-gpu-controller"],"summary":"관리자 GPU 임대 연장","operationId":"extendAdminGpuLease","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtendGpuLeaseRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GpuAllocationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/drift-findings/{findingId}/resolve":{"post":{"tags":["admin-drift-controller"],"operationId":"resolveDriftFinding","parameters":[{"name":"findingId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveDriftFindingRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DriftFindingResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/domains/{domainId}/verify":{"post":{"tags":["admin-publishing-controller"],"operationId":"verifyAdminDomain","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/domains/{domainId}/force-release":{"post":{"tags":["admin-publishing-controller"],"operationId":"forceReleaseDomain","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/campus-ip-requests/{requestId}/status":{"post":{"tags":["admin-campus-ip-request-controller"],"operationId":"updateAdminCampusIpRequestStatus","parameters":[{"name":"requestId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCampusIpRequestStatusRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminCampusIpRequestView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/announcements":{"get":{"tags":["announcement-controller"],"operationId":"listAnnouncements","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseAnnouncementView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["announcement-controller"],"operationId":"createAnnouncement","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnouncementCreateRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AnnouncementView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/workspaces/{workspaceId}":{"get":{"tags":["workspace-controller"],"operationId":"getWorkspace","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkspaceDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["workspace-controller"],"operationId":"deleteWorkspace","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"No Content"},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["workspace-controller"],"operationId":"updateWorkspace","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkspaceRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkspaceDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/workspaces/{workspaceId}/members/{userId}":{"delete":{"tags":["workspace-controller"],"operationId":"removeWorkspaceMember","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["workspace-controller"],"operationId":"updateWorkspaceMember","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkspaceMemberRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkspaceMemberResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/settings":{"get":{"tags":["vm-controller"],"operationId":"getVmSettings","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VmSettingView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["vm-controller"],"operationId":"updateVmSettings","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VmSettingsUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VmSettingView"}}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/access/{grantId}":{"delete":{"tags":["vm-access"],"summary":"접근 권한 회수","description":"회수해도 이미 열람한 초기 비밀번호와 이미 열려 있는 SSH 세션은 회수되지 않습니다. 필요하면 비밀번호를 재생성해 주세요.","operationId":"removeVmAccessGrant","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"grantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["vm-access"],"summary":"접근 권한 등급 변경","operationId":"updateVmAccessGrant","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"grantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateResourceAccessGrantRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResourceAccessGrantView"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/llm-keys/{keyId}":{"get":{"tags":["llm-keys"],"summary":"LLM API 키 상세","description":"접근 권한이 있는 키의 상세입니다. 키 평문과 그 해시는 어떤 응답에도 담기지 않습니다.","operationId":"getLlmKey","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LlmKeyDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["llm-keys"],"summary":"LLM API 키 수정","description":"키 이름과 사용 목적, 본문 기록 여부를 바꿉니다. 생략한 항목은 그대로 둡니다.","operationId":"updateLlmKey","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLlmKeyRequest"}}},"required":true},"responses":{"204":{"description":"No Content"},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/llm-keys/{keyId}/access/{grantId}":{"delete":{"tags":["llm-key-access"],"summary":"접근 권한 회수","description":"회수해도 발급 시 이미 확인한 키 평문은 회수되지 않습니다. 필요하면 키를 재발급해 주세요.","operationId":"removeLlmKeyAccessGrant","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"grantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["llm-key-access"],"summary":"접근 권한 등급 변경","operationId":"updateLlmKeyAccessGrant","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"grantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateResourceAccessGrantRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResourceAccessGrantView"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/gpu-allocations/{allocationId}/access/{grantId}":{"delete":{"tags":["gpu-access"],"summary":"접근 권한 회수","description":"접근 권한만 회수하며 연결된 가상머신은 재시작하지 않습니다.","operationId":"removeGpuAllocationAccessGrant","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"grantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["gpu-access"],"summary":"접근 권한 등급 변경","operationId":"updateGpuAllocationAccessGrant","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"grantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateResourceAccessGrantRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResourceAccessGrantView"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/domains/{domainId}":{"get":{"tags":["publishing-controller"],"operationId":"getDomain","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DomainDetailView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["publishing-controller"],"operationId":"deleteDomain","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["publishing-controller"],"operationId":"updateDomain","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDomainRequest"}}},"required":true},"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/dns-domains/{domainId}/access/{grantId}":{"delete":{"tags":["dns-domain-access"],"summary":"접근 권한 회수","description":"회수해도 이미 존에 들어간 레코드는 그대로 남습니다. 필요하면 레코드를 먼저 정리해 주세요.","operationId":"removeDnsDomainAccessGrant","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"grantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["dns-domain-access"],"summary":"접근 권한 등급 변경","operationId":"updateDnsDomainAccessGrant","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"grantId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateResourceAccessGrantRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResourceAccessGrantView"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/vms/{vmId}/period":{"patch":{"tags":["admin-vm-controller"],"operationId":"updateVmPeriod","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VmPeriodUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/vms/{vmId}/gateway-block":{"patch":{"tags":["admin-vm-controller"],"operationId":"updateVmGatewayBlock","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VmGatewayBlockUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/vm-flavors/{flavorId}":{"patch":{"tags":["admin-vm-flavor-controller"],"operationId":"updateAdminVmFlavor","parameters":[{"name":"flavorId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVmFlavorRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmFlavorResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/users/{userId}":{"get":{"tags":["admin-user-controller"],"operationId":"getUser","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserAdminDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["admin-controller"],"operationId":"updateUser","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserAdminRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserSummaryResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/users/{userId}/profile":{"patch":{"tags":["admin-user-controller"],"operationId":"updateUserProfile","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminUpdateProfileRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserAdminDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/request-periods/{periodId}":{"patch":{"tags":["admin-request-period-controller"],"operationId":"updateAdminRequestPeriod","parameters":[{"name":"periodId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRequestPeriodRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminRequestPeriodResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/port-mappings/{mappingId}/guards":{"patch":{"tags":["admin-port-mapping-controller"],"operationId":"updateAdminPortMappingGuards","parameters":[{"name":"mappingId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePortMappingGuardsRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminPortMappingResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/os-images/{imageId}":{"patch":{"tags":["admin-os-image-controller"],"operationId":"updateAdminOsImage","parameters":[{"name":"imageId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOsImageStatusRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminOsImageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/orgs/{orgId}":{"patch":{"tags":["admin-controller"],"operationId":"updateOrg","parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrgRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OrgDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/notices/{noticeId}":{"delete":{"tags":["admin-notice-controller"],"operationId":"deleteAdminNotice","parameters":[{"name":"noticeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"No Content"},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["admin-notice-controller"],"operationId":"updateAdminNotice","parameters":[{"name":"noticeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoticeUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminNoticeView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/nodes/{nodeId}":{"patch":{"tags":["admin-node-controller"],"operationId":"updateAdminNode","parameters":[{"name":"nodeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateNodeStatusRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NodeSummaryResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/accounts/{accountId}":{"get":{"tags":["admin"],"summary":"OpenRouter 사업 계정 상세","description":"관리 범위의 사업 계정 정보, 유료 모델 연결 가능 여부, 연결된 키 수와 관리용 키 상태를 조회합니다. 키 값은 반환하지 않습니다.","operationId":"getAdminLlmAccount","parameters":[{"name":"accountId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OpenRouterAccountResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["admin"],"summary":"OpenRouter 사업 계정 정보 수정","description":"이름·사업·담당자·상태 중 보낸 항목만 변경합니다. 활성 또는 미만료 key가 연결된 account는 보관할 수 없습니다.","operationId":"updateAdminLlmAccount","parameters":[{"name":"accountId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOpenRouterAccountRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OpenRouterAccountResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/gpus/{gpuId}":{"patch":{"tags":["admin-gpu-controller"],"summary":"GPU 운영 상태 변경","operationId":"updateAdminGpu","parameters":[{"name":"gpuId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateGpuStatusRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GpuView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/domains/{domainId}/renewal":{"patch":{"tags":["admin-publishing-controller"],"summary":"도메인 사용 기한 조정","description":"외부 도메인의 사용 기한을 옮깁니다. 미루면 그만큼 더 쓰고, 당기면 그 시점에 연장하지 않는 한 이름이 해제됩니다.","operationId":"updateDomainRenewal","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDomainRenewalRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminDomainView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/domain-roots/{rootDomain}":{"patch":{"tags":["admin-publishing-controller"],"summary":"루트 도메인 승인 정책 변경","description":"이 루트 아래 이름 신청을 자동으로 승인할지, 승인 큐에 세울지 정합니다. 앞으로 들어오는 신청에만 적용되며 이미 발급된 이름과 이미 기다리는 신청은 건드리지 않습니다.","operationId":"updateDomainRoot","parameters":[{"name":"rootDomain","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDomainRootRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminDomainRootView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms":{"get":{"tags":["vm-controller"],"operationId":"listVms","parameters":[{"name":"workspaceId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseVmSummaryResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}":{"get":{"tags":["vm-controller"],"operationId":"getVm","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["vm-controller"],"operationId":"deleteVm","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmDeletionResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/ssh-key/private-key":{"get":{"tags":["vm-ssh-key-controller"],"operationId":"downloadVmSshKey","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmSshKeyIssueResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/password":{"get":{"tags":["vm-controller"],"operationId":"revealVmPassword","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmPasswordResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/metrics":{"get":{"tags":["vm-controller"],"operationId":"getVmMetrics","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"timeframe","in":"query","description":"조회 구간 — HOUR/DAY/WEEK/MONTH/YEAR (해상도는 구간에 따라 거칠어짐)","required":false,"schema":{"$ref":"#/components/schemas/RrdTimeframe","default":"HOUR"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmMetricsResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/events":{"get":{"tags":["vm-controller"],"operationId":"listVmEvents","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseVmEventResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vm-flavors":{"get":{"tags":["vm-flavor-controller"],"operationId":"listVmFlavors","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VmFlavorResponse"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/resources":{"get":{"tags":["resource-index-controller"],"operationId":"listResources","parameters":[{"name":"type","in":"query","required":false,"schema":{"$ref":"#/components/schemas/ResourceType"}},{"name":"workspaceId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseResourceSummaryResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/requests/{requestId}":{"get":{"tags":["request-controller"],"operationId":"getRequest","parameters":[{"name":"requestId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RequestDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/request-periods":{"get":{"tags":["request-period-controller"],"summary":"신청 가능한 사용 기간 목록","description":"관리자가 등록한 기간 중 오늘 기준으로 아직 끝나지 않은 것만 돌려줍니다. 모든 항목이 종료일을 가집니다. 끝나지 않는 기간은 신청 본문의 reqIndefinite로 요청합니다.","operationId":"listRequestPeriods","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RequestPeriodResponse"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/os-images":{"get":{"tags":["os-image-controller"],"operationId":"listOsImages","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OsImageResponse"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/orgs":{"get":{"tags":["org-controller"],"operationId":"listOrgs","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrgSummaryResponse"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/notifications":{"get":{"tags":["notification-controller"],"operationId":"listNotifications","parameters":[{"name":"unreadOnly","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseNotificationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/notifications/unread-count":{"get":{"tags":["notification-controller"],"operationId":"getUnreadNotificationCount","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UnreadCountResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/notices":{"get":{"tags":["notice-controller"],"operationId":"listNotices","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseNoticeView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/notices/{noticeId}":{"get":{"tags":["notice-controller"],"operationId":"getNotice","parameters":[{"name":"noticeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NoticeView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/notices/{noticeId}/images/{imageId}":{"get":{"tags":["notice-controller"],"operationId":"getNoticeImage","parameters":[{"name":"noticeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"imageId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/meta/terms":{"get":{"tags":["meta-controller"],"operationId":"listTerms","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TermsVersionView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/meta/terms/{docType}":{"get":{"tags":["meta-controller"],"operationId":"getTerms","parameters":[{"name":"docType","in":"path","required":true,"schema":{"$ref":"#/components/schemas/TermsDocType"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TermsDocumentView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/meta/status":{"get":{"tags":["meta-controller"],"operationId":"systemStatus","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SystemStatusResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/meta/request-options":{"get":{"tags":["meta-controller"],"operationId":"requestOptions","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RequestOptionsResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/meta/profile-options":{"get":{"tags":["meta-controller"],"operationId":"profileOptions","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProfileOptionsResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"security":[]}},"/api/v1/me":{"get":{"tags":["me-controller"],"operationId":"me","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserProfileResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/me/activity":{"get":{"tags":["me-activity-controller"],"operationId":"listMyActivity","parameters":[{"name":"action","in":"query","required":false,"schema":{"type":"string"}},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseActivityEntryResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/llm-keys":{"get":{"tags":["llm-keys"],"summary":"LLM API 키 목록","description":"`workspaceId`를 지정하지 않으면 내가 접근 권한을 가진 키만 옵니다. 지정하면 그 워크스페이스의 키 전부이고, 접근 권한이 없는 키는 이름·상태·소유자만 담긴 제한된 행으로 표시됩니다.","operationId":"listLlmKeys","parameters":[{"name":"workspaceId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseLlmKeySummaryResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/llm-keys/{keyId}/usage":{"get":{"tags":["llm-keys"],"summary":"LLM API 키 사용량","description":"이 키의 일별 사용량입니다. 하루는 한국 시간 기준이고, 호출이 없던 날도 0으로 채워집니다. 게이트웨이가 배치로 보고하므로 오늘 자 값은 아직 채워지는 중입니다.","operationId":"getLlmKeyUsage","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"days","in":"query","description":"오늘을 포함해 거슬러 올라갈 일수","required":false,"schema":{"type":"integer","format":"int32","default":30,"maximum":90,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LlmKeyUsageTrendResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/llm-keys/{keyId}/models":{"get":{"tags":["llm-keys"],"summary":"LLM API 키로 호출할 수 있는 모델","description":"이 키로 부를 수 있는 모델입니다. 자체 서빙 모델은 플랫폼 카탈로그에서, 유료 모델은 공급자 목록의 캐시에서 옵니다. 키에 모델 허용 목록이 있으면 그 목록에 맞는 것만 담기고, 금액 한도가 아직 없어도 무엇을 신청할지 볼 수 있도록 목록은 채워집니다. 최종 판정은 호출 시점에 이뤄지므로 여기 있는 모델이 항상 응답한다는 보장은 아닙니다.","operationId":"listLlmKeyModels","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LlmKeyModelsResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/llm-keys/{keyId}/bodies":{"get":{"tags":["llm-keys"],"summary":"기록된 본문 목록","description":"본문 기록을 켠 동안 이 키로 오간 프롬프트와 응답의 목록입니다. 각 줄에는 앞부분만 담기고, 전문은 개별 조회로 봅니다. **이 키에 접근 권한이 있는 사람은 모두 읽을 수 있습니다** — 게이트웨이는 키를 인증할 뿐 보낸 사람이 누구인지 알지 못하므로 열람 단위가 사람이 아니라 키입니다. 기록은 30일 동안 보관하고 지난 것부터 지웁니다. 본문 기록을 끈 뒤에도 이미 기록된 것은 보관 기간까지 그대로 보입니다.","operationId":"listLlmKeyBodies","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","description":"한 번에 가져올 개수. 한 건이 최대 320 KiB라 통상 목록보다 상한이 낮습니다.","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":50,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseLlmKeyBodySummaryResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/llm-keys/{keyId}/bodies/{bodyId}":{"get":{"tags":["llm-keys"],"summary":"기록된 본문 상세","description":"기록 한 건의 전문입니다. `request`는 보통 보낸 messages 배열 그대로이고, 길이 제한에 걸린 경우에는 앞부분을 담은 문자열입니다. 저장된 본문을 그대로 돌려주므로 **재인증이 필요합니다** (X-Reauth-Token). 목록 조회에는 필요하지 않습니다.","operationId":"getLlmKeyBody","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"bodyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LlmKeyBodyDetailResponse"}}}},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/gpus":{"get":{"tags":["gpu-controller"],"summary":"GPU 목록","operationId":"listGpus","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GpuView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/gpu-allocations":{"get":{"tags":["gpu-controller"],"summary":"GPU 할당 목록","operationId":"listGpuAllocations","parameters":[{"name":"workspaceId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseGpuAllocationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/gpu-allocations/{allocationId}":{"get":{"tags":["gpu-controller"],"summary":"GPU 할당 상세","operationId":"getGpuAllocation","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GpuAllocationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/gpu-allocations/{allocationId}/attachment-options":{"get":{"tags":["gpu-controller"],"summary":"GPU에 연결할 가상머신","operationId":"listGpuAttachmentOptions","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GpuAttachmentOption"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/domains":{"get":{"tags":["publishing-controller"],"operationId":"listDomains","parameters":[{"name":"vmId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/DomainStatus"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseDomainSummaryView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/dns-domains":{"get":{"tags":["dns-domain"],"summary":"도메인 목록","description":"`workspaceId`를 지정하지 않으면 내가 접근 권한을 가진 도메인만 옵니다. 지정하면 그 워크스페이스의 도메인 전부이고, 접근 권한이 없는 도메인도 이름과 상태, 소유자까지는 보입니다.","operationId":"listDnsDomains","parameters":[{"name":"workspaceId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseDnsDomainView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/dns-domains/{domainId}":{"get":{"tags":["dns-domain"],"summary":"도메인 상세","operationId":"getDnsDomain","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DnsDomainView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["dns-domain"],"summary":"도메인 해제","description":"레코드를 지우고 이름을 해제합니다. 이름은 예약 기간 동안 이 워크스페이스에 남아 있다가 회수됩니다.","operationId":"deleteDnsDomain","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"202":{"description":"Accepted"},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/workspaces":{"get":{"tags":["admin-workspace-controller"],"operationId":"listAdminWorkspaces","parameters":[{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminWorkspaceOptionResponse"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/workspaces/{workspaceId}":{"get":{"tags":["admin-workspace-controller"],"operationId":"getAdminWorkspace","parameters":[{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminWorkspaceDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/vms":{"get":{"tags":["admin-vm-controller"],"operationId":"listAdminVms","parameters":[{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"workspaceId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/VmStatus"}},{"name":"expiringInDays","in":"query","required":false,"schema":{"type":"integer","format":"int32","minimum":1}},{"name":"expired","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"q","in":"query","required":false,"schema":{"type":"string","maxLength":100,"minLength":1}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["name","-name","endDate","-endDate","createdAt","-createdAt"]}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseVmSummaryResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/vms/{vmId}":{"get":{"tags":["admin-vm-controller"],"operationId":"getAdminVm","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VmDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/vms/{vmId}/events":{"get":{"tags":["admin-vm-controller"],"operationId":"listAdminVmEvents","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseVmEventResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/users":{"get":{"tags":["admin-user-controller"],"operationId":"listUsers","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","maxLength":100,"minLength":1}},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/UserStatus"}},{"name":"role","in":"query","required":false,"schema":{"$ref":"#/components/schemas/UserRole"}},{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["name","-name","email","-email","createdAt","-createdAt"]}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseUserAdminViewResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/terminal-sessions":{"get":{"tags":["admin-terminal-controller"],"operationId":"listAdminTerminalSessions","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TerminalSessionView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/tasks":{"get":{"tags":["admin-task-controller"],"operationId":"listAdminTasks","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProvisioningTaskStatus"}}},{"name":"kind","in":"query","required":false,"schema":{"$ref":"#/components/schemas/ProvisioningTaskKind"}},{"name":"vmId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseAdminTaskResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/system-summary":{"get":{"tags":["admin-summary-controller"],"operationId":"getSystemSummary","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SystemDashboardSummaryResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/summary":{"get":{"tags":["admin-summary-controller"],"operationId":"getAdminSummary","parameters":[{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OrgDashboardSummaryResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/settings":{"get":{"tags":["admin-settings-controller"],"operationId":"listSettings","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SettingView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/routes":{"get":{"tags":["admin-publishing-controller"],"operationId":"listAdminRoutes","parameters":[{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/RouteStatus"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseAdminRouteView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/requests":{"get":{"tags":["admin-request-controller"],"operationId":"listAdminRequests","parameters":[{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/RequestStatus"}},{"name":"type","in":"query","required":false,"schema":{"$ref":"#/components/schemas/ResourceType"}},{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseRequestDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/requests/{requestId}":{"get":{"tags":["admin-request-controller"],"operationId":"getAdminRequest","parameters":[{"name":"requestId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RequestDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/requests/{requestId}/context":{"get":{"tags":["admin-request-controller"],"operationId":"getApprovalContext","parameters":[{"name":"requestId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApprovalContextResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/relays":{"get":{"tags":["admin-relay-controller"],"operationId":"listAdminRelays","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminRelayView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/port-mappings":{"get":{"tags":["admin-port-mapping-controller"],"operationId":"listAdminPortMappings","parameters":[{"name":"relayId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"vmId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/PortMappingStatus"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseAdminPortMappingResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/os-images":{"get":{"tags":["admin-os-image-controller"],"operationId":"listAdminOsImages","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminOsImageResponse"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/notifications":{"get":{"tags":["admin-notification-controller"],"operationId":"listAdminNotifications","parameters":[{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/NotificationStatus"}},{"name":"event","in":"query","required":false,"schema":{"type":"string"}},{"name":"email","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseAdminNotificationResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/nodes":{"get":{"tags":["admin-node-controller"],"operationId":"listAdminNodes","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NodeSummaryResponse"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/nodes/{nodeId}/metrics":{"get":{"tags":["admin-node-controller"],"operationId":"getAdminNodeMetrics","parameters":[{"name":"nodeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"timeframe","in":"query","description":"조회 구간 — HOUR/DAY/WEEK/MONTH/YEAR (해상도는 구간에 따라 거칠어짐)","required":false,"schema":{"$ref":"#/components/schemas/RrdTimeframe","default":"HOUR"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NodeMetricsResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/usage":{"get":{"tags":["admin"],"summary":"관리자 LLM 사용량 통계","description":"DB에 저장된 rollup과 usage event, vendor meter cache, gateway 자기보고를 읽어 수요·소비처·한도 검토·데이터 신뢰도를 제공합니다. 조회 과정에서 gateway나 vendor를 직접 호출하지 않습니다.","operationId":"getAdminLlmUsage","parameters":[{"name":"orgId","in":"query","description":"조회할 기관. 기관 계층은 맡은 기관만 지정할 수 있습니다.","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"workspaceId","in":"query","description":"소비처를 key 단계로 좁힐 workspace 공개 ID","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"days","in":"query","description":"일별 추이와 소비처 기간. 7, 30, 90 중 하나","required":false,"schema":{"type":"integer","format":"int32","default":7}},{"name":"top","in":"query","description":"소비처와 한도 검토가 각각 반환할 최대 행 수","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminLlmUsageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/status":{"get":{"tags":["admin"],"summary":"관리자 LLM 서비스 상태","description":"게이트웨이 자기보고와 upstream별 passive·active·catalog 현재 상태를 조회합니다. 조회 과정에서 gateway나 upstream을 직접 호출하지 않으며 변경 작업도 제공하지 않습니다.","operationId":"getAdminLlmStatus","parameters":[{"name":"orgId","in":"query","description":"조회할 기관. 기관 계층은 맡은 기관만 지정할 수 있습니다.","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LlmStatusResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/openrouter-models":{"get":{"tags":["admin"],"summary":"유료 모델 카탈로그","description":"승인 화면에서 고를 수 있는 유료 모델 후보와 그 가격을 조회합니다. 캐시만 읽으므로 이 호출이 벤더를 부르지 않으며, 목록이 비어 있거나 오래됐어도 모델 이름을 직접 입력해 승인할 수 있습니다. 목록이 빈 이유는 신선도 하나로 갈리지 않습니다. 한 번도 못 가져온 것과 계속 실패하는 것이 둘 다 UNKNOWN이므로, lastError와 consecutiveFailures를 함께 읽어야 구분됩니다.","operationId":"listAdminOpenRouterModels","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OpenRouterCatalogueResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/metrics":{"get":{"tags":["admin"],"summary":"관리자 LLM upstream 지표","description":"raw usage event에서 마지막 처리 upstream별 최종 결과와 지연, token, attempt coverage를 집계합니다. 중간 retry 경로나 uptime을 뜻하지 않습니다.","operationId":"getAdminLlmMetrics","parameters":[{"name":"orgId","in":"query","description":"조회할 기관. 기관 계층은 맡은 기관만 지정할 수 있습니다.","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"days","in":"query","description":"진단 기간(일), 최대 31일","required":false,"schema":{"type":"integer","format":"int32","default":7,"maximum":31,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LlmMetricsResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/keys":{"get":{"tags":["admin"],"summary":"관리자 LLM API 키 목록","description":"기관과 워크스페이스, 발급 신청, 상태, 검색어로 키를 조회합니다. 키 평문과 해시, 평문 앞부분은 반환하지 않습니다.","operationId":"listAdminLlmKeys","parameters":[{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"workspaceId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"requestId","in":"query","description":"키를 발급한 신청 공개 ID","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"openrouterAccountId","in":"query","description":"연결된 사업 계정의 공개 ID","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/LlmApiKeyStatus"}},{"name":"query","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseAdminLlmKeySummaryResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/keys/{keyId}":{"get":{"tags":["admin"],"summary":"관리자 LLM API 키 상세","description":"기관 범위 안의 키 운영 상태와 한도를 조회합니다. 인증 비밀이나 기록된 본문은 반환하지 않습니다.","operationId":"getAdminLlmKey","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminLlmKeyDetailResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/keys/{keyId}/usage":{"get":{"tags":["admin"],"summary":"관리자 LLM API 키 사용량","description":"이 키의 일별 사용량과, 키 소유자 화면에는 없는 분해 셋입니다. 일별 사용량은 소유자가 보는 것과 같은 값이고 같은 계산을 씁니다. 분해 셋은 일별 금액, 경로별 사용, 공급자가 요청과 다른 모델로 응답한 사례입니다. 하루는 한국 시간 기준이고 호출이 없던 날도 0으로 채워집니다. 게이트웨이가 배치로 보고하므로 오늘 자 값은 아직 채워지는 중입니다.","operationId":"getAdminLlmKeyUsage","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"days","in":"query","description":"오늘을 포함해 거슬러 올라갈 일수","required":false,"schema":{"type":"integer","format":"int32","default":30,"maximum":90,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminLlmKeyUsageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/keys/{keyId}/models":{"get":{"tags":["admin"],"summary":"관리자 LLM API 키로 호출할 수 있는 모델","description":"이 키로 부를 수 있는 모델입니다. 키 소유자가 보는 것과 같은 값이고 같은 계산을 씁니다. 허용 목록을 정할 때 그 목록이 실제로 무엇을 남기는지 확인하는 자리입니다. 최종 판정은 호출 시점에 이뤄지므로 여기 있는 모델이 항상 응답한다는 보장은 아닙니다.","operationId":"listAdminLlmKeyModels","parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LlmKeyModelsResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/llm/accounts/{accountId}/usage":{"get":{"tags":["admin"],"summary":"OpenRouter 사업 계정 사용량","description":"이 계정의 키들이 무엇에 얼마를 썼는지 귀속해 보여 줍니다. **공급자가 말하는 지출액이나 잔액이 아닙니다** — 그쪽은 계정 상세의 credits가 답하고 기간도 다릅니다. 키가 확인되지 않은 요청은 어느 계정에도 속하지 않고, 공급자가 금액을 알려 주지 않은 요청은 금액이 0인 것이 아니라 모르는 것이라 합계에서 빠집니다. 그래서 금액마다 가격이 붙은 요청 수가 함께 옵니다.","operationId":"getAdminLlmAccountUsage","parameters":[{"name":"accountId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"days","in":"query","description":"오늘을 포함해 거슬러 올라갈 일수","required":false,"schema":{"type":"integer","format":"int32","default":30,"maximum":90,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminLlmAccountUsageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/ip-allocations":{"get":{"tags":["admin-ip-allocation-controller"],"operationId":"listIpAllocations","parameters":[{"name":"poolId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/AllocationStatus"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseIpAllocationResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/gpus":{"get":{"tags":["admin-gpu-controller"],"summary":"관리자 GPU 목록","operationId":"listAdminGpus","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GpuView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/gpu-reclaim-reviews":{"get":{"tags":["admin-gpu-controller"],"summary":"GPU 회수 검토 목록","operationId":"listGpuReclaimReviews","parameters":[{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseGpuReclaimReviewView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/gpu-allocations":{"get":{"tags":["admin-gpu-controller"],"summary":"관리자 GPU 할당 목록","operationId":"listAdminGpuAllocations","parameters":[{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"workspaceId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/GpuAllocationStatus"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseGpuAllocationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/gpu-allocations/{allocationId}":{"get":{"tags":["admin-gpu-controller"],"summary":"관리자 GPU 할당 상세","operationId":"getAdminGpuAllocation","parameters":[{"name":"allocationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GpuAllocationView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/drift-findings":{"get":{"tags":["admin-drift-controller"],"operationId":"listDriftFindings","parameters":[{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/DriftFindingStatus"}},{"name":"kind","in":"query","required":false,"schema":{"$ref":"#/components/schemas/DriftFindingKind"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseDriftFindingResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/domains":{"get":{"tags":["admin-publishing-controller"],"operationId":"listAdminDomains","parameters":[{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"kind","in":"query","required":false,"schema":{"$ref":"#/components/schemas/DomainKind"}},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/DomainStatus"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseAdminDomainView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/domains/{domainId}/records":{"get":{"tags":["admin-publishing-controller"],"summary":"도메인 레코드 열람","description":"이 이름이 지금 무엇을 가리키는지 봅니다. 읽기 전용입니다.","operationId":"listAdminDomainRecords","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecordSetView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/domain-roots":{"get":{"tags":["admin-publishing-controller"],"summary":"루트 도메인 목록","description":"이름을 발급할 수 있는 루트와 그 승인 정책. 기관으로 좁히지 않습니다 — 이름 공간은 기관끼리 공유하므로, 자기 루트의 정책을 정하는 사람도 다른 루트가 있다는 것은 볼 수 있어야 합니다.","operationId":"listDomainRoots","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminDomainRootView"}}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/certificates":{"get":{"tags":["admin-publishing-controller"],"operationId":"listAdminCertificates","parameters":[{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/CertificateStatus"}},{"name":"expiringInDays","in":"query","required":false,"schema":{"type":"integer","format":"int32","minimum":1}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseAdminCertificateView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/capacity-trend":{"get":{"tags":["admin-summary-controller"],"operationId":"getAdminCapacityTrend","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":90,"maximum":365,"minimum":7}},{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CapacityTrendResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/campus-ip-requests":{"get":{"tags":["admin-campus-ip-request-controller"],"operationId":"listAdminCampusIpRequests","parameters":[{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/CampusIpRequestStatus"}},{"name":"vmId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseAdminCampusIpRequestView"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/audit":{"get":{"tags":["admin-audit-controller"],"operationId":"listAuditLogs","parameters":[{"name":"actorEmail","in":"query","required":false,"schema":{"type":"string"}},{"name":"action","in":"query","required":false,"schema":{"type":"string"}},{"name":"targetType","in":"query","required":false,"schema":{"type":"string"}},{"name":"targetId","in":"query","required":false,"schema":{"type":"string"}},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"orgId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20,"maximum":100,"minimum":1}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseAuditLogViewResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/port-forwardings/{portForwardingId}":{"delete":{"tags":["port-forwarding-controller"],"operationId":"deleteVmPortForwarding","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"portForwardingId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/vms/{vmId}/campus-ip-requests/{requestId}":{"delete":{"tags":["campus-ip-request-controller"],"operationId":"cancelVmCampusIpRequest","parameters":[{"name":"vmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"requestId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"No Content"},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/me/identities/{provider}":{"delete":{"tags":["identity-controller"],"operationId":"unlinkIdentity","parameters":[{"name":"provider","in":"path","required":true,"schema":{"$ref":"#/components/schemas/IdentityProvider"}},{"name":"X-Reauth-Token","in":"header","description":"재인증(sudo-mode) 토큰 — POST /auth/reverify가 발급 (10분 유효, 다회용). 없거나 만료·무효면 403 REAUTH_REQUIRED.","required":false,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"403":{"description":"재인증 필요 — 유효한 X-Reauth-Token 없음 (`REAUTH_REQUIRED`)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/port-mappings/{mappingId}":{"delete":{"tags":["admin-port-mapping-controller"],"operationId":"deleteAdminPortMapping","parameters":[{"name":"mappingId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Accepted","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/admin/notices/{noticeId}/images/{imageId}":{"delete":{"tags":["admin-notice-controller"],"operationId":"deleteAdminNoticeImage","parameters":[{"name":"noticeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"imageId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"No Content"},"default":{"description":"오류 — 상태 코드와 무관하게 Problem 형태","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"components":{"schemas":{"UpdateProfileRequest":{"type":"object","minProperties":1,"properties":{"name":{"type":"string","maxLength":50,"minLength":0},"position":{"anyOf":[{"$ref":"#/components/schemas/UserPosition"},{"type":"null"}]},"studentNo":{"type":["string","null"],"maxLength":20,"minLength":0},"departmentCode":{"type":["string","null"],"maxLength":32,"minLength":0},"departmentOther":{"type":["string","null"],"maxLength":100,"minLength":0}}},"UserPosition":{"type":"string","enum":["STUDENT_UNDERGRAD","STUDENT_GRADUATE","RESEARCHER","PROFESSOR","STAFF","OTHER"]},"IdentityProvider":{"type":"string","enum":["GOOGLE"]},"LinkedIdentity":{"type":"object","properties":{"provider":{"$ref":"#/components/schemas/IdentityProvider"},"email":{"type":"string"},"linkedAt":{"type":"string","format":"date-time"}},"required":["email","linkedAt","provider"]},"ManagedOrgResponse":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","description":"기관 ID"},"orgName":{"type":"string","description":"기관 이름"},"role":{"$ref":"#/components/schemas/UserRole","description":"이 기관에서의 역할"}},"required":["orgId","orgName","role"]},"Membership":{"type":"object","properties":{"workspaceId":{"type":"string","format":"uuid"},"workspaceName":{"type":"string"},"workspaceKind":{"$ref":"#/components/schemas/WorkspaceKind"},"role":{"$ref":"#/components/schemas/WorkspaceMemberRole"}},"required":["role","workspaceId","workspaceKind","workspaceName"]},"TermsDocType":{"type":"string","enum":["TERMS_OF_SERVICE","PRIVACY_POLICY"]},"TermsVersionView":{"type":"object","properties":{"docType":{"$ref":"#/components/schemas/TermsDocType"},"version":{"type":"integer","format":"int32"},"title":{"type":"string"},"effectiveAt":{"type":"string","format":"date-time"}},"required":["docType","effectiveAt","title","version"]},"UserProfileResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"name":{"type":"string"},"role":{"$ref":"#/components/schemas/UserRole"},"managedOrgs":{"type":"array","items":{"$ref":"#/components/schemas/ManagedOrgResponse"}},"status":{"$ref":"#/components/schemas/UserStatus"},"memberships":{"type":"array","items":{"$ref":"#/components/schemas/Membership"}},"mfaEnabled":{"type":"boolean"},"pendingConsents":{"type":"array","items":{"$ref":"#/components/schemas/TermsVersionView"}},"position":{"anyOf":[{"$ref":"#/components/schemas/UserPosition"},{"type":"null"}]},"studentNo":{"type":["string","null"]},"departmentCode":{"type":["string","null"]},"departmentName":{"type":["string","null"]},"departmentOther":{"type":["string","null"]},"profileComplete":{"type":"boolean"},"hasPassword":{"type":"boolean"},"identities":{"type":"array","items":{"$ref":"#/components/schemas/LinkedIdentity"}}},"required":["email","hasPassword","id","identities","managedOrgs","memberships","mfaEnabled","name","pendingConsents","profileComplete","role","status"]},"UserRole":{"type":"string","enum":["USER","ORG_VIEWER","ORG_MANAGER","ORG_ADMIN","SYS_VIEWER","SYS_MANAGER","SYS_ADMIN"]},"UserStatus":{"type":"string","enum":["PENDING_VERIFICATION","ACTIVE","DISABLED","WITHDRAWN"]},"WorkspaceKind":{"type":"string","enum":["PERSONAL","TEAM","PROJECT","COURSE","PROGRAM","LAB","CLUB","COMPETITION","STUDY"]},"WorkspaceMemberRole":{"type":"string","enum":["OWNER","MEMBER"]},"ChangePasswordRequest":{"type":"object","properties":{"currentPassword":{"type":"string","minLength":1},"newPassword":{"type":"string","maxLength":72,"minLength":8}},"required":["currentPassword","newPassword"]},"AuthTokenResponse":{"type":"object","properties":{"accessToken":{"type":"string"},"user":{"$ref":"#/components/schemas/UserSummaryResponse"}},"required":["accessToken","user"]},"UserSummaryResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"name":{"type":"string"},"role":{"$ref":"#/components/schemas/UserRole"}},"required":["email","id","name","role"]},"DesiredRecordSet":{"type":"object","properties":{"name":{"type":"string","description":"도메인 이름 기준 상대 이름. 빈 문자열은 도메인 이름 자신입니다.","example":"www"},"type":{"$ref":"#/components/schemas/DnsRecordType","description":"레코드 종류."},"values":{"type":"array","description":"이 세트의 값 전체. 순서가 의미를 갖는 종류가 있어 그대로 보존됩니다.","items":{"type":"string"}},"ttl":{"type":"integer","format":"int32","description":"TTL(초). 60에서 86400 사이입니다.","example":300}},"required":["name","type","values"]},"DnsRecordType":{"type":"string","enum":["A","AAAA","CNAME","TXT"]},"ReplaceDnsRecordSetsRequest":{"type":"object","properties":{"records":{"type":"array","description":"이 이름이 가져야 할 레코드 세트 전체. 빈 목록은 전부 삭제입니다.","items":{"$ref":"#/components/schemas/DesiredRecordSet"}}},"required":["records"]},"DnsRecordSetView":{"type":"object","properties":{"name":{"type":"string"},"type":{"$ref":"#/components/schemas/DnsRecordType"},"values":{"type":"array","items":{"type":"string"}},"ttl":{"type":"integer","format":"int32"},"status":{"$ref":"#/components/schemas/DomainRecordStatus"},"lastError":{"type":["string","null"]},"appliedAt":{"type":["string","null"],"format":"date-time"}},"required":["name","status","ttl","type","values"]},"DomainRecordStatus":{"type":"string","enum":["PENDING","APPLIED","FAILED","REMOVED"]},"GrantOrgRoleRequest":{"type":"object","properties":{"role":{"$ref":"#/components/schemas/UserRole","description":"이 기관에서 부여할 역할 (ORG_ADMIN, ORG_MANAGER, ORG_VIEWER)"}},"required":["role"]},"SettingUpdateRequest":{"type":"object","properties":{"value":{}},"required":["value"]},"SettingValueType":{"type":"string","enum":["BOOLEAN","INTEGER","NUMBER","STRING","JSON"]},"SettingView":{"type":"object","properties":{"key":{"type":"string"},"value":{},"valueType":{"$ref":"#/components/schemas/SettingValueType"},"description":{"type":"string"},"editable":{"type":"boolean"},"updatedAt":{"type":"string","format":"date-time"}},"required":["description","editable","key","updatedAt","value","valueType"]},"AdminLlmKeyLimitsRequest":{"type":"object","properties":{"rpm":{"type":["integer","null"],"format":"int32","description":"분당 요청 한도. null이면 서비스 기본값을 따릅니다.","maximum":10000,"minimum":1},"tpm":{"type":["integer","null"],"format":"int32","description":"분당 토큰 한도. null이면 서비스 기본값을 따릅니다.","minimum":1},"concurrency":{"type":["integer","null"],"format":"int32","description":"동시 요청 한도. null이면 서비스 기본값을 따릅니다.","maximum":100,"minimum":1},"dailyTokens":{"type":["integer","null"],"format":"int64","description":"일일 토큰 한도. null이면 무제한이고 0이면 토큰 축을 닫습니다.","minimum":0},"creditLimit":{"type":"number","description":"금액 한도(USD 크레딧). 0이면 유료 모델을 닫습니다.","minimum":0},"creditLimitReset":{"anyOf":[{"$ref":"#/components/schemas/CreditLimitReset"},{"type":"null"}],"description":"금액 한도 리셋 창. null이면 리셋 없는 총액 상한입니다."},"creditAllowedModels":{"type":["array","null"],"description":"유료 모델 허용 목록. 빈 배열이나 null이면 제한이 없습니다. 금액 한도와 달리 null이 0을 뜻하지 않습니다. 자체 서빙 모델은 이 값에 영향을 받지 않습니다. 항목은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 공급자 *는 ~별칭도 포함하고, 특정 공급자의 허용은 ~별칭을 별도로 적어야 합니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"},"maxItems":50,"minItems":0},"creditDeniedModels":{"type":["array","null"],"description":"유료 모델 차단 목록. 빈 배열이나 null이면 차단하는 모델이 없습니다. 허용 목록과 함께 걸리면 차단이 이깁니다. 허용 목록과 달리 금액 한도가 0이어도 남습니다. 자체 서빙 모델은 이 값에 영향을 받지 않습니다. 항목은 허용 목록과 같은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 차단은 ~를 제거한 이름도 검사하며, 별칭의 실제 대상 모델은 추적하지 않습니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"},"maxItems":50,"minItems":0},"passthroughEndpoints":{"type":["array","null"],"description":"이 키에 부여할 기능 권한. 빈 배열이나 null이면 기능을 하나도 쓸 수 없습니다. 모델 목록 둘과 반대로 이 목록은 채워야 열립니다. 채팅과 모델 조회는 이 값에 영향을 받지 않습니다.","items":{"type":"string","enum":["images","embeddings"]},"maxItems":20,"minItems":0},"openrouterAccountId":{"type":["string","null"],"format":"uuid","description":"유료 모델을 결제할 사업 계정. 생략하거나 null이면 기존 연결을 유지합니다."}},"required":["concurrency","creditAllowedModels","creditDeniedModels","creditLimit","creditLimitReset","dailyTokens","passthroughEndpoints","rpm","tpm"]},"CreditLimitReset":{"type":"string","enum":["DAILY","WEEKLY","MONTHLY"]},"AdminLlmKeyDetailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"purpose":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/LlmApiKeyStatus"},"expiresAt":{"type":["string","null"],"format":"date-time"},"lastUsedAt":{"type":["string","null"],"format":"date-time"},"rpm":{"type":["integer","null"],"format":"int32"},"tpm":{"type":["integer","null"],"format":"int32"},"concurrency":{"type":["integer","null"],"format":"int32"},"dailyTokens":{"type":["integer","null"],"format":"int64"},"quotaExhausted":{"type":"boolean"},"creditLimit":{"type":"number"},"creditLimitReset":{"anyOf":[{"$ref":"#/components/schemas/CreditLimitReset"},{"type":"null"}]},"creditAxisConnected":{"type":"boolean","description":"유료 모델이 발급되어 현재 연결되어 있는지"},"creditUsage":{"type":["number","null"],"description":"OpenRouter가 마지막으로 보고한 현재 limit window 사용액. 미관측이면 null"},"creditUsageAt":{"type":["string","null"],"format":"date-time","description":"Key 금액을 vendor에서 관측한 시각. 미관측이면 null"},"creditLimitRemaining":{"type":["number","null"],"description":"OpenRouter가 보고한 key 잔여 한도. 미관측 또는 무한도면 null"},"openrouterAccountId":{"type":["string","null"],"format":"uuid"},"openrouterAccountName":{"type":["string","null"]},"workspaceId":{"type":["string","null"],"format":"uuid"},"workspaceName":{"type":"string"},"orgId":{"type":["string","null"],"format":"uuid"},"orgName":{"type":"string"},"requestId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"revokedAt":{"type":["string","null"],"format":"date-time"},"creditAllowedModels":{"type":"array","description":"이 키가 쓸 수 있는 유료 모델 목록. 빈 배열은 제한 없음 항목은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 공급자 *는 ~별칭도 포함하고, 특정 공급자의 허용은 ~별칭을 별도로 적어야 합니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"}},"creditDeniedModels":{"type":"array","description":"이 키가 쓸 수 없는 유료 모델 목록. 빈 배열은 차단 없음. 허용 목록과 함께 걸리면 차단이 이긴다. 항목은 허용 목록과 같은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 차단은 ~를 제거한 이름도 검사하며, 별칭의 실제 대상 모델은 추적하지 않습니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"}},"passthroughEndpoints":{"type":"array","description":"이 키에 부여된 기능 권한. 빈 배열은 부여 없음. 모델 목록 둘과 반대로 채워야 열린다.","items":{"type":"string","enum":["images","embeddings"]}}},"required":["createdAt","creditAllowedModels","creditAxisConnected","creditDeniedModels","creditLimit","id","name","orgName","passthroughEndpoints","quotaExhausted","status","workspaceName"]},"LlmApiKeyStatus":{"type":"string","enum":["PENDING","ACTIVE","SUSPENDED","REVOKED","EXPIRED"]},"CreatableWorkspaceKind":{"type":"string","enum":["PROJECT","COURSE","PROGRAM","LAB","CLUB","COMPETITION","STUDY"]},"CreateWorkspaceRequest":{"type":"object","properties":{"kind":{"$ref":"#/components/schemas/CreatableWorkspaceKind","description":"워크스페이스 유형. PERSONAL은 가입 시 자동 생성되고 TEAM은 폐기된 값이라 요청으로 만들 수 없습니다"},"name":{"type":"string","maxLength":100,"minLength":0},"description":{"type":["string","null"],"maxLength":500,"minLength":0}},"required":["kind","name"]},"WorkspaceDetailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"$ref":"#/components/schemas/WorkspaceKind"},"name":{"type":"string"},"description":{"type":["string","null"]},"myRole":{"$ref":"#/components/schemas/WorkspaceMemberRole"},"members":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceMemberResponse"}},"createdAt":{"type":"string","format":"date-time"}},"required":["createdAt","id","kind","members","myRole","name"]},"WorkspaceMemberResponse":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string"},"role":{"$ref":"#/components/schemas/WorkspaceMemberRole"}},"required":["email","name","role","userId"]},"AddWorkspaceMemberRequest":{"type":"object","properties":{"email":{"type":"string","format":"email","minLength":1},"role":{"$ref":"#/components/schemas/WorkspaceMemberRole"}},"required":["email","role"]},"TerminalTicketResponse":{"type":"object","properties":{"sessionId":{"type":"string"},"ticket":{"type":"string"},"wsPath":{"type":"string"},"subprotocol":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}},"required":["expiresAt","sessionId","subprotocol","ticket","wsPath"]},"MessageResponse":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]},"VmSshKeyIssueResponse":{"type":"object","description":"개인키 응답 (Cache-Control: no-store)","properties":{"privateKey":{"type":"string","description":"OpenSSH 형식 개인키 PEM 전문"},"fileName":{"type":"string","description":"저장할 파일 이름","example":"pickle-algo-judge.pem"},"key":{"$ref":"#/components/schemas/VmSshKeyView","description":"발급된 키의 정보"}},"required":["fileName","key","privateKey"]},"VmSshKeyView":{"type":"object","description":"VM에 발급된 SSH 키 정보 (개인키는 포함하지 않는다)","properties":{"id":{"type":"string","format":"uuid","description":"키 식별자"},"fingerprint":{"type":"string","description":"SHA256 지문 (ssh-keygen -lf 출력과 같은 형식)","example":"SHA256:abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG"},"fileName":{"type":"string","description":"내려받을 개인키 파일 이름","example":"pickle-algo-judge.pem"},"createdAt":{"type":"string","format":"date-time","description":"발급 시각"},"lastUsedAt":{"type":["string","null"],"format":"date-time","description":"이 키로 마지막에 접속한 시각 (없으면 null)"}},"required":["createdAt","fileName","fingerprint","id"]},"CreatePortForwardingRequest":{"type":"object","properties":{"proto":{"$ref":"#/components/schemas/PortMappingProto","description":"프로토콜 (tcp | udp)"},"targetPort":{"type":"integer","format":"int32","description":"VM 내부에서 노출할 대상 포트 (1~65535)","maximum":65535,"minimum":1}},"required":["proto","targetPort"]},"PortMappingProto":{"type":"string","enum":["TCP","UDP"]},"PortForwardApplyState":{"type":"string","enum":["PENDING","ACTIVE","FAILED"]},"PortForwardingView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"proto":{"$ref":"#/components/schemas/PortMappingProto","description":"프로토콜 (tcp | udp)"},"publicPort":{"type":"integer","format":"int32","description":"릴레이에서 열린 공개 포트"},"publicHost":{"type":["string","null"],"description":"접속에 사용할 공개 호스트. 아직 설정 전이면 null"},"targetPort":{"type":"integer","format":"int32","description":"VM 내부 대상 포트"},"status":{"$ref":"#/components/schemas/PortMappingStatus","description":"매핑 상태 (SUSPENDED = 관리자·자동 정지)"},"applyState":{"$ref":"#/components/schemas/PortForwardApplyState","description":"릴레이 반영 상태 (PENDING = 대기, ACTIVE = 활성, FAILED = 실패)"},"createdAt":{"type":"string","format":"date-time"}},"required":["applyState","createdAt","id","proto","publicPort","status","targetPort"]},"PortMappingStatus":{"type":"string","enum":["ACTIVE","SUSPENDED"]},"VmPasswordResponse":{"type":"object","properties":{"password":{"type":"string"},"sshUsername":{"type":"string"},"sshHost":{"type":"string"},"sshPort":{"type":"integer","format":"int32"}},"required":["password","sshHost","sshPort","sshUsername"]},"CreateVmDomainRequest":{"type":"object","properties":{"port":{"type":"integer","format":"int32"},"subdomain":{"type":["string","null"]},"rootDomain":{"type":["string","null"]},"customDomain":{"type":["string","null"]}}},"CertificateKind":{"type":"string","enum":["ORIGIN_CA_WILDCARD","LETS_ENCRYPT"]},"CertificateStatus":{"type":"string","enum":["ACTIVE","RENEWING","FAILED","REVOKED"]},"CertificateView":{"type":"object","properties":{"kind":{"$ref":"#/components/schemas/CertificateKind"},"status":{"$ref":"#/components/schemas/CertificateStatus"},"notAfter":{"type":["string","null"],"format":"date-time"},"lastError":{"type":["string","null"]}},"required":["kind","status"]},"DomainDetailView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"vmId":{"type":"string","format":"uuid"},"kind":{"$ref":"#/components/schemas/DomainKind"},"fqdn":{"type":"string"},"rootDomain":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/DomainStatus"},"verifiedAt":{"type":["string","null"],"format":"date-time"},"releasedAt":{"type":["string","null"],"format":"date-time"},"reservedUntil":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"dnsStatus":{"$ref":"#/components/schemas/DomainDnsStatus"},"dnsLastError":{"type":["string","null"]},"dnsAppliedAt":{"type":["string","null"],"format":"date-time"},"verification":{"anyOf":[{"$ref":"#/components/schemas/DomainVerificationView"},{"type":"null"}]}},"required":["createdAt","dnsStatus","fqdn","id","kind","status","vmId"]},"DomainDnsStatus":{"type":"string","enum":["NONE","PENDING","APPLIED","FAILED"]},"DomainKind":{"type":"string","enum":["AUTO","PLATFORM","CUSTOM","EXTERNAL"]},"DomainStatus":{"type":"string","enum":["PENDING","VERIFYING","ACTIVE","FAILED","REMOVED"]},"DomainVerificationView":{"type":"object","properties":{"token":{"type":"string"},"requiredRecords":{"type":"array","items":{"$ref":"#/components/schemas/RequiredRecord"}},"aVerified":{"type":"boolean"},"txtVerified":{"type":"boolean"},"lastCheckedAt":{"type":["string","null"],"format":"date-time"},"lastError":{"type":["string","null"]}},"required":["aVerified","requiredRecords","token","txtVerified"]},"PublicationView":{"type":"object","properties":{"fqdn":{"type":"string"},"domain":{"$ref":"#/components/schemas/DomainDetailView"},"route":{"anyOf":[{"$ref":"#/components/schemas/RouteView"},{"type":"null"}]},"certificate":{"anyOf":[{"$ref":"#/components/schemas/CertificateView"},{"type":"null"}]}},"required":["domain","fqdn"]},"RequiredRecord":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"}},"required":["name","type","value"]},"RouteStatus":{"type":"string","enum":["PENDING","APPLIED","FAILED","REMOVED"]},"RouteView":{"type":"object","properties":{"targetPort":{"type":"integer","format":"int32"},"protocol":{"type":"string"},"status":{"$ref":"#/components/schemas/RouteStatus"},"appliedAt":{"type":["string","null"],"format":"date-time"},"lastError":{"type":["string","null"]}},"required":["protocol","status","targetPort"]},"CreateCampusIpRequest":{"type":"object","properties":{"purpose":{"type":"string","description":"신청 목적 (관리자 검토 자료)","maxLength":1000,"minLength":0},"ports":{"type":"array","description":"교내 IP로 사용할 포트 번호 목록 (1~65535, 최대 32개)","items":{"type":"integer","format":"int32"},"maxItems":32,"minItems":0}},"required":["ports","purpose"]},"CampusIpRequestStatus":{"type":"string","enum":["REQUESTED","APPROVED","GRANTED","REJECTED","REVOKED"]},"CampusIpRequestView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"vmId":{"type":"string","format":"uuid"},"purpose":{"type":"string","description":"신청 목적"},"ports":{"type":"array","description":"사용할 포트 번호 목록 (중복 제거·오름차순 정규화)","items":{"type":"integer","format":"int32"}},"status":{"$ref":"#/components/schemas/CampusIpRequestStatus","description":"신청 상태 (REQUESTED = 신청, APPROVED = 관리자 승인, GRANTED = 교내 IP 연결 완료, REJECTED = 반려, REVOKED = 회수)"},"grantedAddress":{"type":["string","null"],"description":"연결된 교내 IP 주소 (GRANTED 이후)"},"adminNote":{"type":["string","null"],"description":"관리자 메모"},"requestedBy":{"type":"string","format":"uuid"},"processedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["createdAt","id","ports","purpose","requestedBy","status","vmId"]},"AccessGranteeType":{"type":"string","enum":["USER","WORKSPACE"]},"AddResourceAccessGrantRequest":{"type":"object","properties":{"granteeType":{"$ref":"#/components/schemas/AccessGranteeType","description":"USER는 지정된 사용자 한 명, WORKSPACE은 소유 워크스페이스 전체"},"userId":{"type":["string","null"],"format":"uuid","description":"대상 사용자 id. granteeType이 USER일 때만 보내며, 소유 워크스페이스의 구성원이어야 합니다."},"role":{"$ref":"#/components/schemas/ResourceRole","description":"부여할 등급. 워크스페이스 전체 항목에는 MEMBER 또는 VIEWER만 지정할 수 있습니다."}},"required":["granteeType","role"]},"ResourceRole":{"type":"string","enum":["OWNER","EDITOR","MEMBER","VIEWER"]},"Grantee":{"type":"object","description":"접근 권한을 가진 사용자","properties":{"userId":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string"}},"required":["email","name","userId"]},"ResourceAccessGrantView":{"type":"object","description":"VM 접근 권한 한 건. 대상은 지정된 사용자 한 명이거나 소유 워크스페이스 전체입니다.","properties":{"id":{"type":"string","format":"uuid"},"granteeType":{"$ref":"#/components/schemas/AccessGranteeType","description":"대상 종류 — USER는 지정된 사용자, WORKSPACE은 소유 워크스페이스 전체"},"user":{"anyOf":[{"$ref":"#/components/schemas/Grantee"},{"type":"null"}],"description":"대상 사용자. 워크스페이스 전체 항목이면 null입니다."},"role":{"$ref":"#/components/schemas/ResourceRole","description":"이 대상이 이 VM에서 갖는 등급"},"createdAt":{"type":"string","format":"date-time"}},"required":["createdAt","granteeType","id","role"]},"CreateDomainRequestSpec":{"type":"object","properties":{"label":{"type":"string","description":"루트 도메인 바로 아래 한 라벨. 영문 소문자와 숫자, 하이픈만 쓸 수 있습니다.","example":"myblog","minLength":1},"rootDomain":{"type":"string","description":"이름을 발급받을 루트 도메인. 이 이름이 속할 기관이 여기서 정해집니다.","example":"pusan.dev","minLength":1}},"required":["label","rootDomain"]},"CreateGpuRequestSpec":{"type":"object","properties":{"vmId":{"type":["string","null"],"format":"uuid"},"leaseHours":{"type":"integer","format":"int32","description":"직접 입력한 양의 정수 시간입니다. 1.5처럼 정수가 아닌 값이나 문자열은 허용하지 않습니다.","minimum":1}},"required":["leaseHours"]},"CreateLlmKeyRequestSpec":{"type":"object","properties":{"useCampusModels":{"type":["boolean","null"],"description":"자체 서빙 모델을 쓸지. 비우면 사용으로 봅니다."},"useCommercialModels":{"type":["boolean","null"],"description":"유료 모델을 쓸지. 비우면 사용하지 않는 것으로 봅니다."},"reqCreditLimit":{"type":["number","null"],"description":"희망 금액 한도(USD). 유료 모델을 쓸 때만 적습니다.","example":20.0,"maximum":100000.00,"minimum":0.01},"reqRpm":{"type":["integer","null"],"format":"int32","description":"희망 분당 요청 수. 비우면 서비스 기본값을 받습니다.","maximum":10000,"minimum":1},"reqTpm":{"type":["integer","null"],"format":"int32","description":"희망 분당 토큰 수. 비우면 서비스 기본값을 받습니다.","minimum":1},"reqDailyTokens":{"type":["integer","null"],"format":"int64","description":"희망 일일 토큰 수. 비우면 서비스 기본값을 받습니다.","minimum":1}}},"CreateRequestRequest":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/ResourceType"},"workspaceId":{"type":"string","format":"uuid"},"orgId":{"type":["string","null"],"format":"uuid","description":"신청할 기관. 리소스 종류가 기관을 스스로 정하지 않을 때만 필수입니다. 외부 도메인은 고른 루트 도메인이 기관을 정하므로 보내지 않습니다."},"purpose":{"type":"string","maxLength":2000,"minLength":0},"extraNote":{"type":["string","null"],"maxLength":2000,"minLength":0},"periodPresetId":{"type":["string","null"],"format":"uuid"},"reqEndDate":{"type":["string","null"],"format":"date"},"reqIndefinite":{"type":["boolean","null"],"description":"true면 종료일 없이 신청합니다. reqEndDate·periodPresetId와 함께 보낼 수 없습니다."},"displayName":{"type":"string","maxLength":100,"minLength":0},"vm":{"anyOf":[{"$ref":"#/components/schemas/CreateVmRequestSpec"},{"type":"null"}]},"llmKey":{"anyOf":[{"$ref":"#/components/schemas/CreateLlmKeyRequestSpec"},{"type":"null"}]},"gpu":{"anyOf":[{"$ref":"#/components/schemas/CreateGpuRequestSpec"},{"type":"null"}]},"domain":{"anyOf":[{"$ref":"#/components/schemas/CreateDomainRequestSpec"},{"type":"null"}]}},"required":["displayName","purpose","type","workspaceId"]},"CreateVmRequestSpec":{"type":"object","properties":{"imageId":{"type":"string","format":"uuid"},"flavorId":{"type":["string","null"],"format":"uuid"},"reqVcpu":{"type":"integer","format":"int32","minimum":1},"reqMemoryMb":{"type":"integer","format":"int32","minimum":256},"reqDiskGb":{"type":"integer","format":"int32","minimum":1},"specReason":{"type":["string","null"],"maxLength":2000,"minLength":0},"desiredSlug":{"type":["string","null"],"pattern":"^\\s*$|^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$"}},"required":["imageId","reqDiskGb","reqMemoryMb","reqVcpu"]},"ResourceType":{"type":"string","enum":["VM","LLM_API_KEY","DOMAIN","GPU"]},"DomainRequestSpecResponse":{"type":"object","properties":{"label":{"type":"string","description":"신청한 이름(루트 바로 아래 한 라벨)","example":"myblog"},"rootDomain":{"type":"string","description":"신청한 루트 도메인","example":"pusan.dev"},"grantedFqdn":{"type":["string","null"],"description":"승인이 실제로 발급한 이름. 승인 전에는 null입니다.","example":"myblog.pusan.dev"}},"required":["label","rootDomain"]},"GpuRequestSpecResponse":{"type":"object","properties":{"vmId":{"type":["string","null"],"format":"uuid"},"vmName":{"type":["string","null"]},"leaseHours":{"type":"integer","format":"int32"},"grantedLeaseHours":{"type":["integer","null"],"format":"int32"},"grantedGpuId":{"type":["string","null"],"format":"uuid"},"grantedPriority":{"type":["integer","null"],"format":"int32"}},"required":["leaseHours"]},"LlmKeyRequestSpecResponse":{"type":"object","properties":{"reqRpm":{"type":["integer","null"],"format":"int32","description":"희망 분당 요청 수"},"reqTpm":{"type":["integer","null"],"format":"int32","description":"희망 분당 토큰 수"},"reqDailyTokens":{"type":["integer","null"],"format":"int64","description":"희망 일일 토큰 수"},"useCampusModels":{"type":"boolean","description":"신청자가 자체 서빙 모델을 쓰겠다고 했는지."},"useCommercialModels":{"type":"boolean","description":"신청자가 유료 모델을 쓰겠다고 했는지."},"reqCreditLimit":{"type":["number","null"],"description":"신청자가 요청한 금액 한도(USD). 유료를 쓰지 않는 신청은 비어 있습니다."},"grantedRpm":{"type":["integer","null"],"format":"int32","description":"부여 분당 요청 수. 비어 있으면 서비스 기본값입니다."},"grantedTpm":{"type":["integer","null"],"format":"int32","description":"부여 분당 토큰 수. 비어 있으면 서비스 기본값입니다."},"grantedConcurrency":{"type":["integer","null"],"format":"int32","description":"부여 동시 요청 수. 비어 있으면 서비스 기본값입니다."},"grantedDailyTokens":{"type":["integer","null"],"format":"int64","description":"부여 일일 토큰 수. 비어 있으면 일일 한도가 없습니다. 0이면 자체 서빙(토큰) 축을 쓸 수 없습니다."},"grantedCreditLimit":{"type":["number","null"],"description":"부여 금액 한도(USD 크레딧). 비어 있거나 0이면 유료 모델을 쓸 수 없습니다."},"grantedCreditLimitReset":{"anyOf":[{"$ref":"#/components/schemas/CreditLimitReset"},{"type":"null"}],"description":"금액 한도 리셋 창. 비어 있으면 리셋 없는 총액 상한입니다."},"grantedCreditAllowedModels":{"type":"array","description":"부여된 유료 모델 허용 목록. 빈 배열이면 제한이 없습니다. 어떤 모델을 열지는 신청자가 요구하는 값이 아니라 승인자가 정하는 값이라 희망 쪽 짝이 없습니다. 항목은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 공급자 *는 ~별칭도 포함하고, 특정 공급자의 허용은 ~별칭을 별도로 적어야 합니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"}},"grantedCreditDeniedModels":{"type":"array","description":"부여된 유료 모델 차단 목록. 빈 배열이면 차단이 없습니다. 허용 목록과 함께 걸리면 차단이 이깁니다. 항목은 허용 목록과 같은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 차단은 ~를 제거한 이름도 검사하며, 별칭의 실제 대상 모델은 추적하지 않습니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"}},"grantedPassthroughEndpoints":{"type":"array","description":"승인자가 부여한 기능 권한. 빈 배열이면 부여된 기능이 없습니다.","items":{"type":"string","enum":["images","embeddings"]}}},"required":["grantedCreditAllowedModels","grantedCreditDeniedModels","grantedPassthroughEndpoints","useCampusModels","useCommercialModels"]},"RequestDetailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"$ref":"#/components/schemas/ResourceType"},"workspaceId":{"type":["string","null"],"format":"uuid","description":"신청 대상 워크스페이스. 행이 사라진 경우에만 null입니다."},"workspaceName":{"type":"string"},"orgId":{"type":["string","null"],"format":"uuid","description":"신청 대상 기관. 행이 사라진 경우에만 null입니다."},"orgName":{"type":"string"},"requesterId":{"type":["string","null"],"format":"uuid","description":"신청자. 행이 사라진 경우에만 null입니다."},"requesterName":{"type":"string"},"purpose":{"type":"string"},"extraNote":{"type":["string","null"]},"reqEndDate":{"type":["string","null"],"format":"date","description":"신청한 사용 종료일. 값이 없으면 무기한을 요청한 것입니다."},"periodName":{"type":["string","null"],"description":"종료일을 고른 기간 항목의 이름. 직접 적었으면 null입니다.","example":"2026학년도 1학기"},"displayName":{"type":"string"},"status":{"$ref":"#/components/schemas/RequestStatus"},"review":{"anyOf":[{"$ref":"#/components/schemas/RequestReviewResponse"},{"type":"null"}]},"vm":{"anyOf":[{"$ref":"#/components/schemas/VmRequestSpecResponse"},{"type":"null"}]},"llmKey":{"anyOf":[{"$ref":"#/components/schemas/LlmKeyRequestSpecResponse"},{"type":"null"}]},"gpu":{"anyOf":[{"$ref":"#/components/schemas/GpuRequestSpecResponse"},{"type":"null"}]},"domain":{"anyOf":[{"$ref":"#/components/schemas/DomainRequestSpecResponse"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["createdAt","displayName","id","orgName","purpose","requesterName","status","type","updatedAt","workspaceName"]},"RequestReviewResponse":{"type":"object","properties":{"reviewerId":{"type":["string","null"],"format":"uuid","description":"결재한 사람. 자동 승인이거나 계정 행이 사라진 경우 null입니다."},"reviewerName":{"type":"string","description":"결재자 이름. 자동 승인이면 「자동 승인」, 계정 행이 사라졌으면 「탈퇴 회원」입니다. 두 경우 모두 reviewerId가 null이므로 이 값으로 가릅니다."},"decision":{"$ref":"#/components/schemas/ReviewDecision"},"comment":{"type":["string","null"]},"grantedStartDate":{"type":["string","null"],"format":"date"},"grantedEndDate":{"type":["string","null"],"format":"date"},"decidedAt":{"type":"string","format":"date-time"}},"required":["decidedAt","decision","reviewerName"]},"RequestStatus":{"type":"string","enum":["SUBMITTED","APPROVED","REJECTED","CANCELED"]},"ReviewDecision":{"type":"string","enum":["APPROVE","REJECT"]},"VmGrantedSpecResponse":{"type":"object","properties":{"grantedVcpu":{"type":"integer","format":"int32"},"grantedMemoryMb":{"type":"integer","format":"int32"},"grantedDiskGb":{"type":"integer","format":"int32"},"grantedImageId":{"type":"string","format":"uuid"},"grantedImageName":{"type":"string","description":"승인된 OS 이미지의 표시 이름. 카탈로그에서 내려간 이미지도 이름이 남습니다."},"nodeId":{"type":["string","null"],"format":"uuid"},"nodeName":{"type":["string","null"],"description":"배치된 노드의 이름. nodeId가 있을 때 함께 있습니다."}},"required":["grantedDiskGb","grantedImageId","grantedImageName","grantedMemoryMb","grantedVcpu"]},"VmRequestSpecResponse":{"type":"object","properties":{"imageId":{"type":"string","format":"uuid"},"imageName":{"type":"string","description":"요청한 OS 이미지의 표시 이름. 카탈로그에서 내려간 이미지도 이름이 남습니다."},"flavorId":{"type":["string","null"],"format":"uuid"},"flavorName":{"type":["string","null"],"description":"요청한 사양 프리셋의 표시 이름. flavorId가 있을 때 함께 있습니다."},"reqVcpu":{"type":"integer","format":"int32"},"reqMemoryMb":{"type":"integer","format":"int32"},"reqDiskGb":{"type":"integer","format":"int32"},"specReason":{"type":["string","null"]},"desiredSlug":{"type":["string","null"]},"granted":{"anyOf":[{"$ref":"#/components/schemas/VmGrantedSpecResponse"},{"type":"null"}]}},"required":["imageId","imageName","reqDiskGb","reqMemoryMb","reqVcpu"]},"NotificationImportance":{"type":"string","enum":["NORMAL","HIGH"]},"NotificationView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"event":{"type":"string"},"title":{"type":"string"},"body":{"type":"string"},"linkPath":{"type":["string","null"]},"importance":{"$ref":"#/components/schemas/NotificationImportance"},"createdAt":{"type":"string","format":"date-time"},"readAt":{"type":["string","null"],"format":"date-time"}},"required":["body","createdAt","event","id","importance","title"]},"ReadAllResponse":{"type":"object","properties":{"updatedCount":{"type":"integer","format":"int32"}},"required":["updatedCount"]},"WithdrawRequest":{"type":"object","properties":{"password":{"type":"string","minLength":1},"totpCode":{"type":"string","pattern":"^[0-9]{6}$"},"recoveryCode":{"type":"string"}},"required":["password"]},"SetPasswordRequest":{"type":"object","properties":{"newPassword":{"type":"string","maxLength":72,"minLength":8}},"required":["newPassword"]},"BeginMfaRequest":{"type":"object","properties":{"password":{"type":"string","minLength":1}},"required":["password"]},"MfaSetupResponse":{"type":"object","properties":{"secret":{"type":"string"},"otpauthUri":{"type":"string"}},"required":["otpauthUri","secret"]},"ActivateMfaRequest":{"type":"object","properties":{"code":{"type":"string","minLength":1,"pattern":"^[0-9]{6}$"}},"required":["code"]},"MfaRecoveryCodesResponse":{"type":"object","properties":{"recoveryCodes":{"type":"array","items":{"type":"string"}}},"required":["recoveryCodes"]},"RegenerateRecoveryCodesRequest":{"type":"object","properties":{"password":{"type":"string","minLength":1},"code":{"type":"string","minLength":1,"pattern":"^[0-9]{6}$"}},"required":["code","password"]},"DisableMfaRequest":{"type":"object","properties":{"password":{"type":"string","minLength":1},"code":{"type":"string","pattern":"^[0-9]{6}$"},"recoveryCode":{"type":"string"}},"required":["password"]},"ConsentInput":{"type":"object","properties":{"docType":{"$ref":"#/components/schemas/TermsDocType"},"version":{"type":"integer","format":"int32"}},"required":["docType","version"]},"ConsentUpdateRequest":{"type":"object","properties":{"consents":{"type":"array","items":{"$ref":"#/components/schemas/ConsentInput"},"minItems":1}},"required":["consents"]},"ConsentView":{"type":"object","properties":{"docType":{"$ref":"#/components/schemas/TermsDocType"},"version":{"type":"integer","format":"int32"},"consentedAt":{"type":"string","format":"date-time"}},"required":["consentedAt","docType","version"]},"IssuedLlmKeyResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"키 식별자"},"name":{"type":"string","description":"키 이름"},"token":{"type":"string","description":"발급된 API Key 평문. **이 응답에서만 볼 수 있습니다** — 서버에는 해시만 저장되며 다시 조회할 수 없습니다. 분실하면 재발급해야 합니다."},"expiresAt":{"type":["string","null"],"format":"date-time","description":"만료 시각. 없으면 만료되지 않습니다."}},"required":["id","name","token"]},"ConfirmGpuActionRequest":{"type":"object","properties":{"confirmed":{"type":"boolean"}},"required":["confirmed"]},"GpuAllocationStatus":{"type":"string","enum":["QUEUED","ALLOCATED","RELEASING","RELEASED","CANCELED"]},"GpuAllocationView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"$ref":"#/components/schemas/GpuAllocationStatus"},"connectionStatus":{"$ref":"#/components/schemas/GpuConnectionStatus"},"workspaceId":{"type":"string","format":"uuid"},"workspaceName":{"type":"string"},"orgId":{"type":["string","null"],"format":"uuid"},"orgName":{"type":["string","null"]},"accessLimited":{"type":"boolean"},"ownerNames":{"type":"array","items":{"type":"string"}},"accessManageAllowed":{"type":"boolean"},"myRole":{"anyOf":[{"$ref":"#/components/schemas/ResourceRole"},{"type":"null"}]},"gpu":{"anyOf":[{"$ref":"#/components/schemas/GpuView"},{"type":"null"}]},"vmId":{"type":["string","null"],"format":"uuid"},"vmName":{"type":["string","null"]},"grantedLeaseHours":{"type":["integer","null"],"format":"int32"},"allocatedAt":{"type":["string","null"],"format":"date-time"},"leaseEndsAt":{"type":["string","null"],"format":"date-time"},"unattachedSince":{"type":["string","null"],"format":"date-time"},"queuePosition":{"type":["integer","null"],"format":"int64"},"priority":{"type":["integer","null"],"format":"int32"},"utilizationPercent":{"type":["number","null"],"format":"double"},"sampleObservedAt":{"type":["string","null"],"format":"date-time"},"releaseReason":{"anyOf":[{"$ref":"#/components/schemas/GpuReleaseReason"},{"type":"null"}]},"error":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["accessLimited","accessManageAllowed","connectionStatus","createdAt","id","name","ownerNames","status","updatedAt","workspaceId","workspaceName"]},"GpuConnectionStatus":{"type":"string","enum":["NONE","ATTACHING","ATTACHED","DETACHING","ERROR"]},"GpuReleaseReason":{"type":"string","enum":["USER_RELEASE","LEASE_EXPIRED","ADMIN_RECLAIM","GRANT_ENDED"]},"GpuStatus":{"type":"string","enum":["ACTIVE","MAINTENANCE","RETIRED"]},"GpuView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"nodeId":{"type":"string","format":"uuid"},"model":{"type":"string"},"vramMb":{"type":"integer","format":"int32"},"status":{"$ref":"#/components/schemas/GpuStatus"},"available":{"type":"boolean"}},"required":["available","id","model","nodeId","status","vramMb"]},"ExtendGpuLeaseRequest":{"type":"object","properties":{"hours":{"type":"integer","format":"int32","description":"추가할 양의 정수 시간입니다. 1.5처럼 정수가 아닌 값이나 문자열은 허용하지 않습니다.","minimum":1},"reason":{"type":["string","null"],"maxLength":2000,"minLength":0}},"required":["hours"]},"AttachGpuRequest":{"type":"object","properties":{"vmId":{"type":"string","format":"uuid"},"confirmed":{"type":"boolean"}},"required":["confirmed","vmId"]},"DnsDomainView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fqdn":{"type":"string"},"rootDomain":{"type":"string"},"status":{"$ref":"#/components/schemas/DomainStatus"},"renewDueAt":{"type":"string","format":"date-time"},"releasedAt":{"type":["string","null"],"format":"date-time"},"reservedUntil":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"workspaceId":{"type":"string","format":"uuid"},"workspaceName":{"type":"string"},"accessLimited":{"type":"boolean"},"accessManageAllowed":{"type":"boolean"},"myResourceRole":{"anyOf":[{"$ref":"#/components/schemas/ResourceRole"},{"type":"null"}],"description":"요청자가 이 도메인의 접근 목록에서 받은 등급. 부여가 없으면 null이고, 그런 행은 목록에만 나타납니다. 상세는 부여가 있어야 열리므로 언제나 값이 있습니다."},"ownerNames":{"type":"array","items":{"type":"string"}},"recordSetCount":{"type":"integer","format":"int32"}},"required":["accessLimited","accessManageAllowed","createdAt","fqdn","id","ownerNames","recordSetCount","renewDueAt","rootDomain","status","workspaceId","workspaceName"]},"VerifyEmailRequest":{"type":"object","properties":{"token":{"type":"string","minLength":1}},"required":["token"]},"SignupRequest":{"type":"object","properties":{"email":{"type":"string","minLength":1,"pattern":"^[A-Za-z0-9._%+-]+@(pusan\\.ac\\.kr|pnuops\\.com)$"},"password":{"type":"string","maxLength":72,"minLength":8},"name":{"type":"string","maxLength":50,"minLength":0},"position":{"anyOf":[{"$ref":"#/components/schemas/UserPosition"},{"type":"null"}]},"studentNo":{"type":["string","null"],"maxLength":20,"minLength":0},"departmentCode":{"type":["string","null"],"maxLength":32,"minLength":0},"departmentOther":{"type":["string","null"],"maxLength":100,"minLength":0},"consents":{"type":"array","items":{"$ref":"#/components/schemas/ConsentInput"},"minItems":1}},"required":["consents","email","name","password"]},"ReverifyRequest":{"type":"object","properties":{"password":{"type":"string","minLength":1}},"required":["password"]},"ReverifyResponse":{"type":"object","properties":{"reauthToken":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}},"required":["expiresAt","reauthToken"]},"ResendVerificationRequest":{"type":"object","properties":{"email":{"type":"string","minLength":1,"pattern":"^[A-Za-z0-9._%+-]+@(pusan\\.ac\\.kr|pnuops\\.com)$"}},"required":["email"]},"PasswordResetRequest":{"type":"object","properties":{"email":{"type":"string","minLength":1,"pattern":"^[A-Za-z0-9._%+-]+@(pusan\\.ac\\.kr|pnuops\\.com)$"}},"required":["email"]},"PasswordResetConfirmRequest":{"type":"object","properties":{"token":{"type":"string","minLength":1},"newPassword":{"type":"string","maxLength":72,"minLength":8}},"required":["newPassword","token"]},"OauthPurpose":{"type":"string","enum":["LOGIN","REVERIFY","LINK"]},"OauthStartRequest":{"type":"object","properties":{"purpose":{"anyOf":[{"$ref":"#/components/schemas/OauthPurpose"},{"type":"null"}]},"redirectTo":{"type":["string","null"],"maxLength":512,"minLength":0}}},"OauthStartResponse":{"type":"object","properties":{"authorizationUrl":{"type":"string"},"state":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}},"required":["authorizationUrl","expiresAt","state"]},"OauthCompleteRequest":{"type":"object","properties":{"registrationToken":{"type":"string","maxLength":128,"minLength":0},"name":{"type":"string","maxLength":50,"minLength":0},"position":{"anyOf":[{"$ref":"#/components/schemas/UserPosition"},{"type":"null"}]},"studentNo":{"type":["string","null"],"maxLength":20,"minLength":0},"departmentCode":{"type":["string","null"],"maxLength":32,"minLength":0},"departmentOther":{"type":["string","null"],"maxLength":100,"minLength":0},"consents":{"type":"array","items":{"$ref":"#/components/schemas/ConsentInput"},"minItems":1}},"required":["consents","name","registrationToken"]},"OauthCallbackRequest":{"type":"object","properties":{"code":{"type":"string","maxLength":2048,"minLength":0},"state":{"type":"string","maxLength":128,"minLength":0}},"required":["code","state"]},"MfaChallengeResponse":{"type":"object","properties":{"mfaRequired":{"type":"boolean"},"mfaToken":{"type":"string"}},"required":["mfaRequired","mfaToken"]},"OauthRegistrationResponse":{"type":"object","properties":{"kind":{"type":"string","enum":["REGISTRATION_REQUIRED"]},"registrationToken":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}},"required":["email","expiresAt","kind","name","registrationToken"]},"OauthLinkedResponse":{"type":"object","properties":{"kind":{"type":"string","enum":["LINKED"]}},"required":["kind"]},"MfaLoginRequest":{"type":"object","properties":{"mfaToken":{"type":"string","minLength":1},"code":{"type":"string","pattern":"^[0-9]{6}$"},"recoveryCode":{"type":"string"}},"required":["mfaToken"]},"LoginRequest":{"type":"object","properties":{"email":{"type":"string","minLength":1},"password":{"type":"string","minLength":1}},"required":["email","password"]},"ScheduleVmDeletionRequest":{"type":"object","properties":{"scheduledFor":{"type":"string","format":"date-time"},"reason":{"type":"string","maxLength":2000,"minLength":0}},"required":["reason","scheduledFor"]},"VmDeleteKind":{"type":"string","enum":["SELF","ADMIN","FORCE"]},"VmDeletionResponse":{"type":"object","properties":{"kind":{"$ref":"#/components/schemas/VmDeleteKind"},"scheduledFor":{"type":"string","format":"date-time"},"requestedAt":{"type":"string","format":"date-time"},"requestedById":{"type":["string","null"],"format":"uuid"},"reason":{"type":["string","null"]},"cancelable":{"type":"boolean"}},"required":["cancelable","kind","requestedAt","scheduledFor"]},"ForceDeleteVmRequest":{"type":"object","properties":{"confirmName":{"type":"string","minLength":1},"overrideProtection":{"type":"boolean"}},"required":["confirmName"]},"CreateVmFlavorRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"pattern":"^[a-z0-9][a-z0-9-]{0,38}[a-z0-9]$|^[a-z0-9]$"},"displayName":{"type":"string","maxLength":100,"minLength":0},"vcpu":{"type":"integer","format":"int32","minimum":1},"memoryMb":{"type":"integer","format":"int32","minimum":256},"diskGb":{"type":"integer","format":"int32","minimum":1},"notes":{"type":["string","null"],"maxLength":2000,"minLength":0},"displayOrder":{"type":["integer","null"],"format":"int32"}},"required":["diskGb","displayName","memoryMb","name","vcpu"]},"CatalogStatus":{"type":"string","enum":["ACTIVE","DISABLED"]},"VmFlavorResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"displayName":{"type":"string"},"vcpu":{"type":"integer","format":"int32"},"memoryMb":{"type":"integer","format":"int32"},"diskGb":{"type":"integer","format":"int32"},"status":{"$ref":"#/components/schemas/CatalogStatus"},"notes":{"type":["string","null"]},"displayOrder":{"type":"integer","format":"int32"}},"required":["diskGb","displayName","displayOrder","id","memoryMb","name","status","vcpu"]},"AdminMembershipResponse":{"type":"object","properties":{"workspaceId":{"type":"string","format":"uuid"},"workspaceName":{"type":"string"},"workspaceKind":{"$ref":"#/components/schemas/WorkspaceKind"},"role":{"$ref":"#/components/schemas/WorkspaceMemberRole"},"vmOrgIds":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":["role","vmOrgIds","workspaceId","workspaceKind","workspaceName"]},"UserAdminDetailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"name":{"type":"string"},"role":{"$ref":"#/components/schemas/UserRole"},"managedOrgs":{"type":"array","items":{"$ref":"#/components/schemas/ManagedOrgResponse"}},"status":{"$ref":"#/components/schemas/UserStatus"},"mfaEnabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"withdrawnAt":{"type":["string","null"],"format":"date-time"},"disabledAt":{"type":["string","null"],"format":"date-time"},"disabledReason":{"type":["string","null"]},"memberships":{"type":"array","items":{"$ref":"#/components/schemas/AdminMembershipResponse"}},"activeVmCount":{"type":"integer","format":"int32"},"statusChanges":{"type":"array","items":{"$ref":"#/components/schemas/UserStatusChangeResponse"}},"position":{"anyOf":[{"$ref":"#/components/schemas/UserPosition"},{"type":"null"}]},"studentNo":{"type":["string","null"]},"departmentCode":{"type":["string","null"]},"departmentName":{"type":["string","null"]},"departmentOther":{"type":["string","null"]}},"required":["activeVmCount","createdAt","email","id","managedOrgs","memberships","mfaEnabled","name","role","status","statusChanges"]},"UserStatusChangeResponse":{"type":"object","properties":{"fromStatus":{"$ref":"#/components/schemas/UserStatus"},"toStatus":{"$ref":"#/components/schemas/UserStatus"},"actorId":{"type":["string","null"],"format":"uuid"},"actorEmail":{"type":["string","null"]},"actorName":{"type":["string","null"]},"reason":{"type":["string","null"]},"changedAt":{"type":"string","format":"date-time"}},"required":["changedAt","fromStatus","toStatus"]},"DisableUserRequest":{"type":"object","properties":{"reason":{"type":"string","maxLength":500,"minLength":1}},"required":["reason"]},"RejectRequestRequest":{"type":"object","properties":{"comment":{"type":"string","maxLength":2000,"minLength":0}},"required":["comment"]},"ApproveGpuRequestSpec":{"type":"object","properties":{"leaseHours":{"type":"integer","format":"int32","description":"관리자가 승인하는 양의 정수 시간입니다. 1.5처럼 정수가 아닌 값이나 문자열은 허용하지 않습니다.","minimum":1},"gpuId":{"type":["string","null"],"format":"uuid"},"priority":{"type":["integer","null"],"format":"int32"},"priorityReason":{"type":["string","null"],"maxLength":2000,"minLength":0}},"required":["leaseHours"]},"ApproveLlmKeyRequestSpec":{"type":"object","properties":{"grantedRpm":{"type":["integer","null"],"format":"int32","description":"부여 분당 요청 수. 비우면 서비스 기본값이 적용됩니다.","maximum":10000,"minimum":1},"grantedTpm":{"type":["integer","null"],"format":"int32","description":"부여 분당 토큰 수. 비우면 서비스 기본값이 적용됩니다.","minimum":1},"grantedConcurrency":{"type":["integer","null"],"format":"int32","description":"부여 동시 요청 수. 비우면 서비스 기본값이 적용됩니다.","maximum":100,"minimum":1},"grantedDailyTokens":{"type":["integer","null"],"format":"int64","description":"부여 일일 토큰 수. 비우면 일일 한도가 없습니다. 0이면 자체 서빙(토큰) 축을 쓸 수 없습니다.","minimum":0},"grantedCreditLimit":{"type":["number","null"],"description":"부여 금액 한도(USD 크레딧). 비우거나 0이면 유료 모델을 쓸 수 없습니다.","minimum":0},"grantedCreditLimitReset":{"anyOf":[{"$ref":"#/components/schemas/CreditLimitReset"},{"type":"null"}],"description":"금액 한도 리셋 창. 비우면 리셋 없는 총액 상한입니다. 창은 UTC 자정에 초기화됩니다."},"grantedCreditAllowedModels":{"type":["array","null"],"description":"이 키가 쓸 수 있는 유료 모델 목록. 비우면 제한이 없고, 자체 서빙 모델은 이 목록과 무관합니다. 항목은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 공급자 *는 ~별칭도 포함하고, 특정 공급자의 허용은 ~별칭을 별도로 적어야 합니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"},"maxItems":50,"minItems":0},"grantedCreditDeniedModels":{"type":["array","null"],"description":"이 키가 쓸 수 없는 유료 모델 목록. 비우면 차단하는 모델이 없고, 허용 목록과 함께 걸리면 차단이 이깁니다. 허용 목록과 달리 금액 한도가 0이어도 남습니다. 자체 서빙 모델은 이 목록과 무관합니다. 항목은 허용 목록과 같은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 차단은 ~를 제거한 이름도 검사하며, 별칭의 실제 대상 모델은 추적하지 않습니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"},"maxItems":50,"minItems":0},"grantedPassthroughEndpoints":{"type":["array","null"],"description":"이 키에 부여할 기능 권한. 비우면 기능을 하나도 쓸 수 없습니다. 모델 목록과 반대로 이 목록은 채워야 열립니다. 채팅과 모델 조회는 이 목록과 무관합니다.","items":{"type":"string","enum":["images","embeddings"]},"maxItems":20,"minItems":0},"openrouterAccountId":{"type":["string","null"],"format":"uuid","description":"유료 모델을 결제할 기관 사업 계정. 하나뿐이면 생략할 수 있습니다."}}},"ApproveRequestRequest":{"type":"object","properties":{"grantedStartDate":{"type":["string","null"],"format":"date"},"grantedEndDate":{"type":["string","null"],"format":"date"},"comment":{"type":["string","null"],"maxLength":2000,"minLength":0},"vm":{"anyOf":[{"$ref":"#/components/schemas/ApproveVmRequestSpec"},{"type":"null"}]},"llmKey":{"anyOf":[{"$ref":"#/components/schemas/ApproveLlmKeyRequestSpec"},{"type":"null"}]},"gpu":{"anyOf":[{"$ref":"#/components/schemas/ApproveGpuRequestSpec"},{"type":"null"}]}}},"ApproveVmRequestSpec":{"type":"object","properties":{"grantedVcpu":{"type":"integer","format":"int32","minimum":1},"grantedMemoryMb":{"type":"integer","format":"int32","minimum":256},"grantedDiskGb":{"type":"integer","format":"int32","minimum":1},"grantedImageId":{"type":"string","format":"uuid"},"grantedSlug":{"type":["string","null"],"pattern":"^\\s*$|^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$"},"nodeId":{"type":["string","null"],"format":"uuid"}},"required":["grantedDiskGb","grantedImageId","grantedMemoryMb","grantedVcpu"]},"CreateRequestPeriodRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"pattern":"^[a-z0-9][a-z0-9-]{0,38}[a-z0-9]$|^[a-z0-9]$"},"displayName":{"type":"string","maxLength":100,"minLength":0},"endDate":{"type":"string","format":"date","description":"종료일. 모든 기간 항목은 끝나는 날이 있습니다."},"displayOrder":{"type":["integer","null"],"format":"int32","description":"표시 순서. 비우면 0입니다."}},"required":["displayName","endDate","name"]},"AdminRequestPeriodResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"displayName":{"type":"string"},"endDate":{"type":"string","format":"date","description":"종료일"},"status":{"$ref":"#/components/schemas/CatalogStatus"},"displayOrder":{"type":"integer","format":"int32","description":"신청 화면에서의 표시 순서. 값이 같으면 먼저 만든 것이 앞에 옵니다."},"expired":{"type":"boolean","description":"종료일이 이미 지나 신청 화면에 나오지 않는 항목인지."}},"required":["displayName","displayOrder","endDate","expired","id","name","status"]},"RelayTokenResponse":{"type":"object","properties":{"relayId":{"type":"string","format":"uuid"},"token":{"type":"string","description":"새 동기화 토큰(64자 hex). 이 응답에서만 확인 가능하며 저장되지 않습니다"}},"required":["relayId","token"]},"AdminPortMappingResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"relayId":{"type":"string","format":"uuid"},"relayName":{"type":"string"},"vmId":{"type":"string","format":"uuid"},"vmName":{"type":["string","null"]},"proto":{"$ref":"#/components/schemas/PortMappingProto"},"publicPort":{"type":"integer","format":"int32"},"targetPort":{"type":"integer","format":"int32"},"status":{"$ref":"#/components/schemas/PortMappingStatus"},"suspendedReason":{"type":["string","null"],"description":"정지 사유 (SUSPENDED일 때)"},"suspendedBy":{"type":["string","null"],"format":"uuid","description":"정지한 관리자 id (자동 정지면 null)"},"suspendedByName":{"type":["string","null"],"description":"정지한 관리자 이름 (자동 정지면 null)"},"applyState":{"$ref":"#/components/schemas/PortForwardApplyState"},"ctMax":{"type":["integer","null"],"format":"int32","description":"동시 연결 상한 오버라이드 (null = 에이전트 기본, 0 = 해제)"},"newConnRate":{"type":["integer","null"],"format":"int32","description":"초당 신규 연결 상한 오버라이드"},"newConnBurst":{"type":["integer","null"],"format":"int32","description":"신규 연결 버스트 오버라이드"},"perSourceRate":{"type":["integer","null"],"format":"int32","description":"출발지별 초당 신규 연결 상한 오버라이드"},"perSourceBurst":{"type":["integer","null"],"format":"int32","description":"출발지별 버스트 오버라이드"},"createdBy":{"type":["string","null"],"format":"uuid"},"createdByName":{"type":["string","null"],"description":"매핑을 만든 관리자 이름"},"createdAt":{"type":"string","format":"date-time"}},"required":["applyState","createdAt","id","proto","publicPort","relayId","relayName","status","targetPort","vmId"]},"SuspendPortMappingRequest":{"type":"object","properties":{"reason":{"type":"string","description":"정지 사유 (소유 워크스페이스에 알림으로 전달)","maxLength":500,"minLength":0}},"required":["reason"]},"CreateOrgRequest":{"type":"object","properties":{"name":{"type":"string","maxLength":100,"minLength":0},"description":{"type":["string","null"],"maxLength":500,"minLength":0}},"required":["name"]},"OrgDetailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/OrgStatus"},"hidden":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}},"required":["createdAt","hidden","id","name","status"]},"OrgStatus":{"type":"string","enum":["ACTIVE","DISABLED"]},"NoticeCreateRequest":{"type":"object","properties":{"title":{"type":"string","maxLength":200,"minLength":0},"body":{"type":"string","maxLength":20000,"minLength":0},"pinned":{"type":"boolean","description":"목록 상단 고정 여부. 생략하면 고정하지 않습니다."},"popup":{"type":"boolean","description":"콘솔이 모달로 띄울지. 켜면 로그인하지 않은 방문자에게도 보입니다. 생략하면 둘 다 하지 않습니다."},"startsAt":{"type":["string","null"],"format":"date-time","description":"게시 시작 시각. 생략하면 즉시 게시합니다."},"endsAt":{"type":["string","null"],"format":"date-time","description":"게시 종료 시각. 생략하면 만료되지 않습니다."}},"required":["body","title"]},"AdminNoticeView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"body":{"type":"string"},"pinned":{"type":"boolean","description":"목록 상단 고정 여부"},"popup":{"type":"boolean","description":"콘솔이 모달로 띄울 공지인지. 이 공지가 로그인 없이도 보이는지도 같은 값이 정합니다."},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":["string","null"],"format":"date-time","description":"게시 종료 시각. 비어 있으면 만료되지 않습니다."},"active":{"type":"boolean","description":"지금 게시 창 안에 있는지. 예정·만료된 공지도 이 목록에는 함께 나옵니다."},"createdByName":{"type":["string","null"],"description":"공지를 등록한 사람의 이름. 계정이 지워졌으면 비어 있습니다."},"images":{"type":"array","items":{"$ref":"#/components/schemas/NoticeImageView"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["active","body","createdAt","id","images","pinned","popup","startsAt","title","updatedAt"]},"NoticeImageView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fileName":{"type":["string","null"],"description":"업로드 당시의 파일 이름. 클라이언트가 보내지 않았으면 비어 있습니다."},"contentType":{"type":"string","description":"저장된 실제 형식. 업로드 시 파일 선두 바이트로 판별한 값입니다."},"byteSize":{"type":"integer","format":"int32"},"url":{"type":"string","description":"이미지를 내려받는 경로. 인증 없이 열 수 있는지는 공지의 공개 범위를 따릅니다."}},"required":["byteSize","contentType","id","url"]},"SuspendAdminLlmKeyRequest":{"type":"object","properties":{"reason":{"type":"string","maxLength":500,"minLength":0}},"required":["reason"]},"CreateOpenRouterAccountRequest":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","description":"Account를 소유할 기관 공개 ID"},"name":{"type":"string","description":"기관 관리자가 구분하는 사업 계정 이름","maxLength":120,"minLength":0},"program":{"type":["string","null"],"description":"이 account가 청구되는 사업. 없으면 null","maxLength":500,"minLength":0},"contact":{"type":["string","null"],"description":"이 account를 물어볼 담당자. 없으면 null","maxLength":500,"minLength":0},"defaultCreditAllowedModels":{"type":["array","null"],"description":"승인 화면 프리필에 쓸 유료 모델 허용 목록 기본값. 비우면 제한 없음이 기본이 됩니다. 항목은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 공급자 *는 ~별칭도 포함하고, 특정 공급자의 허용은 ~별칭을 별도로 적어야 합니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"},"maxItems":50,"minItems":0},"defaultCreditDeniedModels":{"type":["array","null"],"description":"승인 화면 프리필에 쓸 유료 모델 차단 목록 기본값. 비우면 차단 없음이 기본이 됩니다. 항목은 허용 목록과 같은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 차단은 ~를 제거한 이름도 검사하며, 별칭의 실제 대상 모델은 추적하지 않습니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"},"maxItems":50,"minItems":0},"defaultPassthroughEndpoints":{"type":["array","null"],"description":"승인 화면 프리필에 쓸 기능 권한 기본값. 비우면 아무 기능도 부여되지 않은 상태가 기본이 됩니다.","items":{"type":"string","enum":["images","embeddings"]},"maxItems":20,"minItems":0},"confirmName":{"type":"string","description":"오입력 방지를 위해 name과 정확히 같아야 하는 확인값","maxLength":120,"minLength":0}},"required":["confirmName","name","orgId"]},"OpenRouterAccountAllocationResponse":{"type":"object","description":"이 account에 걸린 살아 있는 key의 금액 한도 합계","properties":{"committedCreditLimit":{"type":"number","description":"네 갈래 합계를 모두 더한 값. 이미 쓴 금액을 포함한 약속의 총량이라 잔액과 직접 비교하지 않는다"},"committedTotalCap":{"type":"number","description":"리셋 창이 없는 key의 한도 합. 한 번 나가고 끝나는 채무"},"committedDaily":{"type":"number","description":"일간 리셋 key의 한도 합. 창마다 다시 채워진다"},"committedWeekly":{"type":"number","description":"주간 리셋 key의 한도 합. 창마다 다시 채워진다"},"committedMonthly":{"type":"number","description":"월간 리셋 key의 한도 합. 창마다 다시 채워진다"},"committedKeyCount":{"type":"integer","format":"int64","description":"금액 한도가 0보다 큰 살아 있는 key 수. 한도 0인 key는 돈을 쥐고 있지 않으므로 세지 않는다"},"remainingCommitment":{"type":"number","description":"Key마다 한도에서 현재 limit window 사용액을 뺀 값을 0에서 끊어 더한 합. 잔액과 분모가 맞는 쪽은 이 값이다. 사용액은 30분 주기 대사값이라 리셋 직후 다음 대사 전까지는 실제보다 작을 수 있다"},"committedUsage":{"type":"number","description":"살아 있는 key의 reset-aware 누적 사용액 합. 현재 창 사용액이 아니라 account baseline 뒤 누계이며, 폐기와 만료 key의 몫은 빠져 있어 credits.managedUsageSinceBaseline과 다른 수다"},"awaitingProvisionKeyCount":{"type":"integer","format":"int64","description":"금액 한도가 0보다 큰데 아직 프로비저닝되지 않아 vendor에 한도가 걸리지 않은 key 수"},"usageUnreportedKeyCount":{"type":"integer","format":"int64","description":"프로비저닝됐지만 사용액 보고가 아직 없는 key 수. 0이 아니면 remainingCommitment의 그만큼은 실측이 아니라 한도 전액"}},"required":["awaitingProvisionKeyCount","committedCreditLimit","committedDaily","committedKeyCount","committedMonthly","committedTotalCap","committedUsage","committedWeekly","remainingCommitment","usageUnreportedKeyCount"]},"OpenRouterAccountCreditsResponse":{"type":"object","properties":{"totalCredits":{"type":["number","null"],"description":"OpenRouter가 보고한 구매 credits 합계. 성공 이력이 없으면 null"},"totalUsage":{"type":["number","null"],"description":"OpenRouter가 보고한 account 누적 사용액. 성공 이력이 없으면 null"},"balance":{"type":["number","null"],"description":"totalCredits - totalUsage. 음수도 그대로 반환하며 미관측이면 null"},"freshness":{"$ref":"#/components/schemas/OpenRouterCreditsFreshness","description":"마지막 성공 기준 30분 미만 FRESH, 그 이상 STALE, 성공 없음 UNKNOWN"},"observedAt":{"type":["string","null"],"format":"date-time","description":"현재 금액 값을 vendor에서 관측한 시각. 미관측이면 null"},"lastSuccessAt":{"type":["string","null"],"format":"date-time","description":"마지막 성공 시각. 성공 이력이 없으면 null"},"lastAttemptAt":{"type":["string","null"],"format":"date-time","description":"성공·실패를 포함한 마지막 시도 시각. 시도 이력이 없으면 null"},"error":{"anyOf":[{"$ref":"#/components/schemas/OpenRouterCredentialError"},{"type":"null"}],"description":"마지막 시도가 실패했을 때의 분류. vendor 원문은 반환하지 않음"},"averageDailyUsage":{"type":["number","null"],"description":"최근 7일 관측 window의 일평균 사용액. 계산 불가하면 null"},"depletionForecastAt":{"type":["string","null"],"format":"date-time","description":"현재 소비 속도가 계속될 때 잔액 소진 예상 시각. 계산 불가하면 null"},"forecastUnavailableReason":{"anyOf":[{"$ref":"#/components/schemas/OpenRouterForecastUnavailableReason"},{"type":"null"}],"description":"예상 시각이 없는 이유. 예상 시각이 있으면 null"},"forecastWindowStartedAt":{"type":["string","null"],"format":"date-time","description":"예상 계산에 사용한 첫 관측 시각. 이력 부족이면 null"},"accountUsageSinceBaseline":{"type":["number","null"],"description":"첫 paired baseline 뒤 account 누적 사용 증가분. 계산 불가하면 null"},"managedUsageSinceBaseline":{"type":["number","null"],"description":"Key reset·삭제를 보존한 Pickle 관리 key 사용 증가분. 없으면 null"},"unmanagedSpend":{"type":["number","null"],"description":"Account 증가분에서 관리 key 증가분을 뺀 금액. reset 경계면 null"},"unmanagedSpendUnavailableReason":{"anyOf":[{"$ref":"#/components/schemas/OpenRouterUnmanagedSpendUnavailableReason"},{"type":"null"}],"description":"미관리 지출이 없는 이유. 값이 있으면 null"},"pairedCreditsObservedAt":{"type":["string","null"],"format":"date-time","description":"Paired window의 account credits 관측 시각. 없으면 null"},"pairedKeysObservedAt":{"type":["string","null"],"format":"date-time","description":"Paired window의 전체 key 대사 관측 시각. 없으면 null"},"keysFreshness":{"$ref":"#/components/schemas/OpenRouterCreditsFreshness","description":"마지막 성공한 account key 대사의 freshness"},"keysLastSuccessAt":{"type":["string","null"],"format":"date-time","description":"마지막으로 account key 대사가 성공한 시각. 없으면 null"},"keysLastAttemptAt":{"type":["string","null"],"format":"date-time","description":"성공·실패를 포함한 마지막 account key 대사 시도 시각"},"keysError":{"anyOf":[{"$ref":"#/components/schemas/OpenRouterCredentialError"},{"type":"null"}],"description":"마지막 account key 대사가 실패했을 때의 오류 분류"},"unmanagedBaselineAt":{"type":["string","null"],"format":"date-time","description":"미관리 지출 baseline의 paired 관측 시각. 없으면 null"}},"required":["freshness","keysFreshness"]},"OpenRouterAccountResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Account 공개 ID"},"orgId":{"type":"string","format":"uuid","description":"소유 기관 공개 ID"},"orgName":{"type":"string","description":"소유 기관 이름"},"name":{"type":"string","description":"사업 계정 이름"},"status":{"$ref":"#/components/schemas/OpenRouterAccountStatus","description":"Account lifecycle 상태"},"program":{"type":["string","null"],"description":"이 account가 청구되는 사업. 없으면 null"},"contact":{"type":["string","null"],"description":"이 account를 물어볼 담당자. 없으면 null"},"eligibleForBinding":{"type":"boolean","description":"현재 positive-credit key binding에 선택할 수 있는지"},"boundKeyCount":{"type":"integer","format":"int64","description":"이 사업 계정에 연결된 LLM API 키 수"},"credentialAvailable":{"type":"boolean","description":"프로비저닝과 대사에 사용할 management credential이 있는지"},"activeCredential":{"anyOf":[{"$ref":"#/components/schemas/OpenRouterCredentialStateResponse"},{"type":"null"}],"description":"현재 ACTIVE credential의 secret-free 상태. 없으면 null"},"rotationCredential":{"anyOf":[{"$ref":"#/components/schemas/OpenRouterCredentialStateResponse"},{"type":"null"}],"description":"STAGED 또는 RETIRING credential의 secret-free 상태. 없으면 null"},"credits":{"$ref":"#/components/schemas/OpenRouterAccountCreditsResponse","description":"DB cache에서 읽은 account credits·예상·미관리 지출 관측 상태"},"allocation":{"$ref":"#/components/schemas/OpenRouterAccountAllocationResponse","description":"이 account에 걸린 살아 있는 key의 금액 한도 합계"},"defaultCreditAllowedModels":{"type":"array","description":"승인 화면이 프리필에 쓰는 유료 모델 허용 목록 기본값. 복사 원본이지 상속원이 아니라서 여기를 바꿔도 이미 발급된 키는 그대로입니다. 항목은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 공급자 *는 ~별칭도 포함하고, 특정 공급자의 허용은 ~별칭을 별도로 적어야 합니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"}},"defaultCreditDeniedModels":{"type":"array","description":"승인 화면이 프리필에 쓰는 유료 모델 차단 목록 기본값. 복사 원본이지 상속원이 아니라서 여기를 바꿔도 이미 발급된 키는 그대로입니다. 항목은 허용 목록과 같은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 차단은 ~를 제거한 이름도 검사하며, 별칭의 실제 대상 모델은 추적하지 않습니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"}},"defaultPassthroughEndpoints":{"type":"array","description":"승인 화면이 프리필에 쓰는 기능 권한 기본값. 복사 원본이지 상속원이 아니라서 여기를 바꿔도 이미 발급된 키는 그대로입니다.","items":{"type":"string","enum":["images","embeddings"]}},"createdAt":{"type":"string","format":"date-time","description":"등록 시각"},"updatedAt":{"type":"string","format":"date-time","description":"Metadata 최종 변경 시각"}},"required":["allocation","boundKeyCount","createdAt","credentialAvailable","credits","defaultCreditAllowedModels","defaultCreditDeniedModels","defaultPassthroughEndpoints","eligibleForBinding","id","name","orgId","orgName","status","updatedAt"]},"OpenRouterAccountStatus":{"type":"string","enum":["ACTIVE","ARCHIVED"]},"OpenRouterCredentialError":{"type":"string","enum":["CREDENTIAL_ERROR","THROTTLED","VENDOR_UNAVAILABLE","VENDOR_REJECTED"]},"OpenRouterCredentialStateResponse":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/OpenRouterCredentialStatus","description":"Credential lifecycle 상태"},"createdAt":{"type":"string","format":"date-time","description":"등록 시각"},"lastVerificationAttemptAt":{"type":["string","null"],"format":"date-time","description":"마지막 검증 시도 시각. 시도 전이면 null"},"verifiedAt":{"type":["string","null"],"format":"date-time","description":"마지막 검증 성공 시각. 성공 이력이 없으면 null"},"activatedAt":{"type":["string","null"],"format":"date-time","description":"ACTIVE 전환 시각. 활성화 전이면 null"},"retiringAt":{"type":["string","null"],"format":"date-time","description":"RETIRING 전환 시각. 해당 상태가 아니면 null"},"lastUsedAt":{"type":["string","null"],"format":"date-time","description":"Management API 호출에 마지막으로 사용한 시각. 사용 전이면 null"},"lastReconciledAt":{"type":["string","null"],"format":"date-time","description":"이 credential로 key reconciliation이 마지막으로 성공한 시각. 성공 전이면 null"},"verificationError":{"anyOf":[{"$ref":"#/components/schemas/OpenRouterCredentialError"},{"type":"null"}],"description":"마지막 검증 오류 분류. 최근 검증이 성공했으면 null"},"retiringOverdue":{"type":"boolean","description":"RETIRING 상태가 24시간을 넘었는지"}},"required":["createdAt","retiringOverdue","status"]},"OpenRouterCredentialStatus":{"type":"string","enum":["STAGED","ACTIVE","RETIRING"]},"OpenRouterCreditsFreshness":{"type":"string","enum":["FRESH","STALE","UNKNOWN"]},"OpenRouterForecastUnavailableReason":{"type":"string","enum":["INSUFFICIENT_HISTORY","RESET_BOUNDARY","NO_CONSUMPTION","OUT_OF_RANGE"]},"OpenRouterUnmanagedSpendUnavailableReason":{"type":"string","enum":["NO_BASELINE","INCOMPLETE_PAIR","RESET_BOUNDARY"]},"StageOpenRouterCredentialRequest":{"type":"object","properties":{"managementKey":{"type":"string","description":"OpenRouter management key. 응답에는 반환되지 않습니다.","maxLength":4096,"minLength":0,"writeOnly":true},"confirmName":{"type":"string","description":"Account 이름과 정확히 같아야 하는 확인값","maxLength":120,"minLength":0}},"required":["confirmName","managementKey"]},"ConfirmOpenRouterAccountRequest":{"type":"object","properties":{"confirmName":{"type":"string","description":"Account 이름과 정확히 같아야 하는 확인값","maxLength":120,"minLength":0}},"required":["confirmName"]},"FinalizeOpenRouterCredentialRequest":{"type":"object","properties":{"confirmName":{"type":"string","description":"Account 이름과 정확히 같아야 하는 확인값","maxLength":120,"minLength":0},"vendorRevocationConfirmed":{"type":"boolean","description":"Vendor console에서 대상 management key를 폐기했으면 true. API는 vendor key를 폐기하지 않습니다."}},"required":["confirmName","vendorRevocationConfirmed"]},"DecideGpuReviewRequest":{"type":"object","properties":{"decision":{"$ref":"#/components/schemas/GpuReviewDecision"},"reason":{"type":"string","maxLength":2000,"minLength":0}},"required":["decision","reason"]},"GpuReviewDecision":{"type":"string","enum":["KEEP","RECLAIM"]},"GpuReasonRequest":{"type":"object","properties":{"reason":{"type":"string","maxLength":2000,"minLength":0}},"required":["reason"]},"UpdateGpuPriorityRequest":{"type":"object","properties":{"priority":{"type":"integer","format":"int32"},"reason":{"type":"string","maxLength":2000,"minLength":0}},"required":["priority","reason"]},"ResolveDriftFindingRequest":{"type":"object","properties":{"note":{"type":"string","maxLength":2000,"minLength":0}}},"DriftFindingKind":{"type":"string","enum":["GPU_ATTACHMENT_MISMATCH","MISSING_IN_PROXMOX","UNMANAGED_GUEST","SPEC_MISMATCH","OPENROUTER_ORPHAN","OPENROUTER_STALE"]},"DriftFindingResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"$ref":"#/components/schemas/DriftFindingKind"},"vmId":{"type":["string","null"],"format":"uuid"},"vmName":{"type":["string","null"]},"proxmoxVmid":{"type":["integer","null"],"format":"int32"},"nodeName":{"type":["string","null"]},"summary":{"type":"string"},"detail":{},"status":{"$ref":"#/components/schemas/DriftFindingStatus"},"firstSeenAt":{"type":"string","format":"date-time"},"lastSeenAt":{"type":"string","format":"date-time"},"resolvedAt":{"type":["string","null"],"format":"date-time"},"resolvedById":{"type":["string","null"],"format":"uuid"},"resolvedByEmail":{"type":["string","null"]},"resolutionNote":{"type":["string","null"]}},"required":["firstSeenAt","id","kind","lastSeenAt","status","summary"]},"DriftFindingStatus":{"type":"string","enum":["OPEN","RESOLVED"]},"UpdateCampusIpRequestStatusRequest":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/CampusIpRequestStatus","description":"전환할 상태 (APPROVED = 승인, GRANTED = 교내 IP 연결 완료, REJECTED = 반려, REVOKED = 회수)"},"grantedAddress":{"type":["string","null"],"description":"연결한 교내 IP 주소 (GRANTED 전환 시 필수, 10.0.0.0/8 대역)","maxLength":45,"minLength":0},"adminNote":{"type":["string","null"],"description":"관리자 메모 (신청자 알림에 포함)","maxLength":1000,"minLength":0}},"required":["status"]},"AdminCampusIpRequestView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"vmId":{"type":"string","format":"uuid"},"vmName":{"type":["string","null"]},"orgId":{"type":["string","null"],"format":"uuid"},"purpose":{"type":"string","description":"신청 목적"},"ports":{"type":"array","description":"사용할 포트 번호 목록","items":{"type":"integer","format":"int32"}},"status":{"$ref":"#/components/schemas/CampusIpRequestStatus","description":"신청 상태 (REQUESTED = 신청, APPROVED = 관리자 승인, GRANTED = 교내 IP 연결 완료, REJECTED = 반려, REVOKED = 회수)"},"grantedAddress":{"type":["string","null"],"description":"연결된 교내 IP 주소 (10.0.0.0/8)"},"adminNote":{"type":["string","null"]},"requestedBy":{"type":"string","format":"uuid"},"requesterEmail":{"type":["string","null"],"description":"신청자 이메일"},"processedBy":{"type":["string","null"],"format":"uuid"},"processedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["createdAt","id","ports","purpose","requestedBy","status","vmId"]},"AnnouncementCreateRequest":{"type":"object","properties":{"title":{"type":"string","maxLength":200,"minLength":0},"body":{"type":"string","maxLength":10000,"minLength":0},"scope":{"$ref":"#/components/schemas/AnnouncementScope"},"orgId":{"type":["string","null"],"format":"uuid"},"workspaceId":{"type":["string","null"],"format":"uuid"}},"required":["body","scope","title"]},"AnnouncementScope":{"type":"string","enum":["ALL","ORG","WORKSPACE"]},"AnnouncementView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"scope":{"$ref":"#/components/schemas/AnnouncementScope"},"orgId":{"type":["string","null"],"format":"uuid"},"workspaceId":{"type":["string","null"],"format":"uuid"},"recipientCount":{"type":"integer","format":"int32"},"createdAt":{"type":"string","format":"date-time"}},"required":["createdAt","id","recipientCount","scope","title"]},"UpdateWorkspaceRequest":{"type":"object","properties":{"name":{"type":"string","maxLength":100,"minLength":0},"description":{"type":["string","null"],"maxLength":500,"minLength":0},"kind":{"$ref":"#/components/schemas/CreatableWorkspaceKind","description":"워크스페이스 유형. PERSONAL 워크스페이스는 유형을 바꿀 수 없습니다"}}},"UpdateWorkspaceMemberRequest":{"type":"object","properties":{"role":{"$ref":"#/components/schemas/WorkspaceMemberRole"}},"required":["role"]},"VmSettingsUpdateRequest":{"type":"object","properties":{"settings":{"type":"object","additionalProperties":{}}},"required":["settings"]},"VmSettingValueType":{"type":"string","enum":["BOOLEAN","ENUM","INTEGER","STRING"]},"VmSettingView":{"type":"object","properties":{"key":{"type":"string"},"value":{},"valueType":{"$ref":"#/components/schemas/VmSettingValueType"},"allowedValues":{"type":["array","null"],"items":{"type":"string"}},"defaultValue":{},"label":{"type":"string"},"description":{"type":"string"},"requiredRole":{"$ref":"#/components/schemas/ResourceRole"},"editable":{"type":"boolean"},"updatedByName":{"type":["string","null"]},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["defaultValue","description","editable","key","label","requiredRole","value","valueType"]},"UpdateResourceAccessGrantRequest":{"type":"object","properties":{"role":{"$ref":"#/components/schemas/ResourceRole","description":"새 등급. 워크스페이스 전체 항목에는 MEMBER 또는 VIEWER만 지정할 수 있습니다."}},"required":["role"]},"UpdateLlmKeyRequest":{"type":"object","properties":{"name":{"type":["string","null"],"description":"키 이름. 생략하면 그대로 둡니다.","maxLength":100,"minLength":1},"purpose":{"type":["string","null"],"description":"사용 목적. 생략하면 그대로 둡니다.","maxLength":2000,"minLength":0},"recordBodies":{"type":["boolean","null"],"description":"요청·응답 본문 기록 여부. 기본값은 꺼짐이며, 켜면 이 키로 보낸 프롬프트와 응답이 수집됩니다. 생략하면 그대로 둡니다."}}},"UpdateDomainRequest":{"type":"object","properties":{"port":{"type":"integer","format":"int32"}}},"VmPeriodUpdateRequest":{"type":"object","properties":{"endDate":{"type":["string","null"],"format":"date","description":"새 종료일. 무기한으로 바꾸려면 clearEndDate를 씁니다."},"clearEndDate":{"type":["boolean","null"],"description":"true면 종료일을 지워 무기한으로 만듭니다. endDate와 함께 보낼 수 없습니다."},"startDate":{"type":["string","null"],"format":"date"}}},"GpuVmSummary":{"type":"object","properties":{"allocationId":{"type":"string","format":"uuid"},"allocationName":{"type":"string"},"model":{"type":"string"},"connectionStatus":{"$ref":"#/components/schemas/GpuConnectionStatus"},"detailAccessAllowed":{"type":"boolean"}},"required":["allocationId","allocationName","connectionStatus","detailAccessAllowed","model"]},"ProvisioningTaskKind":{"type":"string","enum":["PROVISION","DELETE","REINSTALL"]},"ProvisioningTaskResponse":{"type":"object","properties":{"kind":{"$ref":"#/components/schemas/ProvisioningTaskKind"},"status":{"$ref":"#/components/schemas/ProvisioningTaskStatus"},"currentStep":{"type":"integer","format":"int32"},"totalSteps":{"type":"integer","format":"int32"},"stepLabel":{"type":"string"},"attempts":{"type":"integer","format":"int32"},"lastError":{"type":["string","null"]},"updatedAt":{"type":"string","format":"date-time"}},"required":["attempts","currentStep","kind","status","stepLabel","totalSteps","updatedAt"]},"ProvisioningTaskStatus":{"type":"string","enum":["PENDING","RUNNING","DONE","FAILED","RETRYING","NEEDS_ADMIN"]},"VmDetailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"hostname":{"type":"string"},"status":{"$ref":"#/components/schemas/VmStatus"},"vcpu":{"type":"integer","format":"int32"},"memoryMb":{"type":"integer","format":"int32"},"diskGb":{"type":"integer","format":"int32"},"workspaceId":{"type":["string","null"],"format":"uuid","description":"소유 워크스페이스. 행이 사라진 경우에만 null입니다."},"workspaceName":{"type":"string"},"orgName":{"type":["string","null"]},"displayName":{"type":["string","null"]},"requestId":{"type":["string","null"],"format":"uuid","description":"이 VM을 만든 신청. 행이 사라진 경우에만 null입니다."},"statusDetail":{"type":["string","null"]},"sshGatewayBlocked":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"orgId":{"type":["string","null"],"format":"uuid","description":"소속 기관. 행이 사라진 경우에만 null입니다."},"imageId":{"type":["string","null"],"format":"uuid","description":"생성에 쓰인 OS 이미지. 행이 사라진 경우에만 null입니다."},"ipAddress":{"type":["string","null"]},"sshUsername":{"type":"string"},"sshHost":{"type":"string"},"myResourceRole":{"anyOf":[{"$ref":"#/components/schemas/ResourceRole"},{"type":"null"}]},"startDate":{"type":["string","null"],"format":"date"},"endDate":{"type":["string","null"],"format":"date"},"expiryStoppedAt":{"type":["string","null"],"format":"date-time"},"provisioning":{"anyOf":[{"$ref":"#/components/schemas/ProvisioningTaskResponse"},{"type":"null"}]},"deletion":{"anyOf":[{"$ref":"#/components/schemas/VmDeletionResponse"},{"type":"null"}]},"publications":{"type":"array","items":{"$ref":"#/components/schemas/PublicationView"}},"passwordAvailable":{"type":"boolean"},"passwordRevealAllowed":{"type":"boolean"},"accessAllowed":{"type":"boolean","description":"SSH·웹 터미널로 이 VM에 접속할 수 있는지"},"powerControlAllowed":{"type":"boolean","description":"전원을 제어할 수 있는지"},"settingsEditAllowed":{"type":"boolean","description":"VM 설정을 볼·바꿀 수 있는지"},"accessManageAllowed":{"type":"boolean","description":"접근 권한 목록을 관리할 수 있는지"},"deleteAllowed":{"type":"boolean","description":"삭제를 접수할 수 있는지"},"gpu":{"anyOf":[{"$ref":"#/components/schemas/GpuVmSummary"},{"type":"null"}]},"updatedAt":{"type":"string","format":"date-time"}},"required":["accessAllowed","accessManageAllowed","createdAt","deleteAllowed","diskGb","hostname","id","memoryMb","name","passwordAvailable","passwordRevealAllowed","powerControlAllowed","publications","settingsEditAllowed","sshGatewayBlocked","sshHost","sshUsername","status","updatedAt","vcpu","workspaceName"]},"VmStatus":{"type":"string","enum":["CREATING","RUNNING","STOPPED","REBOOTING","DELETING","DELETED","ERROR","NEEDS_ADMIN"]},"VmGatewayBlockUpdateRequest":{"type":"object","properties":{"blocked":{"type":"boolean","description":"true = SSH 게이트웨이·웹 터미널 차단, false = 차단 해제"},"reason":{"type":["string","null"],"description":"차단·해제 사유 (VM 이벤트·감사 기록에 포함, 선택)","maxLength":200,"minLength":0}},"required":["blocked"]},"UpdateVmFlavorRequest":{"type":"object","properties":{"displayName":{"type":["string","null"],"maxLength":100,"minLength":0},"vcpu":{"type":["integer","null"],"format":"int32","minimum":1},"memoryMb":{"type":["integer","null"],"format":"int32","minimum":256},"diskGb":{"type":["integer","null"],"format":"int32","minimum":1},"notes":{"type":["string","null"],"maxLength":2000,"minLength":0},"status":{"anyOf":[{"$ref":"#/components/schemas/CatalogStatus"},{"type":"null"}],"description":"ACTIVE = 신청 화면에 노출, DISABLED = 은퇴 (기존 신청과 VM 무영향)"},"displayOrder":{"type":["integer","null"],"format":"int32","description":"신청 화면에서의 표시 순서. 값이 같으면 먼저 만든 것이 앞에 옵니다."}}},"AdminGlobalRole":{"type":"string","enum":["USER","SYS_VIEWER","SYS_MANAGER","SYS_ADMIN"]},"UpdateUserAdminRequest":{"type":"object","properties":{"role":{"$ref":"#/components/schemas/AdminGlobalRole"}}},"AdminUpdateProfileRequest":{"type":"object","minProperties":1,"properties":{"position":{"anyOf":[{"$ref":"#/components/schemas/UserPosition"},{"type":"null"}]},"studentNo":{"type":["string","null"],"maxLength":20,"minLength":0},"departmentCode":{"type":["string","null"],"maxLength":32,"minLength":0},"departmentOther":{"type":["string","null"],"maxLength":100,"minLength":0},"reason":{"type":["string","null"],"maxLength":200,"minLength":0}}},"UpdateRequestPeriodRequest":{"type":"object","properties":{"displayName":{"type":["string","null"],"maxLength":100,"minLength":0},"endDate":{"type":["string","null"],"format":"date","description":"새 종료일"},"status":{"anyOf":[{"$ref":"#/components/schemas/CatalogStatus"},{"type":"null"}]},"displayOrder":{"type":["integer","null"],"format":"int32"}}},"UpdatePortMappingGuardsRequest":{"type":"object","properties":{"ctMax":{"type":["integer","null"],"format":"int32","description":"매핑별 동시 연결 상한 (null = 기본값, 0 = 해제)"},"newConnRate":{"type":["integer","null"],"format":"int32","description":"초당 신규 연결 상한"},"newConnBurst":{"type":["integer","null"],"format":"int32","description":"신규 연결 버스트"},"perSourceRate":{"type":["integer","null"],"format":"int32","description":"출발지별 초당 신규 연결 상한"},"perSourceBurst":{"type":["integer","null"],"format":"int32","description":"출발지별 버스트"}}},"UpdateOsImageStatusRequest":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/CatalogStatus","description":"ACTIVE = 신청 위저드에 노출, DISABLED = 은퇴 (기존 VM 무영향)"}},"required":["status"]},"AdminOsImageResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"displayName":{"type":"string"},"osFamily":{"type":"string"},"osVersion":{"type":"string"},"sshUsername":{"type":"string"},"version":{"type":"integer","format":"int32"},"proxmoxVmid":{"type":"integer","format":"int32"},"nodeId":{"type":"string","format":"uuid"},"status":{"$ref":"#/components/schemas/CatalogStatus"},"minDiskGb":{"type":"integer","format":"int32"},"notes":{"type":["string","null"]}},"required":["displayName","id","minDiskGb","name","nodeId","osFamily","osVersion","proxmoxVmid","sshUsername","status","version"]},"UpdateOrgRequest":{"type":"object","properties":{"name":{"type":"string","maxLength":100,"minLength":0},"description":{"type":["string","null"],"maxLength":500,"minLength":0},"status":{"$ref":"#/components/schemas/OrgStatus"},"hidden":{"type":"boolean"}}},"NoticeUpdateRequest":{"type":"object","properties":{"title":{"type":"string","maxLength":200,"minLength":0},"body":{"type":"string","maxLength":20000,"minLength":0},"pinned":{"type":"boolean"},"popup":{"type":"boolean"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":["string","null"],"format":"date-time","description":"게시 종료 시각. null을 명시하면 만료 없음으로 바꿉니다."}}},"NodeStatus":{"type":"string","enum":["ACTIVE","MAINTENANCE","OFFLINE"]},"UpdateNodeStatusRequest":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/NodeStatus","description":"ACTIVE만 신규 VM 배치 대상 — MAINTENANCE/OFFLINE은 배치 제외 (기존 게스트 무영향)"}},"required":["status"]},"IpPoolSummaryResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"cidr":{"type":"string"},"allocatedCount":{"type":"integer","format":"int64"},"freeCount":{"type":"integer","format":"int64"}},"required":["allocatedCount","cidr","freeCount","id","name"]},"NodeSummaryResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"$ref":"#/components/schemas/NodeStatus"},"cpuThreads":{"type":"integer","format":"int32"},"memoryMb":{"type":"integer","format":"int32"},"vmBridge":{"type":"string"},"storage":{"type":"string"},"diskCapacityGb":{"type":["integer","null"],"format":"int64","description":"게스트 디스크가 놓이는 thin pool 용량(GB) — 아직 측정되지 않았으면 null"},"runningVms":{"type":"integer","format":"int64"},"allocatedVcpu":{"type":"integer","format":"int64"},"allocatedMemoryMb":{"type":"integer","format":"int64"},"cpuOvercommitRatio":{"type":"number","format":"double"},"memoryAllocRatio":{"type":"number","format":"double"},"cpuWarnThreshold":{"type":"number","format":"double"},"memoryWarnThreshold":{"type":"number","format":"double"},"ipPool":{"$ref":"#/components/schemas/IpPoolSummaryResponse"}},"required":["allocatedMemoryMb","allocatedVcpu","cpuOvercommitRatio","cpuThreads","cpuWarnThreshold","id","ipPool","memoryAllocRatio","memoryMb","memoryWarnThreshold","name","runningVms","status","storage","vmBridge"]},"UpdateOpenRouterAccountRequest":{"type":"object","properties":{"name":{"type":"string","description":"새 account 이름. 생략하면 유지하며 null은 허용하지 않습니다.","maxLength":120,"minLength":0},"program":{"type":["string","null"],"description":"새 사업. 생략하면 유지하고 null이면 지웁니다.","maxLength":500,"minLength":0},"contact":{"type":["string","null"],"description":"새 담당자. 생략하면 유지하고 null이면 지웁니다.","maxLength":500,"minLength":0},"status":{"$ref":"#/components/schemas/OpenRouterAccountStatus","description":"새 lifecycle 상태. 생략하면 유지하며 null은 허용하지 않습니다."},"defaultCreditAllowedModels":{"type":["array","null"],"description":"새 유료 모델 허용 목록 기본값. 생략하면 유지하고, null이나 빈 배열이면 기본값을 지웁니다. 이 쓰기는 게이트웨이 문서를 바꾸지 않으므로 이미 발급된 키에는 영향이 없습니다. 항목은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 공급자 *는 ~별칭도 포함하고, 특정 공급자의 허용은 ~별칭을 별도로 적어야 합니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"},"maxItems":50,"minItems":0},"defaultCreditDeniedModels":{"type":["array","null"],"description":"새 유료 모델 차단 목록 기본값. 생략하면 유지하고, null이나 빈 배열이면 기본값을 지웁니다. 이 쓰기는 게이트웨이 문서를 바꾸지 않으므로 이미 발급된 키에는 영향이 없습니다. 항목은 허용 목록과 같은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 차단은 ~를 제거한 이름도 검사하며, 별칭의 실제 대상 모델은 추적하지 않습니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"},"maxItems":50,"minItems":0},"defaultPassthroughEndpoints":{"type":["array","null"],"description":"새 기능 권한 기본값. 생략하면 유지하고, null이나 빈 배열이면 기본값을 지웁니다. 이 쓰기는 게이트웨이 문서를 바꾸지 않으므로 이미 발급된 키에는 영향이 없습니다.","items":{"type":"string","enum":["images","embeddings"]},"maxItems":20,"minItems":0}}},"UpdateGpuStatusRequest":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/GpuStatus"},"reason":{"type":"string","maxLength":2000,"minLength":0}},"required":["reason","status"]},"UpdateDomainRenewalRequest":{"type":"object","properties":{"renewDueAt":{"type":"string","format":"date-time","description":"이 시각까지 연장하지 않으면 레코드가 내려가고 이름이 해제됩니다."},"reason":{"type":"string","description":"기한을 바꾼 이유. 감사 기록에 남습니다."}},"required":["renewDueAt"]},"AdminDomainView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"vmId":{"type":["string","null"],"format":"uuid","description":"이 이름을 쓰는 가상머신. 외부 도메인은 가상머신에 매이지 않으므로 null입니다."},"kind":{"$ref":"#/components/schemas/DomainKind"},"fqdn":{"type":"string"},"rootDomain":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/DomainStatus"},"verifiedAt":{"type":["string","null"],"format":"date-time"},"releasedAt":{"type":["string","null"],"format":"date-time"},"reservedUntil":{"type":["string","null"],"format":"date-time"},"renewDueAt":{"type":["string","null"],"format":"date-time","description":"사용 기한. 외부 도메인만 갖습니다 — 다른 종류는 가상머신이나 소유자의 DNS가 수명을 정하므로 null입니다."},"createdAt":{"type":"string","format":"date-time"},"vmName":{"type":["string","null"],"description":"이 이름을 쓰는 가상머신의 이름. 외부 도메인은 null입니다."},"workspaceId":{"type":"string","format":"uuid"},"workspaceName":{"type":"string"},"orgId":{"type":"string","format":"uuid"},"orgName":{"type":"string"},"routeStatus":{"anyOf":[{"$ref":"#/components/schemas/RouteStatus"},{"type":"null"}]},"certificateStatus":{"anyOf":[{"$ref":"#/components/schemas/CertificateStatus"},{"type":"null"}]},"dnsStatus":{"$ref":"#/components/schemas/DomainDnsStatus"},"dnsLastError":{"type":["string","null"]},"dnsAppliedAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["createdAt","dnsStatus","fqdn","id","kind","orgId","orgName","status","workspaceId","workspaceName"]},"UpdateDomainRootRequest":{"type":"object","properties":{"autoApprove":{"type":"boolean","description":"true면 자동 승인, false면 승인 필요."}},"required":["autoApprove"]},"AdminDomainRootView":{"type":"object","properties":{"rootDomain":{"type":"string","description":"루트 도메인","example":"pusan.dev"},"orgId":{"type":"string","format":"uuid","description":"이 루트 아래 이름이 속하는 기관"},"orgName":{"type":"string"},"autoApprove":{"type":"boolean","description":"true면 이 루트 아래 이름 신청이 접수와 동시에 승인됩니다. false면 승인 큐를 탑니다. **지금 이 값이 다스리는 것은 외부 도메인 발급뿐이고 가상머신 서브도메인 공개는 아직 아닙니다.**"},"issuedNames":{"type":"integer","format":"int64","description":"이 루트 아래 지금 서 있는 외부 도메인 수"}},"required":["autoApprove","issuedNames","orgId","orgName","rootDomain"]},"WorkspaceSummaryResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"$ref":"#/components/schemas/WorkspaceKind"},"name":{"type":"string"},"description":{"type":["string","null"]},"myRole":{"$ref":"#/components/schemas/WorkspaceMemberRole"},"memberCount":{"type":"integer","format":"int64"}},"required":["id","kind","memberCount","myRole","name"]},"PageResponseVmSummaryResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/VmSummaryResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"VmSummaryResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","description":"SSH 슬러그. 접근 권한이 없으면 대신 표시 이름이 들어갑니다."},"hostname":{"type":["string","null"],"description":"SSH 슬러그. 접근 권한이 없으면 생략됩니다."},"status":{"$ref":"#/components/schemas/VmStatus"},"vcpu":{"type":["integer","null"],"format":"int32","description":"vCPU. 접근 권한이 없으면 생략됩니다."},"memoryMb":{"type":["integer","null"],"format":"int32","description":"메모리(MiB). 접근 권한이 없으면 생략됩니다."},"diskGb":{"type":["integer","null"],"format":"int32","description":"디스크(GiB). 접근 권한이 없으면 생략됩니다."},"workspaceId":{"type":["string","null"],"format":"uuid","description":"소유 워크스페이스. 행이 사라진 경우에만 null입니다."},"workspaceName":{"type":"string"},"orgId":{"type":["string","null"],"format":"uuid","description":"소유 기관. 접근 권한이 없거나 기관 행이 사라진 경우 null입니다."},"orgName":{"type":["string","null"]},"displayName":{"type":["string","null"]},"requestId":{"type":["string","null"],"format":"uuid"},"statusDetail":{"type":["string","null"]},"sshGatewayBlocked":{"type":["boolean","null"]},"endDate":{"type":["string","null"],"format":"date"},"expiryStoppedAt":{"type":["string","null"],"format":"date-time"},"deletion":{"anyOf":[{"$ref":"#/components/schemas/VmDeletionResponse"},{"type":"null"}],"description":"예약된 삭제. 예약이 없거나 접근 제한 행이면 null입니다."},"createdAt":{"type":"string","format":"date-time"},"accessLimited":{"type":"boolean","description":"true면 이 VM의 접근 권한이 없어 이름·상태·소유자만 표시됩니다."},"ownerNames":{"type":"array","description":"이 VM의 소유자 이름. 접근을 요청할 상대입니다.","items":{"type":"string"}},"accessManageAllowed":{"type":"boolean","description":"접근 권한이 없어도 접근 권한 목록을 관리할 수 있는지. 워크스페이스 소유자가 참입니다."}},"required":["accessLimited","accessManageAllowed","createdAt","id","name","ownerNames","status","workspaceName"]},"VmSshKeyStatus":{"type":"object","description":"이 VM에 대한 내 SSH 키 발급 여부","properties":{"key":{"anyOf":[{"$ref":"#/components/schemas/VmSshKeyView"},{"type":"null"}],"description":"발급된 키. 아직 발급받지 않았으면 null"}}},"RrdTimeframe":{"type":"string","enum":["HOUR","DAY","WEEK","MONTH","YEAR"]},"VmMetricPointResponse":{"type":"object","properties":{"time":{"type":"string","format":"date-time"},"cpu":{"type":["number","null"],"format":"double","description":"할당된 vCPU 전체를 1.0으로 본 사용률 (0~1)"},"memBytes":{"type":["integer","null"],"format":"int64","description":"게스트 내부 기준 메모리 사용량(바이트). 게스트 에이전트가 보고하지 않으면 하이퍼바이저 관점 값으로 대체됩니다."},"memHostBytes":{"type":["integer","null"],"format":"int64","description":"하이퍼바이저 관점 메모리 사용량(바이트) — 게스트 페이지 캐시 포함."},"maxmemBytes":{"type":["integer","null"],"format":"int64"},"netinBps":{"type":["number","null"],"format":"double"},"netoutBps":{"type":["number","null"],"format":"double"},"diskReadBps":{"type":["number","null"],"format":"double"},"diskWriteBps":{"type":["number","null"],"format":"double"}},"required":["time"]},"VmMetricsResponse":{"type":"object","properties":{"timeframe":{"type":"string"},"fetchedAt":{"type":"string","format":"date-time"},"available":{"type":"boolean"},"unavailableReason":{"type":["string","null"],"description":"NOT_PROVISIONED = 아직 프로비저닝되지 않았거나 삭제된 VM"},"points":{"type":"array","items":{"$ref":"#/components/schemas/VmMetricPointResponse"}}},"required":["available","fetchedAt","points","timeframe"]},"PageResponseVmEventResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/VmEventResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"VmActorKind":{"type":"string","enum":["SYSTEM","MEMBER","ADMIN","UNKNOWN"]},"VmEventResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"$ref":"#/components/schemas/VmEventType"},"actorKind":{"$ref":"#/components/schemas/VmActorKind"},"actorId":{"type":["string","null"],"format":"uuid"},"actorName":{"type":["string","null"]},"detail":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["actorKind","createdAt","id","type"]},"VmEventType":{"type":"string","enum":["GPU_ATTACH","GPU_DETACH","CREATE","START","STOP","REBOOT","FORCE_STOP","DELETE","SELF_DELETE","FORCE_DELETE","REINSTALL","SCHEDULE_DELETE","CANCEL_SCHEDULED_DELETE","PUBLISH","UNPUBLISH","EXPIRE_STOP","PERIOD_UPDATE","GATEWAY_BLOCK","GATEWAY_UNBLOCK","PORT_FORWARD_CREATE","PORT_FORWARD_DELETE"]},"ResourceAccessListResponse":{"type":"object","description":"리소스 접근 권한 목록과, 그 목록이 어느 리소스의 것인지 알려 주는 최소 정보","properties":{"resource":{"$ref":"#/components/schemas/ResourceBrief","description":"이 목록이 속한 리소스"},"grants":{"type":"array","description":"접근 권한 항목","items":{"$ref":"#/components/schemas/ResourceAccessGrantView"}}},"required":["grants","resource"]},"ResourceBrief":{"type":"object","description":"접근 권한이 없는 사람에게도 보이는 범위의 리소스 정보","properties":{"id":{"type":"string","format":"uuid"},"type":{"$ref":"#/components/schemas/ResourceType"},"name":{"type":"string"},"displayName":{"type":["string","null"],"description":"표시명. 지정되지 않았으면 null입니다."},"status":{"type":"string","description":"리소스 종류의 상태값. 종류마다 어휘가 다릅니다."},"workspaceId":{"type":"string","format":"uuid"},"workspaceName":{"type":"string"}},"required":["id","name","status","type","workspaceId","workspaceName"]},"PageResponseResourceSummaryResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/ResourceSummaryResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"ResourceSummaryResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"$ref":"#/components/schemas/ResourceType"},"name":{"type":"string"},"displayName":{"type":["string","null"]},"status":{"type":"string"},"workspaceId":{"type":"string","format":"uuid"},"workspaceName":{"type":"string"},"accessLimited":{"type":"boolean"},"ownerNames":{"type":"array","items":{"type":"string"}},"accessManageAllowed":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}},"required":["accessLimited","accessManageAllowed","createdAt","id","name","ownerNames","status","type","workspaceId","workspaceName"]},"PageResponseRequestDetailResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/RequestDetailResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"RequestPeriodResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"기간 항목 식별자"},"displayName":{"type":"string","description":"화면에 보이는 이름","example":"2026학년도 1학기"},"endDate":{"type":"string","format":"date","description":"이 기간의 종료일","example":"2026-06-30"}},"required":["displayName","endDate","id"]},"OsImageResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"displayName":{"type":"string"},"osFamily":{"type":"string"},"osVersion":{"type":"string"},"sshUsername":{"type":"string"},"version":{"type":"integer","format":"int32"},"minDiskGb":{"type":"integer","format":"int32"},"status":{"$ref":"#/components/schemas/CatalogStatus"},"notes":{"type":["string","null"]}},"required":["displayName","id","minDiskGb","name","osFamily","osVersion","sshUsername","status","version"]},"OrgSummaryResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/OrgStatus"},"hidden":{"type":"boolean"}},"required":["hidden","id","name","status"]},"PageResponseNotificationView":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/NotificationView"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"UnreadCountResponse":{"type":"object","properties":{"unreadCount":{"type":"integer","format":"int64"}},"required":["unreadCount"]},"NoticeView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"body":{"type":"string"},"pinned":{"type":"boolean","description":"목록 상단 고정 여부"},"popup":{"type":"boolean","description":"콘솔이 모달로 띄울 공지인지. 이 공지가 로그인 없이도 보이는지도 같은 값이 정합니다."},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":["string","null"],"format":"date-time","description":"게시 종료 시각. 비어 있으면 만료되지 않습니다."},"images":{"type":"array","items":{"$ref":"#/components/schemas/NoticeImageView"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["body","createdAt","id","images","pinned","popup","startsAt","title","updatedAt"]},"PageResponseNoticeView":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/NoticeView"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"TermsDocumentView":{"type":"object","properties":{"docType":{"$ref":"#/components/schemas/TermsDocType"},"version":{"type":"integer","format":"int32"},"title":{"type":"string"},"body":{"type":"string"},"effectiveAt":{"type":"string","format":"date-time"}},"required":["body","docType","effectiveAt","title","version"]},"SystemStatusResponse":{"type":"object","properties":{"maintenance":{"type":"boolean"},"maintenanceMessage":{"type":["string","null"]},"bannerMessage":{"type":["string","null"]},"contactEmail":{"type":["string","null"]}},"required":["maintenance"]},"RequestOptionsResponse":{"type":"object","properties":{"allowedRootDomains":{"type":"array","items":{"type":"string"}},"reservedSubdomains":{"type":"array","items":{"type":"string"}},"sshHost":{"type":"string"}},"required":["allowedRootDomains","reservedSubdomains","sshHost"]},"DepartmentView":{"type":"object","properties":{"code":{"type":"string"},"college":{"type":"string"},"name":{"type":"string"}},"required":["code","college","name"]},"PositionView":{"type":"object","properties":{"code":{"type":"string"},"label":{"type":"string"},"requiresStudentNo":{"type":"boolean"}},"required":["code","label","requiresStudentNo"]},"ProfileOptionsResponse":{"type":"object","properties":{"positions":{"type":"array","items":{"$ref":"#/components/schemas/PositionView"}},"departments":{"type":"array","items":{"$ref":"#/components/schemas/DepartmentView"}}},"required":["departments","positions"]},"ActivityEntryResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"활동 행의 공개 식별자. 목록 렌더링용 키이며 어떤 조회 파라미터도 아닙니다."},"action":{"type":"string"},"targetType":{"type":["string","null"]},"targetId":{"type":["string","null"]},"detail":{},"ip":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["action","createdAt","id"]},"PageResponseActivityEntryResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/ActivityEntryResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"LlmKeySummaryResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","description":"키 이름"},"purpose":{"type":["string","null"],"description":"용도. 접근 권한이 없으면 생략됩니다."},"status":{"$ref":"#/components/schemas/LlmApiKeyStatus"},"tokenPrefix":{"type":["string","null"],"description":"평문 앞부분 — 목록에서 두 키를 구별하기 위한 값입니다. 접근 권한이 없거나 아직 발급 전이면 생략됩니다."},"expiresAt":{"type":["string","null"],"format":"date-time","description":"만료 시각. null이면 만료가 없습니다. 접근 권한이 없으면 생략됩니다."},"lastUsedAt":{"type":["string","null"],"format":"date-time","description":"마지막 사용 시각. 게이트웨이가 배치로 보고하므로 지연될 수 있습니다. 접근 권한이 없으면 생략됩니다."},"rpm":{"type":["integer","null"],"format":"int32","description":"분당 요청 한도. null이면 게이트웨이 기본값을 따릅니다. 접근 권한이 없으면 생략됩니다."},"tpm":{"type":["integer","null"],"format":"int32","description":"분당 토큰 한도. null이면 게이트웨이 기본값을 따릅니다. 접근 권한이 없으면 생략됩니다."},"concurrency":{"type":["integer","null"],"format":"int32","description":"동시 요청 한도. null이면 게이트웨이 기본값을 따릅니다. 접근 권한이 없으면 생략됩니다."},"recordBodies":{"type":["boolean","null"],"description":"프롬프트·응답 본문 기록 여부. 접근 권한이 없으면 생략됩니다."},"workspaceId":{"type":["string","null"],"format":"uuid","description":"소유 워크스페이스. 행이 사라진 경우에만 null입니다."},"workspaceName":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"accessLimited":{"type":"boolean","description":"true면 이 키의 접근 권한이 없어 이름·상태·소유자만 표시됩니다."},"ownerNames":{"type":"array","description":"이 키의 소유자 이름. 접근을 요청할 상대입니다.","items":{"type":"string"}},"accessManageAllowed":{"type":"boolean","description":"접근 권한이 없어도 접근 권한 목록을 관리할 수 있는지. 워크스페이스 소유자가 참입니다."}},"required":["accessLimited","accessManageAllowed","createdAt","id","name","ownerNames","status","workspaceName"]},"PageResponseLlmKeySummaryResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/LlmKeySummaryResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"LlmKeyDetailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","description":"키 이름"},"purpose":{"type":["string","null"],"description":"용도"},"status":{"$ref":"#/components/schemas/LlmApiKeyStatus"},"tokenPrefix":{"type":["string","null"],"description":"평문 앞부분 — 두 키를 구별하기 위한 값입니다. 아직 발급 전이면 null입니다."},"expiresAt":{"type":["string","null"],"format":"date-time","description":"만료 시각. null이면 만료가 없습니다."},"lastUsedAt":{"type":["string","null"],"format":"date-time","description":"마지막 사용 시각. 게이트웨이가 배치로 보고하므로 지연될 수 있습니다."},"rpm":{"type":["integer","null"],"format":"int32","description":"분당 요청 한도. null이면 게이트웨이 기본값을 따릅니다."},"tpm":{"type":["integer","null"],"format":"int32","description":"분당 토큰 한도. null이면 게이트웨이 기본값을 따릅니다."},"concurrency":{"type":["integer","null"],"format":"int32","description":"동시 요청 한도. null이면 게이트웨이 기본값을 따릅니다."},"dailyTokens":{"type":["integer","null"],"format":"int64","description":"일일 토큰 한도. null이면 일일 한도가 없고, 0이면 자체 서빙 모델을 쓸 수 없습니다."},"recordBodies":{"type":"boolean","description":"프롬프트·응답 본문 기록 여부"},"creditLimit":{"type":"number","description":"유료 모델 한도, USD 크레딧. 0이면 유료 모델을 쓸 수 없습니다."},"creditLimitReset":{"anyOf":[{"$ref":"#/components/schemas/CreditLimitReset"},{"type":"null"}],"description":"금액 한도 리셋 창. null이면 리셋 없는 총액 상한입니다. 창은 UTC 자정 기준입니다."},"creditAxisConnected":{"type":"boolean","description":"유료 모델 사용 가능 여부. 금액 한도가 부여됐지만 아직 연결 전이면 false입니다."},"creditAllowedModels":{"type":"array","description":"이 키가 쓸 수 있는 유료 모델 목록. 빈 배열이면 제한이 없습니다. 자체 서빙 모델은 이 목록과 무관하게 쓸 수 있습니다. 항목은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 공급자 *는 ~별칭도 포함하고, 특정 공급자의 허용은 ~별칭을 별도로 적어야 합니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"}},"creditDeniedModels":{"type":"array","description":"이 키가 쓸 수 없는 유료 모델 목록. 빈 배열이면 차단이 없습니다. 허용 목록과 함께 걸리면 차단이 이깁니다. 항목은 허용 목록과 같은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 차단은 ~를 제거한 이름도 검사하며, 별칭의 실제 대상 모델은 추적하지 않습니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"}},"passthroughEndpoints":{"type":"array","description":"이 키에 부여된 기능 권한. 빈 배열이면 기능을 하나도 쓸 수 없습니다. 모델 목록 둘과 반대로 이 목록은 채워야 열립니다. 채팅과 모델 조회는 이 목록과 무관합니다.","items":{"type":"string","enum":["images","embeddings"]}},"workspaceId":{"type":["string","null"],"format":"uuid","description":"소유 워크스페이스. 행이 사라진 경우에만 null입니다."},"workspaceName":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"revokedAt":{"type":["string","null"],"format":"date-time","description":"회수된 시각. 회수되지 않았으면 null입니다."},"myResourceRole":{"anyOf":[{"$ref":"#/components/schemas/ResourceRole"},{"type":"null"}],"description":"요청자가 이 키의 접근 목록에서 받은 등급"},"accessManageAllowed":{"type":"boolean","description":"접근 권한 목록을 관리할 수 있는지"}},"required":["accessManageAllowed","createdAt","creditAllowedModels","creditAxisConnected","creditDeniedModels","creditLimit","id","name","passthroughEndpoints","recordBodies","status","workspaceName"]},"LlmKeyBudgetResponse":{"type":"object","properties":{"dailyTokens":{"type":["integer","null"],"format":"int64","description":"하루에 쓸 수 있는 토큰 수. null이면 한도가 없고, 0이면 자체 서빙 모델을 쓸 수 없습니다."},"todayTokens":{"type":"integer","format":"int64","description":"오늘(KST) 자체 서빙 모델에 쓴 입출력 토큰 합계. 유료 모델 사용은 금액 한도에 계상되므로 여기 들어가지 않습니다. 사용량 전송이 배치라 방금 쓴 만큼은 아직 반영되지 않았을 수 있습니다."},"quotaExhausted":{"type":"boolean","description":"한도에 도달해 자체 서빙 모델 요청이 거절되고 있는 상태."},"creditLimit":{"type":"number","description":"유료 모델에 쓸 수 있는 금액 한도(USD). 0이면 유료 모델을 쓸 수 없습니다."},"creditUsage":{"type":["number","null"],"description":"공급자가 보고한 현재 한도 창 사용액(USD). DAILY/WEEKLY/MONTHLY 리셋 뒤에는 감소할 수 있습니다. 아직 보고된 적이 없으면 null입니다."},"creditUsageAt":{"type":["string","null"],"format":"date-time","description":"그 한도 창 사용액을 읽어 온 시각. 30분마다 갱신됩니다."},"creditDepletionForecast":{"type":["string","null"],"format":"date","description":"최근 소비 속도로 금액 한도에 도달할 것으로 보이는 날짜. 이력이 부족하거나 최근에 쓴 적이 없으면 null입니다."}},"required":["creditLimit","quotaExhausted","todayTokens"]},"LlmKeyErrorTypeResponse":{"type":"object","properties":{"errorType":{"type":["string","null"],"description":"오류 종류. 게이트웨이가 종류를 남기지 않은 실패는 null이며, 화면에서는 '기타'로 묶입니다."},"requests":{"type":"integer","format":"int64"}},"required":["requests"]},"LlmKeyHourlyUsageResponse":{"type":"object","properties":{"weekday":{"type":"integer","format":"int32","description":"요일. 1=월요일 … 7=일요일(ISO), KST 기준."},"hour":{"type":"integer","format":"int32","description":"시각. 0~23, KST 기준."},"requests":{"type":"integer","format":"int64"}},"required":["hour","requests","weekday"]},"LlmKeyLatencyResponse":{"type":"object","properties":{"p50Ms":{"type":"integer","format":"int64","description":"정상 응답 요청의 중앙값 응답 시간(ms)."},"p90Ms":{"type":"integer","format":"int64"},"p99Ms":{"type":"integer","format":"int64"},"samples":{"type":"integer","format":"int64","description":"백분위를 낸 요청 수. 표본이 적을수록 p99는 흔들립니다."}},"required":["p50Ms","p90Ms","p99Ms","samples"]},"LlmKeyModelUsageResponse":{"type":"object","properties":{"modelName":{"type":["string","null"],"description":"호출한 모델의 공개 이름. 모델이 정해지기 전에 실패한 요청은 null이며, 화면에서는 '모델 미상'으로 묶입니다."},"requests":{"type":"integer","format":"int64"},"succeeded":{"type":"integer","format":"int64"},"rateLimited":{"type":"integer","format":"int64"},"failed":{"type":"integer","format":"int64"},"inputTokens":{"type":"integer","format":"int64"},"outputTokens":{"type":"integer","format":"int64"},"estimatedRequests":{"type":"integer","format":"int64"},"avgLatencyMs":{"type":"integer","format":"int64","description":"이 모델 요청의 평균 응답 시간(ms). 실패와 거부까지 포함한 평균이라 정상 응답만 재는 백분위와는 다른 값입니다."},"attributedCostUsd":{"type":["number","null"],"description":"이 기간에 이 모델 요청에 공급자가 알려 준 금액(USD)의 합. 한도나 잔액과 견주는 값이 아니며, 가격이 붙지 않은 요청은 들어 있지 않습니다 (pricedRequests 참조). 가격이 붙은 요청이 하나도 없으면 null입니다."},"pricedRequests":{"type":"integer","format":"int64","description":"이 모델 요청 중 공급자가 금액을 알려 준 요청 수. requests보다 작으면 나머지는 금액을 모르는 것이지 공짜였던 것이 아닙니다."},"pricedInputTokens":{"type":"integer","format":"int64","description":"금액이 붙은 요청이 쓴 입력 토큰 수. 금액이 붙지 않은 요청의 입력 토큰은 inputTokens에서 이 값을 뺀 것입니다."},"pricedOutputTokens":{"type":"integer","format":"int64","description":"금액이 붙은 요청이 쓴 출력 토큰 수"},"pricedAvgLatencyMs":{"type":"integer","format":"int64","description":"금액이 붙은 요청만의 평균 응답 시간(ms). 그런 요청이 없으면 0입니다."},"unpricedAvgLatencyMs":{"type":"integer","format":"int64","description":"금액이 붙지 않은 요청만의 평균 응답 시간(ms). 그런 요청이 없으면 0입니다."},"pricedFailed":{"type":"integer","format":"int64","description":"금액이 붙은 요청 가운데 실패한 수."},"imageCount":{"type":"integer","format":"int64","description":"이 모델이 돌려준 이미지 수"}},"required":["avgLatencyMs","estimatedRequests","failed","imageCount","inputTokens","outputTokens","pricedAvgLatencyMs","pricedFailed","pricedInputTokens","pricedOutputTokens","pricedRequests","rateLimited","requests","succeeded","unpricedAvgLatencyMs"]},"LlmKeyUsagePointResponse":{"type":"object","properties":{"day":{"type":"string","format":"date"},"requests":{"type":"integer","format":"int64","description":"이 날 이 Key로 들어온 요청 수 — 거부된 것과 실패한 것을 포함합니다."},"succeeded":{"type":"integer","format":"int64","description":"정상 응답한 요청 수"},"rateLimited":{"type":"integer","format":"int64","description":"한도에 걸려 거부된 요청 수. 계속 0이 아니면 한도 상향을 신청할 때입니다."},"failed":{"type":"integer","format":"int64","description":"그 밖의 사유로 실패한 요청 수 (업스트림 오류, 시간 초과, 잘못된 요청 등)"},"inputTokens":{"type":"integer","format":"int64","description":"입력 토큰 합"},"outputTokens":{"type":"integer","format":"int64","description":"출력 토큰 합"},"estimatedRequests":{"type":"integer","format":"int64","description":"토큰 수가 실측이 아니라 추정인 요청 수. 스트리밍 응답에서 업스트림이 사용량을 주지 않으면 게이트웨이가 추정하므로, 이 값이 크면 위 토큰 합도 그만큼 추정입니다."},"cachedInputTokens":{"type":"integer","format":"int64","description":"입력 토큰 중 공급자가 캐시에서 읽어 처리한 몫. 입력 토큰의 부분집합이라 입력 토큰에 더하면 이중 계산입니다."},"reasoningTokens":{"type":"integer","format":"int64","description":"출력 토큰 중 모델이 답을 내기 전에 생각하는 데 쓴 몫. 출력 토큰의 부분집합이라 출력 토큰에 더하면 이중 계산입니다."},"imageCount":{"type":"integer","format":"int64","description":"이 날 응답으로 돌아온 이미지 수. 요청한 장수가 아니라 실제로 받은 장수이고, 이미지 생성이 아닌 요청은 여기에 아무것도 더하지 않습니다."},"streamedRequests":{"type":"integer","format":"int64","description":"스트리밍으로 받은 요청 수"}},"required":["cachedInputTokens","day","estimatedRequests","failed","imageCount","inputTokens","outputTokens","rateLimited","reasoningTokens","requests","streamedRequests","succeeded"]},"LlmKeyUsageTrendResponse":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"reportedUntil":{"type":["string","null"],"format":"date-time","description":"게이트웨이가 이 키의 사용량을 마지막으로 보고한 시각. 보고는 배치라 몇 분 늦을 수 있습니다. 보고가 한 번도 없었으면 null입니다."},"points":{"type":"array","description":"하루 한 점, 오래된 날부터","items":{"$ref":"#/components/schemas/LlmKeyUsagePointResponse"}},"models":{"type":"array","description":"이 기간에 실제로 호출된 모델만, 요청이 많은 순","items":{"$ref":"#/components/schemas/LlmKeyModelUsageResponse"}},"errorTypes":{"type":"array","description":"이 기간의 실패를 종류별로, 많은 순","items":{"$ref":"#/components/schemas/LlmKeyErrorTypeResponse"}},"latency":{"anyOf":[{"$ref":"#/components/schemas/LlmKeyLatencyResponse"},{"type":"null"}],"description":"정상 응답 요청의 응답 시간 백분위. 정상 응답이 없으면 null입니다."},"hourly":{"type":"array","description":"요일 x 시각(KST) 요청 분포. 요청이 있는 칸만 담깁니다.","items":{"$ref":"#/components/schemas/LlmKeyHourlyUsageResponse"}},"budget":{"$ref":"#/components/schemas/LlmKeyBudgetResponse","description":"기간이 아니라 현재 시점의 두 예산 축 상태"}},"required":["budget","errorTypes","from","hourly","models","points","to"]},"CatalogFreshness":{"type":"string","description":"목록 신선도","enum":["FRESH","STALE","UNKNOWN"]},"LlmKeyModelsResponse":{"type":"object","description":"이 LLM API 키로 호출할 수 있는 모델","properties":{"selfServed":{"type":"array","description":"자체 서빙 모델","items":{"$ref":"#/components/schemas/SelfServedModel"}},"paid":{"$ref":"#/components/schemas/PaidModels","description":"유료 모델"}},"required":["paid","selfServed"]},"PaidAccess":{"type":"string","description":"유료 모델 사용 가능 여부. LISTED는 허용 목록과 차단 목록 중 어느 쪽으로든 좁혀진 상태이고, UNRESTRICTED는 두 목록이 모두 비어 금액만이 경계인 상태입니다.","enum":["NONE","PENDING","UNRESTRICTED","LISTED"]},"PaidModel":{"type":"object","description":"유료 모델","properties":{"id":{"type":"string","description":"요청의 model 필드에 넣는 이름","example":"openai/gpt-5.6-luna"},"name":{"type":"string","description":"표시 이름"},"promptPricePerMillion":{"type":["number","null"],"description":"입력 100만 토큰당 USD. 모르면 비어 있습니다"},"completionPricePerMillion":{"type":["number","null"],"description":"출력 100만 토큰당 USD. 모르면 비어 있습니다"},"contextLength":{"type":["integer","null"],"format":"int32","description":"컨텍스트 길이. 모르면 비어 있습니다"}},"required":["id","name"]},"PaidModels":{"type":"object","description":"유료 모델과 그 목록의 상태","properties":{"access":{"$ref":"#/components/schemas/PaidAccess","description":"사용 가능 여부"},"allowedPatterns":{"type":"array","description":"이 키의 모델 허용 목록. 비어 있으면 허용 쪽 제한이 없습니다. 항목은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 공급자 *는 ~별칭도 포함하고, 특정 공급자의 허용은 ~별칭을 별도로 적어야 합니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"}},"deniedPatterns":{"type":"array","description":"이 키의 모델 차단 목록. 비어 있으면 차단하는 모델이 없습니다. 허용 목록과 함께 걸리면 차단이 이깁니다. 항목은 허용 목록과 같은 부호 없는 모델 패턴입니다. 공급자는 정확한 이름 또는 *만 사용할 수 있습니다(예: openai/*, */*-pro). 차단은 ~를 제거한 이름도 검사하며, 별칭의 실제 대상 모델은 추적하지 않습니다. 정확한 모델명은 :batch 같은 변형도 포함합니다. 목록별 최대 50개, 항목별 200바이트입니다.","items":{"type":"string"}},"models":{"type":"array","description":"호출할 수 있는 모델","items":{"$ref":"#/components/schemas/PaidModel"}},"unmatchedAllowedPatterns":{"type":"array","description":"허용 목록에 적혀 있지만 지금 목록에서 찾지 못한 이름. 목록에서 사라진 모델이나 아직 없는 이름, 제한된 키에서 호출할 수 없는 라우터도 포함됩니다.","items":{"type":"string"}},"unmatchedDeniedPatterns":{"type":"array","description":"차단 목록에 적혀 있지만 지금 목록에서 찾지 못한 이름. 현재 캐시의 모델명과 별칭 중 이 패턴으로 차단되는 것이 없다는 뜻이며, 아직 나오지 않은 모델을 미리 막아 둔 경우에도 여기에 나옵니다.","items":{"type":"string"}},"catalogFreshness":{"$ref":"#/components/schemas/CatalogFreshness","description":"목록의 신선도"},"catalogObservedAt":{"type":["string","null"],"format":"date-time","description":"목록을 마지막으로 가져온 시각. 한 번도 성공하지 못했으면 비어 있습니다"}},"required":["access","allowedPatterns","catalogFreshness","deniedPatterns","models","unmatchedAllowedPatterns","unmatchedDeniedPatterns"]},"SelfServedModel":{"type":"object","description":"자체 서빙 모델","properties":{"name":{"type":"string","description":"요청의 model 필드에 넣는 이름","example":"pickle-general"},"maxInputTokens":{"type":["integer","null"],"format":"int32","description":"최대 입력 토큰. 상한이 없으면 비어 있습니다"},"maxOutputTokens":{"type":["integer","null"],"format":"int32","description":"최대 출력 토큰. 상한이 없으면 비어 있습니다"}},"required":["name"]},"LlmKeyBodySummaryResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"eventUuid":{"type":"string","description":"이 기록과 같은 요청에서 나온 사용량 이벤트의 식별자입니다. 리소스 id가 아니라 두 기록을 잇는 값이고, 클라이언트 로그와 대조할 때 씁니다."},"requestedAt":{"type":"string","format":"date-time","description":"요청 시각. 게이트웨이가 보고한 값입니다."},"receivedAt":{"type":"string","format":"date-time","description":"이 기록이 서버에 도착한 시각"},"requestTruncated":{"type":"boolean","description":"프롬프트가 길이 제한에 걸려 앞부분만 기록됐는지 여부"},"responseTruncated":{"type":"boolean","description":"응답이 길이 제한에 걸려 앞부분만 기록됐는지 여부"},"requestBytes":{"type":"integer","format":"int32","description":"기록된 프롬프트의 바이트 수"},"responseBytes":{"type":"integer","format":"int32","description":"기록된 응답의 바이트 수"},"readable":{"type":"boolean","description":"false면 이 기록을 푸는 암호화 키가 서버에 없어 본문을 읽을 수 없습니다. 미리보기도 null입니다."},"requestPreview":{"type":["string","null"],"description":"프롬프트 앞부분. 읽을 수 없거나 기록되지 않았으면 null입니다."},"responsePreview":{"type":["string","null"],"description":"응답 앞부분. 읽을 수 없거나 기록되지 않았으면 null입니다."}},"required":["eventUuid","id","readable","receivedAt","requestBytes","requestTruncated","requestedAt","responseBytes","responseTruncated"]},"PageResponseLlmKeyBodySummaryResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/LlmKeyBodySummaryResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"LlmKeyBodyDetailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"eventUuid":{"type":"string","description":"이 기록과 같은 요청에서 나온 사용량 이벤트의 식별자입니다."},"requestedAt":{"type":"string","format":"date-time"},"receivedAt":{"type":"string","format":"date-time"},"requestTruncated":{"type":"boolean","description":"프롬프트가 길이 제한에 걸려 앞부분만 기록됐는지 여부"},"responseTruncated":{"type":"boolean","description":"응답이 길이 제한에 걸려 앞부분만 기록됐는지 여부"},"requestBytes":{"type":"integer","format":"int32"},"responseBytes":{"type":"integer","format":"int32"},"readable":{"type":"boolean","description":"false면 이 기록을 푸는 암호화 키가 서버에 없어 본문을 읽을 수 없습니다."},"request":{"description":"보낸 프롬프트. 보통은 messages 배열 그대로이고, 길이 제한에 걸린 경우에는 앞부분을 담은 문자열입니다. 기록되지 않았으면 null입니다."},"response":{"type":["string","null"],"description":"받은 응답 텍스트. 기록되지 않았으면 null입니다."}},"required":["eventUuid","id","readable","receivedAt","requestBytes","requestTruncated","requestedAt","responseBytes","responseTruncated"]},"PageResponseGpuAllocationView":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/GpuAllocationView"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"GpuAttachmentOption":{"type":"object","properties":{"vmId":{"type":"string","format":"uuid"},"vmName":{"type":"string"},"nodeId":{"type":"string","format":"uuid"},"ready":{"type":"boolean"},"reason":{"type":["string","null"]}},"required":["nodeId","ready","vmId","vmName"]},"DomainSummaryView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"vmId":{"type":"string","format":"uuid"},"kind":{"$ref":"#/components/schemas/DomainKind"},"fqdn":{"type":"string"},"rootDomain":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/DomainStatus"},"verifiedAt":{"type":["string","null"],"format":"date-time"},"releasedAt":{"type":["string","null"],"format":"date-time"},"reservedUntil":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"dnsStatus":{"$ref":"#/components/schemas/DomainDnsStatus"},"dnsLastError":{"type":["string","null"]},"dnsAppliedAt":{"type":["string","null"],"format":"date-time"}},"required":["createdAt","dnsStatus","fqdn","id","kind","status","vmId"]},"PageResponseDomainSummaryView":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/DomainSummaryView"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"PageResponseDnsDomainView":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/DnsDomainView"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"AdminWorkspaceOptionResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"memberCount":{"type":"integer","format":"int64"},"kind":{"$ref":"#/components/schemas/WorkspaceKind"},"createdAt":{"type":"string","format":"date-time"}},"required":["createdAt","id","kind","memberCount","name"]},"AdminWorkspaceDetailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"$ref":"#/components/schemas/WorkspaceKind"},"name":{"type":"string"},"description":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"memberCount":{"type":"integer","format":"int64"},"vmCount":{"type":"integer","format":"int64"},"members":{"type":"array","items":{"$ref":"#/components/schemas/AdminWorkspaceMemberResponse"}}},"required":["createdAt","id","kind","memberCount","members","name","vmCount"]},"AdminWorkspaceMemberResponse":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string"},"workspaceRole":{"$ref":"#/components/schemas/WorkspaceMemberRole"},"userStatus":{"$ref":"#/components/schemas/UserStatus"},"joinedAt":{"type":"string","format":"date-time"}},"required":["email","joinedAt","name","userId","userStatus","workspaceRole"]},"PageResponseUserAdminViewResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/UserAdminViewResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"UserAdminViewResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"name":{"type":"string"},"role":{"$ref":"#/components/schemas/UserRole"},"managedOrgs":{"type":"array","items":{"$ref":"#/components/schemas/ManagedOrgResponse"}},"status":{"$ref":"#/components/schemas/UserStatus"},"mfaEnabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}},"required":["createdAt","email","id","managedOrgs","mfaEnabled","name","role","status"]},"TerminalSessionView":{"type":"object","properties":{"sessionId":{"type":"string"},"vmId":{"type":"string","format":"uuid"},"vmName":{"type":"string"},"orgId":{"type":"string","format":"uuid"},"orgName":{"type":"string"},"workspaceName":{"type":"string"},"userId":{"type":"string","format":"uuid"},"userEmail":{"type":"string"},"userName":{"type":"string"},"clientIp":{"type":"string"},"startedAt":{"type":"string","format":"date-time"}},"required":["clientIp","orgId","orgName","sessionId","startedAt","userEmail","userId","userName","vmId","vmName","workspaceName"]},"AdminTaskResponse":{"type":"object","properties":{"taskId":{"type":"string","format":"uuid"},"vmId":{"type":"string","format":"uuid"},"vmName":{"type":["string","null"]},"hostname":{"type":["string","null"]},"orgId":{"type":["string","null"],"format":"uuid"},"orgName":{"type":["string","null"]},"workspaceName":{"type":["string","null"]},"kind":{"$ref":"#/components/schemas/ProvisioningTaskKind"},"status":{"$ref":"#/components/schemas/ProvisioningTaskStatus"},"currentStep":{"type":"integer","format":"int32"},"totalSteps":{"type":"integer","format":"int32"},"stepLabel":{"type":"string"},"attempts":{"type":"integer","format":"int32"},"lastError":{"type":["string","null"]},"jobrunrJobId":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["attempts","createdAt","currentStep","kind","status","stepLabel","taskId","totalSteps","updatedAt","vmId"]},"PageResponseAdminTaskResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/AdminTaskResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"IpPoolUsage":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"cidr":{"type":"string"},"allocatedCount":{"type":"integer","format":"int64"},"freeCount":{"type":"integer","format":"int64"}},"required":["allocatedCount","cidr","freeCount","id","name"]},"LiveCoverage":{"type":"object","properties":{"nodeCount":{"type":"integer","format":"int32","description":"nodesLive 행 수 (플랫폼 전체 노드 수)"},"memoryMeasuredNodeCount":{"type":"integer","format":"int32","description":"메모리 측정값이 있는 노드 수 — nodeCount보다 작으면 메모리 합계는 부분 측정"},"storageMeasuredNodeCount":{"type":"integer","format":"int32","description":"스토리지 측정값이 있는 노드 수 — nodeCount보다 작으면 스토리지 합계는 부분 측정"}},"required":["memoryMeasuredNodeCount","nodeCount","storageMeasuredNodeCount"]},"NodeLiveResponse":{"type":"object","properties":{"nodeId":{"type":"string","format":"uuid"},"name":{"type":"string"},"reachable":{"type":"boolean","description":"true = 이 노드가 상태 조회에 응답함. false = 응답하지 않음이며 나머지 필드는 모두 null. true여도 스토리지 조회는 별도 권한이라 storage* 필드는 null일 수 있음"},"memTotalBytes":{"type":["integer","null"],"format":"int64"},"memUsedBytes":{"type":["integer","null"],"format":"int64"},"cpu":{"type":["number","null"],"format":"double"},"storageTotalBytes":{"type":["integer","null"],"format":"int64"},"storageUsedBytes":{"type":["integer","null"],"format":"int64"},"checkedAt":{"type":["string","null"],"format":"date-time"}},"required":["name","nodeId","reachable"]},"NodeRatio":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"$ref":"#/components/schemas/NodeStatus"},"cpuOvercommitRatio":{"type":"number","format":"double"},"memoryAllocRatio":{"type":"number","format":"double"},"warn":{"type":"boolean"}},"required":["cpuOvercommitRatio","id","memoryAllocRatio","name","status","warn"]},"SystemDashboardSummaryResponse":{"type":"object","properties":{"nodes":{"type":"array","items":{"$ref":"#/components/schemas/NodeRatio"}},"vmCountsByStatus":{"type":"object","additionalProperties":{"type":"integer","format":"int64"}},"tasks":{"$ref":"#/components/schemas/Tasks"},"notificationFailureCount":{"type":"integer","format":"int64"},"certExpiring30dCount":{"type":"integer","format":"int64"},"openDriftFindingCount":{"type":"integer","format":"int64"},"sshPasswordEnabledVmCount":{"type":"integer","format":"int64"},"ipPools":{"type":"array","items":{"$ref":"#/components/schemas/IpPoolUsage"}},"nodesLive":{"type":"array","items":{"$ref":"#/components/schemas/NodeLiveResponse"}},"liveCoverage":{"$ref":"#/components/schemas/LiveCoverage"}},"required":["certExpiring30dCount","ipPools","liveCoverage","nodes","nodesLive","notificationFailureCount","openDriftFindingCount","sshPasswordEnabledVmCount","tasks","vmCountsByStatus"]},"Tasks":{"type":"object","properties":{"runningCount":{"type":"integer","format":"int64"},"retryingCount":{"type":"integer","format":"int64"},"needsAdminCount":{"type":"integer","format":"int64"},"failed24hCount":{"type":"integer","format":"int64"}},"required":["failed24hCount","needsAdminCount","retryingCount","runningCount"]},"Attention":{"type":"object","properties":{"failedTaskCount":{"type":"integer","format":"int64"},"needsAdminVmCount":{"type":"integer","format":"int64"},"expiredVmCount":{"type":"integer","format":"int64"}},"required":["expiredVmCount","failedTaskCount","needsAdminVmCount"]},"OrgDashboardSummaryResponse":{"type":"object","properties":{"pendingRequestCount":{"type":"integer","format":"int64"},"recentDecisions14d":{"$ref":"#/components/schemas/RecentDecisions"},"vmCountsByStatus":{"type":"object","additionalProperties":{"type":"integer","format":"int64"}},"resource":{"$ref":"#/components/schemas/Resource"},"topWorkspacesByVmCount":{"type":"array","items":{"$ref":"#/components/schemas/TopWorkspace"}},"publishedServiceCount":{"type":"integer","format":"int64"},"expiringVmCount30d":{"type":"integer","format":"int64"},"attention":{"$ref":"#/components/schemas/Attention"}},"required":["attention","expiringVmCount30d","pendingRequestCount","publishedServiceCount","recentDecisions14d","resource","topWorkspacesByVmCount","vmCountsByStatus"]},"RecentDecisions":{"type":"object","properties":{"approvedCount":{"type":"integer","format":"int64"},"rejectedCount":{"type":"integer","format":"int64"}},"required":["approvedCount","rejectedCount"]},"Resource":{"type":"object","properties":{"allocatedVcpu":{"type":"integer","format":"int64"},"allocatedMemoryMb":{"type":"integer","format":"int64"},"allocatedDiskGb":{"type":"integer","format":"int64"},"capacityVcpu":{"type":["integer","null"],"format":"int64"},"capacityMemoryMb":{"type":["integer","null"],"format":"int64"},"capacityDiskGb":{"type":["integer","null"],"format":"int64","description":"ACTIVE 노드의 thin pool 용량 합(GB) — 용량 미등록 노드가 있으면 null"},"guidance":{"type":"string"}},"required":["allocatedDiskGb","allocatedMemoryMb","allocatedVcpu","guidance"]},"TopWorkspace":{"type":"object","properties":{"workspaceId":{"type":"string","format":"uuid"},"name":{"type":"string"},"vmCount":{"type":"integer","format":"int64"}},"required":["name","vmCount","workspaceId"]},"AdminRouteView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"domainId":{"type":"string","format":"uuid"},"fqdn":{"type":"string"},"domainKind":{"$ref":"#/components/schemas/DomainKind"},"vmId":{"type":"string","format":"uuid"},"vmName":{"type":"string"},"workspaceId":{"type":"string","format":"uuid"},"workspaceName":{"type":"string"},"orgId":{"type":"string","format":"uuid"},"orgName":{"type":"string"},"targetPort":{"type":"integer","format":"int32"},"protocol":{"type":"string"},"status":{"$ref":"#/components/schemas/RouteStatus"},"appliedGeneration":{"type":["integer","null"],"format":"int64"},"appliedAt":{"type":["string","null"],"format":"date-time"},"lastError":{"type":["string","null"]},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["domainId","domainKind","fqdn","id","orgId","orgName","protocol","status","targetPort","vmId","vmName","workspaceId","workspaceName"]},"PageResponseAdminRouteView":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/AdminRouteView"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"Applicant":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string"},"signupAt":{"type":"string","format":"date-time"},"approvedCount":{"type":"integer","format":"int64"},"rejectedCount":{"type":"integer","format":"int64"}},"required":["approvedCount","email","id","name","rejectedCount","signupAt"]},"ApprovalContextResponse":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/ResourceType"},"applicant":{"$ref":"#/components/schemas/Applicant"},"applicantResources":{"$ref":"#/components/schemas/Resources","deprecated":true},"workspace":{"$ref":"#/components/schemas/WorkspacePanel"},"history":{"type":"array","items":{"$ref":"#/components/schemas/HistoryEntry"}},"orgHeadroom":{"$ref":"#/components/schemas/OrgHeadroom","deprecated":true},"guidance":{"type":"string","deprecated":true},"vm":{"anyOf":[{"$ref":"#/components/schemas/VmContext"},{"type":"null"}]},"llmKey":{"anyOf":[{"$ref":"#/components/schemas/LlmKeyContext"},{"type":"null"}]},"gpu":{"anyOf":[{"$ref":"#/components/schemas/GpuContext"},{"type":"null"}]},"domain":{"anyOf":[{"$ref":"#/components/schemas/DomainContext"},{"type":"null"}]}},"required":["applicant","applicantResources","guidance","history","orgHeadroom","type","workspace"]},"Capacity":{"type":"object","properties":{"cpuThreads":{"type":"integer","format":"int64"},"memoryMb":{"type":"integer","format":"int64"},"diskGb":{"type":["integer","null"],"format":"int64","description":"ACTIVE 노드의 thin pool 용량 합(GB) — 용량 미등록 노드가 있으면 null"}},"required":["cpuThreads","memoryMb"]},"DomainContext":{"type":"object","properties":{"fqdn":{"type":"string"},"available":{"type":"boolean"},"held":{"type":"integer","format":"int64"},"cap":{"type":"integer","format":"int32"}},"required":["available","cap","fqdn","held"]},"GpuContext":{"type":"object","properties":{"availableCards":{"type":"integer","format":"int64"},"queuedAllocations":{"type":"integer","format":"int64"},"requestedLeaseHours":{"type":"integer","format":"int32"},"vmName":{"type":["string","null"]}},"required":["availableCards","queuedAllocations","requestedLeaseHours"]},"HistoryEntry":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid"},"type":{"$ref":"#/components/schemas/ResourceType"},"resourceName":{"type":"string"},"submittedAt":{"type":"string","format":"date-time"},"status":{"$ref":"#/components/schemas/RequestStatus"},"decision":{"anyOf":[{"$ref":"#/components/schemas/ReviewDecision"},{"type":"null"}]},"comment":{"type":["string","null"]},"reviewerName":{"type":["string","null"]}},"required":["requestId","resourceName","status","submittedAt","type"]},"LlmKeyBrief":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"workspaceId":{"type":["string","null"],"format":"uuid"},"workspaceName":{"type":"string"},"status":{"$ref":"#/components/schemas/LlmApiKeyStatus"},"expiresAt":{"type":["string","null"],"format":"date-time"},"rpm":{"type":["integer","null"],"format":"int32"},"tpm":{"type":["integer","null"],"format":"int32"},"concurrency":{"type":["integer","null"],"format":"int32"},"dailyTokens":{"type":["integer","null"],"format":"int64"},"creditLimit":{"type":"number"},"creditLimitReset":{"anyOf":[{"$ref":"#/components/schemas/CreditLimitReset"},{"type":"null"}]},"creditAxisConnected":{"type":"boolean"}},"required":["creditAxisConnected","creditLimit","id","name","status","workspaceName"]},"LlmKeyContext":{"type":"object","properties":{"applicantKeys":{"type":"array","items":{"$ref":"#/components/schemas/LlmKeyBrief"}},"workspaceKeys":{"type":"array","items":{"$ref":"#/components/schemas/LlmKeyBrief"}}},"required":["applicantKeys","workspaceKeys"]},"MemberBrief":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"name":{"type":"string"},"role":{"$ref":"#/components/schemas/WorkspaceMemberRole"}},"required":["name","role","userId"]},"OrgHeadroom":{"type":"object","properties":{"allocated":{"$ref":"#/components/schemas/ResourceTotalsResponse"},"capacity":{"$ref":"#/components/schemas/Capacity"},"vcpuOvercommitRatio":{"type":"number","format":"double"},"memoryUsageRatio":{"type":"number","format":"double"},"diskUsageRatio":{"type":["number","null"],"format":"double","description":"할당 디스크 / thin pool 용량 — 용량 미등록 노드가 있으면 null. 오버프로비저닝 전제라 1을 넘을 수 있고 경고 임계값은 없습니다."},"warnings":{"type":"array","items":{"type":"string"}}},"required":["allocated","capacity","memoryUsageRatio","vcpuOvercommitRatio","warnings"]},"ResourceTotalsResponse":{"type":"object","properties":{"vcpu":{"type":"integer","format":"int32"},"memoryMb":{"type":"integer","format":"int64"},"diskGb":{"type":"integer","format":"int64"}},"required":["diskGb","memoryMb","vcpu"]},"Resources":{"type":"object","properties":{"activeVms":{"type":"array","items":{"$ref":"#/components/schemas/VmBriefResponse"}},"totals":{"$ref":"#/components/schemas/ResourceTotalsResponse"}},"required":["activeVms","totals"]},"VmBriefResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"$ref":"#/components/schemas/VmStatus"},"vcpu":{"type":"integer","format":"int32"},"memoryMb":{"type":"integer","format":"int32"},"diskGb":{"type":"integer","format":"int32"},"endDate":{"type":["string","null"],"format":"date"}},"required":["diskGb","id","memoryMb","name","status","vcpu"]},"VmContext":{"type":"object","properties":{"applicantResources":{"$ref":"#/components/schemas/Resources","deprecated":true},"workspaceResources":{"$ref":"#/components/schemas/Resources"},"orgHeadroom":{"$ref":"#/components/schemas/OrgHeadroom","deprecated":true},"guidance":{"type":"string"}},"required":["applicantResources","guidance","orgHeadroom","workspaceResources"]},"WorkspacePanel":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"kind":{"$ref":"#/components/schemas/WorkspaceKind"},"members":{"type":"array","items":{"$ref":"#/components/schemas/MemberBrief"}},"activeVms":{"type":"array","deprecated":true,"description":"호환용 VM 목록. 새 클라이언트는 vm.workspaceResources.activeVms를 사용합니다.","items":{"$ref":"#/components/schemas/VmBriefResponse"}},"totals":{"$ref":"#/components/schemas/ResourceTotalsResponse","deprecated":true,"description":"호환용 VM 합계. 새 클라이언트는 vm.workspaceResources.totals를 사용합니다."}},"required":["activeVms","id","kind","members","name","totals"]},"AdminRelayView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"publicHost":{"type":["string","null"],"description":"사용자 접속용 공개 호스트 (설정 전이면 null)"},"bandStart":{"type":"integer","format":"int32","description":"공개 포트 대역 시작"},"bandEnd":{"type":"integer","format":"int32","description":"공개 포트 대역 끝"},"enabled":{"type":"boolean"},"tokenIssued":{"type":"boolean","description":"동기화 토큰 발급 여부 (미발급이면 에이전트 인증이 항상 실패)"},"mappingGeneration":{"type":"integer","format":"int64","description":"현재 매핑 세대 (매핑 변경마다 증가)"},"appliedGeneration":{"type":"integer","format":"int64","description":"에이전트가 적용을 확인한 마지막 세대"},"lastContactAt":{"type":["string","null"],"format":"date-time"},"contactLost":{"type":"boolean","description":"접촉 두절 여부 (마지막 동기화가 폴링 주기 3배를 초과)"},"agentVersion":{"type":["string","null"]},"lastError":{"type":["string","null"],"description":"에이전트가 보고한 마지막 적용 오류(JSON, 정화됨). 없으면 null"},"mappingCount":{"type":"integer","format":"int64","description":"이 릴레이의 매핑 수"},"bandUsagePercent":{"type":"integer","format":"int32","description":"공개 포트 대역 사용률(%)"}},"required":["appliedGeneration","bandEnd","bandStart","bandUsagePercent","contactLost","enabled","id","mappingCount","mappingGeneration","name","tokenIssued"]},"PageResponseAdminPortMappingResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/AdminPortMappingResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"NotificationStatus":{"type":"string","enum":["PENDING","SENT","FAILED","SKIPPED"]},"AdminNotificationResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"event":{"type":"string"},"title":{"type":"string"},"body":{"type":"string"},"linkPath":{"type":["string","null"]},"importance":{"$ref":"#/components/schemas/NotificationImportance"},"createdAt":{"type":"string","format":"date-time"},"readAt":{"type":["string","null"],"format":"date-time"},"userId":{"type":"string","format":"uuid"},"userEmail":{"type":"string"},"channel":{"$ref":"#/components/schemas/NotificationChannel"},"status":{"$ref":"#/components/schemas/NotificationStatus"},"attempts":{"type":"integer","format":"int32"},"lastError":{"type":["string","null"]},"sentAt":{"type":["string","null"],"format":"date-time"}},"required":["attempts","body","channel","createdAt","event","id","importance","status","title","userEmail","userId"]},"NotificationChannel":{"type":"string","enum":["EMAIL"]},"PageResponseAdminNotificationResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/AdminNotificationResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"PageResponseAdminNoticeView":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/AdminNoticeView"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"NodeMetricPointResponse":{"type":"object","properties":{"time":{"type":"string","format":"date-time"},"cpu":{"type":["number","null"],"format":"double","description":"노드 전체 스레드를 1.0으로 본 사용률 (0~1)"},"iowait":{"type":["number","null"],"format":"double"},"loadavg":{"type":["number","null"],"format":"double"},"memTotalBytes":{"type":["integer","null"],"format":"int64"},"memUsedBytes":{"type":["integer","null"],"format":"int64"},"swapTotalBytes":{"type":["integer","null"],"format":"int64"},"swapUsedBytes":{"type":["integer","null"],"format":"int64"},"rootTotalBytes":{"type":["integer","null"],"format":"int64"},"rootUsedBytes":{"type":["integer","null"],"format":"int64","description":"노드 루트 파일시스템 사용량 — 게스트 디스크가 사는 thin pool은 스토리지 상태 값으로 따로 제공"},"netinBps":{"type":["number","null"],"format":"double"},"netoutBps":{"type":["number","null"],"format":"double"}},"required":["time"]},"NodeMetricsResponse":{"type":"object","properties":{"timeframe":{"type":"string"},"fetchedAt":{"type":"string","format":"date-time"},"points":{"type":"array","items":{"$ref":"#/components/schemas/NodeMetricPointResponse"}}},"required":["fetchedAt","points","timeframe"]},"AdminLlmUsageResponse":{"type":"object","properties":{"generatedAt":{"type":"string","format":"date-time"},"timezone":{"type":"string","description":"모든 일자 경계와 오늘 사용량에 적용한 시간대"},"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"days":{"type":"integer","format":"int32"},"demand":{"$ref":"#/components/schemas/LlmUsageDemandResponse"},"consumers":{"$ref":"#/components/schemas/LlmUsageConsumersResponse"},"breakdown":{"$ref":"#/components/schemas/LlmUsageBreakdownResponse","description":"같은 기간을 「무엇을」로 자른 셋. 모델별, 경로별, 그리고 기능 권한이 실제로 쓰이고 있는지입니다."},"limitReview":{"$ref":"#/components/schemas/LlmLimitReviewCollectionResponse"},"quality":{"$ref":"#/components/schemas/LlmUsageQualityResponse"}},"required":["breakdown","consumers","days","demand","from","generatedAt","limitReview","quality","timezone","to"]},"LlmEndpointKindUsageResponse":{"type":"object","properties":{"endpoint":{"type":["string","null"],"description":"요청이 들어온 경로. 값은 게이트웨이가 정하는 열린 어휘이고, null은 「기타」가 아니라 이 축이 기록되기 전의 요청입니다."},"requests":{"type":"integer","format":"int64"},"succeeded":{"type":"integer","format":"int64"},"rateLimited":{"type":"integer","format":"int64","description":"한도에 걸려 거부된 요청 수. failed와 겹치지 않습니다 — 셋을 더하면 requests가 됩니다."},"failed":{"type":"integer","format":"int64","description":"한도 거부가 **아닌** 사유로 실패한 요청 수. 한도 거부를 여기 넣지 않는 것은 집계 표와 같은 가름이라야 같은 이름이 두 숫자를 뜻하지 않기 때문입니다."},"inputTokens":{"type":"integer","format":"int64"},"outputTokens":{"type":"integer","format":"int64"},"attributedCostUsd":{"type":["number","null"],"description":"이 경로가 쓴 금액(USD). 가격이 붙은 요청이 없으면 null입니다."},"pricedRequests":{"type":"integer","format":"int64","description":"이 경로 요청 중 공급자가 금액을 알려 준 요청 수"},"creditAxisRequests":{"type":"integer","format":"int64","description":"이 경로 요청 중 유료 모델로 나간 요청 수. 한 경로에는 두 축이 섞이므로 금액이 빠진 건수를 세려면 전체 요청이 아니라 이 값에서 빼야 합니다. 자체 서빙 요청에는 금액이라는 것이 아예 없으므로, 전체 요청에서 빼면 자체 서빙까지 「금액을 모르는 요청」으로 세게 됩니다."},"imageCount":{"type":"integer","format":"int64","description":"이 경로가 돌려준 이미지 수"}},"required":["creditAxisRequests","failed","imageCount","inputTokens","outputTokens","pricedRequests","rateLimited","requests","succeeded"]},"LlmGatewayReportState":{"type":"string","enum":["NOT_REPORTED","FRESH","STALE"]},"LlmLimitPressureResponse":{"type":"object","properties":{"reason":{"type":"string","enum":["quota_exhausted","credit_exhausted","rate_limit_requests","rate_limit_tokens","rate_limit_concurrency"]},"requests":{"type":"integer","format":"int64"}},"required":["reason","requests"]},"LlmLimitReviewCollectionResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LlmLimitReviewResponse"}},"totalItems":{"type":"integer","format":"int64"},"truncated":{"type":"boolean"}},"required":["items","totalItems","truncated"]},"LlmLimitReviewResponse":{"type":"object","properties":{"keyId":{"type":"string","format":"uuid"},"keyName":{"type":"string"},"orgId":{"type":"string","format":"uuid"},"orgName":{"type":"string"},"workspaceId":{"type":"string","format":"uuid"},"workspaceName":{"type":"string"},"status":{"$ref":"#/components/schemas/LlmApiKeyStatus"},"dailyTokens":{"type":["integer","null"],"format":"int64"},"todayTokens":{"type":"integer","format":"int64"},"todayUnknownAxisTokens":{"type":"integer","format":"int64","description":"요청 당시 budget axis가 보고되지 않은 오늘 입력+출력 token"},"quotaExhausted":{"type":"boolean"},"creditLimit":{"type":"number"},"creditLimitReset":{"anyOf":[{"$ref":"#/components/schemas/CreditLimitReset"},{"type":"null"}]},"creditUsage":{"type":["number","null"]},"creditLimitRemaining":{"type":["number","null"]},"creditUsageAt":{"type":["string","null"],"format":"date-time"},"creditAxisConnected":{"type":"boolean"},"openrouterAccountId":{"type":["string","null"],"format":"uuid","description":"연결된 사업 계정. 연결 전이면 null"},"openrouterAccountName":{"type":["string","null"]},"pressure":{"type":"array","items":{"$ref":"#/components/schemas/LlmLimitPressureResponse"}}},"required":["creditAxisConnected","creditLimit","keyId","keyName","orgId","orgName","pressure","quotaExhausted","status","todayTokens","todayUnknownAxisTokens","workspaceId","workspaceName"]},"LlmUsageBreakdownResponse":{"type":"object","properties":{"models":{"type":"array","description":"이 기간에 실제로 호출된 모델만, 요청이 많은 순","items":{"$ref":"#/components/schemas/LlmUsageModelBreakdownResponse"}},"endpointKinds":{"type":"array","description":"이 기간에 실제로 들어온 경로만, 요청이 많은 순","items":{"$ref":"#/components/schemas/LlmEndpointKindUsageResponse"}},"passthroughGrants":{"type":"array","description":"기능 권한 값마다 한 줄. 부여만 되고 안 쓰이는 것이 보입니다.","items":{"$ref":"#/components/schemas/LlmUsagePassthroughGrantResponse"}}},"required":["endpointKinds","models","passthroughGrants"]},"LlmUsageConsumerLevel":{"type":"string","enum":["ORG","WORKSPACE","KEY"]},"LlmUsageConsumerResponse":{"type":"object","properties":{"orgId":{"type":["string","null"],"format":"uuid"},"orgName":{"type":["string","null"]},"workspaceId":{"type":["string","null"],"format":"uuid"},"workspaceName":{"type":["string","null"]},"keyId":{"type":["string","null"],"format":"uuid"},"keyName":{"type":["string","null"]},"requests":{"type":"integer","format":"int64"},"inputTokens":{"type":"integer","format":"int64"},"outputTokens":{"type":"integer","format":"int64"},"meteredCostUsd":{"type":["number","null"],"description":"이 소비처가 이 기간에 쓴 금액(USD)으로, 공급자가 키마다 보고한 사용액에서 이 기간의 몫만 뽑은 값입니다. 요청마다 더한 `attributedCostUsd`와 달리 요청별 금액이 없던 시기의 지출도 들어 있으므로, 소비처 단위 금액은 이 값을 씁니다. 대사가 30분 주기라 방금 쓴 만큼은 아직 안 보이고, 그 시각은 `meteredObservedAt`이 말합니다. 유료 모델을 쓰지 않는 소비처나 아직 한 번도 대사되지 않은 소비처는 null입니다."},"attributedCostUsd":{"type":["number","null"],"description":"이 소비처의 금액을 요청마다 더한 값(USD). 모델별 표가 쓰는 것과 같은 출처이고, 요청별 금액이 기록되기 전의 지출은 빠져 있습니다. 소비처 표는 `meteredCostUsd`를 쓰므로 이 값은 두 출처를 견줄 때만 씁니다. 가격이 붙은 요청이 하나도 없으면 null이며 0으로 표시하지 않습니다."},"pricedRequests":{"type":"integer","format":"int64","description":"이 소비처의 요청 중 공급자가 금액을 알려 준 요청 수"},"creditAxisRequests":{"type":"integer","format":"int64","description":"이 소비처의 요청 중 유료 모델로 나간 요청 수. **한 행이 여러 모델을 묶는 표에서** 금액이 빠진 건수를 세려면 전체 요청이 아니라 이 값에서 빼야 합니다. 자체 서빙 요청에는 금액이라는 것이 아예 없으므로, 전체 요청에서 빼면 자체 서빙까지 「금액을 모르는 요청」으로 세게 됩니다. 모델별 표는 다릅니다 — 거기서는 한 모델을 두 행으로 나누고 그 둘이 모델의 요청을 남김없이 갈라야 하므로 가격 기준으로 자릅니다."},"meteredObservedAt":{"type":["string","null"],"format":"date-time","description":"이 소비처의 키 가운데 가장 오래된 공급자 대사 시각. 「여기 있는 금액은 적어도 이 시점까지의 것」이라는 뜻이라 가장 최근 시각을 쓰지 않습니다. 금액이 없으면 null입니다."}},"required":["creditAxisRequests","inputTokens","outputTokens","pricedRequests","requests"]},"LlmUsageConsumersResponse":{"type":"object","properties":{"level":{"$ref":"#/components/schemas/LlmUsageConsumerLevel"},"items":{"type":"array","items":{"$ref":"#/components/schemas/LlmUsageConsumerResponse"}},"totalItems":{"type":"integer","format":"int64"},"truncated":{"type":"boolean"}},"required":["items","level","totalItems","truncated"]},"LlmUsageDailyPointResponse":{"type":"object","properties":{"day":{"type":"string","format":"date"},"requests":{"type":"integer","format":"int64"},"inputTokens":{"type":"integer","format":"int64"},"outputTokens":{"type":"integer","format":"int64"},"estimatedRequests":{"type":"integer","format":"int64"},"tokenAxisRequests":{"type":"integer","format":"int64"},"creditAxisRequests":{"type":"integer","format":"int64"},"unknownAxisRequests":{"type":"integer","format":"int64"},"axisCoverage":{"type":["number","null"],"format":"double","description":"요청 당시 TOKEN/CREDIT 축이 기록된 request 비율. 요청이 없으면 null"}},"required":["creditAxisRequests","day","estimatedRequests","inputTokens","outputTokens","requests","tokenAxisRequests","unknownAxisRequests"]},"LlmUsageDemandResponse":{"type":"object","properties":{"windows":{"type":"array","items":{"$ref":"#/components/schemas/LlmUsageWindowResponse"}},"daily":{"type":"array","items":{"$ref":"#/components/schemas/LlmUsageDailyPointResponse"}}},"required":["daily","windows"]},"LlmUsageModelBreakdownResponse":{"type":"object","properties":{"modelName":{"type":["string","null"],"description":"호출한 모델의 공개 이름. 모델이 정해지기 전에 실패한 요청은 null이며 화면에서는 「모델 미상」으로 묶입니다."},"requests":{"type":"integer","format":"int64"},"failed":{"type":"integer","format":"int64"},"inputTokens":{"type":"integer","format":"int64"},"outputTokens":{"type":"integer","format":"int64"},"attributedCostUsd":{"type":["number","null"],"description":"이 모델이 쓴 금액(USD). 가격이 붙은 요청이 없으면 null입니다."},"pricedRequests":{"type":"integer","format":"int64","description":"이 모델 요청 중 공급자가 금액을 알려 준 요청 수"},"creditAxisRequests":{"type":"integer","format":"int64","description":"이 모델의 요청 중 유료 모델로 나간 요청 수. 모델 하나는 자체 서빙이거나 유료거나 하나이므로 이 값은 사실상 0 아니면 requests 이고, **화면은 이것을 「이 모델에 유료 트래픽이 있었나」로만 씁니다.** 금액이 빠진 건수를 여기서 빼지 않습니다 — 이 표는 한 모델을 두 행으로 나누고 그 둘이 모델의 요청을 남김없이 갈라야 해서, 가격 기준(requests - pricedRequests)으로 자릅니다."},"pricedInputTokens":{"type":"integer","format":"int64","description":"금액이 붙은 요청이 쓴 입력 토큰 수. 화면이 이 모델을 「금액 확인」과 「금액 미상」 두 행으로 나누어 각 행의 토큰을 보여 주기 위한 값이고, 미상 쪽 토큰은 전체에서 이 값을 빼서 얻습니다. 알려진 단가로 모르는 쪽을 추정하려면 두 토큰 수가 갈려 있어야 합니다."},"pricedOutputTokens":{"type":"integer","format":"int64","description":"금액이 붙은 요청이 쓴 출력 토큰 수"},"avgLatencyMs":{"type":"integer","format":"int64","description":"평균 응답 시간(ms). 일별 집계의 합을 요청 수로 나눈 값이라 백분위는 낼 수 없습니다. 백분위가 필요하면 키 상세로 갑니다. 이 모델 전체 기준입니다."},"pricedAvgLatencyMs":{"type":"integer","format":"int64","description":"금액이 붙은 요청만의 평균 응답 시간(ms). 그런 요청이 없으면 0입니다."},"unpricedAvgLatencyMs":{"type":"integer","format":"int64","description":"금액이 붙지 않은 요청만의 평균 응답 시간(ms). 화면이 이 모델을 두 행으로 나눌 때 각 행이 자기 요청의 값을 갖게 하려고 서버가 나눕니다 — 한 값을 두 행에 되풀이하면 행마다 다른 요청 수를 갖고도 같은 응답 시간을 말하게 됩니다. 그런 요청이 없으면 0입니다."},"pricedFailed":{"type":"integer","format":"int64","description":"금액이 붙은 요청 가운데 실패한 수. 게이트웨이가 응답을 정산할 때만 금액을 쓰므로 실제로는 언제나 0이지만, 그 불변식은 다른 레포의 동작이라 세어서 보냅니다. 화면이 이 모델을 두 행으로 나눌 때 각 행의 실패율을 가정이 아니라 자료에서 냅니다."}},"required":["avgLatencyMs","creditAxisRequests","failed","inputTokens","outputTokens","pricedAvgLatencyMs","pricedFailed","pricedInputTokens","pricedOutputTokens","pricedRequests","requests","unpricedAvgLatencyMs"]},"LlmUsagePassthroughGrantResponse":{"type":"object","properties":{"capability":{"type":"string","description":"기능 권한 값. images 또는 embeddings입니다."},"grantedKeys":{"type":"integer","format":"int64","description":"지금 이 기능을 부여받은 키 수"},"usedKeys":{"type":"integer","format":"int64","description":"이 기간에 이 기능이 여는 경로를 실제로 호출한 키 수. **grantedKeys의 부분집합이 아닙니다** — 부여는 지금 상태이고 호출은 지나간 사실이라, 쓰고 나서 권한이 회수된 키가 여기에만 남아 grantedKeys보다 클 수 있습니다. 호출한 쪽을 부여로 걸러 내지 않는 것은 그렇게 하면 그 요청이 아래 requests 에는 있고 이 수에는 없어 두 칸이 서로를 반박하기 때문입니다."},"requests":{"type":"integer","format":"int64","description":"이 기능이 여는 경로들로 들어온 요청 수"}},"required":["capability","grantedKeys","requests","usedKeys"]},"LlmUsageQualityResponse":{"type":"object","description":"사용량 숫자의 source와 delivery 상태. latestUsageReceivedAt은 API가 마지막으로 event를 받은 시각일 뿐 completeness watermark가 아닙니다. Gateway queue와 loss 수치는 전역 값이며 SYS가 기관으로 좁혀도 전역이고, ORG에는 null입니다.","properties":{"rollupLastSuccessAt":{"type":["string","null"],"format":"date-time"},"latestUsageReceivedAt":{"type":["string","null"],"format":"date-time","description":"API가 마지막 usage event를 받은 시각. Completeness watermark가 아님"},"creditMetersTotal":{"type":"integer","format":"int64","description":"양수 credit limit을 가진 key 수"},"creditMetersObserved":{"type":"integer","format":"int64","description":"양수 credit limit key 중 vendor meter 관측 이력이 있는 수"},"oldestCreditUsageAt":{"type":["string","null"],"format":"date-time"},"latestCreditUsageAt":{"type":["string","null"],"format":"date-time"},"totalRequests":{"type":"integer","format":"int64"},"estimatedRequests":{"type":"integer","format":"int64"},"estimatedRequestRatio":{"type":["number","null"],"format":"double"},"totalTokens":{"type":"integer","format":"int64"},"estimatedTokens":{"type":["integer","null"],"format":"int64","description":"Estimated input+output token. 원본이 없는 bucket이 섞이면 null"},"estimatedTokenRatio":{"type":["number","null"],"format":"double"},"gatewayReportState":{"$ref":"#/components/schemas/LlmGatewayReportState"},"usageQueueReportState":{"$ref":"#/components/schemas/LlmGatewayReportState"},"lastContactAt":{"type":["string","null"],"format":"date-time"},"lastUsageShipSuccessAt":{"type":["string","null"],"format":"date-time"},"usageQueueObservedAt":{"type":["string","null"],"format":"date-time"},"oldestUnshippedEventAt":{"type":["string","null"],"format":"date-time"},"queuedUsageEvents":{"type":["integer","null"],"format":"int64"},"queuedUsageBytes":{"type":["integer","null"],"format":"int64"},"spoolWriteFailures":{"type":["integer","null"],"format":"int64"},"usageShipFailures":{"type":["integer","null"],"format":"int64"},"usageQueueScanFailures":{"type":["integer","null"],"format":"int64"},"unattributedRequests":{"type":["integer","null"],"format":"int64","description":"Key에 귀속되지 않은 selected-window request 수. SYS global에서만 값이 있음"},"pricedRequests":{"type":"integer","format":"int64","description":"이 기간 요청 중 공급자가 금액을 알려 준 수. 자체 서빙 요청은 금액이라는 것이 없어 여기 들어가지 않으므로, 이 값이 작은 것 자체는 결함이 아닙니다. **totalRequests와 견주지 마십시오** — 그 비율은 「금액을 못 받은 비율」이 아니라 자체 서빙 비중을 함께 담습니다. 이 요약 층에는 유료 요청 수가 없고, 그것이 필요하면 소비처와 호출 종류 행의 creditAxisRequests를 씁니다."},"endpointRecordedRequests":{"type":"integer","format":"int64","description":"이 기간 요청 중 들어온 경로가 기록된 수. 경로 축은 2026-09-06에 생겼으므로 그 전 요청은 여기 들어가지 않고, 경로별 분해도 그만큼 덜 덮습니다."}},"required":["creditMetersObserved","creditMetersTotal","endpointRecordedRequests","estimatedRequests","gatewayReportState","pricedRequests","totalRequests","totalTokens","usageQueueReportState"]},"LlmUsageWindowResponse":{"type":"object","properties":{"days":{"type":"integer","format":"int32"},"requests":{"type":"integer","format":"int64"},"inputTokens":{"type":"integer","format":"int64"},"outputTokens":{"type":"integer","format":"int64"},"estimatedRequests":{"type":"integer","format":"int64"},"tokenAxisRequests":{"type":"integer","format":"int64"},"creditAxisRequests":{"type":"integer","format":"int64"},"unknownAxisRequests":{"type":"integer","format":"int64"},"axisCoverage":{"type":["number","null"],"format":"double","description":"요청 당시 TOKEN/CREDIT 축이 기록된 request 비율. 요청이 없으면 null"}},"required":["creditAxisRequests","days","estimatedRequests","inputTokens","outputTokens","requests","tokenAxisRequests","unknownAxisRequests"]},"LlmActiveObservationResponse":{"type":"object","description":"gateway의 out-of-band /models probe 최신 결과. routing과 cooldown을 바꾸지 않으며 마지막 시도가 intervalSeconds의 3배보다 오래되면 availability에는 UNKNOWN으로 반영됩니다.","properties":{"lastAttemptAt":{"type":["string","null"],"format":"date-time","description":"마지막 probe 시도 시각. 아직 시도하지 않았으면 null"},"lastSuccessAt":{"type":["string","null"],"format":"date-time","description":"마지막 probe 성공 시각. 성공 이력이 없으면 null"},"lastFailureAt":{"type":["string","null"],"format":"date-time","description":"마지막 probe 실패 시각. 실패 이력이 없으면 null"},"status":{"$ref":"#/components/schemas/LlmActiveProbeStatus","description":"마지막으로 보고된 raw probe 결과. freshness가 만료돼도 값 자체는 OK로 남을 수 있으며, 현재 상태는 lastAttemptAt·intervalSeconds를 직접 재해석하지 말고 top-level availability를 사용. AUTH_UNVERIFIED는 도달했지만 인증 여부를 확인하지 못한 상태"},"failureType":{"type":["string","null"],"description":"최신 probe 실패 분류. 실패가 아니면 null"},"intervalSeconds":{"type":["integer","null"],"format":"int32","description":"이 upstream의 probe 주기(초). 마지막 시도 freshness 판정의 기준"},"stale":{"type":"boolean","description":"마지막 probe 시도가 intervalSeconds의 3배보다 오래됐는지 서버가 계산한 값. 미관측 UNKNOWN은 false"},"latencyMs":{"type":["integer","null"],"format":"int64","description":"최신 probe 응답 시간(ms). 측정값이 없으면 null"},"modelCount":{"type":["integer","null"],"format":"int32","description":"성공한 /models 응답의 모델 수. 성공했고 빈 목록이면 0, 성공 이력이 없으면 null"},"consecutiveFailures":{"type":["integer","null"],"format":"int32","description":"연속 probe 실패 수. 보고되지 않았으면 null"}},"required":["stale","status"]},"LlmActiveProbeStatus":{"type":"string","enum":["OK","AUTH_UNVERIFIED","FAILED","UNKNOWN"]},"LlmCatalogObservationResponse":{"type":"object","description":"설정 catalog와 성공한 /models 응답의 비교. 오래된 비교 결과는 availability를 낮추지 않습니다.","properties":{"status":{"$ref":"#/components/schemas/LlmCatalogStatus","description":"catalog 비교 상태. expected set이 없는 passthrough upstream은 NOT_APPLICABLE"},"expectedModelCount":{"type":["integer","null"],"format":"int32","description":"비교한 기대 모델 수. 비교하지 않았으면 null"},"missingModelCount":{"type":["integer","null"],"format":"int32","description":"기대했지만 /models 응답에 없던 모델 수. MATCH/MISMATCH에서 없으면 0, 비교하지 않았으면 null"},"unexpectedModelCount":{"type":["integer","null"],"format":"int32","description":"/models 응답에만 있던 예상 밖 모델 수. curated non-passthrough 비교에서 없으면 0, passthrough subset 비교·미비교 상태에서는 null"},"missingPublicModels":{"type":"array","description":"누락된 public model 이름 표본(최대 20개). SYS 계층에만 반환하며 ORG에서는 항상 빈 배열","items":{"type":"string"}}},"required":["missingPublicModels","status"]},"LlmCatalogStatus":{"type":"string","enum":["MATCH","MISMATCH","NOT_APPLICABLE","UNKNOWN"]},"LlmGatewayStatusResponse":{"type":"object","description":"LLM gateway heartbeat와 usage 전송 상태. reportState, usageQueueReportState와 lastContactAt은 모든 관리자에게 보입니다. Queue 수치와 loss counter를 포함한 나머지 진단 필드는 SYS 계층에만 값이 있고 ORG 계층에서는 null입니다.","properties":{"reportState":{"$ref":"#/components/schemas/LlmGatewayReportState","description":"5초 sync heartbeat의 보고 신선도"},"usageQueueReportState":{"$ref":"#/components/schemas/LlmGatewayReportState","description":"usage queue 관측 신선도. 관측 시각 없음은 NOT_REPORTED, 10분 초과는 STALE, 그 이하는 FRESH"},"desiredGeneration":{"type":["integer","null"],"format":"int64","description":"API가 제공하려는 authorization document 세대. SYS 전용이며 ORG에서는 null"},"appliedGeneration":{"type":["integer","null"],"format":"int64","description":"gateway가 적용했다고 보고한 세대. SYS 전용이며 미보고·ORG에서는 null"},"supportedFormat":{"type":["integer","null"],"format":"int32","description":"gateway가 지원하는 authorization document 형식. SYS 전용이며 미보고·ORG에서는 null"},"agentVersion":{"type":["string","null"],"description":"gateway binary 버전. SYS 전용이며 구 gateway·ORG에서는 null"},"startedAt":{"type":["string","null"],"format":"date-time","description":"gateway 프로세스 시작 시각. SYS 전용이며 미보고·ORG에서는 null"},"inFlight":{"type":["integer","null"],"format":"int32","description":"gateway가 보고한 처리 중 요청 수. SYS 전용이며 ORG에서는 null"},"maxInFlight":{"type":["integer","null"],"format":"int32","description":"gateway 동시 처리 상한. SYS 전용이며 미보고·ORG에서는 null"},"rejectedEntries":{"type":["integer","null"],"format":"int32","description":"authorization 문서에서 거절한 항목의 누적 수. SYS 전용이며 구 gateway·ORG에서는 null"},"reloadFailures":{"type":["integer","null"],"format":"int64","description":"authorization reload 실패 누적 수. SYS 전용이며 구 gateway·ORG에서는 null"},"lastError":{"type":["string","null"],"description":"gateway가 보고한 마지막 오류 요약. SYS 전용이며 없거나 ORG이면 null"},"bodiesDropped":{"type":["integer","null"],"format":"int64","description":"본문 전달 포기 누적 수. SYS 전용이며 구 gateway·ORG에서는 null"},"usageShipFailures":{"type":["integer","null"],"format":"int64","description":"usage batch 전송 실패 누적 수. SYS 전용이며 구 gateway·ORG에서는 null"},"spoolWriteFailures":{"type":["integer","null"],"format":"int64","description":"usage event spool 기록 실패 누적 수. SYS 전용이며 구 gateway·ORG에서는 null"},"lastContactAt":{"type":["string","null"],"format":"date-time","description":"API가 마지막 sync 요청을 받은 시각. 한 번도 접촉하지 않았으면 null"},"lastUsageShipSuccessAt":{"type":["string","null"],"format":"date-time","description":"마지막 usage 전송 성공 시각. SYS 전용이며 성공 이력 없음·ORG에서는 null"},"oldestUnshippedEventAt":{"type":["string","null"],"format":"date-time","description":"미전송 queue에서 가장 오래된 event 시각. SYS 전용이며 빈 queue·미관측·ORG에서는 null"},"queuedUsageEvents":{"type":["integer","null"],"format":"int64","description":"usage queue event 수. SYS 전용이며 관측 시각이 있으면 빈 queue는 0, 미관측·ORG에서는 null"},"queuedUsageBytes":{"type":["integer","null"],"format":"int64","description":"usage queue byte 수. SYS 전용이며 관측 시각이 있으면 빈 queue는 0, 미관측·ORG에서는 null"},"usageQueueObservedAt":{"type":["string","null"],"format":"date-time","description":"usage queue를 마지막으로 온전히 조사한 시각. SYS 전용이며 구 gateway·ORG에서는 null"},"usageQueueScanFailures":{"type":["integer","null"],"format":"int64","description":"usage queue 조사 실패 누적 수. SYS 전용이며 관측 시각이 있으면 실패 없음은 0, 미관측·ORG에서는 null"}},"required":["reportState","usageQueueReportState"]},"LlmPassiveObservationResponse":{"type":"object","description":"실제 사용자 요청에서 얻은 passive 관측. lastAttemptAt은 표시용이며, 가용성 판정은 최근 15분 안의 lastSuccessAt·lastFailureAt만 사용합니다.","properties":{"lastAttemptAt":{"type":["string","null"],"format":"date-time","description":"마지막 실제 요청 시도 시각. key-local 거절·취소도 포함하므로 상태 판정에는 사용하지 않음"},"lastSuccessAt":{"type":["string","null"],"format":"date-time","description":"마지막 upstream 성공 시각. 15분이 지나면 현재 health 근거로 사용하지 않음"},"lastFailureAt":{"type":["string","null"],"format":"date-time","description":"마지막 health-impacting upstream 실패 시각. 15분이 지나면 현재 health 근거로 사용하지 않음"},"lastFailureType":{"type":["string","null"],"description":"마지막 health-impacting 실패 분류. 실패 이력이 없으면 null"},"consecutiveFailures":{"type":["integer","null"],"format":"int32","description":"연속 health-impacting 실패 수. 보고되지 않았으면 null"},"cooldownUntil":{"type":["string","null"],"format":"date-time","description":"실제 요청 실패로 생긴 routing cooldown 종료 시각. cooldown이 없으면 null"}}},"LlmStatusResponse":{"type":"object","properties":{"observedAt":{"type":"string","format":"date-time"},"gateway":{"$ref":"#/components/schemas/LlmGatewayStatusResponse"},"upstreams":{"type":"array","items":{"$ref":"#/components/schemas/LlmUpstreamStatusResponse"}}},"required":["gateway","observedAt","upstreams"]},"LlmUpstreamAvailability":{"type":"string","enum":["UNKNOWN","HEALTHY","DEGRADED","UNAVAILABLE"]},"LlmUpstreamKind":{"type":"string","enum":["ON_PREM","EXTERNAL_API"]},"LlmUpstreamReportState":{"type":"string","enum":["OK","NOT_REPORTED","MISSING","STALE","DECONFIGURED","UNREGISTERED"]},"LlmUpstreamStatusResponse":{"type":"object","description":"upstream 등록 정보와 gateway의 최신 현재 상태. ORG 응답은 허용 범위의 upstream만 포함하며 내부 ref·소유 기관 ID를 숨깁니다.","properties":{"id":{"type":["string","null"],"format":"uuid","description":"upstream 등록 공개 ID. gateway에만 있고 등록되지 않은 ref면 null"},"ref":{"type":["string","null"],"description":"gateway 내부 ref. SYS 계층에만 반환하며 ORG에서는 null"},"name":{"type":"string"},"kind":{"anyOf":[{"$ref":"#/components/schemas/LlmUpstreamKind"},{"type":"null"}],"description":"등록된 upstream 종류. 미등록 ref면 null"},"orgId":{"type":["string","null"],"format":"uuid","description":"소유 기관 공개 ID. SYS 계층의 기관 소유 upstream에만 있고 shared·미등록·ORG에서는 null"},"dedicated":{"type":["boolean","null"],"description":"기관 전용 여부. 미등록 ref면 null"},"enabled":{"type":["boolean","null"],"description":"등록부의 운영 활성 여부. 미등록 ref면 null"},"configured":{"type":"boolean","description":"format 1 최신 gateway 목록에 포함됐는지. 구 gateway 보고에는 기존 값을 보존"},"reportState":{"$ref":"#/components/schemas/LlmUpstreamReportState","description":"등록부와 versioned gateway 보고의 관계 및 신선도"},"availability":{"$ref":"#/components/schemas/LlmUpstreamAvailability","description":"신선한 active·passive·catalog 관측을 합성한 현재 가용성"},"lastReportedAt":{"type":["string","null"],"format":"date-time","description":"이 upstream 관측 행을 마지막으로 받은 시각. 아직 보고되지 않았으면 null"},"passive":{"$ref":"#/components/schemas/LlmPassiveObservationResponse"},"active":{"$ref":"#/components/schemas/LlmActiveObservationResponse"},"catalog":{"$ref":"#/components/schemas/LlmCatalogObservationResponse"}},"required":["active","availability","catalog","configured","name","passive","reportState"]},"OpenRouterCatalogueModel":{"type":"object","description":"카탈로그의 모델 한 건.","properties":{"id":{"type":"string","description":"허용 목록에 그대로 넣을 수 있는 모델 이름."},"name":{"type":"string","description":"벤더가 표시하는 이름."},"promptPricePerMillion":{"type":["number","null"],"description":"백만 토큰당 입력 가격(USD). 모르면 비어 있고, 0은 무료를 뜻합니다."},"completionPricePerMillion":{"type":["number","null"],"description":"백만 토큰당 출력 가격(USD). 모르면 비어 있고, 0은 무료를 뜻합니다."},"contextLength":{"type":["integer","null"],"format":"int32","description":"컨텍스트 길이(토큰)."}},"required":["id","name"]},"OpenRouterCatalogueResponse":{"type":"object","description":"OpenRouter 모델 카탈로그 캐시. 승인 화면의 모델 선택 후보이며, 이 목록이 비어 있어도 모델 이름을 직접 입력할 수 있습니다.","properties":{"models":{"type":"array","description":"캐시에 남아 있는 모델. 벤더 목록에서 사라진 모델은 제외됩니다.","items":{"$ref":"#/components/schemas/OpenRouterCatalogueModel"}},"freshness":{"$ref":"#/components/schemas/OpenRouterCreditsFreshness","description":"마지막 성공 기준 신선도. 갱신 주기의 세 배를 넘기면 STALE, 성공한 적이 없으면 UNKNOWN입니다."},"lastSuccessAt":{"type":["string","null"],"format":"date-time","description":"마지막으로 벤더 목록을 성공적으로 가져온 시각."},"lastAttemptAt":{"type":["string","null"],"format":"date-time","description":"마지막 갱신 시도 시각. 실패해도 갱신됩니다."},"lastError":{"type":["string","null"],"description":"마지막 실패의 분류. 성공했다면 비어 있습니다. 벤더 응답 본문은 담지 않습니다."},"consecutiveFailures":{"type":"integer","format":"int32","description":"연속 실패 횟수. 0이면 마지막 시도가 성공했습니다."}},"required":["consecutiveFailures","freshness","models"]},"LlmLocalRejectionMetricResponse":{"type":"object","properties":{"errorType":{"type":"string"},"requests":{"type":"integer","format":"int64"}},"required":["errorType","requests"]},"LlmMetricsResponse":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"totalEvents":{"type":"integer","format":"int64"},"attributedEvents":{"type":"integer","format":"int64"},"attributionCoverage":{"type":"number","format":"double","description":"upstreamRef가 기록된 event 비율(0..1)"},"attemptsKnownEvents":{"type":"integer","format":"int64"},"attemptCoverage":{"type":"number","format":"double","description":"attempts가 기록된 event 비율(0..1)"},"estimatedEvents":{"type":"integer","format":"int64"},"estimatedCoverage":{"type":"number","format":"double","description":"토큰 수가 추정치인 event 비율(0..1)"},"upstreams":{"type":"array","items":{"$ref":"#/components/schemas/LlmUpstreamMetricResponse"}},"localRejections":{"type":"array","items":{"$ref":"#/components/schemas/LlmLocalRejectionMetricResponse"}}},"required":["attemptCoverage","attemptsKnownEvents","attributedEvents","attributionCoverage","estimatedCoverage","estimatedEvents","from","localRejections","to","totalEvents","upstreams"]},"LlmUpstreamMetricResponse":{"type":"object","properties":{"id":{"type":["string","null"],"format":"uuid","description":"등록된 upstream 공개 ID. 미등록 ref면 null; ORG에는 허용된 upstream 행만 반환"},"ref":{"type":["string","null"],"description":"gateway 내부 ref. SYS 계층에만 반환하며 ORG에서는 null"},"name":{"type":"string"},"finalOutcomes":{"type":"integer","format":"int64"},"succeeded":{"type":"integer","format":"int64"},"timeoutOrError":{"type":"integer","format":"int64"},"timeoutOrErrorRate":{"type":"number","format":"double","description":"최종 결과 중 TIMEOUT 또는 UPSTREAM_ERROR 비율(0..1)"},"inputTokens":{"type":"integer","format":"int64"},"outputTokens":{"type":"integer","format":"int64"},"attemptsKnown":{"type":"integer","format":"int64"},"multiAttemptRequests":{"type":"integer","format":"int64"},"multiAttemptRate":{"type":"number","format":"double","description":"attempts가 기록된 결과 중 attempts > 1 비율(0..1)"},"attemptAmplification":{"type":"number","format":"double","description":"attempts가 기록된 결과의 평균 시도 횟수(배수)"},"latencySamples":{"type":"integer","format":"int64"},"latencyP50Ms":{"type":["integer","null"],"format":"int64"},"latencyP95Ms":{"type":["integer","null"],"format":"int64"},"latencyP99Ms":{"type":["integer","null"],"format":"int64"}},"required":["attemptAmplification","attemptsKnown","finalOutcomes","inputTokens","latencySamples","multiAttemptRate","multiAttemptRequests","name","outputTokens","succeeded","timeoutOrError","timeoutOrErrorRate"]},"AdminLlmKeySummaryResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"purpose":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/LlmApiKeyStatus"},"expiresAt":{"type":["string","null"],"format":"date-time"},"lastUsedAt":{"type":["string","null"],"format":"date-time"},"rpm":{"type":["integer","null"],"format":"int32"},"tpm":{"type":["integer","null"],"format":"int32"},"concurrency":{"type":["integer","null"],"format":"int32"},"dailyTokens":{"type":["integer","null"],"format":"int64"},"creditLimit":{"type":"number"},"creditLimitReset":{"anyOf":[{"$ref":"#/components/schemas/CreditLimitReset"},{"type":"null"}]},"creditAxisConnected":{"type":"boolean","description":"유료 모델이 발급되어 현재 연결되어 있는지"},"creditUsage":{"type":["number","null"],"description":"OpenRouter가 마지막으로 보고한 현재 limit window 사용액. 미관측이면 null"},"creditUsageAt":{"type":["string","null"],"format":"date-time","description":"Key 금액을 vendor에서 관측한 시각. 미관측이면 null"},"creditLimitRemaining":{"type":["number","null"],"description":"OpenRouter가 보고한 key 잔여 한도. 미관측 또는 무한도면 null"},"openrouterAccountId":{"type":["string","null"],"format":"uuid"},"openrouterAccountName":{"type":["string","null"]},"workspaceId":{"type":["string","null"],"format":"uuid"},"workspaceName":{"type":"string"},"orgId":{"type":["string","null"],"format":"uuid"},"orgName":{"type":"string"},"requestId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":"string","format":"date-time"}},"required":["createdAt","creditAxisConnected","creditLimit","id","name","orgName","status","workspaceName"]},"PageResponseAdminLlmKeySummaryResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/AdminLlmKeySummaryResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"AdminLlmKeyUsageResponse":{"type":"object","properties":{"trend":{"$ref":"#/components/schemas/LlmKeyUsageTrendResponse","description":"키 소유자가 보는 것과 같은 응답, 같은 계산"},"costPoints":{"type":"array","description":"일별 금액. 소유자 화면에는 없는 계열입니다 — 소유자는 모델별 금액만 봅니다.","items":{"$ref":"#/components/schemas/LlmUsageCostPointResponse"}},"endpointKinds":{"type":"array","description":"이 기간에 실제로 호출된 경로만, 요청이 많은 순","items":{"$ref":"#/components/schemas/LlmEndpointKindUsageResponse"}},"servedModels":{"type":"array","description":"공급자가 요청과 다른 모델로 응답한 사례. 없으면 빈 목록이고, 빈 것이 「대체가 없었다」를 증명하지는 않습니다.","items":{"$ref":"#/components/schemas/LlmServedModelUsageResponse"}}},"required":["costPoints","endpointKinds","servedModels","trend"]},"LlmServedModelUsageResponse":{"type":"object","properties":{"servedModelName":{"type":"string","description":"공급자가 실제로 응답한 모델 이름. 요청한 모델과 다를 때만 기록됩니다."},"requests":{"type":"integer","format":"int64","description":"그 이름으로 돌아온 요청 수"}},"required":["requests","servedModelName"]},"LlmUsageCostPointResponse":{"type":"object","properties":{"day":{"type":"string","format":"date"},"attributedCostUsd":{"type":["number","null"],"description":"이 날 요청들에 공급자가 매긴 금액의 합(USD). 가격이 붙은 요청이 하나도 없는 날은 null이며 0으로 그리지 않습니다 — 자체 서빙만 쓴 날은 금액이 0인 것이 아니라 금액이라는 것이 없습니다."},"pricedRequests":{"type":"integer","format":"int64","description":"이 날 요청 중 공급자가 금액을 알려 준 요청 수"},"requests":{"type":"integer","format":"int64","description":"이 날 요청 수. pricedRequests와 견주면 합계가 얼마나 덮는지 보입니다."}},"required":["day","pricedRequests","requests"]},"AdminLlmAccountKeyUsageResponse":{"type":"object","properties":{"keyId":{"type":"string","format":"uuid"},"keyName":{"type":"string"},"requests":{"type":"integer","format":"int64"},"inputTokens":{"type":"integer","format":"int64"},"outputTokens":{"type":"integer","format":"int64"},"attributedCostUsd":{"type":["number","null"],"description":"이 키가 이 기간에 쓴 금액(USD). 가격이 붙은 요청이 없으면 null이며 0으로 표시하지 않습니다."},"pricedRequests":{"type":"integer","format":"int64","description":"이 키의 요청 중 공급자가 금액을 알려 준 요청 수"}},"required":["inputTokens","keyId","keyName","outputTokens","pricedRequests","requests"]},"AdminLlmAccountUsageResponse":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"attributedCostUsd":{"type":["number","null"],"description":"이 기간에 이 계정에 귀속된 금액(USD). 공급자가 말하는 지출액이 아닙니다 — 그쪽은 계정 잔액과 함께 따로 오고 기간도 다릅니다. 가격이 붙은 요청이 하나도 없으면 null입니다."},"requests":{"type":"integer","format":"int64","description":"이 기간에 이 계정의 키들이 보낸 요청 수"},"pricedRequests":{"type":"integer","format":"int64","description":"그중 공급자가 금액을 알려 준 요청 수"},"keysUsed":{"type":"integer","format":"int32","description":"이 기간에 실제로 호출된 키 수"},"keysLinked":{"type":"integer","format":"int32","description":"이 계정에 연결된 키 수. keysUsed와 견주면 놀고 있는 키가 보입니다."},"points":{"type":"array","description":"하루 한 점, 오래된 날부터. 호출이 없던 날도 채워집니다.","items":{"$ref":"#/components/schemas/LlmUsageCostPointResponse"}},"keys":{"type":"array","description":"이 기간에 실제로 호출된 키만, 금액이 큰 순","items":{"$ref":"#/components/schemas/AdminLlmAccountKeyUsageResponse"}}},"required":["from","keys","keysLinked","keysUsed","points","pricedRequests","requests","to"]},"AllocationStatus":{"type":"string","enum":["ALLOCATED","RELEASED"]},"IpAllocationResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"poolId":{"type":"string","format":"uuid"},"poolName":{"type":"string"},"ip":{"type":"string"},"vmId":{"type":["string","null"],"format":"uuid"},"vmName":{"type":["string","null"]},"hostname":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/AllocationStatus"},"allocatedAt":{"type":"string","format":"date-time"},"releasedAt":{"type":["string","null"],"format":"date-time"}},"required":["allocatedAt","id","ip","poolId","poolName","status"]},"PageResponseIpAllocationResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/IpAllocationResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"GpuReclaimReviewView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"allocationId":{"type":"string","format":"uuid"},"allocationName":{"type":"string"},"reason":{"type":"string"},"evidence":{"type":"object","additionalProperties":{}},"decision":{"anyOf":[{"$ref":"#/components/schemas/GpuReviewDecision"},{"type":"null"}]},"decisionReason":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"decidedAt":{"type":["string","null"],"format":"date-time"}},"required":["allocationId","allocationName","createdAt","evidence","id","reason"]},"PageResponseGpuReclaimReviewView":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/GpuReclaimReviewView"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"PageResponseDriftFindingResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/DriftFindingResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"PageResponseAdminDomainView":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/AdminDomainView"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"AdminCertificateView":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"$ref":"#/components/schemas/CertificateKind"},"status":{"$ref":"#/components/schemas/CertificateStatus"},"scope":{"type":"string"},"domainId":{"type":["string","null"],"format":"uuid"},"notAfter":{"type":["string","null"],"format":"date-time"},"daysUntilExpiry":{"type":["integer","null"],"format":"int32"},"lastError":{"type":["string","null"]}},"required":["id","kind","scope","status"]},"PageResponseAdminCertificateView":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/AdminCertificateView"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"CapacityTrendPointResponse":{"type":"object","properties":{"day":{"type":"string","format":"date"},"vmCount":{"type":"integer","format":"int64"},"vcpu":{"type":"integer","format":"int64"},"memoryMb":{"type":"integer","format":"int64"},"diskGb":{"type":"integer","format":"int64"}},"required":["day","diskGb","memoryMb","vcpu","vmCount"]},"CapacityTrendResponse":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"capacityCpuThreads":{"type":"integer","format":"int64"},"capacityMemoryMb":{"type":"integer","format":"int64"},"capacityDiskGb":{"type":["integer","null"],"format":"int64","description":"ACTIVE 노드의 thin pool 용량 합(GB) — 오버프로비저닝 전제의 조언용 분모, 용량 미등록 노드가 있으면 null"},"points":{"type":"array","description":"일 단위 스냅샷 — 해당 일 종료 시점에 살아 있던 VM의 할당 합","items":{"$ref":"#/components/schemas/CapacityTrendPointResponse"}}},"required":["capacityCpuThreads","capacityMemoryMb","from","points","to"]},"PageResponseAdminCampusIpRequestView":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/AdminCampusIpRequestView"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"AuditLogViewResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"감사 로그 행의 공개 식별자. 목록 렌더링용 키이며 어떤 조회 파라미터도 아닙니다."},"actorId":{"type":["string","null"],"format":"uuid"},"actorEmail":{"type":["string","null"]},"actorName":{"type":["string","null"]},"actorRole":{"type":["string","null"]},"action":{"type":"string"},"targetType":{"type":["string","null"]},"targetId":{"type":["string","null"]},"detail":{},"ip":{"type":["string","null"]},"orgName":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["action","createdAt","id"]},"PageResponseAuditLogViewResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/AuditLogViewResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"PageResponseAnnouncementView":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/AnnouncementView"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}},"required":["content","page","size","totalElements","totalPages"]},"FieldValidationError":{"type":"object","description":"검증 실패 필드 한 건 (422 응답의 errors[] 원소)","properties":{"field":{"type":"string","description":"실패한 요청 필드 이름"},"message":{"type":"string","description":"한국어 오류 메시지"}},"required":["field","message"]},"Problem":{"type":"object","description":"RFC 9457 오류 응답 + Pickle 확장(code, errors). 모든 비정상 응답은 이 형태로 반환됩니다.","properties":{"type":{"type":"string","description":"문제 유형 URI (기본 about:blank)"},"title":{"type":"string","description":"사람이 읽는 짧은 제목"},"status":{"type":"integer","format":"int32","description":"HTTP 상태 코드"},"detail":{"type":"string","description":"이 발생 건에 대한 설명"},"instance":{"type":"string","description":"발생 경로"},"code":{"type":"string","description":"기계 판독용 안정 오류 코드 (클라이언트 분기 기준)"},"errors":{"type":"array","description":"검증 실패 상세 (422에서만 존재)","items":{"$ref":"#/components/schemas/FieldValidationError"}}},"required":["title","status","code"]}},"securitySchemes":{"bearerAuth":{"type":"http","description":"액세스 토큰 (JWT HS256, 15분 만료). 클레임: sub(계정 공개 식별자 UUID), role, token_version. 비밀번호 변경·계정 비활성화 시 token_version이 올라가 기존 토큰이 즉시 무효화됩니다. 리프레시 토큰은 보안 스킴이 아니라 __Host-pickle_refresh httpOnly 쿠키로만 오갑니다.","scheme":"bearer","bearerFormat":"JWT"}}}}