일회용, 오타, 메일 서버 없는 가입 이메일 잡아내기
가입 양식에서 모든 주소를 초기에 검사하세요: 구문, 알려진 일회용/임시 도메인, 도메인에 메일 서버가 있기나 한지, 가능성 있는 오타와 역할 주소를 확인하고, 그 사유와 함께 accept, review 또는 reject 판정으로 반환합니다. 양식 자체의 JavaScript에서 POST /v1/email/validate를 호출하거나, 백엔드나 대시보드에서 목록을 일괄 검사하세요.
요청 및 인증
X-Api-Key 헤더에 오리진에 고정된 공개 가능 키를 넣어 POST /v1/email/validate로 { "email": "user@example.com" } 형태의 JSON 본문을 전송하세요 — GET /v1/geo와 동일한 키 유형 및 허용 오리진 모델이므로, 방문자가 입력하거나 제출할 때 가입 양식에서 직접 호출해도 안전합니다. 서버 사이드에서는 시크릿 키로 POST /v1/email/batch(요청당 최대 100개 주소), 최대 100,000개 주소의 비동기 목록 작업(API 또는 대시보드의 Email lists 페이지, CSV 입력과 CSV 출력), 그리고 이메일 검사와 가입하는 IP의 네트워크 지표를 하나의 점수로 결합하는 POST /v1/signup/check를 사용할 수 있습니다.
판정을 먼저 읽고, 그다음 사유를 읽으세요
verdict는 가장 심각한 결과입니다: 유효하지 않은 구문, 존재하지 않는 도메인, 메일 서버 없는 도메인, 일회용 도메인이면 reject, 오타 의심, info@ 같은 역할 주소, 암시적 메일 서버만 있는 도메인, 완료되지 않은 DNS 조회면 review, 그 외에는 accept입니다. reasons에는 해당된 모든 조건이 나열되므로 양식에서 구체적인 메시지를 보여 줄 수 있습니다 — didYouMean이 설정되어 있으면 오류 대신 수정을 제안하세요.
호출 시점
키를 누를 때마다가 아니라 입력란을 벗어날 때나 제출할 때 호출하세요 — 아직 완성되지 않은 주소를 글자마다 검사하면 유용한 신호 없이 요청만 늘고, 방문자가 입력하는 동안 오류 메시지가 깜빡일 수 있습니다. 호출마다 요청 1건으로 계산됩니다.
요청이 실패하면
실패 시 허용(fail open)하세요: 클라이언트 측 장애 때문에 모든 방문자를 차단하지 말고, 네트워크 요청이 오류를 내거나 시간 초과되면 가입을 계속 진행하게 하세요. 서버 사이드에서 DNS 조회 실패는 오류나 reject가 아니라 사유 dns_unavailable(판정 review)로 보고됩니다. 검사가 실패해도 방문자가 입력한 내용을 잃지 않도록 이미 입력한 내용을 보존하세요.
일회용 도메인을 탐지하는 방법
알려진 일회용/임시 도메인은 커뮤니티가 관리하는 세 가지 오픈 소스 목록(데이터 소스 참고)을 병합한 것으로, 몇 시간마다 갱신되며, 상위 소스의 잘못된 항목이 주요 제공자를 표시하지 못하도록 허용 목록을 함께 사용합니다. 목록에 있는 도메인의 하위 도메인도 일치합니다. 아직 어떤 목록에도 없는 새로운 일회용 도메인은 메일 서버로 잡히는 경우가 많습니다. 일회용 서비스는 많은 도메인을 소수의 같은 메일 호스트로 연결하므로, 메일 서버가 목록에 있는 도메인을 처리하는 것으로 알려진 도메인은 disposableSource: mx_host로 표시됩니다. 새 메일 서버를 쓰는 아주 새로운 제공자는 아직 표시되지 않을 수 있습니다.
사용량과 할당량
검사한 모든 주소는 요금제의 공유 월간 한도에서 요청 1건으로 계산됩니다 — 단일 검사, 일괄 검사의 각 주소, 목록 작업의 각 고유 주소 — 다른 트래픽과 합산되며 분당 속도 제한도 같습니다. 별도의 이메일 요금제나 가격은 없습니다. 분당 속도 제한은 항목 수가 아니라 HTTP 호출 수를 셉니다. 최대 100개의 IP 또는 이메일 주소를 담은 배치는 1건의 요청으로 계산되며, 각 항목은 여전히 월간 요청 한도에 개별적으로 계산됩니다.
검증하지 않는 것
모든 검사는 도메인 또는 주소 수준입니다. Watch-IP는 수신자의 메일 서버에 절대 접속하지 않으므로, 결과는 메일함이 존재하는지, 메일이 도착할지, 가입하는 사람의 것인지를 입증하지 않습니다. accept 판정은 “문제가 발견되지 않음”을 뜻하며, 작동이 확인된 주소를 뜻하지 않습니다 — 그런 확인에는 확인 이메일을 사용하세요.
응답 필드
- syntaxValid
- 주소가 구문상 유효한지 여부.
- isDisposable
- 도메인이 알려진 일회용/임시 제공자와 직접, 상위 도메인을 통해, 또는 메일 서버를 통해 일치하는지 여부. syntaxValid가 false이면 항상 false.
- disposableSource
- list, parent_domain 또는 mx_host — isDisposable이 true인 이유. 그 외에는 null.
- mx
- 도메인의 메일 서버 상태(found, implicit, none, null_mx, no_domain 또는 unknown)와 기본 MX 호스트.
- didYouMean
- gmial.com → gmail.com 같은 가능성 있는 오타 수정, 또는 null.
- isRoleAccount / isFreeProvider
- 역할 주소(admin@, info@, noreply@…) 및 소비자용 메일함 제공자 플래그. 무료 제공자 플래그는 참고용입니다.
- normalizedEmail / canonicalEmail
- 소문자로 변환한 주소와, 중복 계정을 찾아내기 위해 +태그(및 Gmail의 점)를 제거한 주소.
- verdict / reasons
- accept, review 또는 reject와 해당된 모든 사유 코드 — 전체 목록은 레퍼런스를 참고하세요.
판정에 따라 조치하기
가입 폼 JavaScript
async function checkEmail(email) {
const response = await fetch('https://api.watch-ip.com/v1/email/validate', {
method: 'POST',
headers: { 'X-Api-Key': 'YOUR_PUBLISHABLE_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({ email }),
});
if (!response.ok) return { state: 'unknown' }; // 실패 시 허용 — 네트워크 오류로 가입을 막지 마세요
const result = await response.json();
if (result.didYouMean) return { state: 'suggest', suggestion: result.didYouMean };
if (result.verdict === 'reject') return { state: 'reject', reasons: result.reasons };
return { state: 'ok' }; // accept 또는 review: 가입을 통과시키고 백엔드에서 표시하세요
}사유마다 다른 메시지를 보여 주세요 — invalid_syntax, disposable_domain, no_mail_server는 방문자에게 요구하는 수정 조치가 서로 다릅니다 — 그리고 didYouMean을 클릭 한 번으로 적용하는 수정으로 제안하세요.
자주 묻는 질문
메일함이 실제로 존재하는지 확인하나요?
아니요. 구문, 도메인의 목록과 DNS 메일 서버 레코드, 주소의 형태를 검사합니다. 메일 서버에 접속하거나 개별 메일함이 실제로 있는지 확인하지 않습니다 — no_mail_server로 인한 reject는 도메인 전체에 관한 것입니다.
accept는 이메일이 작동한다는 증거인가요?
아니요. accept는 어떤 검사에서도 문제가 발견되지 않았다는 뜻이며, 주소가 반드시 메일을 받는다거나 가입하는 사람의 것이라는 뜻이 아닙니다. 그런 확인이 필요하면 확인 이메일을 사용하세요.
사용자가 브라우저 검증을 우회할 수 있나요?
예. 이 검사를 포함해 브라우저 측 검사는 JavaScript를 끄거나 가입 엔드포인트를 직접 호출해 우회할 수 있습니다. 중요한 결정은 백엔드에서 시행하세요 — POST /v1/signup/check가 바로 그 용도입니다.
기존 목록을 정리할 수 있나요?
예. 대시보드의 Email lists 페이지에서 CSV를 업로드하거나, 시크릿 키로 POST /v1/email/jobs에 최대 100,000개 주소를 제출한 다음, 행마다 판정과 사유가 담긴 결과 CSV를 다운로드하세요. 중복은 한 번만 과금되며, 업로드와 결과는 7일 후 삭제됩니다.
요청은 어떻게 집계되나요?
검사한 주소당 요청 1건으로 요금제의 공유 월간 한도에서 차감됩니다. 목록 작업 내 중복은 한 번만 계산되며, 가입 검사는 요청 1건으로 계산됩니다.