문서/API 및 웹훅/오류 및 응답

오류 및 응답

모든 공개 API 엔드포인트는 예측 가능한 응답 형식을 반환합니다. 오류는 본문에 안정적인 기계 판독 가능한 코드를 포함하므로 영어를 파싱하지 않고도 분기할 수 있습니다.

응답 봉투

성공 응답은 리소스(또는 리소스 목록)를 직접 반환합니다. 최상위 래퍼는 없습니다 — 클라이언트는 타입이 지정된 모델로 직접 역직렬화할 수 있습니다:

GET /api/public/v1/org

{
  "id": "e188fc87-…",
  "name": "Acme Corp",
  "plan": "growth",
  …
}

실패 응답은 유일한 필수 필드로 error 코드를 포함하는 작고 균일한 형식을 사용합니다. 선택적 필드는 호출을 수정하는 데 도움이 되는 컨텍스트를 제공합니다:

{
  "error": "insufficient_scope",
  "required": "assignments:write",
  "present": ["assignments:read", "users:read"]
}

상태 코드 참조

상태표시 시점처리 방법
200요청 성공. 본문에 리소스 또는 확인 메시지가 들어 있습니다.본문을 처리합니다.
400잘못된 형식의 요청: 필수 필드 누락, 잘못된 열거형 값, 본문 너무 큼, 파싱할 수 없는 JSON입니다.클라이언트 요청을 수정하세요 — 동일한 페이로드로 재시도하지 마세요.
401누락, 잘못된 형식, 취소 또는 만료된 토큰입니다.Authorization 헤더를 확인하세요. 토큰이 취소된 경우 회전하세요.
403토큰은 유효하지만 필요한 범위가 없습니다.관리자 UI에서 범위를 추가하세요. 응답에는 정확한 범위 이름이 포함되어 있습니다.
404리소스가 존재하지 않거나 다른 조직에 속합니다.상위 컬렉션을 다시 가져오세요. 조직 간에 오래된 ID를 따르지 마세요.
409충돌 — 예를 들어 이메일이 이미 사용 중입니다.작업이 멱등성이 있는 경우 성공으로 취급하세요.
413요청 본문이 엔드포인트별 한도를 초과합니다. 하드 오버플로의 경우 Kestrel이 반환합니다. SARIF 엔드포인트도 선언된 Content-Length가 10 MB를 초과할 때 이를 400 body_too_large로 반환합니다.페이로드를 줄이세요. SARIF의 경우 한 번에 한 도구의 결과만 증분 수집하세요.
429이 API 키에서 속도 제한에 도달했습니다.Retry-After을 존중하세요. 속도 제한을 참조하세요.
5xx서버 측 문제입니다.지수 백오프와 함께 재시도하세요. 응답 X-Request-Id 헤더를 캡처하고 모든 지원 티켓에 인용하세요.

오류 코드

error 필드는 버전 간에 안정적입니다 — 동일한 상태가 서로 다른 코드를 전달할 수 있으므로 HTTP 상태가 아니라 클라이언트 코드에서 분기하세요:

코드상태의미
unauthorized401요청에 사용 가능한 bearer 토큰이 없습니다.
insufficient_scope403토큰은 괜찮지만 범위가 누락되었습니다. 응답에 requiredpresent가 포함됩니다.
rate_limited429한도 초과. Retry-After 헤더를 참조하세요.
user_not_found404사용자 ID가 존재하지 않거나 조직에 속하지 않습니다.
team_not_found404팀 ID가 존재하지 않거나 조직에 속하지 않습니다.
assignment_not_found404과제 ID가 존재하지 않거나 조직에 속하지 않습니다.
empty_body400본문이 필요한 곳에 본문 없이 전송된 POST 또는 PATCH입니다.
body_too_large400 / 413요청 본문이 엔드포인트 한도를 초과했습니다. SARIF는 선언된 Content-Length가 너무 클 때 본문에 maxBytes를 포함하여 이를 400으로 발행합니다. 본문이 실제로 오버런되면 Kestrel이 빈 413을 발행합니다.

요청 ID

모든 응답에는 X-Request-Id 헤더(UUID v4)가 포함됩니다. 클라이언트 측에서 캡처하고 지원 요청에 포함시키세요 — 실패한 호출의 정확한 서버 측 추적을 가져올 수 있습니다. 5xx 응답의 경우 요청 ID가 진단의 가장 빠른 단일 경로입니다.

유효성 검사 오류

POSTPATCH 본문의 유효성 검사 실패는 첫 번째 실패한 규칙을 설명하는 플랫 error와 함께 400를 반환합니다. 다중 필드 유효성 검사 노출은 v1의 일부가 아닙니다 — 보고된 첫 번째 필드를 수정하고 재시도하세요. 향후 버전에서는 필드별 상세 정보를 추가할 수 있으며, 최상위 error 계약은 유지됩니다.

오류에서 분기하기 — 예제

const res = await fetch(url, { headers });
if (res.ok) return res.json();

const body = await res.json().catch(() => ({}));
switch (body.error) {
  case 'rate_limited':
    return retryWithBackoff(url);
  case 'insufficient_scope':
    throw new Error(`API key missing scope: ${body.required}`);
  case 'unauthorized':
    throw new Error('API key revoked or invalid — rotate the secret');
  default:
    throw new Error(`API error ${res.status}: ${body.error || 'unknown'}`);
}