오류 및 요청 제한
오류 형식
모든 API 오류는 다음 구조의 JSON으로 반환돼요:
{
"error": "Short error description",
"detail": "Extended description (optional)"
}
일부 엔드포인트에서는 Django REST Framework의 기본 설정에 따라 다음 형식으로도 오류를 반환할 수 있어요:
{
"detail": "Error message"
}
HTTP 상태 코드
| 상태 | 의미 | 발생 상황 |
|---|---|---|
| 200 | 성공 | 요청 성공 |
| 400 | 잘못된 요청 | 매개변수가 누락되었거나 유효하지 않음 |
| 401 | 인증 필요 | 인증 토큰이 누락되었거나 만료되었거나 유효하지 않음 |
| 403 | 접근 금지 | 토큰에 필요한 권한 범위 또는 워크스페이스 접근 권한이 없음 |
| 404 | 찾을 수 없음 | 리소스가 존재하지 않거나 워크스페이스에 동기화된 데이터가 없음 |
| 405 | 허용되지 않는 메서드 | 엔드포인트에 맞지 않는 HTTP 메서드 사용 |
| 422 | 처리할 수 없는 엔터티 | 요청 본문 유효성 검사 실패 |
| 429 | 요청 과다 | 요청 제한 초과 |
| 500 | 내부 서버 오류 | 예기치 않은 서버 오류 |
| 503 | 서비스 이용 불가 | Elasticsearch 또는 기타 종속 구성 요소의 작동 중단 |
요청 제한
V1 API (서비스 토큰)
| 유형 | 제한 | 적용 범위 |
|---|---|---|
| 단기 집중 요청 | 10초당 요청 20회 | 토큰별 |
| 시간 구간 | 15분당 요청 600회 | 토큰별 |
사용자 API (JWT)
| 유형 | 제한 | 적용 범위 |
|---|---|---|
| 인증된 사용자 | 분당 요청 100회 | 사용자별 |
| 익명 사용자 | 분당 요청 20회 | IP별 |
요청 제한 헤더
요청이 제한되면 응답에 다음 항목이 포함돼요:
HTTP/1.1 429 Too Many Requests
Retry-After: 30
요청 제한 처리: Retry-After에 지정된 시간(초)만큼 기다린 후 다시 시도하세요. 429 응답이 반복되면 지수 백오프를 적용하세요.
자주 발생하는 오류 상황
인증 오류
// Missing Authorization header
{"detail": "Authentication credentials were not provided."}
// Invalid or expired JWT
{"detail": "Given token not valid for any token type", "code": "token_not_valid"}
// Invalid service token
{"error": "Invalid or revoked service token."}
// Expired service token
{"error": "Token has expired."}
권한 오류
// Token missing required scope
{"error": "Token does not have the required scope: graph:search"}
// Workspace not in token's allowed list
{"error": "Workspace not allowed for this token."}
유효성 검사 오류
// Missing required parameter
{"error": "workspace_id is required."}
// Invalid UUID format
{"error": "Invalid node_id format."}
// Query too long (V1 API)
{"error": "Query too long (max 256 characters)."}
// Disallowed characters in query
{"error": "Query contains disallowed characters."}
리소스 오류
// Workspace not synced
{"error": "No synced data found for this workspace."}
// Node not found
{"error": "Node not found."}
// Elasticsearch unavailable
{"error": "Search service unavailable."}