REST 인터페이스
특별한 설명이 없으면 모든 인터페이스는 요청 헤더에 테넌트 API Key가 필요합니다:
Authorization: Bearer <테넌트API Key>기본 주소는 http://localhost:8787, 데모 테넌트는 demo(apiKey는 첫 시작 시 무작위 생성되어 로그에 출력)입니다. 이 페이지는 연동 개발 참고용이며 일반 사용자는 신경 쓸 필요가 없습니다.
서버 시작
bash
# 모델 Key 없이도 시작 가능(인증/세션/인터페이스는 테스트 가능. 대화만 오류)
pnpm run server
# 실제 모델 사용(권장)
OPENAI_API_KEY=sk-... OPENAI_MODEL=gpt-4o-mini pnpm run server주요 환경 변수: PORT(기본 8787), DATA_DIR(기본 ./.zqagent_data), APPROVAL_TIMEOUT_SECONDS(승인/질문 보류 타임아웃, 기본 900), TENANT_ID / TENANT_API_KEY / MODEL(데모 테넌트).
인증
bash
export BASE=http://localhost:8787
export TOKEN=zk_xxxx # 시작 로그 '已创建演示租户' 줄의 apiKey
# 상태 확인(공개)
curl -s $BASE/healthz # => {"status":"ok"}
# Key 없음 → 401
curl -s -o /dev/null -w "%{http_code}\n" $BASE/api/v1/sessions # => 401
# 올바른 Key → 200
curl -s -o /dev/null -w "%{http_code}\n" -H "Authorization: Bearer $TOKEN" $BASE/api/v1/sessions주요 엔드포인트 요약
세션
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /healthz | 상태 확인(공개) |
| POST | /api/v1/sessions | 세션 생성 |
| GET | /api/v1/sessions | 세션 나열 |
| GET | /api/v1/sessions/{id} | 세션 조회 |
| PATCH | /api/v1/sessions/{id} | 세션 이름 변경 |
| DELETE | /api/v1/sessions/{id} | 세션 삭제 |
| GET | /api/v1/sessions/{id}/state | 세션 상태(보류 중 승인/질문 포함) |
| PATCH | /api/v1/sessions/{id}/model | 세션 모델 전환 |
| PATCH | /api/v1/sessions/{id}/mode | 권한 모드 전환(plan / interactive / auto / discuss) |
| PATCH | /api/v1/sessions/{id}/draft | 입력창 초안 저장(빈 문자열이면 지움) |
| POST | /api/v1/sessions/{id}/turns | 작업 투입 |
| POST | /api/v1/sessions/{id}/steer | 실행 중 보충 정보 |
| POST | /api/v1/sessions/{id}/interrupt | 현재 작업 중단 |
| POST | /api/v1/sessions/{id}/resume | 세션 재개 |
| GET | /api/v1/sessions/{id}/events | 이벤트 스트림(폴링 또는 SSE, ?since= 증분) |
| GET | /api/v1/sessions/{id}/approvals | 승인 대기 목록 |
| POST | /api/v1/sessions/{id}/approvals/{aid} | 승인 응답 |
| GET | /api/v1/sessions/{id}/questions | 답변 대기 목록 |
| POST | /api/v1/sessions/{id}/questions/{qid} | 질문 답변 |
프로젝트와 노드
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET / POST | /api/v1/projects | 프로젝트 나열 / 생성(생성 시 작업 디렉터리 지정) |
| DELETE | /api/v1/projects/{id} | 프로젝트 삭제 |
| GET | /api/v1/models | 사용 가능한 모델 목록 |
| GET / PUT | /api/v1/config | 노드 구성 조회 / 갱신 |
| GET / PUT | /api/v1/node/llm | 노드 기본 모델 조회 / 설정 |
| GET | /api/v1/node/host | 노드 호스트 정보 |
| GET | /api/v1/tools | 도구 목록 |
| GET | /api/v1/mcp | MCP 서버 목록 |
| PUT | /api/v1/mcp | MCP 구성 전체 교체(프로젝트 .agent/mcp.json에 기록. 플랫폼 배포 시 409) |
| POST | /api/v1/mcp/test | 단일 MCP 서버 연결 테스트(저장 안 함) |
사용량과 비용
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/v1/usage/summary | 사용량 요약(기간 / 모델별) |
| GET | /api/v1/usage/records | 상세 레코드 |
| GET | /api/v1/usage/export | CSV 내보내기 |
| GET / PUT | /api/v1/usage/pricing | 가격표 조회 / 수정 |
| POST | /api/v1/usage/rebuild | 요약 재구축 |
| POST | /api/v1/usage/verify | 원장 검증 |
원격 연결과 페어링
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/v1/fleet/status | 노드 연결 상태 |
| POST | /api/v1/fleet/enroll | 연결 코드로 연결(zqagent link가 호출) |
| POST | /api/v1/fleet/unlink | 연결 해제 |
| GET | /api/v1/fleet/pairing | 클라우드 연결 페어링 정보(게이트웨이 주소 + 네임스페이스/키 + nodeId) |
| GET / POST | /api/v1/notifications | 알림 채널 조회 / 추가 |
| DELETE | /api/v1/notifications/{id} | 알림 채널 삭제 |
빠른 시작
bash
# 세션 생성
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"model":"gpt-4o-mini"}' $BASE/api/v1/sessions
# => {"data":{"sessionId":"e4df66d6...","status":"idle",...}}
export SID=e4df66d6... # 반환된 sessionId로 교체
# 작업 투입(즉시 반환, 백그라운드 비동기 실행)
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"input":"안녕하세요, 자기소개 해 주세요"}' $BASE/api/v1/sessions/$SID/turns
# => {"data":{"accepted":true,"status":"running"}}
# 이벤트 폴링(since 커서로 증분 조회)
curl -s "$BASE/api/v1/sessions/$SID/events?since=0"
# 실시간 구독(SSE)
curl -N -H "Authorization: Bearer $TOKEN" -H "Accept: text/event-stream" \
$BASE/api/v1/sessions/$SID/events세션이 작업 실행 중이면
POST /turns는 자동으로 보충 정보로 현재 작업에 주입됩니다 ({"data":{"accepted":true,"status":"steering"}}반환). 오류가 되지 않습니다.
승인과 질문
모델이 부작용이 있는 작업(파일 쓰기, 명령 실행 등)을 요청하면 보류하고 승인을 기다립니다. ask_user 등의 도구를 호출하면 보류하고 답변을 기다립니다.
bash
# 승인 대기 목록 보기(id는 도구 호출 ID)
curl -s -H "Authorization: Bearer $TOKEN" $BASE/api/v1/sessions/$SID/approvals
# 승인 응답: once | always_tool | always_command | deny
# always_command는 run_shell에서만 유효
export AID=call_xxx
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"decision":"once"}' $BASE/api/v1/sessions/$SID/approvals/$AID
# 질문 답변
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"answer":"계속"}' $BASE/api/v1/sessions/$SID/questions/qid_xxx멀티 테넌트 격리
각 테넌트는 자신의 API Key로 자신의 세션에 접근합니다. 테넌트 A의 Key로 테넌트 B의 세션에 접근하면 404를 반환합니다.
오류 코드 요약
| HTTP | code | 상황 |
|---|---|---|
| 401 | unauthorized | Key 없음 / Key 무효 |
| 404 | not_found | 세션 없음 / 알 수 없는 라우트 / 테넌트 간 접근 |
| 409 | not_running | 명시적 steer 시 세션이 실행 중이 아님 |
| 409 | has_pending_interaction | 미결 승인/질문이 있어 새 작업을 투입할 수 없음 |
| 400 | bad_request | body가 잘못된 JSON / input이 비어 있음 |
| 400 | invalid_decision | decision이 잘못됨, 또는 run_shell 외에 always_command 전송 |
