메인 콘텐츠로 건너뛰기

에러 응답 형식

{
  "success": false,
  "error": {
    "code": "INVALID_API_KEY",
    "message": "API Key is invalid or inactive",
    "timestamp": "2026-03-06T12:00:00.000Z"
  }
}

HTTP 에러 코드

코드HTTP설명
BAD_REQUEST400요청 본문 검증 실패 (필수 필드 누락, 형식 오류)
INVALID_API_KEY401API Key 누락, 무효, 또는 비활성 게임
RATE_LIMITED429요청 빈도 제한 초과
SESSION_NOT_FOUND404게임 세션을 찾을 수 없음 (만료/삭제)
SESSION_ENDED410게임 세션이 이미 종료됨
SESSION_ENDING410게임 세션 종료 진행 중 (유예 기간)
ALREADY_ENDED409이미 종료된 세션에 대한 중복 종료 시도
INTERNAL_ERROR500서버 내부 오류

비즈니스 상태 코드

HTTP 200으로 반환되며, 응답 body의 reason 또는 result 필드로 전달됩니다.

verify 응답 reason

reason설명게임 서버 처리
OTT_EXPIREDOTT 만료 (1분 초과)유저에게 런처 재실행 안내
OTT_ALREADY_USEDOTT 이미 사용됨중복 접속 방지 — 유저 킥
GAME_MISMATCHOTT/API Key 게임 불일치잘못된 OTT — 유저 킥
NOT_CHARGEABLE과금 불가 (G-coin 부족)유저에게 G-coin 충전 안내

heartbeat 응답 result

result설명게임 서버 처리
OK정상다음 하트비트까지 대기
CHARGE_EXHAUSTEDG-coin 소진유저에게 안내, 서버 2분 유예 후 자동 종료
SESSION_REPLACED같은 PC에서 다른 세션 시작됨하트비트 중지. 세션 종료 API 호출 불필요

에러 처리 패턴

재시도 가능한 에러

-- 네트워크 에러, 5xx 에러는 다음 하트비트 주기에 재시도
if err == "NETWORK_ERROR" or string.sub(err, 1, 5) == "HTTP_5" then
    warn("[Playwave] Temporary error, will retry:", err)
    -- 다음 루프 주기에 자동 재시도
end

세션 소멸 에러

-- 404/410 에러는 세션이 사라진 상태 — 하트비트 중지 + 유저 킥
if err == "HTTP_404" or err == "HTTP_410" then
    activeSessions[userId] = nil
    local player = Players:GetPlayerByUserId(userId)
    if player then
        player:Kick("PlayWave session expired")
    end
end

무시 가능한 에러

-- 세션 종료 시 404/409는 이미 정리된 상태 — 무시
if err == "HTTP_404" or err == "HTTP_409" then
    -- 정상 동작 — 세션이 이미 정리됨
    return
end