범위 및 오류
최소 권한을 부여하고 공개 API의 안정적인 오류 코드를 모두 처리합니다.
최소 권한을 부여하고 공개 API의 안정적인 오류 코드를 모두 처리합니다.
모든 공개 API 작업에는 명시적인 범위 하나가 필요합니다. 유효한 자격 증명에 해당 범위가 없으면 403 insufficient_scope를 반환하며 권한을 자동으로 넓히지 않습니다.
범위 레퍼런스#
| 범위 | 허용 작업 |
|---|---|
account:read | 인증된 계정, 요금제, 권한, 지갑 요약 읽기 |
sites:read | 사이트 목록 및 상세 읽기 |
sites:write | 사이트 생성, 수정, 게시, 게시 취소 |
agents:read | 에이전트 설정 읽기 |
agents:write | 페르소나, 지침, 언어, 음성, 임베드 상태, 허용 오리진 수정 |
knowledge:read | 지식 소스 및 FAQ 목록 읽기 |
knowledge:write | 텍스트 소스 추가·삭제 및 FAQ 생성·수정·삭제 |
conversations:read | 대화 목록 및 메시지 읽기 |
leads:read | 수집된 리드 목록 읽기 |
leads:write | 리드 생성·수정·자격 판정 및 영업 기회 파이프라인 수락 |
pipeline:read | 단계, 계정, 영업 기회, 활동, CRM 동기화 상태 읽기 |
pipeline:write | 단계 설정, 계정·영업 기회 생성/수정, CRM 결과 가져오기/재시도 |
analytics:read | 사이트 분석 이벤트 읽기 |
connectors:read | 시크릿 없이 커넥터 상태 읽기 |
connectors:write | 커넥터 생성, 수정, 활성화, 비활성화, 삭제 |
domains:read | 도메인 상태와 필요한 DNS 레코드 읽기 |
domains:write | 도메인 연결, 검증, 수정, 삭제 |
broadcasts:read | 브로드캐스트 및 전달 상태 읽기 |
broadcasts:write | 초안 생성 및 브로드캐스트 전송 대기열 등록 |
notifications:read | 소유자 알림 목록 읽기 |
notifications:write | 알림을 읽음 또는 읽지 않음으로 표시 |
monetization:read | 수익화 상품 목록 읽기 |
monetization:write | 상품 생성, 수정, 활성화, 비활성화, 삭제 |
usage:read | 측정된 사용량 이벤트 읽기 |
webhooks:read | 웹훅 엔드포인트와 전달 상태 읽기 |
webhooks:write | 웹훅 엔드포인트 생성 및 삭제 |
보고 작업에는 읽기 범위를 사용하세요. 연동이 실제로 변경 작업을 수행할 때만 쓰기 범위를 추가합니다. 예를 들어 리드 내보내기는 일반적으로 sites:read와 leads:read만 필요하며 sites:write나 agents:write는 필요하지 않습니다.
범위 오류#
{
"error": {
"code": "insufficient_scope",
"message": "The API key does not grant the required scope.",
"details": { "required": ["sites:write"] },
"request_id": "6c0b2f2e-..."
}
}누락된 범위를 포함한 대체 키를 만들고 서버 시크릿을 업데이트하세요. 기존 API 키의 범위는 그 자리에서 확장할 수 없으므로 권한 변경이 명시적이고 감사 가능하게 유지됩니다.
오류 응답 형식#
모든 API 오류는 같은 최상위 구조를 사용합니다.
type ApiError = {
error: {
code: string;
message: string;
details?: unknown;
request_id: string;
};
};영문 message가 아니라 error.code로 분기하세요. 메시지는 버전 변경 없이 개선될 수 있습니다. 작업 이름, 상태, 재시도 횟수와 함께 error.request_id 및 x-request-id 응답 헤더를 기록하되 Authorization 헤더나 요청 시크릿은 기록하지 마세요.
상태 및 코드 레퍼런스#
| HTTP | 안정적인 코드 | 의미 | 일반적인 처리 |
|---|---|---|---|
400 | invalid_request | 필드 검증 실패 또는 지원하지 않는 값 | details의 필드를 수정하고 같은 입력은 재시도하지 않음 |
400 | invalid_json | 본문이 JSON 객체가 아니거나 잘못된 JSON | 유효한 JSON 객체 하나를 전송 |
401 | authentication_required | Bearer 헤더 누락 | 서버 측 자격 증명 추가 |
401 | invalid_api_key | 키가 잘못되었거나 만료·폐기되었거나 소유자가 없음 | 키 교체 또는 회전 |
403 | subscription_required | 소유자에게 활성 유료 요금제가 없음 | 구독 복구 후 재시도 |
403 | insufficient_scope | 작업에 필요한 범위가 없음 | 최소 권한 대체 자격 증명 생성 |
404 | not_found | 엔드포인트 또는 소유 리소스를 찾을 수 없음 | 경로와 테넌트 소유 ID 확인 |
409 | conflict | 현재 리소스 상태가 작업을 막음 | 현재 상태를 읽은 후 재시도 |
415 | invalid_request | 변경 본문이 application/json이 아님 | Content-Type: application/json 전송 |
429 | rate_limit_exceeded | 키의 1분 요금제 버킷 소진 | Retry-After만큼 기다리고 지터 적용 |
500 | internal_error | 요청을 완료할 수 없음 | 안전하거나 멱등한 작업을 재시도하고 요청 ID 보고 |
자격 증명 소유자의 계정 밖에 있는 리소스는 다른 테넌트의 ID 존재 여부를 숨기기 위해 404를 반환할 수 있습니다.
검증 상세 정보#
필드 검증은 자신의 폼 컨트롤 옆에 표시할 수 있는 경로를 반환합니다.
{
"error": {
"code": "invalid_request",
"message": "Request validation failed.",
"details": [
{ "path": "content.headline", "message": "String must contain at least 1 character(s)" }
],
"request_id": "6c0b2f2e-..."
}
}변경 요청 본문은 JSON 객체여야 합니다. 배열, 빈 본문, 폼 데이터, 텍스트 콘텐츠 유형으로 보낸 JSON은 거부됩니다.
재시도 판단#
429는Retry-After초 뒤에 재시도합니다.500은 안전한 읽기 또는 같은Idempotency-Key로 보호된 쓰기만 재시도합니다.- 처리 중인 멱등성
409는Retry-After: 2헤더 뒤에 재시도합니다. 400,401,403,404또는 상태 충돌은 원인이 바뀌기 전까지 재시도하지 않습니다.