❗ 에러 코드
API 요청 시 발생할 수 있는 에러 응답 형식과 에러 코드 목록입니다.
에러 응답 형식
에러 발생 시 다음 형식의 JSON 응답이 반환됩니다.
{
"status": 400,
"error": "Bad Request",
"message": "URL은 필수 입력값입니다.",
"timestamp": "2026-01-15T14:30:00"
}
{
"error": "TOKEN_NOT_FOUND",
"errorCode": 1001,
"code": 1001,
"message": "The token was not found or has expired"
}
| 필드 | 타입 | 설명 |
| status | Integer | HTTP 상태 코드 |
| error | String | 에러 유형 또는 에러 식별자 |
| errorCode | Integer | 서비스 에러 코드 (딥링크 API) |
| code | Integer | 에러 코드 (errorCode와 동일값) |
| message | String | 사람이 읽을 수 있는 에러 메시지 |
| timestamp | String | 에러 발생 시각 (ISO 8601) |
HTTP 상태 코드
| 코드 | 상태 | 설명 | 대응 방법 |
| 400 |
Bad Request |
잘못된 요청 (입력값 유효성 검증 실패) |
요청 파라미터와 본문 확인 |
| 401 |
Unauthorized |
인증 실패 (잘못된 API Key, 만료된 토큰) |
API Key 또는 JWT 토큰 확인, 토큰 갱신 |
| 403 |
Forbidden |
권한 부족 (역할 또는 구독 미충족) |
사용자 역할, 애드온 구독 상태 확인 |
| 404 |
Not Found |
리소스를 찾을 수 없음 |
요청 경로와 ID 확인 |
| 409 |
Conflict |
리소스 충돌 (중복된 별칭, 이미 존재하는 도메인) |
다른 별칭 또는 값 사용 |
| 429 |
Too Many Requests |
레이트 리미팅 초과 |
잠시 대기 후 재시도 |
| 500 |
Internal Server Error |
서버 내부 오류 |
잠시 후 재시도, 지속 시 고객센터 문의 |
딥링크 에러 코드
Mobile SDK 딥링크 API에서 사용하는 전용 에러 코드입니다.
토큰 관련 (1001~1010)
| 코드 | 식별자 | 설명 | 대응 방법 |
| 1001 |
MISSING_TOKEN |
토큰 파라미터가 누락됨 |
token 쿼리 파라미터 포함 필요 |
| 1001 |
TOKEN_NOT_FOUND |
토큰이 존재하지 않거나 만료됨 |
새 링크 클릭 필요 (토큰 재생성) |
| 1002 |
FINGERPRINT_NOT_MATCHED |
핑거프린트 매칭 실패 |
기기 정보 확인, 시간 초과 가능성 검토 |
| 1004 |
MISSING_CAMPAIGN_ALIAS |
캠페인 별칭이 누락됨 |
캠페인 별칭을 URL 경로에 포함 |
앱 인증 관련 (1101~1199)
| 코드 | 식별자 | 설명 | 대응 방법 |
| 1101 |
INVALID_APP_ID_FORMAT |
App ID 형식이 올바르지 않음 |
App ID 값 형식 확인 |
| 1101 |
MISSING_APP_ID |
X-App-ID 헤더가 누락됨 |
X-App-ID 헤더 추가 |
| 1102 |
INVALID_APP_ID |
등록되지 않은 App ID |
콘솔에서 앱 등록 상태 확인 |
| 1103 |
APP_KEY_MISMATCH |
App API Key가 App ID와 불일치 |
앱에 발급된 올바른 API Key 사용 |
| 1104 |
TOKEN_APP_MISMATCH |
토큰이 다른 앱에서 생성됨 |
해당 앱의 토큰인지 확인 |
일반 비즈니스 에러
URL/캠페인 관련
| HTTP | 에러 메시지 | 원인 |
| 400 | URL은 필수 입력값입니다 | 원본 URL이 누락됨 |
| 400 | 유효하지 않은 URL 형식입니다 | URL 형식이 올바르지 않음 |
| 409 | 이미 사용 중인 별칭입니다 | 커스텀 별칭이 이미 존재함 |
| 404 | URL을 찾을 수 없습니다 | 잘못된 ID 또는 삭제된 URL |
| 404 | 캠페인을 찾을 수 없습니다 | 잘못된 ID 또는 삭제된 캠페인 |
| 403 | 이 리소스에 대한 권한이 없습니다 | 다른 사용자/조직의 리소스에 접근 시도 |
인증/권한 관련
| HTTP | 에러 메시지 | 원인 |
| 401 | 유효하지 않은 API Key입니다 | 잘못되거나 폐기된 API Key |
| 401 | 토큰이 만료되었습니다 | JWT Access Token 만료 |
| 401 | 잘못된 자격 증명입니다 | 아이디 또는 비밀번호 오류 |
| 403 | IP 주소가 허용 목록에 없습니다 | IP 화이트리스트에 없는 IP에서 접근 |
| 403 | 해당 기능을 사용하려면 애드온 구독이 필요합니다 | 필요한 애드온 미구독 |
앱/도메인 관련
| HTTP | 에러 메시지 | 원인 |
| 400 | 앱 이름은 필수입니다 | 필수 필드 누락 |
| 409 | 동일한 이름의 앱이 이미 존재합니다 | 조직 내 중복 앱 이름 |
| 409 | 이미 등록된 도메인입니다 | 중복 도메인 등록 시도 |
| 400 | 도메인 검증에 실패했습니다 | DNS CNAME 설정 오류 |
레이트 리미팅
| HTTP | 에러 메시지 | 대응 |
| 429 | 요청 횟수 제한을 초과했습니다 | 잠시 대기 후 재시도. Retry-After 헤더 확인 |
에러 처리 가이드
💡 에러 처리 모범 사례
- 401 에러: JWT 토큰 만료 시 Refresh Token으로 자동 갱신 구현
- 429 에러: 지수 백오프(Exponential backoff) 재시도 로직 구현
- 400 에러: 요청 전 클라이언트 측 유효성 검증 수행
- 5xx 에러: 서버 측 문제이므로 잠시 후 재시도
async function callApi(url, options) {
try {
const response = await fetch(url, options);
if (!response.ok) {
const error = await response.json();
switch (response.status) {
case 401:
// 토큰 갱신 시도
await refreshToken();
return callApi(url, options);
case 429:
// 레이트 리미팅 - 대기 후 재시도
const retryAfter = response.headers.get('Retry-After') || 5;
await sleep(retryAfter * 1000);
return callApi(url, options);
default:
throw new Error(error.message);
}
}
return response.json();
} catch (err) {
console.error('API 호출 실패:', err.message);
throw err;
}
}