Appearance
에러 및 요청 제한
API 요청이 실패하면 HTTP 상태 코드와 함께 에러 본문이 반환돼요.
요청 제한은 엔드포인트별 Tier에 따라 적용돼요.
에러 응답
에러 응답은 기본적으로 message와 code를 반환해요.
json
{
"message": "Forbidden resource",
"code": "FORBIDDEN_EXCEPTION"
}messagestring 사용자에게 표시할 수 있는 에러 메시지
codestring 에러를 식별하는 코드
message는 Accept-Language에 따라 번역될 수 있어요.
code는 언어와 관계없이 동일하게 유지돼요.
에러 코드
HTTP API의 code는 예외 클래스 이름을 기준으로 만들어져요.
예를 들어 InvalidApiKeyException은 INVALID_API_KEY_EXCEPTION으로 반환돼요.
인증
| 코드 | 상태 |
|---|---|
EMPTY_TFA_TOKEN_EXCEPTION | 400 Bad Request |
INVALID_AUTHENTICATION_HEADER_EXCEPTION | 400 Bad Request |
INVALID_CREDENTIAL_EXCEPTION | 400 Bad Request |
INVALID_EXTERNAL_PROVIDER_TOKEN_EXCEPTION | 400 Bad Request |
INVALID_TFA_CODE_EXCEPTION | 400 Bad Request |
INVALID_VERIFICATION_EXCEPTION | 400 Bad Request |
ONLY_TFA_DISABLED_EXCEPTION | 400 Bad Request |
ONLY_TFA_ENABLED_EXCEPTION | 400 Bad Request |
EXPIRED_TOKEN_EXCEPTION | 401 Unauthorized |
INVALID_API_KEY_EXCEPTION | 401 Unauthorized |
INVALID_TOKEN_EXCEPTION | 401 Unauthorized |
ONLY_ANONYMOUS_EXCEPTION | 401 Unauthorized |
ONLY_USER_EXCEPTION | 401 Unauthorized |
NEED_TFA_EXCEPTION | 403 Forbidden |
ONLY_LOCAL_AUTHENTICATION_PROVIDER_EXCEPTION | 403 Forbidden |
USER_SUSPENDED_EXCEPTION | 403 Forbidden |
API_KEY_NOT_FOUND_EXCEPTION | 404 Not Found |
TOKEN_NOT_FOUND_EXCEPTION | 404 Not Found |
TOO_MANY_VERIFICATION_ATTEMPTS_EXCEPTION | 429 Too Many Requests |
EXTERNAL_PROVIDER_ERROR_EXCEPTION | 500 Internal Server Error |
공통
| 코드 | 상태 |
|---|---|
INVALID_REQUEST_BODY_EXCEPTION | 400 Bad Request |
INVALID_REQUEST_EXCEPTION | 400 Bad Request |
INTERNAL_UNEXPECTED_EXCEPTION | 500 Internal Server Error |
UNKNOWN_EXCEPTION | 500 Internal Server Error |
외부 연동
| 코드 | 상태 |
|---|---|
GET_ACCESS_TOKEN_FAILED_EXCEPTION | 400 Bad Request |
GET_USER_INFO_FAILED_EXCEPTION | 400 Bad Request |
파일
| 코드 | 상태 |
|---|---|
INVALID_UPLOAD_SIZE_EXCEPTION | 400 Bad Request |
FILE_NOT_FOUND_EXCEPTION | 404 Not Found |
INVALID_FILE_TYPE_EXCEPTION | 422 Unprocessable Entity |
TOO_LARGE_FILE_EXCEPTION | 422 Unprocessable Entity |
FAILED_CALCULATE_SIZE_EXCEPTION | 500 Internal Server Error |
FAILED_REMOVE_FILE_EXCEPTION | 500 Internal Server Error |
FAILED_SAVE_FILE_EXCEPTION | 500 Internal Server Error |
이벤트 게이트웨이
이벤트 게이트웨이는 WebSocket 에러 페이로드의 d.code로 코드를 반환해요.
| 코드 | 상태 |
|---|---|
FORBIDDEN_EXCEPTION | WebSocket |
INVALID_OPCODE_EXCEPTION | WebSocket |
INVALID_REQUEST_PAYLOAD_EXCEPTION | WebSocket |
INVALID_TOKEN_EXCEPTION | WebSocket |
알림
| 코드 | 상태 |
|---|---|
NOTIFICATION_INTEGRATION_NOT_FOUND_EXCEPTION | 404 Not Found |
NOTIFICATION_NOT_FOUND_EXCEPTION | 404 Not Found |
ALREADY_INTEGRATED_PROVIDER_EXCEPTION | 409 Conflict |
플랜과 결제
| 코드 | 상태 |
|---|---|
INVALID_PRICE_EXCEPTION | 400 Bad Request |
INVALID_SUBSCRIPTION_ITEM_EXCEPTION | 400 Bad Request |
INVALID_WEBHOOK_SIGNATURE_EXCEPTION | 400 Bad Request |
OVER_MAX_MEMBER_EXCEPTION | 400 Bad Request |
PAID_PLAN_REQUIRED_EXCEPTION | 400 Bad Request |
PLAN_NOT_FOUND_EXCEPTION | 404 Not Found |
SUBSCRIPTION_NOT_FOUND_EXCEPTION | 404 Not Found |
프로젝트
| 코드 | 상태 |
|---|---|
CHANGE_OWNER_ROLE_EXCEPTION | 400 Bad Request |
INVALID_TIME_RANGE_EXCEPTION | 400 Bad Request |
KICK_OWNER_EXCEPTION | 400 Bad Request |
KICK_SELF_EXCEPTION | 400 Bad Request |
LIMIT_REACHED_EXCEPTION | 400 Bad Request |
MAX_FILES_EXCEEDED_EXCEPTION | 400 Bad Request |
MAX_MENTIONED_USER_EXCEEDED | 400 Bad Request |
MAX_PROJECT_SECTION_EXCEPTION | 400 Bad Request |
NESTED_REPLY_EXCEPTION | 400 Bad Request |
NO_DRAWING_EXCEPTION | 400 Bad Request |
NO_EMOJI_EXCEPTION | 400 Bad Request |
NO_TIME_WITH_DRAWING_EXCEPTION | 400 Bad Request |
OVER_MAX_GUEST_EXCEPTION | 400 Bad Request |
PROJECT_NOT_STARRED_EXCEPTION | 400 Bad Request |
SELF_TRANSFER_OWNER_EXCEPTION | 400 Bad Request |
CONNECTED_OWNER_FORBIDDEN_EXCEPTION | 403 Forbidden |
CONNECTION_INVITATION_EMAIL_MISMATCH_EXCEPTION | 403 Forbidden |
NOT_IN_PROJECT_EXCEPTION | 403 Forbidden |
PROJECT_CONNECTION_NOT_ALLOWED_EXCEPTION | 403 Forbidden |
SELF_CONNECTION_FORBIDDEN_EXCEPTION | 403 Forbidden |
UPLOAD_VIDEO_NOT_ALLOWED_EXCEPTION | 403 Forbidden |
COMMENT_NOT_FOUND_EXCEPTION | 404 Not Found |
CONNECTION_INVITATION_EXPIRED_EXCEPTION | 404 Not Found |
CONNECTION_NOT_FOUND_EXCEPTION | 404 Not Found |
FILE_NOT_FOUND_EXCEPTION | 404 Not Found |
FOLDER_NOT_FOUND_EXCEPTION | 404 Not Found |
PROJECT_ACCESS_LINK_NOT_FOUND_EXCEPTION | 404 Not Found |
PROJECT_GUEST_NOT_FOUND_EXCEPTION | 404 Not Found |
PROJECT_NOT_FOUND_EXCEPTION | 404 Not Found |
PROJECT_SCHEDULE_NOT_FOUND_EXCEPTION | 404 Not Found |
PROJECT_SECTION_NOT_FOUND_EXCEPTION | 404 Not Found |
VERSION_CATEGORY_NOT_FOUND_EXCEPTION | 404 Not Found |
VERSION_CONTENT_NOT_FOUND_EXCEPTION | 404 Not Found |
VERSION_NOT_FOUND_EXCEPTION | 404 Not Found |
ALREADY_CONNECTED_MEMBER_EXCEPTION | 409 Conflict |
ALREADY_IN_PROJECT_SECTION_EXCEPTION | 409 Conflict |
ALREADY_PARTICIPATED_IN_EXCEPTION | 409 Conflict |
ALREADY_PROJECT_MEMBER_EXCEPTION | 409 Conflict |
CONTENT_TYPE_MISMATCH_EXCEPTION | 409 Conflict |
DUPLICATE_CONNECTION_INVITATION_EXCEPTION | 409 Conflict |
DUPLICATE_EMOJI_EXCEPTION | 409 Conflict |
DUPLICATE_PARTICIPANT_EXCEPTION | 409 Conflict |
PROJECT_ALREADY_STARRED_EXCEPTION | 409 Conflict |
VERSION_CONTENT_OVERWRITTEN_EXCEPTION | 409 Conflict |
보안
| 코드 | 상태 |
|---|---|
EMPTY_SESSION_DATA_EXCEPTION | 400 Bad Request |
ACCESS_DENIED_EXCEPTION | 403 Forbidden |
FORBIDDEN_ROLE_EXCEPTION | 403 Forbidden |
FORBIDDEN_STATUS_EXCEPTION | 403 Forbidden |
RATE_LIMIT_EXCEPTION | 429 Too Many Requests |
사용자
| 코드 | 상태 |
|---|---|
INVALID_USER_STATUS_EXCEPTION | 403 Forbidden |
PASSWORD_NOT_MATCH_EXCEPTION | 403 Forbidden |
USER_NOT_FOUND_EXCEPTION | 404 Not Found |
DUPLICATED_EMAIL_EXCEPTION | 409 Conflict |
워크스페이스
| 코드 | 상태 |
|---|---|
EDIT_WORKSPACE_OWNER_EXCEPTION | 400 Bad Request |
KICK_SELF_EXCEPTION | 400 Bad Request |
KICK_WORKSPACE_OWNER_EXCEPTION | 400 Bad Request |
MEMBER_NOT_ACTIVE_EXCEPTION | 400 Bad Request |
SELF_TRANSFER_OWNER_EXCEPTION | 400 Bad Request |
USAGE_LIMIT_EXCEEDED_EXCEPTION | 400 Bad Request |
NOT_IN_WORKSPACE_EXCEPTION | 403 Forbidden |
WORKSPACE_INVITATION_NOT_FOUND_EXCEPTION | 404 Not Found |
WORKSPACE_NOT_FOUND_EXCEPTION | 404 Not Found |
ALREADY_PARTICIPATED_IN_EXCEPTION | 409 Conflict |
DUPLICATE_WORKSPACE_INVITATION_EXCEPTION | 409 Conflict |
HAS_OWNED_WORKSPACE_EXCEPTION | 409 Conflict |
추가 필드
일부 에러는 클라이언트가 다음 동작을 판단할 수 있도록 추가 필드를 반환해요.
authenticatedboolean 인증 상태가 유효하지 않거나 로그인이 필요하다는 뜻이에요.
tfaboolean 2단계 인증 검증이 필요하다는 뜻이에요.
인증 정보가 없거나 유효하지 않으면 authenticated가 false로 내려올 수 있어요.
json
{
"message": "인증이 필요해요.",
"code": "ONLY_USER_EXCEPTION",
"authenticated": false
}2단계 인증 검증이 필요한 토큰으로 보호된 API를 호출하면 tfa가 true로 내려와요.
json
{
"message": "2단계 인증이 필요해요.",
"code": "NEED_TFA_EXCEPTION",
"tfa": true
}요청 제한
요청 제한은 엔드포인트별 티어에 따라 적용돼요.
엔드포인트 문서 제목 옆의 Tier 뱃지로 적용 티어를 확인할 수 있어요.
| 티어 | 제한 | 차단 시간 |
|---|---|---|
| Tier 1 | 5분당 5회 | 30분 |
| Tier 2 | 1분당 5회 | 10분 |
| Tier 3 | 1분당 20회 | 10분 |
| Tier 4 | 1분당 60회 | 10분 |
| Default | 1분당 120회 | 10분 |
요청 제한 기준은 인증 방식에 따라 달라져요.
| 인증 상태 | 제한 기준 |
|---|---|
| 공개 API 키 | API 키 소유 사용자 |
| 로그인 세션 | 사용자 세션 |
| 비로그인 요청 | IP 주소 |
요청 제한 헤더
요청 제한 정보는 응답 헤더로 내려와요.
| 헤더 | 설명 |
|---|---|
x-ratelimit-limit | 현재 엔드포인트에서 허용되는 요청 수 |
x-ratelimit-remaining | 현재 기간에 남은 요청 수 |
x-ratelimit-reset | 제한 카운터가 초기화되거나 차단이 해제될 때까지 남은 초 |
요청 제한을 초과하면 429 Too Many Requests가 반환돼요.
json
{
"message": "Too many requests. Please try again in 600 seconds.",
"code": "RATE_LIMIT_EXCEPTION"
}차단된 응답에서는 x-ratelimit-reset만 내려올 수 있어요.