에러
요청이 실패하면 응답 본문에 success: false와 error 객체가 들어 있습니다. 코드로 분기할 때는 HTTP 상태 코드와 함께 error.code를 기준으로 삼으세요. error.message는 사람이 읽는 설명이므로 파싱하지 마세요.
{
"success": false,
"error": {
"code": "INVALID_TOKEN",
"message": "human-readable 설명"
}
}
details는 일부 오류에만 들어 있고, 그 밖의 오류에서는 키가 생략됩니다. INSUFFICIENT_SCOPE는 details.required_scope, RATE_LIMIT_EXCEEDED는 details.scope, VALIDATION_FAILED는 필드 이름과 사유의 쌍을 details에 담습니다.
에러 코드
| HTTP | code | 발생 조건 | 대응 |
|---|---|---|---|
| 400 | INVALID_QUERY | 잘못된 쿼리 파라미터, 만료되었거나 형식이 틀린 cursor, 허용 기간을 넘긴 시간 범위 | 응답의 message를 보고 쿼리를 고칩니다. |
| 400 | INVALID_INPUT | path 파라미터 형식 오류(예: UUID가 아닌 {id}) | path의 id 형식을 고칩니다. |
| 400 | INVALID_JSON | 본문이 올바른 JSON이 아니거나, 엔드포인트가 받지 않는 필드가 들어 있음 | 본문을 엔드포인트 문서의 필드로만 구성합니다. |
| 401 | MISSING_TOKEN | Authorization 헤더 없음 | 헤더를 추가합니다. |
| 401 | INVALID_TOKEN | 형식 오류, 존재하지 않는 토큰, 회수된 토큰, 만료된 토큰. 보안상 한 코드로 통합해서 응답합니다. | 토큰을 확인하고, 만료되었거나 회수되었다면 새로 발급합니다. |
| 403 | INSUFFICIENT_SCOPE | 필요한 scope가 없음. 빠진 scope는 details.required_scope에 있습니다. | 해당 scope를 포함해 새로 발급합니다. |
| 403 | PAT_INCOMPATIBLE_ENDPOINT | Public API에 노출되지 않은 경로를 호출함 | 엔드포인트 카탈로그에서 경로와 메서드를 확인합니다. |
| 403 | IP_NOT_ALLOWED_WORKSPACE | 토큰에 허용 IP를 정했는데, 다른 주소에서 호출함. 호출 주소는 error.client_ip에 있습니다. | 호출하는 서버의 주소를 허용 IP에 추가합니다. |
| 404 | NOT_FOUND | 리소스가 없거나 이 워크스페이스에 속하지 않음 | path의 id를 확인합니다. |
| 404 | CONTACT_NOT_FOUND | 연락처 쓰기(수정·태그·SMS 동의)에서 {id}의 연락처가 없음 | 연락처 id를 확인합니다. |
| 409 | EXTERNAL_ID_ALREADY_EXISTS | POST /contacts의 external_id가 이미 쓰이고 있음 | GET /contacts?external_id=로 기존 연락처를 찾아 이어서 씁니다. |
| 422 | VALIDATION_FAILED | 본문의 값이 형식·길이 제한을 넘음. 어느 필드인지는 details에 있습니다. | 값을 고쳐서 다시 보냅니다. |
| 429 | RATE_LIMIT_EXCEEDED | 요청 한도 초과. 어느 버킷인지는 details.scope에 있습니다. | Retry-After(초)만큼 기다린 뒤 다시 보냅니다. |
| 500 | INTERNAL, INTERNAL_ERROR | 서버 내부 오류. 엔드포인트에 따라 두 코드 중 하나로 응답합니다. | jitter를 둔 backoff로 재시도합니다. |
| 503 | SERVICE_UNAVAILABLE | 인증 저장소 등 서버 쪽이 일시적으로 응답하지 못함 | jitter를 둔 backoff로 재시도합니다. |
| 503 | SEARCH_UNAVAILABLE | 해당 서버에 검색 색인이 구성되지 않음(GET /search 전용) | 재시도하지 마세요. 서버를 재기동해야 해소됩니다. |
엔드포인트마다 따로 정의한 오류 코드는 각 엔드포인트 문서에 적혀 있습니다.
재시도 가이드
429,5xx:Retry-After헤더가 있으면 그 값만큼, 없으면 jitter를 둔 exponential backoff로 기다린 뒤 재시도합니다.SEARCH_UNAVAILABLE은 제외합니다.400,401,403,404,409,422: 재시도하지 마세요. 요청 자체(토큰·scope·경로·본문)를 고쳐야 합니다.- 예외: 엔드포인트 문서가 따로 재시도 방법을 적은 코드는 그 문서를 따릅니다. 예를 들어 멱등키를 받는 엔드포인트의
409는 같은 요청을 아직 처리하는 중이라는 뜻일 수 있고, 이때는 잠시 기다린 뒤 같은 멱등키로 다시 보냅니다.
원인을 모르겠을 때
모든 응답의 X-Request-ID 헤더 값을 기록해 두었다가 문의할 때 함께 전달하세요. 제로톡이 해당 요청을 추적하는 데 쓰입니다. 자세한 내용은 API 개요를 참고하세요.