# rail-api — Korail gateway API (agent guide) A systematized pass-through over the Korail (코레일) mobile API. 159 operations, all reachable through one generic endpoint. This service handles anti-macro (m-token), login/session reuse, cookies, form-encoding and error mapping for you. Base URL: https://rail-api.coderyn.com ## How to call - Generic (any operation): POST https://rail-api.coderyn.com/v1/op/{operationId} body = JSON of raw korail fields - Named aliases: POST /v1/sessions (login), GET /v1/trains (=trains.search) - List operations: GET https://rail-api.coderyn.com/v1/ops (id, kind, auth, mToken, charge, note) - Machine spec: GET https://rail-api.coderyn.com/openapi.json - Health: GET https://rail-api.coderyn.com/v1/health ## Auth model - This service has its OWN users. Each user stores ONE set of korail credentials (encrypted). - Send: Authorization: Bearer on member operations. - Admin (needs ADMIN_TOKEN): POST https://rail-api.coderyn.com/admin/users {"name":"..."} -> {userId, apiKey} POST https://rail-api.coderyn.com/admin/users/{userId}/credentials {"member_no","password"[,"model","os"]} - auth levels per op: none (reference), member (needs Bearer), nonmember (send name+phone+ticket-pw in body). ## Rules - It is a PASS-THROUGH: you supply the raw korail field names (txt*, hid*, h_*) in the JSON body. The gateway adds Device/Version/Key/Lang, the m-token (for 6 protected paths), and the session cookie. - Mutations (kind write/pay/refund) REQUIRE an Idempotency-Key header. - pay/refund move real money — treat as gated. - Reservation window: boarding date <= 31 days ahead, else NOT_YET_OPEN. ## Recipes (concrete field maps) ### A. Reference read (no auth) POST https://rail-api.coderyn.com/v1/op/global.stations body: {"stnLang":"ko"} POST https://rail-api.coderyn.com/v1/op/codes.get body: {"code":"app.login.cphd"} ### B. Establish session (member) POST https://rail-api.coderyn.com/v1/sessions header: Authorization: Bearer → {ok, custNo, mbCrdNo}. A session is also auto-established on the first member op. ### C. Search trains (op: trains.search — m-token handled for you) POST https://rail-api.coderyn.com/v1/op/trains.search body: { "radJobId":"1","srtCheckYn":"N", "txtGoAbrdDt":"YYYYMMDD", // boarding date, <= 31 days ahead "txtGoStart":"서울","txtGoEnd":"부산", "txtGoHour":"060000", // from-time HHMMSS "txtTrnGpCd":"100", // 100=KTX 101=ITX/새마을 102=무궁화 109=all "txtPsgFlg_1":"1" } → data.trn_infos.trn_info[]: each has h_trn_no, h_trn_clsf_cd, h_trn_gp_cd, h_run_dt, h_dpt_dt, h_dpt_tm, h_dpt_rs_stn_cd, h_dpt_stn_cons_ordr, h_dpt_stn_run_ordr, h_arv_rs_stn_cd, h_arv_stn_cons_ordr, h_arv_stn_run_ordr, h_gen_rsv_cd ("00"=seats available, "13"=sold out), h_spe_rsv_cd (special/first class). ### D. Reserve a seat hold (op: reservation.ticketReserve — WRITE, needs Idempotency-Key) Pick a train t from search where h_gen_rsv_cd=="00". 1 adult, auto general seat, one-way: POST https://rail-api.coderyn.com/v1/op/reservation.ticketReserve header: Idempotency-Key: body: { "txtMenuId":"11","txtJobId":"1101","hidFreeFlg":"N","txtStndFlg":"N", "txtTotPsgCnt":"1","txtJrnyCnt":"1", "txtSeatAttCd1":"000","txtSeatAttCd2":"000","txtSeatAttCd3":"000","txtSeatAttCd4":"015","txtSeatAttCd5":"000", "txtCompaCnt1":"1","txtPsgTpCd1":"1","txtDiscKndCd1":"000", "txtJrnyTpCd1":"11","txtJrnySqno1":"001", "txtTrnNo1":t.h_trn_no,"txtTrnClsfCd1":t.h_trn_clsf_cd,"txtTrnGpCd1":t.h_trn_gp_cd, "txtRunDt1":t.h_run_dt,"txtDptDt1":t.h_dpt_dt,"txtDptTm1":t.h_dpt_tm, "txtDptRsStnCd1":t.h_dpt_rs_stn_cd,"txtDptStnConsOrdr1":pad6(t.h_dpt_stn_cons_ordr),"txtDptStnRunOrdr1":pad6(t.h_dpt_stn_run_ordr), "txtArvRsStnCd1":t.h_arv_rs_stn_cd,"txtArvStnConsOrdr1":pad6(t.h_arv_stn_cons_ordr),"txtArvStnRunOrdr1":pad6(t.h_arv_stn_run_ordr), "txtChgFlg1":"N","txtPsrmClCd1":"1" } (pad6 = left-pad numeric to 6 digits, e.g. 1 -> "000001") → data.h_pnr_no (reservation id), data.h_jrny_cnt, data.h_ntisu_lmt_dt + h_ntisu_lmt_tm (payment deadline). The hold auto-cancels if unpaid by the deadline. ### E. Cancel the hold (op: reservation.cancelCheck — this actually performs the cancel) POST https://rail-api.coderyn.com/v1/op/reservation.cancelCheck body: {"txtPnrNo":,"txtJrnySqno":"001","txtJrnyCnt":,"hidRsvChgNo":"000"} → h_msg_cd "IRG000000" on success. Verify with op reservation.view -> data.jrny_infos empty. ### F. My tickets / reservation view POST https://rail-api.coderyn.com/v1/op/myTicket.list body: {} POST https://rail-api.coderyn.com/v1/op/reservation.view body: {"timeStamp":""} ### G. Payment & refund — GATED (real money). Not executed by default. Payment (op: pay.reservationPayment) and refund (op: refund.request / refund.commission) move real money. Build them the same way (pass-through fields) but only fire with explicit intent. ## Response envelope & error codes Every op returns: {ok, code, data, korail:{strResult,h_msg_cd,h_msg_txt}, requestId} - ok=true → success (or benign "no data"). HTTP 200. - ok=false → code tells you why; korail.h_msg_cd is the upstream reason. Gateway codes (HTTP status): OK success MTOKEN_REJECTED 429 anti-macro tripped; the gateway auto-regenerates the token & retries once NOT_YET_OPEN 409 WRD000058 — reservation window not open (>31 days out) SESSION_EXPIRED 401 handled internally: the gateway re-logs-in and retries KORAIL_FAIL 409 upstream strResult:FAIL (usually input error; see korail.h_msg_txt) UPSTREAM_ERROR 502 korail 5xx; retried once for reads/idempotent AUTH_REQUIRED 401 member op without a valid Bearer apiKey LOCK_TIMEOUT 409 another mutation for the same user is in flight NO_CREDENTIALS 400 user has no korail credentials registered Common upstream h_msg_cd you'll see: IRG000000 = success (generic) IRR000018 = reserve success (hold created) IRZ000001 = query success WRT300005 = "no data" (benign) WRR000100 = input error (you omitted/mis-typed a required field) WRD000058 = reservation not yet open ## All operations (159) refund.executeOnline [refund,charge] auth=member refunds.executeOnlineRefunds — 온라인 환불 실행 — 구매이력 불요(pnrNo+원권튜플만). goods.cacheRead [read] auth=none goods.cacheRead.do research.commutationInfo [read] auth=member research.cmtrInfo.do push.crewCallList [read] auth=member push.crwCallRq.do global.stations [read] auth=none /ebizcom/com.korail.mobile.global.stations.do maas.cancelFee [read] auth=member maas.cncFee.do copt.maasDetailList [read] auth=member copt.gdReqQry.do ncard.history [read] auth=member ticket.dcntCrdUseQry.do product.detail [read] auth=member product.ReservationDetail product.list [read] auth=member product.ReservationList goods.meta [read] auth=none goods.meta.do pass.seatInfo [read] auth=member pass.seatInfo.do — 패스 좌석지정 대상 조회(wctNo/saleDt/saleSqno/tkRetPwd 페이징). tripChange.originalTicket [read] auth=member research.tripChgOgtk.do — 여정변경용 원권(원승차권) 조회. tripChange.dates [read] auth=member reservation.tripChgDate.do — 변경가능 날짜 조회(GET). pass.otrReserve [write] auth=member pass.passOtrReserve — OTR(좌석없는 패스권) 예약, passOtrPayIssue 로 이어짐. product.payInfo [read] auth=member product.payInfo — 여행상품 결제 사전확인(strLumpStlTgtNo 획득). maas.reserveStatus [read] auth=member maas.rsvStt.do — 응답 empty(봉투만). mileage.accompanySave [write] auth=member mileage.acpnMlgSave.do delay.acceptProcess [write] auth=member delay.acptPrs.do — 지연배상금 수락처리. research.actualSchedule [read] auth=member research.actualTrainSchedule.do cart.add [write] auth=member cart.addCartList seats.airportBusResidual [read] auth=member lms.TResidualSeatsResearch.do — 공항버스 좌석맵 — research.TResidualSeatsResearch 와 동일 스키마. mileage.amountSpec [read] auth=member mlg.amtSpec.do research.assignScheduleView [read] auth=member research.assignScheduleView.do addService.buyConfirm [write] auth=member addService.buyConfirm.do goods.cacheCheck [read] auth=none goods.cacheCheck.do checkin.cancel [write] auth=member checkin.cnc.do — 필드명 saleDt(psbFlg/reg 는 saleDd). addService.wheelchairCancel [write] auth=member addService.reserve.do — addService.reserve.do 는 다기능 경로(postRequestWheelchairWithHistory 와 공유), jobDvCd 로 분기. cashReceipt.issue [write] auth=member cashReceipt.issue.do delay.cashRefund [write] auth=member dlay.cashRfn.do — 명시적 @Field 바디(In 모델 없음) — 계좌환불(dmnPrsDvCd/dptnBankCd/dptnAcntNo). cert.congressperson [read] auth=member certification.assemblyCert — 국회의원 무임(GET). cert.merit [read] auth=member certification.MeritCert — 국가유공자 인증. qry.transferStation [read] auth=member qry.chtnStn.do codes.get [read] auth=none common.code.do — common.code.do 공유 — 단일 코드셋. codes.getMulti [read] auth=none common.code.do — common.code.do 공유 — 복수 코드셋 변형. crypto.encrypt [read] auth=none common.encrypt.do — common.encrypt.do 공유(postKBPayEncrypt 와 동일 경로). passCard.coupons [read] auth=member passCard.CouponView research.custTripInfo [read] auth=member research.custTripInfo.do research.ncardInfo [read] auth=member research.dcntCrdInfo.do research.ncardScheduleView [read] auth=member research.dcntCrdScheduleView.do crypto.decrypt [read] auth=none common.decrypt.do delay.certificate [read] auth=member dlay.athnIsu.do — 지연증명서 발급조회. passCard.delayDiscount [read] auth=member passCard.DelayDiscountView — 페이징 Query h_page_no. delay.returnReceipt [read] auth=member dlay.pymtRcet.do account.delete [write] auth=member login.mbSced.do — 회원탈퇴 — login.mbSced.do 이지만 로그인 세션 필요. addSrv.wheelchairHistoryDelete [write] auth=member addSrv.helpSrvCust.do — helpSrvCust.do 다기능 경로(qryDvCd/addSrvDvCd 분기). tk.receivedTicketHistory [read] auth=member tk.pbpAcepSpec.do — 받은승차권 내역. tk.deliveryReceiver [read] auth=member tk.dlvRcvCust.do gift.send [write] auth=member giftInfo.GiftSend — 승차권 선물 발송(+presentMap) → 변경 예약번호 chgePbpRsvNo. tk.deviceReset [write] auth=member tk.dvcInfoInit.do — 기기정보 초기화(디바이스 바인딩 리셋). cert.disability [read] auth=member certification.disabled.do passCard.discountCheck [read] auth=member passCard.DiscountCheck delay.depositBankList [read] auth=member dlay.dptnBank.do — 명시적 @Field(Device/Version/Key만) — 계좌환불용 은행목록. ebizcross.uuid [read] auth=none /ebizcross/getUUID.do — 크로스서비스 UUID 발급 유틸(인증 전). trn.freeSeatCar [read] auth=member trn.fresScar.do copt.stationConvenienceMenu [read] auth=member copt.gdMenuLt.do — 역편의 URL 메뉴(엘리베이터/주차/BIS). refund.ticketDetail [read] auth=member refunds.SelTicketInfo — refunds.* 이지만 조회(반환대상 상세). tk.guardianSms [write] auth=member tk.gurdSmsSnd.do — 보호자 SMS 발송(사이드이펙트 액션). reservation.guideSeatCondition [read] auth=member reservation.guideSeatCnd.do login.inquiryIsMember [read] auth=none login.joinCfm.do — joinCfm — 회원존재 확인(인증 전). reservation.ticketRsvInquiry [read] auth=member certification.ReservationList — certification.ReservationList 공유 — 경량변형(hidPnrNo만). pay.integratedSettlement [pay,charge] auth=member pay.intgStl.do — 통합(장바구니) 정산(+PaymentMethod 그리드). crypto.kbPayEncrypt [read] auth=none common.encrypt.do — common.encrypt.do 공유(postCommonEncrypt 와 동일 경로) — KB페이 변형. krPass.list [read] auth=nonmember /ebizcom/krPassLstDtl.do — 외국인 코레일패스 조회(여권/이메일/비번). krPass.changeStartDate [write] auth=nonmember /ebizcom/krPassChgStDt.do krPass.flexiDateFix [write] auth=nonmember /ebizcom/krPassFxDateFix.do — Flexi 이용일 확정. krPass.payment [pay,charge] auth=nonmember /ebizcom/krPassPayment.do — enc 카드필드+3DS, 외국인 결제. mileage.lpointAuth [read] auth=member mlg.lpotAthn.do — L포인트 인증(auth/cert 성격). qr.localRailwayAuth [read] auth=member qr.bchTripSv.do — 벽지노선 여행 QR 인증. session.login [write,mtoken] auth=none login.Login — 🔒 m-token 게이트 — 세션 확립(JSESSIONID). login.authRegister [write] auth=member login.loginAthnReg.do — 로그인 인증(생체 등) 등록. login.authRemove [write] auth=member login.loginAthnRmv.do — 로그인 인증 해제. session.logout [write] auth=none login.Logout — 세션 파기. ebizcom.lostCenterSearch [read] auth=none /ebizcom/cs/guide/lost/srchLostCenter.do — 분실물센터 검색(공개). addService.maasCancelPay [write] auth=member addService.cancelPay.do addService.maasServiceCancel [write] auth=member addService.coptCnc.do — addService.coptCnc.do. ebizmaas.stationList [read] auth=none /ebizmaas/EbizMaasStationList.do — MaaS 역목록(참조데이터). cust.matchedDiscountTarget [read] auth=member cust.mchdDcntTgt.do member.verify [read] auth=none member.verify.do research.mergeSeats [read] auth=member research.mergeSeatsC.do — 중간승차역 좌석연속 조회. file.mobilePlusMain [read] auth=none /file/CACHE/prdMobilePlusMain.cache — 정적 캐시 파일. file.mobileService [read] auth=none /file/CACHE/MobileService.cache — 정적 캐시 파일. myTicket.list [read] auth=member myTicket.MyTicketNewList.do xPoint.myView [read] auth=member xPoint.MyXPointView reservation.ncardExtension [write] auth=member reservation.dcntCrdExtn.do — N카드 연장(상태변경). pay.naverPayMoney [pay,charge] auth=member pay.naverPayMoneyRsv.do pay.naverPay [pay,charge] auth=member pay.naverPayRsv.do — stlScnUrl(결제화면 URL) 반환 — 웹뷰 리다이렉트. nonMember.ticketReserve [write,mtoken] auth=nonmember nonMember.NonMemTicket — 🔒 m-token — 비회원 예매(이름+전화+비번), PNR 생성, 세션 없음. nonMember.ticketList [read] auth=nonmember nonMember.NonMemTicketList xPoint.okCashbagCert [read] auth=member xPoint.OkCashbagCertView pass.infoList [read] auth=member pass.passInfoList pass.menu [read] auth=member pass.passMenu.do pass.otrPayIssue [pay,charge] auth=member pass.passOtrPayIssue — OTR 발권(결제+발권, 3 map). pass.payIssue [pay,charge] auth=member pass.passPayIssue — 패스 결제+발권(fromPassReserveInfo 로 예약객체→결제요청). pass.reserve [write] auth=member pass.passReserve pass.scheduleInfoList [read] auth=member pass.passScheduleInfoList pay.payco [pay,charge] auth=member payment.reserve.payco.do delay.pnrQuery [read] auth=member delay.pnrQry.do login.popupConfirmRecord [write] auth=member login.poppCfmRec.do — 팝업 확인 기록 저장. trn.priceFare [read,mtoken] auth=member trn.prcFare.do — 🔒 m-token 게이트 — 운임계산(조회). reservation.priceReCalculation [write] auth=member certification.PriceReCalculation — PNR 재계산(6개 병렬 @Field 승객행) — 마스터표 W. push.update [write] auth=member push.update — 푸시 등록/토큰 갱신. railplus.autoCharge [write] auth=member railplus.autoCharge.do tk.recentDeliveryHistory [read] auth=member tk.rcntDlvHst.do refund.commission [read] auth=member refunds.CommissionView — CommonIn 미상속 — Device/Version/Key/Lang + h_comp_nm/h_comp_cert_no/ctlDvCd 명시 전송. refund.request [refund,charge] auth=member refunds.RefundsRequest — CommonIn 미상속 — 환불 실행. addSrv.wheelchairRequest [write] auth=member addSrv.helpSrvCust.do — helpSrvCust.do 다기능 경로. addService.wheelchairReRequest [write] auth=member addService.reserve.do — addService.reserve.do 다기능 경로(postCancelWheelchair 와 공유) — 이력 재신청. reservation.cancel [write] auth=member reservationCancel.ReservationCancel — 실제 취소 실행(txtPnrNo/txtJrnySqno/txtJrnyCnt). reservation.cancelCheck [read] auth=member reservationCancel.ReservationCancelChk — 취소 사전확인(수수료/addSrvRetList 반환) — 실제 취소는 ReservationCancel 이 수행. reservation.change [write] auth=member reservation.reservationChange.do reservation.list [read] auth=member certification.ReservationList — certification.ReservationList 공유 — 전체변형(psgDisc0019List). pay.reservationPayment [pay,charge] auth=member payment.ReservationPayment — payment.ReservationPayment 공유(postRsvPayment 와 동일 경로) +PaymentMethod 그리드 — 평문 PAN/VAN_PWD. reservation.view [read] auth=member reservation.ReservationView — timeStamp 캐시버스터. reservationWait.register [write] auth=member reservationWait.ReservationWait — 명절 대기예약(기존 PNR에 등록). tk.retrieveTicket [write] auth=member tk.pbpWdrw.do — 보낸승차권 철회(withdraw). pay.rsvPayment [pay,charge] auth=member payment.ReservationPayment — payment.ReservationPayment 공유(postReservationPayment 와 동일 경로) — RsvPaymentIn 변형(hidRsvChgNo). schedule.runDate [read] auth=member schedule.runDt lmu.scheduleQuery [read] auth=member lmu.scdlQry.do trains.search [read,mtoken] auth=member seatMovie.ScheduleView — 🔒 m-token — 열차조회, 페이징 h_next_pg_flg + qryStNo/qryStTrnNo. trains.searchSpecial [read,mtoken] auth=member seatMovie.ScheduleViewSpecial — 🔒 m-token — 특별열차 조회. ebizcom.travelProductSearch [read] auth=member /ebizcom/gdLstDtl.do reservation.seatAssign [write] auth=member reservation.seatAssign.do — 좌석지정 예약 → ReservationOut(PNR 생성). checkin.info [read] auth=member checkin.info.do — 필드명 saleDt(psbFlg/reg 는 saleDd). checkin.possible [read] auth=member checkin.psbFlg.do — 필드명 saleDd + qrcode. checkin.register [write] auth=member checkin.reg.do — 필드명 saleDd + 물리좌석(scarNo/seatNo). crypto.shinhanEncrypt [read] auth=member shinhan.Encrypt.do — 신한카드 암호화 유틸. cart.show [read] auth=member cart.showCartList pay.samsungPayDecrypt [pay,charge] auth=member pay.spayCphdDatVal.do — 삼성페이 — 서버복호로 stlCrCrdNo 반환. pay.monimoDecrypt [pay,charge] auth=member pay.monimoDecrypt.do — 모니모 — 서버복호 stlCrCrdNo. pay.samsungPayOrderNo [pay,charge] auth=member pay.spayOrdNo.do — encTotTxnAmt AES-256-CBC(키=AppLoginCphd). common.specificDateData [read] auth=none common.specificDateData.do integrate.srCheck [read] auth=none integrate.srCheck.do integrate.srJoin [write] auth=member integrate.srJoin.do — SR 통합회원 가입(join). common.stationData [read] auth=none common.stationdata common.stationInfo [read] auth=none common.stationinfo pay.realtimeAccount [pay,charge] auth=member pay.stbkAcnt.do — 실시간계좌이체 — 예금주 조회(pay.* 경로라 kind=pay). pay.stbkBankList [pay,charge] auth=member pay.stbkRegBank.do — 은행목록 조회(pay.* 경로라 kind=pay). pay.settlementKeyProcess [pay,charge] auth=member pay.stlKeyPrs.do — 정산키 등록. pay.settlementKeyQuery [pay,charge] auth=member pay.stlKeyQry.do — 등록 정산키 목록 조회(pay.* 경로라 kind=pay). seats.residual [read] auth=member research.TResidualSeatsResearch.do — 좌석맵(잔여석). ticket.dupCheck [read] auth=member ticket.ticketDupCheck.do receipt.info [read] auth=member receipt.ReceiptInfo reservation.ticketReserve [write,mtoken] auth=member certification.TicketReservation — 🔒 m-token — 발권요청(자동/입석), PNR 생성. myTicket.widget [read] auth=member myTicket.MyTicketWidget.do — encMbCrdNo(암호 회원카드). pay.tossBillingKey [pay,charge] auth=member pay.tossautoC.do — 토스 빌링키. trainsInfo.tourTrainSpecialRoom [read] auth=member trainsInfo.TourTrainSpecialRoom pass.travelGoodsMenu [read] auth=member pass.trGdMenuLt.do research.trainResearch [read] auth=member research.TrainResearch tripChange.handleCancel [write] auth=member ticket.tripChgHndgCnc.do — 변경 수기취소(+lumpStlTgtMap 동적). tripChange.process [write] auth=member reservation.tripChgPrsC.do — 여정변경 확정 → 신규 PNR(ReservationOut). login.userCheck [read] auth=none login.userCheck addSrv.wheelchairHistory [read] auth=member addSrv.helpSrvCust.do — helpSrvCust.do 다기능 경로(조회 변형). addSrv.wheelchairResult [read] auth=member addSrv.helpSrvTk.do xPoint.view [read] auth=member xPoint.XPointView product.cancel [write] auth=member product.ReservationCancel — GET 메서드이지만 취소 실행. push.crewCall [write] auth=member push.callCrew.do — 승무원 호출(사이드이펙트 액션). self.seatChangeInfo [read] auth=member self.seatChgInfo.do — 좌석변경 가능조회. refund.verifyOnline [read] auth=member refunds.verifyOnlineRefunds — refunds.* 이지만 조회(검증) — CommonOut 미상속.