API 레퍼런스
데이터를 읽고, 쓰고, 연결하는 모든 계약.
학습 데이터와 기본 업무는 API 구독으로 이용합니다. 웹 관리 기능은 웹 구독 등급·관리자 권한도 확인하며, 외부 API·MCP 호출은 API 사용량으로 집계합니다. SaaS AI 도우미는 기존 AI 크레딧을 사용하고 API 사용량에 중복 집계하지 않습니다.
엔드포인트
OpenAPI JSON ↗172 개 API
학생관리
GET/v1/teams/{id}/detail/students반별 전체 수강 이력(종료 포함·재원 인원 아님). 현재 학생 명단·인원은 students.list의 teamId 사용. 학생·수강번호·퇴원/전반/종강 사유+
teams.read · teams.detail.roster
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/teams 응답 data.items[].id의 수강반 번호입니다. |
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].studentId | string | 필수 | 학원 내 실제 학생 번호입니다. | "00000001" |
items[].studentName | string | 필수 | 학생 번호에 해당하는 실제 학생 이름입니다. | "예시 이름" |
items[].enrollment | object | 필수 | 정확한 수강 기록과 명시된 종료 사유·효력일·전반 출처입니다. | 하위 필드·본문 예시 참조 |
items[].enrollment.id | integer | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | 1 |
items[].enrollment.studentId | string | 필수 | 학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다. | "00000001" |
items[].enrollment.teamId | integer | 필수 | 수강반 고유 번호입니다. 수강반 조회에서 확인합니다. | 1 |
items[].enrollment.scheduleId | integer | 필수 | 수강반 시간표 고유 번호입니다. 해당 반의 시간표여야 합니다. | 1 |
items[].enrollment.teamName | string | 필수 | 수강반 이름입니다. | "예시 이름" |
items[].enrollment.scheduleName | string | 필수 | 시간표 표시 이름입니다. | "예시 이름" |
items[].enrollment.beginDate | integer | 필수 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | 20260115 |
items[].enrollment.endDate | integer | 필수 | 종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | 20260115 |
items[].enrollment.endType | string | 필수 | 저장된 수강 종료 사유입니다. 빈 문자열, 퇴원, 전반, 종강, 전반취소를 사용합니다. 최대 20자이며 기존의 미확인 사유도 보존합니다. 이미 시작한 수강의 미래 종료는 active, 미래 시작은 upcoming이며 전반취소는 시작일과 관계없이 항상 cancelled입니다. | "예시" |
items[].enrollment.changeDate | integer | 필수 | 전반으로 종료되는 기존 수강 건의 전반일입니다. yyyyMMdd 정수이며 0은 미설정입니다. | 20260115 |
items[].enrollment.scheduleDay | string | 필수 | 해당 수강 시간표의 실제 요일입니다. 없으면 빈 문자열입니다. | "예시" |
items[].enrollment.scheduleFrom | string | 필수 | 해당 수강 시간표의 실제 시작 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다. | "예시" |
items[].enrollment.scheduleTo | string | 필수 | 해당 수강 시간표의 실제 종료 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다. | "예시" |
items[].enrollment.transferFromId | integer | 필수 | 전반 전의 기존 수강 건 번호입니다. 연결 없는 과거 자료는 null입니다. | 1 |
items[].enrollment.transferDate | integer | 필수 | 새 반으로 전반한 지정일입니다. yyyyMMdd 정수, 0은 연결 없음입니다. | 20260115 |
items[].enrollment.previousTeamName | string | 필수 | 전반 이전 반·시간표 표시명입니다. | "예시 이름" |
items[].enrollment.isTransfer | boolean | 필수 | 명시적인 이전 수강 연결값이 있는 전반 등록인지 나타냅니다. | false |
items[].enrollment.isTransferCancelled | boolean | 필수 | 전반 취소 이력인지 나타냅니다. 취소해도 출결·수납 자료와 수강 건은 보존됩니다. | false |
items[].enrollment.transferCancelledAt | string | 필수 | 전반 취소 시각(UTC)입니다. 취소 전에는 null입니다. | "2026-01-15T00:00:00Z" |
items[].enrollment.classEndDate | integer | 필수 | 반 자체의 종강일입니다. 학생별 endDate와 별개인 yyyyMMdd 정수이며 0은 미설정입니다. | 20260115 |
items[].enrollment.effectiveEndDate | integer | 필수 | 조회 시 적용할 종료일입니다. 학생별 종료일이 없으면 반 종강일을 사용하며 종료 사유는 추정하지 않습니다. | 20260115 |
items[].enrollment.isEnded | boolean | 필수 | 한국 날짜를 기준으로 종료 효력이 발생했는지 나타냅니다. 일반 미래 종료는 false지만 전반 취소 이력은 시작일과 관계없이 항상 true입니다. | false |
items[].enrollment.status | string | 필수 | 수강 시작 전, 수강중, 퇴원, 전반, 종강, 전반 취소, 종료(구분 미확인) 또는 종료 예정 상태입니다. 미래 시작은 현재 수강중이 아니며, 예정 종료 사유는 함께 표시합니다. | "예시" |
items[].enrollment.statusCode | string | 필수 | 상태 표시 코드입니다. upcoming(미래 시작), active, retired, transferred, ended, cancelled, unknown 중 하나입니다. 전반 취소는 시작일과 관계없이 cancelled입니다. | "예시" |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "학원 내 실제 학생 번호입니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호에 해당하는 실제 학생 이름입니다.",
"nullable": false
},
"enrollment": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "수강반 고유 번호입니다. 수강반 조회에서 확인합니다.",
"nullable": false
},
"scheduleId": {
"type": "integer",
"description": "수강반 시간표 고유 번호입니다. 해당 반의 시간표여야 합니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "수강반 이름입니다.",
"nullable": false
},
"scheduleName": {
"type": "string",
"description": "시간표 표시 이름입니다.",
"nullable": false
},
"beginDate": {
"type": "integer",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false
},
"endDate": {
"type": "integer",
"description": "종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false
},
"endType": {
"type": "string",
"description": "저장된 수강 종료 사유입니다. 빈 문자열, 퇴원, 전반, 종강, 전반취소를 사용합니다. 최대 20자이며 기존의 미확인 사유도 보존합니다. 이미 시작한 수강의 미래 종료는 active, 미래 시작은 upcoming이며 전반취소는 시작일과 관계없이 항상 cancelled입니다.",
"nullable": false,
"maxLength": 20
},
"changeDate": {
"type": "integer",
"description": "전반으로 종료되는 기존 수강 건의 전반일입니다. yyyyMMdd 정수이며 0은 미설정입니다.",
"nullable": false
},
"scheduleDay": {
"type": "string",
"description": "해당 수강 시간표의 실제 요일입니다. 없으면 빈 문자열입니다.",
"nullable": false
},
"scheduleFrom": {
"type": "string",
"description": "해당 수강 시간표의 실제 시작 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다.",
"nullable": false
},
"scheduleTo": {
"type": "string",
"description": "해당 수강 시간표의 실제 종료 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다.",
"nullable": false
},
"transferFromId": {
"type": "integer",
"description": "전반 전의 기존 수강 건 번호입니다. 연결 없는 과거 자료는 null입니다.",
"nullable": true
},
"transferDate": {
"type": "integer",
"description": "새 반으로 전반한 지정일입니다. yyyyMMdd 정수, 0은 연결 없음입니다.",
"nullable": false
},
"previousTeamName": {
"type": "string",
"description": "전반 이전 반·시간표 표시명입니다.",
"nullable": false
},
"isTransfer": {
"type": "boolean",
"description": "명시적인 이전 수강 연결값이 있는 전반 등록인지 나타냅니다.",
"nullable": false
},
"isTransferCancelled": {
"type": "boolean",
"description": "전반 취소 이력인지 나타냅니다. 취소해도 출결·수납 자료와 수강 건은 보존됩니다.",
"nullable": false
},
"transferCancelledAt": {
"type": "string",
"format": "date-time",
"description": "전반 취소 시각(UTC)입니다. 취소 전에는 null입니다.",
"nullable": true
},
"classEndDate": {
"type": "integer",
"description": "반 자체의 종강일입니다. 학생별 endDate와 별개인 yyyyMMdd 정수이며 0은 미설정입니다.",
"nullable": false
},
"effectiveEndDate": {
"type": "integer",
"description": "조회 시 적용할 종료일입니다. 학생별 종료일이 없으면 반 종강일을 사용하며 종료 사유는 추정하지 않습니다.",
"nullable": false
},
"isEnded": {
"type": "boolean",
"description": "한국 날짜를 기준으로 종료 효력이 발생했는지 나타냅니다. 일반 미래 종료는 false지만 전반 취소 이력은 시작일과 관계없이 항상 true입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "수강 시작 전, 수강중, 퇴원, 전반, 종강, 전반 취소, 종료(구분 미확인) 또는 종료 예정 상태입니다. 미래 시작은 현재 수강중이 아니며, 예정 종료 사유는 함께 표시합니다.",
"nullable": false
},
"statusCode": {
"type": "string",
"description": "상태 표시 코드입니다. upcoming(미래 시작), active, retired, transferred, ended, cancelled, unknown 중 하나입니다. 전반 취소는 시작일과 관계없이 cancelled입니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"teamId",
"scheduleId",
"teamName",
"scheduleName",
"beginDate",
"endDate",
"endType",
"changeDate",
"scheduleDay",
"scheduleFrom",
"scheduleTo",
"transferFromId",
"transferDate",
"previousTeamName",
"isTransfer",
"isTransferCancelled",
"transferCancelledAt",
"classEndDate",
"effectiveEndDate",
"isEnded",
"status",
"statusCode"
],
"description": "정확한 수강 기록과 명시된 종료 사유·효력일·전반 출처입니다.",
"nullable": false
}
},
"required": [
"studentId",
"studentName",
"enrollment"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"studentId": "00000001",
"studentName": "예시 이름",
"enrollment": {
"id": 1,
"studentId": "00000001",
"teamId": 1,
"scheduleId": 1,
"teamName": "예시 이름",
"scheduleName": "예시 이름",
"beginDate": 20260115,
"endDate": 20260115,
"endType": "예시",
"changeDate": 20260115,
"scheduleDay": "예시",
"scheduleFrom": "예시",
"scheduleTo": "예시",
"transferFromId": 1,
"transferDate": 20260115,
"previousTeamName": "예시 이름",
"isTransfer": false,
"isTransferCancelled": false,
"transferCancelledAt": "2026-01-15T00:00:00Z",
"classEndDate": 20260115,
"effectiveEndDate": 20260115,
"isEnded": false,
"status": "예시",
"statusCode": "예시"
}
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teams수강반·담당·시간표 목록. status=open 미종강(미래 개강·종강 포함), closed 종강, all 전체. 한국 오늘 기준. sort=id_desc 최신 등록번호순, begin_date_asc/desc 개강일순. appliedSort/appliedStatus 확인+
teams.read · teams.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
sort | query | 선택 | 수강반 정렬입니다. id_asc(기본)는 등록번호 오름차순, id_desc는 최신 등록번호순, begin_date_asc/desc는 개강일순입니다. 같은 개강일은 등록번호로 정렬하며 응답 appliedSort로 실제 적용 여부를 확인하세요. |
status | query | 선택 | 종강 필터입니다. all(기본)은 전체, open은 한국 오늘 기준 미종강(미래 개강·종강 포함), closed는 종강일이 오늘 이하인 반입니다. 필터 후 전체 건수와 페이지를 계산하며 응답 appliedStatus와 referenceDate로 적용 여부를 확인하세요. |
search | query | 선택 | 검색어입니다. 최대 100자이며 생략하면 전체를 조회합니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 조건부·선택 | 현재 페이지의 수강반 배열입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | 1 |
items[].name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
items[].grade | string | 필수 | 학년 표시값입니다. | "예시" |
items[].subject | string | 필수 | 수강반의 과목 이름입니다. | "예시" |
items[].level | string | 필수 | 수강반의 수준 또는 단계 이름입니다. | "예시" |
items[].beginDate | integer | 필수 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | 20260115 |
items[].endDate | integer | 필수 | 종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | 20260115 |
items[].teacherIds | array | 필수 | 담당 선생님 번호 배열입니다. 선생님 선택 목록에서 받은 번호만 사용합니다. | 하위 필드·본문 예시 참조 |
items[].teachers | array | 필수 | 담당 번호에 대응하는 선생님 id·name 목록. 현재 권한으로 확인되지 않은 번호는 포함하지 않습니다. | 하위 필드·본문 예시 참조 |
items[].teachers[].id | string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
items[].teachers[].name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
items[].schedules | array | 필수 | 이 반의 저장된 주간 시간표. 요일·시작/종료 시각·적용 기간·상담 여부를 함께 확인. 미래·종료 시간표를 현재 시간표로 단정하지 않음. | 하위 필드·본문 예시 참조 |
items[].schedules[].id | integer | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | 1 |
items[].schedules[].teamId | integer | 필수 | 수강반 고유 번호입니다. 수강반 조회에서 확인합니다. | 1 |
items[].schedules[].day | string | 필수 | 요일입니다. 월·화·수·목·금·토·일 중 하나입니다. | "월" |
items[].schedules[].from | string | 필수 | 수업 시작 시각입니다. HHmm 형식입니다. | "2026-01-15" |
items[].schedules[].to | string | 필수 | 수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다. | "2026-01-15" |
items[].schedules[].beginDate | string | 필수 | 시간표 적용 시작일입니다. yyyyMMdd 문자열이며 0은 미설정입니다. | "2026-01-15" |
items[].schedules[].endDate | string | 필수 | 시간표 적용 종료일입니다. yyyyMMdd 문자열이며 0은 미설정입니다. | "2026-01-15" |
items[].schedules[].kind | integer | 필수 | 시간표 종류입니다. 1은 수업, 2는 상담입니다. | 1 |
page | integer | 조건부·선택 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 조건부·선택 | 한 페이지의 자료 수입니다. 1~100입니다. | 1 |
total | integer | 조건부·선택 | 검색 조건에 맞는 전체 수강반 수입니다. | 1 |
appliedSort | string | 조건부·선택 | 실제로 적용한 정렬입니다. id_asc는 등록번호 오름차순, id_desc는 최신 등록번호순, begin_date_asc/desc는 개강일 순입니다. 같은 개강일은 등록번호로 정렬합니다. | "예시" |
appliedStatus | string | 조건부·선택 | 적용된 종강 필터입니다. all은 전체, open은 미종강(미래 개강·종강 포함), closed는 종강입니다. | "예시" |
referenceDate | integer | 조건부·선택 | 종강 상태를 판정한 한국 오늘 날짜입니다. yyyyMMdd 정수입니다. 종강일이 이 날짜 이하이면 종강입니다. | 20260115 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
},
"grade": {
"type": "string",
"description": "학년 표시값입니다.",
"nullable": false
},
"subject": {
"type": "string",
"description": "수강반의 과목 이름입니다.",
"nullable": false
},
"level": {
"type": "string",
"description": "수강반의 수준 또는 단계 이름입니다.",
"nullable": false
},
"beginDate": {
"type": "integer",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false
},
"endDate": {
"type": "integer",
"description": "종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false
},
"teacherIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "담당 선생님 번호 배열입니다. 선생님 선택 목록에서 받은 번호만 사용합니다.",
"nullable": false
},
"teachers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
}
},
"required": [
"id",
"name"
]
},
"description": "담당 번호에 대응하는 선생님 id·name 목록. 현재 권한으로 확인되지 않은 번호는 포함하지 않습니다.",
"nullable": false
},
"schedules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "수강반 고유 번호입니다. 수강반 조회에서 확인합니다.",
"nullable": false
},
"day": {
"type": "string",
"enum": [
"월",
"화",
"수",
"목",
"금",
"토",
"일"
],
"description": "요일입니다. 월·화·수·목·금·토·일 중 하나입니다.",
"nullable": false
},
"from": {
"type": "string",
"description": "수업 시작 시각입니다. HHmm 형식입니다.",
"nullable": false
},
"to": {
"type": "string",
"description": "수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다.",
"nullable": false
},
"beginDate": {
"type": "string",
"description": "시간표 적용 시작일입니다. yyyyMMdd 문자열이며 0은 미설정입니다.",
"nullable": false
},
"endDate": {
"type": "string",
"description": "시간표 적용 종료일입니다. yyyyMMdd 문자열이며 0은 미설정입니다.",
"nullable": false
},
"kind": {
"type": "integer",
"description": "시간표 종류입니다. 1은 수업, 2는 상담입니다.",
"nullable": false
}
},
"required": [
"id",
"teamId",
"day",
"from",
"to",
"beginDate",
"endDate",
"kind"
]
},
"description": "이 반의 저장된 주간 시간표. 요일·시작/종료 시각·적용 기간·상담 여부를 함께 확인. 미래·종료 시간표를 현재 시간표로 단정하지 않음.",
"nullable": false
}
},
"required": [
"id",
"name",
"grade",
"subject",
"level",
"beginDate",
"endDate",
"teacherIds",
"teachers",
"schedules"
]
},
"description": "현재 페이지의 수강반 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지의 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 수강반 수입니다.",
"nullable": false
},
"appliedSort": {
"type": "string",
"description": "실제로 적용한 정렬입니다. id_asc는 등록번호 오름차순, id_desc는 최신 등록번호순, begin_date_asc/desc는 개강일 순입니다. 같은 개강일은 등록번호로 정렬합니다.",
"nullable": false
},
"appliedStatus": {
"type": "string",
"description": "적용된 종강 필터입니다. all은 전체, open은 미종강(미래 개강·종강 포함), closed는 종강입니다.",
"nullable": false
},
"referenceDate": {
"type": "integer",
"description": "종강 상태를 판정한 한국 오늘 날짜입니다. yyyyMMdd 정수입니다. 종강일이 이 날짜 이하이면 종강입니다.",
"nullable": false
}
}
}성공 응답 예시
{
"data": {
"items": [
{
"id": 1,
"name": "예시 이름",
"grade": "예시",
"subject": "예시",
"level": "예시",
"beginDate": 20260115,
"endDate": 20260115,
"teacherIds": [
1
],
"teachers": [
{
"id": "1",
"name": "예시 이름"
}
],
"schedules": [
{
"id": 1,
"teamId": 1,
"day": "월",
"from": "2026-01-15",
"to": "2026-01-15",
"beginDate": "2026-01-15",
"endDate": "2026-01-15",
"kind": 1
}
]
}
],
"page": 1,
"pageSize": 1,
"total": 1,
"appliedSort": "예시",
"appliedStatus": "예시",
"referenceDate": 20260115
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teams/{id}수강반 상세+
teams.read · teams.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/teams 응답 data.items[].id의 수강반 번호입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | 1 |
name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
grade | string | 필수 | 학년 표시값입니다. | "예시" |
subject | string | 필수 | 수강반의 과목 이름입니다. | "예시" |
level | string | 필수 | 수강반의 수준 또는 단계 이름입니다. | "예시" |
beginDate | integer | 필수 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | 20260115 |
endDate | integer | 필수 | 종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | 20260115 |
teacherIds | array | 필수 | 담당 선생님 번호 배열입니다. 선생님 선택 목록에서 받은 번호만 사용합니다. | 하위 필드·본문 예시 참조 |
teachers | array | 필수 | 담당 번호에 대응하는 선생님 id·name 목록. 현재 권한으로 확인되지 않은 번호는 포함하지 않습니다. | 하위 필드·본문 예시 참조 |
teachers[].id | string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
teachers[].name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
schedules | array | 필수 | 이 반의 저장된 주간 시간표. 요일·시작/종료 시각·적용 기간·상담 여부를 함께 확인. 미래·종료 시간표를 현재 시간표로 단정하지 않음. | 하위 필드·본문 예시 참조 |
schedules[].id | integer | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | 1 |
schedules[].teamId | integer | 필수 | 수강반 고유 번호입니다. 수강반 조회에서 확인합니다. | 1 |
schedules[].day | string | 필수 | 요일입니다. 월·화·수·목·금·토·일 중 하나입니다. | "월" |
schedules[].from | string | 필수 | 수업 시작 시각입니다. HHmm 형식입니다. | "2026-01-15" |
schedules[].to | string | 필수 | 수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다. | "2026-01-15" |
schedules[].beginDate | string | 필수 | 시간표 적용 시작일입니다. yyyyMMdd 문자열이며 0은 미설정입니다. | "2026-01-15" |
schedules[].endDate | string | 필수 | 시간표 적용 종료일입니다. yyyyMMdd 문자열이며 0은 미설정입니다. | "2026-01-15" |
schedules[].kind | integer | 필수 | 시간표 종류입니다. 1은 수업, 2는 상담입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
},
"grade": {
"type": "string",
"description": "학년 표시값입니다.",
"nullable": false
},
"subject": {
"type": "string",
"description": "수강반의 과목 이름입니다.",
"nullable": false
},
"level": {
"type": "string",
"description": "수강반의 수준 또는 단계 이름입니다.",
"nullable": false
},
"beginDate": {
"type": "integer",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false
},
"endDate": {
"type": "integer",
"description": "종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false
},
"teacherIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "담당 선생님 번호 배열입니다. 선생님 선택 목록에서 받은 번호만 사용합니다.",
"nullable": false
},
"teachers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
}
},
"required": [
"id",
"name"
]
},
"description": "담당 번호에 대응하는 선생님 id·name 목록. 현재 권한으로 확인되지 않은 번호는 포함하지 않습니다.",
"nullable": false
},
"schedules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "수강반 고유 번호입니다. 수강반 조회에서 확인합니다.",
"nullable": false
},
"day": {
"type": "string",
"enum": [
"월",
"화",
"수",
"목",
"금",
"토",
"일"
],
"description": "요일입니다. 월·화·수·목·금·토·일 중 하나입니다.",
"nullable": false
},
"from": {
"type": "string",
"description": "수업 시작 시각입니다. HHmm 형식입니다.",
"nullable": false
},
"to": {
"type": "string",
"description": "수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다.",
"nullable": false
},
"beginDate": {
"type": "string",
"description": "시간표 적용 시작일입니다. yyyyMMdd 문자열이며 0은 미설정입니다.",
"nullable": false
},
"endDate": {
"type": "string",
"description": "시간표 적용 종료일입니다. yyyyMMdd 문자열이며 0은 미설정입니다.",
"nullable": false
},
"kind": {
"type": "integer",
"description": "시간표 종류입니다. 1은 수업, 2는 상담입니다.",
"nullable": false
}
},
"required": [
"id",
"teamId",
"day",
"from",
"to",
"beginDate",
"endDate",
"kind"
]
},
"description": "이 반의 저장된 주간 시간표. 요일·시작/종료 시각·적용 기간·상담 여부를 함께 확인. 미래·종료 시간표를 현재 시간표로 단정하지 않음.",
"nullable": false
}
},
"required": [
"id",
"name",
"grade",
"subject",
"level",
"beginDate",
"endDate",
"teacherIds",
"teachers",
"schedules"
]
}성공 응답 예시
{
"data": {
"id": 1,
"name": "예시 이름",
"grade": "예시",
"subject": "예시",
"level": "예시",
"beginDate": 20260115,
"endDate": 20260115,
"teacherIds": [
1
],
"teachers": [
{
"id": "1",
"name": "예시 이름"
}
],
"schedules": [
{
"id": 1,
"teamId": 1,
"day": "월",
"from": "2026-01-15",
"to": "2026-01-15",
"beginDate": "2026-01-15",
"endDate": "2026-01-15",
"kind": 1
}
]
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/teams수강반 등록+
teams.write · teams.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
name | string | 필수 | 이름 또는 표시 명칭입니다. | "수학 A반" |
grade | string | 조건부·선택 | 학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다. | "예시" |
subject | string | 조건부·선택 | 수강반의 과목 이름입니다. | "예시" |
level | string | 조건부·선택 | 수강반의 수준 또는 단계 이름입니다. | "예시" |
beginDate | string | 조건부·선택 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
endDate | string | 조건부·선택 | 종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
teacherIds | array | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 선생님 번호들을 배열로 전달합니다. 예: [12, 13]. 선생님 이름이나 문자열 로그인 아이디 대신 목록 id를 정수로 변환해 사용하세요. 빈 배열 []는 담당 미지정이며 0은 기본 선생님 번호가 아닙니다. | 하위 필드·본문 예시 참조 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false,
"maxLength": 70,
"minLength": 1,
"example": "수학 A반"
},
"grade": {
"type": "string",
"description": "학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다.",
"nullable": false,
"maxLength": 70,
"default": ""
},
"subject": {
"type": "string",
"description": "수강반의 과목 이름입니다.",
"nullable": false,
"maxLength": 70,
"default": ""
},
"level": {
"type": "string",
"description": "수강반의 수준 또는 단계 이름입니다.",
"nullable": false,
"maxLength": 70,
"default": ""
},
"beginDate": {
"type": "string",
"format": "date",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": true
},
"endDate": {
"type": "string",
"format": "date",
"description": "종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": true
},
"teacherIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 선생님 번호들을 배열로 전달합니다. 예: [12, 13]. 선생님 이름이나 문자열 로그인 아이디 대신 목록 id를 정수로 변환해 사용하세요. 빈 배열 []는 담당 미지정이며 0은 기본 선생님 번호가 아닙니다.",
"nullable": false,
"maxItems": 30
}
},
"required": [
"name",
"teacherIds"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"name": "수학 A반",
"grade": "예시",
"subject": "예시",
"level": "예시",
"beginDate": "2026-01-15",
"endDate": "2026-01-15",
"teacherIds": [
1
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/teams/{id}수강반 수정 · 종강/종강 취소+
teams.write · teams.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/teams 응답 data.items[].id의 수강반 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
name | string | 필수 | 이름 또는 표시 명칭입니다. | "수학 A반" |
grade | string | 조건부·선택 | 학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다. | "예시" |
subject | string | 조건부·선택 | 수강반의 과목 이름입니다. | "예시" |
level | string | 조건부·선택 | 수강반의 수준 또는 단계 이름입니다. | "예시" |
beginDate | string | 조건부·선택 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
endDate | string | 조건부·선택 | 종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
teacherIds | array | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 선생님 번호들을 배열로 전달합니다. 예: [12, 13]. 선생님 이름이나 문자열 로그인 아이디 대신 목록 id를 정수로 변환해 사용하세요. 빈 배열 []는 담당 미지정이며 0은 기본 선생님 번호가 아닙니다. | 하위 필드·본문 예시 참조 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false,
"maxLength": 70,
"minLength": 1,
"example": "수학 A반"
},
"grade": {
"type": "string",
"description": "학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다.",
"nullable": false,
"maxLength": 70,
"default": ""
},
"subject": {
"type": "string",
"description": "수강반의 과목 이름입니다.",
"nullable": false,
"maxLength": 70,
"default": ""
},
"level": {
"type": "string",
"description": "수강반의 수준 또는 단계 이름입니다.",
"nullable": false,
"maxLength": 70,
"default": ""
},
"beginDate": {
"type": "string",
"format": "date",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": true
},
"endDate": {
"type": "string",
"format": "date",
"description": "종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": true
},
"teacherIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 선생님 번호들을 배열로 전달합니다. 예: [12, 13]. 선생님 이름이나 문자열 로그인 아이디 대신 목록 id를 정수로 변환해 사용하세요. 빈 배열 []는 담당 미지정이며 0은 기본 선생님 번호가 아닙니다.",
"nullable": false,
"maxItems": 30
}
},
"required": [
"name",
"teacherIds"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"name": "수학 A반",
"grade": "예시",
"subject": "예시",
"level": "예시",
"beginDate": "2026-01-15",
"endDate": "2026-01-15",
"teacherIds": [
1
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/teams/{id}수강반 삭제(재원생이 있으면 거절)+
teams.write · teams.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/teams 응답 data.items[].id의 수강반 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teams/daily-plan예정 수업·담당자·시각·고유 재원 인원. date의 하루 조회; lookAheadDays>0이면 그날부터 범위 안 첫 수업일 조회. 개강·종강·시간표 기간 적용, 저장 출석부 아님+
teams.read · teams.day-plan
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
date | query | 필수 | 조회할 한국 날짜입니다. yyyy-MM-dd 형식입니다. 오늘·내일 등은 서버의 Asia/Seoul 날짜로 계산합니다. |
lookAheadDays | query | 선택 | 0은 지정 날짜만 조회. 1~31은 date부터 해당 일수 뒤까지 첫 수업일을 찾아 그날 전체 시간표 반환. 오늘 없으면 다음 수업 요청에 사용. 인원 0인 예정 수업도 포함. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].date | string | 필수 | 조회한 한국 날짜입니다. yyyy-MM-dd 형식입니다. | "2026-01-15" |
items[].teamId | integer | 필수 | 인증 학원의 수강반 번호입니다. | 1 |
items[].teamName | string | 필수 | 저장된 원본 수강반명입니다. | "예시 이름" |
items[].scheduleId | integer | 필수 | 이 수업의 시간표 번호입니다. | 1 |
items[].day | string | 필수 | 시간표의 요일입니다. | "월" |
items[].from | string | 필수 | 수업 시작 시각입니다. HH:mm 형식입니다. | "2026-01-15" |
items[].to | string | 필수 | 수업 종료 시각입니다. HH:mm 형식입니다. | "2026-01-15" |
items[].studentCount | integer | 필수 | 해당 날짜에 이 반·시간표에 재원 중인 고유 학생 수입니다. 종료 효력일·전반 취소·삭제를 반영하며 저장 출석 인원과 구분합니다. | 1 |
items[].teachers | array | 필수 | 이 수강반에 실제 연결된 권한 내 담당 선생님 번호·이름. 비어 있으면 목록의 유일한 선생님으로 추측하지 않음. | 하위 필드·본문 예시 참조 |
items[].teachers[].id | string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
items[].teachers[].name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "조회한 한국 날짜입니다. yyyy-MM-dd 형식입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "인증 학원의 수강반 번호입니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "저장된 원본 수강반명입니다.",
"nullable": false
},
"scheduleId": {
"type": "integer",
"description": "이 수업의 시간표 번호입니다.",
"nullable": false
},
"day": {
"type": "string",
"enum": [
"월",
"화",
"수",
"목",
"금",
"토",
"일"
],
"description": "시간표의 요일입니다.",
"nullable": false
},
"from": {
"type": "string",
"description": "수업 시작 시각입니다. HH:mm 형식입니다.",
"nullable": false
},
"to": {
"type": "string",
"description": "수업 종료 시각입니다. HH:mm 형식입니다.",
"nullable": false
},
"studentCount": {
"type": "integer",
"description": "해당 날짜에 이 반·시간표에 재원 중인 고유 학생 수입니다. 종료 효력일·전반 취소·삭제를 반영하며 저장 출석 인원과 구분합니다.",
"nullable": false
},
"teachers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
}
},
"required": [
"id",
"name"
]
},
"description": "이 수강반에 실제 연결된 권한 내 담당 선생님 번호·이름. 비어 있으면 목록의 유일한 선생님으로 추측하지 않음.",
"nullable": false
}
},
"required": [
"date",
"teamId",
"teamName",
"scheduleId",
"day",
"from",
"to",
"studentCount",
"teachers"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"date": "2026-01-15",
"teamId": 1,
"teamName": "예시 이름",
"scheduleId": 1,
"day": "월",
"from": "2026-01-15",
"to": "2026-01-15",
"studentCount": 1,
"teachers": [
{
"id": "1",
"name": "예시 이름"
}
]
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teams/{id}/schedules수강반의 시간표 목록(id는 teamId이며 scheduleId 아님)+
teams.read · schedules.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | 대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | integer | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | 1 |
[].teamId | integer | 필수 | 수강반 고유 번호입니다. 수강반 조회에서 확인합니다. | 1 |
[].day | string | 필수 | 요일입니다. 월·화·수·목·금·토·일 중 하나입니다. | "월" |
[].from | string | 필수 | 수업 시작 시각입니다. HHmm 형식입니다. | "2026-01-15" |
[].to | string | 필수 | 수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다. | "2026-01-15" |
[].beginDate | string | 필수 | 시간표 적용 시작일입니다. yyyyMMdd 문자열이며 0은 미설정입니다. | "2026-01-15" |
[].endDate | string | 필수 | 시간표 적용 종료일입니다. yyyyMMdd 문자열이며 0은 미설정입니다. | "2026-01-15" |
[].kind | integer | 필수 | 시간표 종류입니다. 1은 수업, 2는 상담입니다. | 1 |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "수강반 고유 번호입니다. 수강반 조회에서 확인합니다.",
"nullable": false
},
"day": {
"type": "string",
"enum": [
"월",
"화",
"수",
"목",
"금",
"토",
"일"
],
"description": "요일입니다. 월·화·수·목·금·토·일 중 하나입니다.",
"nullable": false
},
"from": {
"type": "string",
"description": "수업 시작 시각입니다. HHmm 형식입니다.",
"nullable": false
},
"to": {
"type": "string",
"description": "수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다.",
"nullable": false
},
"beginDate": {
"type": "string",
"description": "시간표 적용 시작일입니다. yyyyMMdd 문자열이며 0은 미설정입니다.",
"nullable": false
},
"endDate": {
"type": "string",
"description": "시간표 적용 종료일입니다. yyyyMMdd 문자열이며 0은 미설정입니다.",
"nullable": false
},
"kind": {
"type": "integer",
"description": "시간표 종류입니다. 1은 수업, 2는 상담입니다.",
"nullable": false
}
},
"required": [
"id",
"teamId",
"day",
"from",
"to",
"beginDate",
"endDate",
"kind"
]
}
}성공 응답 예시
{
"data": [
{
"id": 1,
"teamId": 1,
"day": "월",
"from": "2026-01-15",
"to": "2026-01-15",
"beginDate": "2026-01-15",
"endDate": "2026-01-15",
"kind": 1
}
],
"meta": {
"requestId": "example-request-id"
}
}POST/v1/teams/{id}/schedules시간표 등록+
teams.write · schedules.create
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | 대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
day | string | 필수 | 요일입니다. 월·화·수·목·금·토·일 중 하나입니다. | "월" |
from | string | 필수 | 수업 시작 시각입니다. HHmm 형식입니다. | "1600" |
to | string | 필수 | 수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다. | "1730" |
beginDate | string | 조건부·선택 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
endDate | string | 조건부·선택 | 종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
kind | integer | 조건부·선택 | 시간표 종류입니다. 1은 수업, 2는 상담입니다. | 1 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"day": {
"type": "string",
"enum": [
"월",
"화",
"수",
"목",
"금",
"토",
"일"
],
"description": "요일입니다. 월·화·수·목·금·토·일 중 하나입니다.",
"nullable": false,
"minLength": 1
},
"from": {
"type": "string",
"description": "수업 시작 시각입니다. HHmm 형식입니다.",
"nullable": false,
"minLength": 1,
"example": "1600"
},
"to": {
"type": "string",
"description": "수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다.",
"nullable": false,
"minLength": 1,
"example": "1730"
},
"beginDate": {
"type": "string",
"format": "date",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": true
},
"endDate": {
"type": "string",
"format": "date",
"description": "종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": true
},
"kind": {
"type": "integer",
"description": "시간표 종류입니다. 1은 수업, 2는 상담입니다.",
"nullable": false,
"minimum": 1,
"maximum": 2,
"default": 1
}
},
"required": [
"day",
"from",
"to"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"day": "월",
"from": "1600",
"to": "1730",
"beginDate": "2026-01-15",
"endDate": "2026-01-15",
"kind": 1
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/teams/{id}/schedules/{scheduleId}시간표 수정+
teams.write · schedules.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | 대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다. |
scheduleId | path | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
day | string | 필수 | 요일입니다. 월·화·수·목·금·토·일 중 하나입니다. | "월" |
from | string | 필수 | 수업 시작 시각입니다. HHmm 형식입니다. | "1600" |
to | string | 필수 | 수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다. | "1730" |
beginDate | string | 조건부·선택 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
endDate | string | 조건부·선택 | 종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
kind | integer | 조건부·선택 | 시간표 종류입니다. 1은 수업, 2는 상담입니다. | 1 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"day": {
"type": "string",
"enum": [
"월",
"화",
"수",
"목",
"금",
"토",
"일"
],
"description": "요일입니다. 월·화·수·목·금·토·일 중 하나입니다.",
"nullable": false,
"minLength": 1
},
"from": {
"type": "string",
"description": "수업 시작 시각입니다. HHmm 형식입니다.",
"nullable": false,
"minLength": 1,
"example": "1600"
},
"to": {
"type": "string",
"description": "수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다.",
"nullable": false,
"minLength": 1,
"example": "1730"
},
"beginDate": {
"type": "string",
"format": "date",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": true
},
"endDate": {
"type": "string",
"format": "date",
"description": "종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": true
},
"kind": {
"type": "integer",
"description": "시간표 종류입니다. 1은 수업, 2는 상담입니다.",
"nullable": false,
"minimum": 1,
"maximum": 2,
"default": 1
}
},
"required": [
"day",
"from",
"to"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"day": "월",
"from": "1600",
"to": "1730",
"beginDate": "2026-01-15",
"endDate": "2026-01-15",
"kind": 1
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/teams/{id}/schedules/{scheduleId}시간표 삭제(수업·재원생이 있으면 거절)+
teams.write · schedules.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | 대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다. |
scheduleId | path | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teams/teachersTeaching teacher names and IDs, including teachers without classes; shared by classes, lessons and exams. Not employee time-clock staff.+
teams.read · teams.teachers
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
[].name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
}
},
"required": [
"id",
"name"
]
}
}성공 응답 예시
{
"data": [
{
"id": "1",
"name": "예시 이름"
}
],
"meta": {
"requestId": "example-request-id"
}
}POST/v1/teams/with-schedules새 수강반과 시간표를 함께 등록(원자적 저장·하나라도 실패하면 전체 취소)+
teams.write · teams.create-with-schedules
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
team | object | 필수 | 새로 등록할 수강반 기본정보입니다. 담당 선생님은 GET /v1/teams/teachers의 실제 번호를 사용합니다. 기존 수강반 수정은 별도 API를 사용하세요. | 하위 필드·본문 예시 참조 |
team.name | string | 필수 | 이름 또는 표시 명칭입니다. | "수학 A반" |
team.grade | string | 조건부·선택 | 학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다. | "예시" |
team.subject | string | 조건부·선택 | 수강반의 과목 이름입니다. | "예시" |
team.level | string | 조건부·선택 | 수강반의 수준 또는 단계 이름입니다. | "예시" |
team.beginDate | string | 조건부·선택 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
team.endDate | string | 조건부·선택 | 종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
team.teacherIds | array | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 선생님 번호들을 배열로 전달합니다. 예: [12, 13]. 선생님 이름이나 문자열 로그인 아이디 대신 목록 id를 정수로 변환해 사용하세요. 빈 배열 []는 담당 미지정이며 0은 기본 선생님 번호가 아닙니다. | 하위 필드·본문 예시 참조 |
schedules | array | 필수 | 함께 새로 등록할 시간표 1~100개입니다. 수강반과 모든 시간표가 하나의 트랜잭션으로 저장되며 하나라도 실패하면 전부 취소됩니다. 요일과 HHmm 시각, 시작일을 지정하세요. | 하위 필드·본문 예시 참조 |
schedules[].day | string | 필수 | 요일입니다. 월·화·수·목·금·토·일 중 하나입니다. | "월" |
schedules[].from | string | 필수 | 수업 시작 시각입니다. HHmm 형식입니다. | "1600" |
schedules[].to | string | 필수 | 수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다. | "1730" |
schedules[].beginDate | string | 조건부·선택 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
schedules[].endDate | string | 조건부·선택 | 종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
schedules[].kind | integer | 조건부·선택 | 시간표 종류입니다. 1은 수업, 2는 상담입니다. | 1 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"team": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false,
"maxLength": 70,
"minLength": 1,
"example": "수학 A반"
},
"grade": {
"type": "string",
"description": "학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다.",
"nullable": false,
"maxLength": 70,
"default": ""
},
"subject": {
"type": "string",
"description": "수강반의 과목 이름입니다.",
"nullable": false,
"maxLength": 70,
"default": ""
},
"level": {
"type": "string",
"description": "수강반의 수준 또는 단계 이름입니다.",
"nullable": false,
"maxLength": 70,
"default": ""
},
"beginDate": {
"type": "string",
"format": "date",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": true
},
"endDate": {
"type": "string",
"format": "date",
"description": "종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": true
},
"teacherIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 선생님 번호들을 배열로 전달합니다. 예: [12, 13]. 선생님 이름이나 문자열 로그인 아이디 대신 목록 id를 정수로 변환해 사용하세요. 빈 배열 []는 담당 미지정이며 0은 기본 선생님 번호가 아닙니다.",
"nullable": false,
"maxItems": 30
}
},
"required": [
"name",
"teacherIds"
],
"description": "새로 등록할 수강반 기본정보입니다. 담당 선생님은 GET /v1/teams/teachers의 실제 번호를 사용합니다. 기존 수강반 수정은 별도 API를 사용하세요.",
"nullable": false
},
"schedules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"day": {
"type": "string",
"enum": [
"월",
"화",
"수",
"목",
"금",
"토",
"일"
],
"description": "요일입니다. 월·화·수·목·금·토·일 중 하나입니다.",
"nullable": false,
"minLength": 1
},
"from": {
"type": "string",
"description": "수업 시작 시각입니다. HHmm 형식입니다.",
"nullable": false,
"minLength": 1,
"example": "1600"
},
"to": {
"type": "string",
"description": "수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다.",
"nullable": false,
"minLength": 1,
"example": "1730"
},
"beginDate": {
"type": "string",
"format": "date",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": true
},
"endDate": {
"type": "string",
"format": "date",
"description": "종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": true
},
"kind": {
"type": "integer",
"description": "시간표 종류입니다. 1은 수업, 2는 상담입니다.",
"nullable": false,
"minimum": 1,
"maximum": 2,
"default": 1
}
},
"required": [
"day",
"from",
"to"
]
},
"description": "함께 새로 등록할 시간표 1~100개입니다. 수강반과 모든 시간표가 하나의 트랜잭션으로 저장되며 하나라도 실패하면 전부 취소됩니다. 요일과 HHmm 시각, 시작일을 지정하세요.",
"nullable": false,
"minItems": 1,
"maxItems": 100
}
},
"required": [
"team",
"schedules"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 새로 등록한 수강반 번호입니다. 이후 수강 등록·수업 등록의 teamId에 사용합니다. | 1 |
scheduleIds | array | 필수 | 입력한 시간표 순서대로 반환한 실제 시간표 번호입니다. 같은 반의 scheduleId로 사용하며 다시 시간표를 등록하지 마세요. | 하위 필드·본문 예시 참조 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "새로 등록한 수강반 번호입니다. 이후 수강 등록·수업 등록의 teamId에 사용합니다.",
"nullable": false
},
"scheduleIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "입력한 시간표 순서대로 반환한 실제 시간표 번호입니다. 같은 반의 scheduleId로 사용하며 다시 시간표를 등록하지 마세요.",
"nullable": false
}
},
"required": [
"id",
"scheduleIds"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"team": {
"name": "수학 A반",
"grade": "예시",
"subject": "예시",
"level": "예시",
"beginDate": "2026-01-15",
"endDate": "2026-01-15",
"teacherIds": [
1
]
},
"schedules": [
{
"day": "월",
"from": "1600",
"to": "1730",
"beginDate": "2026-01-15",
"endDate": "2026-01-15",
"kind": 1
}
]
}성공 응답 예시
{
"data": {
"id": 1,
"scheduleIds": [
1
]
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/enrollments기존 학생 수강 등록+
students.write · enrollments.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 예: 00000001. 이름·전화번호가 아니며 앞자리 0을 유지하세요. | "00000001" |
teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다. | 1 |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요. | 1 |
beginDate | string | 필수 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 예: 00000001. 이름·전화번호가 아니며 앞자리 0을 유지하세요.",
"nullable": false,
"minLength": 1
},
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"beginDate": {
"type": "string",
"format": "date",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false,
"minLength": 1
}
},
"required": [
"studentId",
"teamId",
"scheduleId",
"beginDate"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | string | 필수 | 수강 등록한 학생 번호 문자열입니다. 기존 id 응답과 호환되며, 수강 이력 변경에는 enrollmentId를 사용하세요. | "1" |
enrollmentId | integer | 필수 | 이번에 생성한 수강 이력의 정수 번호입니다. 수강 이력 조회 응답 data[].id와 같으며 등록일 수정·퇴원·전반 요청의 enrollmentId에 사용합니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "수강 등록한 학생 번호 문자열입니다. 기존 id 응답과 호환되며, 수강 이력 변경에는 enrollmentId를 사용하세요.",
"nullable": false
},
"enrollmentId": {
"type": "integer",
"description": "이번에 생성한 수강 이력의 정수 번호입니다. 수강 이력 조회 응답 data[].id와 같으며 등록일 수정·퇴원·전반 요청의 enrollmentId에 사용합니다.",
"nullable": false
}
},
"required": [
"id",
"enrollmentId"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"studentId": "00000001",
"teamId": 1,
"scheduleId": 1,
"beginDate": "2026-01-15"
}성공 응답 예시
{
"data": {
"id": "1",
"enrollmentId": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students학생 검색 · 목록(공백으로 구분한 이름·학생번호·연락처 중 하나라도 일치)+
students.read · students.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
search | query | 선택 | 검색어입니다. 최대 100자이며 생략하면 전체를 조회합니다. |
teamId | query | 선택 | GET /v1/teams 응답 data.items[].id의 정수 번호로 결과를 제한합니다. 검색 조건에서 생략하면 전체 반입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].id | string | 필수 | 조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다. | "1" |
items[].name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
items[].school | string | 필수 | 학교 이름입니다. 빈 문자열이면 미입력입니다. | "예시" |
items[].grade | string | 필수 | 학년 표시값입니다. | "예시" |
items[].major | string | 필수 | 계열 또는 전공 구분값입니다. | "예시" |
items[].studentPhone | string | 필수 | 학생 휴대전화 번호입니다. | "010-0000-0000" |
items[].parentPhone | string | 필수 | 보호자 연락처입니다. | "010-0000-0000" |
items[].paymentPhone | string | 필수 | 결제 안내를 받을 연락처입니다. | "010-0000-0000" |
items[].email | string | 필수 | 이메일 주소입니다. | "sample@example.com" |
items[].memo | string | 필수 | 학생 관리용 메모입니다. | "예시" |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
},
"school": {
"type": "string",
"description": "학교 이름입니다. 빈 문자열이면 미입력입니다.",
"nullable": false
},
"grade": {
"type": "string",
"description": "학년 표시값입니다.",
"nullable": false
},
"major": {
"type": "string",
"description": "계열 또는 전공 구분값입니다.",
"nullable": false
},
"studentPhone": {
"type": "string",
"description": "학생 휴대전화 번호입니다.",
"nullable": false
},
"parentPhone": {
"type": "string",
"description": "보호자 연락처입니다.",
"nullable": false
},
"paymentPhone": {
"type": "string",
"description": "결제 안내를 받을 연락처입니다.",
"nullable": false
},
"email": {
"type": "string",
"description": "이메일 주소입니다.",
"nullable": false
},
"memo": {
"type": "string",
"description": "학생 관리용 메모입니다.",
"nullable": false
}
},
"required": [
"id",
"name",
"school",
"grade",
"major",
"studentPhone",
"parentPhone",
"paymentPhone",
"email",
"memo"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"id": "1",
"name": "예시 이름",
"school": "예시",
"grade": "예시",
"major": "예시",
"studentPhone": "010-0000-0000",
"parentPhone": "010-0000-0000",
"paymentPhone": "010-0000-0000",
"email": "sample@example.com",
"memo": "예시"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}학생 기본정보+
students.read · students.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | string | 필수 | 조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다. | "1" |
name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
school | string | 필수 | 학교 이름입니다. 빈 문자열이면 미입력입니다. | "예시" |
grade | string | 필수 | 학년 표시값입니다. | "예시" |
major | string | 필수 | 계열 또는 전공 구분값입니다. | "예시" |
studentPhone | string | 필수 | 학생 휴대전화 번호입니다. | "010-0000-0000" |
parentPhone | string | 필수 | 보호자 연락처입니다. | "010-0000-0000" |
paymentPhone | string | 필수 | 결제 안내를 받을 연락처입니다. | "010-0000-0000" |
email | string | 필수 | 이메일 주소입니다. | "sample@example.com" |
memo | string | 필수 | 학생 관리용 메모입니다. | "예시" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
},
"school": {
"type": "string",
"description": "학교 이름입니다. 빈 문자열이면 미입력입니다.",
"nullable": false
},
"grade": {
"type": "string",
"description": "학년 표시값입니다.",
"nullable": false
},
"major": {
"type": "string",
"description": "계열 또는 전공 구분값입니다.",
"nullable": false
},
"studentPhone": {
"type": "string",
"description": "학생 휴대전화 번호입니다.",
"nullable": false
},
"parentPhone": {
"type": "string",
"description": "보호자 연락처입니다.",
"nullable": false
},
"paymentPhone": {
"type": "string",
"description": "결제 안내를 받을 연락처입니다.",
"nullable": false
},
"email": {
"type": "string",
"description": "이메일 주소입니다.",
"nullable": false
},
"memo": {
"type": "string",
"description": "학생 관리용 메모입니다.",
"nullable": false
}
},
"required": [
"id",
"name",
"school",
"grade",
"major",
"studentPhone",
"parentPhone",
"paymentPhone",
"email",
"memo"
]
}성공 응답 예시
{
"data": {
"id": "1",
"name": "예시 이름",
"school": "예시",
"grade": "예시",
"major": "예시",
"studentPhone": "010-0000-0000",
"parentPhone": "010-0000-0000",
"paymentPhone": "010-0000-0000",
"email": "sample@example.com",
"memo": "예시"
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/students학생 기본정보 등록(수강 등록은 별도)+
students.write · students.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 학생" |
school | string | 조건부·선택 | 학교 이름입니다. 빈 문자열이면 미입력입니다. | "예시" |
grade | string | 조건부·선택 | 학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다. | "예시" |
major | string | 조건부·선택 | 계열 또는 전공 구분값입니다. | "예시" |
studentPhone | string | 조건부·선택 | 학생 휴대전화 번호입니다. | "010-0000-0000" |
parentPhone | string | 조건부·선택 | 보호자 연락처입니다. | "010-0000-0000" |
paymentPhone | string | 조건부·선택 | 결제 안내를 받을 연락처입니다. | "010-0000-0000" |
email | string | 조건부·선택 | 이메일 주소입니다. | "sample@example.com" |
memo | string | 조건부·선택 | 학생 관리용 메모입니다. | "예시" |
startDate | string | 조건부·선택 | 학생 등록일입니다. yyyy-MM-dd 형식이며 생략하면 서비스의 기본 등록일을 사용합니다. | "2026-01-15" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false,
"maxLength": 40,
"minLength": 1,
"example": "예시 학생"
},
"school": {
"type": "string",
"description": "학교 이름입니다. 빈 문자열이면 미입력입니다.",
"nullable": false,
"maxLength": 20,
"default": ""
},
"grade": {
"type": "string",
"description": "학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다.",
"nullable": false,
"maxLength": 10,
"default": ""
},
"major": {
"type": "string",
"description": "계열 또는 전공 구분값입니다.",
"nullable": false,
"maxLength": 10,
"default": ""
},
"studentPhone": {
"type": "string",
"description": "학생 휴대전화 번호입니다.",
"nullable": false,
"maxLength": 15,
"default": ""
},
"parentPhone": {
"type": "string",
"description": "보호자 연락처입니다.",
"nullable": false,
"maxLength": 40,
"default": ""
},
"paymentPhone": {
"type": "string",
"description": "결제 안내를 받을 연락처입니다.",
"nullable": false,
"maxLength": 15,
"default": ""
},
"email": {
"type": "string",
"description": "이메일 주소입니다.",
"nullable": false,
"maxLength": 30,
"default": ""
},
"memo": {
"type": "string",
"description": "학생 관리용 메모입니다.",
"nullable": false,
"maxLength": 2000,
"default": ""
},
"startDate": {
"type": "string",
"format": "date",
"description": "학생 등록일입니다. yyyy-MM-dd 형식이며 생략하면 서비스의 기본 등록일을 사용합니다.",
"nullable": true
}
},
"required": [
"name"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | string | 필수 | 조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다. | "1" |
name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
school | string | 필수 | 학교 이름입니다. 빈 문자열이면 미입력입니다. | "예시" |
grade | string | 필수 | 학년 표시값입니다. | "예시" |
major | string | 필수 | 계열 또는 전공 구분값입니다. | "예시" |
studentPhone | string | 필수 | 학생 휴대전화 번호입니다. | "010-0000-0000" |
parentPhone | string | 필수 | 보호자 연락처입니다. | "010-0000-0000" |
paymentPhone | string | 필수 | 결제 안내를 받을 연락처입니다. | "010-0000-0000" |
email | string | 필수 | 이메일 주소입니다. | "sample@example.com" |
memo | string | 필수 | 학생 관리용 메모입니다. | "예시" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
},
"school": {
"type": "string",
"description": "학교 이름입니다. 빈 문자열이면 미입력입니다.",
"nullable": false
},
"grade": {
"type": "string",
"description": "학년 표시값입니다.",
"nullable": false
},
"major": {
"type": "string",
"description": "계열 또는 전공 구분값입니다.",
"nullable": false
},
"studentPhone": {
"type": "string",
"description": "학생 휴대전화 번호입니다.",
"nullable": false
},
"parentPhone": {
"type": "string",
"description": "보호자 연락처입니다.",
"nullable": false
},
"paymentPhone": {
"type": "string",
"description": "결제 안내를 받을 연락처입니다.",
"nullable": false
},
"email": {
"type": "string",
"description": "이메일 주소입니다.",
"nullable": false
},
"memo": {
"type": "string",
"description": "학생 관리용 메모입니다.",
"nullable": false
}
},
"required": [
"id",
"name",
"school",
"grade",
"major",
"studentPhone",
"parentPhone",
"paymentPhone",
"email",
"memo"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"name": "예시 학생",
"school": "예시",
"grade": "예시",
"major": "예시",
"studentPhone": "010-0000-0000",
"parentPhone": "010-0000-0000",
"paymentPhone": "010-0000-0000",
"email": "sample@example.com",
"memo": "예시",
"startDate": "2026-01-15"
}성공 응답 예시
{
"data": {
"id": "1",
"name": "예시 이름",
"school": "예시",
"grade": "예시",
"major": "예시",
"studentPhone": "010-0000-0000",
"parentPhone": "010-0000-0000",
"paymentPhone": "010-0000-0000",
"email": "sample@example.com",
"memo": "예시"
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/students/{id}학생 기본정보 수정(전체 필드 교체)+
students.write · students.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 학생" |
school | string | 조건부·선택 | 학교 이름입니다. 빈 문자열이면 미입력입니다. | "예시" |
grade | string | 조건부·선택 | 학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다. | "예시" |
major | string | 조건부·선택 | 계열 또는 전공 구분값입니다. | "예시" |
studentPhone | string | 조건부·선택 | 학생 휴대전화 번호입니다. | "010-0000-0000" |
parentPhone | string | 조건부·선택 | 보호자 연락처입니다. | "010-0000-0000" |
paymentPhone | string | 조건부·선택 | 결제 안내를 받을 연락처입니다. | "010-0000-0000" |
email | string | 조건부·선택 | 이메일 주소입니다. | "sample@example.com" |
memo | string | 조건부·선택 | 학생 관리용 메모입니다. | "예시" |
startDate | string | 조건부·선택 | 학생 등록일입니다. yyyy-MM-dd 형식이며 생략하면 서비스의 기본 등록일을 사용합니다. | "2026-01-15" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false,
"maxLength": 40,
"minLength": 1,
"example": "예시 학생"
},
"school": {
"type": "string",
"description": "학교 이름입니다. 빈 문자열이면 미입력입니다.",
"nullable": false,
"maxLength": 20,
"default": ""
},
"grade": {
"type": "string",
"description": "학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다.",
"nullable": false,
"maxLength": 10,
"default": ""
},
"major": {
"type": "string",
"description": "계열 또는 전공 구분값입니다.",
"nullable": false,
"maxLength": 10,
"default": ""
},
"studentPhone": {
"type": "string",
"description": "학생 휴대전화 번호입니다.",
"nullable": false,
"maxLength": 15,
"default": ""
},
"parentPhone": {
"type": "string",
"description": "보호자 연락처입니다.",
"nullable": false,
"maxLength": 40,
"default": ""
},
"paymentPhone": {
"type": "string",
"description": "결제 안내를 받을 연락처입니다.",
"nullable": false,
"maxLength": 15,
"default": ""
},
"email": {
"type": "string",
"description": "이메일 주소입니다.",
"nullable": false,
"maxLength": 30,
"default": ""
},
"memo": {
"type": "string",
"description": "학생 관리용 메모입니다.",
"nullable": false,
"maxLength": 2000,
"default": ""
},
"startDate": {
"type": "string",
"format": "date",
"description": "학생 등록일입니다. yyyy-MM-dd 형식이며 생략하면 서비스의 기본 등록일을 사용합니다.",
"nullable": true
}
},
"required": [
"name"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | string | 필수 | 조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다. | "1" |
name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
school | string | 필수 | 학교 이름입니다. 빈 문자열이면 미입력입니다. | "예시" |
grade | string | 필수 | 학년 표시값입니다. | "예시" |
major | string | 필수 | 계열 또는 전공 구분값입니다. | "예시" |
studentPhone | string | 필수 | 학생 휴대전화 번호입니다. | "010-0000-0000" |
parentPhone | string | 필수 | 보호자 연락처입니다. | "010-0000-0000" |
paymentPhone | string | 필수 | 결제 안내를 받을 연락처입니다. | "010-0000-0000" |
email | string | 필수 | 이메일 주소입니다. | "sample@example.com" |
memo | string | 필수 | 학생 관리용 메모입니다. | "예시" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
},
"school": {
"type": "string",
"description": "학교 이름입니다. 빈 문자열이면 미입력입니다.",
"nullable": false
},
"grade": {
"type": "string",
"description": "학년 표시값입니다.",
"nullable": false
},
"major": {
"type": "string",
"description": "계열 또는 전공 구분값입니다.",
"nullable": false
},
"studentPhone": {
"type": "string",
"description": "학생 휴대전화 번호입니다.",
"nullable": false
},
"parentPhone": {
"type": "string",
"description": "보호자 연락처입니다.",
"nullable": false
},
"paymentPhone": {
"type": "string",
"description": "결제 안내를 받을 연락처입니다.",
"nullable": false
},
"email": {
"type": "string",
"description": "이메일 주소입니다.",
"nullable": false
},
"memo": {
"type": "string",
"description": "학생 관리용 메모입니다.",
"nullable": false
}
},
"required": [
"id",
"name",
"school",
"grade",
"major",
"studentPhone",
"parentPhone",
"paymentPhone",
"email",
"memo"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"name": "예시 학생",
"school": "예시",
"grade": "예시",
"major": "예시",
"studentPhone": "010-0000-0000",
"parentPhone": "010-0000-0000",
"paymentPhone": "010-0000-0000",
"email": "sample@example.com",
"memo": "예시",
"startDate": "2026-01-15"
}성공 응답 예시
{
"data": {
"id": "1",
"name": "예시 이름",
"school": "예시",
"grade": "예시",
"major": "예시",
"studentPhone": "010-0000-0000",
"parentPhone": "010-0000-0000",
"paymentPhone": "010-0000-0000",
"email": "sample@example.com",
"memo": "예시"
},
"meta": {
"requestId": "example-request-id"
}
}PATCH/v1/students/{id}학생 단일 필드 수정+
students.write · students.patch
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
field | string | 필수 | 수정할 학생 필드입니다. name, school, grade, major, studentPhone, parentPhone, paymentPhone, email, memo 중 하나입니다. | "name" |
value | string | 조건부·선택 | 사용자가 명시한 변경값입니다. 새 값을 모르면 먼저 질문하고 임의로 생성하지 마세요. 빈 값은 사용자가 비우기를 요청한 경우에만 내용을 비웁니다. 최대 길이: name 40, school 20, grade·major 10, studentPhone·paymentPhone 15, parentPhone 40, email 30, memo 2000자입니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"field": {
"type": "string",
"description": "수정할 학생 필드입니다. name, school, grade, major, studentPhone, parentPhone, paymentPhone, email, memo 중 하나입니다.",
"nullable": false,
"minLength": 1,
"enum": [
"name",
"school",
"grade",
"major",
"studentPhone",
"parentPhone",
"paymentPhone",
"email",
"memo"
]
},
"value": {
"type": "string",
"description": "사용자가 명시한 변경값입니다. 새 값을 모르면 먼저 질문하고 임의로 생성하지 마세요. 빈 값은 사용자가 비우기를 요청한 경우에만 내용을 비웁니다. 최대 길이: name 40, school 20, grade·major 10, studentPhone·paymentPhone 15, parentPhone 40, email 30, memo 2000자입니다.",
"nullable": false,
"maxLength": 2000,
"default": ""
}
},
"required": [
"field"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"field": "name",
"value": "예시"
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/students/{id}학생 삭제(재원 중이면 거절)+
students.write · students.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}/enrollments학생 수강 이력+
students.read · enrollments.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | integer | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | 1 |
[].studentId | string | 필수 | 학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다. | "00000001" |
[].teamId | integer | 필수 | 수강반 고유 번호입니다. 수강반 조회에서 확인합니다. | 1 |
[].scheduleId | integer | 필수 | 수강반 시간표 고유 번호입니다. 해당 반의 시간표여야 합니다. | 1 |
[].teamName | string | 필수 | 수강반 이름입니다. | "예시 이름" |
[].scheduleName | string | 필수 | 시간표 표시 이름입니다. | "예시 이름" |
[].beginDate | integer | 필수 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | 20260115 |
[].endDate | integer | 필수 | 종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | 20260115 |
[].endType | string | 필수 | 저장된 수강 종료 사유입니다. 빈 문자열, 퇴원, 전반, 종강, 전반취소를 사용합니다. 최대 20자이며 기존의 미확인 사유도 보존합니다. 이미 시작한 수강의 미래 종료는 active, 미래 시작은 upcoming이며 전반취소는 시작일과 관계없이 항상 cancelled입니다. | "예시" |
[].changeDate | integer | 필수 | 전반으로 종료되는 기존 수강 건의 전반일입니다. yyyyMMdd 정수이며 0은 미설정입니다. | 20260115 |
[].scheduleDay | string | 필수 | 해당 수강 시간표의 실제 요일입니다. 없으면 빈 문자열입니다. | "예시" |
[].scheduleFrom | string | 필수 | 해당 수강 시간표의 실제 시작 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다. | "예시" |
[].scheduleTo | string | 필수 | 해당 수강 시간표의 실제 종료 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다. | "예시" |
[].transferFromId | integer | 필수 | 전반 전의 기존 수강 건 번호입니다. 연결 없는 과거 자료는 null입니다. | 1 |
[].transferDate | integer | 필수 | 새 반으로 전반한 지정일입니다. yyyyMMdd 정수, 0은 연결 없음입니다. | 20260115 |
[].previousTeamName | string | 필수 | 전반 이전 반·시간표 표시명입니다. | "예시 이름" |
[].isTransfer | boolean | 필수 | 명시적인 이전 수강 연결값이 있는 전반 등록인지 나타냅니다. | false |
[].isTransferCancelled | boolean | 필수 | 전반 취소 이력인지 나타냅니다. 취소해도 출결·수납 자료와 수강 건은 보존됩니다. | false |
[].transferCancelledAt | string | 필수 | 전반 취소 시각(UTC)입니다. 취소 전에는 null입니다. | "2026-01-15T00:00:00Z" |
[].classEndDate | integer | 필수 | 반 자체의 종강일입니다. 학생별 endDate와 별개인 yyyyMMdd 정수이며 0은 미설정입니다. | 20260115 |
[].effectiveEndDate | integer | 필수 | 조회 시 적용할 종료일입니다. 학생별 종료일이 없으면 반 종강일을 사용하며 종료 사유는 추정하지 않습니다. | 20260115 |
[].isEnded | boolean | 필수 | 한국 날짜를 기준으로 종료 효력이 발생했는지 나타냅니다. 일반 미래 종료는 false지만 전반 취소 이력은 시작일과 관계없이 항상 true입니다. | false |
[].status | string | 필수 | 수강 시작 전, 수강중, 퇴원, 전반, 종강, 전반 취소, 종료(구분 미확인) 또는 종료 예정 상태입니다. 미래 시작은 현재 수강중이 아니며, 예정 종료 사유는 함께 표시합니다. | "예시" |
[].statusCode | string | 필수 | 상태 표시 코드입니다. upcoming(미래 시작), active, retired, transferred, ended, cancelled, unknown 중 하나입니다. 전반 취소는 시작일과 관계없이 cancelled입니다. | "예시" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "수강반 고유 번호입니다. 수강반 조회에서 확인합니다.",
"nullable": false
},
"scheduleId": {
"type": "integer",
"description": "수강반 시간표 고유 번호입니다. 해당 반의 시간표여야 합니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "수강반 이름입니다.",
"nullable": false
},
"scheduleName": {
"type": "string",
"description": "시간표 표시 이름입니다.",
"nullable": false
},
"beginDate": {
"type": "integer",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false
},
"endDate": {
"type": "integer",
"description": "종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false
},
"endType": {
"type": "string",
"description": "저장된 수강 종료 사유입니다. 빈 문자열, 퇴원, 전반, 종강, 전반취소를 사용합니다. 최대 20자이며 기존의 미확인 사유도 보존합니다. 이미 시작한 수강의 미래 종료는 active, 미래 시작은 upcoming이며 전반취소는 시작일과 관계없이 항상 cancelled입니다.",
"nullable": false,
"maxLength": 20
},
"changeDate": {
"type": "integer",
"description": "전반으로 종료되는 기존 수강 건의 전반일입니다. yyyyMMdd 정수이며 0은 미설정입니다.",
"nullable": false
},
"scheduleDay": {
"type": "string",
"description": "해당 수강 시간표의 실제 요일입니다. 없으면 빈 문자열입니다.",
"nullable": false
},
"scheduleFrom": {
"type": "string",
"description": "해당 수강 시간표의 실제 시작 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다.",
"nullable": false
},
"scheduleTo": {
"type": "string",
"description": "해당 수강 시간표의 실제 종료 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다.",
"nullable": false
},
"transferFromId": {
"type": "integer",
"description": "전반 전의 기존 수강 건 번호입니다. 연결 없는 과거 자료는 null입니다.",
"nullable": true
},
"transferDate": {
"type": "integer",
"description": "새 반으로 전반한 지정일입니다. yyyyMMdd 정수, 0은 연결 없음입니다.",
"nullable": false
},
"previousTeamName": {
"type": "string",
"description": "전반 이전 반·시간표 표시명입니다.",
"nullable": false
},
"isTransfer": {
"type": "boolean",
"description": "명시적인 이전 수강 연결값이 있는 전반 등록인지 나타냅니다.",
"nullable": false
},
"isTransferCancelled": {
"type": "boolean",
"description": "전반 취소 이력인지 나타냅니다. 취소해도 출결·수납 자료와 수강 건은 보존됩니다.",
"nullable": false
},
"transferCancelledAt": {
"type": "string",
"format": "date-time",
"description": "전반 취소 시각(UTC)입니다. 취소 전에는 null입니다.",
"nullable": true
},
"classEndDate": {
"type": "integer",
"description": "반 자체의 종강일입니다. 학생별 endDate와 별개인 yyyyMMdd 정수이며 0은 미설정입니다.",
"nullable": false
},
"effectiveEndDate": {
"type": "integer",
"description": "조회 시 적용할 종료일입니다. 학생별 종료일이 없으면 반 종강일을 사용하며 종료 사유는 추정하지 않습니다.",
"nullable": false
},
"isEnded": {
"type": "boolean",
"description": "한국 날짜를 기준으로 종료 효력이 발생했는지 나타냅니다. 일반 미래 종료는 false지만 전반 취소 이력은 시작일과 관계없이 항상 true입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "수강 시작 전, 수강중, 퇴원, 전반, 종강, 전반 취소, 종료(구분 미확인) 또는 종료 예정 상태입니다. 미래 시작은 현재 수강중이 아니며, 예정 종료 사유는 함께 표시합니다.",
"nullable": false
},
"statusCode": {
"type": "string",
"description": "상태 표시 코드입니다. upcoming(미래 시작), active, retired, transferred, ended, cancelled, unknown 중 하나입니다. 전반 취소는 시작일과 관계없이 cancelled입니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"teamId",
"scheduleId",
"teamName",
"scheduleName",
"beginDate",
"endDate",
"endType",
"changeDate",
"scheduleDay",
"scheduleFrom",
"scheduleTo",
"transferFromId",
"transferDate",
"previousTeamName",
"isTransfer",
"isTransferCancelled",
"transferCancelledAt",
"classEndDate",
"effectiveEndDate",
"isEnded",
"status",
"statusCode"
]
}
}성공 응답 예시
{
"data": [
{
"id": 1,
"studentId": "00000001",
"teamId": 1,
"scheduleId": 1,
"teamName": "예시 이름",
"scheduleName": "예시 이름",
"beginDate": 20260115,
"endDate": 20260115,
"endType": "예시",
"changeDate": 20260115,
"scheduleDay": "예시",
"scheduleFrom": "예시",
"scheduleTo": "예시",
"transferFromId": 1,
"transferDate": 20260115,
"previousTeamName": "예시 이름",
"isTransfer": false,
"isTransferCancelled": false,
"transferCancelledAt": "2026-01-15T00:00:00Z",
"classEndDate": 20260115,
"effectiveEndDate": 20260115,
"isEnded": false,
"status": "예시",
"statusCode": "예시"
}
],
"meta": {
"requestId": "example-request-id"
}
}PATCH/v1/students/{id}/enrollments/{enrollmentId}수강 등록일 수정+
students.write · enrollments.date
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
enrollmentId | path | 필수 | 학생의 수강 이력 번호입니다. 해당 학생의 수강 이력 조회에서 확인합니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
beginDate | string | 필수 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"beginDate": {
"type": "string",
"format": "date",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false,
"minLength": 1
}
},
"required": [
"beginDate"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"beginDate": "2026-01-15"
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/students/{id}/enrollments/{enrollmentId}수강 등록 삭제(출결·과제 기록이 있으면 거절)+
students.write · enrollments.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
enrollmentId | path | 필수 | 학생의 수강 이력 번호입니다. 해당 학생의 수강 이력 조회에서 확인합니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/students/{id}/enrollments/{enrollmentId}/cancel-transfer전반 취소(새 반 수강번호 지정·이전 반 복원·취소 이력 보존)+
students.write · enrollments.cancel-transfer
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
enrollmentId | path | 필수 | 학생의 수강 이력 번호입니다. 해당 학생의 수강 이력 조회에서 확인합니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/students/{id}/enrollments/{enrollmentId}/end퇴원 처리+
students.write · enrollments.end
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
enrollmentId | path | 필수 | 학생의 수강 이력 번호입니다. 해당 학생의 수강 이력 조회에서 확인합니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
endDate | string | 필수 | 종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
memo | string | 조건부·선택 | 퇴원·전반 처리 기록에 함께 저장할 선택 메모입니다. 최대 2000자이며 생략하면 메모를 추가하지 않습니다. 처리와 메모 저장은 함께 성공하거나 취소됩니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"endDate": {
"type": "string",
"format": "date",
"description": "종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false,
"minLength": 1
},
"memo": {
"type": "string",
"description": "퇴원·전반 처리 기록에 함께 저장할 선택 메모입니다. 최대 2000자이며 생략하면 메모를 추가하지 않습니다. 처리와 메모 저장은 함께 성공하거나 취소됩니다.",
"nullable": false,
"maxLength": 2000,
"default": ""
}
},
"required": [
"endDate"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"endDate": "2026-01-15",
"memo": "예시"
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/students/{id}/enrollments/{enrollmentId}/move수강반 전반(원 수강 종료와 신규 등록을 함께 저장)+
students.write · enrollments.move
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
enrollmentId | path | 필수 | 학생의 수강 이력 번호입니다. 해당 학생의 수강 이력 조회에서 확인합니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다. | 1 |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요. | 1 |
beginDate | string | 필수 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | "2026-01-15" |
memo | string | 조건부·선택 | 퇴원·전반 처리 기록에 함께 저장할 선택 메모입니다. 최대 2000자이며 생략하면 메모를 추가하지 않습니다. 처리와 메모 저장은 함께 성공하거나 취소됩니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"beginDate": {
"type": "string",
"format": "date",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false,
"minLength": 1
},
"memo": {
"type": "string",
"description": "퇴원·전반 처리 기록에 함께 저장할 선택 메모입니다. 최대 2000자이며 생략하면 메모를 추가하지 않습니다. 처리와 메모 저장은 함께 성공하거나 취소됩니다.",
"nullable": false,
"maxLength": 2000,
"default": ""
}
},
"required": [
"teamId",
"scheduleId",
"beginDate"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"teamId": 1,
"scheduleId": 1,
"beginDate": "2026-01-15",
"memo": "예시"
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/students/{id}/enrollments/{enrollmentId}/restore퇴원 취소+
students.write · enrollments.restore
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
enrollmentId | path | 필수 | 학생의 수강 이력 번호입니다. 해당 학생의 수강 이력 조회에서 확인합니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}/detail학생 이름 클릭 통합정보: 기본정보·수강 전체·최근 상담·시험성적·클리닉 요약+
students.read · student.detail.overview
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
profile | object | 필수 | 비밀번호를 제외한 실제 학생 기본정보입니다. | 하위 필드·본문 예시 참조 |
profile.id | string | 필수 | 조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다. | "1" |
profile.name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
profile.school | string | 필수 | 학교 이름입니다. 빈 문자열이면 미입력입니다. | "예시" |
profile.grade | string | 필수 | 학년 표시값입니다. | "예시" |
profile.major | string | 필수 | 계열 또는 전공 구분값입니다. | "예시" |
profile.studentPhone | string | 필수 | 학생 휴대전화 번호입니다. | "010-0000-0000" |
profile.parentPhone | string | 필수 | 보호자 연락처입니다. | "010-0000-0000" |
profile.paymentPhone | string | 필수 | 결제 안내를 받을 연락처입니다. | "010-0000-0000" |
profile.email | string | 필수 | 이메일 주소입니다. | "sample@example.com" |
profile.memo | string | 필수 | 학생 관리용 메모입니다. | "예시" |
enrollments | object | 필수 | 수강·종료·전반 이력의 앞 100건과 전체 수입니다. 추가 이력은 수강 상세 API의 다음 페이지에서 조회합니다. | 하위 필드·본문 예시 참조 |
enrollments.studentId | string | 조건부·선택 | 현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다. | "00000001" |
enrollments.studentName | string | 조건부·선택 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
enrollments.items | array | 조건부·선택 | 현재 페이지의 세부 이력입니다. | 하위 필드·본문 예시 참조 |
enrollments.items[].id | integer | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | 1 |
enrollments.items[].studentId | string | 필수 | 학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다. | "00000001" |
enrollments.items[].teamId | integer | 필수 | 수강반 고유 번호입니다. 수강반 조회에서 확인합니다. | 1 |
enrollments.items[].scheduleId | integer | 필수 | 수강반 시간표 고유 번호입니다. 해당 반의 시간표여야 합니다. | 1 |
enrollments.items[].teamName | string | 필수 | 수강반 이름입니다. | "예시 이름" |
enrollments.items[].scheduleName | string | 필수 | 시간표 표시 이름입니다. | "예시 이름" |
enrollments.items[].beginDate | integer | 필수 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | 20260115 |
enrollments.items[].endDate | integer | 필수 | 종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | 20260115 |
enrollments.items[].endType | string | 필수 | 저장된 수강 종료 사유입니다. 빈 문자열, 퇴원, 전반, 종강, 전반취소를 사용합니다. 최대 20자이며 기존의 미확인 사유도 보존합니다. 이미 시작한 수강의 미래 종료는 active, 미래 시작은 upcoming이며 전반취소는 시작일과 관계없이 항상 cancelled입니다. | "예시" |
enrollments.items[].changeDate | integer | 필수 | 전반으로 종료되는 기존 수강 건의 전반일입니다. yyyyMMdd 정수이며 0은 미설정입니다. | 20260115 |
enrollments.items[].scheduleDay | string | 필수 | 해당 수강 시간표의 실제 요일입니다. 없으면 빈 문자열입니다. | "예시" |
enrollments.items[].scheduleFrom | string | 필수 | 해당 수강 시간표의 실제 시작 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다. | "예시" |
enrollments.items[].scheduleTo | string | 필수 | 해당 수강 시간표의 실제 종료 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다. | "예시" |
enrollments.items[].transferFromId | integer | 필수 | 전반 전의 기존 수강 건 번호입니다. 연결 없는 과거 자료는 null입니다. | 1 |
enrollments.items[].transferDate | integer | 필수 | 새 반으로 전반한 지정일입니다. yyyyMMdd 정수, 0은 연결 없음입니다. | 20260115 |
enrollments.items[].previousTeamName | string | 필수 | 전반 이전 반·시간표 표시명입니다. | "예시 이름" |
enrollments.items[].isTransfer | boolean | 필수 | 명시적인 이전 수강 연결값이 있는 전반 등록인지 나타냅니다. | false |
enrollments.items[].isTransferCancelled | boolean | 필수 | 전반 취소 이력인지 나타냅니다. 취소해도 출결·수납 자료와 수강 건은 보존됩니다. | false |
enrollments.items[].transferCancelledAt | string | 필수 | 전반 취소 시각(UTC)입니다. 취소 전에는 null입니다. | "2026-01-15T00:00:00Z" |
enrollments.items[].classEndDate | integer | 필수 | 반 자체의 종강일입니다. 학생별 endDate와 별개인 yyyyMMdd 정수이며 0은 미설정입니다. | 20260115 |
enrollments.items[].effectiveEndDate | integer | 필수 | 조회 시 적용할 종료일입니다. 학생별 종료일이 없으면 반 종강일을 사용하며 종료 사유는 추정하지 않습니다. | 20260115 |
enrollments.items[].isEnded | boolean | 필수 | 한국 날짜를 기준으로 종료 효력이 발생했는지 나타냅니다. 일반 미래 종료는 false지만 전반 취소 이력은 시작일과 관계없이 항상 true입니다. | false |
enrollments.items[].status | string | 필수 | 수강 시작 전, 수강중, 퇴원, 전반, 종강, 전반 취소, 종료(구분 미확인) 또는 종료 예정 상태입니다. 미래 시작은 현재 수강중이 아니며, 예정 종료 사유는 함께 표시합니다. | "예시" |
enrollments.items[].statusCode | string | 필수 | 상태 표시 코드입니다. upcoming(미래 시작), active, retired, transferred, ended, cancelled, unknown 중 하나입니다. 전반 취소는 시작일과 관계없이 cancelled입니다. | "예시" |
enrollments.page | integer | 조건부·선택 | 페이지 번호입니다. | 1 |
enrollments.pageSize | integer | 조건부·선택 | 페이지당 자료 수입니다. | 1 |
enrollments.total | integer | 조건부·선택 | 같은 조건의 전체 이력 수입니다. | 1 |
recentNotes | object | 필수 | 최근 상담 5건입니다. 전체 상담 수와 페이지 정보도 반환합니다. | 하위 필드·본문 예시 참조 |
recentNotes.studentId | string | 조건부·선택 | 현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다. | "00000001" |
recentNotes.studentName | string | 조건부·선택 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
recentNotes.items | array | 조건부·선택 | 현재 페이지의 세부 이력입니다. | 하위 필드·본문 예시 참조 |
recentNotes.items[].id | integer | 필수 | 현재 학생의 상담 기록 번호입니다. | 1 |
recentNotes.items[].studentId | string | 필수 | 이 상담 기록이 속한 실제 학생 번호입니다. | "00000001" |
recentNotes.items[].studentName | string | 필수 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
recentNotes.items[].version | string | 필수 | 다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요. | "예시" |
recentNotes.items[].content | string | 필수 | 저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다. | "예시" |
recentNotes.items[].staffId | string | 필수 | 상담 담당 로그인 아이디입니다. | "1" |
recentNotes.items[].staffName | string | 필수 | 상담 담당자 이름입니다. | "예시 이름" |
recentNotes.items[].type | string | 필수 | 상담 유형입니다. | "예시" |
recentNotes.items[].reservedAt | string | 필수 | 예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다. | "예시" |
recentNotes.items[].status | string | 필수 | 저장된 예약 진행 상태입니다. | "예시" |
recentNotes.items[].recordedAt | string | 필수 | 실제 기록 시각입니다. | "2026-01-15T00:00:00Z" |
recentNotes.items[].homeworkStudentId | integer | 필수 | 연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다. | 1 |
recentNotes.items[].lessonId | integer | 필수 | 명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다. | 1 |
recentNotes.items[].lessonTitle | string | 필수 | 해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다. | "예시" |
recentNotes.items[].lessonDate | string | 필수 | 연결된 수업의 실제 수업일입니다. | "2026-01-15" |
recentNotes.page | integer | 조건부·선택 | 페이지 번호입니다. | 1 |
recentNotes.pageSize | integer | 조건부·선택 | 페이지당 자료 수입니다. | 1 |
recentNotes.total | integer | 조건부·선택 | 같은 조건의 전체 이력 수입니다. | 1 |
recentScores | object | 필수 | 최근 시험성적 5건입니다. 조회만으로 공개 성적표 링크를 발급하지 않습니다. | 하위 필드·본문 예시 참조 |
recentScores.studentId | string | 조건부·선택 | 현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다. | "00000001" |
recentScores.studentName | string | 조건부·선택 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
recentScores.items | array | 조건부·선택 | 현재 페이지의 세부 이력입니다. | 하위 필드·본문 예시 참조 |
recentScores.items[].gradeId | integer | 필수 | 해당 학생의 실제 채점 기록 번호입니다. | 1 |
recentScores.items[].examId | integer | 필수 | 시험 번호입니다. | 1 |
recentScores.items[].name | string | 필수 | 시험 구분 이름입니다. | "예시 이름" |
recentScores.items[].title | string | 필수 | 시험 제목입니다. | "예시" |
recentScores.items[].date | string | 필수 | 저장된 채점일입니다. | "2026-01-15" |
recentScores.items[].score | number | 필수 | 학생 점수입니다. | 1 |
recentScores.items[].average | number | 필수 | 시험 평균 점수입니다. | 1 |
recentScores.items[].maximum | number | 필수 | 정답지 배점 합계인 시험 만점입니다. 실제 응시자의 최고 득점이 아닙니다. | 1 |
recentScores.items[].wrongAnswers | string | 필수 | 이 조회에서 오답 문항을 제공하지 않으면 null입니다. null은 오답 0개가 아니며 등수나 응시 인원을 오답·응시 문항 수로 해석하지 마세요. 문항별 답안·배점·득점은 채점 성적 조회의 includeAnalysis=true로 확인합니다. | "예시" |
recentScores.items[].rank | string | 필수 | 학원에 저장된 등수 / 응시 인원 표시입니다. 예: 2/2. 문항 수나 오답 개수가 아닙니다. | "예시" |
recentScores.items[].questionCount | integer | 필수 | 정답지에 설정된 전체 문항 수입니다. 선택과목에 따라 학생의 실제 응시 문항 수와 다를 수 있으며 알 수 없으면 null입니다. | 1 |
recentScores.items[].differenceFromAverage | number | 필수 | 해당 시험 점수에서 평균을 뺀 값. 음수이면 평균 미만. 서로 다른 시험 점수의 평균이 아님. | 1 |
recentScores.items[].belowAverage | boolean | 필수 | 해당 시험에서 저장된 평균 미만인지 여부. true이면 평균 이상으로 표현하지 않음. 등수·분위와는 별개. | false |
recentScores.page | integer | 조건부·선택 | 페이지 번호입니다. | 1 |
recentScores.pageSize | integer | 조건부·선택 | 페이지당 자료 수입니다. | 1 |
recentScores.total | integer | 조건부·선택 | 같은 조건의 전체 이력 수입니다. | 1 |
recentClinics | object | 필수 | 최근 클리닉 이력 5건입니다. | 하위 필드·본문 예시 참조 |
recentClinics.studentId | string | 조건부·선택 | 현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다. | "00000001" |
recentClinics.studentName | string | 조건부·선택 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
recentClinics.items | array | 조건부·선택 | 현재 페이지의 세부 이력입니다. | 하위 필드·본문 예시 참조 |
recentClinics.items[].appointmentId | integer | 필수 | 클리닉 예약 번호입니다. | 1 |
recentClinics.items[].reviewId | integer | 필수 | 클리닉 리뷰 번호입니다. | 1 |
recentClinics.items[].reservedAt | string | 필수 | 저장된 예약 일시입니다. | "예시" |
recentClinics.items[].status | string | 필수 | 예약 진행 상태입니다. | "예시" |
recentClinics.items[].memo | string | 필수 | 예약 메모입니다. | "예시" |
recentClinics.items[].review | string | 필수 | 등록된 리뷰 원문입니다. | "예시" |
recentClinics.items[].staff | string | 필수 | 기록 담당자입니다. | "예시" |
recentClinics.page | integer | 조건부·선택 | 페이지 번호입니다. | 1 |
recentClinics.pageSize | integer | 조건부·선택 | 페이지당 자료 수입니다. | 1 |
recentClinics.total | integer | 조건부·선택 | 같은 조건의 전체 이력 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"profile": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
},
"school": {
"type": "string",
"description": "학교 이름입니다. 빈 문자열이면 미입력입니다.",
"nullable": false
},
"grade": {
"type": "string",
"description": "학년 표시값입니다.",
"nullable": false
},
"major": {
"type": "string",
"description": "계열 또는 전공 구분값입니다.",
"nullable": false
},
"studentPhone": {
"type": "string",
"description": "학생 휴대전화 번호입니다.",
"nullable": false
},
"parentPhone": {
"type": "string",
"description": "보호자 연락처입니다.",
"nullable": false
},
"paymentPhone": {
"type": "string",
"description": "결제 안내를 받을 연락처입니다.",
"nullable": false
},
"email": {
"type": "string",
"description": "이메일 주소입니다.",
"nullable": false
},
"memo": {
"type": "string",
"description": "학생 관리용 메모입니다.",
"nullable": false
}
},
"required": [
"id",
"name",
"school",
"grade",
"major",
"studentPhone",
"parentPhone",
"paymentPhone",
"email",
"memo"
],
"description": "비밀번호를 제외한 실제 학생 기본정보입니다.",
"nullable": false
},
"enrollments": {
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "수강반 고유 번호입니다. 수강반 조회에서 확인합니다.",
"nullable": false
},
"scheduleId": {
"type": "integer",
"description": "수강반 시간표 고유 번호입니다. 해당 반의 시간표여야 합니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "수강반 이름입니다.",
"nullable": false
},
"scheduleName": {
"type": "string",
"description": "시간표 표시 이름입니다.",
"nullable": false
},
"beginDate": {
"type": "integer",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false
},
"endDate": {
"type": "integer",
"description": "종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false
},
"endType": {
"type": "string",
"description": "저장된 수강 종료 사유입니다. 빈 문자열, 퇴원, 전반, 종강, 전반취소를 사용합니다. 최대 20자이며 기존의 미확인 사유도 보존합니다. 이미 시작한 수강의 미래 종료는 active, 미래 시작은 upcoming이며 전반취소는 시작일과 관계없이 항상 cancelled입니다.",
"nullable": false,
"maxLength": 20
},
"changeDate": {
"type": "integer",
"description": "전반으로 종료되는 기존 수강 건의 전반일입니다. yyyyMMdd 정수이며 0은 미설정입니다.",
"nullable": false
},
"scheduleDay": {
"type": "string",
"description": "해당 수강 시간표의 실제 요일입니다. 없으면 빈 문자열입니다.",
"nullable": false
},
"scheduleFrom": {
"type": "string",
"description": "해당 수강 시간표의 실제 시작 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다.",
"nullable": false
},
"scheduleTo": {
"type": "string",
"description": "해당 수강 시간표의 실제 종료 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다.",
"nullable": false
},
"transferFromId": {
"type": "integer",
"description": "전반 전의 기존 수강 건 번호입니다. 연결 없는 과거 자료는 null입니다.",
"nullable": true
},
"transferDate": {
"type": "integer",
"description": "새 반으로 전반한 지정일입니다. yyyyMMdd 정수, 0은 연결 없음입니다.",
"nullable": false
},
"previousTeamName": {
"type": "string",
"description": "전반 이전 반·시간표 표시명입니다.",
"nullable": false
},
"isTransfer": {
"type": "boolean",
"description": "명시적인 이전 수강 연결값이 있는 전반 등록인지 나타냅니다.",
"nullable": false
},
"isTransferCancelled": {
"type": "boolean",
"description": "전반 취소 이력인지 나타냅니다. 취소해도 출결·수납 자료와 수강 건은 보존됩니다.",
"nullable": false
},
"transferCancelledAt": {
"type": "string",
"format": "date-time",
"description": "전반 취소 시각(UTC)입니다. 취소 전에는 null입니다.",
"nullable": true
},
"classEndDate": {
"type": "integer",
"description": "반 자체의 종강일입니다. 학생별 endDate와 별개인 yyyyMMdd 정수이며 0은 미설정입니다.",
"nullable": false
},
"effectiveEndDate": {
"type": "integer",
"description": "조회 시 적용할 종료일입니다. 학생별 종료일이 없으면 반 종강일을 사용하며 종료 사유는 추정하지 않습니다.",
"nullable": false
},
"isEnded": {
"type": "boolean",
"description": "한국 날짜를 기준으로 종료 효력이 발생했는지 나타냅니다. 일반 미래 종료는 false지만 전반 취소 이력은 시작일과 관계없이 항상 true입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "수강 시작 전, 수강중, 퇴원, 전반, 종강, 전반 취소, 종료(구분 미확인) 또는 종료 예정 상태입니다. 미래 시작은 현재 수강중이 아니며, 예정 종료 사유는 함께 표시합니다.",
"nullable": false
},
"statusCode": {
"type": "string",
"description": "상태 표시 코드입니다. upcoming(미래 시작), active, retired, transferred, ended, cancelled, unknown 중 하나입니다. 전반 취소는 시작일과 관계없이 cancelled입니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"teamId",
"scheduleId",
"teamName",
"scheduleName",
"beginDate",
"endDate",
"endType",
"changeDate",
"scheduleDay",
"scheduleFrom",
"scheduleTo",
"transferFromId",
"transferDate",
"previousTeamName",
"isTransfer",
"isTransferCancelled",
"transferCancelledAt",
"classEndDate",
"effectiveEndDate",
"isEnded",
"status",
"statusCode"
]
},
"description": "현재 페이지의 세부 이력입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "페이지 번호입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 자료 수입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "같은 조건의 전체 이력 수입니다.",
"nullable": false
}
},
"description": "수강·종료·전반 이력의 앞 100건과 전체 수입니다. 추가 이력은 수강 상세 API의 다음 페이지에서 조회합니다.",
"nullable": false
},
"recentNotes": {
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "현재 학생의 상담 기록 번호입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "이 상담 기록이 속한 실제 학생 번호입니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"version": {
"type": "string",
"description": "다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요.",
"nullable": false
},
"content": {
"type": "string",
"description": "저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다.",
"nullable": false
},
"staffId": {
"type": "string",
"description": "상담 담당 로그인 아이디입니다.",
"nullable": false
},
"staffName": {
"type": "string",
"description": "상담 담당자 이름입니다.",
"nullable": false
},
"type": {
"type": "string",
"description": "상담 유형입니다.",
"nullable": false
},
"reservedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$",
"description": "예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "저장된 예약 진행 상태입니다.",
"nullable": false
},
"recordedAt": {
"type": "string",
"format": "date-time",
"description": "실제 기록 시각입니다.",
"nullable": false
},
"homeworkStudentId": {
"type": "integer",
"description": "연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다.",
"nullable": false
},
"lessonId": {
"type": "integer",
"description": "명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다.",
"nullable": false
},
"lessonTitle": {
"type": "string",
"description": "해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다.",
"nullable": false
},
"lessonDate": {
"type": "string",
"description": "연결된 수업의 실제 수업일입니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"studentName",
"version",
"content",
"staffId",
"staffName",
"type",
"reservedAt",
"status",
"recordedAt",
"homeworkStudentId",
"lessonId",
"lessonTitle",
"lessonDate"
]
},
"description": "현재 페이지의 세부 이력입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "페이지 번호입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 자료 수입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "같은 조건의 전체 이력 수입니다.",
"nullable": false
}
},
"description": "최근 상담 5건입니다. 전체 상담 수와 페이지 정보도 반환합니다.",
"nullable": false
},
"recentScores": {
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"gradeId": {
"type": "integer",
"description": "해당 학생의 실제 채점 기록 번호입니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "시험 번호입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "시험 구분 이름입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "시험 제목입니다.",
"nullable": false
},
"date": {
"type": "string",
"description": "저장된 채점일입니다.",
"nullable": false
},
"score": {
"type": "number",
"description": "학생 점수입니다.",
"nullable": false
},
"average": {
"type": "number",
"description": "시험 평균 점수입니다.",
"nullable": false
},
"maximum": {
"type": "number",
"description": "정답지 배점 합계인 시험 만점입니다. 실제 응시자의 최고 득점이 아닙니다.",
"nullable": false
},
"wrongAnswers": {
"type": "string",
"description": "이 조회에서 오답 문항을 제공하지 않으면 null입니다. null은 오답 0개가 아니며 등수나 응시 인원을 오답·응시 문항 수로 해석하지 마세요. 문항별 답안·배점·득점은 채점 성적 조회의 includeAnalysis=true로 확인합니다.",
"nullable": true
},
"rank": {
"type": "string",
"description": "학원에 저장된 등수 / 응시 인원 표시입니다. 예: 2/2. 문항 수나 오답 개수가 아닙니다.",
"nullable": false
},
"questionCount": {
"type": "integer",
"description": "정답지에 설정된 전체 문항 수입니다. 선택과목에 따라 학생의 실제 응시 문항 수와 다를 수 있으며 알 수 없으면 null입니다.",
"nullable": true
},
"differenceFromAverage": {
"type": "number",
"description": "해당 시험 점수에서 평균을 뺀 값. 음수이면 평균 미만. 서로 다른 시험 점수의 평균이 아님.",
"nullable": false
},
"belowAverage": {
"type": "boolean",
"description": "해당 시험에서 저장된 평균 미만인지 여부. true이면 평균 이상으로 표현하지 않음. 등수·분위와는 별개.",
"nullable": false
}
},
"required": [
"gradeId",
"examId",
"name",
"title",
"date",
"score",
"average",
"maximum",
"wrongAnswers",
"rank",
"questionCount",
"differenceFromAverage",
"belowAverage"
]
},
"description": "현재 페이지의 세부 이력입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "페이지 번호입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 자료 수입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "같은 조건의 전체 이력 수입니다.",
"nullable": false
}
},
"description": "최근 시험성적 5건입니다. 조회만으로 공개 성적표 링크를 발급하지 않습니다.",
"nullable": false
},
"recentClinics": {
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"appointmentId": {
"type": "integer",
"description": "클리닉 예약 번호입니다.",
"nullable": false
},
"reviewId": {
"type": "integer",
"description": "클리닉 리뷰 번호입니다.",
"nullable": false
},
"reservedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$",
"description": "저장된 예약 일시입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "예약 진행 상태입니다.",
"nullable": false
},
"memo": {
"type": "string",
"description": "예약 메모입니다.",
"nullable": false
},
"review": {
"type": "string",
"description": "등록된 리뷰 원문입니다.",
"nullable": false
},
"staff": {
"type": "string",
"description": "기록 담당자입니다.",
"nullable": false
}
},
"required": [
"appointmentId",
"reviewId",
"reservedAt",
"status",
"memo",
"review",
"staff"
]
},
"description": "현재 페이지의 세부 이력입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "페이지 번호입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 자료 수입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "같은 조건의 전체 이력 수입니다.",
"nullable": false
}
},
"description": "최근 클리닉 이력 5건입니다.",
"nullable": false
}
},
"required": [
"profile",
"enrollments",
"recentNotes",
"recentScores",
"recentClinics"
]
}성공 응답 예시
{
"data": {
"profile": {
"id": "1",
"name": "예시 이름",
"school": "예시",
"grade": "예시",
"major": "예시",
"studentPhone": "010-0000-0000",
"parentPhone": "010-0000-0000",
"paymentPhone": "010-0000-0000",
"email": "sample@example.com",
"memo": "예시"
},
"enrollments": {
"studentId": "00000001",
"studentName": "예시 이름",
"items": [
{
"id": 1,
"studentId": "00000001",
"teamId": 1,
"scheduleId": 1,
"teamName": "예시 이름",
"scheduleName": "예시 이름",
"beginDate": 20260115,
"endDate": 20260115,
"endType": "예시",
"changeDate": 20260115,
"scheduleDay": "예시",
"scheduleFrom": "예시",
"scheduleTo": "예시",
"transferFromId": 1,
"transferDate": 20260115,
"previousTeamName": "예시 이름",
"isTransfer": false,
"isTransferCancelled": false,
"transferCancelledAt": "2026-01-15T00:00:00Z",
"classEndDate": 20260115,
"effectiveEndDate": 20260115,
"isEnded": false,
"status": "예시",
"statusCode": "예시"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"recentNotes": {
"studentId": "00000001",
"studentName": "예시 이름",
"items": [
{
"id": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"version": "예시",
"content": "예시",
"staffId": "1",
"staffName": "예시 이름",
"type": "예시",
"reservedAt": "예시",
"status": "예시",
"recordedAt": "2026-01-15T00:00:00Z",
"homeworkStudentId": 1,
"lessonId": 1,
"lessonTitle": "예시",
"lessonDate": "2026-01-15"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"recentScores": {
"studentId": "00000001",
"studentName": "예시 이름",
"items": [
{
"gradeId": 1,
"examId": 1,
"name": "예시 이름",
"title": "예시",
"date": "2026-01-15",
"score": 1,
"average": 1,
"maximum": 1,
"wrongAnswers": "예시",
"rank": "예시",
"questionCount": 1,
"differenceFromAverage": 1,
"belowAverage": false
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"recentClinics": {
"studentId": "00000001",
"studentName": "예시 이름",
"items": [
{
"appointmentId": 1,
"reviewId": 1,
"reservedAt": "예시",
"status": "예시",
"memo": "예시",
"review": "예시",
"staff": "예시"
}
],
"page": 1,
"pageSize": 1,
"total": 1
}
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}/detail/attendance지정 학생 1명의 수업일별 출결·보강 이력(0=무결·4=유결은 결석, 5=출석·6=인강·7=보강완료·8=보강생과 구별)+
students.read · student.detail.attendance
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
from | query | 선택 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 선택 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 조건부·선택 | 현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다. | "00000001" |
studentName | string | 조건부·선택 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
items | array | 조건부·선택 | 현재 페이지의 세부 이력입니다. | 하위 필드·본문 예시 참조 |
items[].lessonId | integer | 필수 | 수업 번호입니다. | 1 |
items[].attendanceId | integer | 필수 | 학생 출결 기록 번호입니다. | 1 |
items[].teamId | integer | 필수 | 실제 수강반 번호입니다. | 1 |
items[].teamName | string | 필수 | 수강반 이름입니다. | "예시 이름" |
items[].date | string | 필수 | 저장된 수업일입니다. | "2026-01-15" |
items[].session | integer | 필수 | 수업 회차입니다. | 1 |
items[].attendanceCode | integer | 필수 | 출결 코드: 0=무결(무단결석), 4=유결(사유결석), 5=출석, 6=인강, 7=보강완료, 8=보강생. 결석은 0·4이며 인강·보강과 구별. | 1 |
items[].attendance | string | 필수 | 출결 표시 이름입니다. | "예시" |
items[].comment | string | 필수 | 수업·과제의 학생 개별 학습 피드백 원문. 결석 사유 전용 필드가 아니며 시험 응원·풀이 조언을 결석 이유로 해석하지 않음. 원인이 명시되지 않으면 사유 미확인. | "예시" |
items[].makeupTeamId | integer | 필수 | 연결된 보강 수강반 번호입니다. 0은 없음입니다. | 1 |
items[].makeupTeamName | string | 필수 | 연결된 보강 수강반 이름입니다. | "예시 이름" |
items[].valueItems | array | 필수 | 같은 수업의 실제 과제·시험 항목 제목·내용·결과 안내와 학생 결과. 값 없음은 미완료 증거가 아님. | 하위 필드·본문 예시 참조 |
items[].valueItems[].field | string | 필수 | 저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요. | "예시" |
items[].valueItems[].category | string | 필수 | 과제, 도전, 시험 중 항목 종류입니다. | "예시" |
items[].valueItems[].position | integer | 필수 | 같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다. | 1 |
items[].valueItems[].title | string | 필수 | 같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요. | "예시" |
items[].valueItems[].content | string | 필수 | 같은 수업 설정의 과제·시험 내용 원문입니다. | "예시" |
items[].valueItems[].resultGuide | string | 필수 | 같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요. | "예시" |
items[].valueItems[].value | string | 필수 | 해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다. | "예시" |
items[].valueItems[].valueState | string | 필수 | present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다. | "예시" |
items[].valueItems[].examId | integer | 필수 | 같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다. | 1 |
items[].valueItemsAvailable | boolean | 필수 | 과제 항목의 원본을 조회했는지 여부. false이면 과제 미완료 여부를 판단할 수 없음. | false |
items[].attendanceMeaning | string | 필수 | 출결 코드의 명확한 뜻. 무결은 무단결석이며 정상 참여가 아님. | "예시" |
items[].isAbsence | boolean | 필수 | 명확한 결석 여부. 코드 0·4는 true, 5·6·7·8은 false, 그 밖에는 null. | false |
page | integer | 조건부·선택 | 페이지 번호입니다. | 1 |
pageSize | integer | 조건부·선택 | 페이지당 자료 수입니다. | 1 |
total | integer | 조건부·선택 | 같은 조건의 전체 이력 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"lessonId": {
"type": "integer",
"description": "수업 번호입니다.",
"nullable": false
},
"attendanceId": {
"type": "integer",
"description": "학생 출결 기록 번호입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "실제 수강반 번호입니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "수강반 이름입니다.",
"nullable": false
},
"date": {
"type": "string",
"description": "저장된 수업일입니다.",
"nullable": false
},
"session": {
"type": "integer",
"description": "수업 회차입니다.",
"nullable": false
},
"attendanceCode": {
"type": "integer",
"x-read-display-field": "attendanceMeaning",
"description": "출결 코드: 0=무결(무단결석), 4=유결(사유결석), 5=출석, 6=인강, 7=보강완료, 8=보강생. 결석은 0·4이며 인강·보강과 구별.",
"nullable": false
},
"attendance": {
"type": "string",
"description": "출결 표시 이름입니다.",
"nullable": false
},
"comment": {
"type": "string",
"description": "수업·과제의 학생 개별 학습 피드백 원문. 결석 사유 전용 필드가 아니며 시험 응원·풀이 조언을 결석 이유로 해석하지 않음. 원인이 명시되지 않으면 사유 미확인.",
"nullable": false
},
"makeupTeamId": {
"type": "integer",
"description": "연결된 보강 수강반 번호입니다. 0은 없음입니다.",
"nullable": false
},
"makeupTeamName": {
"type": "string",
"description": "연결된 보강 수강반 이름입니다.",
"nullable": false
},
"valueItems": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field": {
"type": "string",
"description": "저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요.",
"nullable": false
},
"category": {
"type": "string",
"description": "과제, 도전, 시험 중 항목 종류입니다.",
"nullable": false
},
"position": {
"type": "integer",
"description": "같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요.",
"nullable": false
},
"content": {
"type": "string",
"description": "같은 수업 설정의 과제·시험 내용 원문입니다.",
"nullable": false
},
"resultGuide": {
"type": "string",
"description": "같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요.",
"nullable": false
},
"value": {
"type": "string",
"description": "해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다.",
"nullable": true
},
"valueState": {
"type": "string",
"description": "present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다.",
"nullable": false
}
},
"required": [
"field",
"category",
"position",
"title",
"content",
"resultGuide",
"value",
"valueState",
"examId"
]
},
"description": "같은 수업의 실제 과제·시험 항목 제목·내용·결과 안내와 학생 결과. 값 없음은 미완료 증거가 아님.",
"nullable": false
},
"valueItemsAvailable": {
"type": "boolean",
"description": "과제 항목의 원본을 조회했는지 여부. false이면 과제 미완료 여부를 판단할 수 없음.",
"nullable": false
},
"attendanceMeaning": {
"type": "string",
"description": "출결 코드의 명확한 뜻. 무결은 무단결석이며 정상 참여가 아님.",
"nullable": false
},
"isAbsence": {
"type": "boolean",
"x-read-scope-key": "absence",
"description": "명확한 결석 여부. 코드 0·4는 true, 5·6·7·8은 false, 그 밖에는 null.",
"nullable": true
}
},
"required": [
"lessonId",
"attendanceId",
"teamId",
"teamName",
"date",
"session",
"attendanceCode",
"attendance",
"comment",
"makeupTeamId",
"makeupTeamName",
"valueItems",
"valueItemsAvailable",
"attendanceMeaning",
"isAbsence"
]
},
"description": "현재 페이지의 세부 이력입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "페이지 번호입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 자료 수입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "같은 조건의 전체 이력 수입니다.",
"nullable": false
}
}
}성공 응답 예시
{
"data": {
"studentId": "00000001",
"studentName": "예시 이름",
"items": [
{
"lessonId": 1,
"attendanceId": 1,
"teamId": 1,
"teamName": "예시 이름",
"date": "2026-01-15",
"session": 1,
"attendanceCode": 1,
"attendance": "예시",
"comment": "예시",
"makeupTeamId": 1,
"makeupTeamName": "예시 이름",
"valueItems": [
{
"field": "예시",
"category": "예시",
"position": 1,
"title": "예시",
"content": "예시",
"resultGuide": "예시",
"value": "예시",
"valueState": "예시",
"examId": 1
}
],
"valueItemsAvailable": false,
"attendanceMeaning": "예시",
"isAbsence": false
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}/detail/clinics학생의 클리닉 예약·완료·취소·불참과 리뷰·메모 이력 조회+
students.read · student.detail.clinics
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 조건부·선택 | 현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다. | "00000001" |
studentName | string | 조건부·선택 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
items | array | 조건부·선택 | 현재 페이지의 세부 이력입니다. | 하위 필드·본문 예시 참조 |
items[].appointmentId | integer | 필수 | 클리닉 예약 번호입니다. | 1 |
items[].reviewId | integer | 필수 | 클리닉 리뷰 번호입니다. | 1 |
items[].reservedAt | string | 필수 | 저장된 예약 일시입니다. | "예시" |
items[].status | string | 필수 | 예약 진행 상태입니다. | "예시" |
items[].memo | string | 필수 | 예약 메모입니다. | "예시" |
items[].review | string | 필수 | 등록된 리뷰 원문입니다. | "예시" |
items[].staff | string | 필수 | 기록 담당자입니다. | "예시" |
page | integer | 조건부·선택 | 페이지 번호입니다. | 1 |
pageSize | integer | 조건부·선택 | 페이지당 자료 수입니다. | 1 |
total | integer | 조건부·선택 | 같은 조건의 전체 이력 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"appointmentId": {
"type": "integer",
"description": "클리닉 예약 번호입니다.",
"nullable": false
},
"reviewId": {
"type": "integer",
"description": "클리닉 리뷰 번호입니다.",
"nullable": false
},
"reservedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$",
"description": "저장된 예약 일시입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "예약 진행 상태입니다.",
"nullable": false
},
"memo": {
"type": "string",
"description": "예약 메모입니다.",
"nullable": false
},
"review": {
"type": "string",
"description": "등록된 리뷰 원문입니다.",
"nullable": false
},
"staff": {
"type": "string",
"description": "기록 담당자입니다.",
"nullable": false
}
},
"required": [
"appointmentId",
"reviewId",
"reservedAt",
"status",
"memo",
"review",
"staff"
]
},
"description": "현재 페이지의 세부 이력입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "페이지 번호입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 자료 수입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "같은 조건의 전체 이력 수입니다.",
"nullable": false
}
}
}성공 응답 예시
{
"data": {
"studentId": "00000001",
"studentName": "예시 이름",
"items": [
{
"appointmentId": 1,
"reviewId": 1,
"reservedAt": "예시",
"status": "예시",
"memo": "예시",
"review": "예시",
"staff": "예시"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}/detail/discounts학생 통합정보의 할인율·형제 할인 연결 학생 이름과 번호 조회+
students.read · student.detail.discounts
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 조건부·선택 | 현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다. | "00000001" |
studentName | string | 조건부·선택 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
items | array | 조건부·선택 | 현재 페이지의 세부 이력입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 할인 기록 번호입니다. | 1 |
items[].code | string | 필수 | 할인 코드입니다. | "예시" |
items[].rate | integer | 필수 | 현재 할인율입니다. | 1 |
items[].relatedStudentId | string | 필수 | 형제 할인에 연결된 학생 번호입니다. | "00000001" |
items[].relatedStudentName | string | 필수 | 연결된 학생 이름입니다. | "예시 이름" |
page | integer | 조건부·선택 | 페이지 번호입니다. | 1 |
pageSize | integer | 조건부·선택 | 페이지당 자료 수입니다. | 1 |
total | integer | 조건부·선택 | 같은 조건의 전체 이력 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "할인 기록 번호입니다.",
"nullable": false
},
"code": {
"type": "string",
"description": "할인 코드입니다.",
"nullable": false
},
"rate": {
"type": "integer",
"description": "현재 할인율입니다.",
"nullable": false
},
"relatedStudentId": {
"type": "string",
"description": "형제 할인에 연결된 학생 번호입니다.",
"nullable": true
},
"relatedStudentName": {
"type": "string",
"description": "연결된 학생 이름입니다.",
"nullable": true
}
},
"required": [
"id",
"code",
"rate",
"relatedStudentId",
"relatedStudentName"
]
},
"description": "현재 페이지의 세부 이력입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "페이지 번호입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 자료 수입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "같은 조건의 전체 이력 수입니다.",
"nullable": false
}
}
}성공 응답 예시
{
"data": {
"studentId": "00000001",
"studentName": "예시 이름",
"items": [
{
"id": 1,
"code": "예시",
"rate": 1,
"relatedStudentId": "00000001",
"relatedStudentName": "예시 이름"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}/detail/enrollments학생 통합정보의 수강·퇴원·전반·종강·전반취소 이력과 이전 수강반 조회+
students.read · student.detail.enrollments
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 조건부·선택 | 현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다. | "00000001" |
studentName | string | 조건부·선택 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
items | array | 조건부·선택 | 현재 페이지의 세부 이력입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | 1 |
items[].studentId | string | 필수 | 학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다. | "00000001" |
items[].teamId | integer | 필수 | 수강반 고유 번호입니다. 수강반 조회에서 확인합니다. | 1 |
items[].scheduleId | integer | 필수 | 수강반 시간표 고유 번호입니다. 해당 반의 시간표여야 합니다. | 1 |
items[].teamName | string | 필수 | 수강반 이름입니다. | "예시 이름" |
items[].scheduleName | string | 필수 | 시간표 표시 이름입니다. | "예시 이름" |
items[].beginDate | integer | 필수 | 시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | 20260115 |
items[].endDate | integer | 필수 | 종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다. | 20260115 |
items[].endType | string | 필수 | 저장된 수강 종료 사유입니다. 빈 문자열, 퇴원, 전반, 종강, 전반취소를 사용합니다. 최대 20자이며 기존의 미확인 사유도 보존합니다. 이미 시작한 수강의 미래 종료는 active, 미래 시작은 upcoming이며 전반취소는 시작일과 관계없이 항상 cancelled입니다. | "예시" |
items[].changeDate | integer | 필수 | 전반으로 종료되는 기존 수강 건의 전반일입니다. yyyyMMdd 정수이며 0은 미설정입니다. | 20260115 |
items[].scheduleDay | string | 필수 | 해당 수강 시간표의 실제 요일입니다. 없으면 빈 문자열입니다. | "예시" |
items[].scheduleFrom | string | 필수 | 해당 수강 시간표의 실제 시작 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다. | "예시" |
items[].scheduleTo | string | 필수 | 해당 수강 시간표의 실제 종료 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다. | "예시" |
items[].transferFromId | integer | 필수 | 전반 전의 기존 수강 건 번호입니다. 연결 없는 과거 자료는 null입니다. | 1 |
items[].transferDate | integer | 필수 | 새 반으로 전반한 지정일입니다. yyyyMMdd 정수, 0은 연결 없음입니다. | 20260115 |
items[].previousTeamName | string | 필수 | 전반 이전 반·시간표 표시명입니다. | "예시 이름" |
items[].isTransfer | boolean | 필수 | 명시적인 이전 수강 연결값이 있는 전반 등록인지 나타냅니다. | false |
items[].isTransferCancelled | boolean | 필수 | 전반 취소 이력인지 나타냅니다. 취소해도 출결·수납 자료와 수강 건은 보존됩니다. | false |
items[].transferCancelledAt | string | 필수 | 전반 취소 시각(UTC)입니다. 취소 전에는 null입니다. | "2026-01-15T00:00:00Z" |
items[].classEndDate | integer | 필수 | 반 자체의 종강일입니다. 학생별 endDate와 별개인 yyyyMMdd 정수이며 0은 미설정입니다. | 20260115 |
items[].effectiveEndDate | integer | 필수 | 조회 시 적용할 종료일입니다. 학생별 종료일이 없으면 반 종강일을 사용하며 종료 사유는 추정하지 않습니다. | 20260115 |
items[].isEnded | boolean | 필수 | 한국 날짜를 기준으로 종료 효력이 발생했는지 나타냅니다. 일반 미래 종료는 false지만 전반 취소 이력은 시작일과 관계없이 항상 true입니다. | false |
items[].status | string | 필수 | 수강 시작 전, 수강중, 퇴원, 전반, 종강, 전반 취소, 종료(구분 미확인) 또는 종료 예정 상태입니다. 미래 시작은 현재 수강중이 아니며, 예정 종료 사유는 함께 표시합니다. | "예시" |
items[].statusCode | string | 필수 | 상태 표시 코드입니다. upcoming(미래 시작), active, retired, transferred, ended, cancelled, unknown 중 하나입니다. 전반 취소는 시작일과 관계없이 cancelled입니다. | "예시" |
page | integer | 조건부·선택 | 페이지 번호입니다. | 1 |
pageSize | integer | 조건부·선택 | 페이지당 자료 수입니다. | 1 |
total | integer | 조건부·선택 | 같은 조건의 전체 이력 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "수강반 고유 번호입니다. 수강반 조회에서 확인합니다.",
"nullable": false
},
"scheduleId": {
"type": "integer",
"description": "수강반 시간표 고유 번호입니다. 해당 반의 시간표여야 합니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "수강반 이름입니다.",
"nullable": false
},
"scheduleName": {
"type": "string",
"description": "시간표 표시 이름입니다.",
"nullable": false
},
"beginDate": {
"type": "integer",
"description": "시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false
},
"endDate": {
"type": "integer",
"description": "종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.",
"nullable": false
},
"endType": {
"type": "string",
"description": "저장된 수강 종료 사유입니다. 빈 문자열, 퇴원, 전반, 종강, 전반취소를 사용합니다. 최대 20자이며 기존의 미확인 사유도 보존합니다. 이미 시작한 수강의 미래 종료는 active, 미래 시작은 upcoming이며 전반취소는 시작일과 관계없이 항상 cancelled입니다.",
"nullable": false,
"maxLength": 20
},
"changeDate": {
"type": "integer",
"description": "전반으로 종료되는 기존 수강 건의 전반일입니다. yyyyMMdd 정수이며 0은 미설정입니다.",
"nullable": false
},
"scheduleDay": {
"type": "string",
"description": "해당 수강 시간표의 실제 요일입니다. 없으면 빈 문자열입니다.",
"nullable": false
},
"scheduleFrom": {
"type": "string",
"description": "해당 수강 시간표의 실제 시작 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다.",
"nullable": false
},
"scheduleTo": {
"type": "string",
"description": "해당 수강 시간표의 실제 종료 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다.",
"nullable": false
},
"transferFromId": {
"type": "integer",
"description": "전반 전의 기존 수강 건 번호입니다. 연결 없는 과거 자료는 null입니다.",
"nullable": true
},
"transferDate": {
"type": "integer",
"description": "새 반으로 전반한 지정일입니다. yyyyMMdd 정수, 0은 연결 없음입니다.",
"nullable": false
},
"previousTeamName": {
"type": "string",
"description": "전반 이전 반·시간표 표시명입니다.",
"nullable": false
},
"isTransfer": {
"type": "boolean",
"description": "명시적인 이전 수강 연결값이 있는 전반 등록인지 나타냅니다.",
"nullable": false
},
"isTransferCancelled": {
"type": "boolean",
"description": "전반 취소 이력인지 나타냅니다. 취소해도 출결·수납 자료와 수강 건은 보존됩니다.",
"nullable": false
},
"transferCancelledAt": {
"type": "string",
"format": "date-time",
"description": "전반 취소 시각(UTC)입니다. 취소 전에는 null입니다.",
"nullable": true
},
"classEndDate": {
"type": "integer",
"description": "반 자체의 종강일입니다. 학생별 endDate와 별개인 yyyyMMdd 정수이며 0은 미설정입니다.",
"nullable": false
},
"effectiveEndDate": {
"type": "integer",
"description": "조회 시 적용할 종료일입니다. 학생별 종료일이 없으면 반 종강일을 사용하며 종료 사유는 추정하지 않습니다.",
"nullable": false
},
"isEnded": {
"type": "boolean",
"description": "한국 날짜를 기준으로 종료 효력이 발생했는지 나타냅니다. 일반 미래 종료는 false지만 전반 취소 이력은 시작일과 관계없이 항상 true입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "수강 시작 전, 수강중, 퇴원, 전반, 종강, 전반 취소, 종료(구분 미확인) 또는 종료 예정 상태입니다. 미래 시작은 현재 수강중이 아니며, 예정 종료 사유는 함께 표시합니다.",
"nullable": false
},
"statusCode": {
"type": "string",
"description": "상태 표시 코드입니다. upcoming(미래 시작), active, retired, transferred, ended, cancelled, unknown 중 하나입니다. 전반 취소는 시작일과 관계없이 cancelled입니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"teamId",
"scheduleId",
"teamName",
"scheduleName",
"beginDate",
"endDate",
"endType",
"changeDate",
"scheduleDay",
"scheduleFrom",
"scheduleTo",
"transferFromId",
"transferDate",
"previousTeamName",
"isTransfer",
"isTransferCancelled",
"transferCancelledAt",
"classEndDate",
"effectiveEndDate",
"isEnded",
"status",
"statusCode"
]
},
"description": "현재 페이지의 세부 이력입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "페이지 번호입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 자료 수입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "같은 조건의 전체 이력 수입니다.",
"nullable": false
}
}
}성공 응답 예시
{
"data": {
"studentId": "00000001",
"studentName": "예시 이름",
"items": [
{
"id": 1,
"studentId": "00000001",
"teamId": 1,
"scheduleId": 1,
"teamName": "예시 이름",
"scheduleName": "예시 이름",
"beginDate": 20260115,
"endDate": 20260115,
"endType": "예시",
"changeDate": 20260115,
"scheduleDay": "예시",
"scheduleFrom": "예시",
"scheduleTo": "예시",
"transferFromId": 1,
"transferDate": 20260115,
"previousTeamName": "예시 이름",
"isTransfer": false,
"isTransferCancelled": false,
"transferCancelledAt": "2026-01-15T00:00:00Z",
"classEndDate": 20260115,
"effectiveEndDate": 20260115,
"isEnded": false,
"status": "예시",
"statusCode": "예시"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}/detail/homework학생 과제·시험 검사결과와 수업 회차·출결·코멘트. valueItems가 같은 수업의 실제 항목 제목·안내·결과를 연결, 빈 값은 미완료로 추측하지 않음+
students.read · student.detail.homework
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
from | query | 선택 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 선택 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 조건부·선택 | 현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다. | "00000001" |
studentName | string | 조건부·선택 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
items | array | 조건부·선택 | 현재 페이지의 세부 이력입니다. | 하위 필드·본문 예시 참조 |
items[].lessonId | integer | 필수 | 수업 번호입니다. | 1 |
items[].attendanceId | integer | 필수 | 학생 출결 기록 번호입니다. | 1 |
items[].teamId | integer | 필수 | 실제 수강반 번호입니다. | 1 |
items[].teamName | string | 필수 | 수강반 이름입니다. | "예시 이름" |
items[].date | string | 필수 | 저장된 수업일입니다. | "2026-01-15" |
items[].session | integer | 필수 | 수업 회차입니다. | 1 |
items[].attendanceCode | integer | 필수 | 출결 코드: 0=무결(무단결석), 4=유결(사유결석), 5=출석, 6=인강, 7=보강완료, 8=보강생. 결석은 0·4이며 인강·보강과 구별. | 1 |
items[].attendance | string | 필수 | 출결 표시 이름입니다. | "예시" |
items[].comment | string | 필수 | 수업·과제의 학생 개별 학습 피드백 원문. 결석 사유 전용 필드가 아니며 시험 응원·풀이 조언을 결석 이유로 해석하지 않음. 원인이 명시되지 않으면 사유 미확인. | "예시" |
items[].makeupTeamId | integer | 필수 | 연결된 보강 수강반 번호입니다. 0은 없음입니다. | 1 |
items[].makeupTeamName | string | 필수 | 연결된 보강 수강반 이름입니다. | "예시 이름" |
items[].valueItems | array | 필수 | 같은 수업의 실제 과제·시험 항목 제목·내용·결과 안내와 학생 결과. 값 없음은 미완료 증거가 아님. | 하위 필드·본문 예시 참조 |
items[].valueItems[].field | string | 필수 | 저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요. | "예시" |
items[].valueItems[].category | string | 필수 | 과제, 도전, 시험 중 항목 종류입니다. | "예시" |
items[].valueItems[].position | integer | 필수 | 같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다. | 1 |
items[].valueItems[].title | string | 필수 | 같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요. | "예시" |
items[].valueItems[].content | string | 필수 | 같은 수업 설정의 과제·시험 내용 원문입니다. | "예시" |
items[].valueItems[].resultGuide | string | 필수 | 같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요. | "예시" |
items[].valueItems[].value | string | 필수 | 해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다. | "예시" |
items[].valueItems[].valueState | string | 필수 | present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다. | "예시" |
items[].valueItems[].examId | integer | 필수 | 같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다. | 1 |
items[].valueItemsAvailable | boolean | 필수 | 과제 항목의 원본을 조회했는지 여부. false이면 과제 미완료 여부를 판단할 수 없음. | false |
items[].attendanceMeaning | string | 필수 | 출결 코드의 명확한 뜻. 무결은 무단결석이며 정상 참여가 아님. | "예시" |
items[].isAbsence | boolean | 필수 | 명확한 결석 여부. 코드 0·4는 true, 5·6·7·8은 false, 그 밖에는 null. | false |
page | integer | 조건부·선택 | 페이지 번호입니다. | 1 |
pageSize | integer | 조건부·선택 | 페이지당 자료 수입니다. | 1 |
total | integer | 조건부·선택 | 같은 조건의 전체 이력 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"lessonId": {
"type": "integer",
"description": "수업 번호입니다.",
"nullable": false
},
"attendanceId": {
"type": "integer",
"description": "학생 출결 기록 번호입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "실제 수강반 번호입니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "수강반 이름입니다.",
"nullable": false
},
"date": {
"type": "string",
"description": "저장된 수업일입니다.",
"nullable": false
},
"session": {
"type": "integer",
"description": "수업 회차입니다.",
"nullable": false
},
"attendanceCode": {
"type": "integer",
"x-read-display-field": "attendanceMeaning",
"description": "출결 코드: 0=무결(무단결석), 4=유결(사유결석), 5=출석, 6=인강, 7=보강완료, 8=보강생. 결석은 0·4이며 인강·보강과 구별.",
"nullable": false
},
"attendance": {
"type": "string",
"description": "출결 표시 이름입니다.",
"nullable": false
},
"comment": {
"type": "string",
"description": "수업·과제의 학생 개별 학습 피드백 원문. 결석 사유 전용 필드가 아니며 시험 응원·풀이 조언을 결석 이유로 해석하지 않음. 원인이 명시되지 않으면 사유 미확인.",
"nullable": false
},
"makeupTeamId": {
"type": "integer",
"description": "연결된 보강 수강반 번호입니다. 0은 없음입니다.",
"nullable": false
},
"makeupTeamName": {
"type": "string",
"description": "연결된 보강 수강반 이름입니다.",
"nullable": false
},
"valueItems": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field": {
"type": "string",
"description": "저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요.",
"nullable": false
},
"category": {
"type": "string",
"description": "과제, 도전, 시험 중 항목 종류입니다.",
"nullable": false
},
"position": {
"type": "integer",
"description": "같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요.",
"nullable": false
},
"content": {
"type": "string",
"description": "같은 수업 설정의 과제·시험 내용 원문입니다.",
"nullable": false
},
"resultGuide": {
"type": "string",
"description": "같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요.",
"nullable": false
},
"value": {
"type": "string",
"description": "해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다.",
"nullable": true
},
"valueState": {
"type": "string",
"description": "present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다.",
"nullable": false
}
},
"required": [
"field",
"category",
"position",
"title",
"content",
"resultGuide",
"value",
"valueState",
"examId"
]
},
"description": "같은 수업의 실제 과제·시험 항목 제목·내용·결과 안내와 학생 결과. 값 없음은 미완료 증거가 아님.",
"nullable": false
},
"valueItemsAvailable": {
"type": "boolean",
"description": "과제 항목의 원본을 조회했는지 여부. false이면 과제 미완료 여부를 판단할 수 없음.",
"nullable": false
},
"attendanceMeaning": {
"type": "string",
"description": "출결 코드의 명확한 뜻. 무결은 무단결석이며 정상 참여가 아님.",
"nullable": false
},
"isAbsence": {
"type": "boolean",
"x-read-scope-key": "absence",
"description": "명확한 결석 여부. 코드 0·4는 true, 5·6·7·8은 false, 그 밖에는 null.",
"nullable": true
}
},
"required": [
"lessonId",
"attendanceId",
"teamId",
"teamName",
"date",
"session",
"attendanceCode",
"attendance",
"comment",
"makeupTeamId",
"makeupTeamName",
"valueItems",
"valueItemsAvailable",
"attendanceMeaning",
"isAbsence"
]
},
"description": "현재 페이지의 세부 이력입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "페이지 번호입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 자료 수입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "같은 조건의 전체 이력 수입니다.",
"nullable": false
}
}
}성공 응답 예시
{
"data": {
"studentId": "00000001",
"studentName": "예시 이름",
"items": [
{
"lessonId": 1,
"attendanceId": 1,
"teamId": 1,
"teamName": "예시 이름",
"date": "2026-01-15",
"session": 1,
"attendanceCode": 1,
"attendance": "예시",
"comment": "예시",
"makeupTeamId": 1,
"makeupTeamName": "예시 이름",
"valueItems": [
{
"field": "예시",
"category": "예시",
"position": 1,
"title": "예시",
"content": "예시",
"resultGuide": "예시",
"value": "예시",
"valueState": "예시",
"examId": 1
}
],
"valueItemsAvailable": false,
"attendanceMeaning": "예시",
"isAbsence": false
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}/detail/life학생별 생활기록 이력과 실제 사용 설정된 항목 이름·값·도표 설정 조회+
students.read · student.detail.life
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 조건부·선택 | 현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다. | "00000001" |
studentName | string | 조건부·선택 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
items | array | 조건부·선택 | 현재 페이지의 세부 이력입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 생활기록 번호입니다. | 1 |
items[].year | integer | 필수 | 생활기록 연도입니다. | 1 |
items[].name | string | 필수 | 생활기록 분류명입니다. | "예시 이름" |
items[].fields | array | 필수 | 실제 사용 설정된 항목명과 값입니다. | 하위 필드·본문 예시 참조 |
items[].fields[].field | string | 필수 | 실제 설정된 생활기록 필드입니다. | "예시" |
items[].fields[].title | string | 필수 | 화면에 표시하는 항목명입니다. | "예시" |
items[].fields[].value | string | 필수 | 해당 학생의 저장 값입니다. | "예시" |
items[].fields[].numeric | boolean | 필수 | 숫자 입력 항목인지 여부입니다. | false |
items[].fields[].chart | boolean | 필수 | 도표에 사용하는 항목인지 여부입니다. | false |
page | integer | 조건부·선택 | 페이지 번호입니다. | 1 |
pageSize | integer | 조건부·선택 | 페이지당 자료 수입니다. | 1 |
total | integer | 조건부·선택 | 같은 조건의 전체 이력 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "생활기록 번호입니다.",
"nullable": false
},
"year": {
"type": "integer",
"description": "생활기록 연도입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "생활기록 분류명입니다.",
"nullable": false
},
"fields": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field": {
"type": "string",
"description": "실제 설정된 생활기록 필드입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "화면에 표시하는 항목명입니다.",
"nullable": false
},
"value": {
"type": "string",
"description": "해당 학생의 저장 값입니다.",
"nullable": false
},
"numeric": {
"type": "boolean",
"description": "숫자 입력 항목인지 여부입니다.",
"nullable": false
},
"chart": {
"type": "boolean",
"description": "도표에 사용하는 항목인지 여부입니다.",
"nullable": false
}
},
"required": [
"field",
"title",
"value",
"numeric",
"chart"
]
},
"description": "실제 사용 설정된 항목명과 값입니다.",
"nullable": false
}
},
"required": [
"id",
"year",
"name",
"fields"
]
},
"description": "현재 페이지의 세부 이력입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "페이지 번호입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 자료 수입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "같은 조건의 전체 이력 수입니다.",
"nullable": false
}
}
}성공 응답 예시
{
"data": {
"studentId": "00000001",
"studentName": "예시 이름",
"items": [
{
"id": 1,
"year": 1,
"name": "예시 이름",
"fields": [
{
"field": "예시",
"title": "예시",
"value": "예시",
"numeric": false,
"chart": false
}
]
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}/detail/logins학생별 로그인 시각·접속 주소·구분 이력 조회웹 관리 기능+
웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요students.read · student.detail.logins
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
from | query | 필수 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 필수 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 조건부·선택 | 현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다. | "00000001" |
studentName | string | 조건부·선택 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
items | array | 조건부·선택 | 현재 페이지의 세부 이력입니다. | 하위 필드·본문 예시 참조 |
items[].loggedAt | string | 필수 | 저장된 로그인 시각입니다. | "예시" |
items[].name | string | 필수 | 로그인 이름입니다. | "예시 이름" |
items[].ip | string | 필수 | 로그인 접속 주소입니다. | "예시" |
items[].type | integer | 필수 | 로그인 구분입니다. | 1 |
items[].memo | string | 필수 | 기록된 로그인 메모입니다. | "예시" |
page | integer | 조건부·선택 | 페이지 번호입니다. | 1 |
pageSize | integer | 조건부·선택 | 페이지당 자료 수입니다. | 1 |
total | integer | 조건부·선택 | 같은 조건의 전체 이력 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"loggedAt": {
"type": "string",
"description": "저장된 로그인 시각입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "로그인 이름입니다.",
"nullable": false
},
"ip": {
"type": "string",
"description": "로그인 접속 주소입니다.",
"nullable": false
},
"type": {
"type": "integer",
"description": "로그인 구분입니다.",
"nullable": false
},
"memo": {
"type": "string",
"description": "기록된 로그인 메모입니다.",
"nullable": false
}
},
"required": [
"loggedAt",
"name",
"ip",
"type",
"memo"
]
},
"description": "현재 페이지의 세부 이력입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "페이지 번호입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 자료 수입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "같은 조건의 전체 이력 수입니다.",
"nullable": false
}
}
}성공 응답 예시
{
"data": {
"studentId": "00000001",
"studentName": "예시 이름",
"items": [
{
"loggedAt": "예시",
"name": "예시 이름",
"ip": "예시",
"type": 1,
"memo": "예시"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}/detail/messages학생별 문자·알림톡 발송 내용·수신번호·요청번호 이력 조회(발송 실행 없음)웹 관리 기능+
웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요students.read · student.detail.messages
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
from | query | 필수 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 필수 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 조건부·선택 | 현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다. | "00000001" |
studentName | string | 조건부·선택 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
items | array | 조건부·선택 | 현재 페이지의 세부 이력입니다. | 하위 필드·본문 예시 참조 |
items[].sentAt | string | 필수 | 실제 발송 기록 시각입니다. | "예시" |
items[].type | string | 필수 | 문자·알림톡 유형입니다. | "예시" |
items[].receiver | string | 필수 | 실제 수신번호입니다. | "예시" |
items[].sender | string | 필수 | 발송한 직원의 이름입니다. 발신 전화번호가 아닙니다. | "예시" |
items[].calling | string | 필수 | 저장된 발신번호와 발송 구분 표시입니다. | "예시" |
items[].content | string | 필수 | 저장된 발송 내용입니다. | "예시" |
items[].providerRequestId | string | 필수 | 문자 업체의 요청 번호입니다. | "1" |
page | integer | 조건부·선택 | 페이지 번호입니다. | 1 |
pageSize | integer | 조건부·선택 | 페이지당 자료 수입니다. | 1 |
total | integer | 조건부·선택 | 같은 조건의 전체 이력 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"sentAt": {
"type": "string",
"description": "실제 발송 기록 시각입니다.",
"nullable": false
},
"type": {
"type": "string",
"description": "문자·알림톡 유형입니다.",
"nullable": false
},
"receiver": {
"type": "string",
"description": "실제 수신번호입니다.",
"nullable": false
},
"sender": {
"type": "string",
"description": "발송한 직원의 이름입니다. 발신 전화번호가 아닙니다.",
"nullable": false
},
"calling": {
"type": "string",
"description": "저장된 발신번호와 발송 구분 표시입니다.",
"nullable": false
},
"content": {
"type": "string",
"description": "저장된 발송 내용입니다.",
"nullable": false
},
"providerRequestId": {
"type": "string",
"description": "문자 업체의 요청 번호입니다.",
"nullable": false
}
},
"required": [
"sentAt",
"type",
"receiver",
"sender",
"calling",
"content",
"providerRequestId"
]
},
"description": "현재 페이지의 세부 이력입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "페이지 번호입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 자료 수입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "같은 조건의 전체 이력 수입니다.",
"nullable": false
}
}
}성공 응답 예시
{
"data": {
"studentId": "00000001",
"studentName": "예시 이름",
"items": [
{
"sentAt": "예시",
"type": "예시",
"receiver": "예시",
"sender": "예시",
"calling": "예시",
"content": "예시",
"providerRequestId": "1"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/detail/note-options학생 통합정보 상담 편집에서 실제 선택 가능한 담당자·예약 유형 목록+
students.read · student.detail.notes.options
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
staff | array | 조건부·선택 | 실제 선택 가능한 담당자 아이디와 이름입니다. | 하위 필드·본문 예시 참조 |
staff[].id | string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
staff[].name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
types | array | 조건부·선택 | 실제 선택 가능한 상담 유형입니다. | 하위 필드·본문 예시 참조 |
types[].id | string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
types[].name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
currentStaffId | string | 조건부·선택 | 현재 인증된 담당자 아이디입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"staff": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
}
},
"required": [
"id",
"name"
]
},
"description": "실제 선택 가능한 담당자 아이디와 이름입니다.",
"nullable": false
},
"types": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
}
},
"required": [
"id",
"name"
]
},
"description": "실제 선택 가능한 상담 유형입니다.",
"nullable": false
},
"currentStaffId": {
"type": "string",
"description": "현재 인증된 담당자 아이디입니다.",
"nullable": false
}
}
}성공 응답 예시
{
"data": {
"staff": [
{
"id": "1",
"name": "예시 이름"
}
],
"types": [
{
"id": "1",
"name": "예시 이름"
}
],
"currentStaffId": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}/detail/notes학생의 원문 상담 내역·예약 유형·담당자·진행 상태 조회+
students.read · student.detail.notes.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 조건부·선택 | 현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다. | "00000001" |
studentName | string | 조건부·선택 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
items | array | 조건부·선택 | 현재 페이지의 세부 이력입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 현재 학생의 상담 기록 번호입니다. | 1 |
items[].studentId | string | 필수 | 이 상담 기록이 속한 실제 학생 번호입니다. | "00000001" |
items[].studentName | string | 필수 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
items[].version | string | 필수 | 다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요. | "예시" |
items[].content | string | 필수 | 저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다. | "예시" |
items[].staffId | string | 필수 | 상담 담당 로그인 아이디입니다. | "1" |
items[].staffName | string | 필수 | 상담 담당자 이름입니다. | "예시 이름" |
items[].type | string | 필수 | 상담 유형입니다. | "예시" |
items[].reservedAt | string | 필수 | 예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다. | "예시" |
items[].status | string | 필수 | 저장된 예약 진행 상태입니다. | "예시" |
items[].recordedAt | string | 필수 | 실제 기록 시각입니다. | "2026-01-15T00:00:00Z" |
items[].homeworkStudentId | integer | 필수 | 연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다. | 1 |
items[].lessonId | integer | 필수 | 명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다. | 1 |
items[].lessonTitle | string | 필수 | 해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다. | "예시" |
items[].lessonDate | string | 필수 | 연결된 수업의 실제 수업일입니다. | "2026-01-15" |
page | integer | 조건부·선택 | 페이지 번호입니다. | 1 |
pageSize | integer | 조건부·선택 | 페이지당 자료 수입니다. | 1 |
total | integer | 조건부·선택 | 같은 조건의 전체 이력 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "현재 학생의 상담 기록 번호입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "이 상담 기록이 속한 실제 학생 번호입니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"version": {
"type": "string",
"description": "다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요.",
"nullable": false
},
"content": {
"type": "string",
"description": "저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다.",
"nullable": false
},
"staffId": {
"type": "string",
"description": "상담 담당 로그인 아이디입니다.",
"nullable": false
},
"staffName": {
"type": "string",
"description": "상담 담당자 이름입니다.",
"nullable": false
},
"type": {
"type": "string",
"description": "상담 유형입니다.",
"nullable": false
},
"reservedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$",
"description": "예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "저장된 예약 진행 상태입니다.",
"nullable": false
},
"recordedAt": {
"type": "string",
"format": "date-time",
"description": "실제 기록 시각입니다.",
"nullable": false
},
"homeworkStudentId": {
"type": "integer",
"description": "연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다.",
"nullable": false
},
"lessonId": {
"type": "integer",
"description": "명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다.",
"nullable": false
},
"lessonTitle": {
"type": "string",
"description": "해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다.",
"nullable": false
},
"lessonDate": {
"type": "string",
"description": "연결된 수업의 실제 수업일입니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"studentName",
"version",
"content",
"staffId",
"staffName",
"type",
"reservedAt",
"status",
"recordedAt",
"homeworkStudentId",
"lessonId",
"lessonTitle",
"lessonDate"
]
},
"description": "현재 페이지의 세부 이력입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "페이지 번호입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 자료 수입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "같은 조건의 전체 이력 수입니다.",
"nullable": false
}
}
}성공 응답 예시
{
"data": {
"studentId": "00000001",
"studentName": "예시 이름",
"items": [
{
"id": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"version": "예시",
"content": "예시",
"staffId": "1",
"staffName": "예시 이름",
"type": "예시",
"reservedAt": "예시",
"status": "예시",
"recordedAt": "2026-01-15T00:00:00Z",
"homeworkStudentId": 1,
"lessonId": 1,
"lessonTitle": "예시",
"lessonDate": "2026-01-15"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}/detail/notes/{noteId}선택 학생의 특정 상담 원문·담당자·예약 일시·변경 검증 version 조회+
students.read · student.detail.notes.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
noteId | path | 필수 | 해당 학생의 상담 내역·상세 조회에서 확인한 실제 상담 기록 번호입니다. 다른 학생의 기록 번호를 재사용하지 마세요. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 현재 학생의 상담 기록 번호입니다. | 1 |
studentId | string | 필수 | 이 상담 기록이 속한 실제 학생 번호입니다. | "00000001" |
studentName | string | 필수 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
version | string | 필수 | 다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요. | "예시" |
content | string | 필수 | 저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다. | "예시" |
staffId | string | 필수 | 상담 담당 로그인 아이디입니다. | "1" |
staffName | string | 필수 | 상담 담당자 이름입니다. | "예시 이름" |
type | string | 필수 | 상담 유형입니다. | "예시" |
reservedAt | string | 필수 | 예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다. | "예시" |
status | string | 필수 | 저장된 예약 진행 상태입니다. | "예시" |
recordedAt | string | 필수 | 실제 기록 시각입니다. | "2026-01-15T00:00:00Z" |
homeworkStudentId | integer | 필수 | 연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다. | 1 |
lessonId | integer | 필수 | 명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다. | 1 |
lessonTitle | string | 필수 | 해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다. | "예시" |
lessonDate | string | 필수 | 연결된 수업의 실제 수업일입니다. | "2026-01-15" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "현재 학생의 상담 기록 번호입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "이 상담 기록이 속한 실제 학생 번호입니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"version": {
"type": "string",
"description": "다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요.",
"nullable": false
},
"content": {
"type": "string",
"description": "저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다.",
"nullable": false
},
"staffId": {
"type": "string",
"description": "상담 담당 로그인 아이디입니다.",
"nullable": false
},
"staffName": {
"type": "string",
"description": "상담 담당자 이름입니다.",
"nullable": false
},
"type": {
"type": "string",
"description": "상담 유형입니다.",
"nullable": false
},
"reservedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$",
"description": "예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "저장된 예약 진행 상태입니다.",
"nullable": false
},
"recordedAt": {
"type": "string",
"format": "date-time",
"description": "실제 기록 시각입니다.",
"nullable": false
},
"homeworkStudentId": {
"type": "integer",
"description": "연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다.",
"nullable": false
},
"lessonId": {
"type": "integer",
"description": "명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다.",
"nullable": false
},
"lessonTitle": {
"type": "string",
"description": "해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다.",
"nullable": false
},
"lessonDate": {
"type": "string",
"description": "연결된 수업의 실제 수업일입니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"studentName",
"version",
"content",
"staffId",
"staffName",
"type",
"reservedAt",
"status",
"recordedAt",
"homeworkStudentId",
"lessonId",
"lessonTitle",
"lessonDate"
]
}성공 응답 예시
{
"data": {
"id": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"version": "예시",
"content": "예시",
"staffId": "1",
"staffName": "예시 이름",
"type": "예시",
"reservedAt": "예시",
"status": "예시",
"recordedAt": "2026-01-15T00:00:00Z",
"homeworkStudentId": 1,
"lessonId": 1,
"lessonTitle": "예시",
"lessonDate": "2026-01-15"
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/students/{id}/detail/notes학생 통합정보에서 상담 기록 등록(선택한 담당자·유형·명시한 예약일만 사용)+
students.write · student.detail.notes.create
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
content | string | 필수 | 상담 원문입니다. 예약 문구나 화면 표시용 접두사를 임의로 덧붙이지 마세요. | "예시" |
version | string | 조건부·선택 | 수정할 때 상세 조회에서 받은 현재 version입니다. 신규 등록에는 필요하지 않습니다. | "예시" |
staffId | string | 조건부·선택 | 담당자 목록의 실제 로그인 아이디입니다. 수정 시 생략하면 기존 담당자를 유지합니다. | "1" |
type | string | 조건부·선택 | 상담 유형 목록의 실제 값입니다. 수정 시 생략하면 기존 유형을 유지합니다. | "예시" |
reservedAt | string | 조건부·선택 | 사용자가 지정한 yyyy-MM-dd HH:mm 한국 시간입니다. 생략하면 기존 일시를 유지하고 빈 문자열은 예약을 해제합니다. 임의로 날짜를 만들지 마세요. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "상담 원문입니다. 예약 문구나 화면 표시용 접두사를 임의로 덧붙이지 마세요.",
"nullable": false,
"maxLength": 10000,
"minLength": 1
},
"version": {
"type": "string",
"description": "수정할 때 상세 조회에서 받은 현재 version입니다. 신규 등록에는 필요하지 않습니다.",
"nullable": true,
"maxLength": 64
},
"staffId": {
"type": "string",
"description": "담당자 목록의 실제 로그인 아이디입니다. 수정 시 생략하면 기존 담당자를 유지합니다.",
"nullable": true,
"maxLength": 100
},
"type": {
"type": "string",
"description": "상담 유형 목록의 실제 값입니다. 수정 시 생략하면 기존 유형을 유지합니다.",
"nullable": true,
"maxLength": 100
},
"reservedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$",
"description": "사용자가 지정한 yyyy-MM-dd HH:mm 한국 시간입니다. 생략하면 기존 일시를 유지하고 빈 문자열은 예약을 해제합니다. 임의로 날짜를 만들지 마세요.",
"nullable": true,
"maxLength": 16
}
},
"required": [
"content"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 현재 학생의 상담 기록 번호입니다. | 1 |
studentId | string | 필수 | 이 상담 기록이 속한 실제 학생 번호입니다. | "00000001" |
studentName | string | 필수 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
version | string | 필수 | 다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요. | "예시" |
content | string | 필수 | 저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다. | "예시" |
staffId | string | 필수 | 상담 담당 로그인 아이디입니다. | "1" |
staffName | string | 필수 | 상담 담당자 이름입니다. | "예시 이름" |
type | string | 필수 | 상담 유형입니다. | "예시" |
reservedAt | string | 필수 | 예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다. | "예시" |
status | string | 필수 | 저장된 예약 진행 상태입니다. | "예시" |
recordedAt | string | 필수 | 실제 기록 시각입니다. | "2026-01-15T00:00:00Z" |
homeworkStudentId | integer | 필수 | 연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다. | 1 |
lessonId | integer | 필수 | 명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다. | 1 |
lessonTitle | string | 필수 | 해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다. | "예시" |
lessonDate | string | 필수 | 연결된 수업의 실제 수업일입니다. | "2026-01-15" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "현재 학생의 상담 기록 번호입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "이 상담 기록이 속한 실제 학생 번호입니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"version": {
"type": "string",
"description": "다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요.",
"nullable": false
},
"content": {
"type": "string",
"description": "저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다.",
"nullable": false
},
"staffId": {
"type": "string",
"description": "상담 담당 로그인 아이디입니다.",
"nullable": false
},
"staffName": {
"type": "string",
"description": "상담 담당자 이름입니다.",
"nullable": false
},
"type": {
"type": "string",
"description": "상담 유형입니다.",
"nullable": false
},
"reservedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$",
"description": "예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "저장된 예약 진행 상태입니다.",
"nullable": false
},
"recordedAt": {
"type": "string",
"format": "date-time",
"description": "실제 기록 시각입니다.",
"nullable": false
},
"homeworkStudentId": {
"type": "integer",
"description": "연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다.",
"nullable": false
},
"lessonId": {
"type": "integer",
"description": "명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다.",
"nullable": false
},
"lessonTitle": {
"type": "string",
"description": "해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다.",
"nullable": false
},
"lessonDate": {
"type": "string",
"description": "연결된 수업의 실제 수업일입니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"studentName",
"version",
"content",
"staffId",
"staffName",
"type",
"reservedAt",
"status",
"recordedAt",
"homeworkStudentId",
"lessonId",
"lessonTitle",
"lessonDate"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"content": "예시",
"version": "예시",
"staffId": "1",
"type": "예시",
"reservedAt": "예시"
}성공 응답 예시
{
"data": {
"id": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"version": "예시",
"content": "예시",
"staffId": "1",
"staffName": "예시 이름",
"type": "예시",
"reservedAt": "예시",
"status": "예시",
"recordedAt": "2026-01-15T00:00:00Z",
"homeworkStudentId": 1,
"lessonId": 1,
"lessonTitle": "예시",
"lessonDate": "2026-01-15"
},
"meta": {
"requestId": "example-request-id"
}
}PATCH/v1/students/{id}/detail/notes/{noteId}상담 원문·담당자·유형·예약 수정(생략한 값 보존·학원/학생/현재 version 원자적 검증)+
students.write · student.detail.notes.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
noteId | path | 필수 | 해당 학생의 상담 내역·상세 조회에서 확인한 실제 상담 기록 번호입니다. 다른 학생의 기록 번호를 재사용하지 마세요. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
content | string | 필수 | 상담 원문입니다. 예약 문구나 화면 표시용 접두사를 임의로 덧붙이지 마세요. | "예시" |
version | string | 조건부·선택 | 수정할 때 상세 조회에서 받은 현재 version입니다. 신규 등록에는 필요하지 않습니다. | "예시" |
staffId | string | 조건부·선택 | 담당자 목록의 실제 로그인 아이디입니다. 수정 시 생략하면 기존 담당자를 유지합니다. | "1" |
type | string | 조건부·선택 | 상담 유형 목록의 실제 값입니다. 수정 시 생략하면 기존 유형을 유지합니다. | "예시" |
reservedAt | string | 조건부·선택 | 사용자가 지정한 yyyy-MM-dd HH:mm 한국 시간입니다. 생략하면 기존 일시를 유지하고 빈 문자열은 예약을 해제합니다. 임의로 날짜를 만들지 마세요. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "상담 원문입니다. 예약 문구나 화면 표시용 접두사를 임의로 덧붙이지 마세요.",
"nullable": false,
"maxLength": 10000,
"minLength": 1
},
"version": {
"type": "string",
"description": "수정할 때 상세 조회에서 받은 현재 version입니다. 신규 등록에는 필요하지 않습니다.",
"nullable": true,
"maxLength": 64
},
"staffId": {
"type": "string",
"description": "담당자 목록의 실제 로그인 아이디입니다. 수정 시 생략하면 기존 담당자를 유지합니다.",
"nullable": true,
"maxLength": 100
},
"type": {
"type": "string",
"description": "상담 유형 목록의 실제 값입니다. 수정 시 생략하면 기존 유형을 유지합니다.",
"nullable": true,
"maxLength": 100
},
"reservedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$",
"description": "사용자가 지정한 yyyy-MM-dd HH:mm 한국 시간입니다. 생략하면 기존 일시를 유지하고 빈 문자열은 예약을 해제합니다. 임의로 날짜를 만들지 마세요.",
"nullable": true,
"maxLength": 16
}
},
"required": [
"content"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 현재 학생의 상담 기록 번호입니다. | 1 |
studentId | string | 필수 | 이 상담 기록이 속한 실제 학생 번호입니다. | "00000001" |
studentName | string | 필수 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
version | string | 필수 | 다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요. | "예시" |
content | string | 필수 | 저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다. | "예시" |
staffId | string | 필수 | 상담 담당 로그인 아이디입니다. | "1" |
staffName | string | 필수 | 상담 담당자 이름입니다. | "예시 이름" |
type | string | 필수 | 상담 유형입니다. | "예시" |
reservedAt | string | 필수 | 예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다. | "예시" |
status | string | 필수 | 저장된 예약 진행 상태입니다. | "예시" |
recordedAt | string | 필수 | 실제 기록 시각입니다. | "2026-01-15T00:00:00Z" |
homeworkStudentId | integer | 필수 | 연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다. | 1 |
lessonId | integer | 필수 | 명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다. | 1 |
lessonTitle | string | 필수 | 해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다. | "예시" |
lessonDate | string | 필수 | 연결된 수업의 실제 수업일입니다. | "2026-01-15" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "현재 학생의 상담 기록 번호입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "이 상담 기록이 속한 실제 학생 번호입니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"version": {
"type": "string",
"description": "다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요.",
"nullable": false
},
"content": {
"type": "string",
"description": "저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다.",
"nullable": false
},
"staffId": {
"type": "string",
"description": "상담 담당 로그인 아이디입니다.",
"nullable": false
},
"staffName": {
"type": "string",
"description": "상담 담당자 이름입니다.",
"nullable": false
},
"type": {
"type": "string",
"description": "상담 유형입니다.",
"nullable": false
},
"reservedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$",
"description": "예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "저장된 예약 진행 상태입니다.",
"nullable": false
},
"recordedAt": {
"type": "string",
"format": "date-time",
"description": "실제 기록 시각입니다.",
"nullable": false
},
"homeworkStudentId": {
"type": "integer",
"description": "연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다.",
"nullable": false
},
"lessonId": {
"type": "integer",
"description": "명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다.",
"nullable": false
},
"lessonTitle": {
"type": "string",
"description": "해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다.",
"nullable": false
},
"lessonDate": {
"type": "string",
"description": "연결된 수업의 실제 수업일입니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"studentName",
"version",
"content",
"staffId",
"staffName",
"type",
"reservedAt",
"status",
"recordedAt",
"homeworkStudentId",
"lessonId",
"lessonTitle",
"lessonDate"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"content": "예시",
"version": "예시",
"staffId": "1",
"type": "예시",
"reservedAt": "예시"
}성공 응답 예시
{
"data": {
"id": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"version": "예시",
"content": "예시",
"staffId": "1",
"staffName": "예시 이름",
"type": "예시",
"reservedAt": "예시",
"status": "예시",
"recordedAt": "2026-01-15T00:00:00Z",
"homeworkStudentId": 1,
"lessonId": 1,
"lessonTitle": "예시",
"lessonDate": "2026-01-15"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/students/{id}/detail/notes/{noteId}선택 학생의 상담 기록 삭제(현재 version 확인·소프트 삭제)+
students.write · student.detail.notes.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
noteId | path | 필수 | 해당 학생의 상담 내역·상세 조회에서 확인한 실제 상담 기록 번호입니다. 다른 학생의 기록 번호를 재사용하지 마세요. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
version | string | 필수 | 직전 상세 조회에서 받은 정확한 version입니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"version": {
"type": "string",
"description": "직전 상세 조회에서 받은 정확한 version입니다.",
"nullable": false,
"minLength": 1,
"pattern": "^[A-F0-9]{64}$"
}
},
"required": [
"version"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"version": "예시"
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}/detail/profile학생 통합정보 기본정보 조회(이름·번호·연락처·학교·학년·메모, 비밀번호 제외)+
students.read · student.detail.profile
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | string | 필수 | 조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다. | "1" |
name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
school | string | 필수 | 학교 이름입니다. 빈 문자열이면 미입력입니다. | "예시" |
grade | string | 필수 | 학년 표시값입니다. | "예시" |
major | string | 필수 | 계열 또는 전공 구분값입니다. | "예시" |
studentPhone | string | 필수 | 학생 휴대전화 번호입니다. | "010-0000-0000" |
parentPhone | string | 필수 | 보호자 연락처입니다. | "010-0000-0000" |
paymentPhone | string | 필수 | 결제 안내를 받을 연락처입니다. | "010-0000-0000" |
email | string | 필수 | 이메일 주소입니다. | "sample@example.com" |
memo | string | 필수 | 학생 관리용 메모입니다. | "예시" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
},
"school": {
"type": "string",
"description": "학교 이름입니다. 빈 문자열이면 미입력입니다.",
"nullable": false
},
"grade": {
"type": "string",
"description": "학년 표시값입니다.",
"nullable": false
},
"major": {
"type": "string",
"description": "계열 또는 전공 구분값입니다.",
"nullable": false
},
"studentPhone": {
"type": "string",
"description": "학생 휴대전화 번호입니다.",
"nullable": false
},
"parentPhone": {
"type": "string",
"description": "보호자 연락처입니다.",
"nullable": false
},
"paymentPhone": {
"type": "string",
"description": "결제 안내를 받을 연락처입니다.",
"nullable": false
},
"email": {
"type": "string",
"description": "이메일 주소입니다.",
"nullable": false
},
"memo": {
"type": "string",
"description": "학생 관리용 메모입니다.",
"nullable": false
}
},
"required": [
"id",
"name",
"school",
"grade",
"major",
"studentPhone",
"parentPhone",
"paymentPhone",
"email",
"memo"
]
}성공 응답 예시
{
"data": {
"id": "1",
"name": "예시 이름",
"school": "예시",
"grade": "예시",
"major": "예시",
"studentPhone": "010-0000-0000",
"parentPhone": "010-0000-0000",
"paymentPhone": "010-0000-0000",
"email": "sample@example.com",
"memo": "예시"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/{id}/detail/scores학생 시험별 점수·평균·만점·등수 이력(오답 미제공, 공개 성적표 링크 발급 없음)+
students.read · student.detail.scores
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요. |
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
from | query | 선택 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 선택 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 조건부·선택 | 현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다. | "00000001" |
studentName | string | 조건부·선택 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
items | array | 조건부·선택 | 현재 페이지의 세부 이력입니다. | 하위 필드·본문 예시 참조 |
items[].gradeId | integer | 필수 | 해당 학생의 실제 채점 기록 번호입니다. | 1 |
items[].examId | integer | 필수 | 시험 번호입니다. | 1 |
items[].name | string | 필수 | 시험 구분 이름입니다. | "예시 이름" |
items[].title | string | 필수 | 시험 제목입니다. | "예시" |
items[].date | string | 필수 | 저장된 채점일입니다. | "2026-01-15" |
items[].score | number | 필수 | 학생 점수입니다. | 1 |
items[].average | number | 필수 | 시험 평균 점수입니다. | 1 |
items[].maximum | number | 필수 | 정답지 배점 합계인 시험 만점입니다. 실제 응시자의 최고 득점이 아닙니다. | 1 |
items[].wrongAnswers | string | 필수 | 이 조회에서 오답 문항을 제공하지 않으면 null입니다. null은 오답 0개가 아니며 등수나 응시 인원을 오답·응시 문항 수로 해석하지 마세요. 문항별 답안·배점·득점은 채점 성적 조회의 includeAnalysis=true로 확인합니다. | "예시" |
items[].rank | string | 필수 | 학원에 저장된 등수 / 응시 인원 표시입니다. 예: 2/2. 문항 수나 오답 개수가 아닙니다. | "예시" |
items[].questionCount | integer | 필수 | 정답지에 설정된 전체 문항 수입니다. 선택과목에 따라 학생의 실제 응시 문항 수와 다를 수 있으며 알 수 없으면 null입니다. | 1 |
items[].differenceFromAverage | number | 필수 | 해당 시험 점수에서 평균을 뺀 값. 음수이면 평균 미만. 서로 다른 시험 점수의 평균이 아님. | 1 |
items[].belowAverage | boolean | 필수 | 해당 시험에서 저장된 평균 미만인지 여부. true이면 평균 이상으로 표현하지 않음. 등수·분위와는 별개. | false |
page | integer | 조건부·선택 | 페이지 번호입니다. | 1 |
pageSize | integer | 조건부·선택 | 페이지당 자료 수입니다. | 1 |
total | integer | 조건부·선택 | 같은 조건의 전체 이력 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"gradeId": {
"type": "integer",
"description": "해당 학생의 실제 채점 기록 번호입니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "시험 번호입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "시험 구분 이름입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "시험 제목입니다.",
"nullable": false
},
"date": {
"type": "string",
"description": "저장된 채점일입니다.",
"nullable": false
},
"score": {
"type": "number",
"description": "학생 점수입니다.",
"nullable": false
},
"average": {
"type": "number",
"description": "시험 평균 점수입니다.",
"nullable": false
},
"maximum": {
"type": "number",
"description": "정답지 배점 합계인 시험 만점입니다. 실제 응시자의 최고 득점이 아닙니다.",
"nullable": false
},
"wrongAnswers": {
"type": "string",
"description": "이 조회에서 오답 문항을 제공하지 않으면 null입니다. null은 오답 0개가 아니며 등수나 응시 인원을 오답·응시 문항 수로 해석하지 마세요. 문항별 답안·배점·득점은 채점 성적 조회의 includeAnalysis=true로 확인합니다.",
"nullable": true
},
"rank": {
"type": "string",
"description": "학원에 저장된 등수 / 응시 인원 표시입니다. 예: 2/2. 문항 수나 오답 개수가 아닙니다.",
"nullable": false
},
"questionCount": {
"type": "integer",
"description": "정답지에 설정된 전체 문항 수입니다. 선택과목에 따라 학생의 실제 응시 문항 수와 다를 수 있으며 알 수 없으면 null입니다.",
"nullable": true
},
"differenceFromAverage": {
"type": "number",
"description": "해당 시험 점수에서 평균을 뺀 값. 음수이면 평균 미만. 서로 다른 시험 점수의 평균이 아님.",
"nullable": false
},
"belowAverage": {
"type": "boolean",
"description": "해당 시험에서 저장된 평균 미만인지 여부. true이면 평균 이상으로 표현하지 않음. 등수·분위와는 별개.",
"nullable": false
}
},
"required": [
"gradeId",
"examId",
"name",
"title",
"date",
"score",
"average",
"maximum",
"wrongAnswers",
"rank",
"questionCount",
"differenceFromAverage",
"belowAverage"
]
},
"description": "현재 페이지의 세부 이력입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "페이지 번호입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 자료 수입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "같은 조건의 전체 이력 수입니다.",
"nullable": false
}
}
}성공 응답 예시
{
"data": {
"studentId": "00000001",
"studentName": "예시 이름",
"items": [
{
"gradeId": 1,
"examId": 1,
"name": "예시 이름",
"title": "예시",
"date": "2026-01-15",
"score": 1,
"average": 1,
"maximum": 1,
"wrongAnswers": "예시",
"rank": "예시",
"questionCount": 1,
"differenceFromAverage": 1,
"belowAverage": false
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/life-records수강 시간표별 학생 생활기록+
life.read · life.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
year | query | 필수 | 생활기록 연도입니다. 1900~2100입니다. |
category | query | 필수 | 생활기록 분류명입니다. 기존 분류를 선택하거나 새 이름을 입력하며, 새 분류는 첫 기록 저장 시 생성됩니다. |
scheduleId | query | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | integer | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | 1 |
[].studentId | string | 필수 | 학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다. | "00000001" |
[].studentName | string | 필수 | 학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다. | "예시 이름" |
[].year | integer | 필수 | 생활기록 연도입니다. 1900~2100 범위입니다. | 1 |
[].category | string | 필수 | 생활기록 분류명입니다. 분류 목록의 값을 사용합니다. | "예시" |
[].values | object | 필수 | 생활기록 항목 키(V1~V20)와 입력값의 사전입니다. 전달한 항목만 병합합니다. | 하위 필드·본문 예시 참조 |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다.",
"nullable": false
},
"year": {
"type": "integer",
"description": "생활기록 연도입니다. 1900~2100 범위입니다.",
"nullable": false
},
"category": {
"type": "string",
"description": "생활기록 분류명입니다. 분류 목록의 값을 사용합니다.",
"nullable": false
},
"values": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "생활기록 항목 키(V1~V20)와 입력값의 사전입니다. 전달한 항목만 병합합니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"studentName",
"year",
"category",
"values"
]
}
}성공 응답 예시
{
"data": [
{
"id": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"year": 1,
"category": "예시",
"values": {}
}
],
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/life-records학생 생활기록 저장(항목 값 병합)+
life.write · life.save
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
year | integer | 필수 | 생활기록 연도입니다. 1900~2100 범위입니다. | 2026 |
category | string | 필수 | 생활기록 분류명입니다. GET /v1/life-records/categories의 기존 이름을 사용하거나 새 분류명을 직접 입력할 수 있습니다. 분류는 첫 기록 저장 시 생성됩니다. | "예시" |
studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 예: 00000001. 이름·전화번호가 아니며 앞자리 0을 유지하세요. | "00000001" |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요. | 1 |
expectedId | integer | 조건부·선택 | 같은 year·category·scheduleId로 GET /v1/life-records를 먼저 조회하고 대상 학생 행의 id를 전달합니다. 조회 응답 id가 0인 새 기록만 0을 사용합니다. | 1 |
values | object | 조건부·선택 | 생활기록 항목 키(V1~V20)와 입력값의 사전입니다. 전달한 항목만 병합합니다. | 하위 필드·본문 예시 참조 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"year": {
"type": "integer",
"description": "생활기록 연도입니다. 1900~2100 범위입니다.",
"nullable": false,
"minimum": 1900,
"maximum": 2100,
"example": 2026
},
"category": {
"type": "string",
"description": "생활기록 분류명입니다. GET /v1/life-records/categories의 기존 이름을 사용하거나 새 분류명을 직접 입력할 수 있습니다. 분류는 첫 기록 저장 시 생성됩니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1
},
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 예: 00000001. 이름·전화번호가 아니며 앞자리 0을 유지하세요.",
"nullable": false,
"minLength": 1
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"expectedId": {
"type": "integer",
"description": "같은 year·category·scheduleId로 GET /v1/life-records를 먼저 조회하고 대상 학생 행의 id를 전달합니다. 조회 응답 id가 0인 새 기록만 0을 사용합니다.",
"nullable": false,
"default": 0
},
"values": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "생활기록 항목 키(V1~V20)와 입력값의 사전입니다. 전달한 항목만 병합합니다.",
"nullable": false
}
},
"required": [
"year",
"category",
"studentId",
"scheduleId"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | 1 |
studentId | string | 필수 | 학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다. | "00000001" |
studentName | string | 필수 | 학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다. | "예시 이름" |
year | integer | 필수 | 생활기록 연도입니다. 1900~2100 범위입니다. | 1 |
category | string | 필수 | 생활기록 분류명입니다. 분류 목록의 값을 사용합니다. | "예시" |
values | object | 필수 | 생활기록 항목 키(V1~V20)와 입력값의 사전입니다. 전달한 항목만 병합합니다. | 하위 필드·본문 예시 참조 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다.",
"nullable": false
},
"year": {
"type": "integer",
"description": "생활기록 연도입니다. 1900~2100 범위입니다.",
"nullable": false
},
"category": {
"type": "string",
"description": "생활기록 분류명입니다. 분류 목록의 값을 사용합니다.",
"nullable": false
},
"values": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "생활기록 항목 키(V1~V20)와 입력값의 사전입니다. 전달한 항목만 병합합니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"studentName",
"year",
"category",
"values"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"year": 2026,
"category": "예시",
"studentId": "00000001",
"scheduleId": 1,
"expectedId": 1,
"values": {}
}성공 응답 예시
{
"data": {
"id": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"year": 1,
"category": "예시",
"values": {}
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/life-records/{id}학생 생활기록 삭제+
life.write · life.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | 대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다. |
year | query | 필수 | 생활기록 연도입니다. 1900~2100입니다. |
category | query | 필수 | 생활기록 분류명입니다. 기존 분류를 선택하거나 새 이름을 입력하며, 새 분류는 첫 기록 저장 시 생성됩니다. |
scheduleId | query | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/life-records/categories생활기록 분류 목록+
life.read · life.categories
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "string"
}
}성공 응답 예시
{
"data": [
"예시"
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/life-records/fields생활기록 항목 정의+
life.read · life.fields
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].field | string | 조건부·선택 | 생활기록 항목 키입니다. V1~V20 중 하나입니다. | "예시" |
[].title | string | 조건부·선택 | 화면에 표시할 항목 이름입니다. 최대 10자이며 사용하지 않는 항목은 비울 수 있습니다. | "예시" |
[].width | integer | 조건부·선택 | 목록 열 너비입니다. 40~600 픽셀입니다. | 1 |
[].type | boolean | 조건부·선택 | 숫자 입력 항목이면 true입니다. | false |
[].chart | boolean | 조건부·선택 | 도표에 표시하는 숫자 항목이면 true입니다. 사용 중인 숫자 항목만 가능하며 최대 6개입니다. | false |
[].use_Flag | boolean | 조건부·선택 | 이 생활기록 항목을 사용하면 true입니다. | false |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"field": {
"type": "string",
"description": "생활기록 항목 키입니다. V1~V20 중 하나입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "화면에 표시할 항목 이름입니다. 최대 10자이며 사용하지 않는 항목은 비울 수 있습니다.",
"nullable": false
},
"width": {
"type": "integer",
"description": "목록 열 너비입니다. 40~600 픽셀입니다.",
"nullable": false
},
"type": {
"type": "boolean",
"description": "숫자 입력 항목이면 true입니다.",
"nullable": false
},
"chart": {
"type": "boolean",
"description": "도표에 표시하는 숫자 항목이면 true입니다. 사용 중인 숫자 항목만 가능하며 최대 6개입니다.",
"nullable": false
},
"use_Flag": {
"type": "boolean",
"description": "이 생활기록 항목을 사용하면 true입니다.",
"nullable": false
}
}
}
}성공 응답 예시
{
"data": [
{
"field": "예시",
"title": "예시",
"width": 1,
"type": false,
"chart": false,
"use_Flag": false
}
],
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/life-records/fields생활기록 항목 설정+
life.write · life.fields.update
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].field | string | 조건부·선택 | 생활기록 항목 키입니다. V1~V20 중 하나입니다. | "예시" |
[].title | string | 조건부·선택 | 화면에 표시할 항목 이름입니다. 최대 10자이며 사용하지 않는 항목은 비울 수 있습니다. | "예시" |
[].width | integer | 조건부·선택 | 목록 열 너비입니다. 40~600 픽셀입니다. | 1 |
[].type | boolean | 조건부·선택 | 숫자 입력 항목이면 true입니다. | false |
[].chart | boolean | 조건부·선택 | 도표에 표시하는 숫자 항목이면 true입니다. 사용 중인 숫자 항목만 가능하며 최대 6개입니다. | false |
[].use_Flag | boolean | 조건부·선택 | 이 생활기록 항목을 사용하면 true입니다. | false |
요청 JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"field": {
"type": "string",
"description": "생활기록 항목 키입니다. V1~V20 중 하나입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "화면에 표시할 항목 이름입니다. 최대 10자이며 사용하지 않는 항목은 비울 수 있습니다.",
"nullable": false
},
"width": {
"type": "integer",
"description": "목록 열 너비입니다. 40~600 픽셀입니다.",
"nullable": false
},
"type": {
"type": "boolean",
"description": "숫자 입력 항목이면 true입니다.",
"nullable": false
},
"chart": {
"type": "boolean",
"description": "도표에 표시하는 숫자 항목이면 true입니다. 사용 중인 숫자 항목만 가능하며 최대 6개입니다.",
"nullable": false
},
"use_Flag": {
"type": "boolean",
"description": "이 생활기록 항목을 사용하면 true입니다.",
"nullable": false
}
}
}
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
[
{
"field": "예시",
"title": "예시",
"width": 1,
"type": false,
"chart": false,
"use_Flag": false
}
]성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/consultations기간별 상담 예약+
consultations.read · consultations.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
from | query | 필수 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 필수 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다. | 1 |
items[].studentId | string | 필수 | 학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다. | "00000001" |
items[].studentName | string | 필수 | 학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다. | "예시 이름" |
items[].phone | string | 필수 | 상담 대상 연락처입니다. | "010-0000-0000" |
items[].reservedAt | string | 필수 | 상담 예약 일시입니다. 한국 시간 yyyy-MM-dd HH:mm 형식입니다. | "예시" |
items[].type | string | 필수 | 상담 유형 또는 분류입니다. | "예시" |
items[].status | string | 필수 | 상담 상태입니다. 예약·완료·변경·불참·취소 중 하나입니다. | "예약" |
items[].content | string | 필수 | 상담 내용입니다. | "예시" |
items[].staffId | string | 필수 | 상담 담당자 선택 목록의 식별값입니다. | "1" |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다.",
"nullable": false
},
"phone": {
"type": "string",
"description": "상담 대상 연락처입니다.",
"nullable": false
},
"reservedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$",
"description": "상담 예약 일시입니다. 한국 시간 yyyy-MM-dd HH:mm 형식입니다.",
"nullable": false
},
"type": {
"type": "string",
"description": "상담 유형 또는 분류입니다.",
"nullable": false
},
"status": {
"type": "string",
"enum": [
"예약",
"완료",
"변경",
"불참",
"취소"
],
"description": "상담 상태입니다. 예약·완료·변경·불참·취소 중 하나입니다.",
"nullable": false
},
"content": {
"type": "string",
"description": "상담 내용입니다.",
"nullable": false
},
"staffId": {
"type": "string",
"description": "상담 담당자 선택 목록의 식별값입니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"studentName",
"phone",
"reservedAt",
"type",
"status",
"content",
"staffId"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"id": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"phone": "010-0000-0000",
"reservedAt": "예시",
"type": "예시",
"status": "예약",
"content": "예시",
"staffId": "1"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/consultations/{id}상담 예약 상세+
consultations.read · consultations.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/consultations 응답 data.items[].id의 상담 예약 번호입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다. | 1 |
studentId | string | 필수 | 학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다. | "00000001" |
studentName | string | 필수 | 학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다. | "예시 이름" |
phone | string | 필수 | 상담 대상 연락처입니다. | "010-0000-0000" |
reservedAt | string | 필수 | 상담 예약 일시입니다. 한국 시간 yyyy-MM-dd HH:mm 형식입니다. | "예시" |
type | string | 필수 | 상담 유형 또는 분류입니다. | "예시" |
status | string | 필수 | 상담 상태입니다. 예약·완료·변경·불참·취소 중 하나입니다. | "예약" |
content | string | 필수 | 상담 내용입니다. | "예시" |
staffId | string | 필수 | 상담 담당자 선택 목록의 식별값입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다.",
"nullable": false
},
"phone": {
"type": "string",
"description": "상담 대상 연락처입니다.",
"nullable": false
},
"reservedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$",
"description": "상담 예약 일시입니다. 한국 시간 yyyy-MM-dd HH:mm 형식입니다.",
"nullable": false
},
"type": {
"type": "string",
"description": "상담 유형 또는 분류입니다.",
"nullable": false
},
"status": {
"type": "string",
"enum": [
"예약",
"완료",
"변경",
"불참",
"취소"
],
"description": "상담 상태입니다. 예약·완료·변경·불참·취소 중 하나입니다.",
"nullable": false
},
"content": {
"type": "string",
"description": "상담 내용입니다.",
"nullable": false
},
"staffId": {
"type": "string",
"description": "상담 담당자 선택 목록의 식별값입니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"studentName",
"phone",
"reservedAt",
"type",
"status",
"content",
"staffId"
]
}성공 응답 예시
{
"data": {
"id": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"phone": "010-0000-0000",
"reservedAt": "예시",
"type": "예시",
"status": "예약",
"content": "예시",
"staffId": "1"
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/consultations상담 예약 등록+
consultations.write · consultations.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 조건부·선택 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 예: 00000001. 이름·전화번호가 아니며 앞자리 0을 유지하세요. | "00000001" |
studentName | string | 필수 | 학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다. | "예시 이름" |
phone | string | 조건부·선택 | 상담 대상 연락처입니다. | "010-0000-0000" |
reservedAt | string | 필수 | 상담 예약 일시입니다. 한국 시간 yyyy-MM-dd HH:mm 형식입니다. | "예시" |
type | string | 조건부·선택 | 상담 유형 또는 분류입니다. | "예시" |
status | string | 필수 | 상담 상태입니다. 예약·완료·변경·불참·취소 중 하나입니다. | "예약" |
content | string | 조건부·선택 | 상담 내용입니다. | "예시" |
staffId | string | 필수 | GET /v1/consultations/staff 응답 data[].id에서 선택한 상담 담당자 식별값을 문자열로 전달합니다. 담당자 이름이나 직원 출퇴근용 정수 staffId를 넣지 않습니다. 이 목록의 id는 담당자 식별 문자열입니다. API 담당자의 식별값은 로그인 권한을 의미하지 않습니다. | "1" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 예: 00000001. 이름·전화번호가 아니며 앞자리 0을 유지하세요.",
"nullable": false,
"default": ""
},
"studentName": {
"type": "string",
"description": "학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1
},
"phone": {
"type": "string",
"description": "상담 대상 연락처입니다.",
"nullable": false,
"maxLength": 60,
"default": ""
},
"reservedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$",
"description": "상담 예약 일시입니다. 한국 시간 yyyy-MM-dd HH:mm 형식입니다.",
"nullable": false,
"minLength": 1
},
"type": {
"type": "string",
"description": "상담 유형 또는 분류입니다.",
"nullable": false,
"maxLength": 100,
"default": ""
},
"status": {
"type": "string",
"enum": [
"예약",
"완료",
"변경",
"불참",
"취소"
],
"description": "상담 상태입니다. 예약·완료·변경·불참·취소 중 하나입니다.",
"nullable": false,
"minLength": 1
},
"content": {
"type": "string",
"description": "상담 내용입니다.",
"nullable": false,
"maxLength": 10000,
"default": ""
},
"staffId": {
"type": "string",
"description": "GET /v1/consultations/staff 응답 data[].id에서 선택한 상담 담당자 식별값을 문자열로 전달합니다. 담당자 이름이나 직원 출퇴근용 정수 staffId를 넣지 않습니다. 이 목록의 id는 담당자 식별 문자열입니다. API 담당자의 식별값은 로그인 권한을 의미하지 않습니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1
}
},
"required": [
"studentName",
"reservedAt",
"status",
"staffId"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"studentId": "00000001",
"studentName": "예시 이름",
"phone": "010-0000-0000",
"reservedAt": "예시",
"type": "예시",
"status": "예약",
"content": "예시",
"staffId": "1"
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/consultations/{id}상담 예약 변경 · 완료 · 취소+
consultations.write · consultations.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/consultations 응답 data.items[].id의 상담 예약 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 조건부·선택 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 예: 00000001. 이름·전화번호가 아니며 앞자리 0을 유지하세요. | "00000001" |
studentName | string | 필수 | 학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다. | "예시 이름" |
phone | string | 조건부·선택 | 상담 대상 연락처입니다. | "010-0000-0000" |
reservedAt | string | 필수 | 상담 예약 일시입니다. 한국 시간 yyyy-MM-dd HH:mm 형식입니다. | "예시" |
type | string | 조건부·선택 | 상담 유형 또는 분류입니다. | "예시" |
status | string | 필수 | 상담 상태입니다. 예약·완료·변경·불참·취소 중 하나입니다. | "예약" |
content | string | 조건부·선택 | 상담 내용입니다. | "예시" |
staffId | string | 필수 | GET /v1/consultations/staff 응답 data[].id에서 선택한 상담 담당자 식별값을 문자열로 전달합니다. 담당자 이름이나 직원 출퇴근용 정수 staffId를 넣지 않습니다. 이 목록의 id는 담당자 식별 문자열입니다. API 담당자의 식별값은 로그인 권한을 의미하지 않습니다. | "1" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 예: 00000001. 이름·전화번호가 아니며 앞자리 0을 유지하세요.",
"nullable": false,
"default": ""
},
"studentName": {
"type": "string",
"description": "학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1
},
"phone": {
"type": "string",
"description": "상담 대상 연락처입니다.",
"nullable": false,
"maxLength": 60,
"default": ""
},
"reservedAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$",
"description": "상담 예약 일시입니다. 한국 시간 yyyy-MM-dd HH:mm 형식입니다.",
"nullable": false,
"minLength": 1
},
"type": {
"type": "string",
"description": "상담 유형 또는 분류입니다.",
"nullable": false,
"maxLength": 100,
"default": ""
},
"status": {
"type": "string",
"enum": [
"예약",
"완료",
"변경",
"불참",
"취소"
],
"description": "상담 상태입니다. 예약·완료·변경·불참·취소 중 하나입니다.",
"nullable": false,
"minLength": 1
},
"content": {
"type": "string",
"description": "상담 내용입니다.",
"nullable": false,
"maxLength": 10000,
"default": ""
},
"staffId": {
"type": "string",
"description": "GET /v1/consultations/staff 응답 data[].id에서 선택한 상담 담당자 식별값을 문자열로 전달합니다. 담당자 이름이나 직원 출퇴근용 정수 staffId를 넣지 않습니다. 이 목록의 id는 담당자 식별 문자열입니다. API 담당자의 식별값은 로그인 권한을 의미하지 않습니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1
}
},
"required": [
"studentName",
"reservedAt",
"status",
"staffId"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"studentId": "00000001",
"studentName": "예시 이름",
"phone": "010-0000-0000",
"reservedAt": "예시",
"type": "예시",
"status": "예약",
"content": "예시",
"staffId": "1"
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/consultations/{id}상담 예약 삭제+
consultations.write · consultations.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | GET /v1/consultations 응답 data.items[].id의 상담 예약 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/consultations/staff상담 담당자 선택 목록+
consultations.read · consultations.staff
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
[].name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
}
},
"required": [
"id",
"name"
]
}
}성공 응답 예시
{
"data": [
{
"id": "1",
"name": "예시 이름"
}
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/statistics/students통계 학생별 상세(학생 이름·번호 포함, month=0은 연간 월별 집합 합집합)+
statistics.read · statistics.students
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
closedOnly | query | 선택 | 종강한 수강반만 조회할지 여부입니다. 기본 false입니다. |
teamKeys | query | 선택 | 통계 수강반 목록의 실제 key 배열입니다. 생략하면 학원 기준, 지정하면 선택 수강반 기준입니다. |
year | query | 필수 | 통계 조회 연도입니다. 1900~2100입니다. |
month | query | 필수 | 집계 월 1~12입니다. 0은 월별 합집합으로 계산한 연간 고유 인원입니다. |
kind | query | 필수 | new(신규), active(재원), withdrawn(퇴원) 중 하나입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].studentId | string | 필수 | 학생 번호 문자열입니다. 앞자리 0을 유지합니다. | "00000001" |
[].studentName | string | 필수 | 학생 번호와 함께 표시할 실제 학생 이름입니다. | "예시 이름" |
[].schoolName | string | 필수 | 학생 학교명입니다. | "예시 이름" |
[].gradeName | string | 필수 | 학생 학년입니다. | "예시 이름" |
[].enrollments | array | 필수 | 해당 학생의 집계 대상 수강 이력입니다. | 하위 필드·본문 예시 참조 |
[].enrollments[].enrollmentId | integer | 필수 | 수강 이력 번호입니다. | 1 |
[].enrollments[].teamName | string | 필수 | 수강반과 시간표의 표시 이름입니다. | "예시 이름" |
[].enrollments[].beginDate | integer | 필수 | 수강 시작일입니다. yyyyMMdd 정수입니다. | 20260115 |
[].enrollments[].endDate | integer | 필수 | 수강 종료일입니다. yyyyMMdd 정수이며 0은 미설정입니다. | 20260115 |
[].enrollments[].endType | string | 필수 | 저장된 종료 사유입니다. 퇴원·전반·종강을 구분합니다. | "예시" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "학생 번호 문자열입니다. 앞자리 0을 유지합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 번호와 함께 표시할 실제 학생 이름입니다.",
"nullable": false
},
"schoolName": {
"type": "string",
"description": "학생 학교명입니다.",
"nullable": false
},
"gradeName": {
"type": "string",
"description": "학생 학년입니다.",
"nullable": false
},
"enrollments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"enrollmentId": {
"type": "integer",
"description": "수강 이력 번호입니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "수강반과 시간표의 표시 이름입니다.",
"nullable": false
},
"beginDate": {
"type": "integer",
"description": "수강 시작일입니다. yyyyMMdd 정수입니다.",
"nullable": false
},
"endDate": {
"type": "integer",
"description": "수강 종료일입니다. yyyyMMdd 정수이며 0은 미설정입니다.",
"nullable": false
},
"endType": {
"type": "string",
"description": "저장된 종료 사유입니다. 퇴원·전반·종강을 구분합니다.",
"nullable": false
}
},
"required": [
"enrollmentId",
"teamName",
"beginDate",
"endDate",
"endType"
]
},
"description": "해당 학생의 집계 대상 수강 이력입니다.",
"nullable": false
}
},
"required": [
"studentId",
"studentName",
"schoolName",
"gradeName",
"enrollments"
]
}
}성공 응답 예시
{
"data": [
{
"studentId": "00000001",
"studentName": "예시 이름",
"schoolName": "예시 이름",
"gradeName": "예시 이름",
"enrollments": [
{
"enrollmentId": 1,
"teamName": "예시 이름",
"beginDate": 20260115,
"endDate": 20260115,
"endType": "예시"
}
]
}
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/statistics/summary월별·연간 신규·재원·퇴원 고유 인원(명시 선택한 수강반 기준 전환)+
statistics.read · statistics.summary
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
closedOnly | query | 선택 | 종강한 수강반만 조회할지 여부입니다. 기본 false입니다. |
teamKeys | query | 선택 | 통계 수강반 목록의 실제 key 배열입니다. 생략하면 학원 기준, 지정하면 선택 수강반 기준입니다. |
year | query | 필수 | 통계 조회 연도입니다. 1900~2100입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
months | array | 조건부·선택 | 월별 학생 수 집계입니다. | 하위 필드·본문 예시 참조 |
months[].monthNumber | integer | 조건부·선택 | 집계 대상 월입니다. | 1 |
months[].monthEnd | integer | 조건부·선택 | 집계 월 말일입니다. yyyyMMdd 정수입니다. | 1 |
months[].newCount | integer | 조건부·선택 | 중복 제거된 신규 학생 수입니다. | 1 |
months[].activeCount | integer | 조건부·선택 | 계속 재원 학생 수입니다. 해당 월 신규와 최종 퇴원 예정자는 제외합니다. | 1 |
months[].withdrawnCount | integer | 조건부·선택 | 퇴원 학생 수입니다. 전반·종강·전반취소는 제외합니다. | 1 |
months[].referenceDate | integer | 조건부·선택 | 집계의 한국 날짜 기준일입니다. yyyyMMdd 정수입니다. | 20260115 |
months[].isFuture | boolean | 조건부·선택 | 아직 집계하지 않는 미래 월인지 여부입니다. | false |
totals | object | 조건부·선택 | 월별 집합을 합친 후 학생 번호로 중복을 제거한 연간 합계입니다. | 하위 필드·본문 예시 참조 |
totals.newCount | integer | 조건부·선택 | 중복 제거된 신규 학생 수입니다. | 1 |
totals.activeCount | integer | 조건부·선택 | 계속 재원 학생 수입니다. 해당 월 신규와 최종 퇴원 예정자는 제외합니다. | 1 |
totals.withdrawnCount | integer | 조건부·선택 | 퇴원 학생 수입니다. 전반·종강·전반취소는 제외합니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"months": {
"type": "array",
"items": {
"type": "object",
"properties": {
"monthNumber": {
"type": "integer",
"description": "집계 대상 월입니다.",
"nullable": false
},
"monthEnd": {
"type": "integer",
"description": "집계 월 말일입니다. yyyyMMdd 정수입니다.",
"nullable": false
},
"newCount": {
"type": "integer",
"description": "중복 제거된 신규 학생 수입니다.",
"nullable": false
},
"activeCount": {
"type": "integer",
"description": "계속 재원 학생 수입니다. 해당 월 신규와 최종 퇴원 예정자는 제외합니다.",
"nullable": false
},
"withdrawnCount": {
"type": "integer",
"description": "퇴원 학생 수입니다. 전반·종강·전반취소는 제외합니다.",
"nullable": false
},
"referenceDate": {
"type": "integer",
"description": "집계의 한국 날짜 기준일입니다. yyyyMMdd 정수입니다.",
"nullable": false
},
"isFuture": {
"type": "boolean",
"description": "아직 집계하지 않는 미래 월인지 여부입니다.",
"nullable": false
}
}
},
"description": "월별 학생 수 집계입니다.",
"nullable": false
},
"totals": {
"type": "object",
"properties": {
"newCount": {
"type": "integer",
"description": "중복 제거된 신규 학생 수입니다.",
"nullable": false
},
"activeCount": {
"type": "integer",
"description": "계속 재원 학생 수입니다. 해당 월 신규와 최종 퇴원 예정자는 제외합니다.",
"nullable": false
},
"withdrawnCount": {
"type": "integer",
"description": "퇴원 학생 수입니다. 전반·종강·전반취소는 제외합니다.",
"nullable": false
}
},
"description": "월별 집합을 합친 후 학생 번호로 중복을 제거한 연간 합계입니다.",
"nullable": false
}
}
}성공 응답 예시
{
"data": {
"months": [
{
"monthNumber": 1,
"monthEnd": 1,
"newCount": 1,
"activeCount": 1,
"withdrawnCount": 1,
"referenceDate": 20260115,
"isFuture": false
}
],
"totals": {
"newCount": 1,
"activeCount": 1,
"withdrawnCount": 1
}
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/statistics/teams통계 조회 가능한 수강반·시간표 key 목록+
statistics.read · statistics.teams
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
closedOnly | query | 선택 | 종강한 수강반만 조회할지 여부입니다. 기본 false입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].teamCode | integer | 조건부·선택 | 반별 게시판의 대상 수강반 번호입니다. | 1 |
[].scheduleId | integer | 조건부·선택 | 해당 반의 시간표 번호입니다. | 1 |
[].teamName | string | 조건부·선택 | 수강반과 시간표의 표시 이름입니다. | "예시 이름" |
[].isClosed | boolean | 조건부·선택 | 기준일에 종강한 수강반인지 여부입니다. | false |
[].beginDate | integer | 조건부·선택 | 수강반의 개강일입니다. yyyyMMdd 정수이며 0은 미설정입니다. | 20260115 |
[].endDate | integer | 조건부·선택 | 수강반의 종강일입니다. yyyyMMdd 정수이며 0은 미설정입니다. | 20260115 |
[].enrollmentCount | integer | 조건부·선택 | 삭제되거나 전반 취소된 수강을 제외한 해당 반·시간표의 수강 기록 수입니다. 고유 학생 통계 인원과 구분합니다. | 1 |
[].key | string | 조건부·선택 | 반번호:시간표번호 형식의 실제 통계 수강반 선택 키입니다. | "예시" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"teamCode": {
"type": "integer",
"description": "반별 게시판의 대상 수강반 번호입니다.",
"nullable": false
},
"scheduleId": {
"type": "integer",
"description": "해당 반의 시간표 번호입니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "수강반과 시간표의 표시 이름입니다.",
"nullable": false
},
"isClosed": {
"type": "boolean",
"description": "기준일에 종강한 수강반인지 여부입니다.",
"nullable": false
},
"beginDate": {
"type": "integer",
"description": "수강반의 개강일입니다. yyyyMMdd 정수이며 0은 미설정입니다.",
"nullable": false
},
"endDate": {
"type": "integer",
"description": "수강반의 종강일입니다. yyyyMMdd 정수이며 0은 미설정입니다.",
"nullable": false
},
"enrollmentCount": {
"type": "integer",
"description": "삭제되거나 전반 취소된 수강을 제외한 해당 반·시간표의 수강 기록 수입니다. 고유 학생 통계 인원과 구분합니다.",
"nullable": false
},
"key": {
"type": "string",
"description": "반번호:시간표번호 형식의 실제 통계 수강반 선택 키입니다.",
"nullable": false
}
}
}
}성공 응답 예시
{
"data": [
{
"teamCode": 1,
"scheduleId": 1,
"teamName": "예시 이름",
"isClosed": false,
"beginDate": 20260115,
"endDate": 20260115,
"enrollmentCount": 1,
"key": "예시"
}
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/students/statistics/withdrawals기간별 퇴원 명단. basis=academy는 학원 최종 퇴원, enrollment는 반별 퇴원 이력(다른 반 계속 수강도 포함). 반별 명단은 enrollment 사용. 원본 학생·반명·퇴원일, 전반·종강·전반취소 제외+
statistics.read · statistics.withdrawals
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
basis | query | 선택 | 퇴원 조회 기준. academy=다른 반까지 모두 마친 학원 기준 최종 퇴원(기본). enrollment=반별 퇴원 이력이며 다른 반을 계속 듣는 학생도 포함. 수강반별 퇴원일·명단 요청은 enrollment. 전반·종강·전반취소는 두 기준 모두 제외. |
from | query | 필수 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 필수 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].studentId | string | 필수 | 학생 번호입니다. 문자열의 앞자리 0을 보존합니다. | "00000001" |
items[].studentName | string | 필수 | 저장된 원본 학생 이름입니다. | "예시 이름" |
items[].enrollmentId | integer | 필수 | 퇴원한 수강 이력 번호입니다. | 1 |
items[].teamName | string | 필수 | 저장된 원본 반·시간표 표시 이름입니다. | "예시 이름" |
items[].endDate | string | 필수 | 실제 퇴원 효력일입니다. yyyy-MM-dd 형식입니다. | "2026-01-15" |
items[].endType | string | 필수 | 저장된 종료 사유입니다. 선택한 basis의 퇴원만 포함하고 전반·종강·전반취소는 제외합니다. | "예시" |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "학생 번호입니다. 문자열의 앞자리 0을 보존합니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "저장된 원본 학생 이름입니다.",
"nullable": false
},
"enrollmentId": {
"type": "integer",
"description": "퇴원한 수강 이력 번호입니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "저장된 원본 반·시간표 표시 이름입니다.",
"nullable": false
},
"endDate": {
"type": "string",
"description": "실제 퇴원 효력일입니다. yyyy-MM-dd 형식입니다.",
"nullable": false
},
"endType": {
"type": "string",
"description": "저장된 종료 사유입니다. 선택한 basis의 퇴원만 포함하고 전반·종강·전반취소는 제외합니다.",
"nullable": false
}
},
"required": [
"studentId",
"studentName",
"enrollmentId",
"teamName",
"endDate",
"endType"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"studentId": "00000001",
"studentName": "예시 이름",
"enrollmentId": 1,
"teamName": "예시 이름",
"endDate": "2026-01-15",
"endType": "예시"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}채점관리
POST/v1/grading/sections과목·대분류 등록+
grading.write · grading.sections.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
subject | string | 필수 | 과목 이름입니다. 같은 이름으로 대분류를 묶습니다. | "수학" |
name | string | 필수 | 대분류 또는 소분류 이름입니다. | "대수" |
order | integer | 조건부·선택 | 표시 순서입니다. 작은 값부터 정렬합니다. | 0 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"subject": {
"type": "string",
"description": "과목 이름입니다. 같은 이름으로 대분류를 묶습니다.",
"nullable": false,
"maxLength": 20,
"minLength": 1,
"example": "수학"
},
"name": {
"type": "string",
"description": "대분류 또는 소분류 이름입니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1,
"example": "대수"
},
"order": {
"type": "integer",
"description": "표시 순서입니다. 작은 값부터 정렬합니다.",
"nullable": false,
"minimum": 0,
"maximum": 10000,
"default": 0
}
},
"required": [
"subject",
"name"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"subject": "수학",
"name": "대수",
"order": 0
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/grading/sections/{sectionId}과목 내 대분류 수정+
grading.write · grading.sections.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
sectionId | path | 필수 | GET /v1/grading/subjects/{subject}/sections 응답 data[].id의 대분류 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
subject | string | 필수 | 과목 이름입니다. 같은 이름으로 대분류를 묶습니다. | "수학" |
name | string | 필수 | 대분류 또는 소분류 이름입니다. | "대수" |
order | integer | 조건부·선택 | 표시 순서입니다. 작은 값부터 정렬합니다. | 0 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"subject": {
"type": "string",
"description": "과목 이름입니다. 같은 이름으로 대분류를 묶습니다.",
"nullable": false,
"maxLength": 20,
"minLength": 1,
"example": "수학"
},
"name": {
"type": "string",
"description": "대분류 또는 소분류 이름입니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1,
"example": "대수"
},
"order": {
"type": "integer",
"description": "표시 순서입니다. 작은 값부터 정렬합니다.",
"nullable": false,
"minimum": 0,
"maximum": 10000,
"default": 0
}
},
"required": [
"subject",
"name"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"subject": "수학",
"name": "대수",
"order": 0
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/grading/sections/{sectionId}대분류 삭제(사용 중이면 거절)+
grading.write · grading.sections.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
sectionId | path | 필수 | GET /v1/grading/subjects/{subject}/sections 응답 data[].id의 대분류 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/grading/sections/{sectionId}/patterns대분류의 소분류 목록+
grading.read · grading.patterns.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
sectionId | path | 필수 | GET /v1/grading/subjects/{subject}/sections 응답 data[].id의 대분류 번호입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | integer | 필수 | 분류 고유 번호입니다. | 1 |
[].sectionId | integer | 필수 | 소분류가 속한 대분류 번호입니다. 대분류 자체는 자신의 번호입니다. | 1 |
[].subject | string | 필수 | 과목 이름입니다. | "예시" |
[].name | string | 필수 | 분류 표시 이름입니다. | "예시 이름" |
[].order | integer | 필수 | 표시 순서입니다. | 1 |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "분류 고유 번호입니다.",
"nullable": false
},
"sectionId": {
"type": "integer",
"description": "소분류가 속한 대분류 번호입니다. 대분류 자체는 자신의 번호입니다.",
"nullable": false
},
"subject": {
"type": "string",
"description": "과목 이름입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "분류 표시 이름입니다.",
"nullable": false
},
"order": {
"type": "integer",
"description": "표시 순서입니다.",
"nullable": false
}
},
"required": [
"id",
"sectionId",
"subject",
"name",
"order"
]
}
}성공 응답 예시
{
"data": [
{
"id": 1,
"sectionId": 1,
"subject": "예시",
"name": "예시 이름",
"order": 1
}
],
"meta": {
"requestId": "example-request-id"
}
}POST/v1/grading/sections/{sectionId}/patterns소분류 등록+
grading.write · grading.patterns.create
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
sectionId | path | 필수 | GET /v1/grading/subjects/{subject}/sections 응답 data[].id의 대분류 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
subject | string | 필수 | 과목 이름입니다. 같은 이름으로 대분류를 묶습니다. | "수학" |
name | string | 필수 | 대분류 또는 소분류 이름입니다. | "대수" |
order | integer | 조건부·선택 | 표시 순서입니다. 작은 값부터 정렬합니다. | 0 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"subject": {
"type": "string",
"description": "과목 이름입니다. 같은 이름으로 대분류를 묶습니다.",
"nullable": false,
"maxLength": 20,
"minLength": 1,
"example": "수학"
},
"name": {
"type": "string",
"description": "대분류 또는 소분류 이름입니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1,
"example": "대수"
},
"order": {
"type": "integer",
"description": "표시 순서입니다. 작은 값부터 정렬합니다.",
"nullable": false,
"minimum": 0,
"maximum": 10000,
"default": 0
}
},
"required": [
"subject",
"name"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"subject": "수학",
"name": "대수",
"order": 0
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/grading/sections/{sectionId}/patterns/{patternId}소분류 수정+
grading.write · grading.patterns.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
sectionId | path | 필수 | GET /v1/grading/subjects/{subject}/sections 응답 data[].id의 대분류 번호입니다. |
patternId | path | 필수 | GET /v1/grading/sections/{sectionId}/patterns 응답 data[].id의 소분류 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
subject | string | 필수 | 과목 이름입니다. 같은 이름으로 대분류를 묶습니다. | "수학" |
name | string | 필수 | 대분류 또는 소분류 이름입니다. | "대수" |
order | integer | 조건부·선택 | 표시 순서입니다. 작은 값부터 정렬합니다. | 0 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"subject": {
"type": "string",
"description": "과목 이름입니다. 같은 이름으로 대분류를 묶습니다.",
"nullable": false,
"maxLength": 20,
"minLength": 1,
"example": "수학"
},
"name": {
"type": "string",
"description": "대분류 또는 소분류 이름입니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1,
"example": "대수"
},
"order": {
"type": "integer",
"description": "표시 순서입니다. 작은 값부터 정렬합니다.",
"nullable": false,
"minimum": 0,
"maximum": 10000,
"default": 0
}
},
"required": [
"subject",
"name"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"subject": "수학",
"name": "대수",
"order": 0
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/grading/sections/{sectionId}/patterns/{patternId}소분류 삭제(사용 중이면 거절)+
grading.write · grading.patterns.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
sectionId | path | 필수 | GET /v1/grading/subjects/{subject}/sections 응답 data[].id의 대분류 번호입니다. |
patternId | path | 필수 | GET /v1/grading/sections/{sectionId}/patterns 응답 data[].id의 소분류 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/grading/subjects채점 과목 목록+
grading.read · grading.subjects.list
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "string"
}
}성공 응답 예시
{
"data": [
"예시"
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/grading/subjects/{subject}/sections과목별 대분류 목록+
grading.read · grading.sections.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
subject | path | 필수 | 과목 이름입니다. URL 경로로 전달할 때 퍼센트 인코딩합니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | integer | 필수 | 분류 고유 번호입니다. | 1 |
[].sectionId | integer | 필수 | 소분류가 속한 대분류 번호입니다. 대분류 자체는 자신의 번호입니다. | 1 |
[].subject | string | 필수 | 과목 이름입니다. | "예시" |
[].name | string | 필수 | 분류 표시 이름입니다. | "예시 이름" |
[].order | integer | 필수 | 표시 순서입니다. | 1 |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "분류 고유 번호입니다.",
"nullable": false
},
"sectionId": {
"type": "integer",
"description": "소분류가 속한 대분류 번호입니다. 대분류 자체는 자신의 번호입니다.",
"nullable": false
},
"subject": {
"type": "string",
"description": "과목 이름입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "분류 표시 이름입니다.",
"nullable": false
},
"order": {
"type": "integer",
"description": "표시 순서입니다.",
"nullable": false
}
},
"required": [
"id",
"sectionId",
"subject",
"name",
"order"
]
}
}성공 응답 예시
{
"data": [
{
"id": 1,
"sectionId": 1,
"subject": "예시",
"name": "예시 이름",
"order": 1
}
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/grading/omr-templates공식 OMR 양식별 총 칸 수·종류 목록·PDF/이미지 제공 정보. 개별 문항 번호·답안 종류·정답 입력 틀은 grading.answer-template.get에 있음. answerTypes는 필요한 종류 교집합 필터(0 객관식, 1 단답형 정답 비교, 2 서술형 획득점수). 미지정 필터는 생략. 양식 코드는 학원 시험 이름이 아님+
grading.read · grading.omr-templates.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
answerTypes | query | 선택 | OMR 양식에 반드시 포함할 답안 종류. 쉼표로 지정하며 모든 조건을 동시에 만족해야 합니다. 0=객관식, 1=단답형 정답 비교, 2=서술형 획득점수. 객관식과 서술형을 함께 원하면 0,2. 생략하면 전체 양식이며 제목만으로 종류를 추측하지 않습니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].answerTypes | array | 필수 | 공식 문항 구조의 답안 종류: 0 객관식, 1 단답형 정답 비교, 2 서술형 획득점수. null은 구조 미확인입니다. 문항 위치는 정답 입력 틀 조회로 확인하세요. | 하위 필드·본문 예시 참조 |
[].code | string | 필수 | OMR 양식 번호입니다. 정답지 등록과 채점에 사용합니다. | "예시" |
[].title | string | 필수 | OMR 양식 설명입니다. | "예시" |
[].questions | integer | 필수 | 실제 문항 수입니다. | 1 |
[].layout | integer | 필수 | OMR 용도 코드입니다. 7은 두 회차용입니다. | 1 |
[].pdfUrl | string | 필수 | 빈 공식 OMR PDF 다운로드 API 상대 경로입니다. API 서버 주소와 결합하고 Authorization: Bearer 헤더로 요청하세요. 미제공 형식이면 null입니다. JSON이 아닌 PDF 원본을 반환합니다. | "예시" |
[].imageUrl | string | 필수 | 공식 OMR 미리보기 이미지 다운로드 API 상대 경로입니다. API 서버 주소와 결합하고 같은 API 키 헤더로 요청하세요. PNG 또는 JPG 원본이며 제공 이미지가 없으면 null입니다. 채점용 인쇄에는 PDF 사용을 권장합니다. | "예시" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"answerTypes": {
"type": "array",
"items": {
"type": "integer",
"enum": [
0,
1,
2
]
},
"description": "공식 문항 구조의 답안 종류: 0 객관식, 1 단답형 정답 비교, 2 서술형 획득점수. null은 구조 미확인입니다. 문항 위치는 정답 입력 틀 조회로 확인하세요.",
"nullable": true
},
"code": {
"type": "string",
"description": "OMR 양식 번호입니다. 정답지 등록과 채점에 사용합니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "OMR 양식 설명입니다.",
"nullable": false
},
"questions": {
"type": "integer",
"description": "실제 문항 수입니다.",
"nullable": false
},
"layout": {
"type": "integer",
"description": "OMR 용도 코드입니다. 7은 두 회차용입니다.",
"nullable": false
},
"pdfUrl": {
"type": "string",
"description": "빈 공식 OMR PDF 다운로드 API 상대 경로입니다. API 서버 주소와 결합하고 Authorization: Bearer 헤더로 요청하세요. 미제공 형식이면 null입니다. JSON이 아닌 PDF 원본을 반환합니다.",
"nullable": true
},
"imageUrl": {
"type": "string",
"description": "공식 OMR 미리보기 이미지 다운로드 API 상대 경로입니다. API 서버 주소와 결합하고 같은 API 키 헤더로 요청하세요. PNG 또는 JPG 원본이며 제공 이미지가 없으면 null입니다. 채점용 인쇄에는 PDF 사용을 권장합니다.",
"nullable": true
}
},
"required": [
"answerTypes",
"code",
"title",
"questions",
"layout",
"pdfUrl",
"imageUrl"
]
}
}성공 응답 예시
{
"data": [
{
"answerTypes": [
0
],
"code": "예시",
"title": "예시",
"questions": 1,
"layout": 1,
"pdfUrl": "예시",
"imageUrl": "예시"
}
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/grading/omr-templates/{code}/files/{format}공식 빈 OMR PDF·이미지 원본 다운로드+
grading.read · grading.omr-templates.download
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
code | path | 필수 | GET /v1/grading/omr-templates 응답에서 선택한 양식의 code입니다. 예: 문자열 120. 시험 번호와 다릅니다. |
format | path | 필수 | 공식 양식 원본 형식입니다. pdf는 인쇄용 PDF, image는 미리보기 PNG/JPG입니다. 양식 목록에서 제공 여부를 확인하세요. |
성공 응답 · 원본 파일
API 키를 Authorization: Bearer 헤더에 넣어 GET 요청하세요. JSON 봉투 없이 PDF 또는 PNG/JPG 원본과 Content-Disposition 파일명, X-Request-Id를 반환합니다. 경로의 format은 pdf 또는 image입니다. 제공하지 않는 파일 형식은 404입니다.
Explorer에서 요청 구성 →GET/v1/grading/exams시험·정답지 검색·목록(제목·회차·연도·학년으로 구별, 수강반 목록과 다름)+
grading.read · grading.exams.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
search | query | 선택 | 시험 제목·구분·과목 검색어. 공백으로 나눈 모든 단어가 일치해야 하며 괄호 등 사이 문자는 달라도 됨. 최대 100자. 생략 시 전체. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].registeredQuestionCount | integer | 필수 | 전체 답안 칸 중 배점이 양수인 문항 수입니다. null은 상세 원본 미확인입니다. | 1 |
items[].storedSlotCount | integer | 필수 | 배점 0을 포함한 전체 OMR 답안 칸 수입니다. null은 상세 원본 미확인입니다. | 1 |
items[].maximum | number | 필수 | 시험에 저장된 만점. 최고 득점이 아니며 선택과목별 유효 만점은 성적 analysis.maxScore로 확인. null은 만점 미확인. | 1 |
items[].online | object | 필수 | 온라인 시험 번호·구분·응시대상·진행 상태입니다. 온라인 미등록은 null입니다. | 하위 필드·본문 예시 참조 |
items[].online.onlineExamId | integer | 필수 | 온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다. | 1 |
items[].online.examId | integer | 필수 | 채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다. | 1 |
items[].online.title | string | 필수 | 온라인 시험 제목입니다. | "예시" |
items[].online.kind | string | 필수 | 시험 구분: retest 재시험, homework 과제입니다. | "예시" |
items[].online.status | string | 필수 | unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다. | "예시" |
items[].online.studentTargetCount | integer | 필수 | 개별 지정 응시 등록 수입니다. | 1 |
items[].online.classTargetCount | integer | 필수 | 지정한 수강 시간표 수입니다. | 1 |
items[].teacherId | integer | 필수 | 시험 담당 강사의 학원 내 사용자 번호입니다. | 1 |
items[].id | integer | 필수 | 시험 고유 번호입니다. | 1 |
items[].title | string | 필수 | 시험 표시 제목입니다. | "예시" |
items[].name | string | 필수 | 시험 또는 회차 이름입니다. | "예시 이름" |
items[].subject | string | 필수 | 시험 과목입니다. 정확한 값은 등록된 과목 목록을 사용하며 넓은 과목군 검색은 부분 일치로 조회합니다. | "예시" |
items[].grade | string | 필수 | 대상 학년입니다. | "예시" |
items[].year | integer | 필수 | 시험 연도입니다. | 1 |
items[].omrCode | string | 필수 | OMR 양식 번호입니다. | "예시" |
items[].published | boolean | 필수 | 학생 성적 공개 여부입니다. | false |
items[].answers | array | 필수 | 문항별 정답과 배점입니다. 목록 응답의 빈 배열은 미조회이며 실제 문항은 상세 조회에서 확인합니다. | 하위 필드·본문 예시 참조 |
items[].answers[].number | string | 필수 | 유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요. | "1" |
items[].answers[].subjectCode | integer | 조건부·선택 | 선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다. | 0 |
items[].answers[].answerType | integer | 조건부·선택 | 답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다. | 0 |
items[].answers[].answer | string | 조건부·선택 | 정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다. | "1" |
items[].answers[].weight | number | 조건부·선택 | 문항 배점입니다. 0이면 채점하지 않습니다. | 0 |
items[].answers[].sectionId | integer | 조건부·선택 | 학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다. | 0 |
items[].answers[].patternId | integer | 조건부·선택 | 학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다. | 0 |
items[].answers[].difficulty | integer | 조건부·선택 | 난이도 코드입니다. 0~5입니다. | 0 |
items[].answers[].comment | string | 조건부·선택 | 문항 해설 또는 분석 코멘트입니다. | "예시" |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"registeredQuestionCount": {
"type": "integer",
"x-read-source": {
"operation": "grading.exams.get",
"rowKey": "id",
"parameter": "examId",
"authoritative": false
},
"description": "전체 답안 칸 중 배점이 양수인 문항 수입니다. null은 상세 원본 미확인입니다.",
"nullable": true
},
"storedSlotCount": {
"type": "integer",
"x-read-source": {
"operation": "grading.exams.get",
"rowKey": "id",
"parameter": "examId",
"authoritative": false
},
"description": "배점 0을 포함한 전체 OMR 답안 칸 수입니다. null은 상세 원본 미확인입니다.",
"nullable": true
},
"maximum": {
"type": "number",
"description": "시험에 저장된 만점. 최고 득점이 아니며 선택과목별 유효 만점은 성적 analysis.maxScore로 확인. null은 만점 미확인.",
"nullable": true
},
"online": {
"type": "object",
"properties": {
"onlineExamId": {
"type": "integer",
"description": "온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "온라인 시험 제목입니다.",
"nullable": false
},
"kind": {
"type": "string",
"description": "시험 구분: retest 재시험, homework 과제입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다.",
"nullable": false
},
"studentTargetCount": {
"type": "integer",
"description": "개별 지정 응시 등록 수입니다.",
"nullable": false
},
"classTargetCount": {
"type": "integer",
"description": "지정한 수강 시간표 수입니다.",
"nullable": false
}
},
"required": [
"onlineExamId",
"examId",
"title",
"kind",
"status",
"studentTargetCount",
"classTargetCount"
],
"description": "온라인 시험 번호·구분·응시대상·진행 상태입니다. 온라인 미등록은 null입니다.",
"nullable": true
},
"teacherId": {
"type": "integer",
"description": "시험 담당 강사의 학원 내 사용자 번호입니다.",
"nullable": false
},
"id": {
"type": "integer",
"description": "시험 고유 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "시험 표시 제목입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "시험 또는 회차 이름입니다.",
"nullable": false
},
"subject": {
"type": "string",
"description": "시험 과목입니다. 정확한 값은 등록된 과목 목록을 사용하며 넓은 과목군 검색은 부분 일치로 조회합니다.",
"nullable": false
},
"grade": {
"type": "string",
"description": "대상 학년입니다.",
"nullable": false
},
"year": {
"type": "integer",
"description": "시험 연도입니다.",
"nullable": false
},
"omrCode": {
"type": "string",
"description": "OMR 양식 번호입니다.",
"nullable": false
},
"published": {
"type": "boolean",
"description": "학생 성적 공개 여부입니다.",
"nullable": false
},
"answers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"number": {
"type": "string",
"description": "유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요.",
"nullable": false,
"maxLength": 20,
"example": "1"
},
"subjectCode": {
"type": "integer",
"description": "선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다.",
"nullable": false,
"minimum": 0,
"maximum": 99,
"default": 0
},
"answerType": {
"type": "integer",
"description": "답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2,
"default": 0
},
"answer": {
"type": "string",
"description": "정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다.",
"nullable": false,
"maxLength": 100,
"default": ""
},
"weight": {
"type": "number",
"description": "문항 배점입니다. 0이면 채점하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 10000,
"default": 0
},
"sectionId": {
"type": "integer",
"description": "학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"patternId": {
"type": "integer",
"description": "학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"difficulty": {
"type": "integer",
"description": "난이도 코드입니다. 0~5입니다.",
"nullable": false,
"minimum": 0,
"maximum": 5,
"default": 0
},
"comment": {
"type": "string",
"description": "문항 해설 또는 분석 코멘트입니다.",
"nullable": false,
"maxLength": 2000,
"default": ""
}
},
"required": [
"number"
]
},
"x-read-source": {
"operation": "grading.exams.get",
"rowKey": "id",
"parameter": "examId",
"authoritative": true
},
"description": "문항별 정답과 배점입니다. 목록 응답의 빈 배열은 미조회이며 실제 문항은 상세 조회에서 확인합니다.",
"nullable": false
}
},
"required": [
"registeredQuestionCount",
"storedSlotCount",
"maximum",
"online",
"teacherId",
"id",
"title",
"name",
"subject",
"grade",
"year",
"omrCode",
"published",
"answers"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"registeredQuestionCount": 1,
"storedSlotCount": 1,
"maximum": 1,
"online": {
"onlineExamId": 1,
"examId": 1,
"title": "예시",
"kind": "예시",
"status": "예시",
"studentTargetCount": 1,
"classTargetCount": 1
},
"teacherId": 1,
"id": 1,
"title": "예시",
"name": "예시 이름",
"subject": "예시",
"grade": "예시",
"year": 1,
"omrCode": "예시",
"published": false,
"answers": [
{
"number": "1",
"subjectCode": 0,
"answerType": 0,
"answer": "1",
"weight": 0,
"sectionId": 0,
"patternId": 0,
"difficulty": 0,
"comment": "예시"
}
]
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/grading/exams/{examId}시험과 전체 문항별 정답 상세+
grading.read · grading.exams.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
examId | path | 필수 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
registeredQuestionCount | integer | 필수 | 전체 답안 칸 중 배점이 양수인 문항 수입니다. null은 상세 원본 미확인입니다. | 1 |
storedSlotCount | integer | 필수 | 배점 0을 포함한 전체 OMR 답안 칸 수입니다. null은 상세 원본 미확인입니다. | 1 |
maximum | number | 필수 | 시험에 저장된 만점. 최고 득점이 아니며 선택과목별 유효 만점은 성적 analysis.maxScore로 확인. null은 만점 미확인. | 1 |
online | object | 필수 | 온라인 시험 번호·구분·응시대상·진행 상태입니다. 온라인 미등록은 null입니다. | 하위 필드·본문 예시 참조 |
online.onlineExamId | integer | 필수 | 온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다. | 1 |
online.examId | integer | 필수 | 채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다. | 1 |
online.title | string | 필수 | 온라인 시험 제목입니다. | "예시" |
online.kind | string | 필수 | 시험 구분: retest 재시험, homework 과제입니다. | "예시" |
online.status | string | 필수 | unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다. | "예시" |
online.studentTargetCount | integer | 필수 | 개별 지정 응시 등록 수입니다. | 1 |
online.classTargetCount | integer | 필수 | 지정한 수강 시간표 수입니다. | 1 |
teacherId | integer | 필수 | 시험 담당 강사의 학원 내 사용자 번호입니다. | 1 |
id | integer | 필수 | 시험 고유 번호입니다. | 1 |
title | string | 필수 | 시험 표시 제목입니다. | "예시" |
name | string | 필수 | 시험 또는 회차 이름입니다. | "예시 이름" |
subject | string | 필수 | 시험 과목입니다. 정확한 값은 등록된 과목 목록을 사용하며 넓은 과목군 검색은 부분 일치로 조회합니다. | "예시" |
grade | string | 필수 | 대상 학년입니다. | "예시" |
year | integer | 필수 | 시험 연도입니다. | 1 |
omrCode | string | 필수 | OMR 양식 번호입니다. | "예시" |
published | boolean | 필수 | 학생 성적 공개 여부입니다. | false |
answers | array | 필수 | 문항별 정답과 배점입니다. 목록 응답의 빈 배열은 미조회이며 실제 문항은 상세 조회에서 확인합니다. | 하위 필드·본문 예시 참조 |
answers[].number | string | 필수 | 유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요. | "1" |
answers[].subjectCode | integer | 조건부·선택 | 선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다. | 0 |
answers[].answerType | integer | 조건부·선택 | 답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다. | 0 |
answers[].answer | string | 조건부·선택 | 정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다. | "1" |
answers[].weight | number | 조건부·선택 | 문항 배점입니다. 0이면 채점하지 않습니다. | 0 |
answers[].sectionId | integer | 조건부·선택 | 학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다. | 0 |
answers[].patternId | integer | 조건부·선택 | 학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다. | 0 |
answers[].difficulty | integer | 조건부·선택 | 난이도 코드입니다. 0~5입니다. | 0 |
answers[].comment | string | 조건부·선택 | 문항 해설 또는 분석 코멘트입니다. | "예시" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"registeredQuestionCount": {
"type": "integer",
"x-read-source": {
"operation": "grading.exams.get",
"rowKey": "id",
"parameter": "examId",
"authoritative": false
},
"description": "전체 답안 칸 중 배점이 양수인 문항 수입니다. null은 상세 원본 미확인입니다.",
"nullable": true
},
"storedSlotCount": {
"type": "integer",
"x-read-source": {
"operation": "grading.exams.get",
"rowKey": "id",
"parameter": "examId",
"authoritative": false
},
"description": "배점 0을 포함한 전체 OMR 답안 칸 수입니다. null은 상세 원본 미확인입니다.",
"nullable": true
},
"maximum": {
"type": "number",
"description": "시험에 저장된 만점. 최고 득점이 아니며 선택과목별 유효 만점은 성적 analysis.maxScore로 확인. null은 만점 미확인.",
"nullable": true
},
"online": {
"type": "object",
"properties": {
"onlineExamId": {
"type": "integer",
"description": "온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "온라인 시험 제목입니다.",
"nullable": false
},
"kind": {
"type": "string",
"description": "시험 구분: retest 재시험, homework 과제입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다.",
"nullable": false
},
"studentTargetCount": {
"type": "integer",
"description": "개별 지정 응시 등록 수입니다.",
"nullable": false
},
"classTargetCount": {
"type": "integer",
"description": "지정한 수강 시간표 수입니다.",
"nullable": false
}
},
"required": [
"onlineExamId",
"examId",
"title",
"kind",
"status",
"studentTargetCount",
"classTargetCount"
],
"description": "온라인 시험 번호·구분·응시대상·진행 상태입니다. 온라인 미등록은 null입니다.",
"nullable": true
},
"teacherId": {
"type": "integer",
"description": "시험 담당 강사의 학원 내 사용자 번호입니다.",
"nullable": false
},
"id": {
"type": "integer",
"description": "시험 고유 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "시험 표시 제목입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "시험 또는 회차 이름입니다.",
"nullable": false
},
"subject": {
"type": "string",
"description": "시험 과목입니다. 정확한 값은 등록된 과목 목록을 사용하며 넓은 과목군 검색은 부분 일치로 조회합니다.",
"nullable": false
},
"grade": {
"type": "string",
"description": "대상 학년입니다.",
"nullable": false
},
"year": {
"type": "integer",
"description": "시험 연도입니다.",
"nullable": false
},
"omrCode": {
"type": "string",
"description": "OMR 양식 번호입니다.",
"nullable": false
},
"published": {
"type": "boolean",
"description": "학생 성적 공개 여부입니다.",
"nullable": false
},
"answers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"number": {
"type": "string",
"description": "유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요.",
"nullable": false,
"maxLength": 20,
"example": "1"
},
"subjectCode": {
"type": "integer",
"description": "선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다.",
"nullable": false,
"minimum": 0,
"maximum": 99,
"default": 0
},
"answerType": {
"type": "integer",
"description": "답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2,
"default": 0
},
"answer": {
"type": "string",
"description": "정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다.",
"nullable": false,
"maxLength": 100,
"default": ""
},
"weight": {
"type": "number",
"description": "문항 배점입니다. 0이면 채점하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 10000,
"default": 0
},
"sectionId": {
"type": "integer",
"description": "학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"patternId": {
"type": "integer",
"description": "학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"difficulty": {
"type": "integer",
"description": "난이도 코드입니다. 0~5입니다.",
"nullable": false,
"minimum": 0,
"maximum": 5,
"default": 0
},
"comment": {
"type": "string",
"description": "문항 해설 또는 분석 코멘트입니다.",
"nullable": false,
"maxLength": 2000,
"default": ""
}
},
"required": [
"number"
]
},
"x-read-source": {
"operation": "grading.exams.get",
"rowKey": "id",
"parameter": "examId",
"authoritative": true
},
"description": "문항별 정답과 배점입니다. 목록 응답의 빈 배열은 미조회이며 실제 문항은 상세 조회에서 확인합니다.",
"nullable": false
}
},
"required": [
"registeredQuestionCount",
"storedSlotCount",
"maximum",
"online",
"teacherId",
"id",
"title",
"name",
"subject",
"grade",
"year",
"omrCode",
"published",
"answers"
]
}성공 응답 예시
{
"data": {
"registeredQuestionCount": 1,
"storedSlotCount": 1,
"maximum": 1,
"online": {
"onlineExamId": 1,
"examId": 1,
"title": "예시",
"kind": "예시",
"status": "예시",
"studentTargetCount": 1,
"classTargetCount": 1
},
"teacherId": 1,
"id": 1,
"title": "예시",
"name": "예시 이름",
"subject": "예시",
"grade": "예시",
"year": 1,
"omrCode": "예시",
"published": false,
"answers": [
{
"number": "1",
"subjectCode": 0,
"answerType": 0,
"answer": "1",
"weight": 0,
"sectionId": 0,
"patternId": 0,
"difficulty": 0,
"comment": "예시"
}
]
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/grading/exams새 시험·정답지 등록(학생 답안 채점 아님)+
grading.write · grading.exams.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
teacherId | integer | 조건부·선택 | 담당 강사 번호입니다. /teams/teachers에서 선택합니다. 생략하면 신규 시험은 인증한 대표 강사, 수정은 기존 담당자를 유지합니다. | 1 |
title | string | 필수 | 시험 표시 제목입니다. | "예시 수학 평가" |
name | string | 필수 | 시험 또는 회차 이름입니다. | "1회차" |
subject | string | 필수 | 채점 과목 목록의 정확한 이름을 선택합니다. 비슷한 과목이 여럿이면 먼저 선택을 확인하고, 등록되지 않은 과목은 저장 전에 안내합니다. | "수학" |
grade | string | 조건부·선택 | 시험 대상 학년입니다. | "예시" |
year | integer | 필수 | 시험 연도입니다. 1900~2100입니다. | 2026 |
omrCode | string | 필수 | GET /v1/grading/omr-templates 응답 data[].code에서 선택한 양식 번호 문자열입니다. 예: 120. 시험 id와 다릅니다. | "120" |
answers | array | 필수 | GET /v1/grading/omr-templates/{code}/answers 응답 data[]의 문항 번호·선택과목·답안 형식을 기준으로 정답·배점을 채웁니다. 배열 순서를 유지하며 선택한 양식의 모든 문항을 전달하세요. | 하위 필드·본문 예시 참조 |
answers[].number | string | 필수 | 유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요. | "1" |
answers[].subjectCode | integer | 조건부·선택 | 선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다. | 0 |
answers[].answerType | integer | 조건부·선택 | 답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다. | 0 |
answers[].answer | string | 조건부·선택 | 정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다. | "1" |
answers[].weight | number | 조건부·선택 | 문항 배점입니다. 0이면 채점하지 않습니다. | 0 |
answers[].sectionId | integer | 조건부·선택 | 학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다. | 0 |
answers[].patternId | integer | 조건부·선택 | 학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다. | 0 |
answers[].difficulty | integer | 조건부·선택 | 난이도 코드입니다. 0~5입니다. | 0 |
answers[].comment | string | 조건부·선택 | 문항 해설 또는 분석 코멘트입니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"teacherId": {
"type": "integer",
"description": "담당 강사 번호입니다. /teams/teachers에서 선택합니다. 생략하면 신규 시험은 인증한 대표 강사, 수정은 기존 담당자를 유지합니다.",
"nullable": true,
"minimum": 1,
"maximum": 2147483647
},
"title": {
"type": "string",
"description": "시험 표시 제목입니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1,
"example": "예시 수학 평가"
},
"name": {
"type": "string",
"description": "시험 또는 회차 이름입니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1,
"example": "1회차"
},
"subject": {
"type": "string",
"description": "채점 과목 목록의 정확한 이름을 선택합니다. 비슷한 과목이 여럿이면 먼저 선택을 확인하고, 등록되지 않은 과목은 저장 전에 안내합니다.",
"nullable": false,
"maxLength": 20,
"minLength": 1,
"example": "수학"
},
"grade": {
"type": "string",
"description": "시험 대상 학년입니다.",
"nullable": false,
"maxLength": 30,
"default": ""
},
"year": {
"type": "integer",
"description": "시험 연도입니다. 1900~2100입니다.",
"nullable": false,
"minimum": 1900,
"maximum": 2100,
"example": 2026
},
"omrCode": {
"type": "string",
"description": "GET /v1/grading/omr-templates 응답 data[].code에서 선택한 양식 번호 문자열입니다. 예: 120. 시험 id와 다릅니다.",
"nullable": false,
"maxLength": 30,
"minLength": 1,
"example": "120"
},
"answers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"number": {
"type": "string",
"description": "유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요.",
"nullable": false,
"maxLength": 20,
"example": "1"
},
"subjectCode": {
"type": "integer",
"description": "선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다.",
"nullable": false,
"minimum": 0,
"maximum": 99,
"default": 0
},
"answerType": {
"type": "integer",
"description": "답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2,
"default": 0
},
"answer": {
"type": "string",
"description": "정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다.",
"nullable": false,
"maxLength": 100,
"default": ""
},
"weight": {
"type": "number",
"description": "문항 배점입니다. 0이면 채점하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 10000,
"default": 0
},
"sectionId": {
"type": "integer",
"description": "학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"patternId": {
"type": "integer",
"description": "학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"difficulty": {
"type": "integer",
"description": "난이도 코드입니다. 0~5입니다.",
"nullable": false,
"minimum": 0,
"maximum": 5,
"default": 0
},
"comment": {
"type": "string",
"description": "문항 해설 또는 분석 코멘트입니다.",
"nullable": false,
"maxLength": 2000,
"default": ""
}
},
"required": [
"number"
]
},
"description": "GET /v1/grading/omr-templates/{code}/answers 응답 data[]의 문항 번호·선택과목·답안 형식을 기준으로 정답·배점을 채웁니다. 배열 순서를 유지하며 선택한 양식의 모든 문항을 전달하세요.",
"nullable": false,
"minItems": 1,
"maxItems": 400
}
},
"required": [
"title",
"name",
"subject",
"year",
"omrCode",
"answers"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"teacherId": 1,
"title": "예시 수학 평가",
"name": "1회차",
"subject": "수학",
"grade": "예시",
"year": 2026,
"omrCode": "120",
"answers": [
{
"number": "1",
"subjectCode": 0,
"answerType": 0,
"answer": "1",
"weight": 0,
"sectionId": 0,
"patternId": 0,
"difficulty": 0,
"comment": "예시"
}
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/grading/exams/{examId}정답지 전체 교체(성적표 설정·문항 이미지 연결 보존)+
grading.write · grading.exams.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
examId | path | 필수 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
teacherId | integer | 조건부·선택 | 담당 강사 번호입니다. /teams/teachers에서 선택합니다. 생략하면 신규 시험은 인증한 대표 강사, 수정은 기존 담당자를 유지합니다. | 1 |
title | string | 필수 | 시험 표시 제목입니다. | "예시 수학 평가" |
name | string | 필수 | 시험 또는 회차 이름입니다. | "1회차" |
subject | string | 필수 | 채점 과목 목록의 정확한 이름을 선택합니다. 비슷한 과목이 여럿이면 먼저 선택을 확인하고, 등록되지 않은 과목은 저장 전에 안내합니다. | "수학" |
grade | string | 조건부·선택 | 시험 대상 학년입니다. | "예시" |
year | integer | 필수 | 시험 연도입니다. 1900~2100입니다. | 2026 |
omrCode | string | 필수 | GET /v1/grading/omr-templates 응답 data[].code에서 선택한 양식 번호 문자열입니다. 예: 120. 시험 id와 다릅니다. | "120" |
answers | array | 필수 | GET /v1/grading/omr-templates/{code}/answers 응답 data[]의 문항 번호·선택과목·답안 형식을 기준으로 정답·배점을 채웁니다. 배열 순서를 유지하며 선택한 양식의 모든 문항을 전달하세요. | 하위 필드·본문 예시 참조 |
answers[].number | string | 필수 | 유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요. | "1" |
answers[].subjectCode | integer | 조건부·선택 | 선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다. | 0 |
answers[].answerType | integer | 조건부·선택 | 답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다. | 0 |
answers[].answer | string | 조건부·선택 | 정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다. | "1" |
answers[].weight | number | 조건부·선택 | 문항 배점입니다. 0이면 채점하지 않습니다. | 0 |
answers[].sectionId | integer | 조건부·선택 | 학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다. | 0 |
answers[].patternId | integer | 조건부·선택 | 학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다. | 0 |
answers[].difficulty | integer | 조건부·선택 | 난이도 코드입니다. 0~5입니다. | 0 |
answers[].comment | string | 조건부·선택 | 문항 해설 또는 분석 코멘트입니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"teacherId": {
"type": "integer",
"description": "담당 강사 번호입니다. /teams/teachers에서 선택합니다. 생략하면 신규 시험은 인증한 대표 강사, 수정은 기존 담당자를 유지합니다.",
"nullable": true,
"minimum": 1,
"maximum": 2147483647
},
"title": {
"type": "string",
"description": "시험 표시 제목입니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1,
"example": "예시 수학 평가"
},
"name": {
"type": "string",
"description": "시험 또는 회차 이름입니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1,
"example": "1회차"
},
"subject": {
"type": "string",
"description": "채점 과목 목록의 정확한 이름을 선택합니다. 비슷한 과목이 여럿이면 먼저 선택을 확인하고, 등록되지 않은 과목은 저장 전에 안내합니다.",
"nullable": false,
"maxLength": 20,
"minLength": 1,
"example": "수학"
},
"grade": {
"type": "string",
"description": "시험 대상 학년입니다.",
"nullable": false,
"maxLength": 30,
"default": ""
},
"year": {
"type": "integer",
"description": "시험 연도입니다. 1900~2100입니다.",
"nullable": false,
"minimum": 1900,
"maximum": 2100,
"example": 2026
},
"omrCode": {
"type": "string",
"description": "GET /v1/grading/omr-templates 응답 data[].code에서 선택한 양식 번호 문자열입니다. 예: 120. 시험 id와 다릅니다.",
"nullable": false,
"maxLength": 30,
"minLength": 1,
"example": "120"
},
"answers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"number": {
"type": "string",
"description": "유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요.",
"nullable": false,
"maxLength": 20,
"example": "1"
},
"subjectCode": {
"type": "integer",
"description": "선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다.",
"nullable": false,
"minimum": 0,
"maximum": 99,
"default": 0
},
"answerType": {
"type": "integer",
"description": "답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2,
"default": 0
},
"answer": {
"type": "string",
"description": "정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다.",
"nullable": false,
"maxLength": 100,
"default": ""
},
"weight": {
"type": "number",
"description": "문항 배점입니다. 0이면 채점하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 10000,
"default": 0
},
"sectionId": {
"type": "integer",
"description": "학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"patternId": {
"type": "integer",
"description": "학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"difficulty": {
"type": "integer",
"description": "난이도 코드입니다. 0~5입니다.",
"nullable": false,
"minimum": 0,
"maximum": 5,
"default": 0
},
"comment": {
"type": "string",
"description": "문항 해설 또는 분석 코멘트입니다.",
"nullable": false,
"maxLength": 2000,
"default": ""
}
},
"required": [
"number"
]
},
"description": "GET /v1/grading/omr-templates/{code}/answers 응답 data[]의 문항 번호·선택과목·답안 형식을 기준으로 정답·배점을 채웁니다. 배열 순서를 유지하며 선택한 양식의 모든 문항을 전달하세요.",
"nullable": false,
"minItems": 1,
"maxItems": 400
}
},
"required": [
"title",
"name",
"subject",
"year",
"omrCode",
"answers"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"teacherId": 1,
"title": "예시 수학 평가",
"name": "1회차",
"subject": "수학",
"grade": "예시",
"year": 2026,
"omrCode": "120",
"answers": [
{
"number": "1",
"subjectCode": 0,
"answerType": 0,
"answer": "1",
"weight": 0,
"sectionId": 0,
"patternId": 0,
"difficulty": 0,
"comment": "예시"
}
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/grading/exams/{examId}시험 삭제(채점 자료가 있으면 거절)+
grading.write · grading.exams.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
examId | path | 필수 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/grading/omr-templates/{code}/answers지정한 OMR 양식의 문항별 번호(number)·답안 종류(answerType)·정답·배점 입력 틀 배열. 특정 문항 범위의 종류 확인에도 사용. 0 객관식, 1 단답형 정답 비교, 2 서술형 획득점수. 실제 시험·채점 점수 조회가 아님+
grading.read · grading.answer-template.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
code | path | 필수 | GET /v1/grading/omr-templates 응답에서 선택한 양식의 code입니다. 예: 문자열 120. 시험 번호와 다릅니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].number | string | 필수 | 유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요. | "1" |
[].subjectCode | integer | 조건부·선택 | 선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다. | 0 |
[].answerType | integer | 조건부·선택 | 답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다. | 0 |
[].answer | string | 조건부·선택 | 정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다. | "1" |
[].weight | number | 조건부·선택 | 문항 배점입니다. 0이면 채점하지 않습니다. | 0 |
[].sectionId | integer | 조건부·선택 | 학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다. | 0 |
[].patternId | integer | 조건부·선택 | 학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다. | 0 |
[].difficulty | integer | 조건부·선택 | 난이도 코드입니다. 0~5입니다. | 0 |
[].comment | string | 조건부·선택 | 문항 해설 또는 분석 코멘트입니다. | "예시" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"number": {
"type": "string",
"description": "유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요.",
"nullable": false,
"maxLength": 20,
"example": "1"
},
"subjectCode": {
"type": "integer",
"description": "선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다.",
"nullable": false,
"minimum": 0,
"maximum": 99,
"default": 0
},
"answerType": {
"type": "integer",
"description": "답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2,
"default": 0
},
"answer": {
"type": "string",
"description": "정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다.",
"nullable": false,
"maxLength": 100,
"default": ""
},
"weight": {
"type": "number",
"description": "문항 배점입니다. 0이면 채점하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 10000,
"default": 0
},
"sectionId": {
"type": "integer",
"description": "학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"patternId": {
"type": "integer",
"description": "학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"difficulty": {
"type": "integer",
"description": "난이도 코드입니다. 0~5입니다.",
"nullable": false,
"minimum": 0,
"maximum": 5,
"default": 0
},
"comment": {
"type": "string",
"description": "문항 해설 또는 분석 코멘트입니다.",
"nullable": false,
"maxLength": 2000,
"default": ""
}
},
"required": [
"number"
]
}
}성공 응답 예시
{
"data": [
{
"number": "1",
"subjectCode": 0,
"answerType": 0,
"answer": "1",
"weight": 0,
"sectionId": 0,
"patternId": 0,
"difficulty": 0,
"comment": "예시"
}
],
"meta": {
"requestId": "example-request-id"
}
}POST/v1/grading/omr-jobs단일·두 회차 OMR 채점 작업 등록(구독 OMR 장수 집계)+
grading.omr · grading.omr.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
examIds | array | 필수 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호를 배열로 전달합니다. 예: [1234]. 단일 채점은 1개, 두 회차는 순서대로 2개입니다. OMR 양식 번호와 다릅니다. | 하위 필드·본문 예시 참조 |
fileIds | array | 필수 | PDF 업로드 응답 data.files[].id를 페이지 순서대로 전달합니다. 단일 이미지 업로드는 응답 data.id를 배열에 넣습니다. 최대 100개 UUID이며 로컬 파일명·URL·직접 만든 UUID를 넣지 않습니다. | 하위 필드·본문 예시 참조 |
teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요. | 1 |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. teamId로 지정한 응시반에 속한 시간표 번호여야 합니다. | 1 |
examDate | string | 필수 | 응시일입니다. yyyy-MM-dd 형식입니다. | "2026-01-15" |
recognitionRate | integer | 조건부·선택 | 마킹 인식 기준입니다. 1~5이며 기본값 4(70%)입니다. | 1 |
expectedUnitCredits | integer | 조건부·선택 | 이전 연동 호환용 값입니다. 새 구독 요금제는 크레딧을 차감하지 않으며 생략하거나 0을 보냅니다. 실제 이미지 장수는 구독 OMR 한도에서 집계합니다. | 0 |
consent | boolean | 필수 | 실제 OMR 채점 실행에 동의하면 true입니다. 시도한 이미지 장수를 구독 한도에서 집계하며 인식 실패도 포함합니다. 크레딧은 차감하지 않습니다. | true |
요청 JSON 스키마
{
"type": "object",
"properties": {
"examIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호를 배열로 전달합니다. 예: [1234]. 단일 채점은 1개, 두 회차는 순서대로 2개입니다. OMR 양식 번호와 다릅니다.",
"nullable": false,
"minItems": 1,
"maxItems": 2
},
"fileIds": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "PDF 업로드 응답 data.files[].id를 페이지 순서대로 전달합니다. 단일 이미지 업로드는 응답 data.id를 배열에 넣습니다. 최대 100개 UUID이며 로컬 파일명·URL·직접 만든 UUID를 넣지 않습니다.",
"nullable": false,
"minItems": 1,
"maxItems": 100
},
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. teamId로 지정한 응시반에 속한 시간표 번호여야 합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"examDate": {
"type": "string",
"format": "date",
"description": "응시일입니다. yyyy-MM-dd 형식입니다.",
"nullable": false,
"minLength": 1
},
"recognitionRate": {
"type": "integer",
"description": "마킹 인식 기준입니다. 1~5이며 기본값 4(70%)입니다.",
"nullable": false,
"minimum": 1,
"maximum": 5,
"default": 4
},
"expectedUnitCredits": {
"type": "integer",
"description": "이전 연동 호환용 값입니다. 새 구독 요금제는 크레딧을 차감하지 않으며 생략하거나 0을 보냅니다. 실제 이미지 장수는 구독 OMR 한도에서 집계합니다.",
"nullable": false,
"minimum": 0,
"maximum": 1000000,
"default": 0,
"example": 0
},
"consent": {
"type": "boolean",
"description": "실제 OMR 채점 실행에 동의하면 true입니다. 시도한 이미지 장수를 구독 한도에서 집계하며 인식 실패도 포함합니다. 크레딧은 차감하지 않습니다.",
"nullable": false,
"enum": [
true
]
}
},
"required": [
"examIds",
"fileIds",
"teamId",
"scheduleId",
"examDate",
"consent"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | string | 필수 | 작업 고유 번호입니다. 같은 작업의 상태 조회와 결과 다운로드에 사용합니다. | "00000000-0000-4000-8000-000000000001" |
kind | string | 필수 | omr·excel·recalculate·report-pdf·wrong-note·link-issue·link-reissue·teaching-report 중 하나입니다. teaching-report는 과제장·누적 성적표 PDF 작업입니다. | "예시" |
status | string | 필수 | queued 대기, running 처리 중, completed 완료, failed 실패, needs_review 결과 확인 필요입니다. 결과 확인 필요 작업은 자동 재실행하지 않습니다. | "예시" |
message | string | 필수 | 사용자에게 표시할 진행 또는 오류 안내입니다. | "예시" |
createdAt | string | 필수 | 작업 생성 시각입니다. UTC입니다. | "2026-01-15T00:00:00Z" |
result | object | 필수 | 완료된 작업의 처리 결과입니다. 미완료이면 null입니다. | 하위 필드·본문 예시 참조 |
result.logId | integer | 필수 | OMR 인식 이력 번호입니다. OMR 외 작업은 0입니다. | 1 |
result.ids | array | 필수 | 신규 등록 또는 수정된 채점 행 번호 배열입니다. | 하위 필드·본문 예시 참조 |
result.examIds | array | 필수 | 처리한 시험 번호 배열입니다. 두 회차는 입력 순서입니다. | 하위 필드·본문 예시 참조 |
result.rows | array | 필수 | OMR 이미지별 인식 결과입니다. | 하위 필드·본문 예시 참조 |
result.rows[].page | integer | 필수 | 입력 이미지의 1부터 시작하는 페이지 순서입니다. | 1 |
result.rows[].studentId | string | 필수 | 인식한 학원 학생 번호입니다. 미식별이면 빈 문자열입니다. | "00000001" |
result.rows[].studentName | string | 필수 | 인식한 학생 이름입니다. 미식별이면 빈 문자열입니다. | "예시 이름" |
result.rows[].marks | array | 필수 | 인식한 답안 원문 배열이며 채점 확정 결과가 아닙니다. 두 회차는 1회차 양식 슬롯 뒤에 2회차 슬롯 순서입니다. 배열 위치로 표시 문항 번호·정오답·점수를 추정하지 말고 저장된 회차별 성적 분석으로 확인하세요. | 하위 필드·본문 예시 참조 |
result.rows[].message | string | 필수 | 이 이미지의 인식 확인 안내입니다. 문제가 없으면 빈 값입니다. | "예시" |
result.errors | array | 필수 | 인식 실패 또는 검수가 필요한 이미지 안내입니다. 이 배열만으로 미저장을 판단하지 마세요. ids의 실제 저장 결과와 요청한 이미지·회차 수를 대조하고 rows의 페이지 번호로 검수 대상을 확인하세요. | 하위 필드·본문 예시 참조 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "작업 고유 번호입니다. 같은 작업의 상태 조회와 결과 다운로드에 사용합니다.",
"nullable": false
},
"kind": {
"type": "string",
"description": "omr·excel·recalculate·report-pdf·wrong-note·link-issue·link-reissue·teaching-report 중 하나입니다. teaching-report는 과제장·누적 성적표 PDF 작업입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "queued 대기, running 처리 중, completed 완료, failed 실패, needs_review 결과 확인 필요입니다. 결과 확인 필요 작업은 자동 재실행하지 않습니다.",
"nullable": false
},
"message": {
"type": "string",
"description": "사용자에게 표시할 진행 또는 오류 안내입니다.",
"nullable": false
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "작업 생성 시각입니다. UTC입니다.",
"nullable": false
},
"result": {
"type": "object",
"properties": {
"logId": {
"type": "integer",
"description": "OMR 인식 이력 번호입니다. OMR 외 작업은 0입니다.",
"nullable": false
},
"ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "신규 등록 또는 수정된 채점 행 번호 배열입니다.",
"nullable": false
},
"examIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "처리한 시험 번호 배열입니다. 두 회차는 입력 순서입니다.",
"nullable": false
},
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"page": {
"type": "integer",
"description": "입력 이미지의 1부터 시작하는 페이지 순서입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "인식한 학원 학생 번호입니다. 미식별이면 빈 문자열입니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "인식한 학생 이름입니다. 미식별이면 빈 문자열입니다.",
"nullable": false
},
"marks": {
"type": "array",
"items": {
"type": "string"
},
"description": "인식한 답안 원문 배열이며 채점 확정 결과가 아닙니다. 두 회차는 1회차 양식 슬롯 뒤에 2회차 슬롯 순서입니다. 배열 위치로 표시 문항 번호·정오답·점수를 추정하지 말고 저장된 회차별 성적 분석으로 확인하세요.",
"nullable": false
},
"message": {
"type": "string",
"description": "이 이미지의 인식 확인 안내입니다. 문제가 없으면 빈 값입니다.",
"nullable": false
}
},
"required": [
"page",
"studentId",
"studentName",
"marks",
"message"
]
},
"description": "OMR 이미지별 인식 결과입니다.",
"nullable": false
},
"errors": {
"type": "array",
"items": {
"type": "string"
},
"description": "인식 실패 또는 검수가 필요한 이미지 안내입니다. 이 배열만으로 미저장을 판단하지 마세요. ids의 실제 저장 결과와 요청한 이미지·회차 수를 대조하고 rows의 페이지 번호로 검수 대상을 확인하세요.",
"nullable": false
}
},
"required": [
"logId",
"ids",
"examIds",
"rows",
"errors"
],
"description": "완료된 작업의 처리 결과입니다. 미완료이면 null입니다.",
"nullable": true
}
},
"required": [
"id",
"kind",
"status",
"message",
"createdAt",
"result"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"examIds": [
1
],
"fileIds": [
"00000000-0000-4000-8000-000000000001"
],
"teamId": 1,
"scheduleId": 1,
"examDate": "2026-01-15",
"recognitionRate": 1,
"expectedUnitCredits": 0,
"consent": true
}성공 응답 예시
{
"data": {
"id": "00000000-0000-4000-8000-000000000001",
"kind": "예시",
"status": "예시",
"message": "예시",
"createdAt": "2026-01-15T00:00:00Z",
"result": {
"logId": 1,
"ids": [
1
],
"examIds": [
1
],
"rows": [
{
"page": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"marks": [
"1"
],
"message": "예시"
}
],
"errors": [
"예시"
]
}
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/grading/usage현재 API 호출·OMR 장수의 사용량과 구독 한도 확인+
grading.read · grading.usage.get
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
planId | string | 필수 | 현재 구독 요금제 식별자입니다. 기존 구독은 비어 있을 수 있습니다. | "1" |
requestsUnlimited | boolean | 필수 | 월 API 호출량 무제한 여부입니다. 분당 안전 제한은 별도로 적용합니다. | false |
monthlyOmrPages | integer | 필수 | 월 OMR 이미지 한도입니다. null이면 월 채점량 무제한입니다. | 1 |
usedOmrPages | integer | 필수 | 이번 구독 기간에 채점을 시도한 OMR 이미지 장수입니다. | 1 |
remainingOmrPages | integer | 필수 | 남은 OMR 이미지 장수입니다. null이면 무제한입니다. | 1 |
omrUnitCredits | integer | 필수 | 이전 연동 호환용 필드입니다. 구독형 API는 0이며 크레딧을 차감하지 않습니다. | 1 |
requestCredits | integer | 필수 | 이전 연동 호환용 필드이며 0입니다. 구독의 월·분당 호출 제한은 별도입니다. | 1 |
includedCredits | integer | 필수 | 이전 연동 호환용 필드이며 0입니다. 새 구독은 월 호출량과 OMR 이미지 장수로 집계합니다. | 1 |
remainingIncludedCredits | integer | 필수 | 이전 연동 호환용 필드이며 0입니다. 새 구독은 남은 OMR 장수를 확인하세요. | 1 |
purchasedCredits | integer | 필수 | 이전 연동 호환용 필드이며 0입니다. 추가 구매는 지원하지 않습니다. | 1 |
availableCredits | integer | 필수 | 이전 연동 호환용 필드이며 0입니다. 새 요금제는 크레딧 없이 호출·OMR 수량을 집계합니다. | 1 |
requestLimit | integer | 필수 | 이번 구독 기간에 적용하는 요청 한도입니다. requestsUnlimited=true이면 이 숫자로 월 제한을 판단하지 않습니다. 관리자 개별 상한은 별도로 적용됩니다. | 1 |
usedRequests | integer | 필수 | 이번 구독 기간에 접수된 API 요청 수입니다. 이 조회 요청도 포함되며 동일 쓰기 요청의 재응답은 중복 집계하지 않습니다. | 1 |
periodStart | string | 필수 | 이번 API 구독 사용량 기간 시작 시각입니다. 시간대 오프셋을 포함합니다. | "2026-01-15T00:00:00Z" |
periodEnd | string | 필수 | 현재 API 구독 만료 시각입니다. 시간대 오프셋을 포함합니다. | "2026-01-15T00:00:00Z" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"planId": {
"type": "string",
"description": "현재 구독 요금제 식별자입니다. 기존 구독은 비어 있을 수 있습니다.",
"nullable": true
},
"requestsUnlimited": {
"type": "boolean",
"description": "월 API 호출량 무제한 여부입니다. 분당 안전 제한은 별도로 적용합니다.",
"nullable": false
},
"monthlyOmrPages": {
"type": "integer",
"description": "월 OMR 이미지 한도입니다. null이면 월 채점량 무제한입니다.",
"nullable": true
},
"usedOmrPages": {
"type": "integer",
"description": "이번 구독 기간에 채점을 시도한 OMR 이미지 장수입니다.",
"nullable": false
},
"remainingOmrPages": {
"type": "integer",
"description": "남은 OMR 이미지 장수입니다. null이면 무제한입니다.",
"nullable": true
},
"omrUnitCredits": {
"type": "integer",
"description": "이전 연동 호환용 필드입니다. 구독형 API는 0이며 크레딧을 차감하지 않습니다.",
"nullable": false
},
"requestCredits": {
"type": "integer",
"description": "이전 연동 호환용 필드이며 0입니다. 구독의 월·분당 호출 제한은 별도입니다.",
"nullable": false
},
"includedCredits": {
"type": "integer",
"description": "이전 연동 호환용 필드이며 0입니다. 새 구독은 월 호출량과 OMR 이미지 장수로 집계합니다.",
"nullable": false
},
"remainingIncludedCredits": {
"type": "integer",
"description": "이전 연동 호환용 필드이며 0입니다. 새 구독은 남은 OMR 장수를 확인하세요.",
"nullable": false
},
"purchasedCredits": {
"type": "integer",
"description": "이전 연동 호환용 필드이며 0입니다. 추가 구매는 지원하지 않습니다.",
"nullable": false
},
"availableCredits": {
"type": "integer",
"description": "이전 연동 호환용 필드이며 0입니다. 새 요금제는 크레딧 없이 호출·OMR 수량을 집계합니다.",
"nullable": false
},
"requestLimit": {
"type": "integer",
"description": "이번 구독 기간에 적용하는 요청 한도입니다. requestsUnlimited=true이면 이 숫자로 월 제한을 판단하지 않습니다. 관리자 개별 상한은 별도로 적용됩니다.",
"nullable": false
},
"usedRequests": {
"type": "integer",
"description": "이번 구독 기간에 접수된 API 요청 수입니다. 이 조회 요청도 포함되며 동일 쓰기 요청의 재응답은 중복 집계하지 않습니다.",
"nullable": false
},
"periodStart": {
"type": "string",
"format": "date-time",
"description": "이번 API 구독 사용량 기간 시작 시각입니다. 시간대 오프셋을 포함합니다.",
"nullable": false
},
"periodEnd": {
"type": "string",
"format": "date-time",
"description": "현재 API 구독 만료 시각입니다. 시간대 오프셋을 포함합니다.",
"nullable": false
}
},
"required": [
"planId",
"requestsUnlimited",
"monthlyOmrPages",
"usedOmrPages",
"remainingOmrPages",
"omrUnitCredits",
"requestCredits",
"includedCredits",
"remainingIncludedCredits",
"purchasedCredits",
"availableCredits",
"requestLimit",
"usedRequests",
"periodStart",
"periodEnd"
]
}성공 응답 예시
{
"data": {
"planId": "1",
"requestsUnlimited": false,
"monthlyOmrPages": 1,
"usedOmrPages": 1,
"remainingOmrPages": 1,
"omrUnitCredits": 1,
"requestCredits": 1,
"includedCredits": 1,
"remainingIncludedCredits": 1,
"purchasedCredits": 1,
"availableCredits": 1,
"requestLimit": 1,
"usedRequests": 1,
"periodStart": "2026-01-15T00:00:00Z",
"periodEnd": "2026-01-15T00:00:00Z"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/grading/jobs/{jobId}데이터 작업 진행 상태·인식 결과 조회+
grading.read · grading.jobs.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
jobId | path | 필수 | 작업 생성 응답 data.id의 UUID를 그대로 전달합니다. 직접 생성하는 값이 아니며 같은 학원의 작업만 조회합니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | string | 필수 | 작업 고유 번호입니다. 같은 작업의 상태 조회와 결과 다운로드에 사용합니다. | "00000000-0000-4000-8000-000000000001" |
kind | string | 필수 | omr·excel·recalculate·report-pdf·wrong-note·link-issue·link-reissue·teaching-report 중 하나입니다. teaching-report는 과제장·누적 성적표 PDF 작업입니다. | "예시" |
status | string | 필수 | queued 대기, running 처리 중, completed 완료, failed 실패, needs_review 결과 확인 필요입니다. 결과 확인 필요 작업은 자동 재실행하지 않습니다. | "예시" |
message | string | 필수 | 사용자에게 표시할 진행 또는 오류 안내입니다. | "예시" |
createdAt | string | 필수 | 작업 생성 시각입니다. UTC입니다. | "2026-01-15T00:00:00Z" |
result | object | 필수 | 완료된 작업의 처리 결과입니다. 미완료이면 null입니다. | 하위 필드·본문 예시 참조 |
result.logId | integer | 필수 | OMR 인식 이력 번호입니다. OMR 외 작업은 0입니다. | 1 |
result.ids | array | 필수 | 신규 등록 또는 수정된 채점 행 번호 배열입니다. | 하위 필드·본문 예시 참조 |
result.examIds | array | 필수 | 처리한 시험 번호 배열입니다. 두 회차는 입력 순서입니다. | 하위 필드·본문 예시 참조 |
result.rows | array | 필수 | OMR 이미지별 인식 결과입니다. | 하위 필드·본문 예시 참조 |
result.rows[].page | integer | 필수 | 입력 이미지의 1부터 시작하는 페이지 순서입니다. | 1 |
result.rows[].studentId | string | 필수 | 인식한 학원 학생 번호입니다. 미식별이면 빈 문자열입니다. | "00000001" |
result.rows[].studentName | string | 필수 | 인식한 학생 이름입니다. 미식별이면 빈 문자열입니다. | "예시 이름" |
result.rows[].marks | array | 필수 | 인식한 답안 원문 배열이며 채점 확정 결과가 아닙니다. 두 회차는 1회차 양식 슬롯 뒤에 2회차 슬롯 순서입니다. 배열 위치로 표시 문항 번호·정오답·점수를 추정하지 말고 저장된 회차별 성적 분석으로 확인하세요. | 하위 필드·본문 예시 참조 |
result.rows[].message | string | 필수 | 이 이미지의 인식 확인 안내입니다. 문제가 없으면 빈 값입니다. | "예시" |
result.errors | array | 필수 | 인식 실패 또는 검수가 필요한 이미지 안내입니다. 이 배열만으로 미저장을 판단하지 마세요. ids의 실제 저장 결과와 요청한 이미지·회차 수를 대조하고 rows의 페이지 번호로 검수 대상을 확인하세요. | 하위 필드·본문 예시 참조 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "작업 고유 번호입니다. 같은 작업의 상태 조회와 결과 다운로드에 사용합니다.",
"nullable": false
},
"kind": {
"type": "string",
"description": "omr·excel·recalculate·report-pdf·wrong-note·link-issue·link-reissue·teaching-report 중 하나입니다. teaching-report는 과제장·누적 성적표 PDF 작업입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "queued 대기, running 처리 중, completed 완료, failed 실패, needs_review 결과 확인 필요입니다. 결과 확인 필요 작업은 자동 재실행하지 않습니다.",
"nullable": false
},
"message": {
"type": "string",
"description": "사용자에게 표시할 진행 또는 오류 안내입니다.",
"nullable": false
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "작업 생성 시각입니다. UTC입니다.",
"nullable": false
},
"result": {
"type": "object",
"properties": {
"logId": {
"type": "integer",
"description": "OMR 인식 이력 번호입니다. OMR 외 작업은 0입니다.",
"nullable": false
},
"ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "신규 등록 또는 수정된 채점 행 번호 배열입니다.",
"nullable": false
},
"examIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "처리한 시험 번호 배열입니다. 두 회차는 입력 순서입니다.",
"nullable": false
},
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"page": {
"type": "integer",
"description": "입력 이미지의 1부터 시작하는 페이지 순서입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "인식한 학원 학생 번호입니다. 미식별이면 빈 문자열입니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "인식한 학생 이름입니다. 미식별이면 빈 문자열입니다.",
"nullable": false
},
"marks": {
"type": "array",
"items": {
"type": "string"
},
"description": "인식한 답안 원문 배열이며 채점 확정 결과가 아닙니다. 두 회차는 1회차 양식 슬롯 뒤에 2회차 슬롯 순서입니다. 배열 위치로 표시 문항 번호·정오답·점수를 추정하지 말고 저장된 회차별 성적 분석으로 확인하세요.",
"nullable": false
},
"message": {
"type": "string",
"description": "이 이미지의 인식 확인 안내입니다. 문제가 없으면 빈 값입니다.",
"nullable": false
}
},
"required": [
"page",
"studentId",
"studentName",
"marks",
"message"
]
},
"description": "OMR 이미지별 인식 결과입니다.",
"nullable": false
},
"errors": {
"type": "array",
"items": {
"type": "string"
},
"description": "인식 실패 또는 검수가 필요한 이미지 안내입니다. 이 배열만으로 미저장을 판단하지 마세요. ids의 실제 저장 결과와 요청한 이미지·회차 수를 대조하고 rows의 페이지 번호로 검수 대상을 확인하세요.",
"nullable": false
}
},
"required": [
"logId",
"ids",
"examIds",
"rows",
"errors"
],
"description": "완료된 작업의 처리 결과입니다. 미완료이면 null입니다.",
"nullable": true
}
},
"required": [
"id",
"kind",
"status",
"message",
"createdAt",
"result"
]
}성공 응답 예시
{
"data": {
"id": "00000000-0000-4000-8000-000000000001",
"kind": "예시",
"status": "예시",
"message": "예시",
"createdAt": "2026-01-15T00:00:00Z",
"result": {
"logId": 1,
"ids": [
1
],
"examIds": [
1
],
"rows": [
{
"page": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"marks": [
"1"
],
"message": "예시"
}
],
"errors": [
"예시"
]
}
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/grading/attachments채팅 첨부 OMR PDF 업로드(최대 50MB·100쪽 / 이미지·XLSX도 지원)+
grading.write · grading.attachments.upload
이 API의 file.download_url·file.file_id는 첨부 연동 클라이언트가 제공해야 합니다. KlassLab에서 발급받거나 직접 만드는 값이 아닙니다. 로컬 PDF만 가지고 있다면 PDF 직접 업로드 API를 사용하세요. 아래 파일 참조 예시는 구조 설명용이며 다운로드할 수 있는 실주소가 아닙니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
file | object | 필수 | 첨부 참조 연동 전용 객체입니다. 클라이언트가 제공한 download_url·file_id와 선택적 MIME·파일명을 전달합니다. 일반 파일 업로드는 pdf-uploads 또는 uploads를 사용하세요. PDF 최대 50MB·100쪽, 그 외 최대 5MB입니다. | 하위 필드·본문 예시 참조 |
file.download_url | string | 필수 | 첨부 연동 클라이언트가 파일 메타데이터로 제공한 download_url을 그대로 전달합니다. 현재 승인 호스트는 oaiusercontent.com 및 그 하위 도메인의 HTTPS 주소뿐입니다. 일반 웹 URL·개인 저장소 주소·로컬 경로는 받지 않습니다. 이 메타데이터가 없는 일반 PDF 업로드는 /v1/grading/pdf-uploads를 사용하세요. | "https://files.oaiusercontent.com/example/omr.pdf?token=CLIENT_PROVIDED_TOKEN" |
file.file_id | string | 필수 | 첨부 연동 클라이언트의 동일한 파일 메타데이터에 있는 file_id를 그대로 전달합니다. KlassLab이 발급하는 API 키나 업로드 응답의 id가 아니며 직접 생성하는 UUID도 아닙니다. 클라이언트가 이 값을 제공하지 않는 환경에서는 /v1/grading/pdf-uploads로 파일 바이트를 전달하세요. | "file-client-example" |
file.mime_type | string | 조건부·선택 | 첨부 파일의 MIME 형식입니다. PDF는 application/pdf, PNG는 image/png, JPG는 image/jpeg입니다. 메타데이터에 없으면 생략할 수 있습니다. | "application/pdf" |
file.file_name | string | 조건부·선택 | 확장자를 포함한 원본 파일명입니다. 예: omr.pdf. 디렉터리 경로는 제외합니다. 생략하면 파일 내용·MIME 형식에서 확장자를 추정합니다. | "omr.pdf" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"file": {
"type": "object",
"properties": {
"download_url": {
"type": "string",
"description": "첨부 연동 클라이언트가 파일 메타데이터로 제공한 download_url을 그대로 전달합니다. 현재 승인 호스트는 oaiusercontent.com 및 그 하위 도메인의 HTTPS 주소뿐입니다. 일반 웹 URL·개인 저장소 주소·로컬 경로는 받지 않습니다. 이 메타데이터가 없는 일반 PDF 업로드는 /v1/grading/pdf-uploads를 사용하세요.",
"nullable": false,
"maxLength": 8192,
"minLength": 1,
"example": "https://files.oaiusercontent.com/example/omr.pdf?token=CLIENT_PROVIDED_TOKEN"
},
"file_id": {
"type": "string",
"description": "첨부 연동 클라이언트의 동일한 파일 메타데이터에 있는 file_id를 그대로 전달합니다. KlassLab이 발급하는 API 키나 업로드 응답의 id가 아니며 직접 생성하는 UUID도 아닙니다. 클라이언트가 이 값을 제공하지 않는 환경에서는 /v1/grading/pdf-uploads로 파일 바이트를 전달하세요.",
"nullable": false,
"maxLength": 256,
"minLength": 1,
"example": "file-client-example"
},
"mime_type": {
"type": "string",
"description": "첨부 파일의 MIME 형식입니다. PDF는 application/pdf, PNG는 image/png, JPG는 image/jpeg입니다. 메타데이터에 없으면 생략할 수 있습니다.",
"nullable": false,
"maxLength": 100,
"example": "application/pdf"
},
"file_name": {
"type": "string",
"description": "확장자를 포함한 원본 파일명입니다. 예: omr.pdf. 디렉터리 경로는 제외합니다. 생략하면 파일 내용·MIME 형식에서 확장자를 추정합니다.",
"nullable": false,
"maxLength": 120,
"example": "omr.pdf"
}
},
"required": [
"download_url",
"file_id"
],
"additionalProperties": false,
"description": "첨부 참조 연동 전용 객체입니다. 클라이언트가 제공한 download_url·file_id와 선택적 MIME·파일명을 전달합니다. 일반 파일 업로드는 pdf-uploads 또는 uploads를 사용하세요. PDF 최대 50MB·100쪽, 그 외 최대 5MB입니다.",
"nullable": false
}
},
"required": [
"file"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
files | array | 필수 | 페이지 순서대로 저장된 파일입니다. PDF는 각 쪽이 image 파일 하나가 됩니다. OMR 신청 시 이 순서대로 id를 fileIds에 전달하세요. | 하위 필드·본문 예시 참조 |
files[].id | string | 필수 | 업로드 파일 식별자입니다. 작업 등록 시 이 값만 전달합니다. | "00000000-0000-4000-8000-000000000001" |
files[].kind | string | 필수 | image 또는 xlsx입니다. | "예시" |
files[].bytes | integer | 필수 | 검증된 원본 파일 크기(바이트)입니다. | 1 |
files[].expiresAt | string | 필수 | 업로드 만료 시각입니다. UTC이며 업로드 후 24시간입니다. | "2026-01-15T00:00:00Z" |
pageCount | integer | 필수 | 저장된 파일 수입니다. PDF는 실제 변환된 페이지 수입니다. 업로드만으로 채점하거나 OMR 크레딧을 차감하지 않습니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"files": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "업로드 파일 식별자입니다. 작업 등록 시 이 값만 전달합니다.",
"nullable": false
},
"kind": {
"type": "string",
"description": "image 또는 xlsx입니다.",
"nullable": false
},
"bytes": {
"type": "integer",
"description": "검증된 원본 파일 크기(바이트)입니다.",
"nullable": false
},
"expiresAt": {
"type": "string",
"format": "date-time",
"description": "업로드 만료 시각입니다. UTC이며 업로드 후 24시간입니다.",
"nullable": false
}
},
"required": [
"id",
"kind",
"bytes",
"expiresAt"
]
},
"description": "페이지 순서대로 저장된 파일입니다. PDF는 각 쪽이 image 파일 하나가 됩니다. OMR 신청 시 이 순서대로 id를 fileIds에 전달하세요.",
"nullable": false
},
"pageCount": {
"type": "integer",
"description": "저장된 파일 수입니다. PDF는 실제 변환된 페이지 수입니다. 업로드만으로 채점하거나 OMR 크레딧을 차감하지 않습니다.",
"nullable": false
}
},
"required": [
"files",
"pageCount"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"file": {
"download_url": "https://files.oaiusercontent.com/example/omr.pdf?token=CLIENT_PROVIDED_TOKEN",
"file_id": "file-client-example",
"mime_type": "application/pdf",
"file_name": "omr.pdf"
}
}성공 응답 예시
{
"data": {
"files": [
{
"id": "00000000-0000-4000-8000-000000000001",
"kind": "예시",
"bytes": 1,
"expiresAt": "2026-01-15T00:00:00Z"
}
],
"pageCount": 1
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/grading/pdf-uploadsOMR PDF 원본 업로드(최대 50MB·100쪽 / 페이지 자동 변환)+
grading.write · grading.pdfs.upload
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
fileName | string | 필수 | 직접 업로드할 PDF의 파일명입니다. 예: omr.pdf. .pdf 확장자를 포함하고 C:\scan\omr.pdf 같은 디렉터리 경로는 제외하세요. | "omr.pdf" |
base64 | string | 필수 | 호출하는 프로그램이 PDF 파일 전체를 바이트로 읽어 Base64로 인코딩한 문자열입니다. Node.js: buffer.toString('base64'), C#: Convert.ToBase64String(bytes). 파일명·URL·로컬 경로·data: 접두사를 넣지 않습니다. 원본 최대 50MB·100쪽입니다. | "REPLACE_WITH_BASE64_OF_YOUR_FILE_BYTES" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"fileName": {
"type": "string",
"description": "직접 업로드할 PDF의 파일명입니다. 예: omr.pdf. .pdf 확장자를 포함하고 C:\\scan\\omr.pdf 같은 디렉터리 경로는 제외하세요.",
"nullable": false,
"maxLength": 120,
"minLength": 1,
"example": "omr.pdf"
},
"base64": {
"type": "string",
"description": "호출하는 프로그램이 PDF 파일 전체를 바이트로 읽어 Base64로 인코딩한 문자열입니다. Node.js: buffer.toString('base64'), C#: Convert.ToBase64String(bytes). 파일명·URL·로컬 경로·data: 접두사를 넣지 않습니다. 원본 최대 50MB·100쪽입니다.",
"nullable": false,
"maxLength": 69905068,
"minLength": 1,
"example": "REPLACE_WITH_BASE64_OF_YOUR_FILE_BYTES"
}
},
"required": [
"fileName",
"base64"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
files | array | 필수 | 페이지 순서대로 저장된 파일입니다. PDF는 각 쪽이 image 파일 하나가 됩니다. OMR 신청 시 이 순서대로 id를 fileIds에 전달하세요. | 하위 필드·본문 예시 참조 |
files[].id | string | 필수 | 업로드 파일 식별자입니다. 작업 등록 시 이 값만 전달합니다. | "00000000-0000-4000-8000-000000000001" |
files[].kind | string | 필수 | image 또는 xlsx입니다. | "예시" |
files[].bytes | integer | 필수 | 검증된 원본 파일 크기(바이트)입니다. | 1 |
files[].expiresAt | string | 필수 | 업로드 만료 시각입니다. UTC이며 업로드 후 24시간입니다. | "2026-01-15T00:00:00Z" |
pageCount | integer | 필수 | 저장된 파일 수입니다. PDF는 실제 변환된 페이지 수입니다. 업로드만으로 채점하거나 OMR 크레딧을 차감하지 않습니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"files": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "업로드 파일 식별자입니다. 작업 등록 시 이 값만 전달합니다.",
"nullable": false
},
"kind": {
"type": "string",
"description": "image 또는 xlsx입니다.",
"nullable": false
},
"bytes": {
"type": "integer",
"description": "검증된 원본 파일 크기(바이트)입니다.",
"nullable": false
},
"expiresAt": {
"type": "string",
"format": "date-time",
"description": "업로드 만료 시각입니다. UTC이며 업로드 후 24시간입니다.",
"nullable": false
}
},
"required": [
"id",
"kind",
"bytes",
"expiresAt"
]
},
"description": "페이지 순서대로 저장된 파일입니다. PDF는 각 쪽이 image 파일 하나가 됩니다. OMR 신청 시 이 순서대로 id를 fileIds에 전달하세요.",
"nullable": false
},
"pageCount": {
"type": "integer",
"description": "저장된 파일 수입니다. PDF는 실제 변환된 페이지 수입니다. 업로드만으로 채점하거나 OMR 크레딧을 차감하지 않습니다.",
"nullable": false
}
},
"required": [
"files",
"pageCount"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"fileName": "omr.pdf",
"base64": "REPLACE_WITH_BASE64_OF_YOUR_FILE_BYTES"
}성공 응답 예시
{
"data": {
"files": [
{
"id": "00000000-0000-4000-8000-000000000001",
"kind": "예시",
"bytes": 1,
"expiresAt": "2026-01-15T00:00:00Z"
}
],
"pageCount": 1
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/grading/uploads보조 업로드: PNG·JPG 스캔 이미지·XLSX 답안 파일(파일당 5MB)+
grading.write · grading.files.upload
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
fileName | string | 필수 | 원본 파일명입니다. PNG·JPG·XLSX만 허용합니다. 경로는 받지 않습니다. | "scan.jpg" |
base64 | string | 필수 | 호출하는 프로그램에서 파일 전체 바이트를 읽어 Base64 문자열로 변환합니다. Node.js buffer.toString('base64'), C# Convert.ToBase64String(bytes)를 사용합니다. 원본 최대 5MB이며 URL·파일명·로컬 경로·data: 접두사는 넣지 않습니다. | "REPLACE_WITH_BASE64_OF_YOUR_FILE_BYTES" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"fileName": {
"type": "string",
"description": "원본 파일명입니다. PNG·JPG·XLSX만 허용합니다. 경로는 받지 않습니다.",
"nullable": false,
"maxLength": 120,
"minLength": 1,
"example": "scan.jpg"
},
"base64": {
"type": "string",
"description": "호출하는 프로그램에서 파일 전체 바이트를 읽어 Base64 문자열로 변환합니다. Node.js buffer.toString('base64'), C# Convert.ToBase64String(bytes)를 사용합니다. 원본 최대 5MB이며 URL·파일명·로컬 경로·data: 접두사는 넣지 않습니다.",
"nullable": false,
"maxLength": 7000000,
"minLength": 1,
"example": "REPLACE_WITH_BASE64_OF_YOUR_FILE_BYTES"
}
},
"required": [
"fileName",
"base64"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | string | 필수 | 업로드 파일 식별자입니다. 작업 등록 시 이 값만 전달합니다. | "00000000-0000-4000-8000-000000000001" |
kind | string | 필수 | image 또는 xlsx입니다. | "예시" |
bytes | integer | 필수 | 검증된 원본 파일 크기(바이트)입니다. | 1 |
expiresAt | string | 필수 | 업로드 만료 시각입니다. UTC이며 업로드 후 24시간입니다. | "2026-01-15T00:00:00Z" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "업로드 파일 식별자입니다. 작업 등록 시 이 값만 전달합니다.",
"nullable": false
},
"kind": {
"type": "string",
"description": "image 또는 xlsx입니다.",
"nullable": false
},
"bytes": {
"type": "integer",
"description": "검증된 원본 파일 크기(바이트)입니다.",
"nullable": false
},
"expiresAt": {
"type": "string",
"format": "date-time",
"description": "업로드 만료 시각입니다. UTC이며 업로드 후 24시간입니다.",
"nullable": false
}
},
"required": [
"id",
"kind",
"bytes",
"expiresAt"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"fileName": "scan.jpg",
"base64": "REPLACE_WITH_BASE64_OF_YOUR_FILE_BYTES"
}성공 응답 예시
{
"data": {
"id": "00000000-0000-4000-8000-000000000001",
"kind": "예시",
"bytes": 1,
"expiresAt": "2026-01-15T00:00:00Z"
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/grading/exams/{examId}/excel-importsXLSX 답안 등록 작업 생성+
grading.write · grading.excel.create
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
examId | path | 필수 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
fileId | string | 필수 | XLSX를 POST /v1/grading/uploads로 먼저 업로드한 응답 data.id(UUID)입니다. 파일명이나 직접 생성한 UUID가 아닙니다. 첫 시트 머리글은 studentId, 선택적 subjectCode, 문항번호 1, 2 ...이며 최대 100행입니다. | "00000000-0000-4000-8000-000000000001" |
teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요. | 1 |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. teamId로 지정한 응시반에 속한 시간표 번호여야 합니다. | 1 |
examDate | string | 필수 | 응시일입니다. yyyy-MM-dd 형식입니다. | "2026-01-15" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"fileId": {
"type": "string",
"format": "uuid",
"description": "XLSX를 POST /v1/grading/uploads로 먼저 업로드한 응답 data.id(UUID)입니다. 파일명이나 직접 생성한 UUID가 아닙니다. 첫 시트 머리글은 studentId, 선택적 subjectCode, 문항번호 1, 2 ...이며 최대 100행입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. teamId로 지정한 응시반에 속한 시간표 번호여야 합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"examDate": {
"type": "string",
"format": "date",
"description": "응시일입니다. yyyy-MM-dd 형식입니다.",
"nullable": false,
"minLength": 1
}
},
"required": [
"fileId",
"teamId",
"scheduleId",
"examDate"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | string | 필수 | 작업 고유 번호입니다. 같은 작업의 상태 조회와 결과 다운로드에 사용합니다. | "00000000-0000-4000-8000-000000000001" |
kind | string | 필수 | omr·excel·recalculate·report-pdf·wrong-note·link-issue·link-reissue·teaching-report 중 하나입니다. teaching-report는 과제장·누적 성적표 PDF 작업입니다. | "예시" |
status | string | 필수 | queued 대기, running 처리 중, completed 완료, failed 실패, needs_review 결과 확인 필요입니다. 결과 확인 필요 작업은 자동 재실행하지 않습니다. | "예시" |
message | string | 필수 | 사용자에게 표시할 진행 또는 오류 안내입니다. | "예시" |
createdAt | string | 필수 | 작업 생성 시각입니다. UTC입니다. | "2026-01-15T00:00:00Z" |
result | object | 필수 | 완료된 작업의 처리 결과입니다. 미완료이면 null입니다. | 하위 필드·본문 예시 참조 |
result.logId | integer | 필수 | OMR 인식 이력 번호입니다. OMR 외 작업은 0입니다. | 1 |
result.ids | array | 필수 | 신규 등록 또는 수정된 채점 행 번호 배열입니다. | 하위 필드·본문 예시 참조 |
result.examIds | array | 필수 | 처리한 시험 번호 배열입니다. 두 회차는 입력 순서입니다. | 하위 필드·본문 예시 참조 |
result.rows | array | 필수 | OMR 이미지별 인식 결과입니다. | 하위 필드·본문 예시 참조 |
result.rows[].page | integer | 필수 | 입력 이미지의 1부터 시작하는 페이지 순서입니다. | 1 |
result.rows[].studentId | string | 필수 | 인식한 학원 학생 번호입니다. 미식별이면 빈 문자열입니다. | "00000001" |
result.rows[].studentName | string | 필수 | 인식한 학생 이름입니다. 미식별이면 빈 문자열입니다. | "예시 이름" |
result.rows[].marks | array | 필수 | 인식한 답안 원문 배열이며 채점 확정 결과가 아닙니다. 두 회차는 1회차 양식 슬롯 뒤에 2회차 슬롯 순서입니다. 배열 위치로 표시 문항 번호·정오답·점수를 추정하지 말고 저장된 회차별 성적 분석으로 확인하세요. | 하위 필드·본문 예시 참조 |
result.rows[].message | string | 필수 | 이 이미지의 인식 확인 안내입니다. 문제가 없으면 빈 값입니다. | "예시" |
result.errors | array | 필수 | 인식 실패 또는 검수가 필요한 이미지 안내입니다. 이 배열만으로 미저장을 판단하지 마세요. ids의 실제 저장 결과와 요청한 이미지·회차 수를 대조하고 rows의 페이지 번호로 검수 대상을 확인하세요. | 하위 필드·본문 예시 참조 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "작업 고유 번호입니다. 같은 작업의 상태 조회와 결과 다운로드에 사용합니다.",
"nullable": false
},
"kind": {
"type": "string",
"description": "omr·excel·recalculate·report-pdf·wrong-note·link-issue·link-reissue·teaching-report 중 하나입니다. teaching-report는 과제장·누적 성적표 PDF 작업입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "queued 대기, running 처리 중, completed 완료, failed 실패, needs_review 결과 확인 필요입니다. 결과 확인 필요 작업은 자동 재실행하지 않습니다.",
"nullable": false
},
"message": {
"type": "string",
"description": "사용자에게 표시할 진행 또는 오류 안내입니다.",
"nullable": false
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "작업 생성 시각입니다. UTC입니다.",
"nullable": false
},
"result": {
"type": "object",
"properties": {
"logId": {
"type": "integer",
"description": "OMR 인식 이력 번호입니다. OMR 외 작업은 0입니다.",
"nullable": false
},
"ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "신규 등록 또는 수정된 채점 행 번호 배열입니다.",
"nullable": false
},
"examIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "처리한 시험 번호 배열입니다. 두 회차는 입력 순서입니다.",
"nullable": false
},
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"page": {
"type": "integer",
"description": "입력 이미지의 1부터 시작하는 페이지 순서입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "인식한 학원 학생 번호입니다. 미식별이면 빈 문자열입니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "인식한 학생 이름입니다. 미식별이면 빈 문자열입니다.",
"nullable": false
},
"marks": {
"type": "array",
"items": {
"type": "string"
},
"description": "인식한 답안 원문 배열이며 채점 확정 결과가 아닙니다. 두 회차는 1회차 양식 슬롯 뒤에 2회차 슬롯 순서입니다. 배열 위치로 표시 문항 번호·정오답·점수를 추정하지 말고 저장된 회차별 성적 분석으로 확인하세요.",
"nullable": false
},
"message": {
"type": "string",
"description": "이 이미지의 인식 확인 안내입니다. 문제가 없으면 빈 값입니다.",
"nullable": false
}
},
"required": [
"page",
"studentId",
"studentName",
"marks",
"message"
]
},
"description": "OMR 이미지별 인식 결과입니다.",
"nullable": false
},
"errors": {
"type": "array",
"items": {
"type": "string"
},
"description": "인식 실패 또는 검수가 필요한 이미지 안내입니다. 이 배열만으로 미저장을 판단하지 마세요. ids의 실제 저장 결과와 요청한 이미지·회차 수를 대조하고 rows의 페이지 번호로 검수 대상을 확인하세요.",
"nullable": false
}
},
"required": [
"logId",
"ids",
"examIds",
"rows",
"errors"
],
"description": "완료된 작업의 처리 결과입니다. 미완료이면 null입니다.",
"nullable": true
}
},
"required": [
"id",
"kind",
"status",
"message",
"createdAt",
"result"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"fileId": "00000000-0000-4000-8000-000000000001",
"teamId": 1,
"scheduleId": 1,
"examDate": "2026-01-15"
}성공 응답 예시
{
"data": {
"id": "00000000-0000-4000-8000-000000000001",
"kind": "예시",
"status": "예시",
"message": "예시",
"createdAt": "2026-01-15T00:00:00Z",
"result": {
"logId": 1,
"ids": [
1
],
"examIds": [
1
],
"rows": [
{
"page": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"marks": [
"1"
],
"message": "예시"
}
],
"errors": [
"예시"
]
}
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/grading/exams/{examId}/scores채점 점수·답안·코멘트 조회. 오답·보충·만점 대비 비율 분석은 includeAnalysis=true로 서버 판정을 사용. 빈 답안은 실제 무응답으로 단정하지 않고 미식별 학생은 추측하지 않음+
grading.read · grading.scores.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
examId | path | 필수 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다. |
includeAnalysis | query | 선택 | 기본 false. 오답·보충 문항·만점 대비 비율 분석은 true로 조회하여 analysis의 실제 문항 번호·서버 판정을 사용하세요. 저장 점수/답안을 변경하지 않습니다. 긴 시험은 pageSize를 줄이고 전체 페이지 여부를 확인하세요. |
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 채점 행 고유 번호입니다. | 1 |
items[].examId | integer | 필수 | 시험 고유 번호입니다. | 1 |
items[].studentId | string | 필수 | 학생 고유 번호입니다. 미식별 스캔은 빈 값일 수 있습니다. | "00000001" |
items[].studentName | string | 필수 | 학생 이름 또는 스캔에서 읽은 이름입니다. | "예시 이름" |
items[].teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요. | 1 |
items[].scheduleId | integer | 필수 | 응시 시간표 번호입니다. | 1 |
items[].examDate | integer | 필수 | 응시일입니다. yyyyMMdd 정수입니다. | 20260115 |
items[].score | number | 필수 | 현재 채점 점수입니다. | 1 |
items[].comment | string | 필수 | 학생별 성적 개별 코멘트입니다. Tutor_Student_Omr.Etc의 원문입니다. | "예시" |
items[].subjectCode | integer | 필수 | 선택과목 코드입니다. 공통은 0입니다. | 1 |
items[].marks | array | 필수 | 저장 위치 순서의 원문 답안입니다. 배열 인덱스+1을 표시 문항 번호로 추정하지 마세요. 문항별 해석은 includeAnalysis=true의 questions.number·mark·markState·points를 함께 사용하세요. 빈 문자열은 저장 빈 값이며 실제 무응답의 원인을 확정하지 않습니다. | 하위 필드·본문 예시 참조 |
items[].analysis | object | 필수 | includeAnalysis=true일 때의 서버 계산 문항 분석입니다. null은 분석 미요청이며 분석 결과 없음과 다릅니다. | 하위 필드·본문 예시 참조 |
items[].analysis.basis | string | 필수 | 현재 정답·저장 답안으로 계산한 참고 분석입니다. 재채점하거나 저장하지 않습니다. | "예시" |
items[].analysis.maxScore | number | 필수 | 공통과 해당 선택과목의 유효 배점 합계입니다. 선택과목이나 정답이 불확실하면 null입니다. | 1 |
items[].analysis.scorePercent | number | 필수 | 저장 점수÷maxScore×100입니다. 비율의 미만/이하를 구분하세요. 계산 불가이면 null입니다. | 1 |
items[].analysis.recalculatedScore | number | 필수 | 현재 공유 채점 로직으로 계산한 참고 점수입니다. 저장 점수는 덮어쓰지 않습니다. 답안 누락 등이 있으면 null입니다. | 1 |
items[].analysis.matchesStoredScore | boolean | 필수 | 참고 점수와 저장 점수가 일치하는지입니다. 불일치하면 정답 변경 등의 가능성을 안내하고 재채점 완료로 설명하지 마세요. | false |
items[].analysis.correctQuestions | array | 필수 | 배점 전부를 받은 실제 문항 번호입니다. 배열 위치로 문항 번호를 만들지 마세요. | 하위 필드·본문 예시 참조 |
items[].analysis.incorrectQuestions | array | 필수 | 입력된 답안이 있으나 0점인 실제 문항 번호입니다. 빈 값·미저장·대상 외 문항은 포함하지 않습니다. | 하위 필드·본문 예시 참조 |
items[].analysis.partialQuestions | array | 필수 | 0점 초과·배점 미만인 부분 점수 문항 번호입니다. | 하위 필드·본문 예시 참조 |
items[].analysis.blankQuestions | array | 필수 | 저장 답안이 빈 값인 문항 번호입니다. 실제 무응답인지 입력/인식 누락인지는 확정할 수 없습니다. 모두 정답 처리 문항과 겹칠 수 있습니다. | 하위 필드·본문 예시 참조 |
items[].analysis.missingQuestions | array | 필수 | 저장 배열에 위치 자체가 없는 문항 번호입니다. 빈 값이나 오답으로 단정하지 않습니다. | 하위 필드·본문 예시 참조 |
items[].analysis.questions | array | 필수 | 과목·배점에 따른 대상 외 문항을 포함한 명시적 문항 번호·답안·상태·배점·득점입니다. | 하위 필드·본문 예시 참조 |
items[].analysis.questions[].sequence | integer | 필수 | 저장 답안의 1부터 시작하는 위치입니다. 표시 문항 번호와 다릅니다. | 1 |
items[].analysis.questions[].number | string | 필수 | 정답 자료의 실제 문항 번호입니다. 위치에서 번호를 재생성하지 않습니다. | "예시" |
items[].analysis.questions[].subjectCode | integer | 필수 | 선택과목 코드입니다. 0은 공통입니다. | 1 |
items[].analysis.questions[].mark | string | 필수 | 저장 답안 원문입니다. 위치가 없을 때만 null입니다. | "1" |
items[].analysis.questions[].markState | string | 필수 | present=입력 있음, blank=저장 빈 값, missing=위치 미저장입니다. | "예시" |
items[].analysis.questions[].outcome | string | 필수 | full_credit=배점 전부, partial_credit=부분점수, zero_credit=0점, excluded=대상 외, unavailable=판정 불가입니다. 빈 값과 오답을 혼동하지 마세요. | "예시" |
items[].analysis.questions[].weight | number | 필수 | 문항 배점입니다. 배점 0은 채점 대상 외입니다. | 1 |
items[].analysis.questions[].points | number | 필수 | 현재 공유 채점 로직의 참고 득점입니다. 대상 외·누락·판정 불가이면 null입니다. | 1 |
items[].analysis.warnings | array | 필수 | 분석 시 주의점입니다. 빈 값의 원인·미식별 학생·점수 차이를 추측으로 채우지 마세요. | 하위 필드·본문 예시 참조 |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "채점 행 고유 번호입니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "시험 고유 번호입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "학생 고유 번호입니다. 미식별 스캔은 빈 값일 수 있습니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 이름 또는 스캔에서 읽은 이름입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요.",
"nullable": false
},
"scheduleId": {
"type": "integer",
"description": "응시 시간표 번호입니다.",
"nullable": false
},
"examDate": {
"type": "integer",
"description": "응시일입니다. yyyyMMdd 정수입니다.",
"nullable": false
},
"score": {
"type": "number",
"description": "현재 채점 점수입니다.",
"nullable": false
},
"comment": {
"type": "string",
"description": "학생별 성적 개별 코멘트입니다. Tutor_Student_Omr.Etc의 원문입니다.",
"nullable": false
},
"subjectCode": {
"type": "integer",
"description": "선택과목 코드입니다. 공통은 0입니다.",
"nullable": false
},
"marks": {
"type": "array",
"items": {
"type": "string"
},
"description": "저장 위치 순서의 원문 답안입니다. 배열 인덱스+1을 표시 문항 번호로 추정하지 마세요. 문항별 해석은 includeAnalysis=true의 questions.number·mark·markState·points를 함께 사용하세요. 빈 문자열은 저장 빈 값이며 실제 무응답의 원인을 확정하지 않습니다.",
"nullable": false
},
"analysis": {
"type": "object",
"properties": {
"basis": {
"type": "string",
"description": "현재 정답·저장 답안으로 계산한 참고 분석입니다. 재채점하거나 저장하지 않습니다.",
"nullable": false
},
"maxScore": {
"type": "number",
"description": "공통과 해당 선택과목의 유효 배점 합계입니다. 선택과목이나 정답이 불확실하면 null입니다.",
"nullable": true
},
"scorePercent": {
"type": "number",
"description": "저장 점수÷maxScore×100입니다. 비율의 미만/이하를 구분하세요. 계산 불가이면 null입니다.",
"nullable": true
},
"recalculatedScore": {
"type": "number",
"description": "현재 공유 채점 로직으로 계산한 참고 점수입니다. 저장 점수는 덮어쓰지 않습니다. 답안 누락 등이 있으면 null입니다.",
"nullable": true
},
"matchesStoredScore": {
"type": "boolean",
"description": "참고 점수와 저장 점수가 일치하는지입니다. 불일치하면 정답 변경 등의 가능성을 안내하고 재채점 완료로 설명하지 마세요.",
"nullable": true
},
"correctQuestions": {
"type": "array",
"items": {
"type": "string"
},
"description": "배점 전부를 받은 실제 문항 번호입니다. 배열 위치로 문항 번호를 만들지 마세요.",
"nullable": false
},
"incorrectQuestions": {
"type": "array",
"items": {
"type": "string"
},
"description": "입력된 답안이 있으나 0점인 실제 문항 번호입니다. 빈 값·미저장·대상 외 문항은 포함하지 않습니다.",
"nullable": false
},
"partialQuestions": {
"type": "array",
"items": {
"type": "string"
},
"description": "0점 초과·배점 미만인 부분 점수 문항 번호입니다.",
"nullable": false
},
"blankQuestions": {
"type": "array",
"items": {
"type": "string"
},
"description": "저장 답안이 빈 값인 문항 번호입니다. 실제 무응답인지 입력/인식 누락인지는 확정할 수 없습니다. 모두 정답 처리 문항과 겹칠 수 있습니다.",
"nullable": false
},
"missingQuestions": {
"type": "array",
"items": {
"type": "string"
},
"description": "저장 배열에 위치 자체가 없는 문항 번호입니다. 빈 값이나 오답으로 단정하지 않습니다.",
"nullable": false
},
"questions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"sequence": {
"type": "integer",
"description": "저장 답안의 1부터 시작하는 위치입니다. 표시 문항 번호와 다릅니다.",
"nullable": false
},
"number": {
"type": "string",
"description": "정답 자료의 실제 문항 번호입니다. 위치에서 번호를 재생성하지 않습니다.",
"nullable": false
},
"subjectCode": {
"type": "integer",
"description": "선택과목 코드입니다. 0은 공통입니다.",
"nullable": false
},
"mark": {
"type": "string",
"description": "저장 답안 원문입니다. 위치가 없을 때만 null입니다.",
"nullable": true
},
"markState": {
"type": "string",
"description": "present=입력 있음, blank=저장 빈 값, missing=위치 미저장입니다.",
"nullable": false
},
"outcome": {
"type": "string",
"description": "full_credit=배점 전부, partial_credit=부분점수, zero_credit=0점, excluded=대상 외, unavailable=판정 불가입니다. 빈 값과 오답을 혼동하지 마세요.",
"nullable": false
},
"weight": {
"type": "number",
"description": "문항 배점입니다. 배점 0은 채점 대상 외입니다.",
"nullable": false
},
"points": {
"type": "number",
"description": "현재 공유 채점 로직의 참고 득점입니다. 대상 외·누락·판정 불가이면 null입니다.",
"nullable": true
}
},
"required": [
"sequence",
"number",
"subjectCode",
"mark",
"markState",
"outcome",
"weight",
"points"
]
},
"description": "과목·배점에 따른 대상 외 문항을 포함한 명시적 문항 번호·답안·상태·배점·득점입니다.",
"nullable": false
},
"warnings": {
"type": "array",
"items": {
"type": "string"
},
"description": "분석 시 주의점입니다. 빈 값의 원인·미식별 학생·점수 차이를 추측으로 채우지 마세요.",
"nullable": false
}
},
"required": [
"basis",
"maxScore",
"scorePercent",
"recalculatedScore",
"matchesStoredScore",
"correctQuestions",
"incorrectQuestions",
"partialQuestions",
"blankQuestions",
"missingQuestions",
"questions",
"warnings"
],
"description": "includeAnalysis=true일 때의 서버 계산 문항 분석입니다. null은 분석 미요청이며 분석 결과 없음과 다릅니다.",
"nullable": true
}
},
"required": [
"id",
"examId",
"studentId",
"studentName",
"teamId",
"scheduleId",
"examDate",
"score",
"comment",
"subjectCode",
"marks",
"analysis"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"id": 1,
"examId": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"teamId": 1,
"scheduleId": 1,
"examDate": 20260115,
"score": 1,
"comment": "예시",
"subjectCode": 1,
"marks": [
"1"
],
"analysis": {
"basis": "예시",
"maxScore": 1,
"scorePercent": 1,
"recalculatedScore": 1,
"matchesStoredScore": false,
"correctQuestions": [
"예시"
],
"incorrectQuestions": [
"예시"
],
"partialQuestions": [
"예시"
],
"blankQuestions": [
"예시"
],
"missingQuestions": [
"예시"
],
"questions": [
{
"sequence": 1,
"number": "예시",
"subjectCode": 1,
"mark": "1",
"markState": "예시",
"outcome": "예시",
"weight": 1,
"points": 1
}
],
"warnings": [
"예시"
]
}
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/grading/exams/{examId}/scores기존 시험에 학생 수기·엑셀 답안 채점·저장(결과는 학생별 번호 배열)+
grading.write · grading.scores.create
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
examId | path | 필수 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
examDate | string | 필수 | 응시일입니다. yyyy-MM-dd 형식입니다. | "2026-01-15" |
teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요. | 1 |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 응시반에 속한 시간표 번호입니다. | 1 |
rows | array | 필수 | 처리할 학생 답안입니다. 전체 행을 검증한 뒤 하나의 트랜잭션으로 저장합니다. | 하위 필드·본문 예시 참조 |
rows[].id | integer | 조건부·선택 | 기존 채점 행 번호입니다. 신규 등록은 0이며 수정은 대상 시험의 행 번호를 지정합니다. | 0 |
rows[].studentId | string | 필수 | 등록된 학생 고유 번호입니다. 기존 미식별 채점 행 수정은 빈 문자열로 학생 연결·인식 이름을 보존합니다. 신규 등록에는 같은 학원 학생 번호가 필수이며 기존 학생 연결을 빈 값으로 해제할 수 없습니다. | "00000001" |
rows[].subjectCode | integer | 조건부·선택 | 선택과목 코드입니다. 공통은 0입니다. | 0 |
rows[].marks | array | 필수 | 정답지 문항 순서대로 학생 답안을 입력합니다. 빈 문자열은 무응답입니다. | 하위 필드·본문 예시 참조 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"examDate": {
"type": "string",
"format": "date",
"description": "응시일입니다. yyyy-MM-dd 형식입니다.",
"nullable": false,
"minLength": 1
},
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 응시반에 속한 시간표 번호입니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "기존 채점 행 번호입니다. 신규 등록은 0이며 수정은 대상 시험의 행 번호를 지정합니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"studentId": {
"type": "string",
"description": "등록된 학생 고유 번호입니다. 기존 미식별 채점 행 수정은 빈 문자열로 학생 연결·인식 이름을 보존합니다. 신규 등록에는 같은 학원 학생 번호가 필수이며 기존 학생 연결을 빈 값으로 해제할 수 없습니다.",
"nullable": false,
"maxLength": 30
},
"subjectCode": {
"type": "integer",
"description": "선택과목 코드입니다. 공통은 0입니다.",
"nullable": false,
"minimum": 0,
"maximum": 99,
"default": 0
},
"marks": {
"type": "array",
"items": {
"type": "string"
},
"description": "정답지 문항 순서대로 학생 답안을 입력합니다. 빈 문자열은 무응답입니다.",
"nullable": false,
"minItems": 1,
"maxItems": 400
}
},
"required": [
"studentId",
"marks"
]
},
"description": "처리할 학생 답안입니다. 전체 행을 검증한 뒤 하나의 트랜잭션으로 저장합니다.",
"nullable": false,
"minItems": 1,
"maxItems": 100
}
},
"required": [
"examDate",
"teamId",
"scheduleId",
"rows"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"examDate": "2026-01-15",
"teamId": 1,
"scheduleId": 1,
"rows": [
{
"id": 0,
"studentId": "00000001",
"subjectCode": 0,
"marks": [
"1"
]
}
]
}성공 응답 예시
{
"data": [
{
"id": "1"
}
],
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/grading/exams/{examId}/scores개별·일괄 기존 채점 답안 수정 및 재채점. 기존 미식별 답안은 행 id와 빈 studentId로 학생 연결·인식 이름을 보존하며 수정. 정답지와 원본 marks 전체를 조회해 요청하지 않은 답안은 유지+
grading.write · grading.scores.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
examId | path | 필수 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
examDate | string | 필수 | 응시일입니다. yyyy-MM-dd 형식입니다. | "2026-01-15" |
teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요. | 1 |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 응시반에 속한 시간표 번호입니다. | 1 |
rows | array | 필수 | 처리할 학생 답안입니다. 전체 행을 검증한 뒤 하나의 트랜잭션으로 저장합니다. | 하위 필드·본문 예시 참조 |
rows[].id | integer | 조건부·선택 | 기존 채점 행 번호입니다. 신규 등록은 0이며 수정은 대상 시험의 행 번호를 지정합니다. | 0 |
rows[].studentId | string | 필수 | 등록된 학생 고유 번호입니다. 기존 미식별 채점 행 수정은 빈 문자열로 학생 연결·인식 이름을 보존합니다. 신규 등록에는 같은 학원 학생 번호가 필수이며 기존 학생 연결을 빈 값으로 해제할 수 없습니다. | "00000001" |
rows[].subjectCode | integer | 조건부·선택 | 선택과목 코드입니다. 공통은 0입니다. | 0 |
rows[].marks | array | 필수 | 정답지 문항 순서대로 학생 답안을 입력합니다. 빈 문자열은 무응답입니다. | 하위 필드·본문 예시 참조 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"examDate": {
"type": "string",
"format": "date",
"description": "응시일입니다. yyyy-MM-dd 형식입니다.",
"nullable": false,
"minLength": 1
},
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 응시반에 속한 시간표 번호입니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "기존 채점 행 번호입니다. 신규 등록은 0이며 수정은 대상 시험의 행 번호를 지정합니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"studentId": {
"type": "string",
"description": "등록된 학생 고유 번호입니다. 기존 미식별 채점 행 수정은 빈 문자열로 학생 연결·인식 이름을 보존합니다. 신규 등록에는 같은 학원 학생 번호가 필수이며 기존 학생 연결을 빈 값으로 해제할 수 없습니다.",
"nullable": false,
"maxLength": 30
},
"subjectCode": {
"type": "integer",
"description": "선택과목 코드입니다. 공통은 0입니다.",
"nullable": false,
"minimum": 0,
"maximum": 99,
"default": 0
},
"marks": {
"type": "array",
"items": {
"type": "string"
},
"description": "정답지 문항 순서대로 학생 답안을 입력합니다. 빈 문자열은 무응답입니다.",
"nullable": false,
"minItems": 1,
"maxItems": 400
}
},
"required": [
"studentId",
"marks"
]
},
"description": "처리할 학생 답안입니다. 전체 행을 검증한 뒤 하나의 트랜잭션으로 저장합니다.",
"nullable": false,
"minItems": 1,
"maxItems": 100
}
},
"required": [
"examDate",
"teamId",
"scheduleId",
"rows"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"examDate": "2026-01-15",
"teamId": 1,
"scheduleId": 1,
"rows": [
{
"id": 0,
"studentId": "00000001",
"subjectCode": 0,
"marks": [
"1"
]
}
]
}성공 응답 예시
{
"data": [
{
"id": "1"
}
],
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/grading/exams/{examId}/scores/{scoreId}채점 행 삭제+
grading.write · grading.scores.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
examId | path | 필수 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다. |
scoreId | path | 필수 | GET /v1/grading/exams/{examId}/scores 응답 data.items[].id의 채점 행 번호입니다. 학생 번호와 다릅니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}PATCH/v1/grading/exams/{examId}/scores/{scoreId}/comment학생별 성적 개별 코멘트 저장+
grading.write · grading.scores.comment
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
examId | path | 필수 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다. |
scoreId | path | 필수 | GET /v1/grading/exams/{examId}/scores 응답 data.items[].id의 채점 행 번호입니다. 학생 번호와 다릅니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
comment | string | 조건부·선택 | 학생별 성적 개별 코멘트입니다. 빈 문자열이면 코멘트를 비웁니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"comment": {
"type": "string",
"description": "학생별 성적 개별 코멘트입니다. 빈 문자열이면 코멘트를 비웁니다.",
"nullable": false,
"maxLength": 10000,
"default": ""
}
}
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"comment": "예시"
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/grading/recalculation-jobs정답 변경 후 점수·통계 재계산 작업 생성+
grading.write · grading.recalculate.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
examIds | array | 필수 | 정답지 변경 후 점수와 통계를 재계산할 시험 번호 배열입니다. 최대 20개이며 중복은 허용하지 않습니다. | 하위 필드·본문 예시 참조 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"examIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "정답지 변경 후 점수와 통계를 재계산할 시험 번호 배열입니다. 최대 20개이며 중복은 허용하지 않습니다.",
"nullable": false,
"minItems": 1,
"maxItems": 20
}
},
"required": [
"examIds"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | string | 필수 | 작업 고유 번호입니다. 같은 작업의 상태 조회와 결과 다운로드에 사용합니다. | "00000000-0000-4000-8000-000000000001" |
kind | string | 필수 | omr·excel·recalculate·report-pdf·wrong-note·link-issue·link-reissue·teaching-report 중 하나입니다. teaching-report는 과제장·누적 성적표 PDF 작업입니다. | "예시" |
status | string | 필수 | queued 대기, running 처리 중, completed 완료, failed 실패, needs_review 결과 확인 필요입니다. 결과 확인 필요 작업은 자동 재실행하지 않습니다. | "예시" |
message | string | 필수 | 사용자에게 표시할 진행 또는 오류 안내입니다. | "예시" |
createdAt | string | 필수 | 작업 생성 시각입니다. UTC입니다. | "2026-01-15T00:00:00Z" |
result | object | 필수 | 완료된 작업의 처리 결과입니다. 미완료이면 null입니다. | 하위 필드·본문 예시 참조 |
result.logId | integer | 필수 | OMR 인식 이력 번호입니다. OMR 외 작업은 0입니다. | 1 |
result.ids | array | 필수 | 신규 등록 또는 수정된 채점 행 번호 배열입니다. | 하위 필드·본문 예시 참조 |
result.examIds | array | 필수 | 처리한 시험 번호 배열입니다. 두 회차는 입력 순서입니다. | 하위 필드·본문 예시 참조 |
result.rows | array | 필수 | OMR 이미지별 인식 결과입니다. | 하위 필드·본문 예시 참조 |
result.rows[].page | integer | 필수 | 입력 이미지의 1부터 시작하는 페이지 순서입니다. | 1 |
result.rows[].studentId | string | 필수 | 인식한 학원 학생 번호입니다. 미식별이면 빈 문자열입니다. | "00000001" |
result.rows[].studentName | string | 필수 | 인식한 학생 이름입니다. 미식별이면 빈 문자열입니다. | "예시 이름" |
result.rows[].marks | array | 필수 | 인식한 답안 원문 배열이며 채점 확정 결과가 아닙니다. 두 회차는 1회차 양식 슬롯 뒤에 2회차 슬롯 순서입니다. 배열 위치로 표시 문항 번호·정오답·점수를 추정하지 말고 저장된 회차별 성적 분석으로 확인하세요. | 하위 필드·본문 예시 참조 |
result.rows[].message | string | 필수 | 이 이미지의 인식 확인 안내입니다. 문제가 없으면 빈 값입니다. | "예시" |
result.errors | array | 필수 | 인식 실패 또는 검수가 필요한 이미지 안내입니다. 이 배열만으로 미저장을 판단하지 마세요. ids의 실제 저장 결과와 요청한 이미지·회차 수를 대조하고 rows의 페이지 번호로 검수 대상을 확인하세요. | 하위 필드·본문 예시 참조 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "작업 고유 번호입니다. 같은 작업의 상태 조회와 결과 다운로드에 사용합니다.",
"nullable": false
},
"kind": {
"type": "string",
"description": "omr·excel·recalculate·report-pdf·wrong-note·link-issue·link-reissue·teaching-report 중 하나입니다. teaching-report는 과제장·누적 성적표 PDF 작업입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "queued 대기, running 처리 중, completed 완료, failed 실패, needs_review 결과 확인 필요입니다. 결과 확인 필요 작업은 자동 재실행하지 않습니다.",
"nullable": false
},
"message": {
"type": "string",
"description": "사용자에게 표시할 진행 또는 오류 안내입니다.",
"nullable": false
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "작업 생성 시각입니다. UTC입니다.",
"nullable": false
},
"result": {
"type": "object",
"properties": {
"logId": {
"type": "integer",
"description": "OMR 인식 이력 번호입니다. OMR 외 작업은 0입니다.",
"nullable": false
},
"ids": {
"type": "array",
"items": {
"type": "integer"
},
"description": "신규 등록 또는 수정된 채점 행 번호 배열입니다.",
"nullable": false
},
"examIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "처리한 시험 번호 배열입니다. 두 회차는 입력 순서입니다.",
"nullable": false
},
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"page": {
"type": "integer",
"description": "입력 이미지의 1부터 시작하는 페이지 순서입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "인식한 학원 학생 번호입니다. 미식별이면 빈 문자열입니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "인식한 학생 이름입니다. 미식별이면 빈 문자열입니다.",
"nullable": false
},
"marks": {
"type": "array",
"items": {
"type": "string"
},
"description": "인식한 답안 원문 배열이며 채점 확정 결과가 아닙니다. 두 회차는 1회차 양식 슬롯 뒤에 2회차 슬롯 순서입니다. 배열 위치로 표시 문항 번호·정오답·점수를 추정하지 말고 저장된 회차별 성적 분석으로 확인하세요.",
"nullable": false
},
"message": {
"type": "string",
"description": "이 이미지의 인식 확인 안내입니다. 문제가 없으면 빈 값입니다.",
"nullable": false
}
},
"required": [
"page",
"studentId",
"studentName",
"marks",
"message"
]
},
"description": "OMR 이미지별 인식 결과입니다.",
"nullable": false
},
"errors": {
"type": "array",
"items": {
"type": "string"
},
"description": "인식 실패 또는 검수가 필요한 이미지 안내입니다. 이 배열만으로 미저장을 판단하지 마세요. ids의 실제 저장 결과와 요청한 이미지·회차 수를 대조하고 rows의 페이지 번호로 검수 대상을 확인하세요.",
"nullable": false
}
},
"required": [
"logId",
"ids",
"examIds",
"rows",
"errors"
],
"description": "완료된 작업의 처리 결과입니다. 미완료이면 null입니다.",
"nullable": true
}
},
"required": [
"id",
"kind",
"status",
"message",
"createdAt",
"result"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"examIds": [
1
]
}성공 응답 예시
{
"data": {
"id": "00000000-0000-4000-8000-000000000001",
"kind": "예시",
"status": "예시",
"message": "예시",
"createdAt": "2026-01-15T00:00:00Z",
"result": {
"logId": 1,
"ids": [
1
],
"examIds": [
1
],
"rows": [
{
"page": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"marks": [
"1"
],
"message": "예시"
}
],
"errors": [
"예시"
]
}
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/grading/exams/{examId}/missing-submissions미제출 명단 조회(재시험은 지정 응시대상, 통합은 두 시험 모두 성적 없음)+
grading.read · grading.missing-submissions.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
examId | path | 필수 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다. |
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
otherExamId | query | 선택 | 미제출 통합 조회의 두 번째 정답지 examId입니다. 0 또는 생략하면 단일 회차이며 두 시험 모두 성적이 없는 학생을 조회합니다. |
scheduleId | query | 선택 | GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
isRetest | boolean | 필수 | 재시험 지정 응시대상 기준인지 나타냅니다. | false |
items | array | 필수 | 학생번호별 중복을 제외한 미제출 학생입니다. 통합 조회는 두 시험 모두 성적이 없는 학생입니다. | 하위 필드·본문 예시 참조 |
items[].studentId | string | 조건부·선택 | 학원 학생번호입니다. | "00000001" |
items[].studentName | string | 조건부·선택 | 학생 성명입니다. | "예시 이름" |
items[].schoolName | string | 조건부·선택 | 학교명입니다. | "예시 이름" |
items[].gradeName | string | 조건부·선택 | 학년입니다. | "예시 이름" |
items[].teamName | string | 조건부·선택 | 수강반명입니다. | "예시 이름" |
total | integer | 필수 | 전체 미제출 학생 수입니다. | 1 |
page | integer | 필수 | 조회한 페이지(1부터)입니다. | 1 |
pageSize | integer | 필수 | 페이지당 학생 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"isRetest": {
"type": "boolean",
"description": "재시험 지정 응시대상 기준인지 나타냅니다.",
"nullable": false
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "학원 학생번호입니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "학생 성명입니다.",
"nullable": false
},
"schoolName": {
"type": "string",
"description": "학교명입니다.",
"nullable": false
},
"gradeName": {
"type": "string",
"description": "학년입니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "수강반명입니다.",
"nullable": false
}
}
},
"description": "학생번호별 중복을 제외한 미제출 학생입니다. 통합 조회는 두 시험 모두 성적이 없는 학생입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "전체 미제출 학생 수입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "조회한 페이지(1부터)입니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "페이지당 학생 수입니다.",
"nullable": false
}
},
"required": [
"isRetest",
"items",
"total",
"page",
"pageSize"
]
}성공 응답 예시
{
"data": {
"isRetest": false,
"items": [
{
"studentId": "00000001",
"studentName": "예시 이름",
"schoolName": "예시 이름",
"gradeName": "예시 이름",
"teamName": "예시 이름"
}
],
"total": 1,
"page": 1,
"pageSize": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/grading/online-exams등록된 온라인 과제·재시험 조회(온라인 번호·구분·진행 상태)+
grading.read · grading.online-exams.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
search | query | 선택 | 검색어입니다. 최대 100자이며 생략하면 전체를 조회합니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].onlineExamId | integer | 필수 | 온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다. | 1 |
items[].examId | integer | 필수 | 채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다. | 1 |
items[].title | string | 필수 | 온라인 시험 제목입니다. | "예시" |
items[].kind | string | 필수 | 시험 구분: retest 재시험, homework 과제입니다. | "예시" |
items[].status | string | 필수 | unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다. | "예시" |
items[].studentTargetCount | integer | 필수 | 개별 지정 응시 등록 수입니다. | 1 |
items[].classTargetCount | integer | 필수 | 지정한 수강 시간표 수입니다. | 1 |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"onlineExamId": {
"type": "integer",
"description": "온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "온라인 시험 제목입니다.",
"nullable": false
},
"kind": {
"type": "string",
"description": "시험 구분: retest 재시험, homework 과제입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다.",
"nullable": false
},
"studentTargetCount": {
"type": "integer",
"description": "개별 지정 응시 등록 수입니다.",
"nullable": false
},
"classTargetCount": {
"type": "integer",
"description": "지정한 수강 시간표 수입니다.",
"nullable": false
}
},
"required": [
"onlineExamId",
"examId",
"title",
"kind",
"status",
"studentTargetCount",
"classTargetCount"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"onlineExamId": 1,
"examId": 1,
"title": "예시",
"kind": "예시",
"status": "예시",
"studentTargetCount": 1,
"classTargetCount": 1
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/grading/online-exams/{onlineExamId}온라인 시험 구분·응시대상 설정 현황+
grading.read · grading.online-exams.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
onlineExamId | path | 필수 | GET /v1/grading/online-exams의 onlineExamId입니다. 정답지 examId나 학생 응시 등록 번호와 다릅니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
onlineExamId | integer | 필수 | 온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다. | 1 |
examId | integer | 필수 | 채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다. | 1 |
title | string | 필수 | 온라인 시험 제목입니다. | "예시" |
kind | string | 필수 | 시험 구분: retest 재시험, homework 과제입니다. | "예시" |
status | string | 필수 | unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다. | "예시" |
studentTargetCount | integer | 필수 | 개별 지정 응시 등록 수입니다. | 1 |
classTargetCount | integer | 필수 | 지정한 수강 시간표 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"onlineExamId": {
"type": "integer",
"description": "온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "온라인 시험 제목입니다.",
"nullable": false
},
"kind": {
"type": "string",
"description": "시험 구분: retest 재시험, homework 과제입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다.",
"nullable": false
},
"studentTargetCount": {
"type": "integer",
"description": "개별 지정 응시 등록 수입니다.",
"nullable": false
},
"classTargetCount": {
"type": "integer",
"description": "지정한 수강 시간표 수입니다.",
"nullable": false
}
},
"required": [
"onlineExamId",
"examId",
"title",
"kind",
"status",
"studentTargetCount",
"classTargetCount"
]
}성공 응답 예시
{
"data": {
"onlineExamId": 1,
"examId": 1,
"title": "예시",
"kind": "예시",
"status": "예시",
"studentTargetCount": 1,
"classTargetCount": 1
},
"meta": {
"requestId": "example-request-id"
}
}PATCH/v1/grading/online-exams/{onlineExamId}/kind온라인 시험 구분 변경(연결된 재시험은 먼저 연결 해제)+
grading.write · grading.online-exams.kind
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
onlineExamId | path | 필수 | GET /v1/grading/online-exams의 onlineExamId입니다. 정답지 examId나 학생 응시 등록 번호와 다릅니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
kind | string | 조건부·선택 | 시험 구분: retest 또는 homework를 지정합니다. | "retest" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"kind": {
"type": "string",
"description": "시험 구분: retest 또는 homework를 지정합니다.",
"nullable": false,
"default": "retest"
}
}
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
onlineExamId | integer | 필수 | 온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다. | 1 |
examId | integer | 필수 | 채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다. | 1 |
title | string | 필수 | 온라인 시험 제목입니다. | "예시" |
kind | string | 필수 | 시험 구분: retest 재시험, homework 과제입니다. | "예시" |
status | string | 필수 | unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다. | "예시" |
studentTargetCount | integer | 필수 | 개별 지정 응시 등록 수입니다. | 1 |
classTargetCount | integer | 필수 | 지정한 수강 시간표 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"onlineExamId": {
"type": "integer",
"description": "온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "온라인 시험 제목입니다.",
"nullable": false
},
"kind": {
"type": "string",
"description": "시험 구분: retest 재시험, homework 과제입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다.",
"nullable": false
},
"studentTargetCount": {
"type": "integer",
"description": "개별 지정 응시 등록 수입니다.",
"nullable": false
},
"classTargetCount": {
"type": "integer",
"description": "지정한 수강 시간표 수입니다.",
"nullable": false
}
},
"required": [
"onlineExamId",
"examId",
"title",
"kind",
"status",
"studentTargetCount",
"classTargetCount"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"kind": "retest"
}성공 응답 예시
{
"data": {
"onlineExamId": 1,
"examId": 1,
"title": "예시",
"kind": "예시",
"status": "예시",
"studentTargetCount": 1,
"classTargetCount": 1
},
"meta": {
"requestId": "example-request-id"
}
}수업관리
GET/v1/teaching/teams/{id}/report-settings반별 과제장 성적표 저장값·실제 적용 양식·이름·version 조회(미지정 0 등은 당일형 80, 82는 누적형)웹 관리 기능+
웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요teaching.read · teaching.reports.settings.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | 대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
teamId | integer | 필수 | 수강반 번호입니다. | 1 |
teamName | string | 필수 | 실제 수강반 이름입니다. | "예시 이름" |
class | string | 필수 | 저장된 과제장 분류입니다. | "예시" |
group | string | 필수 | 저장된 교과 그룹입니다. | "예시" |
apiFlag | integer | 필수 | 수강반의 저장된 과제장 사용 구분입니다. | 1 |
report | integer | 필수 | 현재 과제장 성적표 양식 번호입니다. 0은 미설정 값입니다. | 1 |
version | string | 필수 | 변경 전 다시 확인해야 하는 현재 설정의 검증 값입니다. | "예시" |
effectiveReport | integer | 필수 | 실제 적용되는 과제장 성적표 양식입니다. 82는 누적형이며, 미지정 0을 포함한 나머지는 관리자 화면과 동일한 당일형 80입니다. 저장된 report는 바꾸지 않습니다. | 1 |
storedReportName | string | 필수 | 저장된 양식의 이름입니다. 0은 미지정이며, 미지정 상태에서도 실제 적용 양식은 당일형입니다. | "예시 이름" |
reportName | string | 필수 | 실제 적용 양식 이름입니다. 당일형 또는 누적형입니다. | "예시 이름" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"teamId": {
"type": "integer",
"description": "수강반 번호입니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "실제 수강반 이름입니다.",
"nullable": false
},
"class": {
"type": "string",
"description": "저장된 과제장 분류입니다.",
"nullable": false
},
"group": {
"type": "string",
"description": "저장된 교과 그룹입니다.",
"nullable": false
},
"apiFlag": {
"type": "integer",
"description": "수강반의 저장된 과제장 사용 구분입니다.",
"nullable": false
},
"report": {
"type": "integer",
"description": "현재 과제장 성적표 양식 번호입니다. 0은 미설정 값입니다.",
"nullable": false
},
"version": {
"type": "string",
"description": "변경 전 다시 확인해야 하는 현재 설정의 검증 값입니다.",
"nullable": false
},
"effectiveReport": {
"type": "integer",
"description": "실제 적용되는 과제장 성적표 양식입니다. 82는 누적형이며, 미지정 0을 포함한 나머지는 관리자 화면과 동일한 당일형 80입니다. 저장된 report는 바꾸지 않습니다.",
"nullable": false
},
"storedReportName": {
"type": "string",
"description": "저장된 양식의 이름입니다. 0은 미지정이며, 미지정 상태에서도 실제 적용 양식은 당일형입니다.",
"nullable": false
},
"reportName": {
"type": "string",
"description": "실제 적용 양식 이름입니다. 당일형 또는 누적형입니다.",
"nullable": false
}
},
"required": [
"teamId",
"teamName",
"class",
"group",
"apiFlag",
"report",
"version",
"effectiveReport",
"storedReportName",
"reportName"
]
}성공 응답 예시
{
"data": {
"teamId": 1,
"teamName": "예시 이름",
"class": "예시",
"group": "예시",
"apiFlag": 1,
"report": 1,
"version": "예시",
"effectiveReport": 1,
"storedReportName": "예시 이름",
"reportName": "예시 이름"
},
"meta": {
"requestId": "example-request-id"
}
}PATCH/v1/teaching/teams/{id}/report-settings반별 과제장 성적표를 당일형 80/누적형 82로 변경(현재 version 확인·다른 반 설정 보존)웹 관리 기능+
웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요teaching.write · teaching.reports.settings.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | 대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
version | string | 필수 | 설정 조회에서 받은 현재 version입니다. 임의 생성하지 않습니다. | "예시" |
report | integer | 조건부·선택 | 화면에서 지원하는 성적표 양식 80 또는 82입니다. | 1 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"version": {
"type": "string",
"description": "설정 조회에서 받은 현재 version입니다. 임의 생성하지 않습니다.",
"nullable": false,
"maxLength": 64,
"minLength": 1
},
"report": {
"type": "integer",
"description": "화면에서 지원하는 성적표 양식 80 또는 82입니다.",
"nullable": false,
"default": 0
}
},
"required": [
"version"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
teamId | integer | 필수 | 수강반 번호입니다. | 1 |
teamName | string | 필수 | 실제 수강반 이름입니다. | "예시 이름" |
class | string | 필수 | 저장된 과제장 분류입니다. | "예시" |
group | string | 필수 | 저장된 교과 그룹입니다. | "예시" |
apiFlag | integer | 필수 | 수강반의 저장된 과제장 사용 구분입니다. | 1 |
report | integer | 필수 | 현재 과제장 성적표 양식 번호입니다. 0은 미설정 값입니다. | 1 |
version | string | 필수 | 변경 전 다시 확인해야 하는 현재 설정의 검증 값입니다. | "예시" |
effectiveReport | integer | 필수 | 실제 적용되는 과제장 성적표 양식입니다. 82는 누적형이며, 미지정 0을 포함한 나머지는 관리자 화면과 동일한 당일형 80입니다. 저장된 report는 바꾸지 않습니다. | 1 |
storedReportName | string | 필수 | 저장된 양식의 이름입니다. 0은 미지정이며, 미지정 상태에서도 실제 적용 양식은 당일형입니다. | "예시 이름" |
reportName | string | 필수 | 실제 적용 양식 이름입니다. 당일형 또는 누적형입니다. | "예시 이름" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"teamId": {
"type": "integer",
"description": "수강반 번호입니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "실제 수강반 이름입니다.",
"nullable": false
},
"class": {
"type": "string",
"description": "저장된 과제장 분류입니다.",
"nullable": false
},
"group": {
"type": "string",
"description": "저장된 교과 그룹입니다.",
"nullable": false
},
"apiFlag": {
"type": "integer",
"description": "수강반의 저장된 과제장 사용 구분입니다.",
"nullable": false
},
"report": {
"type": "integer",
"description": "현재 과제장 성적표 양식 번호입니다. 0은 미설정 값입니다.",
"nullable": false
},
"version": {
"type": "string",
"description": "변경 전 다시 확인해야 하는 현재 설정의 검증 값입니다.",
"nullable": false
},
"effectiveReport": {
"type": "integer",
"description": "실제 적용되는 과제장 성적표 양식입니다. 82는 누적형이며, 미지정 0을 포함한 나머지는 관리자 화면과 동일한 당일형 80입니다. 저장된 report는 바꾸지 않습니다.",
"nullable": false
},
"storedReportName": {
"type": "string",
"description": "저장된 양식의 이름입니다. 0은 미지정이며, 미지정 상태에서도 실제 적용 양식은 당일형입니다.",
"nullable": false
},
"reportName": {
"type": "string",
"description": "실제 적용 양식 이름입니다. 당일형 또는 누적형입니다.",
"nullable": false
}
},
"required": [
"teamId",
"teamName",
"class",
"group",
"apiFlag",
"report",
"version",
"effectiveReport",
"storedReportName",
"reportName"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"version": "예시",
"report": 1
}성공 응답 예시
{
"data": {
"teamId": 1,
"teamName": "예시 이름",
"class": "예시",
"group": "예시",
"apiFlag": 1,
"report": 1,
"version": "예시",
"effectiveReport": 1,
"storedReportName": "예시 이름",
"reportName": "예시 이름"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/lessons/{lessonId}/retest과제장 재시험 연결·해제할 등록 번호 조회+
teaching.read · teaching.retest.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
lessonId | integer | 필수 | 과제장 번호입니다. | 1 |
onlineExamId | integer | 필수 | 연결된 온라인 재시험 번호입니다. 미연결은 0입니다. | 1 |
examId | integer | 필수 | 연결된 채점할 정답지 번호입니다. 미연결은 0입니다. | 1 |
title | string | 필수 | 연결 재시험명입니다. | "예시" |
removableAssignmentIds | array | 필수 | 해제 시 삭제할 개별 응시 등록 번호입니다. 명단에 없는 등록과 반 등록은 제외합니다. | 하위 필드·본문 예시 참조 |
studentIds | array | 필수 | 삭제 대상 학생번호입니다. | 하위 필드·본문 예시 참조 |
sharedStudentCount | integer | 필수 | 다른 과제장과 공유하여 삭제에서 보호하는 학생 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"lessonId": {
"type": "integer",
"description": "과제장 번호입니다.",
"nullable": false
},
"onlineExamId": {
"type": "integer",
"description": "연결된 온라인 재시험 번호입니다. 미연결은 0입니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "연결된 채점할 정답지 번호입니다. 미연결은 0입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "연결 재시험명입니다.",
"nullable": false
},
"removableAssignmentIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "해제 시 삭제할 개별 응시 등록 번호입니다. 명단에 없는 등록과 반 등록은 제외합니다.",
"nullable": false
},
"studentIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "삭제 대상 학생번호입니다.",
"nullable": false
},
"sharedStudentCount": {
"type": "integer",
"description": "다른 과제장과 공유하여 삭제에서 보호하는 학생 수입니다.",
"nullable": false
}
},
"required": [
"lessonId",
"onlineExamId",
"examId",
"title",
"removableAssignmentIds",
"studentIds",
"sharedStudentCount"
]
}성공 응답 예시
{
"data": {
"lessonId": 1,
"onlineExamId": 1,
"examId": 1,
"title": "예시",
"removableAssignmentIds": [
1
],
"studentIds": [
"00000001"
],
"sharedStudentCount": 1
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/teaching/lessons/{lessonId}/retest재시험 연결·선택한 과제장 학생 응시 등록·재시험 대상 체크(원자적 저장)+
teaching.write · teaching.retest.set
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
onlineExamId | integer | 필수 | 연결할 재시험의 온라인 시험 번호입니다. | 1 |
expectedOnlineExamId | integer | 조건부·선택 | 현재 연결 번호입니다. 미연결은 0이며 조회 후 변경된 연결은 거절합니다. | 0 |
studentIds | array | 조건부·선택 | 과제장 명단에서 선택한 학생번호입니다. 빈 배열은 연결만 설정합니다. | 하위 필드·본문 예시 참조 |
start | string | 조건부·선택 | 한국시간 응시 시작입니다. 생략하면 시작 제한이 없습니다. | "2026-01-15T00:00:00Z" |
end | string | 조건부·선택 | 한국시간 응시 마감입니다. 생략하면 마감 제한이 없습니다. | "2026-01-15T00:00:00Z" |
minutes | integer | 조건부·선택 | 응시 제한시간(분)입니다. 응시기간과 독립적입니다. | 1 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"onlineExamId": {
"type": "integer",
"description": "연결할 재시험의 온라인 시험 번호입니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"expectedOnlineExamId": {
"type": "integer",
"description": "현재 연결 번호입니다. 미연결은 0이며 조회 후 변경된 연결은 거절합니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"studentIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "과제장 명단에서 선택한 학생번호입니다. 빈 배열은 연결만 설정합니다.",
"nullable": false,
"maxItems": 1000
},
"start": {
"type": "string",
"format": "date-time",
"description": "한국시간 응시 시작입니다. 생략하면 시작 제한이 없습니다.",
"nullable": true
},
"end": {
"type": "string",
"format": "date-time",
"description": "한국시간 응시 마감입니다. 생략하면 마감 제한이 없습니다.",
"nullable": true
},
"minutes": {
"type": "integer",
"description": "응시 제한시간(분)입니다. 응시기간과 독립적입니다.",
"nullable": false,
"minimum": 1,
"maximum": 720,
"default": 60
}
},
"required": [
"onlineExamId"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
lessonId | integer | 필수 | 과제장 번호입니다. | 1 |
onlineExamId | integer | 필수 | 연결된 온라인 재시험 번호입니다. 미연결은 0입니다. | 1 |
examId | integer | 필수 | 연결된 채점할 정답지 번호입니다. 미연결은 0입니다. | 1 |
title | string | 필수 | 연결 재시험명입니다. | "예시" |
removableAssignmentIds | array | 필수 | 해제 시 삭제할 개별 응시 등록 번호입니다. 명단에 없는 등록과 반 등록은 제외합니다. | 하위 필드·본문 예시 참조 |
studentIds | array | 필수 | 삭제 대상 학생번호입니다. | 하위 필드·본문 예시 참조 |
sharedStudentCount | integer | 필수 | 다른 과제장과 공유하여 삭제에서 보호하는 학생 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"lessonId": {
"type": "integer",
"description": "과제장 번호입니다.",
"nullable": false
},
"onlineExamId": {
"type": "integer",
"description": "연결된 온라인 재시험 번호입니다. 미연결은 0입니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "연결된 채점할 정답지 번호입니다. 미연결은 0입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "연결 재시험명입니다.",
"nullable": false
},
"removableAssignmentIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "해제 시 삭제할 개별 응시 등록 번호입니다. 명단에 없는 등록과 반 등록은 제외합니다.",
"nullable": false
},
"studentIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "삭제 대상 학생번호입니다.",
"nullable": false
},
"sharedStudentCount": {
"type": "integer",
"description": "다른 과제장과 공유하여 삭제에서 보호하는 학생 수입니다.",
"nullable": false
}
},
"required": [
"lessonId",
"onlineExamId",
"examId",
"title",
"removableAssignmentIds",
"studentIds",
"sharedStudentCount"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"onlineExamId": 1,
"expectedOnlineExamId": 0,
"studentIds": [
"00000001"
],
"start": "2026-01-15T00:00:00Z",
"end": "2026-01-15T00:00:00Z",
"minutes": 1
}성공 응답 예시
{
"data": {
"lessonId": 1,
"onlineExamId": 1,
"examId": 1,
"title": "예시",
"removableAssignmentIds": [
1
],
"studentIds": [
"00000001"
],
"sharedStudentCount": 1
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/teaching/lessons/{lessonId}/retest조회한 연결 해제·개별 응시 등록 제거(공유 학생·반 등록·성적·출결 보존)+
teaching.write · teaching.retest.unlink
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
onlineExamId | integer | 필수 | 조회한 연결 재시험 번호입니다. | 1 |
assignmentIds | array | 조건부·선택 | 조회된 RemovableAssignmentIds를 전달합니다. 변경된 대상은 거절합니다. | 하위 필드·본문 예시 참조 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"onlineExamId": {
"type": "integer",
"description": "조회한 연결 재시험 번호입니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"assignmentIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "조회된 RemovableAssignmentIds를 전달합니다. 변경된 대상은 거절합니다.",
"nullable": false,
"maxItems": 1000
}
},
"required": [
"onlineExamId"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
lessonId | integer | 필수 | 연결을 해제한 과제장 번호입니다. | 1 |
deletedAssignmentCount | integer | 필수 | 제거한 개별 응시 등록 수입니다. | 1 |
sharedStudentCount | integer | 필수 | 다른 과제장과 공유하여 보존한 학생 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"lessonId": {
"type": "integer",
"description": "연결을 해제한 과제장 번호입니다.",
"nullable": false
},
"deletedAssignmentCount": {
"type": "integer",
"description": "제거한 개별 응시 등록 수입니다.",
"nullable": false
},
"sharedStudentCount": {
"type": "integer",
"description": "다른 과제장과 공유하여 보존한 학생 수입니다.",
"nullable": false
}
},
"required": [
"lessonId",
"deletedAssignmentCount",
"sharedStudentCount"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"onlineExamId": 1,
"assignmentIds": [
1
]
}성공 응답 예시
{
"data": {
"lessonId": 1,
"deletedAssignmentCount": 1,
"sharedStudentCount": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/lessons날짜·반별 수업 기록·과제장 목록(수강반 목록 아님)+
teaching.read · teaching.lessons.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
teamId | query | 선택 | GET /v1/teams 응답 data.items[].id의 정수 번호로 결과를 제한합니다. 검색 조건에서 생략하면 전체 반입니다. |
from | query | 필수 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 필수 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].teamName | string | 필수 | 해당 수업의 실제 수강반 이름입니다. 같은 학원의 반 번호에 연결한 원본 명칭입니다. | "예시 이름" |
items[].onlineRetestId | integer | 필수 | 연결된 온라인 재시험 번호입니다. 미연결은 0이며 /teaching/lessons/{lessonId}/retest에서 연결 정보를 조회합니다. | 1 |
items[].id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
items[].teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다. | 1 |
items[].scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요. | 1 |
items[].teacherId | integer | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다. | 1 |
items[].date | string | 필수 | 수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다. | "2026-01-15" |
items[].title | string | 필수 | 제목입니다. | "예시" |
items[].season | string | 필수 | 기간·학기 구분입니다. 빈 문자열이면 미지정입니다. | "예시" |
items[].order | integer | 필수 | 수업 회차입니다. 0 이상입니다. | 0 |
items[].content | object | 필수 | 과제·시험 항목과 연결 시험 설정입니다. PUT은 전체 내용을 교체합니다. | 하위 필드·본문 예시 참조 |
items[].content.nes1 | string | 조건부·선택 | 과제 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다. | "예시" |
items[].content.nes1s | string | 조건부·선택 | 과제 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
items[].content.nes1t | string | 조건부·선택 | 과제 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
items[].content.nes2 | string | 조건부·선택 | 과제 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다. | "예시" |
items[].content.nes2s | string | 조건부·선택 | 과제 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
items[].content.nes2t | string | 조건부·선택 | 과제 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
items[].content.nes3 | string | 조건부·선택 | 과제 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다. | "예시" |
items[].content.nes3s | string | 조건부·선택 | 과제 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
items[].content.nes3t | string | 조건부·선택 | 과제 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
items[].content.nes4 | string | 조건부·선택 | 과제 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다. | "예시" |
items[].content.nes4s | string | 조건부·선택 | 과제 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
items[].content.nes4t | string | 조건부·선택 | 과제 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
items[].content.nes5 | string | 조건부·선택 | 과제 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다. | "예시" |
items[].content.nes5s | string | 조건부·선택 | 과제 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
items[].content.nes5t | string | 조건부·선택 | 과제 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
items[].content.nes6 | string | 조건부·선택 | 과제 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다. | "예시" |
items[].content.nes6s | string | 조건부·선택 | 과제 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
items[].content.nes6t | string | 조건부·선택 | 과제 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
items[].content.cag1 | string | 조건부·선택 | 도전 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다. | "예시" |
items[].content.cag1s | string | 조건부·선택 | 도전 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
items[].content.cag1t | string | 조건부·선택 | 도전 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
items[].content.cag2 | string | 조건부·선택 | 도전 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다. | "예시" |
items[].content.cag2s | string | 조건부·선택 | 도전 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
items[].content.cag2t | string | 조건부·선택 | 도전 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
items[].content.exam1 | string | 조건부·선택 | 시험 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다. | "예시" |
items[].content.exam1s | string | 조건부·선택 | 시험 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
items[].content.exam1t | string | 조건부·선택 | 시험 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
items[].content.exam2 | string | 조건부·선택 | 시험 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다. | "예시" |
items[].content.exam2s | string | 조건부·선택 | 시험 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
items[].content.exam2t | string | 조건부·선택 | 시험 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
items[].content.exam3 | string | 조건부·선택 | 시험 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다. | "예시" |
items[].content.exam3s | string | 조건부·선택 | 시험 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
items[].content.exam3t | string | 조건부·선택 | 시험 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
items[].content.exam4 | string | 조건부·선택 | 시험 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다. | "예시" |
items[].content.exam4s | string | 조건부·선택 | 시험 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
items[].content.exam4t | string | 조건부·선택 | 시험 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
items[].content.exam5 | string | 조건부·선택 | 시험 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다. | "예시" |
items[].content.exam5s | string | 조건부·선택 | 시험 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
items[].content.exam5t | string | 조건부·선택 | 시험 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
items[].content.exam6 | string | 조건부·선택 | 시험 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다. | "예시" |
items[].content.exam6s | string | 조건부·선택 | 시험 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
items[].content.exam6t | string | 조건부·선택 | 시험 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
items[].content.comment | string | 조건부·선택 | 수업에서 다룬 내용과 공통 안내입니다. 수업 내용은 이 필드에, 숙제는 Nes1 등 과제 항목에 별도로 보존하세요. | "예시" |
items[].content.etc_Title | string | 조건부·선택 | 기타 항목 제목입니다. | "예시" |
items[].content.etc | string | 조건부·선택 | 기타 항목 내용입니다. | "예시" |
items[].content.reexam_Title | string | 조건부·선택 | 재검사 표시 제목입니다. | "예시" |
items[].content.hw_Idx | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 과제 연결 시험 번호입니다. 수업 번호가 아니며 0이면 연결하지 않습니다. | 0 |
items[].content.exam_Idx1 | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 1 번호입니다. OMR 양식 번호가 아니며 0이면 연결하지 않습니다. | 0 |
items[].content.exam_Idx2 | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 2 번호입니다. 0이면 연결하지 않습니다. | 0 |
items[].content.exam_Idx3 | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 3 번호입니다. 0이면 연결하지 않습니다. | 0 |
items[].published | boolean | 필수 | 학생용 과제장 공개 여부입니다. | false |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"teamName": {
"type": "string",
"description": "해당 수업의 실제 수강반 이름입니다. 같은 학원의 반 번호에 연결한 원본 명칭입니다.",
"nullable": false
},
"onlineRetestId": {
"type": "integer",
"description": "연결된 온라인 재시험 번호입니다. 미연결은 0이며 /teaching/lessons/{lessonId}/retest에서 연결 정보를 조회합니다.",
"nullable": false
},
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"teacherId": {
"type": "integer",
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"date": {
"type": "string",
"description": "수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다.",
"nullable": false,
"minLength": 1
},
"title": {
"type": "string",
"description": "제목입니다.",
"nullable": false,
"maxLength": 200,
"minLength": 1
},
"season": {
"type": "string",
"description": "기간·학기 구분입니다. 빈 문자열이면 미지정입니다.",
"nullable": false,
"maxLength": 100
},
"order": {
"type": "integer",
"description": "수업 회차입니다. 0 이상입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647
},
"content": {
"type": "object",
"properties": {
"nes1": {
"type": "string",
"description": "과제 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes1s": {
"type": "string",
"description": "과제 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes1t": {
"type": "string",
"description": "과제 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes2": {
"type": "string",
"description": "과제 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes2s": {
"type": "string",
"description": "과제 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes2t": {
"type": "string",
"description": "과제 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes3": {
"type": "string",
"description": "과제 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes3s": {
"type": "string",
"description": "과제 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes3t": {
"type": "string",
"description": "과제 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes4": {
"type": "string",
"description": "과제 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes4s": {
"type": "string",
"description": "과제 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes4t": {
"type": "string",
"description": "과제 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes5": {
"type": "string",
"description": "과제 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes5s": {
"type": "string",
"description": "과제 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes5t": {
"type": "string",
"description": "과제 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes6": {
"type": "string",
"description": "과제 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes6s": {
"type": "string",
"description": "과제 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes6t": {
"type": "string",
"description": "과제 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag1": {
"type": "string",
"description": "도전 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag1s": {
"type": "string",
"description": "도전 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag1t": {
"type": "string",
"description": "도전 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag2": {
"type": "string",
"description": "도전 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag2s": {
"type": "string",
"description": "도전 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag2t": {
"type": "string",
"description": "도전 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam1": {
"type": "string",
"description": "시험 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam1s": {
"type": "string",
"description": "시험 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam1t": {
"type": "string",
"description": "시험 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam2": {
"type": "string",
"description": "시험 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam2s": {
"type": "string",
"description": "시험 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam2t": {
"type": "string",
"description": "시험 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam3": {
"type": "string",
"description": "시험 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam3s": {
"type": "string",
"description": "시험 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam3t": {
"type": "string",
"description": "시험 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam4": {
"type": "string",
"description": "시험 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam4s": {
"type": "string",
"description": "시험 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam4t": {
"type": "string",
"description": "시험 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam5": {
"type": "string",
"description": "시험 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam5s": {
"type": "string",
"description": "시험 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam5t": {
"type": "string",
"description": "시험 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam6": {
"type": "string",
"description": "시험 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam6s": {
"type": "string",
"description": "시험 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam6t": {
"type": "string",
"description": "시험 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"comment": {
"type": "string",
"description": "수업에서 다룬 내용과 공통 안내입니다. 수업 내용은 이 필드에, 숙제는 Nes1 등 과제 항목에 별도로 보존하세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"etc_Title": {
"type": "string",
"description": "기타 항목 제목입니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"etc": {
"type": "string",
"description": "기타 항목 내용입니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"reexam_Title": {
"type": "string",
"description": "재검사 표시 제목입니다.",
"nullable": false,
"maxLength": 4,
"default": ""
},
"hw_Idx": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 과제 연결 시험 번호입니다. 수업 번호가 아니며 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"exam_Idx1": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 1 번호입니다. OMR 양식 번호가 아니며 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"exam_Idx2": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 2 번호입니다. 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"exam_Idx3": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 3 번호입니다. 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
}
},
"description": "과제·시험 항목과 연결 시험 설정입니다. PUT은 전체 내용을 교체합니다.",
"nullable": false
},
"published": {
"type": "boolean",
"description": "학생용 과제장 공개 여부입니다.",
"nullable": false
}
},
"required": [
"teamName",
"onlineRetestId",
"id",
"teamId",
"scheduleId",
"teacherId",
"date",
"title",
"season",
"order",
"content",
"published"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"teamName": "예시 이름",
"onlineRetestId": 1,
"id": 1,
"teamId": 1,
"scheduleId": 1,
"teacherId": 1,
"date": "2026-01-15",
"title": "예시",
"season": "예시",
"order": 0,
"content": {
"nes1": "예시",
"nes1s": "예시",
"nes1t": "예시",
"nes2": "예시",
"nes2s": "예시",
"nes2t": "예시",
"nes3": "예시",
"nes3s": "예시",
"nes3t": "예시",
"nes4": "예시",
"nes4s": "예시",
"nes4t": "예시",
"nes5": "예시",
"nes5s": "예시",
"nes5t": "예시",
"nes6": "예시",
"nes6s": "예시",
"nes6t": "예시",
"cag1": "예시",
"cag1s": "예시",
"cag1t": "예시",
"cag2": "예시",
"cag2s": "예시",
"cag2t": "예시",
"exam1": "예시",
"exam1s": "예시",
"exam1t": "예시",
"exam2": "예시",
"exam2s": "예시",
"exam2t": "예시",
"exam3": "예시",
"exam3s": "예시",
"exam3t": "예시",
"exam4": "예시",
"exam4s": "예시",
"exam4t": "예시",
"exam5": "예시",
"exam5s": "예시",
"exam5t": "예시",
"exam6": "예시",
"exam6s": "예시",
"exam6t": "예시",
"comment": "예시",
"etc_Title": "예시",
"etc": "예시",
"reexam_Title": "예시",
"hw_Idx": 0,
"exam_Idx1": 0,
"exam_Idx2": 0,
"exam_Idx3": 0
},
"published": false
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/lessons/{lessonId}과제장 수업과 항목 상세+
teaching.read · teaching.lessons.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
teamName | string | 필수 | 해당 수업의 실제 수강반 이름입니다. 같은 학원의 반 번호에 연결한 원본 명칭입니다. | "예시 이름" |
onlineRetestId | integer | 필수 | 연결된 온라인 재시험 번호입니다. 미연결은 0이며 /teaching/lessons/{lessonId}/retest에서 연결 정보를 조회합니다. | 1 |
id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다. | 1 |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요. | 1 |
teacherId | integer | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다. | 1 |
date | string | 필수 | 수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다. | "2026-01-15" |
title | string | 필수 | 제목입니다. | "예시" |
season | string | 필수 | 기간·학기 구분입니다. 빈 문자열이면 미지정입니다. | "예시" |
order | integer | 필수 | 수업 회차입니다. 0 이상입니다. | 0 |
content | object | 필수 | 과제·시험 항목과 연결 시험 설정입니다. PUT은 전체 내용을 교체합니다. | 하위 필드·본문 예시 참조 |
content.nes1 | string | 조건부·선택 | 과제 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다. | "예시" |
content.nes1s | string | 조건부·선택 | 과제 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes1t | string | 조건부·선택 | 과제 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes2 | string | 조건부·선택 | 과제 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다. | "예시" |
content.nes2s | string | 조건부·선택 | 과제 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes2t | string | 조건부·선택 | 과제 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes3 | string | 조건부·선택 | 과제 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다. | "예시" |
content.nes3s | string | 조건부·선택 | 과제 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes3t | string | 조건부·선택 | 과제 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes4 | string | 조건부·선택 | 과제 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다. | "예시" |
content.nes4s | string | 조건부·선택 | 과제 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes4t | string | 조건부·선택 | 과제 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes5 | string | 조건부·선택 | 과제 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다. | "예시" |
content.nes5s | string | 조건부·선택 | 과제 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes5t | string | 조건부·선택 | 과제 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes6 | string | 조건부·선택 | 과제 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다. | "예시" |
content.nes6s | string | 조건부·선택 | 과제 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes6t | string | 조건부·선택 | 과제 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.cag1 | string | 조건부·선택 | 도전 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다. | "예시" |
content.cag1s | string | 조건부·선택 | 도전 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.cag1t | string | 조건부·선택 | 도전 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.cag2 | string | 조건부·선택 | 도전 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다. | "예시" |
content.cag2s | string | 조건부·선택 | 도전 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.cag2t | string | 조건부·선택 | 도전 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam1 | string | 조건부·선택 | 시험 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다. | "예시" |
content.exam1s | string | 조건부·선택 | 시험 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam1t | string | 조건부·선택 | 시험 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam2 | string | 조건부·선택 | 시험 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다. | "예시" |
content.exam2s | string | 조건부·선택 | 시험 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam2t | string | 조건부·선택 | 시험 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam3 | string | 조건부·선택 | 시험 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다. | "예시" |
content.exam3s | string | 조건부·선택 | 시험 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam3t | string | 조건부·선택 | 시험 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam4 | string | 조건부·선택 | 시험 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다. | "예시" |
content.exam4s | string | 조건부·선택 | 시험 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam4t | string | 조건부·선택 | 시험 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam5 | string | 조건부·선택 | 시험 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다. | "예시" |
content.exam5s | string | 조건부·선택 | 시험 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam5t | string | 조건부·선택 | 시험 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam6 | string | 조건부·선택 | 시험 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다. | "예시" |
content.exam6s | string | 조건부·선택 | 시험 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam6t | string | 조건부·선택 | 시험 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.comment | string | 조건부·선택 | 수업에서 다룬 내용과 공통 안내입니다. 수업 내용은 이 필드에, 숙제는 Nes1 등 과제 항목에 별도로 보존하세요. | "예시" |
content.etc_Title | string | 조건부·선택 | 기타 항목 제목입니다. | "예시" |
content.etc | string | 조건부·선택 | 기타 항목 내용입니다. | "예시" |
content.reexam_Title | string | 조건부·선택 | 재검사 표시 제목입니다. | "예시" |
content.hw_Idx | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 과제 연결 시험 번호입니다. 수업 번호가 아니며 0이면 연결하지 않습니다. | 0 |
content.exam_Idx1 | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 1 번호입니다. OMR 양식 번호가 아니며 0이면 연결하지 않습니다. | 0 |
content.exam_Idx2 | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 2 번호입니다. 0이면 연결하지 않습니다. | 0 |
content.exam_Idx3 | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 3 번호입니다. 0이면 연결하지 않습니다. | 0 |
published | boolean | 필수 | 학생용 과제장 공개 여부입니다. | false |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"teamName": {
"type": "string",
"description": "해당 수업의 실제 수강반 이름입니다. 같은 학원의 반 번호에 연결한 원본 명칭입니다.",
"nullable": false
},
"onlineRetestId": {
"type": "integer",
"description": "연결된 온라인 재시험 번호입니다. 미연결은 0이며 /teaching/lessons/{lessonId}/retest에서 연결 정보를 조회합니다.",
"nullable": false
},
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"teacherId": {
"type": "integer",
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"date": {
"type": "string",
"description": "수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다.",
"nullable": false,
"minLength": 1
},
"title": {
"type": "string",
"description": "제목입니다.",
"nullable": false,
"maxLength": 200,
"minLength": 1
},
"season": {
"type": "string",
"description": "기간·학기 구분입니다. 빈 문자열이면 미지정입니다.",
"nullable": false,
"maxLength": 100
},
"order": {
"type": "integer",
"description": "수업 회차입니다. 0 이상입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647
},
"content": {
"type": "object",
"properties": {
"nes1": {
"type": "string",
"description": "과제 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes1s": {
"type": "string",
"description": "과제 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes1t": {
"type": "string",
"description": "과제 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes2": {
"type": "string",
"description": "과제 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes2s": {
"type": "string",
"description": "과제 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes2t": {
"type": "string",
"description": "과제 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes3": {
"type": "string",
"description": "과제 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes3s": {
"type": "string",
"description": "과제 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes3t": {
"type": "string",
"description": "과제 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes4": {
"type": "string",
"description": "과제 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes4s": {
"type": "string",
"description": "과제 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes4t": {
"type": "string",
"description": "과제 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes5": {
"type": "string",
"description": "과제 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes5s": {
"type": "string",
"description": "과제 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes5t": {
"type": "string",
"description": "과제 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes6": {
"type": "string",
"description": "과제 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes6s": {
"type": "string",
"description": "과제 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes6t": {
"type": "string",
"description": "과제 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag1": {
"type": "string",
"description": "도전 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag1s": {
"type": "string",
"description": "도전 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag1t": {
"type": "string",
"description": "도전 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag2": {
"type": "string",
"description": "도전 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag2s": {
"type": "string",
"description": "도전 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag2t": {
"type": "string",
"description": "도전 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam1": {
"type": "string",
"description": "시험 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam1s": {
"type": "string",
"description": "시험 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam1t": {
"type": "string",
"description": "시험 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam2": {
"type": "string",
"description": "시험 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam2s": {
"type": "string",
"description": "시험 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam2t": {
"type": "string",
"description": "시험 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam3": {
"type": "string",
"description": "시험 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam3s": {
"type": "string",
"description": "시험 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam3t": {
"type": "string",
"description": "시험 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam4": {
"type": "string",
"description": "시험 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam4s": {
"type": "string",
"description": "시험 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam4t": {
"type": "string",
"description": "시험 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam5": {
"type": "string",
"description": "시험 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam5s": {
"type": "string",
"description": "시험 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam5t": {
"type": "string",
"description": "시험 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam6": {
"type": "string",
"description": "시험 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam6s": {
"type": "string",
"description": "시험 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam6t": {
"type": "string",
"description": "시험 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"comment": {
"type": "string",
"description": "수업에서 다룬 내용과 공통 안내입니다. 수업 내용은 이 필드에, 숙제는 Nes1 등 과제 항목에 별도로 보존하세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"etc_Title": {
"type": "string",
"description": "기타 항목 제목입니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"etc": {
"type": "string",
"description": "기타 항목 내용입니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"reexam_Title": {
"type": "string",
"description": "재검사 표시 제목입니다.",
"nullable": false,
"maxLength": 4,
"default": ""
},
"hw_Idx": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 과제 연결 시험 번호입니다. 수업 번호가 아니며 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"exam_Idx1": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 1 번호입니다. OMR 양식 번호가 아니며 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"exam_Idx2": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 2 번호입니다. 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"exam_Idx3": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 3 번호입니다. 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
}
},
"description": "과제·시험 항목과 연결 시험 설정입니다. PUT은 전체 내용을 교체합니다.",
"nullable": false
},
"published": {
"type": "boolean",
"description": "학생용 과제장 공개 여부입니다.",
"nullable": false
}
},
"required": [
"teamName",
"onlineRetestId",
"id",
"teamId",
"scheduleId",
"teacherId",
"date",
"title",
"season",
"order",
"content",
"published"
]
}성공 응답 예시
{
"data": {
"teamName": "예시 이름",
"onlineRetestId": 1,
"id": 1,
"teamId": 1,
"scheduleId": 1,
"teacherId": 1,
"date": "2026-01-15",
"title": "예시",
"season": "예시",
"order": 0,
"content": {
"nes1": "예시",
"nes1s": "예시",
"nes1t": "예시",
"nes2": "예시",
"nes2s": "예시",
"nes2t": "예시",
"nes3": "예시",
"nes3s": "예시",
"nes3t": "예시",
"nes4": "예시",
"nes4s": "예시",
"nes4t": "예시",
"nes5": "예시",
"nes5s": "예시",
"nes5t": "예시",
"nes6": "예시",
"nes6s": "예시",
"nes6t": "예시",
"cag1": "예시",
"cag1s": "예시",
"cag1t": "예시",
"cag2": "예시",
"cag2s": "예시",
"cag2t": "예시",
"exam1": "예시",
"exam1s": "예시",
"exam1t": "예시",
"exam2": "예시",
"exam2s": "예시",
"exam2t": "예시",
"exam3": "예시",
"exam3s": "예시",
"exam3t": "예시",
"exam4": "예시",
"exam4s": "예시",
"exam4t": "예시",
"exam5": "예시",
"exam5s": "예시",
"exam5t": "예시",
"exam6": "예시",
"exam6s": "예시",
"exam6t": "예시",
"comment": "예시",
"etc_Title": "예시",
"etc": "예시",
"reexam_Title": "예시",
"hw_Idx": 0,
"exam_Idx1": 0,
"exam_Idx2": 0,
"exam_Idx3": 0
},
"published": false
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/teaching/lessons수업·과제장 내용과 숙제 정의 등록(학생별 출석·과제완료는 학생별 결과 변경으로 별도 처리)+
teaching.write · teaching.lessons.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다. | 1 |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요. | 1 |
teacherId | integer | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다. | 1 |
date | string | 필수 | 수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다. | "2026-01-15" |
title | string | 필수 | 수업·과제장 제목입니다. 수강반명과 구별하며 최대 200자입니다. | "수학 정규 수업" |
season | string | 조건부·선택 | 기간·학기 구분입니다. 빈 문자열이면 미지정입니다. | "예시" |
order | integer | 조건부·선택 | 수업 회차입니다. 0 이상입니다. | 0 |
content | object | 필수 | 과제·시험 항목과 연결 시험 설정입니다. PUT은 전체 내용을 교체합니다. | 하위 필드·본문 예시 참조 |
content.nes1 | string | 조건부·선택 | 과제 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다. | "예시" |
content.nes1s | string | 조건부·선택 | 과제 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes1t | string | 조건부·선택 | 과제 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes2 | string | 조건부·선택 | 과제 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다. | "예시" |
content.nes2s | string | 조건부·선택 | 과제 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes2t | string | 조건부·선택 | 과제 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes3 | string | 조건부·선택 | 과제 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다. | "예시" |
content.nes3s | string | 조건부·선택 | 과제 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes3t | string | 조건부·선택 | 과제 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes4 | string | 조건부·선택 | 과제 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다. | "예시" |
content.nes4s | string | 조건부·선택 | 과제 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes4t | string | 조건부·선택 | 과제 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes5 | string | 조건부·선택 | 과제 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다. | "예시" |
content.nes5s | string | 조건부·선택 | 과제 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes5t | string | 조건부·선택 | 과제 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes6 | string | 조건부·선택 | 과제 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다. | "예시" |
content.nes6s | string | 조건부·선택 | 과제 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes6t | string | 조건부·선택 | 과제 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.cag1 | string | 조건부·선택 | 도전 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다. | "예시" |
content.cag1s | string | 조건부·선택 | 도전 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.cag1t | string | 조건부·선택 | 도전 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.cag2 | string | 조건부·선택 | 도전 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다. | "예시" |
content.cag2s | string | 조건부·선택 | 도전 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.cag2t | string | 조건부·선택 | 도전 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam1 | string | 조건부·선택 | 시험 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다. | "예시" |
content.exam1s | string | 조건부·선택 | 시험 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam1t | string | 조건부·선택 | 시험 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam2 | string | 조건부·선택 | 시험 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다. | "예시" |
content.exam2s | string | 조건부·선택 | 시험 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam2t | string | 조건부·선택 | 시험 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam3 | string | 조건부·선택 | 시험 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다. | "예시" |
content.exam3s | string | 조건부·선택 | 시험 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam3t | string | 조건부·선택 | 시험 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam4 | string | 조건부·선택 | 시험 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다. | "예시" |
content.exam4s | string | 조건부·선택 | 시험 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam4t | string | 조건부·선택 | 시험 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam5 | string | 조건부·선택 | 시험 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다. | "예시" |
content.exam5s | string | 조건부·선택 | 시험 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam5t | string | 조건부·선택 | 시험 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam6 | string | 조건부·선택 | 시험 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다. | "예시" |
content.exam6s | string | 조건부·선택 | 시험 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam6t | string | 조건부·선택 | 시험 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.comment | string | 조건부·선택 | 수업에서 다룬 내용과 공통 안내입니다. 수업 내용은 이 필드에, 숙제는 Nes1 등 과제 항목에 별도로 보존하세요. | "예시" |
content.etc_Title | string | 조건부·선택 | 기타 항목 제목입니다. | "예시" |
content.etc | string | 조건부·선택 | 기타 항목 내용입니다. | "예시" |
content.reexam_Title | string | 조건부·선택 | 재검사 표시 제목입니다. | "예시" |
content.hw_Idx | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 과제 연결 시험 번호입니다. 수업 번호가 아니며 0이면 연결하지 않습니다. | 0 |
content.exam_Idx1 | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 1 번호입니다. OMR 양식 번호가 아니며 0이면 연결하지 않습니다. | 0 |
content.exam_Idx2 | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 2 번호입니다. 0이면 연결하지 않습니다. | 0 |
content.exam_Idx3 | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 3 번호입니다. 0이면 연결하지 않습니다. | 0 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"teacherId": {
"type": "integer",
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"date": {
"type": "string",
"format": "date",
"description": "수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다.",
"nullable": false,
"minLength": 1
},
"title": {
"type": "string",
"description": "수업·과제장 제목입니다. 수강반명과 구별하며 최대 200자입니다.",
"nullable": false,
"maxLength": 200,
"minLength": 1,
"example": "수학 정규 수업"
},
"season": {
"type": "string",
"description": "기간·학기 구분입니다. 빈 문자열이면 미지정입니다.",
"nullable": false,
"maxLength": 100,
"default": ""
},
"order": {
"type": "integer",
"description": "수업 회차입니다. 0 이상입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"content": {
"type": "object",
"properties": {
"nes1": {
"type": "string",
"description": "과제 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes1s": {
"type": "string",
"description": "과제 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes1t": {
"type": "string",
"description": "과제 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes2": {
"type": "string",
"description": "과제 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes2s": {
"type": "string",
"description": "과제 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes2t": {
"type": "string",
"description": "과제 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes3": {
"type": "string",
"description": "과제 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes3s": {
"type": "string",
"description": "과제 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes3t": {
"type": "string",
"description": "과제 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes4": {
"type": "string",
"description": "과제 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes4s": {
"type": "string",
"description": "과제 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes4t": {
"type": "string",
"description": "과제 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes5": {
"type": "string",
"description": "과제 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes5s": {
"type": "string",
"description": "과제 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes5t": {
"type": "string",
"description": "과제 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes6": {
"type": "string",
"description": "과제 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes6s": {
"type": "string",
"description": "과제 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes6t": {
"type": "string",
"description": "과제 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag1": {
"type": "string",
"description": "도전 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag1s": {
"type": "string",
"description": "도전 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag1t": {
"type": "string",
"description": "도전 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag2": {
"type": "string",
"description": "도전 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag2s": {
"type": "string",
"description": "도전 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag2t": {
"type": "string",
"description": "도전 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam1": {
"type": "string",
"description": "시험 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam1s": {
"type": "string",
"description": "시험 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam1t": {
"type": "string",
"description": "시험 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam2": {
"type": "string",
"description": "시험 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam2s": {
"type": "string",
"description": "시험 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam2t": {
"type": "string",
"description": "시험 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam3": {
"type": "string",
"description": "시험 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam3s": {
"type": "string",
"description": "시험 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam3t": {
"type": "string",
"description": "시험 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam4": {
"type": "string",
"description": "시험 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam4s": {
"type": "string",
"description": "시험 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam4t": {
"type": "string",
"description": "시험 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam5": {
"type": "string",
"description": "시험 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam5s": {
"type": "string",
"description": "시험 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam5t": {
"type": "string",
"description": "시험 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam6": {
"type": "string",
"description": "시험 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam6s": {
"type": "string",
"description": "시험 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam6t": {
"type": "string",
"description": "시험 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"comment": {
"type": "string",
"description": "수업에서 다룬 내용과 공통 안내입니다. 수업 내용은 이 필드에, 숙제는 Nes1 등 과제 항목에 별도로 보존하세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"etc_Title": {
"type": "string",
"description": "기타 항목 제목입니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"etc": {
"type": "string",
"description": "기타 항목 내용입니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"reexam_Title": {
"type": "string",
"description": "재검사 표시 제목입니다.",
"nullable": false,
"maxLength": 4,
"default": ""
},
"hw_Idx": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 과제 연결 시험 번호입니다. 수업 번호가 아니며 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"exam_Idx1": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 1 번호입니다. OMR 양식 번호가 아니며 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"exam_Idx2": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 2 번호입니다. 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"exam_Idx3": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 3 번호입니다. 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
}
},
"description": "과제·시험 항목과 연결 시험 설정입니다. PUT은 전체 내용을 교체합니다.",
"nullable": false
}
},
"required": [
"teamId",
"scheduleId",
"teacherId",
"date",
"title",
"content"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"teamId": 1,
"scheduleId": 1,
"teacherId": 1,
"date": "2026-01-15",
"title": "수학 정규 수업",
"season": "예시",
"order": 0,
"content": {
"nes1": "예시",
"nes1s": "예시",
"nes1t": "예시",
"nes2": "예시",
"nes2s": "예시",
"nes2t": "예시",
"nes3": "예시",
"nes3s": "예시",
"nes3t": "예시",
"nes4": "예시",
"nes4s": "예시",
"nes4t": "예시",
"nes5": "예시",
"nes5s": "예시",
"nes5t": "예시",
"nes6": "예시",
"nes6s": "예시",
"nes6t": "예시",
"cag1": "예시",
"cag1s": "예시",
"cag1t": "예시",
"cag2": "예시",
"cag2s": "예시",
"cag2t": "예시",
"exam1": "예시",
"exam1s": "예시",
"exam1t": "예시",
"exam2": "예시",
"exam2s": "예시",
"exam2t": "예시",
"exam3": "예시",
"exam3s": "예시",
"exam3t": "예시",
"exam4": "예시",
"exam4s": "예시",
"exam4t": "예시",
"exam5": "예시",
"exam5s": "예시",
"exam5t": "예시",
"exam6": "예시",
"exam6s": "예시",
"exam6t": "예시",
"comment": "예시",
"etc_Title": "예시",
"etc": "예시",
"reexam_Title": "예시",
"hw_Idx": 0,
"exam_Idx1": 0,
"exam_Idx2": 0,
"exam_Idx3": 0
}
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/teaching/lessons/{lessonId}수업·과제장 전체 수정+
teaching.write · teaching.lessons.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다. | 1 |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요. | 1 |
teacherId | integer | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다. | 1 |
date | string | 필수 | 수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다. | "2026-01-15" |
title | string | 필수 | 수업·과제장 제목입니다. 수강반명과 구별하며 최대 200자입니다. | "수학 정규 수업" |
season | string | 조건부·선택 | 기간·학기 구분입니다. 빈 문자열이면 미지정입니다. | "예시" |
order | integer | 조건부·선택 | 수업 회차입니다. 0 이상입니다. | 0 |
content | object | 필수 | 과제·시험 항목과 연결 시험 설정입니다. PUT은 전체 내용을 교체합니다. | 하위 필드·본문 예시 참조 |
content.nes1 | string | 조건부·선택 | 과제 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다. | "예시" |
content.nes1s | string | 조건부·선택 | 과제 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes1t | string | 조건부·선택 | 과제 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes2 | string | 조건부·선택 | 과제 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다. | "예시" |
content.nes2s | string | 조건부·선택 | 과제 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes2t | string | 조건부·선택 | 과제 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes3 | string | 조건부·선택 | 과제 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다. | "예시" |
content.nes3s | string | 조건부·선택 | 과제 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes3t | string | 조건부·선택 | 과제 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes4 | string | 조건부·선택 | 과제 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다. | "예시" |
content.nes4s | string | 조건부·선택 | 과제 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes4t | string | 조건부·선택 | 과제 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes5 | string | 조건부·선택 | 과제 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다. | "예시" |
content.nes5s | string | 조건부·선택 | 과제 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes5t | string | 조건부·선택 | 과제 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.nes6 | string | 조건부·선택 | 과제 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다. | "예시" |
content.nes6s | string | 조건부·선택 | 과제 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.nes6t | string | 조건부·선택 | 과제 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.cag1 | string | 조건부·선택 | 도전 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다. | "예시" |
content.cag1s | string | 조건부·선택 | 도전 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.cag1t | string | 조건부·선택 | 도전 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.cag2 | string | 조건부·선택 | 도전 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다. | "예시" |
content.cag2s | string | 조건부·선택 | 도전 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.cag2t | string | 조건부·선택 | 도전 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam1 | string | 조건부·선택 | 시험 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다. | "예시" |
content.exam1s | string | 조건부·선택 | 시험 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam1t | string | 조건부·선택 | 시험 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam2 | string | 조건부·선택 | 시험 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다. | "예시" |
content.exam2s | string | 조건부·선택 | 시험 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam2t | string | 조건부·선택 | 시험 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam3 | string | 조건부·선택 | 시험 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다. | "예시" |
content.exam3s | string | 조건부·선택 | 시험 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam3t | string | 조건부·선택 | 시험 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam4 | string | 조건부·선택 | 시험 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다. | "예시" |
content.exam4s | string | 조건부·선택 | 시험 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam4t | string | 조건부·선택 | 시험 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam5 | string | 조건부·선택 | 시험 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다. | "예시" |
content.exam5s | string | 조건부·선택 | 시험 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam5t | string | 조건부·선택 | 시험 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.exam6 | string | 조건부·선택 | 시험 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다. | "예시" |
content.exam6s | string | 조건부·선택 | 시험 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요. | "예시" |
content.exam6t | string | 조건부·선택 | 시험 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요. | "예시" |
content.comment | string | 조건부·선택 | 수업에서 다룬 내용과 공통 안내입니다. 수업 내용은 이 필드에, 숙제는 Nes1 등 과제 항목에 별도로 보존하세요. | "예시" |
content.etc_Title | string | 조건부·선택 | 기타 항목 제목입니다. | "예시" |
content.etc | string | 조건부·선택 | 기타 항목 내용입니다. | "예시" |
content.reexam_Title | string | 조건부·선택 | 재검사 표시 제목입니다. | "예시" |
content.hw_Idx | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 과제 연결 시험 번호입니다. 수업 번호가 아니며 0이면 연결하지 않습니다. | 0 |
content.exam_Idx1 | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 1 번호입니다. OMR 양식 번호가 아니며 0이면 연결하지 않습니다. | 0 |
content.exam_Idx2 | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 2 번호입니다. 0이면 연결하지 않습니다. | 0 |
content.exam_Idx3 | integer | 조건부·선택 | GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 3 번호입니다. 0이면 연결하지 않습니다. | 0 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"teacherId": {
"type": "integer",
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"date": {
"type": "string",
"format": "date",
"description": "수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다.",
"nullable": false,
"minLength": 1
},
"title": {
"type": "string",
"description": "수업·과제장 제목입니다. 수강반명과 구별하며 최대 200자입니다.",
"nullable": false,
"maxLength": 200,
"minLength": 1,
"example": "수학 정규 수업"
},
"season": {
"type": "string",
"description": "기간·학기 구분입니다. 빈 문자열이면 미지정입니다.",
"nullable": false,
"maxLength": 100,
"default": ""
},
"order": {
"type": "integer",
"description": "수업 회차입니다. 0 이상입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"content": {
"type": "object",
"properties": {
"nes1": {
"type": "string",
"description": "과제 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes1s": {
"type": "string",
"description": "과제 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes1t": {
"type": "string",
"description": "과제 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes2": {
"type": "string",
"description": "과제 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes2s": {
"type": "string",
"description": "과제 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes2t": {
"type": "string",
"description": "과제 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes3": {
"type": "string",
"description": "과제 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes3s": {
"type": "string",
"description": "과제 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes3t": {
"type": "string",
"description": "과제 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes4": {
"type": "string",
"description": "과제 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes4s": {
"type": "string",
"description": "과제 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes4t": {
"type": "string",
"description": "과제 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes5": {
"type": "string",
"description": "과제 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes5s": {
"type": "string",
"description": "과제 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes5t": {
"type": "string",
"description": "과제 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes6": {
"type": "string",
"description": "과제 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes6s": {
"type": "string",
"description": "과제 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"nes6t": {
"type": "string",
"description": "과제 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag1": {
"type": "string",
"description": "도전 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag1s": {
"type": "string",
"description": "도전 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag1t": {
"type": "string",
"description": "도전 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag2": {
"type": "string",
"description": "도전 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag2s": {
"type": "string",
"description": "도전 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"cag2t": {
"type": "string",
"description": "도전 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam1": {
"type": "string",
"description": "시험 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam1s": {
"type": "string",
"description": "시험 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam1t": {
"type": "string",
"description": "시험 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam2": {
"type": "string",
"description": "시험 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam2s": {
"type": "string",
"description": "시험 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam2t": {
"type": "string",
"description": "시험 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam3": {
"type": "string",
"description": "시험 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam3s": {
"type": "string",
"description": "시험 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam3t": {
"type": "string",
"description": "시험 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam4": {
"type": "string",
"description": "시험 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam4s": {
"type": "string",
"description": "시험 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam4t": {
"type": "string",
"description": "시험 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam5": {
"type": "string",
"description": "시험 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam5s": {
"type": "string",
"description": "시험 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam5t": {
"type": "string",
"description": "시험 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam6": {
"type": "string",
"description": "시험 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam6s": {
"type": "string",
"description": "시험 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"exam6t": {
"type": "string",
"description": "시험 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"comment": {
"type": "string",
"description": "수업에서 다룬 내용과 공통 안내입니다. 수업 내용은 이 필드에, 숙제는 Nes1 등 과제 항목에 별도로 보존하세요.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"etc_Title": {
"type": "string",
"description": "기타 항목 제목입니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"etc": {
"type": "string",
"description": "기타 항목 내용입니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"reexam_Title": {
"type": "string",
"description": "재검사 표시 제목입니다.",
"nullable": false,
"maxLength": 4,
"default": ""
},
"hw_Idx": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 과제 연결 시험 번호입니다. 수업 번호가 아니며 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"exam_Idx1": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 1 번호입니다. OMR 양식 번호가 아니며 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"exam_Idx2": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 2 번호입니다. 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"exam_Idx3": {
"type": "integer",
"description": "GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 3 번호입니다. 0이면 연결하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
}
},
"description": "과제·시험 항목과 연결 시험 설정입니다. PUT은 전체 내용을 교체합니다.",
"nullable": false
}
},
"required": [
"teamId",
"scheduleId",
"teacherId",
"date",
"title",
"content"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"teamId": 1,
"scheduleId": 1,
"teacherId": 1,
"date": "2026-01-15",
"title": "수학 정규 수업",
"season": "예시",
"order": 0,
"content": {
"nes1": "예시",
"nes1s": "예시",
"nes1t": "예시",
"nes2": "예시",
"nes2s": "예시",
"nes2t": "예시",
"nes3": "예시",
"nes3s": "예시",
"nes3t": "예시",
"nes4": "예시",
"nes4s": "예시",
"nes4t": "예시",
"nes5": "예시",
"nes5s": "예시",
"nes5t": "예시",
"nes6": "예시",
"nes6s": "예시",
"nes6t": "예시",
"cag1": "예시",
"cag1s": "예시",
"cag1t": "예시",
"cag2": "예시",
"cag2s": "예시",
"cag2t": "예시",
"exam1": "예시",
"exam1s": "예시",
"exam1t": "예시",
"exam2": "예시",
"exam2s": "예시",
"exam2t": "예시",
"exam3": "예시",
"exam3s": "예시",
"exam3t": "예시",
"exam4": "예시",
"exam4s": "예시",
"exam4t": "예시",
"exam5": "예시",
"exam5s": "예시",
"exam5t": "예시",
"exam6": "예시",
"exam6s": "예시",
"exam6t": "예시",
"comment": "예시",
"etc_Title": "예시",
"etc": "예시",
"reexam_Title": "예시",
"hw_Idx": 0,
"exam_Idx1": 0,
"exam_Idx2": 0,
"exam_Idx3": 0
}
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/teaching/lessons/{lessonId}수업·과제장 삭제와 연결 출석 정리+
teaching.write · teaching.lessons.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/lessons/{lessonId}/absence-candidates목적지 보강 수업 lessonId로 원래 결석 후보 조회(응답 originalLessonId에서 선택)+
teaching.read · teaching.absences.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | 보강생을 추가할 목적지 수업 번호입니다. 원래 결석 수업 번호가 아닙니다. 원래 결석은 absence-candidates 응답 originalLessonId에서 선택합니다. |
search | query | 필수 | 보강할 학생의 이름 검색어입니다. 1~100자로 반드시 전달하며 빈 문자열은 허용하지 않습니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
[].studentName | string | 필수 | 학생 이름입니다. | "예시 이름" |
[].enrollmentId | integer | 필수 | 원래 반 수강 등록 번호입니다. | 1 |
[].originalTeamId | integer | 필수 | 원래 결석한 수강반 번호입니다. | 1 |
[].originalLessonId | integer | 필수 | 선택할 원래 결석 수업 번호입니다. 보강생 추가 시 반드시 그대로 전달합니다. | 1 |
[].date | string | 필수 | 원래 결석 수업일입니다. | "2026-01-15" |
[].attendanceCode | integer | 필수 | 출결 코드입니다. 0 무결(무단결석), 4 인정결석(인결), 5 출석, 6 인강, 7 보강완료, 8 타반에서 온 보강생입니다. | 1 |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"studentName": {
"type": "string",
"description": "학생 이름입니다.",
"nullable": false
},
"enrollmentId": {
"type": "integer",
"description": "원래 반 수강 등록 번호입니다.",
"nullable": false
},
"originalTeamId": {
"type": "integer",
"description": "원래 결석한 수강반 번호입니다.",
"nullable": false
},
"originalLessonId": {
"type": "integer",
"description": "선택할 원래 결석 수업 번호입니다. 보강생 추가 시 반드시 그대로 전달합니다.",
"nullable": false
},
"date": {
"type": "string",
"description": "원래 결석 수업일입니다.",
"nullable": false
},
"attendanceCode": {
"type": "integer",
"description": "출결 코드입니다. 0 무결(무단결석), 4 인정결석(인결), 5 출석, 6 인강, 7 보강완료, 8 타반에서 온 보강생입니다.",
"nullable": false
}
},
"required": [
"studentId",
"studentName",
"enrollmentId",
"originalTeamId",
"originalLessonId",
"date",
"attendanceCode"
]
}
}성공 응답 예시
{
"data": [
{
"studentId": "00000001",
"studentName": "예시 이름",
"enrollmentId": 1,
"originalTeamId": 1,
"originalLessonId": 1,
"date": "2026-01-15",
"attendanceCode": 1
}
],
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/teaching/lessons/{lessonId}/attendance수업의 저장된 출석부 삭제+
teaching.write · teaching.attendance.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/teaching/lessons/{lessonId}/makeups목적지 lessonId에 선택한 원래 결석 originalLessonId를 연결해 보강생(8) 추가·원반 보강완료(7) 처리+
teaching.write · teaching.makeups.create
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | 보강생을 추가할 목적지 수업 번호입니다. 원래 결석 수업 번호가 아닙니다. 원래 결석은 absence-candidates 응답 originalLessonId에서 선택합니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
originalLessonId | integer | 필수 | GET /v1/teaching/lessons/{lessonId}/absence-candidates 응답에서 같은 학생의 결석을 선택한 뒤 originalLessonId를 전달합니다. 후보의 id·enrollmentId와 혼동하지 마세요. | 1 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"originalLessonId": {
"type": "integer",
"description": "GET /v1/teaching/lessons/{lessonId}/absence-candidates 응답에서 같은 학생의 결석을 선택한 뒤 originalLessonId를 전달합니다. 후보의 id·enrollmentId와 혼동하지 마세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
}
},
"required": [
"studentId",
"originalLessonId"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
count | integer | 필수 | 정상 처리된 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"count": {
"type": "integer",
"description": "정상 처리된 자료 수입니다.",
"nullable": false
}
},
"required": [
"count"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"studentId": "00000001",
"originalLessonId": 1
}성공 응답 예시
{
"data": {
"count": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/lessons/{lessonId}/publication선택 과제장 제목과 현재 학생 공개 상태 조회웹 관리 기능+
웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요teaching.read · teaching.publication.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
lessonId | integer | 필수 | 과제장 수업 번호입니다. | 1 |
title | string | 필수 | 선택한 과제장의 실제 제목입니다. | "예시" |
published | boolean | 필수 | 현재 학생 공개 여부입니다. | false |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"lessonId": {
"type": "integer",
"description": "과제장 수업 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "선택한 과제장의 실제 제목입니다.",
"nullable": false
},
"published": {
"type": "boolean",
"description": "현재 학생 공개 여부입니다.",
"nullable": false
}
},
"required": [
"lessonId",
"title",
"published"
]
}성공 응답 예시
{
"data": {
"lessonId": 1,
"title": "예시",
"published": false
},
"meta": {
"requestId": "example-request-id"
}
}PATCH/v1/teaching/lessons/{lessonId}/publication학생에게 과제장 공개·비공개 변경(직전 공개 상태 일치 확인·수업 내용 보존)웹 관리 기능+
웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요teaching.write · teaching.publication.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
expectedPublished | boolean | 필수 | 조회한 직전 공개 상태입니다. 생략할 수 없습니다. | false |
published | boolean | 필수 | 학생 공개 여부로 저장할 값입니다. 생략할 수 없습니다. | false |
요청 JSON 스키마
{
"type": "object",
"properties": {
"expectedPublished": {
"type": "boolean",
"description": "조회한 직전 공개 상태입니다. 생략할 수 없습니다.",
"nullable": true
},
"published": {
"type": "boolean",
"description": "학생 공개 여부로 저장할 값입니다. 생략할 수 없습니다.",
"nullable": true
}
},
"required": [
"expectedPublished",
"published"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
lessonId | integer | 필수 | 과제장 수업 번호입니다. | 1 |
title | string | 필수 | 선택한 과제장의 실제 제목입니다. | "예시" |
published | boolean | 필수 | 현재 학생 공개 여부입니다. | false |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"lessonId": {
"type": "integer",
"description": "과제장 수업 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "선택한 과제장의 실제 제목입니다.",
"nullable": false
},
"published": {
"type": "boolean",
"description": "현재 학생 공개 여부입니다.",
"nullable": false
}
},
"required": [
"lessonId",
"title",
"published"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"expectedPublished": false,
"published": false
}성공 응답 예시
{
"data": {
"lessonId": 1,
"title": "예시",
"published": false
},
"meta": {
"requestId": "example-request-id"
}
}PATCH/v1/teaching/lessons/{lessonId}/results수업 학생 출석·결석·검사결과 부분 수정(입퇴실·수강등록 아님). 학생 코멘트는 rows[].values.comment에 전달하고 생략 항목은 보존+
teaching.write · teaching.results.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
rows | array | 필수 | 변경할 학생 배열입니다. 학생 번호는 중복할 수 없으며 저장된 명단의 학생만 가능합니다. | 하위 필드·본문 예시 참조 |
rows[].studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
rows[].values | object | 조건부·선택 | 변경할 검사 결과만 전달합니다. 생략한 속성은 기존 값을 유지합니다. | 하위 필드·본문 예시 참조 |
rows[].values.nes1 | string | 조건부·선택 | 과제 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
rows[].values.nes2 | string | 조건부·선택 | 과제 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
rows[].values.nes3 | string | 조건부·선택 | 과제 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
rows[].values.nes4 | string | 조건부·선택 | 과제 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
rows[].values.nes5 | string | 조건부·선택 | 과제 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
rows[].values.nes6 | string | 조건부·선택 | 과제 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
rows[].values.cag1 | string | 조건부·선택 | 도전 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
rows[].values.cag2 | string | 조건부·선택 | 도전 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
rows[].values.exam1 | string | 조건부·선택 | 시험 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
rows[].values.exam2 | string | 조건부·선택 | 시험 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
rows[].values.exam3 | string | 조건부·선택 | 시험 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
rows[].values.exam4 | string | 조건부·선택 | 시험 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
rows[].values.exam5 | string | 조건부·선택 | 시험 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
rows[].values.exam6 | string | 조건부·선택 | 시험 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
rows[].values.etc | string | 조건부·선택 | 학생별 기타 검사 결과입니다. 생략하면 유지합니다. | "예시" |
rows[].values.comment | string | 조건부·선택 | 학생별 수업 메모입니다. yyyy-MM-dd HH:mm 날짜를 포함하면 기존 규칙으로 재검사 일정을 인식합니다. | "예시" |
rows[].values.re_Exam1 | boolean | 조건부·선택 | 시험 1의 재시험 대상 여부입니다. 생략하면 유지합니다. | false |
rows[].values.re_Exam_Result1 | string | 조건부·선택 | 시험 1 재시험 결과입니다. 생략하면 유지합니다. | "예시" |
rows[].values.re_Exam2 | boolean | 조건부·선택 | 시험 2의 재시험 대상 여부입니다. 생략하면 유지합니다. | false |
rows[].values.re_Exam_Result2 | string | 조건부·선택 | 시험 2 재시험 결과입니다. 생략하면 유지합니다. | "예시" |
rows[].values.re_Exam3 | boolean | 조건부·선택 | 시험 3의 재시험 대상 여부입니다. 생략하면 유지합니다. | false |
rows[].values.re_Exam_Result3 | string | 조건부·선택 | 시험 3 재시험 결과입니다. 생략하면 유지합니다. | "예시" |
rows[].attendanceCode | integer | 조건부·선택 | 출결 코드입니다. 0 무결(무단결석), 4 인정결석(인결), 5 출석, 6 인강, 7 보강완료, 8 타반에서 온 보강생입니다. 생략하면 출결은 유지합니다. | 0 |
rows[].makeupId | integer | 조건부·선택 | 출결을 7 보강완료로 새로 변경할 때 GET /v1/teaching/lessons/{lessonId}/students/{studentId}/makeup-candidates 응답 data[].id에서 명시적으로 선택한 값을 전달합니다. 같은 학생·원래 반·수업일 ±10일 조건을 충족한 기존 타반 보강생 기록이어야 합니다. | 1 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"values": {
"type": "object",
"properties": {
"nes1": {
"type": "string",
"description": "과제 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes2": {
"type": "string",
"description": "과제 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes3": {
"type": "string",
"description": "과제 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes4": {
"type": "string",
"description": "과제 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes5": {
"type": "string",
"description": "과제 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes6": {
"type": "string",
"description": "과제 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"cag1": {
"type": "string",
"description": "도전 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"cag2": {
"type": "string",
"description": "도전 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam1": {
"type": "string",
"description": "시험 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam2": {
"type": "string",
"description": "시험 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam3": {
"type": "string",
"description": "시험 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam4": {
"type": "string",
"description": "시험 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam5": {
"type": "string",
"description": "시험 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam6": {
"type": "string",
"description": "시험 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"etc": {
"type": "string",
"description": "학생별 기타 검사 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
},
"comment": {
"type": "string",
"description": "학생별 수업 메모입니다. yyyy-MM-dd HH:mm 날짜를 포함하면 기존 규칙으로 재검사 일정을 인식합니다.",
"nullable": true,
"maxLength": 4000
},
"re_Exam1": {
"type": "boolean",
"description": "시험 1의 재시험 대상 여부입니다. 생략하면 유지합니다.",
"nullable": true
},
"re_Exam_Result1": {
"type": "string",
"description": "시험 1 재시험 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
},
"re_Exam2": {
"type": "boolean",
"description": "시험 2의 재시험 대상 여부입니다. 생략하면 유지합니다.",
"nullable": true
},
"re_Exam_Result2": {
"type": "string",
"description": "시험 2 재시험 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
},
"re_Exam3": {
"type": "boolean",
"description": "시험 3의 재시험 대상 여부입니다. 생략하면 유지합니다.",
"nullable": true
},
"re_Exam_Result3": {
"type": "string",
"description": "시험 3 재시험 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
}
},
"description": "변경할 검사 결과만 전달합니다. 생략한 속성은 기존 값을 유지합니다.",
"nullable": false
},
"attendanceCode": {
"type": "integer",
"enum": [
0,
4,
5,
6,
7,
8
],
"description": "출결 코드입니다. 0 무결(무단결석), 4 인정결석(인결), 5 출석, 6 인강, 7 보강완료, 8 타반에서 온 보강생입니다. 생략하면 출결은 유지합니다.",
"nullable": true
},
"makeupId": {
"type": "integer",
"description": "출결을 7 보강완료로 새로 변경할 때 GET /v1/teaching/lessons/{lessonId}/students/{studentId}/makeup-candidates 응답 data[].id에서 명시적으로 선택한 값을 전달합니다. 같은 학생·원래 반·수업일 ±10일 조건을 충족한 기존 타반 보강생 기록이어야 합니다.",
"nullable": true
}
},
"required": [
"studentId"
]
},
"description": "변경할 학생 배열입니다. 학생 번호는 중복할 수 없으며 저장된 명단의 학생만 가능합니다.",
"nullable": false,
"minItems": 1,
"maxItems": 100
}
},
"required": [
"rows"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
count | integer | 필수 | 정상 처리된 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"count": {
"type": "integer",
"description": "정상 처리된 자료 수입니다.",
"nullable": false
}
},
"required": [
"count"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"rows": [
{
"studentId": "00000001",
"values": {
"nes1": "예시",
"nes2": "예시",
"nes3": "예시",
"nes4": "예시",
"nes5": "예시",
"nes6": "예시",
"cag1": "예시",
"cag2": "예시",
"exam1": "예시",
"exam2": "예시",
"exam3": "예시",
"exam4": "예시",
"exam5": "예시",
"exam6": "예시",
"etc": "예시",
"comment": "예시",
"re_Exam1": false,
"re_Exam_Result1": "예시",
"re_Exam2": false,
"re_Exam_Result2": "예시",
"re_Exam3": false,
"re_Exam_Result3": "예시"
},
"attendanceCode": 0,
"makeupId": 1
}
]
}성공 응답 예시
{
"data": {
"count": 1
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/teaching/lessons/{lessonId}/score-sync연결된 OMR 점수를 과제장에 동기화+
teaching.write · teaching.scores.sync
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
count | integer | 필수 | 정상 처리된 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"count": {
"type": "integer",
"description": "정상 처리된 자료 수입니다.",
"nullable": false
}
},
"required": [
"count"
]
}성공 응답 예시
{
"data": {
"count": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/lessons/{lessonId}/students수업 목록의 lessonId로 저장된 출석·검사 조회(반·시간표 번호 아님, 빈 명단은 roster.add 후 기록)+
teaching.read · teaching.roster.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].teamName | string | 필수 | 해당 수업의 실제 수강반 이름입니다. 학생의 다른 반이나 보강 원래 반의 이름이 아닙니다. | "예시 이름" |
[].id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
[].lessonId | integer | 필수 | 과제장 수업 번호입니다. | 1 |
[].studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
[].studentName | string | 필수 | 학생 이름입니다. | "예시 이름" |
[].attendanceCode | integer | 필수 | 출결 코드입니다. 0 무결(무단결석), 4 인정결석(인결), 5 출석, 6 인강, 7 보강완료, 8 타반에서 온 보강생입니다. | 1 |
[].absent | boolean | 필수 | 무결 또는 인정결석이면 true입니다. | false |
[].originalTeamId | integer | 필수 | 보강생의 원래 반 번호입니다. 일반 학생과 보강완료 학생은 0입니다. | 1 |
[].originalLessonId | integer | 필수 | 보강 연결의 원래 결석 수업 번호입니다. 연결이 없으면 0입니다. | 1 |
[].values | object | 필수 | 과제·시험 결과와 메모입니다. | 하위 필드·본문 예시 참조 |
[].values.nes1 | string | 조건부·선택 | 과제 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
[].values.nes2 | string | 조건부·선택 | 과제 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
[].values.nes3 | string | 조건부·선택 | 과제 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
[].values.nes4 | string | 조건부·선택 | 과제 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
[].values.nes5 | string | 조건부·선택 | 과제 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
[].values.nes6 | string | 조건부·선택 | 과제 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
[].values.cag1 | string | 조건부·선택 | 도전 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
[].values.cag2 | string | 조건부·선택 | 도전 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
[].values.exam1 | string | 조건부·선택 | 시험 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
[].values.exam2 | string | 조건부·선택 | 시험 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
[].values.exam3 | string | 조건부·선택 | 시험 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
[].values.exam4 | string | 조건부·선택 | 시험 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
[].values.exam5 | string | 조건부·선택 | 시험 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
[].values.exam6 | string | 조건부·선택 | 시험 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
[].values.etc | string | 조건부·선택 | 학생별 기타 검사 결과입니다. 생략하면 유지합니다. | "예시" |
[].values.comment | string | 조건부·선택 | 학생별 수업 메모입니다. yyyy-MM-dd HH:mm 날짜를 포함하면 기존 규칙으로 재검사 일정을 인식합니다. | "예시" |
[].values.re_Exam1 | boolean | 조건부·선택 | 시험 1의 재시험 대상 여부입니다. 생략하면 유지합니다. | false |
[].values.re_Exam_Result1 | string | 조건부·선택 | 시험 1 재시험 결과입니다. 생략하면 유지합니다. | "예시" |
[].values.re_Exam2 | boolean | 조건부·선택 | 시험 2의 재시험 대상 여부입니다. 생략하면 유지합니다. | false |
[].values.re_Exam_Result2 | string | 조건부·선택 | 시험 2 재시험 결과입니다. 생략하면 유지합니다. | "예시" |
[].values.re_Exam3 | boolean | 조건부·선택 | 시험 3의 재시험 대상 여부입니다. 생략하면 유지합니다. | false |
[].values.re_Exam_Result3 | string | 조건부·선택 | 시험 3 재시험 결과입니다. 생략하면 유지합니다. | "예시" |
[].valueItems | array | 필수 | 같은 수업의 항목 제목·결과 안내·슬롯 번호와 학생 결과를 명시적으로 연결한 읽기 전용 자료입니다. 배열 순서로 의미나 단위를 추정하지 마세요. 수정할 때는 field에 대응하는 values 필드를 사용하세요. | 하위 필드·본문 예시 참조 |
[].valueItems[].field | string | 필수 | 저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요. | "예시" |
[].valueItems[].category | string | 필수 | 과제, 도전, 시험 중 항목 종류입니다. | "예시" |
[].valueItems[].position | integer | 필수 | 같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다. | 1 |
[].valueItems[].title | string | 필수 | 같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요. | "예시" |
[].valueItems[].content | string | 필수 | 같은 수업 설정의 과제·시험 내용 원문입니다. | "예시" |
[].valueItems[].resultGuide | string | 필수 | 같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요. | "예시" |
[].valueItems[].value | string | 필수 | 해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다. | "예시" |
[].valueItems[].valueState | string | 필수 | present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다. | "예시" |
[].valueItems[].examId | integer | 필수 | 같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다. | 1 |
[].attendanceName | string | 필수 | attendanceCode와 같은 원본 코드표의 출결 명칭입니다. | "예시 이름" |
[].date | string | 필수 | 수업 등록일입니다. yyyy-MM-dd 형식입니다. | "2026-01-15" |
[].teamId | integer | 필수 | 해당 수업의 수강반 번호입니다. | 1 |
[].scheduleId | integer | 필수 | 수업 시간표 번호입니다. | 1 |
[].teacherId | integer | 필수 | 담당 선생님 번호입니다. | 1 |
[].title | string | 필수 | 수업·과제장 제목입니다. | "예시" |
[].season | string | 필수 | 학기·기간 구분입니다. | "예시" |
[].order | integer | 필수 | 수업 회차입니다. | 1 |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"teamName": {
"type": "string",
"description": "해당 수업의 실제 수강반 이름입니다. 학생의 다른 반이나 보강 원래 반의 이름이 아닙니다.",
"nullable": false
},
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"lessonId": {
"type": "integer",
"description": "과제장 수업 번호입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"studentName": {
"type": "string",
"description": "학생 이름입니다.",
"nullable": false
},
"attendanceCode": {
"type": "integer",
"x-read-display-field": "attendanceName",
"description": "출결 코드입니다. 0 무결(무단결석), 4 인정결석(인결), 5 출석, 6 인강, 7 보강완료, 8 타반에서 온 보강생입니다.",
"nullable": false
},
"absent": {
"type": "boolean",
"x-read-scope-key": "absence",
"description": "무결 또는 인정결석이면 true입니다.",
"nullable": false
},
"originalTeamId": {
"type": "integer",
"description": "보강생의 원래 반 번호입니다. 일반 학생과 보강완료 학생은 0입니다.",
"nullable": false
},
"originalLessonId": {
"type": "integer",
"description": "보강 연결의 원래 결석 수업 번호입니다. 연결이 없으면 0입니다.",
"nullable": false
},
"values": {
"type": "object",
"properties": {
"nes1": {
"type": "string",
"description": "과제 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes2": {
"type": "string",
"description": "과제 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes3": {
"type": "string",
"description": "과제 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes4": {
"type": "string",
"description": "과제 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes5": {
"type": "string",
"description": "과제 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes6": {
"type": "string",
"description": "과제 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"cag1": {
"type": "string",
"description": "도전 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"cag2": {
"type": "string",
"description": "도전 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam1": {
"type": "string",
"description": "시험 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam2": {
"type": "string",
"description": "시험 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam3": {
"type": "string",
"description": "시험 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam4": {
"type": "string",
"description": "시험 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam5": {
"type": "string",
"description": "시험 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam6": {
"type": "string",
"description": "시험 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"etc": {
"type": "string",
"description": "학생별 기타 검사 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
},
"comment": {
"type": "string",
"description": "학생별 수업 메모입니다. yyyy-MM-dd HH:mm 날짜를 포함하면 기존 규칙으로 재검사 일정을 인식합니다.",
"nullable": true,
"maxLength": 4000
},
"re_Exam1": {
"type": "boolean",
"description": "시험 1의 재시험 대상 여부입니다. 생략하면 유지합니다.",
"nullable": true
},
"re_Exam_Result1": {
"type": "string",
"description": "시험 1 재시험 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
},
"re_Exam2": {
"type": "boolean",
"description": "시험 2의 재시험 대상 여부입니다. 생략하면 유지합니다.",
"nullable": true
},
"re_Exam_Result2": {
"type": "string",
"description": "시험 2 재시험 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
},
"re_Exam3": {
"type": "boolean",
"description": "시험 3의 재시험 대상 여부입니다. 생략하면 유지합니다.",
"nullable": true
},
"re_Exam_Result3": {
"type": "string",
"description": "시험 3 재시험 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
}
},
"description": "과제·시험 결과와 메모입니다.",
"nullable": false
},
"valueItems": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field": {
"type": "string",
"description": "저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요.",
"nullable": false
},
"category": {
"type": "string",
"description": "과제, 도전, 시험 중 항목 종류입니다.",
"nullable": false
},
"position": {
"type": "integer",
"description": "같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요.",
"nullable": false
},
"content": {
"type": "string",
"description": "같은 수업 설정의 과제·시험 내용 원문입니다.",
"nullable": false
},
"resultGuide": {
"type": "string",
"description": "같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요.",
"nullable": false
},
"value": {
"type": "string",
"description": "해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다.",
"nullable": true
},
"valueState": {
"type": "string",
"description": "present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다.",
"nullable": false
}
},
"required": [
"field",
"category",
"position",
"title",
"content",
"resultGuide",
"value",
"valueState",
"examId"
]
},
"description": "같은 수업의 항목 제목·결과 안내·슬롯 번호와 학생 결과를 명시적으로 연결한 읽기 전용 자료입니다. 배열 순서로 의미나 단위를 추정하지 마세요. 수정할 때는 field에 대응하는 values 필드를 사용하세요.",
"nullable": false
},
"attendanceName": {
"type": "string",
"description": "attendanceCode와 같은 원본 코드표의 출결 명칭입니다.",
"nullable": false
},
"date": {
"type": "string",
"description": "수업 등록일입니다. yyyy-MM-dd 형식입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "해당 수업의 수강반 번호입니다.",
"nullable": false
},
"scheduleId": {
"type": "integer",
"description": "수업 시간표 번호입니다.",
"nullable": false
},
"teacherId": {
"type": "integer",
"description": "담당 선생님 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "수업·과제장 제목입니다.",
"nullable": false
},
"season": {
"type": "string",
"description": "학기·기간 구분입니다.",
"nullable": false
},
"order": {
"type": "integer",
"description": "수업 회차입니다.",
"nullable": false
}
},
"required": [
"teamName",
"id",
"lessonId",
"studentId",
"studentName",
"attendanceCode",
"absent",
"originalTeamId",
"originalLessonId",
"values",
"valueItems",
"attendanceName",
"date",
"teamId",
"scheduleId",
"teacherId",
"title",
"season",
"order"
]
}
}성공 응답 예시
{
"data": [
{
"teamName": "예시 이름",
"id": 1,
"lessonId": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"attendanceCode": 1,
"absent": false,
"originalTeamId": 1,
"originalLessonId": 1,
"values": {
"nes1": "예시",
"nes2": "예시",
"nes3": "예시",
"nes4": "예시",
"nes5": "예시",
"nes6": "예시",
"cag1": "예시",
"cag2": "예시",
"exam1": "예시",
"exam2": "예시",
"exam3": "예시",
"exam4": "예시",
"exam5": "예시",
"exam6": "예시",
"etc": "예시",
"comment": "예시",
"re_Exam1": false,
"re_Exam_Result1": "예시",
"re_Exam2": false,
"re_Exam_Result2": "예시",
"re_Exam3": false,
"re_Exam_Result3": "예시"
},
"valueItems": [
{
"field": "예시",
"category": "예시",
"position": 1,
"title": "예시",
"content": "예시",
"resultGuide": "예시",
"value": "예시",
"valueState": "예시",
"examId": 1
}
],
"attendanceName": "예시 이름",
"date": "2026-01-15",
"teamId": 1,
"scheduleId": 1,
"teacherId": 1,
"title": "예시",
"season": "예시",
"order": 1
}
],
"meta": {
"requestId": "example-request-id"
}
}POST/v1/teaching/lessons/{lessonId}/students수강 등록에서 선택한 일반 학생을 출석부에 추가+
teaching.write · teaching.roster.add
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentIds | array | 필수 | 해당 반에 유효하게 수강 등록된 학생 번호입니다. 기존 명단에 없는 학생만 추가합니다. 보강생은 별도 API를 사용합니다. | 하위 필드·본문 예시 참조 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"studentIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "해당 반에 유효하게 수강 등록된 학생 번호입니다. 기존 명단에 없는 학생만 추가합니다. 보강생은 별도 API를 사용합니다.",
"nullable": false,
"minItems": 1,
"maxItems": 100
}
},
"required": [
"studentIds"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
count | integer | 필수 | 정상 처리된 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"count": {
"type": "integer",
"description": "정상 처리된 자료 수입니다.",
"nullable": false
}
},
"required": [
"count"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"studentIds": [
"00000001"
]
}성공 응답 예시
{
"data": {
"count": 1
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/teaching/lessons/{lessonId}/students/{studentId}명단 학생 삭제(연결된 원래 결석 복원)+
teaching.write · teaching.roster.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다. |
studentId | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/lessons/{lessonId}/students/{studentId}/makeup-candidates보강완료 연결 후보(같은 학생·타반·수업일 ±10일)+
teaching.read · teaching.makeups.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | 보강완료로 연결하려는 원래 결석 수업 번호입니다. 다른 반에서 수업한 보강생 기록 후보를 조회합니다. |
studentId | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
[].lessonId | integer | 필수 | 타반 보강 수업 번호입니다. | 1 |
[].date | string | 필수 | 보강 수업일입니다. 원래 수업일 전후 10일 이내입니다. | "2026-01-15" |
[].teamName | string | 필수 | 보강을 받은 수강반 이름입니다. | "예시 이름" |
[].originalLessonId | integer | 필수 | 현재 연결된 원래 결석 수업 번호입니다. 0이면 미연결입니다. | 1 |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"lessonId": {
"type": "integer",
"description": "타반 보강 수업 번호입니다.",
"nullable": false
},
"date": {
"type": "string",
"description": "보강 수업일입니다. 원래 수업일 전후 10일 이내입니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "보강을 받은 수강반 이름입니다.",
"nullable": false
},
"originalLessonId": {
"type": "integer",
"description": "현재 연결된 원래 결석 수업 번호입니다. 0이면 미연결입니다.",
"nullable": false
}
},
"required": [
"id",
"lessonId",
"date",
"teamName",
"originalLessonId"
]
}
}성공 응답 예시
{
"data": [
{
"id": 1,
"lessonId": 1,
"date": "2026-01-15",
"teamName": "예시 이름",
"originalLessonId": 1
}
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/lessons/{lessonId}/students/{studentId}/makeup-link원래 수업의 현재 보강 연결·복원 출결 조회(해제 전 필수 확인)+
teaching.read · teaching.makeups.link.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | 보강완료로 처리된 원래 수업 번호입니다. 연결된 보강 수업을 조회한 뒤 그 연결만 해제합니다. 목적지 수업 번호가 아닙니다. |
studentId | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 필수 | 조회한 학생 번호입니다. | "00000001" |
studentName | string | 필수 | 조회한 학생 이름입니다. | "예시 이름" |
originalLessonId | integer | 필수 | 보강완료로 처리된 원래 수업 번호입니다. | 1 |
originalTeamName | string | 필수 | 원래 수업의 수강반 이름입니다. | "예시 이름" |
incomingTeamName | string | 필수 | 보강 수업의 수강반 이름입니다. | "예시 이름" |
originalDate | string | 필수 | 원래 수업일입니다. | "2026-01-15" |
incomingDate | string | 필수 | 보강 수업일입니다. | "2026-01-15" |
originalRecordId | integer | 필수 | 보강 연결 조회에서 받은 원래 출결 행 번호입니다. | 1 |
incomingRecordId | integer | 필수 | 보강 연결 조회에서 받은 보강생 출결 행 번호입니다. 행은 삭제하지 않습니다. | 1 |
incomingLessonId | integer | 필수 | 보강 연결 조회에서 받은 보강 목적지 수업 번호입니다. | 1 |
originalAttendanceCode | integer | 필수 | 연결 시 보존한 원래 출결 코드입니다. 0 무결, 4 인정결석, 5 출석, 6 인강만 복원 가능합니다. | 0 |
version | string | 필수 | 보강 연결 조회에서 받은 최신 원본 확인값입니다. 수정하거나 생성하지 마세요. | "예시" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "조회한 학생 번호입니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "조회한 학생 이름입니다.",
"nullable": false
},
"originalLessonId": {
"type": "integer",
"description": "보강완료로 처리된 원래 수업 번호입니다.",
"nullable": false
},
"originalTeamName": {
"type": "string",
"description": "원래 수업의 수강반 이름입니다.",
"nullable": false
},
"incomingTeamName": {
"type": "string",
"description": "보강 수업의 수강반 이름입니다.",
"nullable": false
},
"originalDate": {
"type": "string",
"description": "원래 수업일입니다.",
"nullable": false
},
"incomingDate": {
"type": "string",
"description": "보강 수업일입니다.",
"nullable": false
},
"originalRecordId": {
"type": "integer",
"description": "보강 연결 조회에서 받은 원래 출결 행 번호입니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"incomingRecordId": {
"type": "integer",
"description": "보강 연결 조회에서 받은 보강생 출결 행 번호입니다. 행은 삭제하지 않습니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"incomingLessonId": {
"type": "integer",
"description": "보강 연결 조회에서 받은 보강 목적지 수업 번호입니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"originalAttendanceCode": {
"type": "integer",
"description": "연결 시 보존한 원래 출결 코드입니다. 0 무결, 4 인정결석, 5 출석, 6 인강만 복원 가능합니다.",
"nullable": false,
"minimum": 0,
"maximum": 6
},
"version": {
"type": "string",
"description": "보강 연결 조회에서 받은 최신 원본 확인값입니다. 수정하거나 생성하지 마세요.",
"nullable": false,
"minLength": 1,
"pattern": "^[A-F0-9]{64}$"
}
},
"required": [
"studentId",
"studentName",
"originalLessonId",
"originalTeamName",
"incomingTeamName",
"originalDate",
"incomingDate",
"originalRecordId",
"incomingRecordId",
"incomingLessonId",
"originalAttendanceCode",
"version"
]
}성공 응답 예시
{
"data": {
"studentId": "00000001",
"studentName": "예시 이름",
"originalLessonId": 1,
"originalTeamName": "예시 이름",
"incomingTeamName": "예시 이름",
"originalDate": "2026-01-15",
"incomingDate": "2026-01-15",
"originalRecordId": 1,
"incomingRecordId": 1,
"incomingLessonId": 1,
"originalAttendanceCode": 0,
"version": "예시"
},
"meta": {
"requestId": "example-request-id"
}
}PATCH/v1/teaching/lessons/{lessonId}/students/{studentId}/makeup-link조회한 보강 연결만 해제하고 보존된 원래 출결 복원. 보강생 행·과제·코멘트는 보존하며 확인값이 달라지면 거절+
teaching.write · teaching.makeups.unlink
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
lessonId | path | 필수 | 보강완료로 처리된 원래 수업 번호입니다. 연결된 보강 수업을 조회한 뒤 그 연결만 해제합니다. 목적지 수업 번호가 아닙니다. |
studentId | path | 필수 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
originalRecordId | integer | 필수 | 보강 연결 조회에서 받은 원래 출결 행 번호입니다. | 1 |
incomingRecordId | integer | 필수 | 보강 연결 조회에서 받은 보강생 출결 행 번호입니다. 행은 삭제하지 않습니다. | 1 |
incomingLessonId | integer | 필수 | 보강 연결 조회에서 받은 보강 목적지 수업 번호입니다. | 1 |
originalAttendanceCode | integer | 조건부·선택 | 연결 시 보존한 원래 출결 코드입니다. 0 무결, 4 인정결석, 5 출석, 6 인강만 복원 가능합니다. | 0 |
version | string | 필수 | 보강 연결 조회에서 받은 최신 원본 확인값입니다. 수정하거나 생성하지 마세요. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"originalRecordId": {
"type": "integer",
"description": "보강 연결 조회에서 받은 원래 출결 행 번호입니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"incomingRecordId": {
"type": "integer",
"description": "보강 연결 조회에서 받은 보강생 출결 행 번호입니다. 행은 삭제하지 않습니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"incomingLessonId": {
"type": "integer",
"description": "보강 연결 조회에서 받은 보강 목적지 수업 번호입니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"originalAttendanceCode": {
"type": "integer",
"description": "연결 시 보존한 원래 출결 코드입니다. 0 무결, 4 인정결석, 5 출석, 6 인강만 복원 가능합니다.",
"nullable": false,
"minimum": 0,
"maximum": 6,
"default": 0
},
"version": {
"type": "string",
"description": "보강 연결 조회에서 받은 최신 원본 확인값입니다. 수정하거나 생성하지 마세요.",
"nullable": false,
"minLength": 1,
"pattern": "^[A-F0-9]{64}$"
}
},
"required": [
"originalRecordId",
"incomingRecordId",
"incomingLessonId",
"version"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
count | integer | 필수 | 정상 처리된 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"count": {
"type": "integer",
"description": "정상 처리된 자료 수입니다.",
"nullable": false
}
},
"required": [
"count"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"originalRecordId": 1,
"incomingRecordId": 1,
"incomingLessonId": 1,
"originalAttendanceCode": 0,
"version": "예시"
}성공 응답 예시
{
"data": {
"count": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/options/copy-sources담당 선생님의 복사 원본 과제장 선택 목록(조회만 하며 새 과제장을 만들지 않음)+
teaching.read · teaching.options.copy
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
[].name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
}
},
"required": [
"id",
"name"
]
}
}성공 응답 예시
{
"data": [
{
"id": "1",
"name": "예시 이름"
}
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/options/exams과제장의 시험 항목에 연결 가능한 담당 선생님의 채점지 이름과 번호+
teaching.read · teaching.options.exams
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
[].name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
}
},
"required": [
"id",
"name"
]
}
}성공 응답 예시
{
"data": [
{
"id": "1",
"name": "예시 이름"
}
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/options/seasons실제 저장된 과제장 학기·기간 선택 목록+
teaching.read · teaching.options.seasons
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "string"
}
}성공 응답 예시
{
"data": [
"예시"
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/options/teachers과제장 등록에서 실제 선택 가능한 담당 선생님 이름과 번호+
teaching.read · teaching.options.teachers
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
[].name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
}
},
"required": [
"id",
"name"
]
}
}성공 응답 예시
{
"data": [
{
"id": "1",
"name": "예시 이름"
}
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/options/templates공유 템플릿 불러오기에서 실제 선택 가능한 과제장 목록+
teaching.read · teaching.options.templates
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
[].name | string | 필수 | 이름 또는 표시 명칭입니다. | "예시 이름" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "이름 또는 표시 명칭입니다.",
"nullable": false
}
},
"required": [
"id",
"name"
]
}
}성공 응답 예시
{
"data": [
{
"id": "1",
"name": "예시 이름"
}
],
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/teaching/seasons선택 과제장의 학기·기간 일괄 변경+
teaching.write · teaching.season.update
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
lessonIds | array | 필수 | GET /v1/teaching/lessons 응답 data.items[].id에서 선택한 과제장 번호들을 배열로 전달합니다. 중복 없이 1~100개입니다. | 하위 필드·본문 예시 참조 |
season | string | 조건부·선택 | 변경할 학기·기간 구분입니다. 빈 문자열은 미지정입니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"lessonIds": {
"type": "array",
"items": {
"type": "integer"
},
"description": "GET /v1/teaching/lessons 응답 data.items[].id에서 선택한 과제장 번호들을 배열로 전달합니다. 중복 없이 1~100개입니다.",
"nullable": false,
"minItems": 1,
"maxItems": 100
},
"season": {
"type": "string",
"description": "변경할 학기·기간 구분입니다. 빈 문자열은 미지정입니다.",
"nullable": false,
"maxLength": 100,
"default": ""
}
},
"required": [
"lessonIds"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
count | integer | 필수 | 정상 처리된 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"count": {
"type": "integer",
"description": "정상 처리된 자료 수입니다.",
"nullable": false
}
},
"required": [
"count"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"lessonIds": [
1
],
"season": "예시"
}성공 응답 예시
{
"data": {
"count": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/teams/{id}/course반별 과제장 분류·교과·저장 양식과 실제 적용 양식 조회(시간표 자동 선택 없음)+
teaching.read · teaching.options.course
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | 대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
teamId | integer | 필수 | 수강반 번호입니다. | 1 |
teamName | string | 필수 | 실제 수강반 이름입니다. | "예시 이름" |
class | string | 필수 | 저장된 과제장 분류입니다. | "예시" |
group | string | 필수 | 저장된 교과 그룹입니다. | "예시" |
apiFlag | integer | 필수 | 수강반의 저장된 과제장 사용 구분입니다. | 1 |
report | integer | 필수 | 현재 과제장 성적표 양식 번호입니다. 0은 미설정 값입니다. | 1 |
version | string | 필수 | 변경 전 다시 확인해야 하는 현재 설정의 검증 값입니다. | "예시" |
effectiveReport | integer | 필수 | 실제 적용되는 과제장 성적표 양식입니다. 82는 누적형이며, 미지정 0을 포함한 나머지는 관리자 화면과 동일한 당일형 80입니다. 저장된 report는 바꾸지 않습니다. | 1 |
storedReportName | string | 필수 | 저장된 양식의 이름입니다. 0은 미지정이며, 미지정 상태에서도 실제 적용 양식은 당일형입니다. | "예시 이름" |
reportName | string | 필수 | 실제 적용 양식 이름입니다. 당일형 또는 누적형입니다. | "예시 이름" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"teamId": {
"type": "integer",
"description": "수강반 번호입니다.",
"nullable": false
},
"teamName": {
"type": "string",
"description": "실제 수강반 이름입니다.",
"nullable": false
},
"class": {
"type": "string",
"description": "저장된 과제장 분류입니다.",
"nullable": false
},
"group": {
"type": "string",
"description": "저장된 교과 그룹입니다.",
"nullable": false
},
"apiFlag": {
"type": "integer",
"description": "수강반의 저장된 과제장 사용 구분입니다.",
"nullable": false
},
"report": {
"type": "integer",
"description": "현재 과제장 성적표 양식 번호입니다. 0은 미설정 값입니다.",
"nullable": false
},
"version": {
"type": "string",
"description": "변경 전 다시 확인해야 하는 현재 설정의 검증 값입니다.",
"nullable": false
},
"effectiveReport": {
"type": "integer",
"description": "실제 적용되는 과제장 성적표 양식입니다. 82는 누적형이며, 미지정 0을 포함한 나머지는 관리자 화면과 동일한 당일형 80입니다. 저장된 report는 바꾸지 않습니다.",
"nullable": false
},
"storedReportName": {
"type": "string",
"description": "저장된 양식의 이름입니다. 0은 미지정이며, 미지정 상태에서도 실제 적용 양식은 당일형입니다.",
"nullable": false
},
"reportName": {
"type": "string",
"description": "실제 적용 양식 이름입니다. 당일형 또는 누적형입니다.",
"nullable": false
}
},
"required": [
"teamId",
"teamName",
"class",
"group",
"apiFlag",
"report",
"version",
"effectiveReport",
"storedReportName",
"reportName"
]
}성공 응답 예시
{
"data": {
"teamId": 1,
"teamName": "예시 이름",
"class": "예시",
"group": "예시",
"apiFlag": 1,
"report": 1,
"version": "예시",
"effectiveReport": 1,
"storedReportName": "예시 이름",
"reportName": "예시 이름"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/teams/{id}/registration-defaults반별 최근 학기·다음 회차와 실제 시간표에서 계산한 다음 수업일 후보(저장·자동 지정 없음)+
teaching.read · teaching.options.defaults
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | 대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
teamId | integer | 필수 | 선택 수강반 번호입니다. | 1 |
lastSeason | string | 필수 | 최근 등록한 과제장의 학기입니다. 없으면 빈 값입니다. | "예시" |
nextOrder | integer | 필수 | 해당 반의 최대 회차 다음 값입니다. | 1 |
suggestedDate | string | 필수 | 실제 시간표로 계산한 다음 수업일 후보입니다. 없으면 null이며 사용자 확인 없이 저장하지 않습니다. | "2026-01-15" |
suggestedScheduleId | integer | 필수 | 후보 수업일에 해당하는 실제 시간표 번호입니다. 후보가 없으면 null입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"teamId": {
"type": "integer",
"description": "선택 수강반 번호입니다.",
"nullable": false
},
"lastSeason": {
"type": "string",
"description": "최근 등록한 과제장의 학기입니다. 없으면 빈 값입니다.",
"nullable": false
},
"nextOrder": {
"type": "integer",
"description": "해당 반의 최대 회차 다음 값입니다.",
"nullable": false
},
"suggestedDate": {
"type": "string",
"description": "실제 시간표로 계산한 다음 수업일 후보입니다. 없으면 null이며 사용자 확인 없이 저장하지 않습니다.",
"nullable": true
},
"suggestedScheduleId": {
"type": "integer",
"description": "후보 수업일에 해당하는 실제 시간표 번호입니다. 후보가 없으면 null입니다.",
"nullable": true
}
},
"required": [
"teamId",
"lastSeason",
"nextOrder",
"suggestedDate",
"suggestedScheduleId"
]
}성공 응답 예시
{
"data": {
"teamId": 1,
"lastSeason": "예시",
"nextOrder": 1,
"suggestedDate": "2026-01-15",
"suggestedScheduleId": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/teams/{id}/schedules선택 수강반의 실제 시간표 목록(요일에 맞는 시간표를 임의 지정하지 않음)+
teaching.read · teaching.options.schedules
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
id | path | 필수 | 대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | integer | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | 1 |
[].teamId | integer | 필수 | 수강반 고유 번호입니다. 수강반 조회에서 확인합니다. | 1 |
[].day | string | 필수 | 요일입니다. 월·화·수·목·금·토·일 중 하나입니다. | "월" |
[].from | string | 필수 | 수업 시작 시각입니다. HHmm 형식입니다. | "2026-01-15" |
[].to | string | 필수 | 수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다. | "2026-01-15" |
[].beginDate | string | 필수 | 시간표 적용 시작일입니다. yyyyMMdd 문자열이며 0은 미설정입니다. | "2026-01-15" |
[].endDate | string | 필수 | 시간표 적용 종료일입니다. yyyyMMdd 문자열이며 0은 미설정입니다. | "2026-01-15" |
[].kind | integer | 필수 | 시간표 종류입니다. 1은 수업, 2는 상담입니다. | 1 |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "수강반 고유 번호입니다. 수강반 조회에서 확인합니다.",
"nullable": false
},
"day": {
"type": "string",
"enum": [
"월",
"화",
"수",
"목",
"금",
"토",
"일"
],
"description": "요일입니다. 월·화·수·목·금·토·일 중 하나입니다.",
"nullable": false
},
"from": {
"type": "string",
"description": "수업 시작 시각입니다. HHmm 형식입니다.",
"nullable": false
},
"to": {
"type": "string",
"description": "수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다.",
"nullable": false
},
"beginDate": {
"type": "string",
"description": "시간표 적용 시작일입니다. yyyyMMdd 문자열이며 0은 미설정입니다.",
"nullable": false
},
"endDate": {
"type": "string",
"description": "시간표 적용 종료일입니다. yyyyMMdd 문자열이며 0은 미설정입니다.",
"nullable": false
},
"kind": {
"type": "integer",
"description": "시간표 종류입니다. 1은 수업, 2는 상담입니다.",
"nullable": false
}
},
"required": [
"id",
"teamId",
"day",
"from",
"to",
"beginDate",
"endDate",
"kind"
]
}
}성공 응답 예시
{
"data": [
{
"id": 1,
"teamId": 1,
"day": "월",
"from": "2026-01-15",
"to": "2026-01-15",
"beginDate": "2026-01-15",
"endDate": "2026-01-15",
"kind": 1
}
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/todos기간별 재검사 일정 목록+
teaching.read · teaching.todos.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
teamId | query | 선택 | GET /v1/teams 응답 data.items[].id의 정수 번호로 결과를 제한합니다. 검색 조건에서 생략하면 전체 반입니다. |
from | query | 필수 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 필수 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
items[].lessonId | integer | 필수 | 재검사 일정의 원래 과제장 번호입니다. | 1 |
items[].studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
items[].studentName | string | 필수 | 학생 이름입니다. | "예시 이름" |
items[].plannedAt | string | 필수 | 재검사 예정일시입니다. 시간이 없으면 yyyy-MM-dd, 있으면 yyyy-MM-ddTHH:mm입니다. | "예시" |
items[].comment | string | 필수 | 재검사 메모입니다. | "예시" |
items[].status | string | 필수 | 예약·완료·취소·불참·변경 중 처리 상태입니다. | "예시" |
items[].teamId | integer | 필수 | 원래 수업의 수강반 번호입니다. | 1 |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"lessonId": {
"type": "integer",
"description": "재검사 일정의 원래 과제장 번호입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"studentName": {
"type": "string",
"description": "학생 이름입니다.",
"nullable": false
},
"plannedAt": {
"type": "string",
"description": "재검사 예정일시입니다. 시간이 없으면 yyyy-MM-dd, 있으면 yyyy-MM-ddTHH:mm입니다.",
"nullable": false
},
"comment": {
"type": "string",
"description": "재검사 메모입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "예약·완료·취소·불참·변경 중 처리 상태입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "원래 수업의 수강반 번호입니다.",
"nullable": false
}
},
"required": [
"id",
"lessonId",
"studentId",
"studentName",
"plannedAt",
"comment",
"status",
"teamId"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"id": 1,
"lessonId": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"plannedAt": "예시",
"comment": "예시",
"status": "예시",
"teamId": 1
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/todos/{todoId}재검사 일정 상세+
teaching.read · teaching.todos.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
todoId | path | 필수 | GET /v1/teaching/todos 응답 data.items[].id의 재검사 기록 번호입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
lessonId | integer | 필수 | 재검사 일정의 원래 과제장 번호입니다. | 1 |
studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
studentName | string | 필수 | 학생 이름입니다. | "예시 이름" |
plannedAt | string | 필수 | 재검사 예정일시입니다. 시간이 없으면 yyyy-MM-dd, 있으면 yyyy-MM-ddTHH:mm입니다. | "예시" |
comment | string | 필수 | 재검사 메모입니다. | "예시" |
status | string | 필수 | 예약·완료·취소·불참·변경 중 처리 상태입니다. | "예시" |
teamId | integer | 필수 | 원래 수업의 수강반 번호입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"lessonId": {
"type": "integer",
"description": "재검사 일정의 원래 과제장 번호입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"studentName": {
"type": "string",
"description": "학생 이름입니다.",
"nullable": false
},
"plannedAt": {
"type": "string",
"description": "재검사 예정일시입니다. 시간이 없으면 yyyy-MM-dd, 있으면 yyyy-MM-ddTHH:mm입니다.",
"nullable": false
},
"comment": {
"type": "string",
"description": "재검사 메모입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "예약·완료·취소·불참·변경 중 처리 상태입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "원래 수업의 수강반 번호입니다.",
"nullable": false
}
},
"required": [
"id",
"lessonId",
"studentId",
"studentName",
"plannedAt",
"comment",
"status",
"teamId"
]
}성공 응답 예시
{
"data": {
"id": 1,
"lessonId": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"plannedAt": "예시",
"comment": "예시",
"status": "예시",
"teamId": 1
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/teaching/todos/{todoId}재검사 메모·날짜·처리 결과 저장+
teaching.write · teaching.todos.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
todoId | path | 필수 | GET /v1/teaching/todos 응답 data.items[].id의 재검사 기록 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
comment | string | 조건부·선택 | 재검사 메모입니다. 일정 변경은 yyyy-MM-dd HH:mm 날짜를 포함합니다. 날짜가 없으면 일정을 지웁니다. | "예시" |
status | string | 조건부·선택 | 예약·완료·취소·불참·변경 또는 빈 문자열입니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"comment": {
"type": "string",
"description": "재검사 메모입니다. 일정 변경은 yyyy-MM-dd HH:mm 날짜를 포함합니다. 날짜가 없으면 일정을 지웁니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"status": {
"type": "string",
"description": "예약·완료·취소·불참·변경 또는 빈 문자열입니다.",
"nullable": false,
"default": "",
"pattern": "^(예약|완료|취소|불참|변경)?$"
}
}
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"comment": "예시",
"status": "예시"
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/cumulative-results기간별 누적 과제·시험·출결 결과. valueItems가 같은 수업의 제목·슬롯·표시 안내·결과를 연결. 값만으로 만점·단위를 추측하지 않음+
teaching.read · teaching.cumulative.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
teamId | query | 선택 | GET /v1/teams 응답 data.items[].id의 정수 번호로 결과를 제한합니다. 검색 조건에서 생략하면 전체 반입니다. |
from | query | 필수 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 필수 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
scheduleId | query | 선택 | GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다. |
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
studentId | query | 선택 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].teamName | string | 필수 | 해당 수업의 실제 수강반 이름입니다. 학생의 다른 반이나 보강 원래 반의 이름이 아닙니다. | "예시 이름" |
items[].id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
items[].lessonId | integer | 필수 | 과제장 수업 번호입니다. | 1 |
items[].studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
items[].studentName | string | 필수 | 학생 이름입니다. | "예시 이름" |
items[].attendanceCode | integer | 필수 | 출결 코드입니다. 0 무결(무단결석), 4 인정결석(인결), 5 출석, 6 인강, 7 보강완료, 8 타반에서 온 보강생입니다. | 1 |
items[].absent | boolean | 필수 | 무결 또는 인정결석이면 true입니다. | false |
items[].originalTeamId | integer | 필수 | 보강생의 원래 반 번호입니다. 일반 학생과 보강완료 학생은 0입니다. | 1 |
items[].originalLessonId | integer | 필수 | 보강 연결의 원래 결석 수업 번호입니다. 연결이 없으면 0입니다. | 1 |
items[].values | object | 필수 | 과제·시험 결과와 메모입니다. | 하위 필드·본문 예시 참조 |
items[].values.nes1 | string | 조건부·선택 | 과제 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.nes2 | string | 조건부·선택 | 과제 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.nes3 | string | 조건부·선택 | 과제 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.nes4 | string | 조건부·선택 | 과제 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.nes5 | string | 조건부·선택 | 과제 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.nes6 | string | 조건부·선택 | 과제 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.cag1 | string | 조건부·선택 | 도전 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.cag2 | string | 조건부·선택 | 도전 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.exam1 | string | 조건부·선택 | 시험 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.exam2 | string | 조건부·선택 | 시험 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.exam3 | string | 조건부·선택 | 시험 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.exam4 | string | 조건부·선택 | 시험 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.exam5 | string | 조건부·선택 | 시험 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.exam6 | string | 조건부·선택 | 시험 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.etc | string | 조건부·선택 | 학생별 기타 검사 결과입니다. 생략하면 유지합니다. | "예시" |
items[].values.comment | string | 조건부·선택 | 학생별 수업 메모입니다. yyyy-MM-dd HH:mm 날짜를 포함하면 기존 규칙으로 재검사 일정을 인식합니다. | "예시" |
items[].values.re_Exam1 | boolean | 조건부·선택 | 시험 1의 재시험 대상 여부입니다. 생략하면 유지합니다. | false |
items[].values.re_Exam_Result1 | string | 조건부·선택 | 시험 1 재시험 결과입니다. 생략하면 유지합니다. | "예시" |
items[].values.re_Exam2 | boolean | 조건부·선택 | 시험 2의 재시험 대상 여부입니다. 생략하면 유지합니다. | false |
items[].values.re_Exam_Result2 | string | 조건부·선택 | 시험 2 재시험 결과입니다. 생략하면 유지합니다. | "예시" |
items[].values.re_Exam3 | boolean | 조건부·선택 | 시험 3의 재시험 대상 여부입니다. 생략하면 유지합니다. | false |
items[].values.re_Exam_Result3 | string | 조건부·선택 | 시험 3 재시험 결과입니다. 생략하면 유지합니다. | "예시" |
items[].valueItems | array | 필수 | 같은 수업의 항목 제목·결과 안내·슬롯 번호와 학생 결과를 명시적으로 연결한 읽기 전용 자료입니다. 배열 순서로 의미나 단위를 추정하지 마세요. 수정할 때는 field에 대응하는 values 필드를 사용하세요. | 하위 필드·본문 예시 참조 |
items[].valueItems[].field | string | 필수 | 저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요. | "예시" |
items[].valueItems[].category | string | 필수 | 과제, 도전, 시험 중 항목 종류입니다. | "예시" |
items[].valueItems[].position | integer | 필수 | 같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다. | 1 |
items[].valueItems[].title | string | 필수 | 같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요. | "예시" |
items[].valueItems[].content | string | 필수 | 같은 수업 설정의 과제·시험 내용 원문입니다. | "예시" |
items[].valueItems[].resultGuide | string | 필수 | 같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요. | "예시" |
items[].valueItems[].value | string | 필수 | 해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다. | "예시" |
items[].valueItems[].valueState | string | 필수 | present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다. | "예시" |
items[].valueItems[].examId | integer | 필수 | 같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다. | 1 |
items[].attendanceName | string | 필수 | attendanceCode와 같은 원본 코드표의 출결 명칭입니다. | "예시 이름" |
items[].date | string | 필수 | 수업 등록일입니다. yyyy-MM-dd 형식입니다. | "2026-01-15" |
items[].teamId | integer | 필수 | 해당 수업의 수강반 번호입니다. | 1 |
items[].scheduleId | integer | 필수 | 수업 시간표 번호입니다. | 1 |
items[].teacherId | integer | 필수 | 담당 선생님 번호입니다. | 1 |
items[].title | string | 필수 | 수업·과제장 제목입니다. | "예시" |
items[].season | string | 필수 | 학기·기간 구분입니다. | "예시" |
items[].order | integer | 필수 | 수업 회차입니다. | 1 |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"teamName": {
"type": "string",
"description": "해당 수업의 실제 수강반 이름입니다. 학생의 다른 반이나 보강 원래 반의 이름이 아닙니다.",
"nullable": false
},
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"lessonId": {
"type": "integer",
"description": "과제장 수업 번호입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"studentName": {
"type": "string",
"description": "학생 이름입니다.",
"nullable": false
},
"attendanceCode": {
"type": "integer",
"x-read-display-field": "attendanceName",
"description": "출결 코드입니다. 0 무결(무단결석), 4 인정결석(인결), 5 출석, 6 인강, 7 보강완료, 8 타반에서 온 보강생입니다.",
"nullable": false
},
"absent": {
"type": "boolean",
"x-read-scope-key": "absence",
"description": "무결 또는 인정결석이면 true입니다.",
"nullable": false
},
"originalTeamId": {
"type": "integer",
"description": "보강생의 원래 반 번호입니다. 일반 학생과 보강완료 학생은 0입니다.",
"nullable": false
},
"originalLessonId": {
"type": "integer",
"description": "보강 연결의 원래 결석 수업 번호입니다. 연결이 없으면 0입니다.",
"nullable": false
},
"values": {
"type": "object",
"properties": {
"nes1": {
"type": "string",
"description": "과제 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes2": {
"type": "string",
"description": "과제 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes3": {
"type": "string",
"description": "과제 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes4": {
"type": "string",
"description": "과제 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes5": {
"type": "string",
"description": "과제 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes6": {
"type": "string",
"description": "과제 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"cag1": {
"type": "string",
"description": "도전 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"cag2": {
"type": "string",
"description": "도전 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam1": {
"type": "string",
"description": "시험 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam2": {
"type": "string",
"description": "시험 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam3": {
"type": "string",
"description": "시험 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam4": {
"type": "string",
"description": "시험 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam5": {
"type": "string",
"description": "시험 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam6": {
"type": "string",
"description": "시험 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"etc": {
"type": "string",
"description": "학생별 기타 검사 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
},
"comment": {
"type": "string",
"description": "학생별 수업 메모입니다. yyyy-MM-dd HH:mm 날짜를 포함하면 기존 규칙으로 재검사 일정을 인식합니다.",
"nullable": true,
"maxLength": 4000
},
"re_Exam1": {
"type": "boolean",
"description": "시험 1의 재시험 대상 여부입니다. 생략하면 유지합니다.",
"nullable": true
},
"re_Exam_Result1": {
"type": "string",
"description": "시험 1 재시험 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
},
"re_Exam2": {
"type": "boolean",
"description": "시험 2의 재시험 대상 여부입니다. 생략하면 유지합니다.",
"nullable": true
},
"re_Exam_Result2": {
"type": "string",
"description": "시험 2 재시험 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
},
"re_Exam3": {
"type": "boolean",
"description": "시험 3의 재시험 대상 여부입니다. 생략하면 유지합니다.",
"nullable": true
},
"re_Exam_Result3": {
"type": "string",
"description": "시험 3 재시험 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
}
},
"description": "과제·시험 결과와 메모입니다.",
"nullable": false
},
"valueItems": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field": {
"type": "string",
"description": "저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요.",
"nullable": false
},
"category": {
"type": "string",
"description": "과제, 도전, 시험 중 항목 종류입니다.",
"nullable": false
},
"position": {
"type": "integer",
"description": "같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요.",
"nullable": false
},
"content": {
"type": "string",
"description": "같은 수업 설정의 과제·시험 내용 원문입니다.",
"nullable": false
},
"resultGuide": {
"type": "string",
"description": "같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요.",
"nullable": false
},
"value": {
"type": "string",
"description": "해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다.",
"nullable": true
},
"valueState": {
"type": "string",
"description": "present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다.",
"nullable": false
}
},
"required": [
"field",
"category",
"position",
"title",
"content",
"resultGuide",
"value",
"valueState",
"examId"
]
},
"description": "같은 수업의 항목 제목·결과 안내·슬롯 번호와 학생 결과를 명시적으로 연결한 읽기 전용 자료입니다. 배열 순서로 의미나 단위를 추정하지 마세요. 수정할 때는 field에 대응하는 values 필드를 사용하세요.",
"nullable": false
},
"attendanceName": {
"type": "string",
"description": "attendanceCode와 같은 원본 코드표의 출결 명칭입니다.",
"nullable": false
},
"date": {
"type": "string",
"description": "수업 등록일입니다. yyyy-MM-dd 형식입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "해당 수업의 수강반 번호입니다.",
"nullable": false
},
"scheduleId": {
"type": "integer",
"description": "수업 시간표 번호입니다.",
"nullable": false
},
"teacherId": {
"type": "integer",
"description": "담당 선생님 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "수업·과제장 제목입니다.",
"nullable": false
},
"season": {
"type": "string",
"description": "학기·기간 구분입니다.",
"nullable": false
},
"order": {
"type": "integer",
"description": "수업 회차입니다.",
"nullable": false
}
},
"required": [
"teamName",
"id",
"lessonId",
"studentId",
"studentName",
"attendanceCode",
"absent",
"originalTeamId",
"originalLessonId",
"values",
"valueItems",
"attendanceName",
"date",
"teamId",
"scheduleId",
"teacherId",
"title",
"season",
"order"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"teamName": "예시 이름",
"id": 1,
"lessonId": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"attendanceCode": 1,
"absent": false,
"originalTeamId": 1,
"originalLessonId": 1,
"values": {
"nes1": "예시",
"nes2": "예시",
"nes3": "예시",
"nes4": "예시",
"nes5": "예시",
"nes6": "예시",
"cag1": "예시",
"cag2": "예시",
"exam1": "예시",
"exam2": "예시",
"exam3": "예시",
"exam4": "예시",
"exam5": "예시",
"exam6": "예시",
"etc": "예시",
"comment": "예시",
"re_Exam1": false,
"re_Exam_Result1": "예시",
"re_Exam2": false,
"re_Exam_Result2": "예시",
"re_Exam3": false,
"re_Exam_Result3": "예시"
},
"valueItems": [
{
"field": "예시",
"category": "예시",
"position": 1,
"title": "예시",
"content": "예시",
"resultGuide": "예시",
"value": "예시",
"valueState": "예시",
"examId": 1
}
],
"attendanceName": "예시 이름",
"date": "2026-01-15",
"teamId": 1,
"scheduleId": 1,
"teacherId": 1,
"title": "예시",
"season": "예시",
"order": 1
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/attendance/checks학생 입퇴실 체크 내역+
attendance.read · attendance.checks.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
from | query | 필수 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 필수 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
studentId | query | 선택 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
items[].studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
items[].studentName | string | 필수 | 학생 이름입니다. | "예시 이름" |
items[].date | integer | 필수 | 입퇴실 확인일입니다. yyyyMMdd 정수입니다. | 20260115 |
items[].time | string | 필수 | 한국 시간 HH:mm입니다. | "14:00" |
items[].kind | integer | 필수 | 입실 0, 퇴실 1입니다. | 1 |
items[].source | integer | 필수 | 기존 패드와 호환되는 확인 경로 코드입니다. | 1 |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"studentName": {
"type": "string",
"description": "학생 이름입니다.",
"nullable": false
},
"date": {
"type": "integer",
"description": "입퇴실 확인일입니다. yyyyMMdd 정수입니다.",
"nullable": false
},
"time": {
"type": "string",
"description": "한국 시간 HH:mm입니다.",
"nullable": false
},
"kind": {
"type": "integer",
"description": "입실 0, 퇴실 1입니다.",
"nullable": false
},
"source": {
"type": "integer",
"description": "기존 패드와 호환되는 확인 경로 코드입니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"studentName",
"date",
"time",
"kind",
"source"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"id": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"date": 20260115,
"time": "14:00",
"kind": 1,
"source": 1
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/attendance/checks현재 시각 입실·퇴실 기록(수업 출석 아님·발송 없음)+
attendance.write · attendance.checks.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
kind | integer | 조건부·선택 | 입실은 0, 퇴실은 1입니다. 지정한 상태로 기록하며 문자·알림톡은 발송하지 않습니다. | 0 |
요청 JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"kind": {
"type": "integer",
"description": "입실은 0, 퇴실은 1입니다. 지정한 상태로 기록하며 문자·알림톡은 발송하지 않습니다.",
"nullable": false,
"minimum": 0,
"maximum": 1,
"default": 0
}
},
"required": [
"studentId"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"studentId": "00000001",
"kind": 0
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/attendance/checks/{checkId}학생 입퇴실 기록 삭제+
attendance.write · attendance.checks.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
checkId | path | 필수 | GET /v1/attendance/checks 응답 data.items[].id의 입퇴실 기록 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/attendance/daily반·날짜별 학생 이름·출결 상태·검사 조회. teamId와 from/to로 직접 조회하며 lessonId 불필요. 출결 단순 조회에 우선 사용+
attendance.read · attendance.daily.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
teamId | query | 선택 | GET /v1/teams 응답 data.items[].id의 정수 번호로 결과를 제한합니다. 검색 조건에서 생략하면 전체 반입니다. |
from | query | 필수 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 필수 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
scheduleId | query | 선택 | GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다. |
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
studentId | query | 선택 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].teamName | string | 필수 | 해당 수업의 실제 수강반 이름입니다. 학생의 다른 반이나 보강 원래 반의 이름이 아닙니다. | "예시 이름" |
items[].id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
items[].lessonId | integer | 필수 | 과제장 수업 번호입니다. | 1 |
items[].studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
items[].studentName | string | 필수 | 학생 이름입니다. | "예시 이름" |
items[].attendanceCode | integer | 필수 | 출결 코드입니다. 0 무결(무단결석), 4 인정결석(인결), 5 출석, 6 인강, 7 보강완료, 8 타반에서 온 보강생입니다. | 1 |
items[].absent | boolean | 필수 | 무결 또는 인정결석이면 true입니다. | false |
items[].originalTeamId | integer | 필수 | 보강생의 원래 반 번호입니다. 일반 학생과 보강완료 학생은 0입니다. | 1 |
items[].originalLessonId | integer | 필수 | 보강 연결의 원래 결석 수업 번호입니다. 연결이 없으면 0입니다. | 1 |
items[].values | object | 필수 | 과제·시험 결과와 메모입니다. | 하위 필드·본문 예시 참조 |
items[].values.nes1 | string | 조건부·선택 | 과제 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.nes2 | string | 조건부·선택 | 과제 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.nes3 | string | 조건부·선택 | 과제 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.nes4 | string | 조건부·선택 | 과제 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.nes5 | string | 조건부·선택 | 과제 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.nes6 | string | 조건부·선택 | 과제 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.cag1 | string | 조건부·선택 | 도전 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.cag2 | string | 조건부·선택 | 도전 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.exam1 | string | 조건부·선택 | 시험 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.exam2 | string | 조건부·선택 | 시험 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.exam3 | string | 조건부·선택 | 시험 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.exam4 | string | 조건부·선택 | 시험 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.exam5 | string | 조건부·선택 | 시험 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.exam6 | string | 조건부·선택 | 시험 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다. | "예시" |
items[].values.etc | string | 조건부·선택 | 학생별 기타 검사 결과입니다. 생략하면 유지합니다. | "예시" |
items[].values.comment | string | 조건부·선택 | 학생별 수업 메모입니다. yyyy-MM-dd HH:mm 날짜를 포함하면 기존 규칙으로 재검사 일정을 인식합니다. | "예시" |
items[].values.re_Exam1 | boolean | 조건부·선택 | 시험 1의 재시험 대상 여부입니다. 생략하면 유지합니다. | false |
items[].values.re_Exam_Result1 | string | 조건부·선택 | 시험 1 재시험 결과입니다. 생략하면 유지합니다. | "예시" |
items[].values.re_Exam2 | boolean | 조건부·선택 | 시험 2의 재시험 대상 여부입니다. 생략하면 유지합니다. | false |
items[].values.re_Exam_Result2 | string | 조건부·선택 | 시험 2 재시험 결과입니다. 생략하면 유지합니다. | "예시" |
items[].values.re_Exam3 | boolean | 조건부·선택 | 시험 3의 재시험 대상 여부입니다. 생략하면 유지합니다. | false |
items[].values.re_Exam_Result3 | string | 조건부·선택 | 시험 3 재시험 결과입니다. 생략하면 유지합니다. | "예시" |
items[].valueItems | array | 필수 | 같은 수업의 항목 제목·결과 안내·슬롯 번호와 학생 결과를 명시적으로 연결한 읽기 전용 자료입니다. 배열 순서로 의미나 단위를 추정하지 마세요. 수정할 때는 field에 대응하는 values 필드를 사용하세요. | 하위 필드·본문 예시 참조 |
items[].valueItems[].field | string | 필수 | 저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요. | "예시" |
items[].valueItems[].category | string | 필수 | 과제, 도전, 시험 중 항목 종류입니다. | "예시" |
items[].valueItems[].position | integer | 필수 | 같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다. | 1 |
items[].valueItems[].title | string | 필수 | 같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요. | "예시" |
items[].valueItems[].content | string | 필수 | 같은 수업 설정의 과제·시험 내용 원문입니다. | "예시" |
items[].valueItems[].resultGuide | string | 필수 | 같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요. | "예시" |
items[].valueItems[].value | string | 필수 | 해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다. | "예시" |
items[].valueItems[].valueState | string | 필수 | present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다. | "예시" |
items[].valueItems[].examId | integer | 필수 | 같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다. | 1 |
items[].attendanceName | string | 필수 | attendanceCode와 같은 원본 코드표의 출결 명칭입니다. | "예시 이름" |
items[].date | string | 필수 | 수업 등록일입니다. yyyy-MM-dd 형식입니다. | "2026-01-15" |
items[].teamId | integer | 필수 | 해당 수업의 수강반 번호입니다. | 1 |
items[].scheduleId | integer | 필수 | 수업 시간표 번호입니다. | 1 |
items[].teacherId | integer | 필수 | 담당 선생님 번호입니다. | 1 |
items[].title | string | 필수 | 수업·과제장 제목입니다. | "예시" |
items[].season | string | 필수 | 학기·기간 구분입니다. | "예시" |
items[].order | integer | 필수 | 수업 회차입니다. | 1 |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"teamName": {
"type": "string",
"description": "해당 수업의 실제 수강반 이름입니다. 학생의 다른 반이나 보강 원래 반의 이름이 아닙니다.",
"nullable": false
},
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"lessonId": {
"type": "integer",
"description": "과제장 수업 번호입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"studentName": {
"type": "string",
"description": "학생 이름입니다.",
"nullable": false
},
"attendanceCode": {
"type": "integer",
"x-read-display-field": "attendanceName",
"description": "출결 코드입니다. 0 무결(무단결석), 4 인정결석(인결), 5 출석, 6 인강, 7 보강완료, 8 타반에서 온 보강생입니다.",
"nullable": false
},
"absent": {
"type": "boolean",
"x-read-scope-key": "absence",
"description": "무결 또는 인정결석이면 true입니다.",
"nullable": false
},
"originalTeamId": {
"type": "integer",
"description": "보강생의 원래 반 번호입니다. 일반 학생과 보강완료 학생은 0입니다.",
"nullable": false
},
"originalLessonId": {
"type": "integer",
"description": "보강 연결의 원래 결석 수업 번호입니다. 연결이 없으면 0입니다.",
"nullable": false
},
"values": {
"type": "object",
"properties": {
"nes1": {
"type": "string",
"description": "과제 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes2": {
"type": "string",
"description": "과제 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes3": {
"type": "string",
"description": "과제 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes4": {
"type": "string",
"description": "과제 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes5": {
"type": "string",
"description": "과제 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"nes6": {
"type": "string",
"description": "과제 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"cag1": {
"type": "string",
"description": "도전 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"cag2": {
"type": "string",
"description": "도전 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam1": {
"type": "string",
"description": "시험 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam2": {
"type": "string",
"description": "시험 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam3": {
"type": "string",
"description": "시험 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam4": {
"type": "string",
"description": "시험 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam5": {
"type": "string",
"description": "시험 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"exam6": {
"type": "string",
"description": "시험 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다.",
"nullable": true,
"maxLength": 4000
},
"etc": {
"type": "string",
"description": "학생별 기타 검사 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
},
"comment": {
"type": "string",
"description": "학생별 수업 메모입니다. yyyy-MM-dd HH:mm 날짜를 포함하면 기존 규칙으로 재검사 일정을 인식합니다.",
"nullable": true,
"maxLength": 4000
},
"re_Exam1": {
"type": "boolean",
"description": "시험 1의 재시험 대상 여부입니다. 생략하면 유지합니다.",
"nullable": true
},
"re_Exam_Result1": {
"type": "string",
"description": "시험 1 재시험 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
},
"re_Exam2": {
"type": "boolean",
"description": "시험 2의 재시험 대상 여부입니다. 생략하면 유지합니다.",
"nullable": true
},
"re_Exam_Result2": {
"type": "string",
"description": "시험 2 재시험 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
},
"re_Exam3": {
"type": "boolean",
"description": "시험 3의 재시험 대상 여부입니다. 생략하면 유지합니다.",
"nullable": true
},
"re_Exam_Result3": {
"type": "string",
"description": "시험 3 재시험 결과입니다. 생략하면 유지합니다.",
"nullable": true,
"maxLength": 4000
}
},
"description": "과제·시험 결과와 메모입니다.",
"nullable": false
},
"valueItems": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field": {
"type": "string",
"description": "저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요.",
"nullable": false
},
"category": {
"type": "string",
"description": "과제, 도전, 시험 중 항목 종류입니다.",
"nullable": false
},
"position": {
"type": "integer",
"description": "같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요.",
"nullable": false
},
"content": {
"type": "string",
"description": "같은 수업 설정의 과제·시험 내용 원문입니다.",
"nullable": false
},
"resultGuide": {
"type": "string",
"description": "같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요.",
"nullable": false
},
"value": {
"type": "string",
"description": "해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다.",
"nullable": true
},
"valueState": {
"type": "string",
"description": "present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다.",
"nullable": false
},
"examId": {
"type": "integer",
"description": "같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다.",
"nullable": false
}
},
"required": [
"field",
"category",
"position",
"title",
"content",
"resultGuide",
"value",
"valueState",
"examId"
]
},
"description": "같은 수업의 항목 제목·결과 안내·슬롯 번호와 학생 결과를 명시적으로 연결한 읽기 전용 자료입니다. 배열 순서로 의미나 단위를 추정하지 마세요. 수정할 때는 field에 대응하는 values 필드를 사용하세요.",
"nullable": false
},
"attendanceName": {
"type": "string",
"description": "attendanceCode와 같은 원본 코드표의 출결 명칭입니다.",
"nullable": false
},
"date": {
"type": "string",
"description": "수업 등록일입니다. yyyy-MM-dd 형식입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "해당 수업의 수강반 번호입니다.",
"nullable": false
},
"scheduleId": {
"type": "integer",
"description": "수업 시간표 번호입니다.",
"nullable": false
},
"teacherId": {
"type": "integer",
"description": "담당 선생님 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "수업·과제장 제목입니다.",
"nullable": false
},
"season": {
"type": "string",
"description": "학기·기간 구분입니다.",
"nullable": false
},
"order": {
"type": "integer",
"description": "수업 회차입니다.",
"nullable": false
}
},
"required": [
"teamName",
"id",
"lessonId",
"studentId",
"studentName",
"attendanceCode",
"absent",
"originalTeamId",
"originalLessonId",
"values",
"valueItems",
"attendanceName",
"date",
"teamId",
"scheduleId",
"teacherId",
"title",
"season",
"order"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"teamName": "예시 이름",
"id": 1,
"lessonId": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"attendanceCode": 1,
"absent": false,
"originalTeamId": 1,
"originalLessonId": 1,
"values": {
"nes1": "예시",
"nes2": "예시",
"nes3": "예시",
"nes4": "예시",
"nes5": "예시",
"nes6": "예시",
"cag1": "예시",
"cag2": "예시",
"exam1": "예시",
"exam2": "예시",
"exam3": "예시",
"exam4": "예시",
"exam5": "예시",
"exam6": "예시",
"etc": "예시",
"comment": "예시",
"re_Exam1": false,
"re_Exam_Result1": "예시",
"re_Exam2": false,
"re_Exam_Result2": "예시",
"re_Exam3": false,
"re_Exam_Result3": "예시"
},
"valueItems": [
{
"field": "예시",
"category": "예시",
"position": 1,
"title": "예시",
"content": "예시",
"resultGuide": "예시",
"value": "예시",
"valueState": "예시",
"examId": 1
}
],
"attendanceName": "예시 이름",
"date": "2026-01-15",
"teamId": 1,
"scheduleId": 1,
"teacherId": 1,
"title": "예시",
"season": "예시",
"order": 1
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/attendance/students기간 내 전체 또는 선택 반의 학생별 출결 합계·결석 학생 명단 조회. 무결·유결 합계로 결석 구분, 타반 보강생 제외+
attendance.read · attendance.students.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
teamId | query | 선택 | GET /v1/teams 응답 data.items[].id의 정수 번호로 결과를 제한합니다. 검색 조건에서 생략하면 전체 반입니다. |
from | query | 필수 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 필수 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
scheduleId | query | 선택 | GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다. |
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
studentId | query | 선택 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
items[].studentName | string | 필수 | 학생 이름입니다. | "예시 이름" |
items[].total | integer | 필수 | 조회 기간의 일반 출석 기록 수입니다. 타반에서 온 보강생 기록은 제외합니다. | 1 |
items[].unexcused | integer | 필수 | 무결 횟수입니다. | 1 |
items[].excused | integer | 필수 | 인정결석 횟수입니다. | 1 |
items[].present | integer | 필수 | 출석 횟수입니다. | 1 |
items[].video | integer | 필수 | 인강 횟수입니다. | 1 |
items[].makeupCompleted | integer | 필수 | 원래 반에서 보강완료로 연결된 횟수입니다. | 1 |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"studentName": {
"type": "string",
"description": "학생 이름입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "조회 기간의 일반 출석 기록 수입니다. 타반에서 온 보강생 기록은 제외합니다.",
"nullable": false
},
"unexcused": {
"type": "integer",
"description": "무결 횟수입니다.",
"nullable": false
},
"excused": {
"type": "integer",
"description": "인정결석 횟수입니다.",
"nullable": false
},
"present": {
"type": "integer",
"description": "출석 횟수입니다.",
"nullable": false
},
"video": {
"type": "integer",
"description": "인강 횟수입니다.",
"nullable": false
},
"makeupCompleted": {
"type": "integer",
"description": "원래 반에서 보강완료로 연결된 횟수입니다.",
"nullable": false
}
},
"required": [
"studentId",
"studentName",
"total",
"unexcused",
"excused",
"present",
"video",
"makeupCompleted"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"studentId": "00000001",
"studentName": "예시 이름",
"total": 1,
"unexcused": 1,
"excused": 1,
"present": 1,
"video": 1,
"makeupCompleted": 1
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/clinic-appointments클리닉 실제 예약·입실·퇴실·불참·취소 학생 명단 조회(상태 동기화나 메시지 발송 없음)+
teaching.read · clinic.appointments.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
from | query | 필수 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 필수 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
studentId | query | 선택 | GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 예약 학생 기록 번호입니다. | 1 |
items[].clinicId | integer | 필수 | 클리닉 일정 번호입니다. | 1 |
items[].studentId | string | 필수 | 학생 번호입니다. | "00000001" |
items[].studentName | string | 필수 | 실제 학생 이름입니다. | "예시 이름" |
items[].teacherId | integer | 필수 | 예약 담당 선생님 번호입니다. | 1 |
items[].title | string | 필수 | 클리닉 일정 이름입니다. | "예시" |
items[].startsAt | string | 필수 | 저장된 한국 시각 기준 예약 일시입니다. | "예시" |
items[].status | string | 필수 | 저장된 예약·입실·퇴실·불참 상태입니다. | "예시" |
items[].cancelledAt | string | 필수 | 예약 취소 일시입니다. 미취소이면 null입니다. | "2026-01-15T00:00:00Z" |
items[].enteredAt | string | 필수 | 저장된 입실 일시입니다. | "2026-01-15T00:00:00Z" |
items[].exitedAt | string | 필수 | 저장된 퇴실 일시입니다. | "2026-01-15T00:00:00Z" |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "예약 학생 기록 번호입니다.",
"nullable": false
},
"clinicId": {
"type": "integer",
"description": "클리닉 일정 번호입니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "학생 번호입니다.",
"nullable": false
},
"studentName": {
"type": "string",
"description": "실제 학생 이름입니다.",
"nullable": false
},
"teacherId": {
"type": "integer",
"description": "예약 담당 선생님 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "클리닉 일정 이름입니다.",
"nullable": false
},
"startsAt": {
"type": "string",
"description": "저장된 한국 시각 기준 예약 일시입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "저장된 예약·입실·퇴실·불참 상태입니다.",
"nullable": false
},
"cancelledAt": {
"type": "string",
"format": "date-time",
"description": "예약 취소 일시입니다. 미취소이면 null입니다.",
"nullable": true
},
"enteredAt": {
"type": "string",
"format": "date-time",
"description": "저장된 입실 일시입니다.",
"nullable": true
},
"exitedAt": {
"type": "string",
"format": "date-time",
"description": "저장된 퇴실 일시입니다.",
"nullable": true
}
},
"required": [
"id",
"clinicId",
"studentId",
"studentName",
"teacherId",
"title",
"startsAt",
"status",
"cancelledAt",
"enteredAt",
"exitedAt"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"id": 1,
"clinicId": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"teacherId": 1,
"title": "예시",
"startsAt": "예시",
"status": "예시",
"cancelledAt": "2026-01-15T00:00:00Z",
"enteredAt": "2026-01-15T00:00:00Z",
"exitedAt": "2026-01-15T00:00:00Z"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/clinic-message-templates클리닉 문자 작성에서 저장된 문구 목록 조회(발송 없음)웹 관리 기능+
웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요teaching.read · clinic.templates.message
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | integer | 필수 | 저장된 문구 번호입니다. | 1 |
[].title | string | 필수 | 저장된 문구 제목입니다. | "예시" |
[].category | string | 필수 | 문구의 분류명입니다. | "예시" |
[].content | string | 필수 | 저장된 원문입니다. 조회만으로 치환하거나 발송하지 않습니다. | "예시" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "저장된 문구 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "저장된 문구 제목입니다.",
"nullable": false
},
"category": {
"type": "string",
"description": "문구의 분류명입니다.",
"nullable": false
},
"content": {
"type": "string",
"description": "저장된 원문입니다. 조회만으로 치환하거나 발송하지 않습니다.",
"nullable": false
}
},
"required": [
"id",
"title",
"category",
"content"
]
}
}성공 응답 예시
{
"data": [
{
"id": 1,
"title": "예시",
"category": "예시",
"content": "예시"
}
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/clinic-review-templates클리닉 리뷰 등록에서 저장된 리뷰 문구 목록 조회+
teaching.read · clinic.templates.review
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | integer | 필수 | 저장된 문구 번호입니다. | 1 |
[].title | string | 필수 | 저장된 문구 제목입니다. | "예시" |
[].category | string | 필수 | 문구의 분류명입니다. | "예시" |
[].content | string | 필수 | 저장된 원문입니다. 조회만으로 치환하거나 발송하지 않습니다. | "예시" |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "저장된 문구 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "저장된 문구 제목입니다.",
"nullable": false
},
"category": {
"type": "string",
"description": "문구의 분류명입니다.",
"nullable": false
},
"content": {
"type": "string",
"description": "저장된 원문입니다. 조회만으로 치환하거나 발송하지 않습니다.",
"nullable": false
}
},
"required": [
"id",
"title",
"category",
"content"
]
}
}성공 응답 예시
{
"data": [
{
"id": 1,
"title": "예시",
"category": "예시",
"content": "예시"
}
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/clinic-reviews기간별 클리닉 리뷰 목록+
teaching.read · teaching.clinics.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
teamId | query | 선택 | GET /v1/teams 응답 data.items[].id의 정수 번호로 결과를 제한합니다. 검색 조건에서 생략하면 전체 반입니다. |
from | query | 필수 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 필수 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
teacherId | query | 선택 | GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
items[].studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
items[].studentName | string | 필수 | 학생 이름입니다. | "예시 이름" |
items[].teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다. | 1 |
items[].scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요. | 1 |
items[].teacherId | integer | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다. | 1 |
items[].date | string | 필수 | 수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다. | "2026-01-15" |
items[].time | string | 필수 | 클리닉 시각입니다. HH:mm 또는 빈 문자열입니다. | "14:00" |
items[].lessonId | integer | 필수 | 연결된 과제장 번호입니다. | 1 |
items[].title | string | 필수 | 제목입니다. | "예시" |
items[].review | string | 필수 | 클리닉 리뷰 본문입니다. | "예시" |
items[].memo | string | 필수 | 내부 메모입니다. | "예시" |
items[].status | string | 필수 | 클리닉 처리 결과입니다. | "예시" |
items[].nextDate | string | 필수 | 변경 일자입니다. | "2026-01-15" |
items[].retest | boolean | 필수 | 재시험 여부입니다. | false |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"studentName": {
"type": "string",
"description": "학생 이름입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"teacherId": {
"type": "integer",
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"date": {
"type": "string",
"description": "수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다.",
"nullable": false,
"minLength": 1
},
"time": {
"type": "string",
"description": "클리닉 시각입니다. HH:mm 또는 빈 문자열입니다.",
"nullable": false
},
"lessonId": {
"type": "integer",
"description": "연결된 과제장 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "제목입니다.",
"nullable": false,
"maxLength": 200,
"minLength": 1
},
"review": {
"type": "string",
"description": "클리닉 리뷰 본문입니다.",
"nullable": false
},
"memo": {
"type": "string",
"description": "내부 메모입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "클리닉 처리 결과입니다.",
"nullable": false
},
"nextDate": {
"type": "string",
"description": "변경 일자입니다.",
"nullable": false
},
"retest": {
"type": "boolean",
"description": "재시험 여부입니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"studentName",
"teamId",
"scheduleId",
"teacherId",
"date",
"time",
"lessonId",
"title",
"review",
"memo",
"status",
"nextDate",
"retest"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"id": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"teamId": 1,
"scheduleId": 1,
"teacherId": 1,
"date": "2026-01-15",
"time": "14:00",
"lessonId": 1,
"title": "예시",
"review": "예시",
"memo": "예시",
"status": "예시",
"nextDate": "2026-01-15",
"retest": false
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/teaching/clinic-reviews/{reviewId}클리닉 리뷰 상세+
teaching.read · teaching.clinics.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
reviewId | path | 필수 | GET /v1/teaching/clinic-reviews 응답 data.items[].id의 클리닉 리뷰 번호입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
studentName | string | 필수 | 학생 이름입니다. | "예시 이름" |
teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다. | 1 |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요. | 1 |
teacherId | integer | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다. | 1 |
date | string | 필수 | 수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다. | "2026-01-15" |
time | string | 필수 | 클리닉 시각입니다. HH:mm 또는 빈 문자열입니다. | "14:00" |
lessonId | integer | 필수 | 연결된 과제장 번호입니다. | 1 |
title | string | 필수 | 제목입니다. | "예시" |
review | string | 필수 | 클리닉 리뷰 본문입니다. | "예시" |
memo | string | 필수 | 내부 메모입니다. | "예시" |
status | string | 필수 | 클리닉 처리 결과입니다. | "예시" |
nextDate | string | 필수 | 변경 일자입니다. | "2026-01-15" |
retest | boolean | 필수 | 재시험 여부입니다. | false |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"studentName": {
"type": "string",
"description": "학생 이름입니다.",
"nullable": false
},
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"teacherId": {
"type": "integer",
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"date": {
"type": "string",
"description": "수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다.",
"nullable": false,
"minLength": 1
},
"time": {
"type": "string",
"description": "클리닉 시각입니다. HH:mm 또는 빈 문자열입니다.",
"nullable": false
},
"lessonId": {
"type": "integer",
"description": "연결된 과제장 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "제목입니다.",
"nullable": false,
"maxLength": 200,
"minLength": 1
},
"review": {
"type": "string",
"description": "클리닉 리뷰 본문입니다.",
"nullable": false
},
"memo": {
"type": "string",
"description": "내부 메모입니다.",
"nullable": false
},
"status": {
"type": "string",
"description": "클리닉 처리 결과입니다.",
"nullable": false
},
"nextDate": {
"type": "string",
"description": "변경 일자입니다.",
"nullable": false
},
"retest": {
"type": "boolean",
"description": "재시험 여부입니다.",
"nullable": false
}
},
"required": [
"id",
"studentId",
"studentName",
"teamId",
"scheduleId",
"teacherId",
"date",
"time",
"lessonId",
"title",
"review",
"memo",
"status",
"nextDate",
"retest"
]
}성공 응답 예시
{
"data": {
"id": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"teamId": 1,
"scheduleId": 1,
"teacherId": 1,
"date": "2026-01-15",
"time": "14:00",
"lessonId": 1,
"title": "예시",
"review": "예시",
"memo": "예시",
"status": "예시",
"nextDate": "2026-01-15",
"retest": false
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/teaching/clinic-reviews클리닉 리뷰 등록+
teaching.write · teaching.clinics.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다. | 1 |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요. | 1 |
teacherId | integer | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다. | 1 |
date | string | 필수 | 수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다. | "2026-01-15" |
time | string | 조건부·선택 | 클리닉 시각입니다. HH:mm 형식이며 빈 문자열이면 미지정입니다. | "14:00" |
lessonId | integer | 조건부·선택 | 연결된 과제장 번호입니다. 0이면 독립 리뷰입니다. | 0 |
title | string | 필수 | 제목입니다. | "예시" |
review | string | 조건부·선택 | 클리닉 리뷰 본문입니다. 일반 텍스트로 입력합니다. | "예시" |
memo | string | 조건부·선택 | 내부 메모입니다. | "예시" |
status | string | 조건부·선택 | 클리닉 처리 결과입니다. 예약·입실·완료·취소·불참·변경 또는 빈 문자열입니다. | "예시" |
nextDate | string | 조건부·선택 | 변경된 클리닉 일자입니다. 빈 문자열이면 수업일을 사용합니다. | "2026-01-15" |
retest | boolean | 조건부·선택 | 재시험 대상 여부입니다. | false |
요청 JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"teacherId": {
"type": "integer",
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"date": {
"type": "string",
"format": "date",
"description": "수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다.",
"nullable": false,
"minLength": 1
},
"time": {
"type": "string",
"description": "클리닉 시각입니다. HH:mm 형식이며 빈 문자열이면 미지정입니다.",
"nullable": false,
"maxLength": 5,
"default": ""
},
"lessonId": {
"type": "integer",
"description": "연결된 과제장 번호입니다. 0이면 독립 리뷰입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"title": {
"type": "string",
"description": "제목입니다.",
"nullable": false,
"maxLength": 200,
"minLength": 1
},
"review": {
"type": "string",
"description": "클리닉 리뷰 본문입니다. 일반 텍스트로 입력합니다.",
"nullable": false,
"maxLength": 10000,
"default": ""
},
"memo": {
"type": "string",
"description": "내부 메모입니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"status": {
"type": "string",
"description": "클리닉 처리 결과입니다. 예약·입실·완료·취소·불참·변경 또는 빈 문자열입니다.",
"nullable": false,
"default": "",
"pattern": "^(예약|입실|완료|취소|불참|변경)?$"
},
"nextDate": {
"type": "string",
"format": "date",
"description": "변경된 클리닉 일자입니다. 빈 문자열이면 수업일을 사용합니다.",
"nullable": false,
"default": ""
},
"retest": {
"type": "boolean",
"description": "재시험 대상 여부입니다.",
"nullable": false,
"default": false
}
},
"required": [
"studentId",
"teamId",
"scheduleId",
"teacherId",
"date",
"title"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"studentId": "00000001",
"teamId": 1,
"scheduleId": 1,
"teacherId": 1,
"date": "2026-01-15",
"time": "14:00",
"lessonId": 0,
"title": "예시",
"review": "예시",
"memo": "예시",
"status": "예시",
"nextDate": "2026-01-15",
"retest": false
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/teaching/clinic-reviews/{reviewId}클리닉 리뷰 전체 수정+
teaching.write · teaching.clinics.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
reviewId | path | 필수 | GET /v1/teaching/clinic-reviews 응답 data.items[].id의 클리닉 리뷰 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
teamId | integer | 필수 | GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다. | 1 |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요. | 1 |
teacherId | integer | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다. | 1 |
date | string | 필수 | 수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다. | "2026-01-15" |
time | string | 조건부·선택 | 클리닉 시각입니다. HH:mm 형식이며 빈 문자열이면 미지정입니다. | "14:00" |
lessonId | integer | 조건부·선택 | 연결된 과제장 번호입니다. 0이면 독립 리뷰입니다. | 0 |
title | string | 필수 | 제목입니다. | "예시" |
review | string | 조건부·선택 | 클리닉 리뷰 본문입니다. 일반 텍스트로 입력합니다. | "예시" |
memo | string | 조건부·선택 | 내부 메모입니다. | "예시" |
status | string | 조건부·선택 | 클리닉 처리 결과입니다. 예약·입실·완료·취소·불참·변경 또는 빈 문자열입니다. | "예시" |
nextDate | string | 조건부·선택 | 변경된 클리닉 일자입니다. 빈 문자열이면 수업일을 사용합니다. | "2026-01-15" |
retest | boolean | 조건부·선택 | 재시험 대상 여부입니다. | false |
요청 JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"teamId": {
"type": "integer",
"description": "GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"teacherId": {
"type": "integer",
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"date": {
"type": "string",
"format": "date",
"description": "수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다.",
"nullable": false,
"minLength": 1
},
"time": {
"type": "string",
"description": "클리닉 시각입니다. HH:mm 형식이며 빈 문자열이면 미지정입니다.",
"nullable": false,
"maxLength": 5,
"default": ""
},
"lessonId": {
"type": "integer",
"description": "연결된 과제장 번호입니다. 0이면 독립 리뷰입니다.",
"nullable": false,
"minimum": 0,
"maximum": 2147483647,
"default": 0
},
"title": {
"type": "string",
"description": "제목입니다.",
"nullable": false,
"maxLength": 200,
"minLength": 1
},
"review": {
"type": "string",
"description": "클리닉 리뷰 본문입니다. 일반 텍스트로 입력합니다.",
"nullable": false,
"maxLength": 10000,
"default": ""
},
"memo": {
"type": "string",
"description": "내부 메모입니다.",
"nullable": false,
"maxLength": 4000,
"default": ""
},
"status": {
"type": "string",
"description": "클리닉 처리 결과입니다. 예약·입실·완료·취소·불참·변경 또는 빈 문자열입니다.",
"nullable": false,
"default": "",
"pattern": "^(예약|입실|완료|취소|불참|변경)?$"
},
"nextDate": {
"type": "string",
"format": "date",
"description": "변경된 클리닉 일자입니다. 빈 문자열이면 수업일을 사용합니다.",
"nullable": false,
"default": ""
},
"retest": {
"type": "boolean",
"description": "재시험 대상 여부입니다.",
"nullable": false,
"default": false
}
},
"required": [
"studentId",
"teamId",
"scheduleId",
"teacherId",
"date",
"title"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"studentId": "00000001",
"teamId": 1,
"scheduleId": 1,
"teacherId": 1,
"date": "2026-01-15",
"time": "14:00",
"lessonId": 0,
"title": "예시",
"review": "예시",
"memo": "예시",
"status": "예시",
"nextDate": "2026-01-15",
"retest": false
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/teaching/clinic-reviews/{reviewId}클리닉 리뷰 삭제+
teaching.write · teaching.clinics.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
reviewId | path | 필수 | GET /v1/teaching/clinic-reviews 응답 data.items[].id의 클리닉 리뷰 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/attendance/staffTime-clock employee identities, excluding passwords/payroll. Never use as the teaching teacher roster or teacher IDs.+
staff.read · staff.list
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
[].name | string | 필수 | 직원 이름입니다. | "예시 이름" |
[].role | string | 필수 | 등록된 직원 직무입니다. | "예시" |
[].startDate | integer | 필수 | 입사일입니다. yyyyMMdd 정수입니다. | 20260115 |
[].endDate | integer | 필수 | 퇴사일입니다. 0이면 재직 중입니다. | 20260115 |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "직원 이름입니다.",
"nullable": false
},
"role": {
"type": "string",
"description": "등록된 직원 직무입니다.",
"nullable": false
},
"startDate": {
"type": "integer",
"description": "입사일입니다. yyyyMMdd 정수입니다.",
"nullable": false
},
"endDate": {
"type": "integer",
"description": "퇴사일입니다. 0이면 재직 중입니다.",
"nullable": false
}
},
"required": [
"id",
"name",
"role",
"startDate",
"endDate"
]
}
}성공 응답 예시
{
"data": [
{
"id": 1,
"name": "예시 이름",
"role": "예시",
"startDate": 20260115,
"endDate": 20260115
}
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/attendance/staff/{staffId}직원 기본정보 상세(비밀번호·급여 제외)+
staff.read · staff.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
staffId | path | 필수 | GET /v1/attendance/staff 응답 data[].id의 직원 번호입니다. 검색 조건에서 0 또는 생략하면 전체입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
name | string | 필수 | 직원 이름입니다. | "예시 이름" |
role | string | 필수 | 등록된 직원 직무입니다. | "예시" |
startDate | integer | 필수 | 입사일입니다. yyyyMMdd 정수입니다. | 20260115 |
endDate | integer | 필수 | 퇴사일입니다. 0이면 재직 중입니다. | 20260115 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "직원 이름입니다.",
"nullable": false
},
"role": {
"type": "string",
"description": "등록된 직원 직무입니다.",
"nullable": false
},
"startDate": {
"type": "integer",
"description": "입사일입니다. yyyyMMdd 정수입니다.",
"nullable": false
},
"endDate": {
"type": "integer",
"description": "퇴사일입니다. 0이면 재직 중입니다.",
"nullable": false
}
},
"required": [
"id",
"name",
"role",
"startDate",
"endDate"
]
}성공 응답 예시
{
"data": {
"id": 1,
"name": "예시 이름",
"role": "예시",
"startDate": 20260115,
"endDate": 20260115
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/attendance/staff직원 기본정보 등록(로그인 비밀번호 발급 없음)+
staff.manage · staff.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
name | string | 필수 | 출퇴근용 직원 이름입니다. 최대 20바이트(한글 10자·영문 20자)이며 저장할 수 없는 문자는 거절합니다. 로그인 비밀번호·급여는 설정하지 않습니다. | "예시 직원" |
role | string | 조건부·선택 | 직무 표시명입니다. 예: 조교. 최대 10바이트(한글 5자·영문 10자)이며 권한 그룹·로그인 권한 코드가 아닙니다. | "조교" |
startDate | string | 필수 | 입사일입니다. 한국 날짜 yyyy-MM-dd 형식입니다. | "2026-01-15" |
endDate | string | 조건부·선택 | 퇴사일입니다. 한국 날짜 yyyy-MM-dd 형식이며 입사일보다 빠를 수 없습니다. null 또는 생략은 재직입니다. 이력은 삭제하지 않습니다. | "2026-01-15" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "출퇴근용 직원 이름입니다. 최대 20바이트(한글 10자·영문 20자)이며 저장할 수 없는 문자는 거절합니다. 로그인 비밀번호·급여는 설정하지 않습니다.",
"nullable": false,
"maxLength": 20,
"minLength": 1,
"example": "예시 직원"
},
"role": {
"type": "string",
"description": "직무 표시명입니다. 예: 조교. 최대 10바이트(한글 5자·영문 10자)이며 권한 그룹·로그인 권한 코드가 아닙니다.",
"nullable": false,
"maxLength": 10,
"default": "",
"example": "조교"
},
"startDate": {
"type": "string",
"format": "date",
"description": "입사일입니다. 한국 날짜 yyyy-MM-dd 형식입니다.",
"nullable": false,
"minLength": 1
},
"endDate": {
"type": "string",
"format": "date",
"description": "퇴사일입니다. 한국 날짜 yyyy-MM-dd 형식이며 입사일보다 빠를 수 없습니다. null 또는 생략은 재직입니다. 이력은 삭제하지 않습니다.",
"nullable": true
}
},
"required": [
"name",
"startDate"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
name | string | 필수 | 직원 이름입니다. | "예시 이름" |
role | string | 필수 | 등록된 직원 직무입니다. | "예시" |
startDate | integer | 필수 | 입사일입니다. yyyyMMdd 정수입니다. | 20260115 |
endDate | integer | 필수 | 퇴사일입니다. 0이면 재직 중입니다. | 20260115 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "직원 이름입니다.",
"nullable": false
},
"role": {
"type": "string",
"description": "등록된 직원 직무입니다.",
"nullable": false
},
"startDate": {
"type": "integer",
"description": "입사일입니다. yyyyMMdd 정수입니다.",
"nullable": false
},
"endDate": {
"type": "integer",
"description": "퇴사일입니다. 0이면 재직 중입니다.",
"nullable": false
}
},
"required": [
"id",
"name",
"role",
"startDate",
"endDate"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"name": "예시 직원",
"role": "조교",
"startDate": "2026-01-15",
"endDate": "2026-01-15"
}성공 응답 예시
{
"data": {
"id": 1,
"name": "예시 이름",
"role": "예시",
"startDate": 20260115,
"endDate": 20260115
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/attendance/staff/{staffId}직원 기본정보·입퇴사일 수정+
staff.manage · staff.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
staffId | path | 필수 | GET /v1/attendance/staff 응답 data[].id의 직원 번호입니다. 검색 조건에서 0 또는 생략하면 전체입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
name | string | 필수 | 출퇴근용 직원 이름입니다. 최대 20바이트(한글 10자·영문 20자)이며 저장할 수 없는 문자는 거절합니다. 로그인 비밀번호·급여는 설정하지 않습니다. | "예시 직원" |
role | string | 조건부·선택 | 직무 표시명입니다. 예: 조교. 최대 10바이트(한글 5자·영문 10자)이며 권한 그룹·로그인 권한 코드가 아닙니다. | "조교" |
startDate | string | 필수 | 입사일입니다. 한국 날짜 yyyy-MM-dd 형식입니다. | "2026-01-15" |
endDate | string | 조건부·선택 | 퇴사일입니다. 한국 날짜 yyyy-MM-dd 형식이며 입사일보다 빠를 수 없습니다. null 또는 생략은 재직입니다. 이력은 삭제하지 않습니다. | "2026-01-15" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "출퇴근용 직원 이름입니다. 최대 20바이트(한글 10자·영문 20자)이며 저장할 수 없는 문자는 거절합니다. 로그인 비밀번호·급여는 설정하지 않습니다.",
"nullable": false,
"maxLength": 20,
"minLength": 1,
"example": "예시 직원"
},
"role": {
"type": "string",
"description": "직무 표시명입니다. 예: 조교. 최대 10바이트(한글 5자·영문 10자)이며 권한 그룹·로그인 권한 코드가 아닙니다.",
"nullable": false,
"maxLength": 10,
"default": "",
"example": "조교"
},
"startDate": {
"type": "string",
"format": "date",
"description": "입사일입니다. 한국 날짜 yyyy-MM-dd 형식입니다.",
"nullable": false,
"minLength": 1
},
"endDate": {
"type": "string",
"format": "date",
"description": "퇴사일입니다. 한국 날짜 yyyy-MM-dd 형식이며 입사일보다 빠를 수 없습니다. null 또는 생략은 재직입니다. 이력은 삭제하지 않습니다.",
"nullable": true
}
},
"required": [
"name",
"startDate"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
name | string | 필수 | 직원 이름입니다. | "예시 이름" |
role | string | 필수 | 등록된 직원 직무입니다. | "예시" |
startDate | integer | 필수 | 입사일입니다. yyyyMMdd 정수입니다. | 20260115 |
endDate | integer | 필수 | 퇴사일입니다. 0이면 재직 중입니다. | 20260115 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "직원 이름입니다.",
"nullable": false
},
"role": {
"type": "string",
"description": "등록된 직원 직무입니다.",
"nullable": false
},
"startDate": {
"type": "integer",
"description": "입사일입니다. yyyyMMdd 정수입니다.",
"nullable": false
},
"endDate": {
"type": "integer",
"description": "퇴사일입니다. 0이면 재직 중입니다.",
"nullable": false
}
},
"required": [
"id",
"name",
"role",
"startDate",
"endDate"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"name": "예시 직원",
"role": "조교",
"startDate": "2026-01-15",
"endDate": "2026-01-15"
}성공 응답 예시
{
"data": {
"id": 1,
"name": "예시 이름",
"role": "예시",
"startDate": 20260115,
"endDate": 20260115
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/attendance/staff/{staffId}직원 퇴사 처리(근무 이력 보존)+
staff.manage · staff.stop
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
staffId | path | 필수 | GET /v1/attendance/staff 응답 data[].id의 직원 번호입니다. 검색 조건에서 0 또는 생략하면 전체입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
name | string | 필수 | 직원 이름입니다. | "예시 이름" |
role | string | 필수 | 등록된 직원 직무입니다. | "예시" |
startDate | integer | 필수 | 입사일입니다. yyyyMMdd 정수입니다. | 20260115 |
endDate | integer | 필수 | 퇴사일입니다. 0이면 재직 중입니다. | 20260115 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "직원 이름입니다.",
"nullable": false
},
"role": {
"type": "string",
"description": "등록된 직원 직무입니다.",
"nullable": false
},
"startDate": {
"type": "integer",
"description": "입사일입니다. yyyyMMdd 정수입니다.",
"nullable": false
},
"endDate": {
"type": "integer",
"description": "퇴사일입니다. 0이면 재직 중입니다.",
"nullable": false
}
},
"required": [
"id",
"name",
"role",
"startDate",
"endDate"
]
}성공 응답 예시
{
"data": {
"id": 1,
"name": "예시 이름",
"role": "예시",
"startDate": 20260115,
"endDate": 20260115
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/attendance/staff/journals기간별 직원 출퇴근·근무일지+
staff.read · staff.journals.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
from | query | 필수 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 필수 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
staffId | query | 선택 | GET /v1/attendance/staff 응답 data[].id의 직원 번호입니다. 검색 조건에서 0 또는 생략하면 전체입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
items[].staffId | integer | 필수 | 직원 번호입니다. | 1 |
items[].name | string | 필수 | 직원 이름입니다. | "예시 이름" |
items[].inAt | string | 필수 | 한국 현지 시각의 출근일시입니다. | "2026-01-15T14:00:00" |
items[].outAt | string | 필수 | 한국 현지 시각의 퇴근일시입니다. null이면 미퇴근입니다. | "2026-01-15T14:00:00" |
items[].title | string | 필수 | 근무일지 제목입니다. | "예시" |
items[].journal | string | 필수 | 근무일지 일반 텍스트입니다. | "예시" |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"staffId": {
"type": "integer",
"description": "직원 번호입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "직원 이름입니다.",
"nullable": false
},
"inAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,7})?$",
"description": "한국 현지 시각의 출근일시입니다.",
"nullable": true
},
"outAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,7})?$",
"description": "한국 현지 시각의 퇴근일시입니다. null이면 미퇴근입니다.",
"nullable": true
},
"title": {
"type": "string",
"description": "근무일지 제목입니다.",
"nullable": false
},
"journal": {
"type": "string",
"description": "근무일지 일반 텍스트입니다.",
"nullable": false
}
},
"required": [
"id",
"staffId",
"name",
"inAt",
"outAt",
"title",
"journal"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"id": 1,
"staffId": 1,
"name": "예시 이름",
"inAt": "2026-01-15T14:00:00",
"outAt": "2026-01-15T14:00:00",
"title": "예시",
"journal": "예시"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/attendance/staff/journals/{journalId}직원 출퇴근·근무일지 상세+
staff.read · staff.journals.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
journalId | path | 필수 | GET /v1/attendance/staff/journals 응답 data.items[].id의 근무일지 번호입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
staffId | integer | 필수 | 직원 번호입니다. | 1 |
name | string | 필수 | 직원 이름입니다. | "예시 이름" |
inAt | string | 필수 | 한국 현지 시각의 출근일시입니다. | "2026-01-15T14:00:00" |
outAt | string | 필수 | 한국 현지 시각의 퇴근일시입니다. null이면 미퇴근입니다. | "2026-01-15T14:00:00" |
title | string | 필수 | 근무일지 제목입니다. | "예시" |
journal | string | 필수 | 근무일지 일반 텍스트입니다. | "예시" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"staffId": {
"type": "integer",
"description": "직원 번호입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "직원 이름입니다.",
"nullable": false
},
"inAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,7})?$",
"description": "한국 현지 시각의 출근일시입니다.",
"nullable": true
},
"outAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,7})?$",
"description": "한국 현지 시각의 퇴근일시입니다. null이면 미퇴근입니다.",
"nullable": true
},
"title": {
"type": "string",
"description": "근무일지 제목입니다.",
"nullable": false
},
"journal": {
"type": "string",
"description": "근무일지 일반 텍스트입니다.",
"nullable": false
}
},
"required": [
"id",
"staffId",
"name",
"inAt",
"outAt",
"title",
"journal"
]
}성공 응답 예시
{
"data": {
"id": 1,
"staffId": 1,
"name": "예시 이름",
"inAt": "2026-01-15T14:00:00",
"outAt": "2026-01-15T14:00:00",
"title": "예시",
"journal": "예시"
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/attendance/staff/journals직원 출근·퇴근·근무일지 등록+
staff.write · staff.journals.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
staffId | integer | 필수 | GET /v1/attendance/staff 응답 data[].id에서 선택한 직원 번호입니다. 직원 이름이 아닌 정수 id를 전달하세요. | 1 |
inAt | string | 필수 | 출근일시입니다. 한국 현지 시각 yyyy-MM-ddTHH:mm:ss를 전달하며 미래 날짜는 허용하지 않습니다. | "2026-01-15T14:00:00" |
outAt | string | 조건부·선택 | 퇴근일시입니다. 출근 이후 같은 날짜여야 하며 미퇴근은 null입니다. | "2026-01-15T14:00:00" |
title | string | 조건부·선택 | 근무일지 제목입니다. | "예시" |
journal | string | 조건부·선택 | 일반 텍스트 근무일지입니다. HTML은 텍스트로 저장합니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"staffId": {
"type": "integer",
"description": "GET /v1/attendance/staff 응답 data[].id에서 선택한 직원 번호입니다. 직원 이름이 아닌 정수 id를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"inAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,7})?$",
"description": "출근일시입니다. 한국 현지 시각 yyyy-MM-ddTHH:mm:ss를 전달하며 미래 날짜는 허용하지 않습니다.",
"nullable": false
},
"outAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,7})?$",
"description": "퇴근일시입니다. 출근 이후 같은 날짜여야 하며 미퇴근은 null입니다.",
"nullable": true
},
"title": {
"type": "string",
"description": "근무일지 제목입니다.",
"nullable": false,
"maxLength": 200,
"default": ""
},
"journal": {
"type": "string",
"description": "일반 텍스트 근무일지입니다. HTML은 텍스트로 저장합니다.",
"nullable": false,
"maxLength": 10000,
"default": ""
}
},
"required": [
"staffId",
"inAt"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"staffId": 1,
"inAt": "2026-01-15T14:00:00",
"outAt": "2026-01-15T14:00:00",
"title": "예시",
"journal": "예시"
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/attendance/staff/journals/{journalId}직원 출퇴근·근무일지 수정+
staff.write · staff.journals.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
journalId | path | 필수 | GET /v1/attendance/staff/journals 응답 data.items[].id의 근무일지 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
staffId | integer | 필수 | GET /v1/attendance/staff 응답 data[].id에서 선택한 직원 번호입니다. 직원 이름이 아닌 정수 id를 전달하세요. | 1 |
inAt | string | 필수 | 출근일시입니다. 한국 현지 시각 yyyy-MM-ddTHH:mm:ss를 전달하며 미래 날짜는 허용하지 않습니다. | "2026-01-15T14:00:00" |
outAt | string | 조건부·선택 | 퇴근일시입니다. 출근 이후 같은 날짜여야 하며 미퇴근은 null입니다. | "2026-01-15T14:00:00" |
title | string | 조건부·선택 | 근무일지 제목입니다. | "예시" |
journal | string | 조건부·선택 | 일반 텍스트 근무일지입니다. HTML은 텍스트로 저장합니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"staffId": {
"type": "integer",
"description": "GET /v1/attendance/staff 응답 data[].id에서 선택한 직원 번호입니다. 직원 이름이 아닌 정수 id를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"inAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,7})?$",
"description": "출근일시입니다. 한국 현지 시각 yyyy-MM-ddTHH:mm:ss를 전달하며 미래 날짜는 허용하지 않습니다.",
"nullable": false
},
"outAt": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,7})?$",
"description": "퇴근일시입니다. 출근 이후 같은 날짜여야 하며 미퇴근은 null입니다.",
"nullable": true
},
"title": {
"type": "string",
"description": "근무일지 제목입니다.",
"nullable": false,
"maxLength": 200,
"default": ""
},
"journal": {
"type": "string",
"description": "일반 텍스트 근무일지입니다. HTML은 텍스트로 저장합니다.",
"nullable": false,
"maxLength": 10000,
"default": ""
}
},
"required": [
"staffId",
"inAt"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"staffId": 1,
"inAt": "2026-01-15T14:00:00",
"outAt": "2026-01-15T14:00:00",
"title": "예시",
"journal": "예시"
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/attendance/staff/journals/{journalId}직원 출퇴근 기록 삭제+
staff.write · staff.journals.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
journalId | path | 필수 | GET /v1/attendance/staff/journals 응답 data.items[].id의 근무일지 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/attendance/staff/summary직원별 근무 일수·시간 합계+
staff.read · staff.summary
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
from | query | 필수 | 조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다. |
to | query | 필수 | 조회 종료일입니다. yyyy-MM-dd 형식입니다. |
staffId | query | 선택 | GET /v1/attendance/staff 응답 data[].id의 직원 번호입니다. 검색 조건에서 0 또는 생략하면 전체입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
[].staffId | integer | 필수 | 직원 번호입니다. | 1 |
[].name | string | 필수 | 직원 이름입니다. | "예시 이름" |
[].workDays | integer | 필수 | 조회 기간의 출근 일수입니다. | 1 |
[].workHours | number | 필수 | 퇴근까지 기록된 총 근무 시간입니다. 미퇴근은 계산하지 않습니다. | 1 |
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "object",
"properties": {
"staffId": {
"type": "integer",
"description": "직원 번호입니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "직원 이름입니다.",
"nullable": false
},
"workDays": {
"type": "integer",
"description": "조회 기간의 출근 일수입니다.",
"nullable": false
},
"workHours": {
"type": "number",
"description": "퇴근까지 기록된 총 근무 시간입니다. 미퇴근은 계산하지 않습니다.",
"nullable": false
}
},
"required": [
"staffId",
"name",
"workDays",
"workHours"
]
}
}성공 응답 예시
{
"data": [
{
"staffId": 1,
"name": "예시 이름",
"workDays": 1,
"workHours": 1
}
],
"meta": {
"requestId": "example-request-id"
}
}교재관리
GET/v1/books교재비 항목 목록+
books.read · books.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
search | query | 선택 | 검색어입니다. 최대 100자이며 생략하면 전체를 조회합니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
items[].name | string | 필수 | 교재비 항목 이름입니다. | "예시 이름" |
items[].subject | string | 필수 | 과목 이름입니다. | "예시" |
items[].grade | string | 필수 | 학년 구분입니다. | "예시" |
items[].level | string | 필수 | 수준 구분입니다. | "예시" |
items[].teacherId | integer | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다. | 1 |
items[].price | integer | 필수 | 기본 출고 금액입니다. 원 단위입니다. | 1 |
items[].active | boolean | 필수 | 사용 중인지 나타냅니다. | false |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "교재비 항목 이름입니다.",
"nullable": false
},
"subject": {
"type": "string",
"description": "과목 이름입니다.",
"nullable": false
},
"grade": {
"type": "string",
"description": "학년 구분입니다.",
"nullable": false
},
"level": {
"type": "string",
"description": "수준 구분입니다.",
"nullable": false
},
"teacherId": {
"type": "integer",
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"price": {
"type": "integer",
"description": "기본 출고 금액입니다. 원 단위입니다.",
"nullable": false
},
"active": {
"type": "boolean",
"description": "사용 중인지 나타냅니다.",
"nullable": false
}
},
"required": [
"id",
"name",
"subject",
"grade",
"level",
"teacherId",
"price",
"active"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"id": 1,
"name": "예시 이름",
"subject": "예시",
"grade": "예시",
"level": "예시",
"teacherId": 1,
"price": 1,
"active": false
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/books/{bookId}교재비 항목 상세+
books.read · books.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
bookId | path | 필수 | GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
name | string | 필수 | 교재비 항목 이름입니다. | "예시 이름" |
subject | string | 필수 | 과목 이름입니다. | "예시" |
grade | string | 필수 | 학년 구분입니다. | "예시" |
level | string | 필수 | 수준 구분입니다. | "예시" |
teacherId | integer | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다. | 1 |
price | integer | 필수 | 기본 출고 금액입니다. 원 단위입니다. | 1 |
active | boolean | 필수 | 사용 중인지 나타냅니다. | false |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"name": {
"type": "string",
"description": "교재비 항목 이름입니다.",
"nullable": false
},
"subject": {
"type": "string",
"description": "과목 이름입니다.",
"nullable": false
},
"grade": {
"type": "string",
"description": "학년 구분입니다.",
"nullable": false
},
"level": {
"type": "string",
"description": "수준 구분입니다.",
"nullable": false
},
"teacherId": {
"type": "integer",
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"price": {
"type": "integer",
"description": "기본 출고 금액입니다. 원 단위입니다.",
"nullable": false
},
"active": {
"type": "boolean",
"description": "사용 중인지 나타냅니다.",
"nullable": false
}
},
"required": [
"id",
"name",
"subject",
"grade",
"level",
"teacherId",
"price",
"active"
]
}성공 응답 예시
{
"data": {
"id": 1,
"name": "예시 이름",
"subject": "예시",
"grade": "예시",
"level": "예시",
"teacherId": 1,
"price": 1,
"active": false
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/books교재비 항목 등록+
books.write · books.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
name | string | 필수 | 교재비 항목 이름입니다. | "예시 교재" |
subject | string | 필수 | 교재 과목 이름입니다. | "수학" |
grade | string | 조건부·선택 | 학년 구분입니다. | "예시" |
level | string | 조건부·선택 | 수준 구분입니다. | "예시" |
teacherId | integer | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다. | 1 |
price | integer | 조건부·선택 | 기본 출고 금액입니다. 원 단위의 0 이상 정수입니다. | 0 |
active | boolean | 조건부·선택 | 사용 여부입니다. | false |
요청 JSON 스키마
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "교재비 항목 이름입니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1,
"example": "예시 교재"
},
"subject": {
"type": "string",
"description": "교재 과목 이름입니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1,
"example": "수학"
},
"grade": {
"type": "string",
"description": "학년 구분입니다.",
"nullable": false,
"maxLength": 100,
"default": ""
},
"level": {
"type": "string",
"description": "수준 구분입니다.",
"nullable": false,
"maxLength": 100,
"default": ""
},
"teacherId": {
"type": "integer",
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"price": {
"type": "integer",
"description": "기본 출고 금액입니다. 원 단위의 0 이상 정수입니다.",
"nullable": false,
"minimum": 0,
"maximum": 100000000,
"default": 0
},
"active": {
"type": "boolean",
"description": "사용 여부입니다.",
"nullable": false,
"default": false
}
},
"required": [
"name",
"subject",
"teacherId"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"name": "예시 교재",
"subject": "수학",
"grade": "예시",
"level": "예시",
"teacherId": 1,
"price": 0,
"active": false
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/books/{bookId}교재비 항목 수정+
books.write · books.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
bookId | path | 필수 | GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
name | string | 필수 | 교재비 항목 이름입니다. | "예시 교재" |
subject | string | 필수 | 교재 과목 이름입니다. | "수학" |
grade | string | 조건부·선택 | 학년 구분입니다. | "예시" |
level | string | 조건부·선택 | 수준 구분입니다. | "예시" |
teacherId | integer | 필수 | GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다. | 1 |
price | integer | 조건부·선택 | 기본 출고 금액입니다. 원 단위의 0 이상 정수입니다. | 0 |
active | boolean | 조건부·선택 | 사용 여부입니다. | false |
요청 JSON 스키마
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "교재비 항목 이름입니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1,
"example": "예시 교재"
},
"subject": {
"type": "string",
"description": "교재 과목 이름입니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1,
"example": "수학"
},
"grade": {
"type": "string",
"description": "학년 구분입니다.",
"nullable": false,
"maxLength": 100,
"default": ""
},
"level": {
"type": "string",
"description": "수준 구분입니다.",
"nullable": false,
"maxLength": 100,
"default": ""
},
"teacherId": {
"type": "integer",
"description": "GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"price": {
"type": "integer",
"description": "기본 출고 금액입니다. 원 단위의 0 이상 정수입니다.",
"nullable": false,
"minimum": 0,
"maximum": 100000000,
"default": 0
},
"active": {
"type": "boolean",
"description": "사용 여부입니다.",
"nullable": false,
"default": false
}
},
"required": [
"name",
"subject",
"teacherId"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"name": "예시 교재",
"subject": "수학",
"grade": "예시",
"level": "예시",
"teacherId": 1,
"price": 0,
"active": false
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/books/{bookId}사용 이력이 없는 교재비 항목 삭제+
books.write · books.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
bookId | path | 필수 | GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/books/{bookId}/issues원본 교재 번호(books.list/get id)별 출고·반품·수납 현황+
books.read · books.issues.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
bookId | path | 필수 | GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다. |
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
items[].studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
items[].studentName | string | 필수 | 학생 이름입니다. | "예시 이름" |
items[].scheduleId | integer | 필수 | 현재 조회 시간표 번호입니다. | 1 |
items[].issuedScheduleId | integer | 필수 | 처음 출고된 시간표 번호입니다. | 1 |
items[].item | string | 필수 | 출고한 부교재 이름입니다. | "예시" |
items[].issued | boolean | 필수 | 출고 여부입니다. | false |
items[].returned | boolean | 필수 | 반품 여부입니다. | false |
items[].excluded | boolean | 필수 | 출고 대상 제외 여부입니다. | false |
items[].amount | integer | 필수 | 출고 금액입니다. 원 단위입니다. | 1 |
items[].paymentType | string | 필수 | 수납 구분입니다. | "예시" |
items[].memo | string | 필수 | 출고 메모입니다. | "예시" |
items[].issuedAt | string | 필수 | 출고일시입니다. | "2026-01-15T00:00:00Z" |
items[].returnedAt | string | 필수 | 과거 반품 처리 시각입니다. 반품 해제 후에도 남을 수 있으며 현재 반품 상태는 returned가 기준입니다. | "2026-01-15T00:00:00Z" |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"studentName": {
"type": "string",
"description": "학생 이름입니다.",
"nullable": false
},
"scheduleId": {
"type": "integer",
"description": "현재 조회 시간표 번호입니다.",
"nullable": false
},
"issuedScheduleId": {
"type": "integer",
"description": "처음 출고된 시간표 번호입니다.",
"nullable": false
},
"item": {
"type": "string",
"description": "출고한 부교재 이름입니다.",
"nullable": false
},
"issued": {
"type": "boolean",
"description": "출고 여부입니다.",
"nullable": false
},
"returned": {
"type": "boolean",
"description": "반품 여부입니다.",
"nullable": false
},
"excluded": {
"type": "boolean",
"description": "출고 대상 제외 여부입니다.",
"nullable": false
},
"amount": {
"type": "integer",
"description": "출고 금액입니다. 원 단위입니다.",
"nullable": false
},
"paymentType": {
"type": "string",
"description": "수납 구분입니다.",
"nullable": false
},
"memo": {
"type": "string",
"description": "출고 메모입니다.",
"nullable": false
},
"issuedAt": {
"type": "string",
"format": "date-time",
"description": "출고일시입니다.",
"nullable": true
},
"returnedAt": {
"type": "string",
"format": "date-time",
"description": "과거 반품 처리 시각입니다. 반품 해제 후에도 남을 수 있으며 현재 반품 상태는 returned가 기준입니다.",
"nullable": true
}
},
"required": [
"id",
"studentId",
"studentName",
"scheduleId",
"issuedScheduleId",
"item",
"issued",
"returned",
"excluded",
"amount",
"paymentType",
"memo",
"issuedAt",
"returnedAt"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"id": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"scheduleId": 1,
"issuedScheduleId": 1,
"item": "예시",
"issued": false,
"returned": false,
"excluded": false,
"amount": 1,
"paymentType": "예시",
"memo": "예시",
"issuedAt": "2026-01-15T00:00:00Z",
"returnedAt": "2026-01-15T00:00:00Z"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/books/{bookId}/issues/{issueId}원본 교재·출고 번호의 학생별 현재 지급·반품·제외·금액·수납·메모 조회+
books.read · books.issues.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
bookId | path | 필수 | GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다. |
issueId | path | 필수 | GET /v1/books/{bookId}/issues 응답 data.items[].id의 출고 기록 번호입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다. | 1 |
studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
studentName | string | 필수 | 학생 이름입니다. | "예시 이름" |
scheduleId | integer | 필수 | 현재 조회 시간표 번호입니다. | 1 |
issuedScheduleId | integer | 필수 | 처음 출고된 시간표 번호입니다. | 1 |
item | string | 필수 | 출고한 부교재 이름입니다. | "예시" |
issued | boolean | 필수 | 출고 여부입니다. | false |
returned | boolean | 필수 | 반품 여부입니다. | false |
excluded | boolean | 필수 | 출고 대상 제외 여부입니다. | false |
amount | integer | 필수 | 출고 금액입니다. 원 단위입니다. | 1 |
paymentType | string | 필수 | 수납 구분입니다. | "예시" |
memo | string | 필수 | 출고 메모입니다. | "예시" |
issuedAt | string | 필수 | 출고일시입니다. | "2026-01-15T00:00:00Z" |
returnedAt | string | 필수 | 과거 반품 처리 시각입니다. 반품 해제 후에도 남을 수 있으며 현재 반품 상태는 returned가 기준입니다. | "2026-01-15T00:00:00Z" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.",
"nullable": false
},
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"studentName": {
"type": "string",
"description": "학생 이름입니다.",
"nullable": false
},
"scheduleId": {
"type": "integer",
"description": "현재 조회 시간표 번호입니다.",
"nullable": false
},
"issuedScheduleId": {
"type": "integer",
"description": "처음 출고된 시간표 번호입니다.",
"nullable": false
},
"item": {
"type": "string",
"description": "출고한 부교재 이름입니다.",
"nullable": false
},
"issued": {
"type": "boolean",
"description": "출고 여부입니다.",
"nullable": false
},
"returned": {
"type": "boolean",
"description": "반품 여부입니다.",
"nullable": false
},
"excluded": {
"type": "boolean",
"description": "출고 대상 제외 여부입니다.",
"nullable": false
},
"amount": {
"type": "integer",
"description": "출고 금액입니다. 원 단위입니다.",
"nullable": false
},
"paymentType": {
"type": "string",
"description": "수납 구분입니다.",
"nullable": false
},
"memo": {
"type": "string",
"description": "출고 메모입니다.",
"nullable": false
},
"issuedAt": {
"type": "string",
"format": "date-time",
"description": "출고일시입니다.",
"nullable": true
},
"returnedAt": {
"type": "string",
"format": "date-time",
"description": "과거 반품 처리 시각입니다. 반품 해제 후에도 남을 수 있으며 현재 반품 상태는 returned가 기준입니다.",
"nullable": true
}
},
"required": [
"id",
"studentId",
"studentName",
"scheduleId",
"issuedScheduleId",
"item",
"issued",
"returned",
"excluded",
"amount",
"paymentType",
"memo",
"issuedAt",
"returnedAt"
]
}성공 응답 예시
{
"data": {
"id": 1,
"studentId": "00000001",
"studentName": "예시 이름",
"scheduleId": 1,
"issuedScheduleId": 1,
"item": "예시",
"issued": false,
"returned": false,
"excluded": false,
"amount": 1,
"paymentType": "예시",
"memo": "예시",
"issuedAt": "2026-01-15T00:00:00Z",
"returnedAt": "2026-01-15T00:00:00Z"
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/books/{bookId}/issues원본 교재 번호·학생·시간표로 학생별 교재 출고 등록+
books.write · books.issues.create
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
bookId | path | 필수 | GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요. | 1 |
item | string | 필수 | 부교재 이름입니다. 공통 교재는 공통으로 입력합니다. | "예시" |
issued | boolean | 조건부·선택 | 출고 여부입니다. | false |
returned | boolean | 조건부·선택 | 반품 여부입니다. | false |
excluded | boolean | 조건부·선택 | 출고 대상에서 제외할지 여부입니다. | false |
amount | integer | 조건부·선택 | 현재 출고 금액입니다. 원 단위입니다. | 0 |
paymentType | string | 필수 | 미납·현금·카드·이체·수표·상품권·인터넷 결제·토스 프런트 중 하나입니다. 수납 내역을 기록하며 실제 결제는 실행하지 않습니다. | "예시" |
memo | string | 조건부·선택 | 출고 관리 메모입니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"item": {
"type": "string",
"description": "부교재 이름입니다. 공통 교재는 공통으로 입력합니다.",
"nullable": false,
"maxLength": 200,
"minLength": 1
},
"issued": {
"type": "boolean",
"description": "출고 여부입니다.",
"nullable": false,
"default": false
},
"returned": {
"type": "boolean",
"description": "반품 여부입니다.",
"nullable": false,
"default": false
},
"excluded": {
"type": "boolean",
"description": "출고 대상에서 제외할지 여부입니다.",
"nullable": false,
"default": false
},
"amount": {
"type": "integer",
"description": "현재 출고 금액입니다. 원 단위입니다.",
"nullable": false,
"minimum": 0,
"maximum": 100000000,
"default": 0
},
"paymentType": {
"type": "string",
"description": "미납·현금·카드·이체·수표·상품권·인터넷 결제·토스 프런트 중 하나입니다. 수납 내역을 기록하며 실제 결제는 실행하지 않습니다.",
"nullable": false,
"maxLength": 20,
"minLength": 1
},
"memo": {
"type": "string",
"description": "출고 관리 메모입니다.",
"nullable": false,
"maxLength": 2000,
"default": ""
}
},
"required": [
"studentId",
"scheduleId",
"item",
"paymentType"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"studentId": "00000001",
"scheduleId": 1,
"item": "예시",
"issued": false,
"returned": false,
"excluded": false,
"amount": 0,
"paymentType": "예시",
"memo": "예시"
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/books/{bookId}/issues/{issueId}원본 출고 조회 후 전체 값 수정(반품 해제·원복은 returned=false, 제외 해제·원복은 excluded=false, 다른 현재 값 보존)+
books.write · books.issues.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
bookId | path | 필수 | GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다. |
issueId | path | 필수 | GET /v1/books/{bookId}/issues 응답 data.items[].id의 출고 기록 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
studentId | string | 필수 | GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요. | "00000001" |
scheduleId | integer | 필수 | GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요. | 1 |
item | string | 필수 | 부교재 이름입니다. 공통 교재는 공통으로 입력합니다. | "예시" |
issued | boolean | 조건부·선택 | 출고 여부입니다. | false |
returned | boolean | 조건부·선택 | 반품 여부입니다. | false |
excluded | boolean | 조건부·선택 | 출고 대상에서 제외할지 여부입니다. | false |
amount | integer | 조건부·선택 | 현재 출고 금액입니다. 원 단위입니다. | 0 |
paymentType | string | 필수 | 미납·현금·카드·이체·수표·상품권·인터넷 결제·토스 프런트 중 하나입니다. 수납 내역을 기록하며 실제 결제는 실행하지 않습니다. | "예시" |
memo | string | 조건부·선택 | 출고 관리 메모입니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"studentId": {
"type": "string",
"description": "GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요.",
"nullable": false,
"maxLength": 30,
"minLength": 1
},
"scheduleId": {
"type": "integer",
"description": "GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.",
"nullable": false,
"minimum": 1,
"maximum": 2147483647
},
"item": {
"type": "string",
"description": "부교재 이름입니다. 공통 교재는 공통으로 입력합니다.",
"nullable": false,
"maxLength": 200,
"minLength": 1
},
"issued": {
"type": "boolean",
"description": "출고 여부입니다.",
"nullable": false,
"default": false
},
"returned": {
"type": "boolean",
"description": "반품 여부입니다.",
"nullable": false,
"default": false
},
"excluded": {
"type": "boolean",
"description": "출고 대상에서 제외할지 여부입니다.",
"nullable": false,
"default": false
},
"amount": {
"type": "integer",
"description": "현재 출고 금액입니다. 원 단위입니다.",
"nullable": false,
"minimum": 0,
"maximum": 100000000,
"default": 0
},
"paymentType": {
"type": "string",
"description": "미납·현금·카드·이체·수표·상품권·인터넷 결제·토스 프런트 중 하나입니다. 수납 내역을 기록하며 실제 결제는 실행하지 않습니다.",
"nullable": false,
"maxLength": 20,
"minLength": 1
},
"memo": {
"type": "string",
"description": "출고 관리 메모입니다.",
"nullable": false,
"maxLength": 2000,
"default": ""
}
},
"required": [
"studentId",
"scheduleId",
"item",
"paymentType"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"studentId": "00000001",
"scheduleId": 1,
"item": "예시",
"issued": false,
"returned": false,
"excluded": false,
"amount": 0,
"paymentType": "예시",
"memo": "예시"
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/books/{bookId}/issues/{issueId}청구에 사용하지 않은 출고 기록 삭제+
books.write · books.issues.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
bookId | path | 필수 | GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다. |
issueId | path | 필수 | GET /v1/books/{bookId}/issues 응답 data.items[].id의 출고 기록 번호입니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/books/{bookId}/items기존 출고 부교재 이름 목록+
books.read · books.items
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
bookId | path | 필수 | GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "string"
}
}성공 응답 예시
{
"data": [
"예시"
],
"meta": {
"requestId": "example-request-id"
}
}문자·알림톡
GET/v1/messages/template-examples공유 문자 예제 제목·분류·원문 조회(제목순·삭제 제외)웹 관리 기능+
웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요messages.read · messages.templates.examples
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
search | query | 선택 | 검색어입니다. 최대 100자이며 생략하면 전체를 조회합니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 저장된 문구 번호입니다. | 1 |
items[].title | string | 필수 | 저장된 문구 제목입니다. | "예시" |
items[].category | string | 필수 | 문구의 분류명입니다. | "예시" |
items[].content | string | 필수 | 저장된 원문입니다. 조회만으로 치환하거나 발송하지 않습니다. | "예시" |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "저장된 문구 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "저장된 문구 제목입니다.",
"nullable": false
},
"category": {
"type": "string",
"description": "문구의 분류명입니다.",
"nullable": false
},
"content": {
"type": "string",
"description": "저장된 원문입니다. 조회만으로 치환하거나 발송하지 않습니다.",
"nullable": false
}
},
"required": [
"id",
"title",
"category",
"content"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"id": 1,
"title": "예시",
"category": "예시",
"content": "예시"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/messages/template-examples/categories공유 문자 예제 분류 목록(학원 저장 문구와 분리)웹 관리 기능+
웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요messages.read · messages.templates.categories
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|
응답 data JSON 스키마
{
"type": "array",
"items": {
"type": "string"
}
}성공 응답 예시
{
"data": [
"예시"
],
"meta": {
"requestId": "example-request-id"
}
}GET/v1/messages/templates현재 학원이 저장한 문자 문구 목록(공유 예제·AI 프롬프트 제외)웹 관리 기능+
웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요messages.read · messages.templates.list
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
page | query | 선택 | 페이지 번호입니다. 기본값 1, 1~100000입니다. |
pageSize | query | 선택 | 페이지당 결과 수입니다. 기본값 30, 최대 100입니다. |
search | query | 선택 | 검색어입니다. 최대 100자이며 생략하면 전체를 조회합니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
items | array | 필수 | 현재 페이지의 조회 결과 배열입니다. | 하위 필드·본문 예시 참조 |
items[].id | integer | 필수 | 저장된 문구 번호입니다. | 1 |
items[].title | string | 필수 | 저장된 문구 제목입니다. | "예시" |
items[].category | string | 필수 | 문구의 분류명입니다. | "예시" |
items[].content | string | 필수 | 저장된 원문입니다. 조회만으로 치환하거나 발송하지 않습니다. | "예시" |
page | integer | 필수 | 현재 페이지 번호입니다. 1부터 시작합니다. | 1 |
pageSize | integer | 필수 | 한 페이지에 반환하는 자료 수입니다. 1~100입니다. | 1 |
total | integer | 필수 | 검색 조건에 맞는 전체 자료 수입니다. | 1 |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "저장된 문구 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "저장된 문구 제목입니다.",
"nullable": false
},
"category": {
"type": "string",
"description": "문구의 분류명입니다.",
"nullable": false
},
"content": {
"type": "string",
"description": "저장된 원문입니다. 조회만으로 치환하거나 발송하지 않습니다.",
"nullable": false
}
},
"required": [
"id",
"title",
"category",
"content"
]
},
"description": "현재 페이지의 조회 결과 배열입니다.",
"nullable": false
},
"page": {
"type": "integer",
"description": "현재 페이지 번호입니다. 1부터 시작합니다.",
"nullable": false
},
"pageSize": {
"type": "integer",
"description": "한 페이지에 반환하는 자료 수입니다. 1~100입니다.",
"nullable": false
},
"total": {
"type": "integer",
"description": "검색 조건에 맞는 전체 자료 수입니다.",
"nullable": false
}
},
"required": [
"items",
"page",
"pageSize",
"total"
]
}성공 응답 예시
{
"data": {
"items": [
{
"id": 1,
"title": "예시",
"category": "예시",
"content": "예시"
}
],
"page": 1,
"pageSize": 1,
"total": 1
},
"meta": {
"requestId": "example-request-id"
}
}GET/v1/messages/templates/{templateId}저장된 문자 문구 원문·현재 변경 검증 version 조회웹 관리 기능+
웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요messages.read · messages.templates.get
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
templateId | path | 필수 | 현재 학원이 저장한 문자 문구 목록에서 확인한 실제 문구 번호입니다. 공용 예제 번호를 전달하지 않습니다. |
응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 학원이 저장한 문구 번호입니다. | 1 |
title | string | 필수 | 문구 제목입니다. | "예시" |
category | string | 필수 | 문구 분류명입니다. | "예시" |
content | string | 필수 | 저장된 치환변수를 유지한 문구 원문입니다. | "예시" |
version | string | 필수 | 수정·삭제 시 그대로 보내는 현재 변경 검증 값입니다. | "예시" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "학원이 저장한 문구 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "문구 제목입니다.",
"nullable": false
},
"category": {
"type": "string",
"description": "문구 분류명입니다.",
"nullable": false
},
"content": {
"type": "string",
"description": "저장된 치환변수를 유지한 문구 원문입니다.",
"nullable": false
},
"version": {
"type": "string",
"description": "수정·삭제 시 그대로 보내는 현재 변경 검증 값입니다.",
"nullable": false
}
},
"required": [
"id",
"title",
"category",
"content",
"version"
]
}성공 응답 예시
{
"data": {
"id": 1,
"title": "예시",
"category": "예시",
"content": "예시",
"version": "예시"
},
"meta": {
"requestId": "example-request-id"
}
}POST/v1/messages/templates학원 문자 문구 신규 저장(발송·AI 호출 없음)웹 관리 기능+
웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요messages.write · messages.templates.create
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
title | string | 필수 | 문구 제목입니다. 화면과 동일하게 100바이트까지 저장합니다. | "예시" |
category | string | 조건부·선택 | 분류명입니다. null이면 수정 시 기존 분류를 보존하며 빈 문자열이면 비웁니다. 최대 200바이트입니다. | "예시" |
content | string | 필수 | 문구 원문입니다. 치환변수를 유지하며 최대 2000바이트입니다. | "예시" |
version | string | 조건부·선택 | 수정 시 상세 조회에서 받은 현재 version이 필수입니다. 신규 저장에서는 생략합니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "문구 제목입니다. 화면과 동일하게 100바이트까지 저장합니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1
},
"category": {
"type": "string",
"description": "분류명입니다. null이면 수정 시 기존 분류를 보존하며 빈 문자열이면 비웁니다. 최대 200바이트입니다.",
"nullable": true,
"maxLength": 200
},
"content": {
"type": "string",
"description": "문구 원문입니다. 치환변수를 유지하며 최대 2000바이트입니다.",
"nullable": false,
"maxLength": 2000,
"minLength": 1
},
"version": {
"type": "string",
"description": "수정 시 상세 조회에서 받은 현재 version이 필수입니다. 신규 저장에서는 생략합니다.",
"nullable": true,
"maxLength": 64
}
},
"required": [
"title",
"content"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 학원이 저장한 문구 번호입니다. | 1 |
title | string | 필수 | 문구 제목입니다. | "예시" |
category | string | 필수 | 문구 분류명입니다. | "예시" |
content | string | 필수 | 저장된 치환변수를 유지한 문구 원문입니다. | "예시" |
version | string | 필수 | 수정·삭제 시 그대로 보내는 현재 변경 검증 값입니다. | "예시" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "학원이 저장한 문구 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "문구 제목입니다.",
"nullable": false
},
"category": {
"type": "string",
"description": "문구 분류명입니다.",
"nullable": false
},
"content": {
"type": "string",
"description": "저장된 치환변수를 유지한 문구 원문입니다.",
"nullable": false
},
"version": {
"type": "string",
"description": "수정·삭제 시 그대로 보내는 현재 변경 검증 값입니다.",
"nullable": false
}
},
"required": [
"id",
"title",
"category",
"content",
"version"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"title": "예시",
"category": "예시",
"content": "예시",
"version": "예시"
}성공 응답 예시
{
"data": {
"id": 1,
"title": "예시",
"category": "예시",
"content": "예시",
"version": "예시"
},
"meta": {
"requestId": "example-request-id"
}
}PUT/v1/messages/templates/{templateId}현재 학원의 문자 문구 제목·분류·내용 수정(현재 version 검증·공유 예제 수정 불가)웹 관리 기능+
웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요messages.write · messages.templates.update
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
templateId | path | 필수 | 현재 학원이 저장한 문자 문구 목록에서 확인한 실제 문구 번호입니다. 공용 예제 번호를 전달하지 않습니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
title | string | 필수 | 문구 제목입니다. 화면과 동일하게 100바이트까지 저장합니다. | "예시" |
category | string | 조건부·선택 | 분류명입니다. null이면 수정 시 기존 분류를 보존하며 빈 문자열이면 비웁니다. 최대 200바이트입니다. | "예시" |
content | string | 필수 | 문구 원문입니다. 치환변수를 유지하며 최대 2000바이트입니다. | "예시" |
version | string | 조건부·선택 | 수정 시 상세 조회에서 받은 현재 version이 필수입니다. 신규 저장에서는 생략합니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "문구 제목입니다. 화면과 동일하게 100바이트까지 저장합니다.",
"nullable": false,
"maxLength": 100,
"minLength": 1
},
"category": {
"type": "string",
"description": "분류명입니다. null이면 수정 시 기존 분류를 보존하며 빈 문자열이면 비웁니다. 최대 200바이트입니다.",
"nullable": true,
"maxLength": 200
},
"content": {
"type": "string",
"description": "문구 원문입니다. 치환변수를 유지하며 최대 2000바이트입니다.",
"nullable": false,
"maxLength": 2000,
"minLength": 1
},
"version": {
"type": "string",
"description": "수정 시 상세 조회에서 받은 현재 version이 필수입니다. 신규 저장에서는 생략합니다.",
"nullable": true,
"maxLength": 64
}
},
"required": [
"title",
"content"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer | 필수 | 학원이 저장한 문구 번호입니다. | 1 |
title | string | 필수 | 문구 제목입니다. | "예시" |
category | string | 필수 | 문구 분류명입니다. | "예시" |
content | string | 필수 | 저장된 치환변수를 유지한 문구 원문입니다. | "예시" |
version | string | 필수 | 수정·삭제 시 그대로 보내는 현재 변경 검증 값입니다. | "예시" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "학원이 저장한 문구 번호입니다.",
"nullable": false
},
"title": {
"type": "string",
"description": "문구 제목입니다.",
"nullable": false
},
"category": {
"type": "string",
"description": "문구 분류명입니다.",
"nullable": false
},
"content": {
"type": "string",
"description": "저장된 치환변수를 유지한 문구 원문입니다.",
"nullable": false
},
"version": {
"type": "string",
"description": "수정·삭제 시 그대로 보내는 현재 변경 검증 값입니다.",
"nullable": false
}
},
"required": [
"id",
"title",
"category",
"content",
"version"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"title": "예시",
"category": "예시",
"content": "예시",
"version": "예시"
}성공 응답 예시
{
"data": {
"id": 1,
"title": "예시",
"category": "예시",
"content": "예시",
"version": "예시"
},
"meta": {
"requestId": "example-request-id"
}
}DELETE/v1/messages/templates/{templateId}현재 학원 문자 문구 삭제(현재 version 검증·소프트 삭제)웹 관리 기능+
웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요messages.write · messages.templates.delete
경로 · 검색 파라미터
| 이름 | 위치 | 필수 | 설명 |
|---|---|---|---|
templateId | path | 필수 | 현재 학원이 저장한 문자 문구 목록에서 확인한 실제 문구 번호입니다. 공용 예제 번호를 전달하지 않습니다. |
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →요청 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
version | string | 필수 | 직전 문구 상세 조회에서 받은 정확한 version입니다. | "예시" |
요청 JSON 스키마
{
"type": "object",
"properties": {
"version": {
"type": "string",
"description": "직전 문구 상세 조회에서 받은 정확한 version입니다.",
"nullable": false,
"minLength": 1,
"pattern": "^[A-F0-9]{64}$"
}
},
"required": [
"version"
]
}응답 data 필드
| 필드 | 자료형 | 필수 여부 | 값 출처 · 입력 방법 | 예시 값 |
|---|---|---|---|---|
id | integer|string | 필수 | 자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다. | "1" |
응답 data JSON 스키마
{
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.",
"nullable": false
}
},
"required": [
"id"
]
}요청 본문 예시
형식 설명용 합성 예제입니다. ID는 실제 조회·업로드 응답으로 바꾸세요. REPLACE_WITH_로 시작하는 값은 실행 가능한 파일 데이터가 아니며 실제 파일 바이트를 인코딩해 넣어야 합니다.
{
"version": "예시"
}성공 응답 예시
{
"data": {
"id": "1"
},
"meta": {
"requestId": "example-request-id"
}
}웹 관리자 문자 API 웹 관리 기능
호출 서버는 klasslab.com(Web)입니다. 관리자 로그인 세션과 문자 메뉴 권한이 필요하고 POST에는 CSRF 토큰이 필요합니다. 외부 API 키·공개 MCP에서는 사용할 수 없습니다.
| 메서드·경로 | 내용 |
|---|---|
GET /internal/assistant/messages/connections | 연동·사용 중지 상태와 등록 발신번호 조회. 인증정보는 반환하지 않습니다. |
POST /internal/assistant/messages/preview | provider, sender, title, message, studentIds, contact를 검증해 학생 이름·번호·실제 연락처와 보호된 발송 확인 토큰을 반환합니다. |
POST /internal/assistant/messages/send | previewToken과 confirm=true로 확인한 발송만 실행합니다. 학생 연락처·연동 상태·토큰 유효기간을 다시 검증하며 업체 요금이 적용됩니다. |
GET /internal/assistant/messages/status/{id} | 실제 발송 응답에서 받은 요청 UUID로 업체 접수 결과를 조회합니다. 실제 휴대폰 전달 완료와는 구분합니다. |
요청에 넣을 값 준비하기
요청 필드의 필수는 반드시 보내야 한다는 뜻입니다. 응답 data 표의 필수는 서버가 반환하는 항목이며 요청에 넣을 값이 아닙니다. 자료의 ID는 먼저 조회하거나 생성한 응답에서 가져오고, 파일 바이트는 호출하는 프로그램이 읽어 준비합니다. 아래와 본문의 숫자·UUID·파일 주소는 형식을 설명하는 합성 예시입니다. 실제 계정의 응답 값으로 바꾸세요.
| 입력 필드 | 값을 얻는 방법 |
|---|---|
studentId | GET /v1/students의 data.items[].id. 학생 이름·전화번호가 아닌 문자열 ID이며 앞자리 0을 유지합니다. |
teamId · scheduleId | GET /v1/teams의 data.items[].id로 반을 선택한 뒤 GET /v1/teams/{teamId}/schedules의 data[].id로 해당 반의 시간표를 선택합니다. |
teacherId · teacherIds | GET /v1/teams/teachers의 data[].id를 정수로 변환해 사용합니다(teams.read 권한 필요). 대표 계정도 목록의 실제 번호를 사용하며 0은 기본 선생님이 아닙니다. 시험 등록의 teacherId만 생략할 수 있고, 신규 시험은 대표 담당자·수정은 기존 담당자를 유지합니다. |
staffId | 상담 예약은 GET /v1/consultations/staff의 문자열 id, 직원 근무일지는 GET /v1/attendance/staff의 정수 id를 사용합니다. 서로 다른 자료이므로 바꿔 넣을 수 없습니다. 업무 담당자는 GET /v1/teams/teachers에서 선택합니다. 출퇴근용 직원 등록은 POST /v1/attendance/staff를 사용하며 웹 로그인 계정·비밀번호를 발급하지 않습니다. |
enrollmentId | 수강 등록 응답의 data.enrollmentId 또는 GET /v1/students/{id}/enrollments의 data[].id입니다. 수강 등록 응답의 기존 data.id는 학생 번호입니다. |
examId · examIds | GET /v1/grading/exams의 data.items[].id. 시험 번호이며 OMR 양식 번호(예: 120)와 다릅니다. |
fileId · fileIds | PDF 업로드 응답 data.files[].id를 페이지 순서대로 전달합니다. 이미지·XLSX 단일 업로드는 data.id를 사용합니다. 직접 만든 UUID나 로컬 파일 경로는 사용하지 않습니다. |
expectedUnitCredits · consent | expectedUnitCredits는 이전 연동 호환용으로 생략하거나 0을 보냅니다. 현재 구독의 OMR 한도와 이미지 장수를 확인하고 실행에 동의한 경우에만 consent: true를 보냅니다. |
반과 시간표를 함께 등록하기
새 반과 주간 시간표를 함께 만들려면 POST /v1/teams/with-schedules에 team과 schedules를 보냅니다. 하나의 트랜잭션으로 저장하며 시간표 하나라도 실패하면 반 등록도 취소됩니다. 반환된 data.id와 data.scheduleIds를 다음 수강·수업 등록에 사용하세요. 동일 요청을 다시 확인할 때는 같은 중복 방지 키를 사용합니다.
담당 선생님 선택·직원 출퇴근·수강 전반 취소
API·MCP 사용자는 가입한 대표 선생님을 기준으로 업무를 처리합니다. 담당자가 필요한 작업에서는 GET /v1/teams/teachers의 실제 번호를 사용하세요.
선생님·로그인 계정·권한 관리와 홈페이지 관리는 AI 도우미 및 공개 API·MCP에서 제공하지 않습니다. 해당 작업은 관리자 화면에서 직접 진행해 주세요.
직원은 POST /v1/attendance/staff에 { "name": "김조교", "role": "조교", "startDate": "2026-10-19" }처럼 등록합니다. 기본정보 등록·수정·퇴사는 staff.manage, 근무일지 저장은 staff.write, 조회는 staff.read 권한을 사용합니다. 직원 정보의 data.id를 근무일지의 정수 staffId에 넣으세요. DELETE는 오늘 날짜로 퇴사 처리하며 근무 이력을 삭제하지 않습니다. 입사 전이나 퇴사일부터의 근무일지는 저장할 수 없습니다.
전반 취소는 먼저 학생의 수강 이력을 조회해 이전 반·새 반·전반일을 확인한 뒤 새 반의 수강번호로 POST /v1/students/{id}/enrollments/{enrollmentId}/cancel-transfer를 호출합니다. 본문은 없고 students.write와 Idempotency-Key가 필요합니다. 이전 반을 복원하고 새 반은 전반 취소 이력으로 보존합니다. 여러 번 전반했다면 마지막 전반부터 취소하며, 종강되었거나 이후 이력이 변경된 경우에는 거절합니다.
기존 API 키에 새 관리 권한이 없다면 필요한 권한을 선택해 새 키를 발급하세요. MCP 연결도 새 권한에 다시 동의해야 사용할 수 있습니다.
파일 업로드 방식 선택
| 업로드 경로 | 입력값과 준비 방법 |
|---|---|
POST /v1/grading/pdf-uploads | 일반 PDF 업로드입니다. fileName에는 확장자를 포함한 파일명, base64에는 PDF 파일 전체 바이트를 Base64로 인코딩한 문자열을 보냅니다. |
POST /v1/grading/uploads | PNG·JPG 스캔 이미지 또는 XLSX 답안 파일을 같은 fileName·base64 방식으로 보냅니다. |
POST /v1/grading/attachments | 첨부 참조 메타데이터를 제공하는 연동 클라이언트 전용입니다. file.download_url과 file.file_id는 클라이언트가 제공한 같은 파일의 메타데이터에서 가져옵니다. 현재 승인된 다운로드 호스트는 oaiusercontent.com 및 그 하위 도메인입니다. 이 값을 제공받지 못하는 일반 API 프로그램은 위의 직접 업로드 경로를 사용하세요. |
다음은 Node.js에서 실제 PDF 파일로 요청 본문을 만드는 예입니다. 생성한 객체를 PDF 업로드 API에 JSON으로 전송하세요. Base64는 파일명·URL·로컬 경로가 아니며 data: 접두사를 붙이지 않습니다.
import { readFile } from 'node:fs/promises';
const bytes = await readFile('./omr.pdf');
const body = { fileName: 'omr.pdf', base64: bytes.toString('base64') };OMR PDF 업로드
스캔한 PDF는 최대 50MB·100쪽까지 업로드할 수 있습니다. POST /v1/grading/pdf-uploads에 PDF 원본의 Base64와 파일명을 보내세요. 채팅 첨부파일은 POST /v1/grading/attachments로 전달합니다.
응답의 files 순서대로 파일 ID를 OMR 채점 요청에 넣습니다. 업로드만으로 채점되거나 OMR 크레딧이 차감되지 않습니다. 변환 이미지는 페이지당 5MB·전체 100MB 이하이며, 유효한 업로드는 학원별 최대 100개입니다(PDF 페이지마다 1개, 24시간 보관).
보조 업로드는 PNG·JPG 스캔 이미지와 XLSX 답안 파일을 파일당 5MB까지 지원합니다. XLSX는 OMR 인식이 아닌 학생 번호·문항별 답안 가져오기에 사용합니다.
공통 오류
400 | 필수값·자료형·범위를 확인하세요. |
401 | API 키를 확인하세요. |
403 | 활성 API 구독·키 권한·이용 동의를 확인하세요. |
404 | 자료가 없거나 접근 범위에 없습니다. |
409 | 업무 상태·가격 변경·중복 방지 키 충돌을 확인하세요. |
429 | 분당·구독 기간 사용량 한도를 확인하세요. |
503 | 실행기·저장소 등 서비스 준비 상태를 확인하세요. |
업무 오류 예시
{
"error": {
"code": "not_found",
"message": "자료를 찾을 수 없습니다."
},
"requestId": "example-request-id"
}인증·공통 계층 오류 예시
{
"status": 401,
"title": "API 키 인증이 필요합니다.",
"code": "invalid_api_key",
"traceId": "example-trace-id"
}오류의 code로 분기하고 requestId 또는 traceId를 문의에 포함하세요. 같은 변경 요청을 재시도할 때는 기존 Idempotency-Key를 유지하세요.