기숙사 API
기숙사비 고지서, 호실 배정, 입사 합격 고지서, 외박신청, 상벌점, 점호 마일리지
엔드포인트 목록
| 메서드 | 경로 | 설명 |
|---|---|---|
GET | /api/dorm/bill/info/ | 방학 중 생활관 고지서 정보 |
POST | /api/dorm/bill/report/ | 방학 중 생활관 고지서 출력 URL |
GET | /api/dorm/room/info/ | 방학 중 호실 배정 조회 |
GET | /api/dorm/pass/info/ | 생활관 입사 합격 여부 + 고지서 정보 |
POST | /api/dorm/pass/report/ | 합격자 고지서 출력 URL 생성 |
GET | /api/dorm/asgn/result/ | 생활관 배정결과 조회 |
GET | /api/dorm/rwpn/ | 상벌점 조회 |
GET | /api/dorm/sleepout/ | 외박 신청 현황 |
GET | /api/dorm/sleepout/sigungu/ | 외박 목적지 시군구 목록 |
POST | /api/dorm/sleepout/apply/ | 외박 신청 |
POST | /api/dorm/sleepout/cancel/ | 외박 취소 |
GET | /api/dorm/sleep-call-mileage/ | 점호 마일리지 조회 |
모든 엔드포인트는 sch_session 쿠키 인증이 필요합니다.
GET /api/dorm/bill/info/
방학 중 생활관 고지서 정보를 조회합니다. yy, smt를 생략하면 서버가 오늘 날짜 기준으로 현재 방학 학기를 자동 계산합니다.
요청
쿼리 파라미터
| 파라미터 | 타입 | 필수 | 허용값 | 설명 |
|---|---|---|---|---|
yy | string | 아니오 | 4자리 연도 | 학년도 (예: 2025). 생략 시 자동 판별 |
smt | string | 아니오 | 12, 22 | 방학 학기 코드. 12=하계, 22=동계. 생략 시 자동 판별 |
smt에 11(1학기)이나 21(2학기)를 전달하면 INVALID_SMT 오류가 반환됩니다. 이 엔드포인트는 방학 학기 코드(12, 22)만 허용합니다.
요청 예시 — 2025 하계방학 조회
GET /api/dorm/bill/info/?yy=2025&smt=12
Cookie: sch_session=<token>요청 예시 — 자동 판별
GET /api/dorm/bill/info/
Cookie: sch_session=<token>응답
200 OK
notice와 period.pass_seq는 화면 표시용입니다. POST /api/dorm/bill/report/는 이 값을 요청으로 받지 않고 서버가 다시 조회합니다.
{
"period": {
"pass_seq": "20250701",
"start_date": "2025-07-01",
"end_date": "2025-08-31"
},
"notice": {
"yy": "2025",
"smt": "12",
"orgn_div": "01",
"aply_div": "01",
"wk_div": "01",
"gp_seq": "001",
"prsnl_no": "U000001234",
"aply_cd": "A"
}
}응답 필드
| 필드 | 타입 | 설명 |
|---|---|---|
period.pass_seq | string | 고지서 일련번호 (표시용) |
period.start_date | string | 생활관 입주 시작일 YYYY-MM-DD |
period.end_date | string | 생활관 퇴소 종료일 YYYY-MM-DD |
notice.yy | string | 학년도 |
notice.smt | string | 방학 학기 코드 (12 / 22) |
notice.orgn_div | string | 기관 구분 코드 |
notice.aply_div | string | 신청 구분 코드 |
notice.wk_div | string | 주간 구분 코드 |
notice.gp_seq | string | 그룹 시퀀스 |
notice.prsnl_no | string | SCH 사용자 번호 |
notice.aply_cd | string | 신청 코드 |
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 또는 만료 |
INVALID_YEAR | 400 | yy가 4자리 숫자가 아님 |
INVALID_SMT | 400 | smt가 12 또는 22가 아님 |
SCH_UNAVAILABLE | 503 | SCH 서버 연결 실패 |
// INVALID_SMT 예시
{
"error": "INVALID_SMT",
"message": "방학 학기 코드(12, 22)만 허용됩니다."
}POST /api/dorm/bill/report/
방학 중 생활관 고지서 OZ 리포트 출력 URL을 생성합니다.
고지서 파라미터를 클라이언트에서 받지 않습니다. 서버가 세션 학번으로 GET /api/dorm/bill/info/와 동일한 조회를 다시 태워 notice·pass_seq를 직접 만듭니다. 예전에는 이 값을 요청 본문으로 받았는데, notice.prsnl_no 등이 실제 출력 대상을 결정하므로 타 학생 고지서가 발급될 수 있었습니다(BOLA).
요청
Body (application/json) — 어느 방학 고지서인지만 고릅니다. 생략하면 서버가 자동 계산합니다.
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
yy | string | 아니오 | 학년도 (YYYY) |
smt | string | 아니오 | 방학 학기 코드 — 12(하계) 또는 22(동계) |
{ "yy": "2026", "smt": "12" }응답
200 OK
{
"url": "https://report.sch.ac.kr/oz7/r.jsp?..."
}| 필드 | 타입 | 설명 |
|---|---|---|
url | string | OZ 리포트 출력 URL. 프론트엔드는 window.open()으로 엽니다 |
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 또는 만료 |
INVALID_YEAR | 400 | yy가 4자리 숫자가 아님 |
INVALID_SMT | 400 | smt가 12/22가 아님 |
NOT_PRINTABLE | 403 | 출력 가능한 고지서가 없음 |
REPORT_FAILED | 500 | SCH 서버에서 리포트 URL 생성 실패 |
SCH_UNAVAILABLE | 503 | SCH 서버 연결 실패 |
GET /api/dorm/room/info/
방학 중 호실 배정 정보를 조회합니다.
요청
쿼리 파라미터 — 없음 (서버가 현재 방학 학기 자동 감지)
GET /api/dorm/room/info/
Cookie: sch_session=<token>응답
200 OK — SCH 서버의 호실 배정 정보
{
"yy": "2025",
"smt": "12",
"bldg_nm": "향설생활관2",
"room_no": "204",
"bed_no": "A",
"room_type": "하층"
}에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 |
SCH_UNAVAILABLE | 503 | SCH 서버 연결 실패 |
GET /api/dorm/pass/info/
생활관 입사 합격 여부와 합격자 고지서 출력에 필요한 데이터를 조회합니다. 파라미터 없음 — 기준 연도/학기는 서버가 자동 결정합니다.
pass_data와 period.pass_seq는 화면 표시용입니다. POST /api/dorm/pass/report/는 이 값을 요청으로 받지 않고 서버가 다시 조회합니다.
요청
쿼리 파라미터 — 없음
GET /api/dorm/pass/info/
Cookie: sch_session=<token>응답
200 OK
{
"period": {
"pass_seq": "20250301"
},
"pass_data": {
"yy": "2025",
"smt": "11",
"wk_div": "01",
"gp_seq": "001",
"prsnl_no": "U000001234",
"aply_div": "01",
"orgn_div": "01",
"aply_cd": "A"
},
"result": {
"pass_yn": "Y",
"bldg_nm": "향설생활관2",
"room_no": "204",
"bed_no": "A",
"in_date": "2025-03-01",
"out_date": "2025-08-31"
}
}| 필드 | 타입 | 설명 |
|---|---|---|
period.pass_seq | string | 고지서 일련번호 (표시용) |
pass_data | object | 고지서 출력 파라미터 묶음 (표시용 — 요청으로 되돌려 보내지 않습니다) |
result.pass_yn | string | 합격 여부 ("Y" / "N") |
result.bldg_nm | string | 배정 생활관 건물명 |
result.room_no | string | 호실 번호 |
result.bed_no | string | 침대 위치 ("A" / "B") |
result.in_date | string | 입소 예정일 YYYY-MM-DD |
result.out_date | string | 퇴소 예정일 YYYY-MM-DD |
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 |
SCH_UNAVAILABLE | 503 | SCH 서버 연결 실패 |
POST /api/dorm/pass/report/
생활관 합격자 고지서 OZ 리포트 출력 URL을 생성합니다.
요청 본문이 없습니다. 서버가 세션 학번으로 GET /api/dorm/pass/info/와 동일한 조회를 다시 태워 pass_data·pass_seq를 직접 만듭니다. 예전에는 이 값을 요청으로 받았는데, pass_data.prsnl_no 등이 실제 출력 대상을 결정하므로 타 학생 고지서가 발급될 수 있었습니다(BOLA).
요청
Body 없음. 쿠키 sch_session만 포함합니다.
POST /api/dorm/pass/report/
Cookie: sch_session=<token>응답
200 OK
{
"url": "https://report.sch.ac.kr/oz7/r.jsp?..."
}에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 또는 만료 |
NOT_PRINTABLE | 403 | 합격 내역이 없거나 출력 가능한 고지서가 없음 |
REPORT_FAILED | 500 | SCH 서버에서 리포트 URL 생성 실패 |
SCH_UNAVAILABLE | 503 | SCH 서버 연결 실패 |
GET /api/dorm/asgn/result/
생활관 배정결과를 조회합니다. 합격 발표 후 호실 배정이 완료된 결과를 반환하며, 기준 연도/학기는 서버(TDMBASE_pSearchBaseYear)가 자동 결정합니다.
요청
쿼리 파라미터 — 없음
응답
200 OK — SCH 서버의 배정결과 (배정 생활관, 호실, 입소일 등)
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 |
AUTH_ERROR | 401 | SCH 서버 인증 오류 |
SCH_UNAVAILABLE | 503 | SCH 서버 연결 실패 |
GET /api/dorm/rwpn/
생활관 상벌점 현황을 반환합니다. 학기를 지정하지 않으면 SCH 서버에서 현재 학기를 자동 감지합니다.
요청
쿼리 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
yy | string | 아니오 | 학년도 (예: 2025). 생략 시 자동 |
smt | string | 아니오 | 학기 코드 (11 / 21). 생략 시 자동 |
요청 예시
GET /api/dorm/rwpn/?yy=2025&smt=11
Cookie: sch_session=<token>응답
200 OK — 상벌점 합계 및 상세 내역
{
"yy": "2025",
"smt": "11",
"total": -5,
"items": [
{
"date": "2025-04-10",
"type": "벌점",
"reason": "점호 불참",
"score": -5
},
{
"date": "2025-03-15",
"type": "상점",
"reason": "기숙사 청결 우수",
"score": 3
}
]
}| 필드 | 타입 | 설명 |
|---|---|---|
yy | string | 조회 학년도 |
smt | string | 조회 학기 |
total | number | 상벌점 합계 (음수 = 벌점 초과) |
items[].date | string | 부여 일자 YYYY-MM-DD |
items[].type | string | 구분 (상점 / 벌점) |
items[].reason | string | 부여 사유 |
items[].score | number | 점수 (상점 양수, 벌점 음수) |
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 |
AUTH_ERROR | 401 | SCH 서버 인증 오류 |
SCH_UNAVAILABLE | 503 | SCH 서버 연결 실패 |
GET /api/dorm/sleepout/
외박 신청 화면의 초기 데이터를 반환합니다. 기준 학기·입사 정보, 해당 월 신청 내역, 그리고 신청 폼의 선택 목록(시도·사유)을 한 번에 내려줍니다.
요청
쿼리 파라미터
| 파라미터 | 타입 | 필수 | 형식 | 설명 |
|---|---|---|---|---|
yyyymm | string | 아니오 | YYYYMM (6자리 숫자) | 조회 월. 생략 시 서버가 기준 월로 결정 |
GET /api/dorm/sleepout/?yyyymm=202609
Cookie: sch_session=<token>응답
200 OK
{
"status": "OK",
"message": "",
"month": "202609",
"term": { "YY": "2026", "SMT": "21", "STD_NO": "20201234" },
"student": { "ROOM_NO": "512", "DTLS_ROOM": "A" },
"items": [
{ "SLEEP_OUT_DT": "20260905", "APLY_STAT_NM": "신청" }
],
"sido": [
{ "code": "C0570006", "name": "서울특별시" }
],
"reasons": [
{ "code": "T1290001", "name": "귀가" }
]
}| 필드 | 타입 | 설명 |
|---|---|---|
status | string | OK / NO_TARGET(외박 대상 입사 정보 없음) / NOT_AVAILABLE(외박 신청 기준기간 없음) |
message | string | NO_TARGET일 때의 안내 문구 |
month | string | 실제로 조회한 월 (YYYYMM) |
term | object | 기준 학기 정보 (SCH 원본 행) |
student | object | 외박 신청 대상 입사 정보 (SCH 원본 행) |
items | object[] | 해당 월 외박 신청 내역 (SCH 원본 행) |
sido | object[] | 시도 선택 목록 — 서버 상수 [{code, name}] |
reasons | object[] | 외박 사유 선택 목록 — 서버 상수 [{code, name}] |
term·student·items는 SCH 서버의 XML 행을 대문자 키 그대로 전달합니다. 화면에 필요한 필드 선택과 표기는 프론트엔드가 담당합니다.
status가 OK가 아니어도 HTTP 200입니다. 이때 student·items는 비어 있고 선택 목록은 그대로 채워집니다.
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 |
INVALID_MONTH | 400 | yyyymm이 6자리 숫자가 아님 |
SCH_UNAVAILABLE | 503 | SCH 서버 연결 실패 |
GET /api/dorm/sleepout/sigungu/
외박 목적지 선택용 시군구 목록을 반환합니다. 외박 신청 폼의 2단계 지역 선택에 사용합니다.
요청
쿼리 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
sido | string | O | 시도 코드 — GET /api/dorm/sleepout/ 응답의 sido[].code. 생략하거나 빈 문자열이면 빈 목록 |
GET /api/dorm/sleepout/sigungu/?sido=C0570006
Cookie: sch_session=<token>응답
200 OK
{
"items": [
{ "code": "C0580001", "name": "종로구" },
{ "code": "C0580002", "name": "중구" }
]
}sido 미제공 시 {"items": []}를 반환합니다.
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 |
SCH_UNAVAILABLE | 503 | SCH 서버 연결 실패 |
POST /api/dorm/sleepout/apply/
외박을 신청합니다.
요청
Body (application/json)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
date | string | O | 외박 날짜 (YYYYMMDD). 지난 날짜는 신청할 수 없습니다 |
sido_code | string | O | 시도 코드 — GET /api/dorm/sleepout/ 응답의 sido[].code |
sigungu_code | string | 아니오 | 시군구 코드 — sigungu/ API로 조회 |
destination | string | O | 행선지 상세 |
reason_code | string | O | 외박 사유 코드 — reasons[].code |
emergency_contact | string | O | 비상 연락처 |
remark | string | 아니오 | 비고 |
요청 예시
{
"date": "20260905",
"sido_code": "C0570006",
"sigungu_code": "C0580001",
"destination": "서울특별시 종로구 인사동 123",
"reason_code": "T1290001",
"emergency_contact": "010-1234-5678",
"remark": "가족 행사 참석"
}응답
200 OK
{
"ok": true,
"message": ""
}서버가 신청 전에 자체 검증을 먼저 수행합니다 — 지난 날짜, 같은 날짜 중복 신청, 신청 기간·시간(00:00~23:00) 여부 등. 검증에 걸리면 SCH 서버로 요청을 보내지 않고 APPLY_FAILED와 사유를 반환합니다.
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 |
APPLY_FAILED | 400 | 신청 실패 (SCH 서버 거부 — 기간 외, 중복 신청 등) |
// APPLY_FAILED 예시 — 신청 기간 외
{
"error": "APPLY_FAILED",
"message": "외박 신청 기간이 아닙니다."
}POST /api/dorm/sleepout/cancel/
외박 신청을 취소합니다.
요청
Body (application/json)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
row | object | O | GET /api/dorm/sleepout/ 응답의 items 항목 원본. SCH 서버가 취소에 필요한 모든 식별자를 포함 |
요청 예시
{
"row": {
"SLEEP_OUT_DT": "20260905",
"APLY_STAT_NM": "신청"
}
}row 객체를 직접 구성하지 말고, GET /api/dorm/sleepout/ 응답의 items 배열에서 받은 항목을 대문자 키 그대로 전달하세요.
이미 승인된 신청, 외박일이 지난 신청은 서버가 SCH 요청 전에 걸러 CANCEL_FAILED로 응답합니다.
응답
200 OK
{
"ok": true,
"message": ""
}에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 |
INVALID_ROW | 400 | row가 없거나 객체가 아님 |
CANCEL_FAILED | 400 | SCH 서버 취소 거부 (이미 취소됨, 처리 완료 등) |
// INVALID_ROW 예시
{
"error": "INVALID_ROW",
"message": "취소할 외박 신청 정보를 찾지 못했습니다."
}GET /api/dorm/sleep-call-mileage/
점호 마일리지 현황을 반환합니다.
요청
쿼리 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
yy | string | 아니오 | 학년도 (예: 2026). 생략 시 SCH 서버에서 현재 학기 자동 감지 |
smt | string | 아니오 | 학기 코드 (11 / 21). 생략 시 자동 |
GET /api/dorm/sleep-call-mileage/?yy=2026&smt=21
Cookie: sch_session=<token>응답
200 OK
{
"status": "OK",
"yy": "2026",
"smt": "21",
"student_info": {
"hope_dorm_nm": "향설 1관",
"room_no": "512",
"dtls_room": "A",
"prsnl_no": "U000001234"
},
"term": {
"from_dt": "20260901",
"to_dt": "20261220"
},
"summary": {
"from_dt": "20260901",
"to_dt": "20261220",
"days": 84,
"call_count": 80,
"sleep_count": 3,
"unauthorized_count": 1,
"mileage_total": "79",
"score": "9.8"
},
"detail": [
{
"date": "20260901",
"call_yn": "1",
"sleep_yn": "",
"jumho": "점호",
"mil": "1"
}
]
}| 필드 | 타입 | 설명 |
|---|---|---|
status | string | OK / NOT_IN_DORM(생활관 미등록) / NO_TERM(기준기간 없음) / BEFORE_PERIOD(조회 시작일 이전) |
student_info | object | 생활관·호실 정보 |
term | object | 마일리지 기준기간 |
summary.days | number | 집계 대상 일수 |
summary.call_count | number | 점호 참여 횟수 |
summary.sleep_count | number | 외박 횟수 |
summary.unauthorized_count | number | 무단(미참여) 횟수 |
summary.mileage_total | string | 마일리지 합계 |
summary.score | string | 환산 점수. 서버가 주지 않으면 빈 문자열 — 임의로 만들어내지 않습니다 |
detail[].date | string | 일자 (YYYYMMDD) |
detail[].jumho | string | 구분 문구 (점호 / 외박 / 무단 등) |
detail[].mil | string | 해당 일자의 마일리지 |
집계 종료일은 어제입니다. 점호는 전날 밤에 마감되므로 오늘 자료는 아직 집계에 반영되지 않습니다. 기준기간이 이미 끝났으면 기간 종료일에서 자릅니다.
집계 행이 비어 있을 때만 상세 목록으로 근사치를 계산합니다. call_yn/sleep_yn의 값 표기가 일정하지 않아, 이때는 구분 문구와 마일리지 부호로 분류합니다.
status가 OK가 아니어도 HTTP 200입니다. 클라이언트가 status를 보고 안내 문구를 결정합니다.
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 |
AUTH_ERROR | 401 | SCH 서버 인증 오류 |
SCH_UNAVAILABLE | 503 | SCH 서버 연결 실패 |