개발자 문서

CONDERI AI API (Enterprise) v1.0.0

기업 테넌트용 AI API. 외부 AI 서비스에 의존하지 않으며 자체 서버의 오픈 가중치 모델(Ollama)과 pgvector로 처리한다. 모든 생성 작업은 큐 기반(202 + 폴링)이다. AI 결과는 사람 승인 전까지 approved 가 되지 않는다(review_mode=none 은 테넌트가 명시적으로 선택). 인증: API 키(`Authorization: Bearer sb_live_<prefix>.<secret>`) 또는 콘솔 세션(쿠키). 키 전용/세션 전용 경로는 각 operation 의 설명에 표기.

Base URL /api/ai/v1응답 JSON · UTF-8결제 비활성 · 플랜 한도만 적용

이 페이지는 계약 파일 packages/contracts/openapi/ai.v1.yaml 에서 빌드 시 생성됩니다. 생성 결과의 정확도·속도는 보장하지 않으며, 진단 결과는 검토자 승인 전까지 확정되지 않습니다.

인증

방식헤더설명
API 키Authorization: Bearer sb_live_<prefix>.<secret>기관 콘솔 → AI → API 키에서 발급. 비밀값은 발급 시 한 번만 표시되고 서버에는 해시만 저장됩니다. 키별 스코프(assessments·documents·queries·usage)와 분당 한도가 적용됩니다.
콘솔 세션쿠키기관 콘솔 로그인 세션. 키 발급·폐기, 진단 승인·반려는 세션 전용입니다.
워커 토큰Authorization: Bearer <worker_token>내부 처리 워커 전용(/api/worker/rag/*). 외부 연동에서는 사용하지 않습니다.

공통 규약

진단

메서드경로요약인증
POST/assessments역량 진단 작업 생성(큐)API 키 · 콘솔 세션
GET/assessments진단 목록API 키 · 콘솔 세션
GET/assessments/{assessmentId}진단 조회(결과 포함)API 키 · 콘솔 세션
POST/assessments/{assessmentId}/decisions테넌트 담당자 승인/반려 (세션 전용, role manager 이상)API 키 · 콘솔 세션
GET/rubrics사용 가능한 루브릭(공용 + 테넌트)API 키 · 콘솔 세션
POST/rubrics테넌트 루브릭 생성(세션 전용)API 키 · 콘솔 세션

POST /api/ai/v1/assessments

역량 진단 작업 생성(큐)

operationId aiCreateAssessment · 인증 API 키 / 콘솔 세션 · 성공 202 + Retry-After → Assessment

파라미터
이름위치필수타입
Idempotency-Keyheader예string(8–128자)

요청 본문: AssessmentCreate

curl -X POST "https://<your-host>/api/ai/v1/assessments" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>" \
  -H "Idempotency-Key: <unique-key-8-to-128-chars>" \
  -H "Content-Type: application/json" \
  -d '{"rubric_id":"00000000-0000-4000-8000-000000000000","external_ref":"string","review_mode":"none","submission":{"text":"string","attachments":[{"kind":"document","ref":"string","label":"string"}]}}'

GET /api/ai/v1/assessments

진단 목록

operationId aiListAssessments · 인증 API 키 / 콘솔 세션 · 성공 200 → object

파라미터
이름위치필수타입
statusquery아니오AssessmentStatus
external_refquery아니오string(0–200자)
cursorquery아니오string
limitquery아니오integer(1~100)
응답 200
필드타입필수설명
itemsAssessment[]예
next_cursorstring | null예
curl -X GET "https://<your-host>/api/ai/v1/assessments" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>"

GET /api/ai/v1/assessments/{assessmentId}

진단 조회(결과 포함)

operationId aiGetAssessment · 인증 API 키 / 콘솔 세션 · 성공 200 → Assessment

파라미터
이름위치필수타입
assessmentIdpath예string(uuid)
curl -X GET "https://<your-host>/api/ai/v1/assessments/<assessmentId>" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>"

POST /api/ai/v1/assessments/{assessmentId}/decisions

테넌트 담당자 승인/반려 (세션 전용, role manager 이상)

operationId aiDecideAssessment · 인증 API 키 / 콘솔 세션 · 성공 200 → Assessment

파라미터
이름위치필수타입
assessmentIdpath예string(uuid)
Idempotency-Keyheader예string(8–128자)
요청 본문
필드타입필수설명
actionenum(approve | reject)예
rationalestring(10–2000자)예
expected_hashstring아니오approve 시 필수. Assessment.result_hash
curl -X POST "https://<your-host>/api/ai/v1/assessments/<assessmentId>/decisions" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>" \
  -H "Idempotency-Key: <unique-key-8-to-128-chars>" \
  -H "Content-Type: application/json" \
  -d '{"action":"approve","rationale":"string","expected_hash":"string"}'

GET /api/ai/v1/rubrics

사용 가능한 루브릭(공용 + 테넌트)

operationId aiListRubrics · 인증 API 키 / 콘솔 세션 · 성공 200 → object

응답 200
필드타입필수설명
itemsRubric[]예
curl -X GET "https://<your-host>/api/ai/v1/rubrics" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>"

POST /api/ai/v1/rubrics

테넌트 루브릭 생성(세션 전용)

operationId aiCreateRubric · 인증 API 키 / 콘솔 세션 · 성공 201 → Rubric

파라미터
이름위치필수타입
Idempotency-Keyheader예string(8–128자)

요청 본문: RubricCreate

curl -X POST "https://<your-host>/api/ai/v1/rubrics" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>" \
  -H "Idempotency-Key: <unique-key-8-to-128-chars>" \
  -H "Content-Type: application/json" \
  -d '{"name":"string","axes":[{"id":"string","label":"string","weight":0,"indicators":[{"id":null,"label":null,"weight":null,"levels":null}]}]}'

문서

메서드경로요약인증
POST/documents문서 등록(텍스트 직접 또는 업로드 완료 참조). 등록 후 비동기 임베딩API 키 · 콘솔 세션
GET/documents문서 목록API 키 · 콘솔 세션
POST/documents/upload-sessions파일 업로드용 서명 URL 발급(Supabase Storage, 버킷 ai-docs/<tenant>)API 키 · 콘솔 세션
GET/documents/{documentId}API 키 · 콘솔 세션
DELETE/documents/{documentId}문서·청크·임베딩 삭제(원본 Storage 객체 포함)API 키 · 콘솔 세션

POST /api/ai/v1/documents

문서 등록(텍스트 직접 또는 업로드 완료 참조). 등록 후 비동기 임베딩

operationId aiCreateDocument · 인증 API 키 / 콘솔 세션 · 성공 202 → Document

파라미터
이름위치필수타입
Idempotency-Keyheader예string(8–128자)
요청 본문
필드타입필수설명
titlestring(1–200자)예
textstring(0–2000000자)아니오직접 텍스트. upload_id 와 택일
upload_idstring(uuid)아니오/documents/upload-sessions 로 올린 파일
tagsstring(0–40자)[]아니오
curl -X POST "https://<your-host>/api/ai/v1/documents" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>" \
  -H "Idempotency-Key: <unique-key-8-to-128-chars>" \
  -H "Content-Type: application/json" \
  -d '{"title":"string","text":"string","upload_id":"00000000-0000-4000-8000-000000000000","tags":["string"]}'

GET /api/ai/v1/documents

문서 목록

operationId aiListDocuments · 인증 API 키 / 콘솔 세션 · 성공 200 → object

파라미터
이름위치필수타입
statusquery아니오DocumentStatus
cursorquery아니오string
limitquery아니오integer(1~100)
응답 200
필드타입필수설명
itemsDocument[]예
next_cursorstring | null예
curl -X GET "https://<your-host>/api/ai/v1/documents" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>"

POST /api/ai/v1/documents/upload-sessions

파일 업로드용 서명 URL 발급(Supabase Storage, 버킷 ai-docs/<tenant>)

operationId aiCreateUploadSession · 인증 API 키 / 콘솔 세션 · 성공 201 → object

파라미터
이름위치필수타입
Idempotency-Keyheader예string(8–128자)
요청 본문
필드타입필수설명
filenamestring(0–200자)예
mimeenum(application/pdf | text/plain | text/markdown | application/vnd.openxmlformats-officedocument.wordprocessingml.document)예
bytesinteger(1~26214400)예
sha256string아니오
응답 201
필드타입필수설명
upload_idstring(uuid)예
put_urlstring예
expires_atstring(date-time)예
curl -X POST "https://<your-host>/api/ai/v1/documents/upload-sessions" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>" \
  -H "Idempotency-Key: <unique-key-8-to-128-chars>" \
  -H "Content-Type: application/json" \
  -d '{"filename":"string","mime":"application/pdf","bytes":1,"sha256":"string"}'

GET /api/ai/v1/documents/{documentId}

operationId aiGetDocument · 인증 API 키 / 콘솔 세션 · 성공 200 → Document

파라미터
이름위치필수타입
documentIdpath예string(uuid)
curl -X GET "https://<your-host>/api/ai/v1/documents/<documentId>" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>"

DELETE /api/ai/v1/documents/{documentId}

문서·청크·임베딩 삭제(원본 Storage 객체 포함)

operationId aiDeleteDocument · 인증 API 키 / 콘솔 세션 · 성공 204

파라미터
이름위치필수타입
documentIdpath예string(uuid)
curl -X DELETE "https://<your-host>/api/ai/v1/documents/<documentId>" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>"

질의

메서드경로요약인증
POST/queries문서 근거 질의(큐). 근거 없으면 grounded=false 로 답한다API 키 · 콘솔 세션
GET/queries/{queryId}API 키 · 콘솔 세션

POST /api/ai/v1/queries

문서 근거 질의(큐). 근거 없으면 grounded=false 로 답한다

operationId aiCreateQuery · 인증 API 키 / 콘솔 세션 · 성공 202 + Retry-After → Query

파라미터
이름위치필수타입
Idempotency-Keyheader예string(8–128자)
요청 본문
필드타입필수설명
questionstring(2–4000자)예
top_kinteger(1~20)아니오 (기본 6)
document_idsstring(uuid)[]아니오
tagsstring[]아니오
curl -X POST "https://<your-host>/api/ai/v1/queries" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>" \
  -H "Idempotency-Key: <unique-key-8-to-128-chars>" \
  -H "Content-Type: application/json" \
  -d '{"question":"string","top_k":1,"document_ids":["00000000-0000-4000-8000-000000000000"],"tags":["string"]}'

GET /api/ai/v1/queries/{queryId}

operationId aiGetQuery · 인증 API 키 / 콘솔 세션 · 성공 200 → Query

파라미터
이름위치필수타입
queryIdpath예string(uuid)
curl -X GET "https://<your-host>/api/ai/v1/queries/<queryId>" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>"

API 키

메서드경로요약인증
GET/keysAPI 키 목록(세션 전용, prefix 만 노출)API 키 · 콘솔 세션
POST/keysAPI 키 발급(세션 전용, owner/manager). 평문은 이 응답에서만 1회 노출API 키 · 콘솔 세션
DELETE/keys/{keyId}키 폐기(세션 전용)API 키 · 콘솔 세션

GET /api/ai/v1/keys

API 키 목록(세션 전용, prefix 만 노출)

operationId aiListKeys · 인증 API 키 / 콘솔 세션 · 성공 200 → object

응답 200
필드타입필수설명
itemsApiKey[]예
curl -X GET "https://<your-host>/api/ai/v1/keys" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>"

POST /api/ai/v1/keys

API 키 발급(세션 전용, owner/manager). 평문은 이 응답에서만 1회 노출

operationId aiCreateKey · 인증 API 키 / 콘솔 세션 · 성공 201 → object

파라미터
이름위치필수타입
Idempotency-Keyheader예string(8–128자)
요청 본문
필드타입필수설명
namestring(1–60자)예
scopesApiScope[]아니오 (기본 assessments,documents,queries,usage)
rate_limit_per_mininteger(1~600)아니오 (기본 60)
curl -X POST "https://<your-host>/api/ai/v1/keys" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>" \
  -H "Idempotency-Key: <unique-key-8-to-128-chars>" \
  -H "Content-Type: application/json" \
  -d '{"name":"string","scopes":["assessments"],"rate_limit_per_min":1}'

DELETE /api/ai/v1/keys/{keyId}

키 폐기(세션 전용)

operationId aiRevokeKey · 인증 API 키 / 콘솔 세션 · 성공 204

파라미터
이름위치필수타입
keyIdpath예string(uuid)
curl -X DELETE "https://<your-host>/api/ai/v1/keys/<keyId>" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>"

사용량·모델·감사

메서드경로요약인증
GET/usage일별 사용량 집계(과금 없음, 한도 표시용)API 키 · 콘솔 세션
GET/models서빙 중인 모델 정보(공개 범위)API 키 · 콘솔 세션
GET/audit테넌트 감사 로그(세션 전용, owner/manager)API 키 · 콘솔 세션

GET /api/ai/v1/usage

일별 사용량 집계(과금 없음, 한도 표시용)

operationId aiGetUsage · 인증 API 키 / 콘솔 세션 · 성공 200 → Usage

파라미터
이름위치필수타입
fromquery아니오string(date)
toquery아니오string(date)
curl -X GET "https://<your-host>/api/ai/v1/usage" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>"

GET /api/ai/v1/models

서빙 중인 모델 정보(공개 범위)

operationId aiListModels · 인증 API 키 / 콘솔 세션 · 성공 200 → object

응답 200
필드타입필수설명
generationModelInfo예
embeddingModelInfo예
curl -X GET "https://<your-host>/api/ai/v1/models" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>"

GET /api/ai/v1/audit

테넌트 감사 로그(세션 전용, owner/manager)

operationId aiListAudit · 인증 API 키 / 콘솔 세션 · 성공 200 → object

파라미터
이름위치필수타입
cursorquery아니오string
limitquery아니오integer(1~100)
응답 200
필드타입필수설명
itemsAuditItem[]예
next_cursorstring | null예
curl -X GET "https://<your-host>/api/ai/v1/audit" \
  -H "Authorization: Bearer sb_live_<prefix>.<secret>"

워커 전용(내부)

메서드경로요약인증
POST/worker/rag/search워커가 질의 임베딩으로 테넌트 청크를 검색(서버가 pgvector 실행). 실제 경로 /api/worker/rag/search워커 토큰
POST/worker/rag/chunks워커가 생성한 청크+임베딩 저장(서버가 job 의 tenant/document 검증). 실제 경로 /api/worker/rag/chunks워커 토큰

POST /api/ai/v1/worker/rag/search

워커가 질의 임베딩으로 테넌트 청크를 검색(서버가 pgvector 실행). 실제 경로 /api/worker/rag/search

operationId workerRagSearch · 인증 워커 토큰 · 성공 200 → object

요청 본문
필드타입필수설명
job_idstring(uuid)예
lease_tokenstring예
embeddingnumber[](1024)예
top_kinteger(1~20)예
document_idsstring(uuid)[]아니오
응답 200
필드타입필수설명
chunksChunkHit[]예
curl -X POST "https://<your-host>/api/ai/v1/worker/rag/search" \
  -H "Authorization: Bearer <worker_token>" \
  -H "Idempotency-Key: <unique-key-8-to-128-chars>" \
  -H "Content-Type: application/json" \
  -d '{"job_id":"00000000-0000-4000-8000-000000000000","lease_token":"string","embedding":[0],"top_k":1,"document_ids":["00000000-0000-4000-8000-000000000000"]}'

POST /api/ai/v1/worker/rag/chunks

워커가 생성한 청크+임베딩 저장(서버가 job 의 tenant/document 검증). 실제 경로 /api/worker/rag/chunks

operationId workerRagStoreChunks · 인증 워커 토큰 · 성공 200 → object

요청 본문
필드타입필수설명
job_idstring(uuid)예
lease_tokenstring예
document_idstring(uuid)예
chunksobject[]예
finalboolean아니오true 면 문서 status=ready, chunk_count 확정 (기본 false)
응답 200
필드타입필수설명
storedinteger예
curl -X POST "https://<your-host>/api/ai/v1/worker/rag/chunks" \
  -H "Authorization: Bearer <worker_token>" \
  -H "Idempotency-Key: <unique-key-8-to-128-chars>" \
  -H "Content-Type: application/json" \
  -d '{"job_id":"00000000-0000-4000-8000-000000000000","lease_token":"string","document_id":"00000000-0000-4000-8000-000000000000","chunks":[{"ord":0,"content":"string","tokens":0,"embedding":[0],"meta":{}}],"final":false}'

스키마

ErrorCode

skillbridge.v1 ErrorCode 와 동일 집합(단일 규약)

UNAUTHENTICATED | MFA_REQUIRED | FORBIDDEN | NOT_FOUND | REVISION_CONFLICT | APPROVAL_HASH_MISMATCH | SECOND_REVIEW_REQUIRED | INVALID_REVIEW | INVALID_INPUT | CONSENT_REQUIRED | UPLOAD_INCOMPLETE | LEASE_EXPIRED | LEASE_MISMATCH | ALREADY_SUBMITTED | SEAT_LIMIT | COUPON_INVALID | RATE_LIMITED | VALIDATION_FAILED | CONFLICT | INVALID_STATE | IDEMPOTENCY_REPLAY_MISMATCH | QUOTA_EXCEEDED | UNSUPPORTED_MEDIA | PAYLOAD_TOO_LARGE | INTERNAL

ErrorEnvelope

필드타입필수설명
errorobject예

ApiScope

assessments | documents | queries | usage

AssessmentStatus

queued | processing | awaiting_review | approved | rejected | failed

DocumentStatus

uploaded | processing | ready | failed

QueryStatus

queued | processing | done | failed

ReviewMode

none: 테넌트가 명시 선택 시에만. 기본 tenant

none | tenant | conderi

AssessmentCreate

필드타입필수설명
rubric_idstring | null(uuid)아니오null 이면 공용 SkillBridge 5축
external_refstring | null(0–200자)아니오
review_modeReviewMode아니오
submissionobject예

Assessment

필드타입필수설명
idstring(uuid)예
external_refstring | null아니오
statusAssessmentStatus예
review_modeReviewMode예
rubric_idstring | null(uuid)예
created_atstring(date-time)예
updated_atstring(date-time)아니오
resultAssessmentResult | null아니오
result_hashstring | null아니오
engine_versionstring | null아니오
model_versionstring | null아니오
decisionobject | null아니오
failurestring | null아니오failed 시 사유 코드

AssessmentResult

필드타입필수설명
axesobject[]예
indicatorsobject[]예
pendingstring[]예증빙 부족 지표. 0점이 아님
overallnumber | null(0~100)아니오모든 축 채점 시에만
narrativestring(0–8000자)예

Rubric

필드타입필수설명
idstring(uuid)예
namestring예
scopeenum(shared | tenant)예
versioninteger예
axesRubricAxis[]예

RubricCreate

필드타입필수설명
namestring(1–80자)예
axesRubricAxis[]예

RubricAxis

필드타입필수설명
idstring예
labelstring(0–60자)예
weightnumber(0~10)예
indicatorsobject[]예

Document

필드타입필수설명
idstring(uuid)예
titlestring예
statusDocumentStatus예
sourceenum(text | upload)예
bytesinteger | null아니오
sha256string | null아니오
chunk_countinteger아니오 (기본 0)
tagsstring[]아니오
failurestring | null아니오
created_atstring(date-time)예
ready_atstring | null(date-time)아니오

ChunkHit

필드타입필수설명
document_idstring(uuid)예
ordinteger예
contentstring예
scorenumber예cosine similarity
metaobject아니오

Query

필드타입필수설명
idstring(uuid)예
statusQueryStatus예
questionstring예
answerstring | null아니오
groundedboolean | null아니오false 면 문서 근거 부족. 답변은 '문서에서 확인되지 않음' 안내
citationsobject[]아니오
model_versionstring | null아니오
failurestring | null아니오
created_atstring(date-time)예
answered_atstring | null(date-time)아니오

ApiKey

필드타입필수설명
idstring(uuid)예
namestring예
prefixstring예sb_live_xxxxxxxx
scopesApiScope[]예
statusenum(active | revoked)예
rate_limit_per_mininteger예
last_used_atstring | null(date-time)아니오
created_atstring(date-time)예

Usage

필드타입필수설명
planstring예
periodobject예
limitsobject예
daysobject[]예

ModelInfo

필드타입필수설명
namestring예
versionstring예
licensestring예
served_byenum(self_hosted)예
finetune_tagstring | null아니오

AuditItem

필드타입필수설명
idstring예
atstring(date-time)예
actor_kindenum(api_key | member | system)예
actor_labelstring | null아니오
actionstring예
targetstring | null아니오
detailobject아니오

오류 코드

codeHTTP
UNAUTHENTICATED401
MFA_REQUIRED403
FORBIDDEN403
NOT_FOUND404
REVISION_CONFLICT409
APPROVAL_HASH_MISMATCH409
SECOND_REVIEW_REQUIRED409
INVALID_REVIEW422
INVALID_INPUT422
CONSENT_REQUIRED422
UPLOAD_INCOMPLETE422
LEASE_EXPIRED409
LEASE_MISMATCH409
ALREADY_SUBMITTED409
SEAT_LIMIT422
COUPON_INVALID422
RATE_LIMITED429
VALIDATION_FAILED422
CONFLICT409
INVALID_STATE409
IDEMPOTENCY_REPLAY_MISMATCH409
QUOTA_EXCEEDED429
UNSUPPORTED_MEDIA415
PAYLOAD_TOO_LARGE413
INTERNAL500

상태 코드 매핑은 서버 구현(AI_HTTP_STATUS)과 동일합니다. 기관 콘솔에서 키 발급 후 사용하세요.