OTP 이메일 · 회원 탈퇴/취소 API 가이드
백엔드 운영·프론트 연동 시 참고용 문서입니다. OpenAPI 스펙은 /api/v1/docs (Swagger UI)에서 동일 내용이 엔드포인트 설명으로 노출됩니다.
1. 이메일 OTP 발송 — POST /api/v1/accounts/otp/send
| 항목 |
내용 |
| 인증 |
없음 (auth=None) |
| 용도 |
회원가입 전 이메일 소유 확인 |
동작 요약
- 이미 활성(
is_active=True)인 동일 이메일이 있으면 400 + DUPLICATE_EMAIL.
- 비활성 임시 사용자가 없으면
is_active=False 임시 계정을 만들고 랜덤 닉네임을 부여합니다.
- DB에 OTP 레코드를 생성한 뒤 메일을 보냅니다.
- Celery(큐) 로 먼저 발송을 예약하고, Redis 브로커에 약 5초 안에 응답이 없으면 동기 SMTP 스레드로 폴백합니다.
- 그래서 HTTP 응답이 수 초 걸릴 수 있습니다(정상).
제한
- 동일 사용자 기준 5분에 최대 2회 발송 초과 시
429 + RATE_LIMIT_EXCEEDED.
- OTP는 6자리 숫자, 유효 시간 10분 (
expires_at).
응답 예시 (200)
{
"detail": "OTP가 발송되었습니다.",
"expires_at": "2026-04-14T16:47:24.825000+09:00"
}
연관 API
POST /api/v1/accounts/otp/verify — 코드 검증
POST /api/v1/accounts/signup 등 — 검증 후 가입 완료
2. 이메일 OTP 검증 — POST /api/v1/accounts/otp/verify
- 본문:
email, otp(6자리 숫자).
- 만료·시도 초과·불일치 시
400 및 고정 error 코드(OTP_NOT_FOUND, OTP_EXPIRED, OTP_MAX_ATTEMPTS, OTP_MISMATCH 등).
3. 탈퇴 신청 — POST /api/v1/accounts/withdraw
| 항목 |
내용 |
| 인증 |
JWT 필수 (Authorization: Bearer …) |
비밀번호 필드
password를 보낸 경우 현재 비밀번호와 일치해야 합니다.
- 생략 시 비밀번호 검사 없이 진행될 수 있습니다(제품 정책에 맞게 사용).
구독·슬롯
- 유료(플랜 가격 > 0) 활성 구독이 있으면 탈퇴 불가 — 환불·해지 후 재시도.
- 무료(가격 0) 활성 구독은 탈퇴 신청 시 자동
CANCELLED.
- 본인 활성 슬롯은
INACTIVE로 전환.
계정 상태
is_active=False, deleted_at 설정, pending_delete_at은 통상 14일 후.
- 유예 중 로그인은 허용되어 탈퇴 취소·안내가 가능합니다.
- 탈퇴 직후 기존 액세스 토큰으로 보호 API를 호출하면 401이 될 수 있습니다 → 아래 취소 또는 재로그인.
4. 탈퇴 취소 — POST /api/v1/accounts/withdraw/cancel
| 항목 |
내용 |
| 인증 |
없음 (auth=None) — Authorization 없이 호출하는 것을 권장 |
요청 본문 (JSON)
| 필드 |
필수 |
설명 |
email |
강력 권장 |
탈퇴한 계정 이메일 |
password |
필수 |
계정 비밀번호 |
유예 기간(pending_delete_at 이전)에만 성공합니다.
성공 시
- 계정 활성화, 탈퇴 관련 타임스탬프 제거.
- 활성 구독이 없으면 기본 무료 구독 재생성.
- 슬롯은 자동으로 다시 켜지지 않습니다. 운영 정책상 관리자 복구 또는 별도 API가 필요할 수 있습니다.
권장 클라이언트 플로우
- 탈퇴 신청 후 토큰이 무효화되면
POST /accounts/withdraw/cancel에 email + password만 전송.
- 성공 후
POST /accounts/login으로 새 토큰 발급.
5. 로그인과 탈퇴 유예
- 일반 비활성 계정은 로그인 거부.
- 탈퇴 유예 중(
pending_delete_at이 미래)인 비활성 계정은 로그인 허용 — 취소·고객 안내용.
6. 운영 메모 (Celery / Redis)
- OTP는 Celery 워커가 정상일 때 큐로 발송됩니다.
- 브로커 지연 시 위에서 설명한 폴백으로 메일은 도착할 수 있으나, 장기적으로는 Redis 연결·방화벽을 점검하는 것이 좋습니다.
관련 링크