API 레퍼런스
Mooni 챗 직접 호출 HTTP API
대부분의 통합은 <mooni-frame> Web Component로 충분하며, 이 엔드포인트들은 내부적으로 호출됩니다. 서버 사이드나 커스텀 클라이언트 통합이 필요할 때만 이 페이지를 참고하세요.
Base URL
| 환경 | Base URL |
|---|---|
| 프로덕션 | https://ax-cs-demo.vercel.app |
| 스테이징 | https://ax-cs-demo.vercel.app |
인증
모든 엔드포인트는 mooni-api-key 헤더가 필요합니다:
mooni-api-key: mooni_your_api_key_here서버는 키의 SHA-256 해시를 테넌트 설정과 비교합니다. Origin도 테넌트 화이트리스트와 검증합니다.
POST /api/chat
챗 응답을 Server-Sent Events로 스트리밍합니다.
요청
POST /api/chat
Content-Type: application/json
mooni-api-key: mooni_xxx{
"query": "비밀번호는 어떻게 재설정하나요?",
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"userId": "user@example.com",
"brandId": "school-a"
}| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
query | string | ✅ | 사용자 질문. trim됩니다. 최대 500자. |
sessionId | string | optional | 대화 식별자 (UUID 권장). 어드민 기록을 위해 필요. |
userId | string | null | optional | 호스트 사이트 유저 ID. null/없음 → 익명 세션. |
brandId | string | optional | 브랜드별 FAQ 검색 필터. |
응답 (Server-Sent Events)
Content-Type: text/event-stream. 이벤트는 data: 라인의 JSON이며 data: [DONE]으로 종료됩니다.
type | 페이로드 | 발생 시점 |
|---|---|---|
status | { status: "searching", level: "loading" } | 검색 시작 |
status | { status: "out_of_scope", level: "warning" } | 점수가 임계값 미만 (적절한 매칭 없음) |
text | { content: "..." } | 답변 청크 (~3단어 단위, ~18ms 간격) |
faq | { results: [...] } | 관련 FAQ 추천 (있는 경우) |
status | { status: "done", level: "success" } | 스트림 완료 |
error | { message: "search_failed" } | 서버 에러 ([DONE] 따라옴) |
스트림 예시:
data: {"type":"status","status":"searching","level":"loading"}
data: {"type":"text","content":"비밀번호 재설정은 "}
data: {"type":"text","content":"설정 → 계정 → "}
data: {"type":"text","content":"재설정 메뉴에서 가능합니다."}
data: {"type":"faq","results":[{"id":"faq_1","title":"비밀번호 복구"}]}
data: {"type":"status","status":"done","level":"success"}
data: [DONE]에러
| 상태 | 본문 | 원인 |
|---|---|---|
400 | {"error":"invalid_json"} | 본문이 유효한 JSON이 아님 |
400 | {"error":"missing_query"} | query가 비었거나 string이 아님 |
400 | {"error":"query_too_long","maxLength":500} | query가 500자 초과 |
401 | — | mooni-api-key 누락 또는 무효 |
403 | — | 요청 Origin이 테넌트 화이트리스트에 없음 |
GET /api/config
테넌트 공개 설정 (표시 이름, 기본 테마, 지원 언어 등)을 반환합니다. iframe 앱이 부팅 시 호출합니다.
GET /api/config
mooni-api-key: mooni_xxx응답 형태는 테넌트 설정의 공개 영역을 반영합니다. 스키마는 내부 구현이므로 운영 로직에서 직접 의존하지 말고 Web Component를 사용하세요.
Rate Limit
기본: API 키당 분당 60 요청. 프로덕션 테넌트의 한도 상향이 필요하면 문의주세요.
데이터 영속화 노트
- 세션과 메시지는
sessionId가 제공된 경우에만 영속화됩니다.sessionId없는 레거시 임베드는 어드민 기록 자체가 생성되지 않습니다. - 사용자 레코드는
userId가 non-null일 때만 어드민에 생성됩니다. - 영속화는 fire-and-forget으로 동작하며, 쓰기 실패는 로깅되지만 챗 응답에는 영향을 주지 않습니다.
