본문 바로가기
KLASSLAB API / V1

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

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/teams 응답 data.items[].id의 수강반 번호입니다.
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].studentIdstring필수학원 내 실제 학생 번호입니다."00000001"
items[].studentNamestring필수학생 번호에 해당하는 실제 학생 이름입니다."예시 이름"
items[].enrollmentobject필수정확한 수강 기록과 명시된 종료 사유·효력일·전반 출처입니다.하위 필드·본문 예시 참조
items[].enrollment.idinteger필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.1
items[].enrollment.studentIdstring필수학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다."00000001"
items[].enrollment.teamIdinteger필수수강반 고유 번호입니다. 수강반 조회에서 확인합니다.1
items[].enrollment.scheduleIdinteger필수수강반 시간표 고유 번호입니다. 해당 반의 시간표여야 합니다.1
items[].enrollment.teamNamestring필수수강반 이름입니다."예시 이름"
items[].enrollment.scheduleNamestring필수시간표 표시 이름입니다."예시 이름"
items[].enrollment.beginDateinteger필수시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.20260115
items[].enrollment.endDateinteger필수종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.20260115
items[].enrollment.endTypestring필수저장된 수강 종료 사유입니다. 빈 문자열, 퇴원, 전반, 종강, 전반취소를 사용합니다. 최대 20자이며 기존의 미확인 사유도 보존합니다. 이미 시작한 수강의 미래 종료는 active, 미래 시작은 upcoming이며 전반취소는 시작일과 관계없이 항상 cancelled입니다."예시"
items[].enrollment.changeDateinteger필수전반으로 종료되는 기존 수강 건의 전반일입니다. yyyyMMdd 정수이며 0은 미설정입니다.20260115
items[].enrollment.scheduleDaystring필수해당 수강 시간표의 실제 요일입니다. 없으면 빈 문자열입니다."예시"
items[].enrollment.scheduleFromstring필수해당 수강 시간표의 실제 시작 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다."예시"
items[].enrollment.scheduleTostring필수해당 수강 시간표의 실제 종료 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다."예시"
items[].enrollment.transferFromIdinteger필수전반 전의 기존 수강 건 번호입니다. 연결 없는 과거 자료는 null입니다.1
items[].enrollment.transferDateinteger필수새 반으로 전반한 지정일입니다. yyyyMMdd 정수, 0은 연결 없음입니다.20260115
items[].enrollment.previousTeamNamestring필수전반 이전 반·시간표 표시명입니다."예시 이름"
items[].enrollment.isTransferboolean필수명시적인 이전 수강 연결값이 있는 전반 등록인지 나타냅니다.false
items[].enrollment.isTransferCancelledboolean필수전반 취소 이력인지 나타냅니다. 취소해도 출결·수납 자료와 수강 건은 보존됩니다.false
items[].enrollment.transferCancelledAtstring필수전반 취소 시각(UTC)입니다. 취소 전에는 null입니다."2026-01-15T00:00:00Z"
items[].enrollment.classEndDateinteger필수반 자체의 종강일입니다. 학생별 endDate와 별개인 yyyyMMdd 정수이며 0은 미설정입니다.20260115
items[].enrollment.effectiveEndDateinteger필수조회 시 적용할 종료일입니다. 학생별 종료일이 없으면 반 종강일을 사용하며 종료 사유는 추정하지 않습니다.20260115
items[].enrollment.isEndedboolean필수한국 날짜를 기준으로 종료 효력이 발생했는지 나타냅니다. 일반 미래 종료는 false지만 전반 취소 이력은 시작일과 관계없이 항상 true입니다.false
items[].enrollment.statusstring필수수강 시작 전, 수강중, 퇴원, 전반, 종강, 전반 취소, 종료(구분 미확인) 또는 종료 예정 상태입니다. 미래 시작은 현재 수강중이 아니며, 예정 종료 사유는 함께 표시합니다."예시"
items[].enrollment.statusCodestring필수상태 표시 코드입니다. upcoming(미래 시작), active, retired, transferred, ended, cancelled, unknown 중 하나입니다. 전반 취소는 시작일과 관계없이 cancelled입니다."예시"
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teams수강반·담당·시간표 목록. status=open 미종강(미래 개강·종강 포함), closed 종강, all 전체. 한국 오늘 기준. sort=id_desc 최신 등록번호순, begin_date_asc/desc 개강일순. appliedSort/appliedStatus 확인

teams.read · teams.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
sortquery선택수강반 정렬입니다. id_asc(기본)는 등록번호 오름차순, id_desc는 최신 등록번호순, begin_date_asc/desc는 개강일순입니다. 같은 개강일은 등록번호로 정렬하며 응답 appliedSort로 실제 적용 여부를 확인하세요.
statusquery선택종강 필터입니다. all(기본)은 전체, open은 한국 오늘 기준 미종강(미래 개강·종강 포함), closed는 종강일이 오늘 이하인 반입니다. 필터 후 전체 건수와 페이지를 계산하며 응답 appliedStatus와 referenceDate로 적용 여부를 확인하세요.
searchquery선택검색어입니다. 최대 100자이며 생략하면 전체를 조회합니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray조건부·선택현재 페이지의 수강반 배열입니다.하위 필드·본문 예시 참조
items[].idinteger필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.1
items[].namestring필수이름 또는 표시 명칭입니다."예시 이름"
items[].gradestring필수학년 표시값입니다."예시"
items[].subjectstring필수수강반의 과목 이름입니다."예시"
items[].levelstring필수수강반의 수준 또는 단계 이름입니다."예시"
items[].beginDateinteger필수시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.20260115
items[].endDateinteger필수종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.20260115
items[].teacherIdsarray필수담당 선생님 번호 배열입니다. 선생님 선택 목록에서 받은 번호만 사용합니다.하위 필드·본문 예시 참조
items[].teachersarray필수담당 번호에 대응하는 선생님 id·name 목록. 현재 권한으로 확인되지 않은 번호는 포함하지 않습니다.하위 필드·본문 예시 참조
items[].teachers[].idstring필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다."1"
items[].teachers[].namestring필수이름 또는 표시 명칭입니다."예시 이름"
items[].schedulesarray필수이 반의 저장된 주간 시간표. 요일·시작/종료 시각·적용 기간·상담 여부를 함께 확인. 미래·종료 시간표를 현재 시간표로 단정하지 않음.하위 필드·본문 예시 참조
items[].schedules[].idinteger필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.1
items[].schedules[].teamIdinteger필수수강반 고유 번호입니다. 수강반 조회에서 확인합니다.1
items[].schedules[].daystring필수요일입니다. 월·화·수·목·금·토·일 중 하나입니다."월"
items[].schedules[].fromstring필수수업 시작 시각입니다. HHmm 형식입니다."2026-01-15"
items[].schedules[].tostring필수수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다."2026-01-15"
items[].schedules[].beginDatestring필수시간표 적용 시작일입니다. yyyyMMdd 문자열이며 0은 미설정입니다."2026-01-15"
items[].schedules[].endDatestring필수시간표 적용 종료일입니다. yyyyMMdd 문자열이며 0은 미설정입니다."2026-01-15"
items[].schedules[].kindinteger필수시간표 종류입니다. 1은 수업, 2는 상담입니다.1
pageinteger조건부·선택현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger조건부·선택한 페이지의 자료 수입니다. 1~100입니다.1
totalinteger조건부·선택검색 조건에 맞는 전체 수강반 수입니다.1
appliedSortstring조건부·선택실제로 적용한 정렬입니다. id_asc는 등록번호 오름차순, id_desc는 최신 등록번호순, begin_date_asc/desc는 개강일 순입니다. 같은 개강일은 등록번호로 정렬합니다."예시"
appliedStatusstring조건부·선택적용된 종강 필터입니다. all은 전체, open은 미종강(미래 개강·종강 포함), closed는 종강입니다."예시"
referenceDateinteger조건부·선택종강 상태를 판정한 한국 오늘 날짜입니다. 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teams/{id}수강반 상세

teams.read · teams.get

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/teams 응답 data.items[].id의 수강반 번호입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.1
namestring필수이름 또는 표시 명칭입니다."예시 이름"
gradestring필수학년 표시값입니다."예시"
subjectstring필수수강반의 과목 이름입니다."예시"
levelstring필수수강반의 수준 또는 단계 이름입니다."예시"
beginDateinteger필수시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.20260115
endDateinteger필수종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.20260115
teacherIdsarray필수담당 선생님 번호 배열입니다. 선생님 선택 목록에서 받은 번호만 사용합니다.하위 필드·본문 예시 참조
teachersarray필수담당 번호에 대응하는 선생님 id·name 목록. 현재 권한으로 확인되지 않은 번호는 포함하지 않습니다.하위 필드·본문 예시 참조
teachers[].idstring필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다."1"
teachers[].namestring필수이름 또는 표시 명칭입니다."예시 이름"
schedulesarray필수이 반의 저장된 주간 시간표. 요일·시작/종료 시각·적용 기간·상담 여부를 함께 확인. 미래·종료 시간표를 현재 시간표로 단정하지 않음.하위 필드·본문 예시 참조
schedules[].idinteger필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.1
schedules[].teamIdinteger필수수강반 고유 번호입니다. 수강반 조회에서 확인합니다.1
schedules[].daystring필수요일입니다. 월·화·수·목·금·토·일 중 하나입니다."월"
schedules[].fromstring필수수업 시작 시각입니다. HHmm 형식입니다."2026-01-15"
schedules[].tostring필수수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다."2026-01-15"
schedules[].beginDatestring필수시간표 적용 시작일입니다. yyyyMMdd 문자열이며 0은 미설정입니다."2026-01-15"
schedules[].endDatestring필수시간표 적용 종료일입니다. yyyyMMdd 문자열이며 0은 미설정입니다."2026-01-15"
schedules[].kindinteger필수시간표 종류입니다. 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"
  }
}
Explorer에서 요청 구성 →
POST/v1/teams수강반 등록

teams.write · teams.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
namestring필수이름 또는 표시 명칭입니다."수학 A반"
gradestring조건부·선택학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다."예시"
subjectstring조건부·선택수강반의 과목 이름입니다."예시"
levelstring조건부·선택수강반의 수준 또는 단계 이름입니다."예시"
beginDatestring조건부·선택시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다."2026-01-15"
endDatestring조건부·선택종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다."2026-01-15"
teacherIdsarray필수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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/teams/{id}수강반 수정 · 종강/종강 취소

teams.write · teams.update

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/teams 응답 data.items[].id의 수강반 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
namestring필수이름 또는 표시 명칭입니다."수학 A반"
gradestring조건부·선택학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다."예시"
subjectstring조건부·선택수강반의 과목 이름입니다."예시"
levelstring조건부·선택수강반의 수준 또는 단계 이름입니다."예시"
beginDatestring조건부·선택시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다."2026-01-15"
endDatestring조건부·선택종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다."2026-01-15"
teacherIdsarray필수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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/teams/{id}수강반 삭제(재원생이 있으면 거절)

teams.write · teams.delete

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/teams 응답 data.items[].id의 수강반 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teams/daily-plan예정 수업·담당자·시각·고유 재원 인원. date의 하루 조회; lookAheadDays>0이면 그날부터 범위 안 첫 수업일 조회. 개강·종강·시간표 기간 적용, 저장 출석부 아님

teams.read · teams.day-plan

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
datequery필수조회할 한국 날짜입니다. yyyy-MM-dd 형식입니다. 오늘·내일 등은 서버의 Asia/Seoul 날짜로 계산합니다.
lookAheadDaysquery선택0은 지정 날짜만 조회. 1~31은 date부터 해당 일수 뒤까지 첫 수업일을 찾아 그날 전체 시간표 반환. 오늘 없으면 다음 수업 요청에 사용. 인원 0인 예정 수업도 포함.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].datestring필수조회한 한국 날짜입니다. yyyy-MM-dd 형식입니다."2026-01-15"
items[].teamIdinteger필수인증 학원의 수강반 번호입니다.1
items[].teamNamestring필수저장된 원본 수강반명입니다."예시 이름"
items[].scheduleIdinteger필수이 수업의 시간표 번호입니다.1
items[].daystring필수시간표의 요일입니다."월"
items[].fromstring필수수업 시작 시각입니다. HH:mm 형식입니다."2026-01-15"
items[].tostring필수수업 종료 시각입니다. HH:mm 형식입니다."2026-01-15"
items[].studentCountinteger필수해당 날짜에 이 반·시간표에 재원 중인 고유 학생 수입니다. 종료 효력일·전반 취소·삭제를 반영하며 저장 출석 인원과 구분합니다.1
items[].teachersarray필수이 수강반에 실제 연결된 권한 내 담당 선생님 번호·이름. 비어 있으면 목록의 유일한 선생님으로 추측하지 않음.하위 필드·본문 예시 참조
items[].teachers[].idstring필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다."1"
items[].teachers[].namestring필수이름 또는 표시 명칭입니다."예시 이름"
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teams/{id}/schedules수강반의 시간표 목록(id는 teamId이며 scheduleId 아님)

teams.read · schedules.list

경로 · 검색 파라미터

이름위치필수설명
idpath필수대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idinteger필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.1
[].teamIdinteger필수수강반 고유 번호입니다. 수강반 조회에서 확인합니다.1
[].daystring필수요일입니다. 월·화·수·목·금·토·일 중 하나입니다."월"
[].fromstring필수수업 시작 시각입니다. HHmm 형식입니다."2026-01-15"
[].tostring필수수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다."2026-01-15"
[].beginDatestring필수시간표 적용 시작일입니다. yyyyMMdd 문자열이며 0은 미설정입니다."2026-01-15"
[].endDatestring필수시간표 적용 종료일입니다. yyyyMMdd 문자열이며 0은 미설정입니다."2026-01-15"
[].kindinteger필수시간표 종류입니다. 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"
  }
}
Explorer에서 요청 구성 →
POST/v1/teams/{id}/schedules시간표 등록

teams.write · schedules.create

경로 · 검색 파라미터

이름위치필수설명
idpath필수대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
daystring필수요일입니다. 월·화·수·목·금·토·일 중 하나입니다."월"
fromstring필수수업 시작 시각입니다. HHmm 형식입니다."1600"
tostring필수수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다."1730"
beginDatestring조건부·선택시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다."2026-01-15"
endDatestring조건부·선택종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다."2026-01-15"
kindinteger조건부·선택시간표 종류입니다. 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/teams/{id}/schedules/{scheduleId}시간표 수정

teams.write · schedules.update

경로 · 검색 파라미터

이름위치필수설명
idpath필수대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다.
scheduleIdpath필수GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
daystring필수요일입니다. 월·화·수·목·금·토·일 중 하나입니다."월"
fromstring필수수업 시작 시각입니다. HHmm 형식입니다."1600"
tostring필수수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다."1730"
beginDatestring조건부·선택시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다."2026-01-15"
endDatestring조건부·선택종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다."2026-01-15"
kindinteger조건부·선택시간표 종류입니다. 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/teams/{id}/schedules/{scheduleId}시간표 삭제(수업·재원생이 있으면 거절)

teams.write · schedules.delete

경로 · 검색 파라미터

이름위치필수설명
idpath필수대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다.
scheduleIdpath필수GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idstring필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다."1"
[].namestring필수이름 또는 표시 명칭입니다."예시 이름"
응답 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"
  }
}
Explorer에서 요청 구성 →
POST/v1/teams/with-schedules새 수강반과 시간표를 함께 등록(원자적 저장·하나라도 실패하면 전체 취소)

teams.write · teams.create-with-schedules

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
teamobject필수새로 등록할 수강반 기본정보입니다. 담당 선생님은 GET /v1/teams/teachers의 실제 번호를 사용합니다. 기존 수강반 수정은 별도 API를 사용하세요.하위 필드·본문 예시 참조
team.namestring필수이름 또는 표시 명칭입니다."수학 A반"
team.gradestring조건부·선택학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다."예시"
team.subjectstring조건부·선택수강반의 과목 이름입니다."예시"
team.levelstring조건부·선택수강반의 수준 또는 단계 이름입니다."예시"
team.beginDatestring조건부·선택시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다."2026-01-15"
team.endDatestring조건부·선택종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다."2026-01-15"
team.teacherIdsarray필수GET /v1/teams/teachers 응답 data[].id에서 선택한 선생님 번호들을 배열로 전달합니다. 예: [12, 13]. 선생님 이름이나 문자열 로그인 아이디 대신 목록 id를 정수로 변환해 사용하세요. 빈 배열 []는 담당 미지정이며 0은 기본 선생님 번호가 아닙니다.하위 필드·본문 예시 참조
schedulesarray필수함께 새로 등록할 시간표 1~100개입니다. 수강반과 모든 시간표가 하나의 트랜잭션으로 저장되며 하나라도 실패하면 전부 취소됩니다. 요일과 HHmm 시각, 시작일을 지정하세요.하위 필드·본문 예시 참조
schedules[].daystring필수요일입니다. 월·화·수·목·금·토·일 중 하나입니다."월"
schedules[].fromstring필수수업 시작 시각입니다. HHmm 형식입니다."1600"
schedules[].tostring필수수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다."1730"
schedules[].beginDatestring조건부·선택시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다."2026-01-15"
schedules[].endDatestring조건부·선택종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다."2026-01-15"
schedules[].kindinteger조건부·선택시간표 종류입니다. 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수새로 등록한 수강반 번호입니다. 이후 수강 등록·수업 등록의 teamId에 사용합니다.1
scheduleIdsarray필수입력한 시간표 순서대로 반환한 실제 시간표 번호입니다. 같은 반의 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"
  }
}
Explorer에서 요청 구성 →
POST/v1/enrollments기존 학생 수강 등록

students.write · enrollments.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 예: 00000001. 이름·전화번호가 아니며 앞자리 0을 유지하세요."00000001"
teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.1
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.1
beginDatestring필수시작일입니다. 입력은 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idstring필수수강 등록한 학생 번호 문자열입니다. 기존 id 응답과 호환되며, 수강 이력 변경에는 enrollmentId를 사용하세요."1"
enrollmentIdinteger필수이번에 생성한 수강 이력의 정수 번호입니다. 수강 이력 조회 응답 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students학생 검색 · 목록(공백으로 구분한 이름·학생번호·연락처 중 하나라도 일치)

students.read · students.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
searchquery선택검색어입니다. 최대 100자이며 생략하면 전체를 조회합니다.
teamIdquery선택GET /v1/teams 응답 data.items[].id의 정수 번호로 결과를 제한합니다. 검색 조건에서 생략하면 전체 반입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].idstring필수조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다."1"
items[].namestring필수이름 또는 표시 명칭입니다."예시 이름"
items[].schoolstring필수학교 이름입니다. 빈 문자열이면 미입력입니다."예시"
items[].gradestring필수학년 표시값입니다."예시"
items[].majorstring필수계열 또는 전공 구분값입니다."예시"
items[].studentPhonestring필수학생 휴대전화 번호입니다."010-0000-0000"
items[].parentPhonestring필수보호자 연락처입니다."010-0000-0000"
items[].paymentPhonestring필수결제 안내를 받을 연락처입니다."010-0000-0000"
items[].emailstring필수이메일 주소입니다."sample@example.com"
items[].memostring필수학생 관리용 메모입니다."예시"
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}학생 기본정보

students.read · students.get

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idstring필수조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다."1"
namestring필수이름 또는 표시 명칭입니다."예시 이름"
schoolstring필수학교 이름입니다. 빈 문자열이면 미입력입니다."예시"
gradestring필수학년 표시값입니다."예시"
majorstring필수계열 또는 전공 구분값입니다."예시"
studentPhonestring필수학생 휴대전화 번호입니다."010-0000-0000"
parentPhonestring필수보호자 연락처입니다."010-0000-0000"
paymentPhonestring필수결제 안내를 받을 연락처입니다."010-0000-0000"
emailstring필수이메일 주소입니다."sample@example.com"
memostring필수학생 관리용 메모입니다."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
POST/v1/students학생 기본정보 등록(수강 등록은 별도)

students.write · students.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
namestring필수이름 또는 표시 명칭입니다."예시 학생"
schoolstring조건부·선택학교 이름입니다. 빈 문자열이면 미입력입니다."예시"
gradestring조건부·선택학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다."예시"
majorstring조건부·선택계열 또는 전공 구분값입니다."예시"
studentPhonestring조건부·선택학생 휴대전화 번호입니다."010-0000-0000"
parentPhonestring조건부·선택보호자 연락처입니다."010-0000-0000"
paymentPhonestring조건부·선택결제 안내를 받을 연락처입니다."010-0000-0000"
emailstring조건부·선택이메일 주소입니다."sample@example.com"
memostring조건부·선택학생 관리용 메모입니다."예시"
startDatestring조건부·선택학생 등록일입니다. 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idstring필수조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다."1"
namestring필수이름 또는 표시 명칭입니다."예시 이름"
schoolstring필수학교 이름입니다. 빈 문자열이면 미입력입니다."예시"
gradestring필수학년 표시값입니다."예시"
majorstring필수계열 또는 전공 구분값입니다."예시"
studentPhonestring필수학생 휴대전화 번호입니다."010-0000-0000"
parentPhonestring필수보호자 연락처입니다."010-0000-0000"
paymentPhonestring필수결제 안내를 받을 연락처입니다."010-0000-0000"
emailstring필수이메일 주소입니다."sample@example.com"
memostring필수학생 관리용 메모입니다."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/students/{id}학생 기본정보 수정(전체 필드 교체)

students.write · students.update

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
namestring필수이름 또는 표시 명칭입니다."예시 학생"
schoolstring조건부·선택학교 이름입니다. 빈 문자열이면 미입력입니다."예시"
gradestring조건부·선택학년 표시값입니다. 한글 5자 또는 영문·숫자 10자 이내이며 혼합 문자는 저장 바이트 한도를 적용합니다."예시"
majorstring조건부·선택계열 또는 전공 구분값입니다."예시"
studentPhonestring조건부·선택학생 휴대전화 번호입니다."010-0000-0000"
parentPhonestring조건부·선택보호자 연락처입니다."010-0000-0000"
paymentPhonestring조건부·선택결제 안내를 받을 연락처입니다."010-0000-0000"
emailstring조건부·선택이메일 주소입니다."sample@example.com"
memostring조건부·선택학생 관리용 메모입니다."예시"
startDatestring조건부·선택학생 등록일입니다. 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idstring필수조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다."1"
namestring필수이름 또는 표시 명칭입니다."예시 이름"
schoolstring필수학교 이름입니다. 빈 문자열이면 미입력입니다."예시"
gradestring필수학년 표시값입니다."예시"
majorstring필수계열 또는 전공 구분값입니다."예시"
studentPhonestring필수학생 휴대전화 번호입니다."010-0000-0000"
parentPhonestring필수보호자 연락처입니다."010-0000-0000"
paymentPhonestring필수결제 안내를 받을 연락처입니다."010-0000-0000"
emailstring필수이메일 주소입니다."sample@example.com"
memostring필수학생 관리용 메모입니다."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
PATCH/v1/students/{id}학생 단일 필드 수정

students.write · students.patch

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
fieldstring필수수정할 학생 필드입니다. name, school, grade, major, studentPhone, parentPhone, paymentPhone, email, memo 중 하나입니다."name"
valuestring조건부·선택사용자가 명시한 변경값입니다. 새 값을 모르면 먼저 질문하고 임의로 생성하지 마세요. 빈 값은 사용자가 비우기를 요청한 경우에만 내용을 비웁니다. 최대 길이: 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/students/{id}학생 삭제(재원 중이면 거절)

students.write · students.delete

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}/enrollments학생 수강 이력

students.read · enrollments.list

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idinteger필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.1
[].studentIdstring필수학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다."00000001"
[].teamIdinteger필수수강반 고유 번호입니다. 수강반 조회에서 확인합니다.1
[].scheduleIdinteger필수수강반 시간표 고유 번호입니다. 해당 반의 시간표여야 합니다.1
[].teamNamestring필수수강반 이름입니다."예시 이름"
[].scheduleNamestring필수시간표 표시 이름입니다."예시 이름"
[].beginDateinteger필수시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.20260115
[].endDateinteger필수종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.20260115
[].endTypestring필수저장된 수강 종료 사유입니다. 빈 문자열, 퇴원, 전반, 종강, 전반취소를 사용합니다. 최대 20자이며 기존의 미확인 사유도 보존합니다. 이미 시작한 수강의 미래 종료는 active, 미래 시작은 upcoming이며 전반취소는 시작일과 관계없이 항상 cancelled입니다."예시"
[].changeDateinteger필수전반으로 종료되는 기존 수강 건의 전반일입니다. yyyyMMdd 정수이며 0은 미설정입니다.20260115
[].scheduleDaystring필수해당 수강 시간표의 실제 요일입니다. 없으면 빈 문자열입니다."예시"
[].scheduleFromstring필수해당 수강 시간표의 실제 시작 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다."예시"
[].scheduleTostring필수해당 수강 시간표의 실제 종료 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다."예시"
[].transferFromIdinteger필수전반 전의 기존 수강 건 번호입니다. 연결 없는 과거 자료는 null입니다.1
[].transferDateinteger필수새 반으로 전반한 지정일입니다. yyyyMMdd 정수, 0은 연결 없음입니다.20260115
[].previousTeamNamestring필수전반 이전 반·시간표 표시명입니다."예시 이름"
[].isTransferboolean필수명시적인 이전 수강 연결값이 있는 전반 등록인지 나타냅니다.false
[].isTransferCancelledboolean필수전반 취소 이력인지 나타냅니다. 취소해도 출결·수납 자료와 수강 건은 보존됩니다.false
[].transferCancelledAtstring필수전반 취소 시각(UTC)입니다. 취소 전에는 null입니다."2026-01-15T00:00:00Z"
[].classEndDateinteger필수반 자체의 종강일입니다. 학생별 endDate와 별개인 yyyyMMdd 정수이며 0은 미설정입니다.20260115
[].effectiveEndDateinteger필수조회 시 적용할 종료일입니다. 학생별 종료일이 없으면 반 종강일을 사용하며 종료 사유는 추정하지 않습니다.20260115
[].isEndedboolean필수한국 날짜를 기준으로 종료 효력이 발생했는지 나타냅니다. 일반 미래 종료는 false지만 전반 취소 이력은 시작일과 관계없이 항상 true입니다.false
[].statusstring필수수강 시작 전, 수강중, 퇴원, 전반, 종강, 전반 취소, 종료(구분 미확인) 또는 종료 예정 상태입니다. 미래 시작은 현재 수강중이 아니며, 예정 종료 사유는 함께 표시합니다."예시"
[].statusCodestring필수상태 표시 코드입니다. 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"
  }
}
Explorer에서 요청 구성 →
PATCH/v1/students/{id}/enrollments/{enrollmentId}수강 등록일 수정

students.write · enrollments.date

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
enrollmentIdpath필수학생의 수강 이력 번호입니다. 해당 학생의 수강 이력 조회에서 확인합니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
beginDatestring필수시작일입니다. 입력은 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/students/{id}/enrollments/{enrollmentId}수강 등록 삭제(출결·과제 기록이 있으면 거절)

students.write · enrollments.delete

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
enrollmentIdpath필수학생의 수강 이력 번호입니다. 해당 학생의 수강 이력 조회에서 확인합니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
POST/v1/students/{id}/enrollments/{enrollmentId}/cancel-transfer전반 취소(새 반 수강번호 지정·이전 반 복원·취소 이력 보존)

students.write · enrollments.cancel-transfer

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
enrollmentIdpath필수학생의 수강 이력 번호입니다. 해당 학생의 수강 이력 조회에서 확인합니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/students/{id}/enrollments/{enrollmentId}/end퇴원 처리

students.write · enrollments.end

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
enrollmentIdpath필수학생의 수강 이력 번호입니다. 해당 학생의 수강 이력 조회에서 확인합니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
endDatestring필수종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다."2026-01-15"
memostring조건부·선택퇴원·전반 처리 기록에 함께 저장할 선택 메모입니다. 최대 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
POST/v1/students/{id}/enrollments/{enrollmentId}/move수강반 전반(원 수강 종료와 신규 등록을 함께 저장)

students.write · enrollments.move

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
enrollmentIdpath필수학생의 수강 이력 번호입니다. 해당 학생의 수강 이력 조회에서 확인합니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.1
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.1
beginDatestring필수시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다."2026-01-15"
memostring조건부·선택퇴원·전반 처리 기록에 함께 저장할 선택 메모입니다. 최대 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
POST/v1/students/{id}/enrollments/{enrollmentId}/restore퇴원 취소

students.write · enrollments.restore

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
enrollmentIdpath필수학생의 수강 이력 번호입니다. 해당 학생의 수강 이력 조회에서 확인합니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}/detail학생 이름 클릭 통합정보: 기본정보·수강 전체·최근 상담·시험성적·클리닉 요약

students.read · student.detail.overview

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
profileobject필수비밀번호를 제외한 실제 학생 기본정보입니다.하위 필드·본문 예시 참조
profile.idstring필수조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다."1"
profile.namestring필수이름 또는 표시 명칭입니다."예시 이름"
profile.schoolstring필수학교 이름입니다. 빈 문자열이면 미입력입니다."예시"
profile.gradestring필수학년 표시값입니다."예시"
profile.majorstring필수계열 또는 전공 구분값입니다."예시"
profile.studentPhonestring필수학생 휴대전화 번호입니다."010-0000-0000"
profile.parentPhonestring필수보호자 연락처입니다."010-0000-0000"
profile.paymentPhonestring필수결제 안내를 받을 연락처입니다."010-0000-0000"
profile.emailstring필수이메일 주소입니다."sample@example.com"
profile.memostring필수학생 관리용 메모입니다."예시"
enrollmentsobject필수수강·종료·전반 이력의 앞 100건과 전체 수입니다. 추가 이력은 수강 상세 API의 다음 페이지에서 조회합니다.하위 필드·본문 예시 참조
enrollments.studentIdstring조건부·선택현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다."00000001"
enrollments.studentNamestring조건부·선택학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
enrollments.itemsarray조건부·선택현재 페이지의 세부 이력입니다.하위 필드·본문 예시 참조
enrollments.items[].idinteger필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.1
enrollments.items[].studentIdstring필수학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다."00000001"
enrollments.items[].teamIdinteger필수수강반 고유 번호입니다. 수강반 조회에서 확인합니다.1
enrollments.items[].scheduleIdinteger필수수강반 시간표 고유 번호입니다. 해당 반의 시간표여야 합니다.1
enrollments.items[].teamNamestring필수수강반 이름입니다."예시 이름"
enrollments.items[].scheduleNamestring필수시간표 표시 이름입니다."예시 이름"
enrollments.items[].beginDateinteger필수시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.20260115
enrollments.items[].endDateinteger필수종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.20260115
enrollments.items[].endTypestring필수저장된 수강 종료 사유입니다. 빈 문자열, 퇴원, 전반, 종강, 전반취소를 사용합니다. 최대 20자이며 기존의 미확인 사유도 보존합니다. 이미 시작한 수강의 미래 종료는 active, 미래 시작은 upcoming이며 전반취소는 시작일과 관계없이 항상 cancelled입니다."예시"
enrollments.items[].changeDateinteger필수전반으로 종료되는 기존 수강 건의 전반일입니다. yyyyMMdd 정수이며 0은 미설정입니다.20260115
enrollments.items[].scheduleDaystring필수해당 수강 시간표의 실제 요일입니다. 없으면 빈 문자열입니다."예시"
enrollments.items[].scheduleFromstring필수해당 수강 시간표의 실제 시작 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다."예시"
enrollments.items[].scheduleTostring필수해당 수강 시간표의 실제 종료 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다."예시"
enrollments.items[].transferFromIdinteger필수전반 전의 기존 수강 건 번호입니다. 연결 없는 과거 자료는 null입니다.1
enrollments.items[].transferDateinteger필수새 반으로 전반한 지정일입니다. yyyyMMdd 정수, 0은 연결 없음입니다.20260115
enrollments.items[].previousTeamNamestring필수전반 이전 반·시간표 표시명입니다."예시 이름"
enrollments.items[].isTransferboolean필수명시적인 이전 수강 연결값이 있는 전반 등록인지 나타냅니다.false
enrollments.items[].isTransferCancelledboolean필수전반 취소 이력인지 나타냅니다. 취소해도 출결·수납 자료와 수강 건은 보존됩니다.false
enrollments.items[].transferCancelledAtstring필수전반 취소 시각(UTC)입니다. 취소 전에는 null입니다."2026-01-15T00:00:00Z"
enrollments.items[].classEndDateinteger필수반 자체의 종강일입니다. 학생별 endDate와 별개인 yyyyMMdd 정수이며 0은 미설정입니다.20260115
enrollments.items[].effectiveEndDateinteger필수조회 시 적용할 종료일입니다. 학생별 종료일이 없으면 반 종강일을 사용하며 종료 사유는 추정하지 않습니다.20260115
enrollments.items[].isEndedboolean필수한국 날짜를 기준으로 종료 효력이 발생했는지 나타냅니다. 일반 미래 종료는 false지만 전반 취소 이력은 시작일과 관계없이 항상 true입니다.false
enrollments.items[].statusstring필수수강 시작 전, 수강중, 퇴원, 전반, 종강, 전반 취소, 종료(구분 미확인) 또는 종료 예정 상태입니다. 미래 시작은 현재 수강중이 아니며, 예정 종료 사유는 함께 표시합니다."예시"
enrollments.items[].statusCodestring필수상태 표시 코드입니다. upcoming(미래 시작), active, retired, transferred, ended, cancelled, unknown 중 하나입니다. 전반 취소는 시작일과 관계없이 cancelled입니다."예시"
enrollments.pageinteger조건부·선택페이지 번호입니다.1
enrollments.pageSizeinteger조건부·선택페이지당 자료 수입니다.1
enrollments.totalinteger조건부·선택같은 조건의 전체 이력 수입니다.1
recentNotesobject필수최근 상담 5건입니다. 전체 상담 수와 페이지 정보도 반환합니다.하위 필드·본문 예시 참조
recentNotes.studentIdstring조건부·선택현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다."00000001"
recentNotes.studentNamestring조건부·선택학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
recentNotes.itemsarray조건부·선택현재 페이지의 세부 이력입니다.하위 필드·본문 예시 참조
recentNotes.items[].idinteger필수현재 학생의 상담 기록 번호입니다.1
recentNotes.items[].studentIdstring필수이 상담 기록이 속한 실제 학생 번호입니다."00000001"
recentNotes.items[].studentNamestring필수학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
recentNotes.items[].versionstring필수다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요."예시"
recentNotes.items[].contentstring필수저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다."예시"
recentNotes.items[].staffIdstring필수상담 담당 로그인 아이디입니다."1"
recentNotes.items[].staffNamestring필수상담 담당자 이름입니다."예시 이름"
recentNotes.items[].typestring필수상담 유형입니다."예시"
recentNotes.items[].reservedAtstring필수예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다."예시"
recentNotes.items[].statusstring필수저장된 예약 진행 상태입니다."예시"
recentNotes.items[].recordedAtstring필수실제 기록 시각입니다."2026-01-15T00:00:00Z"
recentNotes.items[].homeworkStudentIdinteger필수연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다.1
recentNotes.items[].lessonIdinteger필수명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다.1
recentNotes.items[].lessonTitlestring필수해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다."예시"
recentNotes.items[].lessonDatestring필수연결된 수업의 실제 수업일입니다."2026-01-15"
recentNotes.pageinteger조건부·선택페이지 번호입니다.1
recentNotes.pageSizeinteger조건부·선택페이지당 자료 수입니다.1
recentNotes.totalinteger조건부·선택같은 조건의 전체 이력 수입니다.1
recentScoresobject필수최근 시험성적 5건입니다. 조회만으로 공개 성적표 링크를 발급하지 않습니다.하위 필드·본문 예시 참조
recentScores.studentIdstring조건부·선택현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다."00000001"
recentScores.studentNamestring조건부·선택학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
recentScores.itemsarray조건부·선택현재 페이지의 세부 이력입니다.하위 필드·본문 예시 참조
recentScores.items[].gradeIdinteger필수해당 학생의 실제 채점 기록 번호입니다.1
recentScores.items[].examIdinteger필수시험 번호입니다.1
recentScores.items[].namestring필수시험 구분 이름입니다."예시 이름"
recentScores.items[].titlestring필수시험 제목입니다."예시"
recentScores.items[].datestring필수저장된 채점일입니다."2026-01-15"
recentScores.items[].scorenumber필수학생 점수입니다.1
recentScores.items[].averagenumber필수시험 평균 점수입니다.1
recentScores.items[].maximumnumber필수정답지 배점 합계인 시험 만점입니다. 실제 응시자의 최고 득점이 아닙니다.1
recentScores.items[].wrongAnswersstring필수이 조회에서 오답 문항을 제공하지 않으면 null입니다. null은 오답 0개가 아니며 등수나 응시 인원을 오답·응시 문항 수로 해석하지 마세요. 문항별 답안·배점·득점은 채점 성적 조회의 includeAnalysis=true로 확인합니다."예시"
recentScores.items[].rankstring필수학원에 저장된 등수 / 응시 인원 표시입니다. 예: 2/2. 문항 수나 오답 개수가 아닙니다."예시"
recentScores.items[].questionCountinteger필수정답지에 설정된 전체 문항 수입니다. 선택과목에 따라 학생의 실제 응시 문항 수와 다를 수 있으며 알 수 없으면 null입니다.1
recentScores.items[].differenceFromAveragenumber필수해당 시험 점수에서 평균을 뺀 값. 음수이면 평균 미만. 서로 다른 시험 점수의 평균이 아님.1
recentScores.items[].belowAverageboolean필수해당 시험에서 저장된 평균 미만인지 여부. true이면 평균 이상으로 표현하지 않음. 등수·분위와는 별개.false
recentScores.pageinteger조건부·선택페이지 번호입니다.1
recentScores.pageSizeinteger조건부·선택페이지당 자료 수입니다.1
recentScores.totalinteger조건부·선택같은 조건의 전체 이력 수입니다.1
recentClinicsobject필수최근 클리닉 이력 5건입니다.하위 필드·본문 예시 참조
recentClinics.studentIdstring조건부·선택현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다."00000001"
recentClinics.studentNamestring조건부·선택학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
recentClinics.itemsarray조건부·선택현재 페이지의 세부 이력입니다.하위 필드·본문 예시 참조
recentClinics.items[].appointmentIdinteger필수클리닉 예약 번호입니다.1
recentClinics.items[].reviewIdinteger필수클리닉 리뷰 번호입니다.1
recentClinics.items[].reservedAtstring필수저장된 예약 일시입니다."예시"
recentClinics.items[].statusstring필수예약 진행 상태입니다."예시"
recentClinics.items[].memostring필수예약 메모입니다."예시"
recentClinics.items[].reviewstring필수등록된 리뷰 원문입니다."예시"
recentClinics.items[].staffstring필수기록 담당자입니다."예시"
recentClinics.pageinteger조건부·선택페이지 번호입니다.1
recentClinics.pageSizeinteger조건부·선택페이지당 자료 수입니다.1
recentClinics.totalinteger조건부·선택같은 조건의 전체 이력 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}/detail/attendance지정 학생 1명의 수업일별 출결·보강 이력(0=무결·4=유결은 결석, 5=출석·6=인강·7=보강완료·8=보강생과 구별)

students.read · student.detail.attendance

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
fromquery선택조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery선택조회 종료일입니다. yyyy-MM-dd 형식입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring조건부·선택현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다."00000001"
studentNamestring조건부·선택학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
itemsarray조건부·선택현재 페이지의 세부 이력입니다.하위 필드·본문 예시 참조
items[].lessonIdinteger필수수업 번호입니다.1
items[].attendanceIdinteger필수학생 출결 기록 번호입니다.1
items[].teamIdinteger필수실제 수강반 번호입니다.1
items[].teamNamestring필수수강반 이름입니다."예시 이름"
items[].datestring필수저장된 수업일입니다."2026-01-15"
items[].sessioninteger필수수업 회차입니다.1
items[].attendanceCodeinteger필수출결 코드: 0=무결(무단결석), 4=유결(사유결석), 5=출석, 6=인강, 7=보강완료, 8=보강생. 결석은 0·4이며 인강·보강과 구별.1
items[].attendancestring필수출결 표시 이름입니다."예시"
items[].commentstring필수수업·과제의 학생 개별 학습 피드백 원문. 결석 사유 전용 필드가 아니며 시험 응원·풀이 조언을 결석 이유로 해석하지 않음. 원인이 명시되지 않으면 사유 미확인."예시"
items[].makeupTeamIdinteger필수연결된 보강 수강반 번호입니다. 0은 없음입니다.1
items[].makeupTeamNamestring필수연결된 보강 수강반 이름입니다."예시 이름"
items[].valueItemsarray필수같은 수업의 실제 과제·시험 항목 제목·내용·결과 안내와 학생 결과. 값 없음은 미완료 증거가 아님.하위 필드·본문 예시 참조
items[].valueItems[].fieldstring필수저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요."예시"
items[].valueItems[].categorystring필수과제, 도전, 시험 중 항목 종류입니다."예시"
items[].valueItems[].positioninteger필수같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다.1
items[].valueItems[].titlestring필수같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요."예시"
items[].valueItems[].contentstring필수같은 수업 설정의 과제·시험 내용 원문입니다."예시"
items[].valueItems[].resultGuidestring필수같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요."예시"
items[].valueItems[].valuestring필수해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다."예시"
items[].valueItems[].valueStatestring필수present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다."예시"
items[].valueItems[].examIdinteger필수같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다.1
items[].valueItemsAvailableboolean필수과제 항목의 원본을 조회했는지 여부. false이면 과제 미완료 여부를 판단할 수 없음.false
items[].attendanceMeaningstring필수출결 코드의 명확한 뜻. 무결은 무단결석이며 정상 참여가 아님."예시"
items[].isAbsenceboolean필수명확한 결석 여부. 코드 0·4는 true, 5·6·7·8은 false, 그 밖에는 null.false
pageinteger조건부·선택페이지 번호입니다.1
pageSizeinteger조건부·선택페이지당 자료 수입니다.1
totalinteger조건부·선택같은 조건의 전체 이력 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}/detail/clinics학생의 클리닉 예약·완료·취소·불참과 리뷰·메모 이력 조회

students.read · student.detail.clinics

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring조건부·선택현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다."00000001"
studentNamestring조건부·선택학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
itemsarray조건부·선택현재 페이지의 세부 이력입니다.하위 필드·본문 예시 참조
items[].appointmentIdinteger필수클리닉 예약 번호입니다.1
items[].reviewIdinteger필수클리닉 리뷰 번호입니다.1
items[].reservedAtstring필수저장된 예약 일시입니다."예시"
items[].statusstring필수예약 진행 상태입니다."예시"
items[].memostring필수예약 메모입니다."예시"
items[].reviewstring필수등록된 리뷰 원문입니다."예시"
items[].staffstring필수기록 담당자입니다."예시"
pageinteger조건부·선택페이지 번호입니다.1
pageSizeinteger조건부·선택페이지당 자료 수입니다.1
totalinteger조건부·선택같은 조건의 전체 이력 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}/detail/discounts학생 통합정보의 할인율·형제 할인 연결 학생 이름과 번호 조회

students.read · student.detail.discounts

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring조건부·선택현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다."00000001"
studentNamestring조건부·선택학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
itemsarray조건부·선택현재 페이지의 세부 이력입니다.하위 필드·본문 예시 참조
items[].idinteger필수할인 기록 번호입니다.1
items[].codestring필수할인 코드입니다."예시"
items[].rateinteger필수현재 할인율입니다.1
items[].relatedStudentIdstring필수형제 할인에 연결된 학생 번호입니다."00000001"
items[].relatedStudentNamestring필수연결된 학생 이름입니다."예시 이름"
pageinteger조건부·선택페이지 번호입니다.1
pageSizeinteger조건부·선택페이지당 자료 수입니다.1
totalinteger조건부·선택같은 조건의 전체 이력 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}/detail/enrollments학생 통합정보의 수강·퇴원·전반·종강·전반취소 이력과 이전 수강반 조회

students.read · student.detail.enrollments

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring조건부·선택현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다."00000001"
studentNamestring조건부·선택학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
itemsarray조건부·선택현재 페이지의 세부 이력입니다.하위 필드·본문 예시 참조
items[].idinteger필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.1
items[].studentIdstring필수학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다."00000001"
items[].teamIdinteger필수수강반 고유 번호입니다. 수강반 조회에서 확인합니다.1
items[].scheduleIdinteger필수수강반 시간표 고유 번호입니다. 해당 반의 시간표여야 합니다.1
items[].teamNamestring필수수강반 이름입니다."예시 이름"
items[].scheduleNamestring필수시간표 표시 이름입니다."예시 이름"
items[].beginDateinteger필수시작일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.20260115
items[].endDateinteger필수종료일입니다. 입력은 yyyy-MM-dd, 정수 응답은 yyyyMMdd이며 0은 미설정입니다.20260115
items[].endTypestring필수저장된 수강 종료 사유입니다. 빈 문자열, 퇴원, 전반, 종강, 전반취소를 사용합니다. 최대 20자이며 기존의 미확인 사유도 보존합니다. 이미 시작한 수강의 미래 종료는 active, 미래 시작은 upcoming이며 전반취소는 시작일과 관계없이 항상 cancelled입니다."예시"
items[].changeDateinteger필수전반으로 종료되는 기존 수강 건의 전반일입니다. yyyyMMdd 정수이며 0은 미설정입니다.20260115
items[].scheduleDaystring필수해당 수강 시간표의 실제 요일입니다. 없으면 빈 문자열입니다."예시"
items[].scheduleFromstring필수해당 수강 시간표의 실제 시작 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다."예시"
items[].scheduleTostring필수해당 수강 시간표의 실제 종료 시각입니다. HHmm 형식이며 없으면 빈 문자열입니다."예시"
items[].transferFromIdinteger필수전반 전의 기존 수강 건 번호입니다. 연결 없는 과거 자료는 null입니다.1
items[].transferDateinteger필수새 반으로 전반한 지정일입니다. yyyyMMdd 정수, 0은 연결 없음입니다.20260115
items[].previousTeamNamestring필수전반 이전 반·시간표 표시명입니다."예시 이름"
items[].isTransferboolean필수명시적인 이전 수강 연결값이 있는 전반 등록인지 나타냅니다.false
items[].isTransferCancelledboolean필수전반 취소 이력인지 나타냅니다. 취소해도 출결·수납 자료와 수강 건은 보존됩니다.false
items[].transferCancelledAtstring필수전반 취소 시각(UTC)입니다. 취소 전에는 null입니다."2026-01-15T00:00:00Z"
items[].classEndDateinteger필수반 자체의 종강일입니다. 학생별 endDate와 별개인 yyyyMMdd 정수이며 0은 미설정입니다.20260115
items[].effectiveEndDateinteger필수조회 시 적용할 종료일입니다. 학생별 종료일이 없으면 반 종강일을 사용하며 종료 사유는 추정하지 않습니다.20260115
items[].isEndedboolean필수한국 날짜를 기준으로 종료 효력이 발생했는지 나타냅니다. 일반 미래 종료는 false지만 전반 취소 이력은 시작일과 관계없이 항상 true입니다.false
items[].statusstring필수수강 시작 전, 수강중, 퇴원, 전반, 종강, 전반 취소, 종료(구분 미확인) 또는 종료 예정 상태입니다. 미래 시작은 현재 수강중이 아니며, 예정 종료 사유는 함께 표시합니다."예시"
items[].statusCodestring필수상태 표시 코드입니다. upcoming(미래 시작), active, retired, transferred, ended, cancelled, unknown 중 하나입니다. 전반 취소는 시작일과 관계없이 cancelled입니다."예시"
pageinteger조건부·선택페이지 번호입니다.1
pageSizeinteger조건부·선택페이지당 자료 수입니다.1
totalinteger조건부·선택같은 조건의 전체 이력 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}/detail/homework학생 과제·시험 검사결과와 수업 회차·출결·코멘트. valueItems가 같은 수업의 실제 항목 제목·안내·결과를 연결, 빈 값은 미완료로 추측하지 않음

students.read · student.detail.homework

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
fromquery선택조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery선택조회 종료일입니다. yyyy-MM-dd 형식입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring조건부·선택현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다."00000001"
studentNamestring조건부·선택학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
itemsarray조건부·선택현재 페이지의 세부 이력입니다.하위 필드·본문 예시 참조
items[].lessonIdinteger필수수업 번호입니다.1
items[].attendanceIdinteger필수학생 출결 기록 번호입니다.1
items[].teamIdinteger필수실제 수강반 번호입니다.1
items[].teamNamestring필수수강반 이름입니다."예시 이름"
items[].datestring필수저장된 수업일입니다."2026-01-15"
items[].sessioninteger필수수업 회차입니다.1
items[].attendanceCodeinteger필수출결 코드: 0=무결(무단결석), 4=유결(사유결석), 5=출석, 6=인강, 7=보강완료, 8=보강생. 결석은 0·4이며 인강·보강과 구별.1
items[].attendancestring필수출결 표시 이름입니다."예시"
items[].commentstring필수수업·과제의 학생 개별 학습 피드백 원문. 결석 사유 전용 필드가 아니며 시험 응원·풀이 조언을 결석 이유로 해석하지 않음. 원인이 명시되지 않으면 사유 미확인."예시"
items[].makeupTeamIdinteger필수연결된 보강 수강반 번호입니다. 0은 없음입니다.1
items[].makeupTeamNamestring필수연결된 보강 수강반 이름입니다."예시 이름"
items[].valueItemsarray필수같은 수업의 실제 과제·시험 항목 제목·내용·결과 안내와 학생 결과. 값 없음은 미완료 증거가 아님.하위 필드·본문 예시 참조
items[].valueItems[].fieldstring필수저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요."예시"
items[].valueItems[].categorystring필수과제, 도전, 시험 중 항목 종류입니다."예시"
items[].valueItems[].positioninteger필수같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다.1
items[].valueItems[].titlestring필수같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요."예시"
items[].valueItems[].contentstring필수같은 수업 설정의 과제·시험 내용 원문입니다."예시"
items[].valueItems[].resultGuidestring필수같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요."예시"
items[].valueItems[].valuestring필수해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다."예시"
items[].valueItems[].valueStatestring필수present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다."예시"
items[].valueItems[].examIdinteger필수같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다.1
items[].valueItemsAvailableboolean필수과제 항목의 원본을 조회했는지 여부. false이면 과제 미완료 여부를 판단할 수 없음.false
items[].attendanceMeaningstring필수출결 코드의 명확한 뜻. 무결은 무단결석이며 정상 참여가 아님."예시"
items[].isAbsenceboolean필수명확한 결석 여부. 코드 0·4는 true, 5·6·7·8은 false, 그 밖에는 null.false
pageinteger조건부·선택페이지 번호입니다.1
pageSizeinteger조건부·선택페이지당 자료 수입니다.1
totalinteger조건부·선택같은 조건의 전체 이력 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}/detail/life학생별 생활기록 이력과 실제 사용 설정된 항목 이름·값·도표 설정 조회

students.read · student.detail.life

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring조건부·선택현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다."00000001"
studentNamestring조건부·선택학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
itemsarray조건부·선택현재 페이지의 세부 이력입니다.하위 필드·본문 예시 참조
items[].idinteger필수생활기록 번호입니다.1
items[].yearinteger필수생활기록 연도입니다.1
items[].namestring필수생활기록 분류명입니다."예시 이름"
items[].fieldsarray필수실제 사용 설정된 항목명과 값입니다.하위 필드·본문 예시 참조
items[].fields[].fieldstring필수실제 설정된 생활기록 필드입니다."예시"
items[].fields[].titlestring필수화면에 표시하는 항목명입니다."예시"
items[].fields[].valuestring필수해당 학생의 저장 값입니다."예시"
items[].fields[].numericboolean필수숫자 입력 항목인지 여부입니다.false
items[].fields[].chartboolean필수도표에 사용하는 항목인지 여부입니다.false
pageinteger조건부·선택페이지 번호입니다.1
pageSizeinteger조건부·선택페이지당 자료 수입니다.1
totalinteger조건부·선택같은 조건의 전체 이력 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}/detail/logins학생별 로그인 시각·접속 주소·구분 이력 조회웹 관리 기능

웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요
students.read · student.detail.logins

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
fromquery필수조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery필수조회 종료일입니다. yyyy-MM-dd 형식입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring조건부·선택현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다."00000001"
studentNamestring조건부·선택학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
itemsarray조건부·선택현재 페이지의 세부 이력입니다.하위 필드·본문 예시 참조
items[].loggedAtstring필수저장된 로그인 시각입니다."예시"
items[].namestring필수로그인 이름입니다."예시 이름"
items[].ipstring필수로그인 접속 주소입니다."예시"
items[].typeinteger필수로그인 구분입니다.1
items[].memostring필수기록된 로그인 메모입니다."예시"
pageinteger조건부·선택페이지 번호입니다.1
pageSizeinteger조건부·선택페이지당 자료 수입니다.1
totalinteger조건부·선택같은 조건의 전체 이력 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}/detail/messages학생별 문자·알림톡 발송 내용·수신번호·요청번호 이력 조회(발송 실행 없음)웹 관리 기능

웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요
students.read · student.detail.messages

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
fromquery필수조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery필수조회 종료일입니다. yyyy-MM-dd 형식입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring조건부·선택현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다."00000001"
studentNamestring조건부·선택학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
itemsarray조건부·선택현재 페이지의 세부 이력입니다.하위 필드·본문 예시 참조
items[].sentAtstring필수실제 발송 기록 시각입니다."예시"
items[].typestring필수문자·알림톡 유형입니다."예시"
items[].receiverstring필수실제 수신번호입니다."예시"
items[].senderstring필수발송한 직원의 이름입니다. 발신 전화번호가 아닙니다."예시"
items[].callingstring필수저장된 발신번호와 발송 구분 표시입니다."예시"
items[].contentstring필수저장된 발송 내용입니다."예시"
items[].providerRequestIdstring필수문자 업체의 요청 번호입니다."1"
pageinteger조건부·선택페이지 번호입니다.1
pageSizeinteger조건부·선택페이지당 자료 수입니다.1
totalinteger조건부·선택같은 조건의 전체 이력 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/detail/note-options학생 통합정보 상담 편집에서 실제 선택 가능한 담당자·예약 유형 목록

students.read · student.detail.notes.options

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
staffarray조건부·선택실제 선택 가능한 담당자 아이디와 이름입니다.하위 필드·본문 예시 참조
staff[].idstring필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다."1"
staff[].namestring필수이름 또는 표시 명칭입니다."예시 이름"
typesarray조건부·선택실제 선택 가능한 상담 유형입니다.하위 필드·본문 예시 참조
types[].idstring필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다."1"
types[].namestring필수이름 또는 표시 명칭입니다."예시 이름"
currentStaffIdstring조건부·선택현재 인증된 담당자 아이디입니다."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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}/detail/notes학생의 원문 상담 내역·예약 유형·담당자·진행 상태 조회

students.read · student.detail.notes.list

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring조건부·선택현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다."00000001"
studentNamestring조건부·선택학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
itemsarray조건부·선택현재 페이지의 세부 이력입니다.하위 필드·본문 예시 참조
items[].idinteger필수현재 학생의 상담 기록 번호입니다.1
items[].studentIdstring필수이 상담 기록이 속한 실제 학생 번호입니다."00000001"
items[].studentNamestring필수학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
items[].versionstring필수다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요."예시"
items[].contentstring필수저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다."예시"
items[].staffIdstring필수상담 담당 로그인 아이디입니다."1"
items[].staffNamestring필수상담 담당자 이름입니다."예시 이름"
items[].typestring필수상담 유형입니다."예시"
items[].reservedAtstring필수예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다."예시"
items[].statusstring필수저장된 예약 진행 상태입니다."예시"
items[].recordedAtstring필수실제 기록 시각입니다."2026-01-15T00:00:00Z"
items[].homeworkStudentIdinteger필수연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다.1
items[].lessonIdinteger필수명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다.1
items[].lessonTitlestring필수해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다."예시"
items[].lessonDatestring필수연결된 수업의 실제 수업일입니다."2026-01-15"
pageinteger조건부·선택페이지 번호입니다.1
pageSizeinteger조건부·선택페이지당 자료 수입니다.1
totalinteger조건부·선택같은 조건의 전체 이력 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}/detail/notes/{noteId}선택 학생의 특정 상담 원문·담당자·예약 일시·변경 검증 version 조회

students.read · student.detail.notes.get

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
noteIdpath필수해당 학생의 상담 내역·상세 조회에서 확인한 실제 상담 기록 번호입니다. 다른 학생의 기록 번호를 재사용하지 마세요.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수현재 학생의 상담 기록 번호입니다.1
studentIdstring필수이 상담 기록이 속한 실제 학생 번호입니다."00000001"
studentNamestring필수학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
versionstring필수다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요."예시"
contentstring필수저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다."예시"
staffIdstring필수상담 담당 로그인 아이디입니다."1"
staffNamestring필수상담 담당자 이름입니다."예시 이름"
typestring필수상담 유형입니다."예시"
reservedAtstring필수예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다."예시"
statusstring필수저장된 예약 진행 상태입니다."예시"
recordedAtstring필수실제 기록 시각입니다."2026-01-15T00:00:00Z"
homeworkStudentIdinteger필수연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다.1
lessonIdinteger필수명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다.1
lessonTitlestring필수해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다."예시"
lessonDatestring필수연결된 수업의 실제 수업일입니다."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"
  }
}
Explorer에서 요청 구성 →
POST/v1/students/{id}/detail/notes학생 통합정보에서 상담 기록 등록(선택한 담당자·유형·명시한 예약일만 사용)

students.write · student.detail.notes.create

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
contentstring필수상담 원문입니다. 예약 문구나 화면 표시용 접두사를 임의로 덧붙이지 마세요."예시"
versionstring조건부·선택수정할 때 상세 조회에서 받은 현재 version입니다. 신규 등록에는 필요하지 않습니다."예시"
staffIdstring조건부·선택담당자 목록의 실제 로그인 아이디입니다. 수정 시 생략하면 기존 담당자를 유지합니다."1"
typestring조건부·선택상담 유형 목록의 실제 값입니다. 수정 시 생략하면 기존 유형을 유지합니다."예시"
reservedAtstring조건부·선택사용자가 지정한 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수현재 학생의 상담 기록 번호입니다.1
studentIdstring필수이 상담 기록이 속한 실제 학생 번호입니다."00000001"
studentNamestring필수학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
versionstring필수다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요."예시"
contentstring필수저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다."예시"
staffIdstring필수상담 담당 로그인 아이디입니다."1"
staffNamestring필수상담 담당자 이름입니다."예시 이름"
typestring필수상담 유형입니다."예시"
reservedAtstring필수예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다."예시"
statusstring필수저장된 예약 진행 상태입니다."예시"
recordedAtstring필수실제 기록 시각입니다."2026-01-15T00:00:00Z"
homeworkStudentIdinteger필수연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다.1
lessonIdinteger필수명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다.1
lessonTitlestring필수해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다."예시"
lessonDatestring필수연결된 수업의 실제 수업일입니다."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"
  }
}
Explorer에서 요청 구성 →
PATCH/v1/students/{id}/detail/notes/{noteId}상담 원문·담당자·유형·예약 수정(생략한 값 보존·학원/학생/현재 version 원자적 검증)

students.write · student.detail.notes.update

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
noteIdpath필수해당 학생의 상담 내역·상세 조회에서 확인한 실제 상담 기록 번호입니다. 다른 학생의 기록 번호를 재사용하지 마세요.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
contentstring필수상담 원문입니다. 예약 문구나 화면 표시용 접두사를 임의로 덧붙이지 마세요."예시"
versionstring조건부·선택수정할 때 상세 조회에서 받은 현재 version입니다. 신규 등록에는 필요하지 않습니다."예시"
staffIdstring조건부·선택담당자 목록의 실제 로그인 아이디입니다. 수정 시 생략하면 기존 담당자를 유지합니다."1"
typestring조건부·선택상담 유형 목록의 실제 값입니다. 수정 시 생략하면 기존 유형을 유지합니다."예시"
reservedAtstring조건부·선택사용자가 지정한 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수현재 학생의 상담 기록 번호입니다.1
studentIdstring필수이 상담 기록이 속한 실제 학생 번호입니다."00000001"
studentNamestring필수학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
versionstring필수다음 수정·삭제에 사용할 현재 기록의 SHA-256 버전입니다. 추측하지 마세요."예시"
contentstring필수저장된 원문 상담 내용입니다. 예약·수업 제목을 합성하지 않습니다."예시"
staffIdstring필수상담 담당 로그인 아이디입니다."1"
staffNamestring필수상담 담당자 이름입니다."예시 이름"
typestring필수상담 유형입니다."예시"
reservedAtstring필수예약 일시입니다. yyyy-MM-dd HH:mm 한국 시간, 빈 값은 예약 없음입니다."예시"
statusstring필수저장된 예약 진행 상태입니다."예시"
recordedAtstring필수실제 기록 시각입니다."2026-01-15T00:00:00Z"
homeworkStudentIdinteger필수연결된 학생 과제장 기록 번호입니다. 0은 일반 상담입니다.1
lessonIdinteger필수명시적으로 연결된 수업 번호입니다. 확인된 연결이 없으면 0입니다.1
lessonTitlestring필수해당 상담이 연결된 실제 수업 제목입니다. 임의로 합성하지 않습니다."예시"
lessonDatestring필수연결된 수업의 실제 수업일입니다."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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/students/{id}/detail/notes/{noteId}선택 학생의 상담 기록 삭제(현재 version 확인·소프트 삭제)

students.write · student.detail.notes.delete

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
noteIdpath필수해당 학생의 상담 내역·상세 조회에서 확인한 실제 상담 기록 번호입니다. 다른 학생의 기록 번호를 재사용하지 마세요.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
versionstring필수직전 상세 조회에서 받은 정확한 version입니다."예시"
요청 JSON 스키마
{
  "type": "object",
  "properties": {
    "version": {
      "type": "string",
      "description": "직전 상세 조회에서 받은 정확한 version입니다.",
      "nullable": false,
      "minLength": 1,
      "pattern": "^[A-F0-9]{64}$"
    }
  },
  "required": [
    "version"
  ]
}

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}/detail/profile학생 통합정보 기본정보 조회(이름·번호·연락처·학교·학년·메모, 비밀번호 제외)

students.read · student.detail.profile

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idstring필수조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다."1"
namestring필수이름 또는 표시 명칭입니다."예시 이름"
schoolstring필수학교 이름입니다. 빈 문자열이면 미입력입니다."예시"
gradestring필수학년 표시값입니다."예시"
majorstring필수계열 또는 전공 구분값입니다."예시"
studentPhonestring필수학생 휴대전화 번호입니다."010-0000-0000"
parentPhonestring필수보호자 연락처입니다."010-0000-0000"
paymentPhonestring필수결제 안내를 받을 연락처입니다."010-0000-0000"
emailstring필수이메일 주소입니다."sample@example.com"
memostring필수학생 관리용 메모입니다."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/{id}/detail/scores학생 시험별 점수·평균·만점·등수 이력(오답 미제공, 공개 성적표 링크 발급 없음)

students.read · student.detail.scores

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지하세요.
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
fromquery선택조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery선택조회 종료일입니다. yyyy-MM-dd 형식입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring조건부·선택현재 학원의 실제 학생 번호입니다. 앞자리 0을 유지합니다."00000001"
studentNamestring조건부·선택학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
itemsarray조건부·선택현재 페이지의 세부 이력입니다.하위 필드·본문 예시 참조
items[].gradeIdinteger필수해당 학생의 실제 채점 기록 번호입니다.1
items[].examIdinteger필수시험 번호입니다.1
items[].namestring필수시험 구분 이름입니다."예시 이름"
items[].titlestring필수시험 제목입니다."예시"
items[].datestring필수저장된 채점일입니다."2026-01-15"
items[].scorenumber필수학생 점수입니다.1
items[].averagenumber필수시험 평균 점수입니다.1
items[].maximumnumber필수정답지 배점 합계인 시험 만점입니다. 실제 응시자의 최고 득점이 아닙니다.1
items[].wrongAnswersstring필수이 조회에서 오답 문항을 제공하지 않으면 null입니다. null은 오답 0개가 아니며 등수나 응시 인원을 오답·응시 문항 수로 해석하지 마세요. 문항별 답안·배점·득점은 채점 성적 조회의 includeAnalysis=true로 확인합니다."예시"
items[].rankstring필수학원에 저장된 등수 / 응시 인원 표시입니다. 예: 2/2. 문항 수나 오답 개수가 아닙니다."예시"
items[].questionCountinteger필수정답지에 설정된 전체 문항 수입니다. 선택과목에 따라 학생의 실제 응시 문항 수와 다를 수 있으며 알 수 없으면 null입니다.1
items[].differenceFromAveragenumber필수해당 시험 점수에서 평균을 뺀 값. 음수이면 평균 미만. 서로 다른 시험 점수의 평균이 아님.1
items[].belowAverageboolean필수해당 시험에서 저장된 평균 미만인지 여부. true이면 평균 이상으로 표현하지 않음. 등수·분위와는 별개.false
pageinteger조건부·선택페이지 번호입니다.1
pageSizeinteger조건부·선택페이지당 자료 수입니다.1
totalinteger조건부·선택같은 조건의 전체 이력 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/life-records수강 시간표별 학생 생활기록

life.read · life.list

경로 · 검색 파라미터

이름위치필수설명
yearquery필수생활기록 연도입니다. 1900~2100입니다.
categoryquery필수생활기록 분류명입니다. 기존 분류를 선택하거나 새 이름을 입력하며, 새 분류는 첫 기록 저장 시 생성됩니다.
scheduleIdquery필수GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idinteger필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.1
[].studentIdstring필수학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다."00000001"
[].studentNamestring필수학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다."예시 이름"
[].yearinteger필수생활기록 연도입니다. 1900~2100 범위입니다.1
[].categorystring필수생활기록 분류명입니다. 분류 목록의 값을 사용합니다."예시"
[].valuesobject필수생활기록 항목 키(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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/life-records학생 생활기록 저장(항목 값 병합)

life.write · life.save

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
yearinteger필수생활기록 연도입니다. 1900~2100 범위입니다.2026
categorystring필수생활기록 분류명입니다. GET /v1/life-records/categories의 기존 이름을 사용하거나 새 분류명을 직접 입력할 수 있습니다. 분류는 첫 기록 저장 시 생성됩니다."예시"
studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 예: 00000001. 이름·전화번호가 아니며 앞자리 0을 유지하세요."00000001"
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.1
expectedIdinteger조건부·선택같은 year·category·scheduleId로 GET /v1/life-records를 먼저 조회하고 대상 학생 행의 id를 전달합니다. 조회 응답 id가 0인 새 기록만 0을 사용합니다.1
valuesobject조건부·선택생활기록 항목 키(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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.1
studentIdstring필수학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다."00000001"
studentNamestring필수학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다."예시 이름"
yearinteger필수생활기록 연도입니다. 1900~2100 범위입니다.1
categorystring필수생활기록 분류명입니다. 분류 목록의 값을 사용합니다."예시"
valuesobject필수생활기록 항목 키(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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/life-records/{id}학생 생활기록 삭제

life.write · life.delete

경로 · 검색 파라미터

이름위치필수설명
idpath필수대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다.
yearquery필수생활기록 연도입니다. 1900~2100입니다.
categoryquery필수생활기록 분류명입니다. 기존 분류를 선택하거나 새 이름을 입력하며, 새 분류는 첫 기록 저장 시 생성됩니다.
scheduleIdquery필수GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/life-records/categories생활기록 분류 목록

life.read · life.categories

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
응답 data JSON 스키마
{
  "type": "array",
  "items": {
    "type": "string"
  }
}

성공 응답 예시

{
  "data": [
    "예시"
  ],
  "meta": {
    "requestId": "example-request-id"
  }
}
Explorer에서 요청 구성 →
GET/v1/life-records/fields생활기록 항목 정의

life.read · life.fields

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].fieldstring조건부·선택생활기록 항목 키입니다. V1~V20 중 하나입니다."예시"
[].titlestring조건부·선택화면에 표시할 항목 이름입니다. 최대 10자이며 사용하지 않는 항목은 비울 수 있습니다."예시"
[].widthinteger조건부·선택목록 열 너비입니다. 40~600 픽셀입니다.1
[].typeboolean조건부·선택숫자 입력 항목이면 true입니다.false
[].chartboolean조건부·선택도표에 표시하는 숫자 항목이면 true입니다. 사용 중인 숫자 항목만 가능하며 최대 6개입니다.false
[].use_Flagboolean조건부·선택이 생활기록 항목을 사용하면 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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/life-records/fields생활기록 항목 설정

life.write · life.fields.update

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].fieldstring조건부·선택생활기록 항목 키입니다. V1~V20 중 하나입니다."예시"
[].titlestring조건부·선택화면에 표시할 항목 이름입니다. 최대 10자이며 사용하지 않는 항목은 비울 수 있습니다."예시"
[].widthinteger조건부·선택목록 열 너비입니다. 40~600 픽셀입니다.1
[].typeboolean조건부·선택숫자 입력 항목이면 true입니다.false
[].chartboolean조건부·선택도표에 표시하는 숫자 항목이면 true입니다. 사용 중인 숫자 항목만 가능하며 최대 6개입니다.false
[].use_Flagboolean조건부·선택이 생활기록 항목을 사용하면 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/consultations기간별 상담 예약

consultations.read · consultations.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
fromquery필수조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery필수조회 종료일입니다. yyyy-MM-dd 형식입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].idinteger필수조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다.1
items[].studentIdstring필수학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다."00000001"
items[].studentNamestring필수학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다."예시 이름"
items[].phonestring필수상담 대상 연락처입니다."010-0000-0000"
items[].reservedAtstring필수상담 예약 일시입니다. 한국 시간 yyyy-MM-dd HH:mm 형식입니다."예시"
items[].typestring필수상담 유형 또는 분류입니다."예시"
items[].statusstring필수상담 상태입니다. 예약·완료·변경·불참·취소 중 하나입니다."예약"
items[].contentstring필수상담 내용입니다."예시"
items[].staffIdstring필수상담 담당자 선택 목록의 식별값입니다."1"
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/consultations/{id}상담 예약 상세

consultations.read · consultations.get

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/consultations 응답 data.items[].id의 상담 예약 번호입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수조회·변경할 자원의 고유 번호입니다. 학생 번호는 문자열이며 그 외 번호는 정수입니다.1
studentIdstring필수학원 내 학생 고유 번호입니다. 학생 조회에서 받은 문자열을 그대로 사용합니다."00000001"
studentNamestring필수학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다."예시 이름"
phonestring필수상담 대상 연락처입니다."010-0000-0000"
reservedAtstring필수상담 예약 일시입니다. 한국 시간 yyyy-MM-dd HH:mm 형식입니다."예시"
typestring필수상담 유형 또는 분류입니다."예시"
statusstring필수상담 상태입니다. 예약·완료·변경·불참·취소 중 하나입니다."예약"
contentstring필수상담 내용입니다."예시"
staffIdstring필수상담 담당자 선택 목록의 식별값입니다."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"
  }
}
Explorer에서 요청 구성 →
POST/v1/consultations상담 예약 등록

consultations.write · consultations.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring조건부·선택GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 예: 00000001. 이름·전화번호가 아니며 앞자리 0을 유지하세요."00000001"
studentNamestring필수학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다."예시 이름"
phonestring조건부·선택상담 대상 연락처입니다."010-0000-0000"
reservedAtstring필수상담 예약 일시입니다. 한국 시간 yyyy-MM-dd HH:mm 형식입니다."예시"
typestring조건부·선택상담 유형 또는 분류입니다."예시"
statusstring필수상담 상태입니다. 예약·완료·변경·불참·취소 중 하나입니다."예약"
contentstring조건부·선택상담 내용입니다."예시"
staffIdstring필수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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/consultations/{id}상담 예약 변경 · 완료 · 취소

consultations.write · consultations.update

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/consultations 응답 data.items[].id의 상담 예약 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring조건부·선택GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 예: 00000001. 이름·전화번호가 아니며 앞자리 0을 유지하세요."00000001"
studentNamestring필수학생 이름입니다. 상담의 학생 번호가 없으면 비등록 상담 대상 이름입니다."예시 이름"
phonestring조건부·선택상담 대상 연락처입니다."010-0000-0000"
reservedAtstring필수상담 예약 일시입니다. 한국 시간 yyyy-MM-dd HH:mm 형식입니다."예시"
typestring조건부·선택상담 유형 또는 분류입니다."예시"
statusstring필수상담 상태입니다. 예약·완료·변경·불참·취소 중 하나입니다."예약"
contentstring조건부·선택상담 내용입니다."예시"
staffIdstring필수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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/consultations/{id}상담 예약 삭제

consultations.write · consultations.delete

경로 · 검색 파라미터

이름위치필수설명
idpath필수GET /v1/consultations 응답 data.items[].id의 상담 예약 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/consultations/staff상담 담당자 선택 목록

consultations.read · consultations.staff

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idstring필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다."1"
[].namestring필수이름 또는 표시 명칭입니다."예시 이름"
응답 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/statistics/students통계 학생별 상세(학생 이름·번호 포함, month=0은 연간 월별 집합 합집합)

statistics.read · statistics.students

경로 · 검색 파라미터

이름위치필수설명
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.
closedOnlyquery선택종강한 수강반만 조회할지 여부입니다. 기본 false입니다.
teamKeysquery선택통계 수강반 목록의 실제 key 배열입니다. 생략하면 학원 기준, 지정하면 선택 수강반 기준입니다.
yearquery필수통계 조회 연도입니다. 1900~2100입니다.
monthquery필수집계 월 1~12입니다. 0은 월별 합집합으로 계산한 연간 고유 인원입니다.
kindquery필수new(신규), active(재원), withdrawn(퇴원) 중 하나입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].studentIdstring필수학생 번호 문자열입니다. 앞자리 0을 유지합니다."00000001"
[].studentNamestring필수학생 번호와 함께 표시할 실제 학생 이름입니다."예시 이름"
[].schoolNamestring필수학생 학교명입니다."예시 이름"
[].gradeNamestring필수학생 학년입니다."예시 이름"
[].enrollmentsarray필수해당 학생의 집계 대상 수강 이력입니다.하위 필드·본문 예시 참조
[].enrollments[].enrollmentIdinteger필수수강 이력 번호입니다.1
[].enrollments[].teamNamestring필수수강반과 시간표의 표시 이름입니다."예시 이름"
[].enrollments[].beginDateinteger필수수강 시작일입니다. yyyyMMdd 정수입니다.20260115
[].enrollments[].endDateinteger필수수강 종료일입니다. yyyyMMdd 정수이며 0은 미설정입니다.20260115
[].enrollments[].endTypestring필수저장된 종료 사유입니다. 퇴원·전반·종강을 구분합니다."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/statistics/summary월별·연간 신규·재원·퇴원 고유 인원(명시 선택한 수강반 기준 전환)

statistics.read · statistics.summary

경로 · 검색 파라미터

이름위치필수설명
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.
closedOnlyquery선택종강한 수강반만 조회할지 여부입니다. 기본 false입니다.
teamKeysquery선택통계 수강반 목록의 실제 key 배열입니다. 생략하면 학원 기준, 지정하면 선택 수강반 기준입니다.
yearquery필수통계 조회 연도입니다. 1900~2100입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
monthsarray조건부·선택월별 학생 수 집계입니다.하위 필드·본문 예시 참조
months[].monthNumberinteger조건부·선택집계 대상 월입니다.1
months[].monthEndinteger조건부·선택집계 월 말일입니다. yyyyMMdd 정수입니다.1
months[].newCountinteger조건부·선택중복 제거된 신규 학생 수입니다.1
months[].activeCountinteger조건부·선택계속 재원 학생 수입니다. 해당 월 신규와 최종 퇴원 예정자는 제외합니다.1
months[].withdrawnCountinteger조건부·선택퇴원 학생 수입니다. 전반·종강·전반취소는 제외합니다.1
months[].referenceDateinteger조건부·선택집계의 한국 날짜 기준일입니다. yyyyMMdd 정수입니다.20260115
months[].isFutureboolean조건부·선택아직 집계하지 않는 미래 월인지 여부입니다.false
totalsobject조건부·선택월별 집합을 합친 후 학생 번호로 중복을 제거한 연간 합계입니다.하위 필드·본문 예시 참조
totals.newCountinteger조건부·선택중복 제거된 신규 학생 수입니다.1
totals.activeCountinteger조건부·선택계속 재원 학생 수입니다. 해당 월 신규와 최종 퇴원 예정자는 제외합니다.1
totals.withdrawnCountinteger조건부·선택퇴원 학생 수입니다. 전반·종강·전반취소는 제외합니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/statistics/teams통계 조회 가능한 수강반·시간표 key 목록

statistics.read · statistics.teams

경로 · 검색 파라미터

이름위치필수설명
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.
closedOnlyquery선택종강한 수강반만 조회할지 여부입니다. 기본 false입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].teamCodeinteger조건부·선택반별 게시판의 대상 수강반 번호입니다.1
[].scheduleIdinteger조건부·선택해당 반의 시간표 번호입니다.1
[].teamNamestring조건부·선택수강반과 시간표의 표시 이름입니다."예시 이름"
[].isClosedboolean조건부·선택기준일에 종강한 수강반인지 여부입니다.false
[].beginDateinteger조건부·선택수강반의 개강일입니다. yyyyMMdd 정수이며 0은 미설정입니다.20260115
[].endDateinteger조건부·선택수강반의 종강일입니다. yyyyMMdd 정수이며 0은 미설정입니다.20260115
[].enrollmentCountinteger조건부·선택삭제되거나 전반 취소된 수강을 제외한 해당 반·시간표의 수강 기록 수입니다. 고유 학생 통계 인원과 구분합니다.1
[].keystring조건부·선택반번호:시간표번호 형식의 실제 통계 수강반 선택 키입니다."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/students/statistics/withdrawals기간별 퇴원 명단. basis=academy는 학원 최종 퇴원, enrollment는 반별 퇴원 이력(다른 반 계속 수강도 포함). 반별 명단은 enrollment 사용. 원본 학생·반명·퇴원일, 전반·종강·전반취소 제외

statistics.read · statistics.withdrawals

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
basisquery선택퇴원 조회 기준. academy=다른 반까지 모두 마친 학원 기준 최종 퇴원(기본). enrollment=반별 퇴원 이력이며 다른 반을 계속 듣는 학생도 포함. 수강반별 퇴원일·명단 요청은 enrollment. 전반·종강·전반취소는 두 기준 모두 제외.
fromquery필수조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery필수조회 종료일입니다. yyyy-MM-dd 형식입니다.
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].studentIdstring필수학생 번호입니다. 문자열의 앞자리 0을 보존합니다."00000001"
items[].studentNamestring필수저장된 원본 학생 이름입니다."예시 이름"
items[].enrollmentIdinteger필수퇴원한 수강 이력 번호입니다.1
items[].teamNamestring필수저장된 원본 반·시간표 표시 이름입니다."예시 이름"
items[].endDatestring필수실제 퇴원 효력일입니다. yyyy-MM-dd 형식입니다."2026-01-15"
items[].endTypestring필수저장된 종료 사유입니다. 선택한 basis의 퇴원만 포함하고 전반·종강·전반취소는 제외합니다."예시"
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →

채점관리

POST/v1/grading/sections과목·대분류 등록

grading.write · grading.sections.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
subjectstring필수과목 이름입니다. 같은 이름으로 대분류를 묶습니다."수학"
namestring필수대분류 또는 소분류 이름입니다."대수"
orderinteger조건부·선택표시 순서입니다. 작은 값부터 정렬합니다.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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/grading/sections/{sectionId}과목 내 대분류 수정

grading.write · grading.sections.update

경로 · 검색 파라미터

이름위치필수설명
sectionIdpath필수GET /v1/grading/subjects/{subject}/sections 응답 data[].id의 대분류 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
subjectstring필수과목 이름입니다. 같은 이름으로 대분류를 묶습니다."수학"
namestring필수대분류 또는 소분류 이름입니다."대수"
orderinteger조건부·선택표시 순서입니다. 작은 값부터 정렬합니다.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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/grading/sections/{sectionId}대분류 삭제(사용 중이면 거절)

grading.write · grading.sections.delete

경로 · 검색 파라미터

이름위치필수설명
sectionIdpath필수GET /v1/grading/subjects/{subject}/sections 응답 data[].id의 대분류 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/grading/sections/{sectionId}/patterns대분류의 소분류 목록

grading.read · grading.patterns.list

경로 · 검색 파라미터

이름위치필수설명
sectionIdpath필수GET /v1/grading/subjects/{subject}/sections 응답 data[].id의 대분류 번호입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idinteger필수분류 고유 번호입니다.1
[].sectionIdinteger필수소분류가 속한 대분류 번호입니다. 대분류 자체는 자신의 번호입니다.1
[].subjectstring필수과목 이름입니다."예시"
[].namestring필수분류 표시 이름입니다."예시 이름"
[].orderinteger필수표시 순서입니다.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"
  }
}
Explorer에서 요청 구성 →
POST/v1/grading/sections/{sectionId}/patterns소분류 등록

grading.write · grading.patterns.create

경로 · 검색 파라미터

이름위치필수설명
sectionIdpath필수GET /v1/grading/subjects/{subject}/sections 응답 data[].id의 대분류 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
subjectstring필수과목 이름입니다. 같은 이름으로 대분류를 묶습니다."수학"
namestring필수대분류 또는 소분류 이름입니다."대수"
orderinteger조건부·선택표시 순서입니다. 작은 값부터 정렬합니다.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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/grading/sections/{sectionId}/patterns/{patternId}소분류 수정

grading.write · grading.patterns.update

경로 · 검색 파라미터

이름위치필수설명
sectionIdpath필수GET /v1/grading/subjects/{subject}/sections 응답 data[].id의 대분류 번호입니다.
patternIdpath필수GET /v1/grading/sections/{sectionId}/patterns 응답 data[].id의 소분류 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
subjectstring필수과목 이름입니다. 같은 이름으로 대분류를 묶습니다."수학"
namestring필수대분류 또는 소분류 이름입니다."대수"
orderinteger조건부·선택표시 순서입니다. 작은 값부터 정렬합니다.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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/grading/sections/{sectionId}/patterns/{patternId}소분류 삭제(사용 중이면 거절)

grading.write · grading.patterns.delete

경로 · 검색 파라미터

이름위치필수설명
sectionIdpath필수GET /v1/grading/subjects/{subject}/sections 응답 data[].id의 대분류 번호입니다.
patternIdpath필수GET /v1/grading/sections/{sectionId}/patterns 응답 data[].id의 소분류 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/grading/subjects채점 과목 목록

grading.read · grading.subjects.list

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
응답 data JSON 스키마
{
  "type": "array",
  "items": {
    "type": "string"
  }
}

성공 응답 예시

{
  "data": [
    "예시"
  ],
  "meta": {
    "requestId": "example-request-id"
  }
}
Explorer에서 요청 구성 →
GET/v1/grading/subjects/{subject}/sections과목별 대분류 목록

grading.read · grading.sections.list

경로 · 검색 파라미터

이름위치필수설명
subjectpath필수과목 이름입니다. URL 경로로 전달할 때 퍼센트 인코딩합니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idinteger필수분류 고유 번호입니다.1
[].sectionIdinteger필수소분류가 속한 대분류 번호입니다. 대분류 자체는 자신의 번호입니다.1
[].subjectstring필수과목 이름입니다."예시"
[].namestring필수분류 표시 이름입니다."예시 이름"
[].orderinteger필수표시 순서입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/grading/omr-templates공식 OMR 양식별 총 칸 수·종류 목록·PDF/이미지 제공 정보. 개별 문항 번호·답안 종류·정답 입력 틀은 grading.answer-template.get에 있음. answerTypes는 필요한 종류 교집합 필터(0 객관식, 1 단답형 정답 비교, 2 서술형 획득점수). 미지정 필터는 생략. 양식 코드는 학원 시험 이름이 아님

grading.read · grading.omr-templates.list

경로 · 검색 파라미터

이름위치필수설명
answerTypesquery선택OMR 양식에 반드시 포함할 답안 종류. 쉼표로 지정하며 모든 조건을 동시에 만족해야 합니다. 0=객관식, 1=단답형 정답 비교, 2=서술형 획득점수. 객관식과 서술형을 함께 원하면 0,2. 생략하면 전체 양식이며 제목만으로 종류를 추측하지 않습니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].answerTypesarray필수공식 문항 구조의 답안 종류: 0 객관식, 1 단답형 정답 비교, 2 서술형 획득점수. null은 구조 미확인입니다. 문항 위치는 정답 입력 틀 조회로 확인하세요.하위 필드·본문 예시 참조
[].codestring필수OMR 양식 번호입니다. 정답지 등록과 채점에 사용합니다."예시"
[].titlestring필수OMR 양식 설명입니다."예시"
[].questionsinteger필수실제 문항 수입니다.1
[].layoutinteger필수OMR 용도 코드입니다. 7은 두 회차용입니다.1
[].pdfUrlstring필수빈 공식 OMR PDF 다운로드 API 상대 경로입니다. API 서버 주소와 결합하고 Authorization: Bearer 헤더로 요청하세요. 미제공 형식이면 null입니다. JSON이 아닌 PDF 원본을 반환합니다."예시"
[].imageUrlstring필수공식 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/grading/omr-templates/{code}/files/{format}공식 빈 OMR PDF·이미지 원본 다운로드

grading.read · grading.omr-templates.download

경로 · 검색 파라미터

이름위치필수설명
codepath필수GET /v1/grading/omr-templates 응답에서 선택한 양식의 code입니다. 예: 문자열 120. 시험 번호와 다릅니다.
formatpath필수공식 양식 원본 형식입니다. 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

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
searchquery선택시험 제목·구분·과목 검색어. 공백으로 나눈 모든 단어가 일치해야 하며 괄호 등 사이 문자는 달라도 됨. 최대 100자. 생략 시 전체.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].registeredQuestionCountinteger필수전체 답안 칸 중 배점이 양수인 문항 수입니다. null은 상세 원본 미확인입니다.1
items[].storedSlotCountinteger필수배점 0을 포함한 전체 OMR 답안 칸 수입니다. null은 상세 원본 미확인입니다.1
items[].maximumnumber필수시험에 저장된 만점. 최고 득점이 아니며 선택과목별 유효 만점은 성적 analysis.maxScore로 확인. null은 만점 미확인.1
items[].onlineobject필수온라인 시험 번호·구분·응시대상·진행 상태입니다. 온라인 미등록은 null입니다.하위 필드·본문 예시 참조
items[].online.onlineExamIdinteger필수온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다.1
items[].online.examIdinteger필수채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다.1
items[].online.titlestring필수온라인 시험 제목입니다."예시"
items[].online.kindstring필수시험 구분: retest 재시험, homework 과제입니다."예시"
items[].online.statusstring필수unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다."예시"
items[].online.studentTargetCountinteger필수개별 지정 응시 등록 수입니다.1
items[].online.classTargetCountinteger필수지정한 수강 시간표 수입니다.1
items[].teacherIdinteger필수시험 담당 강사의 학원 내 사용자 번호입니다.1
items[].idinteger필수시험 고유 번호입니다.1
items[].titlestring필수시험 표시 제목입니다."예시"
items[].namestring필수시험 또는 회차 이름입니다."예시 이름"
items[].subjectstring필수시험 과목입니다. 정확한 값은 등록된 과목 목록을 사용하며 넓은 과목군 검색은 부분 일치로 조회합니다."예시"
items[].gradestring필수대상 학년입니다."예시"
items[].yearinteger필수시험 연도입니다.1
items[].omrCodestring필수OMR 양식 번호입니다."예시"
items[].publishedboolean필수학생 성적 공개 여부입니다.false
items[].answersarray필수문항별 정답과 배점입니다. 목록 응답의 빈 배열은 미조회이며 실제 문항은 상세 조회에서 확인합니다.하위 필드·본문 예시 참조
items[].answers[].numberstring필수유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요."1"
items[].answers[].subjectCodeinteger조건부·선택선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다.0
items[].answers[].answerTypeinteger조건부·선택답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다.0
items[].answers[].answerstring조건부·선택정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다."1"
items[].answers[].weightnumber조건부·선택문항 배점입니다. 0이면 채점하지 않습니다.0
items[].answers[].sectionIdinteger조건부·선택학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다.0
items[].answers[].patternIdinteger조건부·선택학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다.0
items[].answers[].difficultyinteger조건부·선택난이도 코드입니다. 0~5입니다.0
items[].answers[].commentstring조건부·선택문항 해설 또는 분석 코멘트입니다."예시"
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/grading/exams/{examId}시험과 전체 문항별 정답 상세

grading.read · grading.exams.get

경로 · 검색 파라미터

이름위치필수설명
examIdpath필수GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
registeredQuestionCountinteger필수전체 답안 칸 중 배점이 양수인 문항 수입니다. null은 상세 원본 미확인입니다.1
storedSlotCountinteger필수배점 0을 포함한 전체 OMR 답안 칸 수입니다. null은 상세 원본 미확인입니다.1
maximumnumber필수시험에 저장된 만점. 최고 득점이 아니며 선택과목별 유효 만점은 성적 analysis.maxScore로 확인. null은 만점 미확인.1
onlineobject필수온라인 시험 번호·구분·응시대상·진행 상태입니다. 온라인 미등록은 null입니다.하위 필드·본문 예시 참조
online.onlineExamIdinteger필수온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다.1
online.examIdinteger필수채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다.1
online.titlestring필수온라인 시험 제목입니다."예시"
online.kindstring필수시험 구분: retest 재시험, homework 과제입니다."예시"
online.statusstring필수unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다."예시"
online.studentTargetCountinteger필수개별 지정 응시 등록 수입니다.1
online.classTargetCountinteger필수지정한 수강 시간표 수입니다.1
teacherIdinteger필수시험 담당 강사의 학원 내 사용자 번호입니다.1
idinteger필수시험 고유 번호입니다.1
titlestring필수시험 표시 제목입니다."예시"
namestring필수시험 또는 회차 이름입니다."예시 이름"
subjectstring필수시험 과목입니다. 정확한 값은 등록된 과목 목록을 사용하며 넓은 과목군 검색은 부분 일치로 조회합니다."예시"
gradestring필수대상 학년입니다."예시"
yearinteger필수시험 연도입니다.1
omrCodestring필수OMR 양식 번호입니다."예시"
publishedboolean필수학생 성적 공개 여부입니다.false
answersarray필수문항별 정답과 배점입니다. 목록 응답의 빈 배열은 미조회이며 실제 문항은 상세 조회에서 확인합니다.하위 필드·본문 예시 참조
answers[].numberstring필수유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요."1"
answers[].subjectCodeinteger조건부·선택선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다.0
answers[].answerTypeinteger조건부·선택답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다.0
answers[].answerstring조건부·선택정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다."1"
answers[].weightnumber조건부·선택문항 배점입니다. 0이면 채점하지 않습니다.0
answers[].sectionIdinteger조건부·선택학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다.0
answers[].patternIdinteger조건부·선택학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다.0
answers[].difficultyinteger조건부·선택난이도 코드입니다. 0~5입니다.0
answers[].commentstring조건부·선택문항 해설 또는 분석 코멘트입니다."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
POST/v1/grading/exams새 시험·정답지 등록(학생 답안 채점 아님)

grading.write · grading.exams.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
teacherIdinteger조건부·선택담당 강사 번호입니다. /teams/teachers에서 선택합니다. 생략하면 신규 시험은 인증한 대표 강사, 수정은 기존 담당자를 유지합니다.1
titlestring필수시험 표시 제목입니다."예시 수학 평가"
namestring필수시험 또는 회차 이름입니다."1회차"
subjectstring필수채점 과목 목록의 정확한 이름을 선택합니다. 비슷한 과목이 여럿이면 먼저 선택을 확인하고, 등록되지 않은 과목은 저장 전에 안내합니다."수학"
gradestring조건부·선택시험 대상 학년입니다."예시"
yearinteger필수시험 연도입니다. 1900~2100입니다.2026
omrCodestring필수GET /v1/grading/omr-templates 응답 data[].code에서 선택한 양식 번호 문자열입니다. 예: 120. 시험 id와 다릅니다."120"
answersarray필수GET /v1/grading/omr-templates/{code}/answers 응답 data[]의 문항 번호·선택과목·답안 형식을 기준으로 정답·배점을 채웁니다. 배열 순서를 유지하며 선택한 양식의 모든 문항을 전달하세요.하위 필드·본문 예시 참조
answers[].numberstring필수유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요."1"
answers[].subjectCodeinteger조건부·선택선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다.0
answers[].answerTypeinteger조건부·선택답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다.0
answers[].answerstring조건부·선택정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다."1"
answers[].weightnumber조건부·선택문항 배점입니다. 0이면 채점하지 않습니다.0
answers[].sectionIdinteger조건부·선택학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다.0
answers[].patternIdinteger조건부·선택학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다.0
answers[].difficultyinteger조건부·선택난이도 코드입니다. 0~5입니다.0
answers[].commentstring조건부·선택문항 해설 또는 분석 코멘트입니다."예시"
요청 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/grading/exams/{examId}정답지 전체 교체(성적표 설정·문항 이미지 연결 보존)

grading.write · grading.exams.update

경로 · 검색 파라미터

이름위치필수설명
examIdpath필수GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
teacherIdinteger조건부·선택담당 강사 번호입니다. /teams/teachers에서 선택합니다. 생략하면 신규 시험은 인증한 대표 강사, 수정은 기존 담당자를 유지합니다.1
titlestring필수시험 표시 제목입니다."예시 수학 평가"
namestring필수시험 또는 회차 이름입니다."1회차"
subjectstring필수채점 과목 목록의 정확한 이름을 선택합니다. 비슷한 과목이 여럿이면 먼저 선택을 확인하고, 등록되지 않은 과목은 저장 전에 안내합니다."수학"
gradestring조건부·선택시험 대상 학년입니다."예시"
yearinteger필수시험 연도입니다. 1900~2100입니다.2026
omrCodestring필수GET /v1/grading/omr-templates 응답 data[].code에서 선택한 양식 번호 문자열입니다. 예: 120. 시험 id와 다릅니다."120"
answersarray필수GET /v1/grading/omr-templates/{code}/answers 응답 data[]의 문항 번호·선택과목·답안 형식을 기준으로 정답·배점을 채웁니다. 배열 순서를 유지하며 선택한 양식의 모든 문항을 전달하세요.하위 필드·본문 예시 참조
answers[].numberstring필수유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요."1"
answers[].subjectCodeinteger조건부·선택선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다.0
answers[].answerTypeinteger조건부·선택답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다.0
answers[].answerstring조건부·선택정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다."1"
answers[].weightnumber조건부·선택문항 배점입니다. 0이면 채점하지 않습니다.0
answers[].sectionIdinteger조건부·선택학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다.0
answers[].patternIdinteger조건부·선택학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다.0
answers[].difficultyinteger조건부·선택난이도 코드입니다. 0~5입니다.0
answers[].commentstring조건부·선택문항 해설 또는 분석 코멘트입니다."예시"
요청 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/grading/exams/{examId}시험 삭제(채점 자료가 있으면 거절)

grading.write · grading.exams.delete

경로 · 검색 파라미터

이름위치필수설명
examIdpath필수GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/grading/omr-templates/{code}/answers지정한 OMR 양식의 문항별 번호(number)·답안 종류(answerType)·정답·배점 입력 틀 배열. 특정 문항 범위의 종류 확인에도 사용. 0 객관식, 1 단답형 정답 비교, 2 서술형 획득점수. 실제 시험·채점 점수 조회가 아님

grading.read · grading.answer-template.get

경로 · 검색 파라미터

이름위치필수설명
codepath필수GET /v1/grading/omr-templates 응답에서 선택한 양식의 code입니다. 예: 문자열 120. 시험 번호와 다릅니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].numberstring필수유효 공통 문항 뒤로 이어지는 표시 번호입니다. 공통 22문항이면 선택과목은 1-23부터입니다. 배점 0은 빈 번호가 가능합니다. OMR 배열 순서는 유지하세요."1"
[].subjectCodeinteger조건부·선택선택과목 코드입니다. 공통 문항은 0이며 OMR 양식에 정의된 값을 사용합니다.0
[].answerTypeinteger조건부·선택답안 형식입니다. 0 객관식, 1 단답형, 2 서술형입니다.0
[].answerstring조건부·선택정답입니다. 복수 정답은 해당 OMR 양식의 정답 표기 방식으로 입력합니다."1"
[].weightnumber조건부·선택문항 배점입니다. 0이면 채점하지 않습니다.0
[].sectionIdinteger조건부·선택학원에 등록한 대분류 번호입니다. 0이면 분류 없음입니다.0
[].patternIdinteger조건부·선택학원에 등록한 소분류 번호입니다. 0이면 분류 없음입니다.0
[].difficultyinteger조건부·선택난이도 코드입니다. 0~5입니다.0
[].commentstring조건부·선택문항 해설 또는 분석 코멘트입니다."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
POST/v1/grading/omr-jobs단일·두 회차 OMR 채점 작업 등록(구독 OMR 장수 집계)

grading.omr · grading.omr.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
examIdsarray필수GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호를 배열로 전달합니다. 예: [1234]. 단일 채점은 1개, 두 회차는 순서대로 2개입니다. OMR 양식 번호와 다릅니다.하위 필드·본문 예시 참조
fileIdsarray필수PDF 업로드 응답 data.files[].id를 페이지 순서대로 전달합니다. 단일 이미지 업로드는 응답 data.id를 배열에 넣습니다. 최대 100개 UUID이며 로컬 파일명·URL·직접 만든 UUID를 넣지 않습니다.하위 필드·본문 예시 참조
teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요.1
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. teamId로 지정한 응시반에 속한 시간표 번호여야 합니다.1
examDatestring필수응시일입니다. yyyy-MM-dd 형식입니다."2026-01-15"
recognitionRateinteger조건부·선택마킹 인식 기준입니다. 1~5이며 기본값 4(70%)입니다.1
expectedUnitCreditsinteger조건부·선택이전 연동 호환용 값입니다. 새 구독 요금제는 크레딧을 차감하지 않으며 생략하거나 0을 보냅니다. 실제 이미지 장수는 구독 OMR 한도에서 집계합니다.0
consentboolean필수실제 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idstring필수작업 고유 번호입니다. 같은 작업의 상태 조회와 결과 다운로드에 사용합니다."00000000-0000-4000-8000-000000000001"
kindstring필수omr·excel·recalculate·report-pdf·wrong-note·link-issue·link-reissue·teaching-report 중 하나입니다. teaching-report는 과제장·누적 성적표 PDF 작업입니다."예시"
statusstring필수queued 대기, running 처리 중, completed 완료, failed 실패, needs_review 결과 확인 필요입니다. 결과 확인 필요 작업은 자동 재실행하지 않습니다."예시"
messagestring필수사용자에게 표시할 진행 또는 오류 안내입니다."예시"
createdAtstring필수작업 생성 시각입니다. UTC입니다."2026-01-15T00:00:00Z"
resultobject필수완료된 작업의 처리 결과입니다. 미완료이면 null입니다.하위 필드·본문 예시 참조
result.logIdinteger필수OMR 인식 이력 번호입니다. OMR 외 작업은 0입니다.1
result.idsarray필수신규 등록 또는 수정된 채점 행 번호 배열입니다.하위 필드·본문 예시 참조
result.examIdsarray필수처리한 시험 번호 배열입니다. 두 회차는 입력 순서입니다.하위 필드·본문 예시 참조
result.rowsarray필수OMR 이미지별 인식 결과입니다.하위 필드·본문 예시 참조
result.rows[].pageinteger필수입력 이미지의 1부터 시작하는 페이지 순서입니다.1
result.rows[].studentIdstring필수인식한 학원 학생 번호입니다. 미식별이면 빈 문자열입니다."00000001"
result.rows[].studentNamestring필수인식한 학생 이름입니다. 미식별이면 빈 문자열입니다."예시 이름"
result.rows[].marksarray필수인식한 답안 원문 배열이며 채점 확정 결과가 아닙니다. 두 회차는 1회차 양식 슬롯 뒤에 2회차 슬롯 순서입니다. 배열 위치로 표시 문항 번호·정오답·점수를 추정하지 말고 저장된 회차별 성적 분석으로 확인하세요.하위 필드·본문 예시 참조
result.rows[].messagestring필수이 이미지의 인식 확인 안내입니다. 문제가 없으면 빈 값입니다."예시"
result.errorsarray필수인식 실패 또는 검수가 필요한 이미지 안내입니다. 이 배열만으로 미저장을 판단하지 마세요. 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/grading/usage현재 API 호출·OMR 장수의 사용량과 구독 한도 확인

grading.read · grading.usage.get

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
planIdstring필수현재 구독 요금제 식별자입니다. 기존 구독은 비어 있을 수 있습니다."1"
requestsUnlimitedboolean필수월 API 호출량 무제한 여부입니다. 분당 안전 제한은 별도로 적용합니다.false
monthlyOmrPagesinteger필수월 OMR 이미지 한도입니다. null이면 월 채점량 무제한입니다.1
usedOmrPagesinteger필수이번 구독 기간에 채점을 시도한 OMR 이미지 장수입니다.1
remainingOmrPagesinteger필수남은 OMR 이미지 장수입니다. null이면 무제한입니다.1
omrUnitCreditsinteger필수이전 연동 호환용 필드입니다. 구독형 API는 0이며 크레딧을 차감하지 않습니다.1
requestCreditsinteger필수이전 연동 호환용 필드이며 0입니다. 구독의 월·분당 호출 제한은 별도입니다.1
includedCreditsinteger필수이전 연동 호환용 필드이며 0입니다. 새 구독은 월 호출량과 OMR 이미지 장수로 집계합니다.1
remainingIncludedCreditsinteger필수이전 연동 호환용 필드이며 0입니다. 새 구독은 남은 OMR 장수를 확인하세요.1
purchasedCreditsinteger필수이전 연동 호환용 필드이며 0입니다. 추가 구매는 지원하지 않습니다.1
availableCreditsinteger필수이전 연동 호환용 필드이며 0입니다. 새 요금제는 크레딧 없이 호출·OMR 수량을 집계합니다.1
requestLimitinteger필수이번 구독 기간에 적용하는 요청 한도입니다. requestsUnlimited=true이면 이 숫자로 월 제한을 판단하지 않습니다. 관리자 개별 상한은 별도로 적용됩니다.1
usedRequestsinteger필수이번 구독 기간에 접수된 API 요청 수입니다. 이 조회 요청도 포함되며 동일 쓰기 요청의 재응답은 중복 집계하지 않습니다.1
periodStartstring필수이번 API 구독 사용량 기간 시작 시각입니다. 시간대 오프셋을 포함합니다."2026-01-15T00:00:00Z"
periodEndstring필수현재 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/grading/jobs/{jobId}데이터 작업 진행 상태·인식 결과 조회

grading.read · grading.jobs.get

경로 · 검색 파라미터

이름위치필수설명
jobIdpath필수작업 생성 응답 data.id의 UUID를 그대로 전달합니다. 직접 생성하는 값이 아니며 같은 학원의 작업만 조회합니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idstring필수작업 고유 번호입니다. 같은 작업의 상태 조회와 결과 다운로드에 사용합니다."00000000-0000-4000-8000-000000000001"
kindstring필수omr·excel·recalculate·report-pdf·wrong-note·link-issue·link-reissue·teaching-report 중 하나입니다. teaching-report는 과제장·누적 성적표 PDF 작업입니다."예시"
statusstring필수queued 대기, running 처리 중, completed 완료, failed 실패, needs_review 결과 확인 필요입니다. 결과 확인 필요 작업은 자동 재실행하지 않습니다."예시"
messagestring필수사용자에게 표시할 진행 또는 오류 안내입니다."예시"
createdAtstring필수작업 생성 시각입니다. UTC입니다."2026-01-15T00:00:00Z"
resultobject필수완료된 작업의 처리 결과입니다. 미완료이면 null입니다.하위 필드·본문 예시 참조
result.logIdinteger필수OMR 인식 이력 번호입니다. OMR 외 작업은 0입니다.1
result.idsarray필수신규 등록 또는 수정된 채점 행 번호 배열입니다.하위 필드·본문 예시 참조
result.examIdsarray필수처리한 시험 번호 배열입니다. 두 회차는 입력 순서입니다.하위 필드·본문 예시 참조
result.rowsarray필수OMR 이미지별 인식 결과입니다.하위 필드·본문 예시 참조
result.rows[].pageinteger필수입력 이미지의 1부터 시작하는 페이지 순서입니다.1
result.rows[].studentIdstring필수인식한 학원 학생 번호입니다. 미식별이면 빈 문자열입니다."00000001"
result.rows[].studentNamestring필수인식한 학생 이름입니다. 미식별이면 빈 문자열입니다."예시 이름"
result.rows[].marksarray필수인식한 답안 원문 배열이며 채점 확정 결과가 아닙니다. 두 회차는 1회차 양식 슬롯 뒤에 2회차 슬롯 순서입니다. 배열 위치로 표시 문항 번호·정오답·점수를 추정하지 말고 저장된 회차별 성적 분석으로 확인하세요.하위 필드·본문 예시 참조
result.rows[].messagestring필수이 이미지의 인식 확인 안내입니다. 문제가 없으면 빈 값입니다."예시"
result.errorsarray필수인식 실패 또는 검수가 필요한 이미지 안내입니다. 이 배열만으로 미저장을 판단하지 마세요. 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"
  }
}
Explorer에서 요청 구성 →
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. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
fileobject필수첨부 참조 연동 전용 객체입니다. 클라이언트가 제공한 download_url·file_id와 선택적 MIME·파일명을 전달합니다. 일반 파일 업로드는 pdf-uploads 또는 uploads를 사용하세요. PDF 최대 50MB·100쪽, 그 외 최대 5MB입니다.하위 필드·본문 예시 참조
file.download_urlstring필수첨부 연동 클라이언트가 파일 메타데이터로 제공한 download_url을 그대로 전달합니다. 현재 승인 호스트는 oaiusercontent.com 및 그 하위 도메인의 HTTPS 주소뿐입니다. 일반 웹 URL·개인 저장소 주소·로컬 경로는 받지 않습니다. 이 메타데이터가 없는 일반 PDF 업로드는 /v1/grading/pdf-uploads를 사용하세요."https://files.oaiusercontent.com/example/omr.pdf?token=CLIENT_PROVIDED_TOKEN"
file.file_idstring필수첨부 연동 클라이언트의 동일한 파일 메타데이터에 있는 file_id를 그대로 전달합니다. KlassLab이 발급하는 API 키나 업로드 응답의 id가 아니며 직접 생성하는 UUID도 아닙니다. 클라이언트가 이 값을 제공하지 않는 환경에서는 /v1/grading/pdf-uploads로 파일 바이트를 전달하세요."file-client-example"
file.mime_typestring조건부·선택첨부 파일의 MIME 형식입니다. PDF는 application/pdf, PNG는 image/png, JPG는 image/jpeg입니다. 메타데이터에 없으면 생략할 수 있습니다."application/pdf"
file.file_namestring조건부·선택확장자를 포함한 원본 파일명입니다. 예: 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
filesarray필수페이지 순서대로 저장된 파일입니다. PDF는 각 쪽이 image 파일 하나가 됩니다. OMR 신청 시 이 순서대로 id를 fileIds에 전달하세요.하위 필드·본문 예시 참조
files[].idstring필수업로드 파일 식별자입니다. 작업 등록 시 이 값만 전달합니다."00000000-0000-4000-8000-000000000001"
files[].kindstring필수image 또는 xlsx입니다."예시"
files[].bytesinteger필수검증된 원본 파일 크기(바이트)입니다.1
files[].expiresAtstring필수업로드 만료 시각입니다. UTC이며 업로드 후 24시간입니다."2026-01-15T00:00:00Z"
pageCountinteger필수저장된 파일 수입니다. 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"
  }
}
Explorer에서 요청 구성 →
POST/v1/grading/pdf-uploadsOMR PDF 원본 업로드(최대 50MB·100쪽 / 페이지 자동 변환)

grading.write · grading.pdfs.upload

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
fileNamestring필수직접 업로드할 PDF의 파일명입니다. 예: omr.pdf. .pdf 확장자를 포함하고 C:\scan\omr.pdf 같은 디렉터리 경로는 제외하세요."omr.pdf"
base64string필수호출하는 프로그램이 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
filesarray필수페이지 순서대로 저장된 파일입니다. PDF는 각 쪽이 image 파일 하나가 됩니다. OMR 신청 시 이 순서대로 id를 fileIds에 전달하세요.하위 필드·본문 예시 참조
files[].idstring필수업로드 파일 식별자입니다. 작업 등록 시 이 값만 전달합니다."00000000-0000-4000-8000-000000000001"
files[].kindstring필수image 또는 xlsx입니다."예시"
files[].bytesinteger필수검증된 원본 파일 크기(바이트)입니다.1
files[].expiresAtstring필수업로드 만료 시각입니다. UTC이며 업로드 후 24시간입니다."2026-01-15T00:00:00Z"
pageCountinteger필수저장된 파일 수입니다. 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"
  }
}
Explorer에서 요청 구성 →
POST/v1/grading/uploads보조 업로드: PNG·JPG 스캔 이미지·XLSX 답안 파일(파일당 5MB)

grading.write · grading.files.upload

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
fileNamestring필수원본 파일명입니다. PNG·JPG·XLSX만 허용합니다. 경로는 받지 않습니다."scan.jpg"
base64string필수호출하는 프로그램에서 파일 전체 바이트를 읽어 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idstring필수업로드 파일 식별자입니다. 작업 등록 시 이 값만 전달합니다."00000000-0000-4000-8000-000000000001"
kindstring필수image 또는 xlsx입니다."예시"
bytesinteger필수검증된 원본 파일 크기(바이트)입니다.1
expiresAtstring필수업로드 만료 시각입니다. 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"
  }
}
Explorer에서 요청 구성 →
POST/v1/grading/exams/{examId}/excel-importsXLSX 답안 등록 작업 생성

grading.write · grading.excel.create

경로 · 검색 파라미터

이름위치필수설명
examIdpath필수GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
fileIdstring필수XLSX를 POST /v1/grading/uploads로 먼저 업로드한 응답 data.id(UUID)입니다. 파일명이나 직접 생성한 UUID가 아닙니다. 첫 시트 머리글은 studentId, 선택적 subjectCode, 문항번호 1, 2 ...이며 최대 100행입니다."00000000-0000-4000-8000-000000000001"
teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요.1
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. teamId로 지정한 응시반에 속한 시간표 번호여야 합니다.1
examDatestring필수응시일입니다. 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idstring필수작업 고유 번호입니다. 같은 작업의 상태 조회와 결과 다운로드에 사용합니다."00000000-0000-4000-8000-000000000001"
kindstring필수omr·excel·recalculate·report-pdf·wrong-note·link-issue·link-reissue·teaching-report 중 하나입니다. teaching-report는 과제장·누적 성적표 PDF 작업입니다."예시"
statusstring필수queued 대기, running 처리 중, completed 완료, failed 실패, needs_review 결과 확인 필요입니다. 결과 확인 필요 작업은 자동 재실행하지 않습니다."예시"
messagestring필수사용자에게 표시할 진행 또는 오류 안내입니다."예시"
createdAtstring필수작업 생성 시각입니다. UTC입니다."2026-01-15T00:00:00Z"
resultobject필수완료된 작업의 처리 결과입니다. 미완료이면 null입니다.하위 필드·본문 예시 참조
result.logIdinteger필수OMR 인식 이력 번호입니다. OMR 외 작업은 0입니다.1
result.idsarray필수신규 등록 또는 수정된 채점 행 번호 배열입니다.하위 필드·본문 예시 참조
result.examIdsarray필수처리한 시험 번호 배열입니다. 두 회차는 입력 순서입니다.하위 필드·본문 예시 참조
result.rowsarray필수OMR 이미지별 인식 결과입니다.하위 필드·본문 예시 참조
result.rows[].pageinteger필수입력 이미지의 1부터 시작하는 페이지 순서입니다.1
result.rows[].studentIdstring필수인식한 학원 학생 번호입니다. 미식별이면 빈 문자열입니다."00000001"
result.rows[].studentNamestring필수인식한 학생 이름입니다. 미식별이면 빈 문자열입니다."예시 이름"
result.rows[].marksarray필수인식한 답안 원문 배열이며 채점 확정 결과가 아닙니다. 두 회차는 1회차 양식 슬롯 뒤에 2회차 슬롯 순서입니다. 배열 위치로 표시 문항 번호·정오답·점수를 추정하지 말고 저장된 회차별 성적 분석으로 확인하세요.하위 필드·본문 예시 참조
result.rows[].messagestring필수이 이미지의 인식 확인 안내입니다. 문제가 없으면 빈 값입니다."예시"
result.errorsarray필수인식 실패 또는 검수가 필요한 이미지 안내입니다. 이 배열만으로 미저장을 판단하지 마세요. 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/grading/exams/{examId}/scores채점 점수·답안·코멘트 조회. 오답·보충·만점 대비 비율 분석은 includeAnalysis=true로 서버 판정을 사용. 빈 답안은 실제 무응답으로 단정하지 않고 미식별 학생은 추측하지 않음

grading.read · grading.scores.list

경로 · 검색 파라미터

이름위치필수설명
examIdpath필수GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다.
includeAnalysisquery선택기본 false. 오답·보충 문항·만점 대비 비율 분석은 true로 조회하여 analysis의 실제 문항 번호·서버 판정을 사용하세요. 저장 점수/답안을 변경하지 않습니다. 긴 시험은 pageSize를 줄이고 전체 페이지 여부를 확인하세요.
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].idinteger필수채점 행 고유 번호입니다.1
items[].examIdinteger필수시험 고유 번호입니다.1
items[].studentIdstring필수학생 고유 번호입니다. 미식별 스캔은 빈 값일 수 있습니다."00000001"
items[].studentNamestring필수학생 이름 또는 스캔에서 읽은 이름입니다."예시 이름"
items[].teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요.1
items[].scheduleIdinteger필수응시 시간표 번호입니다.1
items[].examDateinteger필수응시일입니다. yyyyMMdd 정수입니다.20260115
items[].scorenumber필수현재 채점 점수입니다.1
items[].commentstring필수학생별 성적 개별 코멘트입니다. Tutor_Student_Omr.Etc의 원문입니다."예시"
items[].subjectCodeinteger필수선택과목 코드입니다. 공통은 0입니다.1
items[].marksarray필수저장 위치 순서의 원문 답안입니다. 배열 인덱스+1을 표시 문항 번호로 추정하지 마세요. 문항별 해석은 includeAnalysis=true의 questions.number·mark·markState·points를 함께 사용하세요. 빈 문자열은 저장 빈 값이며 실제 무응답의 원인을 확정하지 않습니다.하위 필드·본문 예시 참조
items[].analysisobject필수includeAnalysis=true일 때의 서버 계산 문항 분석입니다. null은 분석 미요청이며 분석 결과 없음과 다릅니다.하위 필드·본문 예시 참조
items[].analysis.basisstring필수현재 정답·저장 답안으로 계산한 참고 분석입니다. 재채점하거나 저장하지 않습니다."예시"
items[].analysis.maxScorenumber필수공통과 해당 선택과목의 유효 배점 합계입니다. 선택과목이나 정답이 불확실하면 null입니다.1
items[].analysis.scorePercentnumber필수저장 점수÷maxScore×100입니다. 비율의 미만/이하를 구분하세요. 계산 불가이면 null입니다.1
items[].analysis.recalculatedScorenumber필수현재 공유 채점 로직으로 계산한 참고 점수입니다. 저장 점수는 덮어쓰지 않습니다. 답안 누락 등이 있으면 null입니다.1
items[].analysis.matchesStoredScoreboolean필수참고 점수와 저장 점수가 일치하는지입니다. 불일치하면 정답 변경 등의 가능성을 안내하고 재채점 완료로 설명하지 마세요.false
items[].analysis.correctQuestionsarray필수배점 전부를 받은 실제 문항 번호입니다. 배열 위치로 문항 번호를 만들지 마세요.하위 필드·본문 예시 참조
items[].analysis.incorrectQuestionsarray필수입력된 답안이 있으나 0점인 실제 문항 번호입니다. 빈 값·미저장·대상 외 문항은 포함하지 않습니다.하위 필드·본문 예시 참조
items[].analysis.partialQuestionsarray필수0점 초과·배점 미만인 부분 점수 문항 번호입니다.하위 필드·본문 예시 참조
items[].analysis.blankQuestionsarray필수저장 답안이 빈 값인 문항 번호입니다. 실제 무응답인지 입력/인식 누락인지는 확정할 수 없습니다. 모두 정답 처리 문항과 겹칠 수 있습니다.하위 필드·본문 예시 참조
items[].analysis.missingQuestionsarray필수저장 배열에 위치 자체가 없는 문항 번호입니다. 빈 값이나 오답으로 단정하지 않습니다.하위 필드·본문 예시 참조
items[].analysis.questionsarray필수과목·배점에 따른 대상 외 문항을 포함한 명시적 문항 번호·답안·상태·배점·득점입니다.하위 필드·본문 예시 참조
items[].analysis.questions[].sequenceinteger필수저장 답안의 1부터 시작하는 위치입니다. 표시 문항 번호와 다릅니다.1
items[].analysis.questions[].numberstring필수정답 자료의 실제 문항 번호입니다. 위치에서 번호를 재생성하지 않습니다."예시"
items[].analysis.questions[].subjectCodeinteger필수선택과목 코드입니다. 0은 공통입니다.1
items[].analysis.questions[].markstring필수저장 답안 원문입니다. 위치가 없을 때만 null입니다."1"
items[].analysis.questions[].markStatestring필수present=입력 있음, blank=저장 빈 값, missing=위치 미저장입니다."예시"
items[].analysis.questions[].outcomestring필수full_credit=배점 전부, partial_credit=부분점수, zero_credit=0점, excluded=대상 외, unavailable=판정 불가입니다. 빈 값과 오답을 혼동하지 마세요."예시"
items[].analysis.questions[].weightnumber필수문항 배점입니다. 배점 0은 채점 대상 외입니다.1
items[].analysis.questions[].pointsnumber필수현재 공유 채점 로직의 참고 득점입니다. 대상 외·누락·판정 불가이면 null입니다.1
items[].analysis.warningsarray필수분석 시 주의점입니다. 빈 값의 원인·미식별 학생·점수 차이를 추측으로 채우지 마세요.하위 필드·본문 예시 참조
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
POST/v1/grading/exams/{examId}/scores기존 시험에 학생 수기·엑셀 답안 채점·저장(결과는 학생별 번호 배열)

grading.write · grading.scores.create

경로 · 검색 파라미터

이름위치필수설명
examIdpath필수GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
examDatestring필수응시일입니다. yyyy-MM-dd 형식입니다."2026-01-15"
teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요.1
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 응시반에 속한 시간표 번호입니다.1
rowsarray필수처리할 학생 답안입니다. 전체 행을 검증한 뒤 하나의 트랜잭션으로 저장합니다.하위 필드·본문 예시 참조
rows[].idinteger조건부·선택기존 채점 행 번호입니다. 신규 등록은 0이며 수정은 대상 시험의 행 번호를 지정합니다.0
rows[].studentIdstring필수등록된 학생 고유 번호입니다. 기존 미식별 채점 행 수정은 빈 문자열로 학생 연결·인식 이름을 보존합니다. 신규 등록에는 같은 학원 학생 번호가 필수이며 기존 학생 연결을 빈 값으로 해제할 수 없습니다."00000001"
rows[].subjectCodeinteger조건부·선택선택과목 코드입니다. 공통은 0입니다.0
rows[].marksarray필수정답지 문항 순서대로 학생 답안을 입력합니다. 빈 문자열은 무응답입니다.하위 필드·본문 예시 참조
요청 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idinteger|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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/grading/exams/{examId}/scores개별·일괄 기존 채점 답안 수정 및 재채점. 기존 미식별 답안은 행 id와 빈 studentId로 학생 연결·인식 이름을 보존하며 수정. 정답지와 원본 marks 전체를 조회해 요청하지 않은 답안은 유지

grading.write · grading.scores.update

경로 · 검색 파라미터

이름위치필수설명
examIdpath필수GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
examDatestring필수응시일입니다. yyyy-MM-dd 형식입니다."2026-01-15"
teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 응시반 번호입니다. 반 이름이 아닌 정수 id를 전달하세요.1
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 응시반에 속한 시간표 번호입니다.1
rowsarray필수처리할 학생 답안입니다. 전체 행을 검증한 뒤 하나의 트랜잭션으로 저장합니다.하위 필드·본문 예시 참조
rows[].idinteger조건부·선택기존 채점 행 번호입니다. 신규 등록은 0이며 수정은 대상 시험의 행 번호를 지정합니다.0
rows[].studentIdstring필수등록된 학생 고유 번호입니다. 기존 미식별 채점 행 수정은 빈 문자열로 학생 연결·인식 이름을 보존합니다. 신규 등록에는 같은 학원 학생 번호가 필수이며 기존 학생 연결을 빈 값으로 해제할 수 없습니다."00000001"
rows[].subjectCodeinteger조건부·선택선택과목 코드입니다. 공통은 0입니다.0
rows[].marksarray필수정답지 문항 순서대로 학생 답안을 입력합니다. 빈 문자열은 무응답입니다.하위 필드·본문 예시 참조
요청 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/grading/exams/{examId}/scores/{scoreId}채점 행 삭제

grading.write · grading.scores.delete

경로 · 검색 파라미터

이름위치필수설명
examIdpath필수GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다.
scoreIdpath필수GET /v1/grading/exams/{examId}/scores 응답 data.items[].id의 채점 행 번호입니다. 학생 번호와 다릅니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
PATCH/v1/grading/exams/{examId}/scores/{scoreId}/comment학생별 성적 개별 코멘트 저장

grading.write · grading.scores.comment

경로 · 검색 파라미터

이름위치필수설명
examIdpath필수GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다.
scoreIdpath필수GET /v1/grading/exams/{examId}/scores 응답 data.items[].id의 채점 행 번호입니다. 학생 번호와 다릅니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
commentstring조건부·선택학생별 성적 개별 코멘트입니다. 빈 문자열이면 코멘트를 비웁니다."예시"
요청 JSON 스키마
{
  "type": "object",
  "properties": {
    "comment": {
      "type": "string",
      "description": "학생별 성적 개별 코멘트입니다. 빈 문자열이면 코멘트를 비웁니다.",
      "nullable": false,
      "maxLength": 10000,
      "default": ""
    }
  }
}

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
POST/v1/grading/recalculation-jobs정답 변경 후 점수·통계 재계산 작업 생성

grading.write · grading.recalculate.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
examIdsarray필수정답지 변경 후 점수와 통계를 재계산할 시험 번호 배열입니다. 최대 20개이며 중복은 허용하지 않습니다.하위 필드·본문 예시 참조
요청 JSON 스키마
{
  "type": "object",
  "properties": {
    "examIds": {
      "type": "array",
      "items": {
        "type": "integer"
      },
      "description": "정답지 변경 후 점수와 통계를 재계산할 시험 번호 배열입니다. 최대 20개이며 중복은 허용하지 않습니다.",
      "nullable": false,
      "minItems": 1,
      "maxItems": 20
    }
  },
  "required": [
    "examIds"
  ]
}

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idstring필수작업 고유 번호입니다. 같은 작업의 상태 조회와 결과 다운로드에 사용합니다."00000000-0000-4000-8000-000000000001"
kindstring필수omr·excel·recalculate·report-pdf·wrong-note·link-issue·link-reissue·teaching-report 중 하나입니다. teaching-report는 과제장·누적 성적표 PDF 작업입니다."예시"
statusstring필수queued 대기, running 처리 중, completed 완료, failed 실패, needs_review 결과 확인 필요입니다. 결과 확인 필요 작업은 자동 재실행하지 않습니다."예시"
messagestring필수사용자에게 표시할 진행 또는 오류 안내입니다."예시"
createdAtstring필수작업 생성 시각입니다. UTC입니다."2026-01-15T00:00:00Z"
resultobject필수완료된 작업의 처리 결과입니다. 미완료이면 null입니다.하위 필드·본문 예시 참조
result.logIdinteger필수OMR 인식 이력 번호입니다. OMR 외 작업은 0입니다.1
result.idsarray필수신규 등록 또는 수정된 채점 행 번호 배열입니다.하위 필드·본문 예시 참조
result.examIdsarray필수처리한 시험 번호 배열입니다. 두 회차는 입력 순서입니다.하위 필드·본문 예시 참조
result.rowsarray필수OMR 이미지별 인식 결과입니다.하위 필드·본문 예시 참조
result.rows[].pageinteger필수입력 이미지의 1부터 시작하는 페이지 순서입니다.1
result.rows[].studentIdstring필수인식한 학원 학생 번호입니다. 미식별이면 빈 문자열입니다."00000001"
result.rows[].studentNamestring필수인식한 학생 이름입니다. 미식별이면 빈 문자열입니다."예시 이름"
result.rows[].marksarray필수인식한 답안 원문 배열이며 채점 확정 결과가 아닙니다. 두 회차는 1회차 양식 슬롯 뒤에 2회차 슬롯 순서입니다. 배열 위치로 표시 문항 번호·정오답·점수를 추정하지 말고 저장된 회차별 성적 분석으로 확인하세요.하위 필드·본문 예시 참조
result.rows[].messagestring필수이 이미지의 인식 확인 안내입니다. 문제가 없으면 빈 값입니다."예시"
result.errorsarray필수인식 실패 또는 검수가 필요한 이미지 안내입니다. 이 배열만으로 미저장을 판단하지 마세요. 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/grading/exams/{examId}/missing-submissions미제출 명단 조회(재시험은 지정 응시대상, 통합은 두 시험 모두 성적 없음)

grading.read · grading.missing-submissions.list

경로 · 검색 파라미터

이름위치필수설명
examIdpath필수GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 번호입니다. OMR 양식 번호와 다릅니다.
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
otherExamIdquery선택미제출 통합 조회의 두 번째 정답지 examId입니다. 0 또는 생략하면 단일 회차이며 두 시험 모두 성적이 없는 학생을 조회합니다.
scheduleIdquery선택GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
isRetestboolean필수재시험 지정 응시대상 기준인지 나타냅니다.false
itemsarray필수학생번호별 중복을 제외한 미제출 학생입니다. 통합 조회는 두 시험 모두 성적이 없는 학생입니다.하위 필드·본문 예시 참조
items[].studentIdstring조건부·선택학원 학생번호입니다."00000001"
items[].studentNamestring조건부·선택학생 성명입니다."예시 이름"
items[].schoolNamestring조건부·선택학교명입니다."예시 이름"
items[].gradeNamestring조건부·선택학년입니다."예시 이름"
items[].teamNamestring조건부·선택수강반명입니다."예시 이름"
totalinteger필수전체 미제출 학생 수입니다.1
pageinteger필수조회한 페이지(1부터)입니다.1
pageSizeinteger필수페이지당 학생 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/grading/online-exams등록된 온라인 과제·재시험 조회(온라인 번호·구분·진행 상태)

grading.read · grading.online-exams.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
searchquery선택검색어입니다. 최대 100자이며 생략하면 전체를 조회합니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].onlineExamIdinteger필수온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다.1
items[].examIdinteger필수채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다.1
items[].titlestring필수온라인 시험 제목입니다."예시"
items[].kindstring필수시험 구분: retest 재시험, homework 과제입니다."예시"
items[].statusstring필수unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다."예시"
items[].studentTargetCountinteger필수개별 지정 응시 등록 수입니다.1
items[].classTargetCountinteger필수지정한 수강 시간표 수입니다.1
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/grading/online-exams/{onlineExamId}온라인 시험 구분·응시대상 설정 현황

grading.read · grading.online-exams.get

경로 · 검색 파라미터

이름위치필수설명
onlineExamIdpath필수GET /v1/grading/online-exams의 onlineExamId입니다. 정답지 examId나 학생 응시 등록 번호와 다릅니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
onlineExamIdinteger필수온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다.1
examIdinteger필수채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다.1
titlestring필수온라인 시험 제목입니다."예시"
kindstring필수시험 구분: retest 재시험, homework 과제입니다."예시"
statusstring필수unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다."예시"
studentTargetCountinteger필수개별 지정 응시 등록 수입니다.1
classTargetCountinteger필수지정한 수강 시간표 수입니다.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"
  }
}
Explorer에서 요청 구성 →
PATCH/v1/grading/online-exams/{onlineExamId}/kind온라인 시험 구분 변경(연결된 재시험은 먼저 연결 해제)

grading.write · grading.online-exams.kind

경로 · 검색 파라미터

이름위치필수설명
onlineExamIdpath필수GET /v1/grading/online-exams의 onlineExamId입니다. 정답지 examId나 학생 응시 등록 번호와 다릅니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
kindstring조건부·선택시험 구분: retest 또는 homework를 지정합니다."retest"
요청 JSON 스키마
{
  "type": "object",
  "properties": {
    "kind": {
      "type": "string",
      "description": "시험 구분: retest 또는 homework를 지정합니다.",
      "nullable": false,
      "default": "retest"
    }
  }
}

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
onlineExamIdinteger필수온라인 시험 고유 번호(Tutor_Exam_Online.Idx)입니다.1
examIdinteger필수채점할 정답지 번호(Tutor_Exam_List.Exam_Idx)입니다.1
titlestring필수온라인 시험 제목입니다."예시"
kindstring필수시험 구분: retest 재시험, homework 과제입니다."예시"
statusstring필수unassigned 대상 미등록, ongoing 진행중, scheduled 예정, completed 완료입니다."예시"
studentTargetCountinteger필수개별 지정 응시 등록 수입니다.1
classTargetCountinteger필수지정한 수강 시간표 수입니다.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"
  }
}
Explorer에서 요청 구성 →

수업관리

GET/v1/teaching/teams/{id}/report-settings반별 과제장 성적표 저장값·실제 적용 양식·이름·version 조회(미지정 0 등은 당일형 80, 82는 누적형)웹 관리 기능

웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요
teaching.read · teaching.reports.settings.get

경로 · 검색 파라미터

이름위치필수설명
idpath필수대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
teamIdinteger필수수강반 번호입니다.1
teamNamestring필수실제 수강반 이름입니다."예시 이름"
classstring필수저장된 과제장 분류입니다."예시"
groupstring필수저장된 교과 그룹입니다."예시"
apiFlaginteger필수수강반의 저장된 과제장 사용 구분입니다.1
reportinteger필수현재 과제장 성적표 양식 번호입니다. 0은 미설정 값입니다.1
versionstring필수변경 전 다시 확인해야 하는 현재 설정의 검증 값입니다."예시"
effectiveReportinteger필수실제 적용되는 과제장 성적표 양식입니다. 82는 누적형이며, 미지정 0을 포함한 나머지는 관리자 화면과 동일한 당일형 80입니다. 저장된 report는 바꾸지 않습니다.1
storedReportNamestring필수저장된 양식의 이름입니다. 0은 미지정이며, 미지정 상태에서도 실제 적용 양식은 당일형입니다."예시 이름"
reportNamestring필수실제 적용 양식 이름입니다. 당일형 또는 누적형입니다."예시 이름"
응답 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"
  }
}
Explorer에서 요청 구성 →
PATCH/v1/teaching/teams/{id}/report-settings반별 과제장 성적표를 당일형 80/누적형 82로 변경(현재 version 확인·다른 반 설정 보존)웹 관리 기능

웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요
teaching.write · teaching.reports.settings.update

경로 · 검색 파라미터

이름위치필수설명
idpath필수대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
versionstring필수설정 조회에서 받은 현재 version입니다. 임의 생성하지 않습니다."예시"
reportinteger조건부·선택화면에서 지원하는 성적표 양식 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
teamIdinteger필수수강반 번호입니다.1
teamNamestring필수실제 수강반 이름입니다."예시 이름"
classstring필수저장된 과제장 분류입니다."예시"
groupstring필수저장된 교과 그룹입니다."예시"
apiFlaginteger필수수강반의 저장된 과제장 사용 구분입니다.1
reportinteger필수현재 과제장 성적표 양식 번호입니다. 0은 미설정 값입니다.1
versionstring필수변경 전 다시 확인해야 하는 현재 설정의 검증 값입니다."예시"
effectiveReportinteger필수실제 적용되는 과제장 성적표 양식입니다. 82는 누적형이며, 미지정 0을 포함한 나머지는 관리자 화면과 동일한 당일형 80입니다. 저장된 report는 바꾸지 않습니다.1
storedReportNamestring필수저장된 양식의 이름입니다. 0은 미지정이며, 미지정 상태에서도 실제 적용 양식은 당일형입니다."예시 이름"
reportNamestring필수실제 적용 양식 이름입니다. 당일형 또는 누적형입니다."예시 이름"
응답 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/lessons/{lessonId}/retest과제장 재시험 연결·해제할 등록 번호 조회

teaching.read · teaching.retest.get

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
lessonIdinteger필수과제장 번호입니다.1
onlineExamIdinteger필수연결된 온라인 재시험 번호입니다. 미연결은 0입니다.1
examIdinteger필수연결된 채점할 정답지 번호입니다. 미연결은 0입니다.1
titlestring필수연결 재시험명입니다."예시"
removableAssignmentIdsarray필수해제 시 삭제할 개별 응시 등록 번호입니다. 명단에 없는 등록과 반 등록은 제외합니다.하위 필드·본문 예시 참조
studentIdsarray필수삭제 대상 학생번호입니다.하위 필드·본문 예시 참조
sharedStudentCountinteger필수다른 과제장과 공유하여 삭제에서 보호하는 학생 수입니다.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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/teaching/lessons/{lessonId}/retest재시험 연결·선택한 과제장 학생 응시 등록·재시험 대상 체크(원자적 저장)

teaching.write · teaching.retest.set

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
onlineExamIdinteger필수연결할 재시험의 온라인 시험 번호입니다.1
expectedOnlineExamIdinteger조건부·선택현재 연결 번호입니다. 미연결은 0이며 조회 후 변경된 연결은 거절합니다.0
studentIdsarray조건부·선택과제장 명단에서 선택한 학생번호입니다. 빈 배열은 연결만 설정합니다.하위 필드·본문 예시 참조
startstring조건부·선택한국시간 응시 시작입니다. 생략하면 시작 제한이 없습니다."2026-01-15T00:00:00Z"
endstring조건부·선택한국시간 응시 마감입니다. 생략하면 마감 제한이 없습니다."2026-01-15T00:00:00Z"
minutesinteger조건부·선택응시 제한시간(분)입니다. 응시기간과 독립적입니다.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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
lessonIdinteger필수과제장 번호입니다.1
onlineExamIdinteger필수연결된 온라인 재시험 번호입니다. 미연결은 0입니다.1
examIdinteger필수연결된 채점할 정답지 번호입니다. 미연결은 0입니다.1
titlestring필수연결 재시험명입니다."예시"
removableAssignmentIdsarray필수해제 시 삭제할 개별 응시 등록 번호입니다. 명단에 없는 등록과 반 등록은 제외합니다.하위 필드·본문 예시 참조
studentIdsarray필수삭제 대상 학생번호입니다.하위 필드·본문 예시 참조
sharedStudentCountinteger필수다른 과제장과 공유하여 삭제에서 보호하는 학생 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/lessons날짜·반별 수업 기록·과제장 목록(수강반 목록 아님)

teaching.read · teaching.lessons.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
teamIdquery선택GET /v1/teams 응답 data.items[].id의 정수 번호로 결과를 제한합니다. 검색 조건에서 생략하면 전체 반입니다.
fromquery필수조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery필수조회 종료일입니다. yyyy-MM-dd 형식입니다.
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].teamNamestring필수해당 수업의 실제 수강반 이름입니다. 같은 학원의 반 번호에 연결한 원본 명칭입니다."예시 이름"
items[].onlineRetestIdinteger필수연결된 온라인 재시험 번호입니다. 미연결은 0이며 /teaching/lessons/{lessonId}/retest에서 연결 정보를 조회합니다.1
items[].idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
items[].teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.1
items[].scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.1
items[].teacherIdinteger필수GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.1
items[].datestring필수수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다."2026-01-15"
items[].titlestring필수제목입니다."예시"
items[].seasonstring필수기간·학기 구분입니다. 빈 문자열이면 미지정입니다."예시"
items[].orderinteger필수수업 회차입니다. 0 이상입니다.0
items[].contentobject필수과제·시험 항목과 연결 시험 설정입니다. PUT은 전체 내용을 교체합니다.하위 필드·본문 예시 참조
items[].content.nes1string조건부·선택과제 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다."예시"
items[].content.nes1sstring조건부·선택과제 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
items[].content.nes1tstring조건부·선택과제 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
items[].content.nes2string조건부·선택과제 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다."예시"
items[].content.nes2sstring조건부·선택과제 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
items[].content.nes2tstring조건부·선택과제 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
items[].content.nes3string조건부·선택과제 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다."예시"
items[].content.nes3sstring조건부·선택과제 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
items[].content.nes3tstring조건부·선택과제 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
items[].content.nes4string조건부·선택과제 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다."예시"
items[].content.nes4sstring조건부·선택과제 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
items[].content.nes4tstring조건부·선택과제 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
items[].content.nes5string조건부·선택과제 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다."예시"
items[].content.nes5sstring조건부·선택과제 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
items[].content.nes5tstring조건부·선택과제 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
items[].content.nes6string조건부·선택과제 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다."예시"
items[].content.nes6sstring조건부·선택과제 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
items[].content.nes6tstring조건부·선택과제 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
items[].content.cag1string조건부·선택도전 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다."예시"
items[].content.cag1sstring조건부·선택도전 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
items[].content.cag1tstring조건부·선택도전 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
items[].content.cag2string조건부·선택도전 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다."예시"
items[].content.cag2sstring조건부·선택도전 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
items[].content.cag2tstring조건부·선택도전 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
items[].content.exam1string조건부·선택시험 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다."예시"
items[].content.exam1sstring조건부·선택시험 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
items[].content.exam1tstring조건부·선택시험 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
items[].content.exam2string조건부·선택시험 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다."예시"
items[].content.exam2sstring조건부·선택시험 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
items[].content.exam2tstring조건부·선택시험 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
items[].content.exam3string조건부·선택시험 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다."예시"
items[].content.exam3sstring조건부·선택시험 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
items[].content.exam3tstring조건부·선택시험 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
items[].content.exam4string조건부·선택시험 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다."예시"
items[].content.exam4sstring조건부·선택시험 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
items[].content.exam4tstring조건부·선택시험 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
items[].content.exam5string조건부·선택시험 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다."예시"
items[].content.exam5sstring조건부·선택시험 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
items[].content.exam5tstring조건부·선택시험 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
items[].content.exam6string조건부·선택시험 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다."예시"
items[].content.exam6sstring조건부·선택시험 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
items[].content.exam6tstring조건부·선택시험 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
items[].content.commentstring조건부·선택수업에서 다룬 내용과 공통 안내입니다. 수업 내용은 이 필드에, 숙제는 Nes1 등 과제 항목에 별도로 보존하세요."예시"
items[].content.etc_Titlestring조건부·선택기타 항목 제목입니다."예시"
items[].content.etcstring조건부·선택기타 항목 내용입니다."예시"
items[].content.reexam_Titlestring조건부·선택재검사 표시 제목입니다."예시"
items[].content.hw_Idxinteger조건부·선택GET /v1/grading/exams 응답 data.items[].id에서 선택한 과제 연결 시험 번호입니다. 수업 번호가 아니며 0이면 연결하지 않습니다.0
items[].content.exam_Idx1integer조건부·선택GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 1 번호입니다. OMR 양식 번호가 아니며 0이면 연결하지 않습니다.0
items[].content.exam_Idx2integer조건부·선택GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 2 번호입니다. 0이면 연결하지 않습니다.0
items[].content.exam_Idx3integer조건부·선택GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 3 번호입니다. 0이면 연결하지 않습니다.0
items[].publishedboolean필수학생용 과제장 공개 여부입니다.false
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/lessons/{lessonId}과제장 수업과 항목 상세

teaching.read · teaching.lessons.get

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
teamNamestring필수해당 수업의 실제 수강반 이름입니다. 같은 학원의 반 번호에 연결한 원본 명칭입니다."예시 이름"
onlineRetestIdinteger필수연결된 온라인 재시험 번호입니다. 미연결은 0이며 /teaching/lessons/{lessonId}/retest에서 연결 정보를 조회합니다.1
idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.1
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.1
teacherIdinteger필수GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.1
datestring필수수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다."2026-01-15"
titlestring필수제목입니다."예시"
seasonstring필수기간·학기 구분입니다. 빈 문자열이면 미지정입니다."예시"
orderinteger필수수업 회차입니다. 0 이상입니다.0
contentobject필수과제·시험 항목과 연결 시험 설정입니다. PUT은 전체 내용을 교체합니다.하위 필드·본문 예시 참조
content.nes1string조건부·선택과제 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다."예시"
content.nes1sstring조건부·선택과제 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes1tstring조건부·선택과제 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes2string조건부·선택과제 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다."예시"
content.nes2sstring조건부·선택과제 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes2tstring조건부·선택과제 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes3string조건부·선택과제 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다."예시"
content.nes3sstring조건부·선택과제 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes3tstring조건부·선택과제 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes4string조건부·선택과제 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다."예시"
content.nes4sstring조건부·선택과제 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes4tstring조건부·선택과제 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes5string조건부·선택과제 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다."예시"
content.nes5sstring조건부·선택과제 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes5tstring조건부·선택과제 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes6string조건부·선택과제 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다."예시"
content.nes6sstring조건부·선택과제 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes6tstring조건부·선택과제 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.cag1string조건부·선택도전 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다."예시"
content.cag1sstring조건부·선택도전 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.cag1tstring조건부·선택도전 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.cag2string조건부·선택도전 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다."예시"
content.cag2sstring조건부·선택도전 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.cag2tstring조건부·선택도전 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam1string조건부·선택시험 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다."예시"
content.exam1sstring조건부·선택시험 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam1tstring조건부·선택시험 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam2string조건부·선택시험 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다."예시"
content.exam2sstring조건부·선택시험 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam2tstring조건부·선택시험 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam3string조건부·선택시험 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다."예시"
content.exam3sstring조건부·선택시험 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam3tstring조건부·선택시험 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam4string조건부·선택시험 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다."예시"
content.exam4sstring조건부·선택시험 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam4tstring조건부·선택시험 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam5string조건부·선택시험 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다."예시"
content.exam5sstring조건부·선택시험 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam5tstring조건부·선택시험 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam6string조건부·선택시험 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다."예시"
content.exam6sstring조건부·선택시험 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam6tstring조건부·선택시험 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.commentstring조건부·선택수업에서 다룬 내용과 공통 안내입니다. 수업 내용은 이 필드에, 숙제는 Nes1 등 과제 항목에 별도로 보존하세요."예시"
content.etc_Titlestring조건부·선택기타 항목 제목입니다."예시"
content.etcstring조건부·선택기타 항목 내용입니다."예시"
content.reexam_Titlestring조건부·선택재검사 표시 제목입니다."예시"
content.hw_Idxinteger조건부·선택GET /v1/grading/exams 응답 data.items[].id에서 선택한 과제 연결 시험 번호입니다. 수업 번호가 아니며 0이면 연결하지 않습니다.0
content.exam_Idx1integer조건부·선택GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 1 번호입니다. OMR 양식 번호가 아니며 0이면 연결하지 않습니다.0
content.exam_Idx2integer조건부·선택GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 2 번호입니다. 0이면 연결하지 않습니다.0
content.exam_Idx3integer조건부·선택GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 3 번호입니다. 0이면 연결하지 않습니다.0
publishedboolean필수학생용 과제장 공개 여부입니다.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"
  }
}
Explorer에서 요청 구성 →
POST/v1/teaching/lessons수업·과제장 내용과 숙제 정의 등록(학생별 출석·과제완료는 학생별 결과 변경으로 별도 처리)

teaching.write · teaching.lessons.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.1
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.1
teacherIdinteger필수GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.1
datestring필수수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다."2026-01-15"
titlestring필수수업·과제장 제목입니다. 수강반명과 구별하며 최대 200자입니다."수학 정규 수업"
seasonstring조건부·선택기간·학기 구분입니다. 빈 문자열이면 미지정입니다."예시"
orderinteger조건부·선택수업 회차입니다. 0 이상입니다.0
contentobject필수과제·시험 항목과 연결 시험 설정입니다. PUT은 전체 내용을 교체합니다.하위 필드·본문 예시 참조
content.nes1string조건부·선택과제 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다."예시"
content.nes1sstring조건부·선택과제 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes1tstring조건부·선택과제 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes2string조건부·선택과제 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다."예시"
content.nes2sstring조건부·선택과제 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes2tstring조건부·선택과제 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes3string조건부·선택과제 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다."예시"
content.nes3sstring조건부·선택과제 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes3tstring조건부·선택과제 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes4string조건부·선택과제 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다."예시"
content.nes4sstring조건부·선택과제 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes4tstring조건부·선택과제 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes5string조건부·선택과제 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다."예시"
content.nes5sstring조건부·선택과제 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes5tstring조건부·선택과제 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes6string조건부·선택과제 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다."예시"
content.nes6sstring조건부·선택과제 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes6tstring조건부·선택과제 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.cag1string조건부·선택도전 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다."예시"
content.cag1sstring조건부·선택도전 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.cag1tstring조건부·선택도전 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.cag2string조건부·선택도전 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다."예시"
content.cag2sstring조건부·선택도전 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.cag2tstring조건부·선택도전 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam1string조건부·선택시험 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다."예시"
content.exam1sstring조건부·선택시험 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam1tstring조건부·선택시험 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam2string조건부·선택시험 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다."예시"
content.exam2sstring조건부·선택시험 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam2tstring조건부·선택시험 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam3string조건부·선택시험 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다."예시"
content.exam3sstring조건부·선택시험 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam3tstring조건부·선택시험 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam4string조건부·선택시험 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다."예시"
content.exam4sstring조건부·선택시험 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam4tstring조건부·선택시험 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam5string조건부·선택시험 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다."예시"
content.exam5sstring조건부·선택시험 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam5tstring조건부·선택시험 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam6string조건부·선택시험 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다."예시"
content.exam6sstring조건부·선택시험 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam6tstring조건부·선택시험 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.commentstring조건부·선택수업에서 다룬 내용과 공통 안내입니다. 수업 내용은 이 필드에, 숙제는 Nes1 등 과제 항목에 별도로 보존하세요."예시"
content.etc_Titlestring조건부·선택기타 항목 제목입니다."예시"
content.etcstring조건부·선택기타 항목 내용입니다."예시"
content.reexam_Titlestring조건부·선택재검사 표시 제목입니다."예시"
content.hw_Idxinteger조건부·선택GET /v1/grading/exams 응답 data.items[].id에서 선택한 과제 연결 시험 번호입니다. 수업 번호가 아니며 0이면 연결하지 않습니다.0
content.exam_Idx1integer조건부·선택GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 1 번호입니다. OMR 양식 번호가 아니며 0이면 연결하지 않습니다.0
content.exam_Idx2integer조건부·선택GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 2 번호입니다. 0이면 연결하지 않습니다.0
content.exam_Idx3integer조건부·선택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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/teaching/lessons/{lessonId}수업·과제장 전체 수정

teaching.write · teaching.lessons.update

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.1
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.1
teacherIdinteger필수GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.1
datestring필수수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다."2026-01-15"
titlestring필수수업·과제장 제목입니다. 수강반명과 구별하며 최대 200자입니다."수학 정규 수업"
seasonstring조건부·선택기간·학기 구분입니다. 빈 문자열이면 미지정입니다."예시"
orderinteger조건부·선택수업 회차입니다. 0 이상입니다.0
contentobject필수과제·시험 항목과 연결 시험 설정입니다. PUT은 전체 내용을 교체합니다.하위 필드·본문 예시 참조
content.nes1string조건부·선택과제 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다."예시"
content.nes1sstring조건부·선택과제 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes1tstring조건부·선택과제 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes2string조건부·선택과제 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다."예시"
content.nes2sstring조건부·선택과제 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes2tstring조건부·선택과제 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes3string조건부·선택과제 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다."예시"
content.nes3sstring조건부·선택과제 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes3tstring조건부·선택과제 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes4string조건부·선택과제 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다."예시"
content.nes4sstring조건부·선택과제 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes4tstring조건부·선택과제 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes5string조건부·선택과제 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다."예시"
content.nes5sstring조건부·선택과제 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes5tstring조건부·선택과제 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.nes6string조건부·선택과제 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다."예시"
content.nes6sstring조건부·선택과제 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.nes6tstring조건부·선택과제 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.cag1string조건부·선택도전 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다."예시"
content.cag1sstring조건부·선택도전 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.cag1tstring조건부·선택도전 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.cag2string조건부·선택도전 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다."예시"
content.cag2sstring조건부·선택도전 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.cag2tstring조건부·선택도전 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam1string조건부·선택시험 1 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 1은 시험 문항 번호가 아닙니다."예시"
content.exam1sstring조건부·선택시험 1 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam1tstring조건부·선택시험 1 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam2string조건부·선택시험 2 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 2은 시험 문항 번호가 아닙니다."예시"
content.exam2sstring조건부·선택시험 2 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam2tstring조건부·선택시험 2 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam3string조건부·선택시험 3 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 3은 시험 문항 번호가 아닙니다."예시"
content.exam3sstring조건부·선택시험 3 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam3tstring조건부·선택시험 3 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam4string조건부·선택시험 4 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 4은 시험 문항 번호가 아닙니다."예시"
content.exam4sstring조건부·선택시험 4 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam4tstring조건부·선택시험 4 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam5string조건부·선택시험 5 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 5은 시험 문항 번호가 아닙니다."예시"
content.exam5sstring조건부·선택시험 5 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam5tstring조건부·선택시험 5 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.exam6string조건부·선택시험 6 슬롯의 내용 원문입니다. 화면 항목 제목은 같은 슬롯의 s 필드이고 학생 결과는 values의 같은 키입니다. 숫자 6은 시험 문항 번호가 아닙니다."예시"
content.exam6sstring조건부·선택시험 6 슬롯의 화면 표시 제목입니다. 같은 슬롯의 학생 결과와 연결하며 다른 슬롯 제목을 재사용하지 마세요."예시"
content.exam6tstring조건부·선택시험 6 슬롯의 결과 표시 안내입니다. 단위·범위·만점이 명시되지 않으면 결과값으로 추측하지 마세요."예시"
content.commentstring조건부·선택수업에서 다룬 내용과 공통 안내입니다. 수업 내용은 이 필드에, 숙제는 Nes1 등 과제 항목에 별도로 보존하세요."예시"
content.etc_Titlestring조건부·선택기타 항목 제목입니다."예시"
content.etcstring조건부·선택기타 항목 내용입니다."예시"
content.reexam_Titlestring조건부·선택재검사 표시 제목입니다."예시"
content.hw_Idxinteger조건부·선택GET /v1/grading/exams 응답 data.items[].id에서 선택한 과제 연결 시험 번호입니다. 수업 번호가 아니며 0이면 연결하지 않습니다.0
content.exam_Idx1integer조건부·선택GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 1 번호입니다. OMR 양식 번호가 아니며 0이면 연결하지 않습니다.0
content.exam_Idx2integer조건부·선택GET /v1/grading/exams 응답 data.items[].id에서 선택한 시험 2 번호입니다. 0이면 연결하지 않습니다.0
content.exam_Idx3integer조건부·선택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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/teaching/lessons/{lessonId}수업·과제장 삭제와 연결 출석 정리

teaching.write · teaching.lessons.delete

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/lessons/{lessonId}/absence-candidates목적지 보강 수업 lessonId로 원래 결석 후보 조회(응답 originalLessonId에서 선택)

teaching.read · teaching.absences.list

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수보강생을 추가할 목적지 수업 번호입니다. 원래 결석 수업 번호가 아닙니다. 원래 결석은 absence-candidates 응답 originalLessonId에서 선택합니다.
searchquery필수보강할 학생의 이름 검색어입니다. 1~100자로 반드시 전달하며 빈 문자열은 허용하지 않습니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
[].studentNamestring필수학생 이름입니다."예시 이름"
[].enrollmentIdinteger필수원래 반 수강 등록 번호입니다.1
[].originalTeamIdinteger필수원래 결석한 수강반 번호입니다.1
[].originalLessonIdinteger필수선택할 원래 결석 수업 번호입니다. 보강생 추가 시 반드시 그대로 전달합니다.1
[].datestring필수원래 결석 수업일입니다."2026-01-15"
[].attendanceCodeinteger필수출결 코드입니다. 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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/teaching/lessons/{lessonId}/attendance수업의 저장된 출석부 삭제

teaching.write · teaching.attendance.delete

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
POST/v1/teaching/lessons/{lessonId}/makeups목적지 lessonId에 선택한 원래 결석 originalLessonId를 연결해 보강생(8) 추가·원반 보강완료(7) 처리

teaching.write · teaching.makeups.create

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수보강생을 추가할 목적지 수업 번호입니다. 원래 결석 수업 번호가 아닙니다. 원래 결석은 absence-candidates 응답 originalLessonId에서 선택합니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
originalLessonIdinteger필수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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
countinteger필수정상 처리된 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/lessons/{lessonId}/publication선택 과제장 제목과 현재 학생 공개 상태 조회웹 관리 기능

웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요
teaching.read · teaching.publication.get

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
lessonIdinteger필수과제장 수업 번호입니다.1
titlestring필수선택한 과제장의 실제 제목입니다."예시"
publishedboolean필수현재 학생 공개 여부입니다.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"
  }
}
Explorer에서 요청 구성 →
PATCH/v1/teaching/lessons/{lessonId}/publication학생에게 과제장 공개·비공개 변경(직전 공개 상태 일치 확인·수업 내용 보존)웹 관리 기능

웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요
teaching.write · teaching.publication.update

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
expectedPublishedboolean필수조회한 직전 공개 상태입니다. 생략할 수 없습니다.false
publishedboolean필수학생 공개 여부로 저장할 값입니다. 생략할 수 없습니다.false
요청 JSON 스키마
{
  "type": "object",
  "properties": {
    "expectedPublished": {
      "type": "boolean",
      "description": "조회한 직전 공개 상태입니다. 생략할 수 없습니다.",
      "nullable": true
    },
    "published": {
      "type": "boolean",
      "description": "학생 공개 여부로 저장할 값입니다. 생략할 수 없습니다.",
      "nullable": true
    }
  },
  "required": [
    "expectedPublished",
    "published"
  ]
}

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
lessonIdinteger필수과제장 수업 번호입니다.1
titlestring필수선택한 과제장의 실제 제목입니다."예시"
publishedboolean필수현재 학생 공개 여부입니다.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"
  }
}
Explorer에서 요청 구성 →
PATCH/v1/teaching/lessons/{lessonId}/results수업 학생 출석·결석·검사결과 부분 수정(입퇴실·수강등록 아님). 학생 코멘트는 rows[].values.comment에 전달하고 생략 항목은 보존

teaching.write · teaching.results.update

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
rowsarray필수변경할 학생 배열입니다. 학생 번호는 중복할 수 없으며 저장된 명단의 학생만 가능합니다.하위 필드·본문 예시 참조
rows[].studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
rows[].valuesobject조건부·선택변경할 검사 결과만 전달합니다. 생략한 속성은 기존 값을 유지합니다.하위 필드·본문 예시 참조
rows[].values.nes1string조건부·선택과제 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
rows[].values.nes2string조건부·선택과제 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
rows[].values.nes3string조건부·선택과제 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
rows[].values.nes4string조건부·선택과제 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
rows[].values.nes5string조건부·선택과제 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
rows[].values.nes6string조건부·선택과제 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
rows[].values.cag1string조건부·선택도전 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
rows[].values.cag2string조건부·선택도전 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
rows[].values.exam1string조건부·선택시험 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
rows[].values.exam2string조건부·선택시험 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
rows[].values.exam3string조건부·선택시험 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
rows[].values.exam4string조건부·선택시험 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
rows[].values.exam5string조건부·선택시험 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
rows[].values.exam6string조건부·선택시험 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
rows[].values.etcstring조건부·선택학생별 기타 검사 결과입니다. 생략하면 유지합니다."예시"
rows[].values.commentstring조건부·선택학생별 수업 메모입니다. yyyy-MM-dd HH:mm 날짜를 포함하면 기존 규칙으로 재검사 일정을 인식합니다."예시"
rows[].values.re_Exam1boolean조건부·선택시험 1의 재시험 대상 여부입니다. 생략하면 유지합니다.false
rows[].values.re_Exam_Result1string조건부·선택시험 1 재시험 결과입니다. 생략하면 유지합니다."예시"
rows[].values.re_Exam2boolean조건부·선택시험 2의 재시험 대상 여부입니다. 생략하면 유지합니다.false
rows[].values.re_Exam_Result2string조건부·선택시험 2 재시험 결과입니다. 생략하면 유지합니다."예시"
rows[].values.re_Exam3boolean조건부·선택시험 3의 재시험 대상 여부입니다. 생략하면 유지합니다.false
rows[].values.re_Exam_Result3string조건부·선택시험 3 재시험 결과입니다. 생략하면 유지합니다."예시"
rows[].attendanceCodeinteger조건부·선택출결 코드입니다. 0 무결(무단결석), 4 인정결석(인결), 5 출석, 6 인강, 7 보강완료, 8 타반에서 온 보강생입니다. 생략하면 출결은 유지합니다.0
rows[].makeupIdinteger조건부·선택출결을 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
countinteger필수정상 처리된 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
POST/v1/teaching/lessons/{lessonId}/score-sync연결된 OMR 점수를 과제장에 동기화

teaching.write · teaching.scores.sync

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
countinteger필수정상 처리된 자료 수입니다.1
응답 data JSON 스키마
{
  "type": "object",
  "properties": {
    "count": {
      "type": "integer",
      "description": "정상 처리된 자료 수입니다.",
      "nullable": false
    }
  },
  "required": [
    "count"
  ]
}

성공 응답 예시

{
  "data": {
    "count": 1
  },
  "meta": {
    "requestId": "example-request-id"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/lessons/{lessonId}/students수업 목록의 lessonId로 저장된 출석·검사 조회(반·시간표 번호 아님, 빈 명단은 roster.add 후 기록)

teaching.read · teaching.roster.get

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].teamNamestring필수해당 수업의 실제 수강반 이름입니다. 학생의 다른 반이나 보강 원래 반의 이름이 아닙니다."예시 이름"
[].idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
[].lessonIdinteger필수과제장 수업 번호입니다.1
[].studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
[].studentNamestring필수학생 이름입니다."예시 이름"
[].attendanceCodeinteger필수출결 코드입니다. 0 무결(무단결석), 4 인정결석(인결), 5 출석, 6 인강, 7 보강완료, 8 타반에서 온 보강생입니다.1
[].absentboolean필수무결 또는 인정결석이면 true입니다.false
[].originalTeamIdinteger필수보강생의 원래 반 번호입니다. 일반 학생과 보강완료 학생은 0입니다.1
[].originalLessonIdinteger필수보강 연결의 원래 결석 수업 번호입니다. 연결이 없으면 0입니다.1
[].valuesobject필수과제·시험 결과와 메모입니다.하위 필드·본문 예시 참조
[].values.nes1string조건부·선택과제 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
[].values.nes2string조건부·선택과제 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
[].values.nes3string조건부·선택과제 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
[].values.nes4string조건부·선택과제 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
[].values.nes5string조건부·선택과제 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
[].values.nes6string조건부·선택과제 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
[].values.cag1string조건부·선택도전 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
[].values.cag2string조건부·선택도전 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
[].values.exam1string조건부·선택시험 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
[].values.exam2string조건부·선택시험 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
[].values.exam3string조건부·선택시험 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
[].values.exam4string조건부·선택시험 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
[].values.exam5string조건부·선택시험 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
[].values.exam6string조건부·선택시험 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
[].values.etcstring조건부·선택학생별 기타 검사 결과입니다. 생략하면 유지합니다."예시"
[].values.commentstring조건부·선택학생별 수업 메모입니다. yyyy-MM-dd HH:mm 날짜를 포함하면 기존 규칙으로 재검사 일정을 인식합니다."예시"
[].values.re_Exam1boolean조건부·선택시험 1의 재시험 대상 여부입니다. 생략하면 유지합니다.false
[].values.re_Exam_Result1string조건부·선택시험 1 재시험 결과입니다. 생략하면 유지합니다."예시"
[].values.re_Exam2boolean조건부·선택시험 2의 재시험 대상 여부입니다. 생략하면 유지합니다.false
[].values.re_Exam_Result2string조건부·선택시험 2 재시험 결과입니다. 생략하면 유지합니다."예시"
[].values.re_Exam3boolean조건부·선택시험 3의 재시험 대상 여부입니다. 생략하면 유지합니다.false
[].values.re_Exam_Result3string조건부·선택시험 3 재시험 결과입니다. 생략하면 유지합니다."예시"
[].valueItemsarray필수같은 수업의 항목 제목·결과 안내·슬롯 번호와 학생 결과를 명시적으로 연결한 읽기 전용 자료입니다. 배열 순서로 의미나 단위를 추정하지 마세요. 수정할 때는 field에 대응하는 values 필드를 사용하세요.하위 필드·본문 예시 참조
[].valueItems[].fieldstring필수저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요."예시"
[].valueItems[].categorystring필수과제, 도전, 시험 중 항목 종류입니다."예시"
[].valueItems[].positioninteger필수같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다.1
[].valueItems[].titlestring필수같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요."예시"
[].valueItems[].contentstring필수같은 수업 설정의 과제·시험 내용 원문입니다."예시"
[].valueItems[].resultGuidestring필수같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요."예시"
[].valueItems[].valuestring필수해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다."예시"
[].valueItems[].valueStatestring필수present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다."예시"
[].valueItems[].examIdinteger필수같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다.1
[].attendanceNamestring필수attendanceCode와 같은 원본 코드표의 출결 명칭입니다."예시 이름"
[].datestring필수수업 등록일입니다. yyyy-MM-dd 형식입니다."2026-01-15"
[].teamIdinteger필수해당 수업의 수강반 번호입니다.1
[].scheduleIdinteger필수수업 시간표 번호입니다.1
[].teacherIdinteger필수담당 선생님 번호입니다.1
[].titlestring필수수업·과제장 제목입니다."예시"
[].seasonstring필수학기·기간 구분입니다."예시"
[].orderinteger필수수업 회차입니다.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"
  }
}
Explorer에서 요청 구성 →
POST/v1/teaching/lessons/{lessonId}/students수강 등록에서 선택한 일반 학생을 출석부에 추가

teaching.write · teaching.roster.add

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdsarray필수해당 반에 유효하게 수강 등록된 학생 번호입니다. 기존 명단에 없는 학생만 추가합니다. 보강생은 별도 API를 사용합니다.하위 필드·본문 예시 참조
요청 JSON 스키마
{
  "type": "object",
  "properties": {
    "studentIds": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "해당 반에 유효하게 수강 등록된 학생 번호입니다. 기존 명단에 없는 학생만 추가합니다. 보강생은 별도 API를 사용합니다.",
      "nullable": false,
      "minItems": 1,
      "maxItems": 100
    }
  },
  "required": [
    "studentIds"
  ]
}

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
countinteger필수정상 처리된 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/teaching/lessons/{lessonId}/students/{studentId}명단 학생 삭제(연결된 원래 결석 복원)

teaching.write · teaching.roster.delete

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수GET /v1/teaching/lessons 응답 data.items[].id의 수업·과제장 번호입니다.
studentIdpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/lessons/{lessonId}/students/{studentId}/makeup-candidates보강완료 연결 후보(같은 학생·타반·수업일 ±10일)

teaching.read · teaching.makeups.list

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수보강완료로 연결하려는 원래 결석 수업 번호입니다. 다른 반에서 수업한 보강생 기록 후보를 조회합니다.
studentIdpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
[].lessonIdinteger필수타반 보강 수업 번호입니다.1
[].datestring필수보강 수업일입니다. 원래 수업일 전후 10일 이내입니다."2026-01-15"
[].teamNamestring필수보강을 받은 수강반 이름입니다."예시 이름"
[].originalLessonIdinteger필수현재 연결된 원래 결석 수업 번호입니다. 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/lessons/{lessonId}/students/{studentId}/makeup-link원래 수업의 현재 보강 연결·복원 출결 조회(해제 전 필수 확인)

teaching.read · teaching.makeups.link.get

경로 · 검색 파라미터

이름위치필수설명
lessonIdpath필수보강완료로 처리된 원래 수업 번호입니다. 연결된 보강 수업을 조회한 뒤 그 연결만 해제합니다. 목적지 수업 번호가 아닙니다.
studentIdpath필수GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring필수조회한 학생 번호입니다."00000001"
studentNamestring필수조회한 학생 이름입니다."예시 이름"
originalLessonIdinteger필수보강완료로 처리된 원래 수업 번호입니다.1
originalTeamNamestring필수원래 수업의 수강반 이름입니다."예시 이름"
incomingTeamNamestring필수보강 수업의 수강반 이름입니다."예시 이름"
originalDatestring필수원래 수업일입니다."2026-01-15"
incomingDatestring필수보강 수업일입니다."2026-01-15"
originalRecordIdinteger필수보강 연결 조회에서 받은 원래 출결 행 번호입니다.1
incomingRecordIdinteger필수보강 연결 조회에서 받은 보강생 출결 행 번호입니다. 행은 삭제하지 않습니다.1
incomingLessonIdinteger필수보강 연결 조회에서 받은 보강 목적지 수업 번호입니다.1
originalAttendanceCodeinteger필수연결 시 보존한 원래 출결 코드입니다. 0 무결, 4 인정결석, 5 출석, 6 인강만 복원 가능합니다.0
versionstring필수보강 연결 조회에서 받은 최신 원본 확인값입니다. 수정하거나 생성하지 마세요."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/options/copy-sources담당 선생님의 복사 원본 과제장 선택 목록(조회만 하며 새 과제장을 만들지 않음)

teaching.read · teaching.options.copy

경로 · 검색 파라미터

이름위치필수설명
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idstring필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다."1"
[].namestring필수이름 또는 표시 명칭입니다."예시 이름"
응답 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/options/exams과제장의 시험 항목에 연결 가능한 담당 선생님의 채점지 이름과 번호

teaching.read · teaching.options.exams

경로 · 검색 파라미터

이름위치필수설명
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idstring필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다."1"
[].namestring필수이름 또는 표시 명칭입니다."예시 이름"
응답 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/options/seasons실제 저장된 과제장 학기·기간 선택 목록

teaching.read · teaching.options.seasons

경로 · 검색 파라미터

이름위치필수설명
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
응답 data JSON 스키마
{
  "type": "array",
  "items": {
    "type": "string"
  }
}

성공 응답 예시

{
  "data": [
    "예시"
  ],
  "meta": {
    "requestId": "example-request-id"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/options/teachers과제장 등록에서 실제 선택 가능한 담당 선생님 이름과 번호

teaching.read · teaching.options.teachers

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idstring필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다."1"
[].namestring필수이름 또는 표시 명칭입니다."예시 이름"
응답 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/options/templates공유 템플릿 불러오기에서 실제 선택 가능한 과제장 목록

teaching.read · teaching.options.templates

경로 · 검색 파라미터

이름위치필수설명
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idstring필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다."1"
[].namestring필수이름 또는 표시 명칭입니다."예시 이름"
응답 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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/teaching/seasons선택 과제장의 학기·기간 일괄 변경

teaching.write · teaching.season.update

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
lessonIdsarray필수GET /v1/teaching/lessons 응답 data.items[].id에서 선택한 과제장 번호들을 배열로 전달합니다. 중복 없이 1~100개입니다.하위 필드·본문 예시 참조
seasonstring조건부·선택변경할 학기·기간 구분입니다. 빈 문자열은 미지정입니다."예시"
요청 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
countinteger필수정상 처리된 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/teams/{id}/course반별 과제장 분류·교과·저장 양식과 실제 적용 양식 조회(시간표 자동 선택 없음)

teaching.read · teaching.options.course

경로 · 검색 파라미터

이름위치필수설명
idpath필수대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
teamIdinteger필수수강반 번호입니다.1
teamNamestring필수실제 수강반 이름입니다."예시 이름"
classstring필수저장된 과제장 분류입니다."예시"
groupstring필수저장된 교과 그룹입니다."예시"
apiFlaginteger필수수강반의 저장된 과제장 사용 구분입니다.1
reportinteger필수현재 과제장 성적표 양식 번호입니다. 0은 미설정 값입니다.1
versionstring필수변경 전 다시 확인해야 하는 현재 설정의 검증 값입니다."예시"
effectiveReportinteger필수실제 적용되는 과제장 성적표 양식입니다. 82는 누적형이며, 미지정 0을 포함한 나머지는 관리자 화면과 동일한 당일형 80입니다. 저장된 report는 바꾸지 않습니다.1
storedReportNamestring필수저장된 양식의 이름입니다. 0은 미지정이며, 미지정 상태에서도 실제 적용 양식은 당일형입니다."예시 이름"
reportNamestring필수실제 적용 양식 이름입니다. 당일형 또는 누적형입니다."예시 이름"
응답 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/teams/{id}/registration-defaults반별 최근 학기·다음 회차와 실제 시간표에서 계산한 다음 수업일 후보(저장·자동 지정 없음)

teaching.read · teaching.options.defaults

경로 · 검색 파라미터

이름위치필수설명
idpath필수대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
teamIdinteger필수선택 수강반 번호입니다.1
lastSeasonstring필수최근 등록한 과제장의 학기입니다. 없으면 빈 값입니다."예시"
nextOrderinteger필수해당 반의 최대 회차 다음 값입니다.1
suggestedDatestring필수실제 시간표로 계산한 다음 수업일 후보입니다. 없으면 null이며 사용자 확인 없이 저장하지 않습니다."2026-01-15"
suggestedScheduleIdinteger필수후보 수업일에 해당하는 실제 시간표 번호입니다. 후보가 없으면 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/teams/{id}/schedules선택 수강반의 실제 시간표 목록(요일에 맞는 시간표를 임의 지정하지 않음)

teaching.read · teaching.options.schedules

경로 · 검색 파라미터

이름위치필수설명
idpath필수대상 목록 조회 응답의 id입니다. 이름이나 직접 생성한 번호가 아닙니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idinteger필수자원의 고유 식별값입니다. 학생 번호는 문자열, 일반 자료 번호는 정수, 파일·작업·링크 번호는 UUID 문자열입니다.1
[].teamIdinteger필수수강반 고유 번호입니다. 수강반 조회에서 확인합니다.1
[].daystring필수요일입니다. 월·화·수·목·금·토·일 중 하나입니다."월"
[].fromstring필수수업 시작 시각입니다. HHmm 형식입니다."2026-01-15"
[].tostring필수수업 종료 시각입니다. HHmm 형식이며 시작 시각보다 늦어야 합니다."2026-01-15"
[].beginDatestring필수시간표 적용 시작일입니다. yyyyMMdd 문자열이며 0은 미설정입니다."2026-01-15"
[].endDatestring필수시간표 적용 종료일입니다. yyyyMMdd 문자열이며 0은 미설정입니다."2026-01-15"
[].kindinteger필수시간표 종류입니다. 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/todos기간별 재검사 일정 목록

teaching.read · teaching.todos.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
teamIdquery선택GET /v1/teams 응답 data.items[].id의 정수 번호로 결과를 제한합니다. 검색 조건에서 생략하면 전체 반입니다.
fromquery필수조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery필수조회 종료일입니다. yyyy-MM-dd 형식입니다.
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
items[].lessonIdinteger필수재검사 일정의 원래 과제장 번호입니다.1
items[].studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
items[].studentNamestring필수학생 이름입니다."예시 이름"
items[].plannedAtstring필수재검사 예정일시입니다. 시간이 없으면 yyyy-MM-dd, 있으면 yyyy-MM-ddTHH:mm입니다."예시"
items[].commentstring필수재검사 메모입니다."예시"
items[].statusstring필수예약·완료·취소·불참·변경 중 처리 상태입니다."예시"
items[].teamIdinteger필수원래 수업의 수강반 번호입니다.1
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/todos/{todoId}재검사 일정 상세

teaching.read · teaching.todos.get

경로 · 검색 파라미터

이름위치필수설명
todoIdpath필수GET /v1/teaching/todos 응답 data.items[].id의 재검사 기록 번호입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
lessonIdinteger필수재검사 일정의 원래 과제장 번호입니다.1
studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
studentNamestring필수학생 이름입니다."예시 이름"
plannedAtstring필수재검사 예정일시입니다. 시간이 없으면 yyyy-MM-dd, 있으면 yyyy-MM-ddTHH:mm입니다."예시"
commentstring필수재검사 메모입니다."예시"
statusstring필수예약·완료·취소·불참·변경 중 처리 상태입니다."예시"
teamIdinteger필수원래 수업의 수강반 번호입니다.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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/teaching/todos/{todoId}재검사 메모·날짜·처리 결과 저장

teaching.write · teaching.todos.update

경로 · 검색 파라미터

이름위치필수설명
todoIdpath필수GET /v1/teaching/todos 응답 data.items[].id의 재검사 기록 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
commentstring조건부·선택재검사 메모입니다. 일정 변경은 yyyy-MM-dd HH:mm 날짜를 포함합니다. 날짜가 없으면 일정을 지웁니다."예시"
statusstring조건부·선택예약·완료·취소·불참·변경 또는 빈 문자열입니다."예시"
요청 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/cumulative-results기간별 누적 과제·시험·출결 결과. valueItems가 같은 수업의 제목·슬롯·표시 안내·결과를 연결. 값만으로 만점·단위를 추측하지 않음

teaching.read · teaching.cumulative.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
teamIdquery선택GET /v1/teams 응답 data.items[].id의 정수 번호로 결과를 제한합니다. 검색 조건에서 생략하면 전체 반입니다.
fromquery필수조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery필수조회 종료일입니다. yyyy-MM-dd 형식입니다.
scheduleIdquery선택GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다.
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.
studentIdquery선택GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].teamNamestring필수해당 수업의 실제 수강반 이름입니다. 학생의 다른 반이나 보강 원래 반의 이름이 아닙니다."예시 이름"
items[].idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
items[].lessonIdinteger필수과제장 수업 번호입니다.1
items[].studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
items[].studentNamestring필수학생 이름입니다."예시 이름"
items[].attendanceCodeinteger필수출결 코드입니다. 0 무결(무단결석), 4 인정결석(인결), 5 출석, 6 인강, 7 보강완료, 8 타반에서 온 보강생입니다.1
items[].absentboolean필수무결 또는 인정결석이면 true입니다.false
items[].originalTeamIdinteger필수보강생의 원래 반 번호입니다. 일반 학생과 보강완료 학생은 0입니다.1
items[].originalLessonIdinteger필수보강 연결의 원래 결석 수업 번호입니다. 연결이 없으면 0입니다.1
items[].valuesobject필수과제·시험 결과와 메모입니다.하위 필드·본문 예시 참조
items[].values.nes1string조건부·선택과제 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.nes2string조건부·선택과제 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.nes3string조건부·선택과제 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.nes4string조건부·선택과제 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.nes5string조건부·선택과제 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.nes6string조건부·선택과제 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.cag1string조건부·선택도전 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.cag2string조건부·선택도전 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.exam1string조건부·선택시험 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.exam2string조건부·선택시험 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.exam3string조건부·선택시험 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.exam4string조건부·선택시험 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.exam5string조건부·선택시험 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.exam6string조건부·선택시험 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.etcstring조건부·선택학생별 기타 검사 결과입니다. 생략하면 유지합니다."예시"
items[].values.commentstring조건부·선택학생별 수업 메모입니다. yyyy-MM-dd HH:mm 날짜를 포함하면 기존 규칙으로 재검사 일정을 인식합니다."예시"
items[].values.re_Exam1boolean조건부·선택시험 1의 재시험 대상 여부입니다. 생략하면 유지합니다.false
items[].values.re_Exam_Result1string조건부·선택시험 1 재시험 결과입니다. 생략하면 유지합니다."예시"
items[].values.re_Exam2boolean조건부·선택시험 2의 재시험 대상 여부입니다. 생략하면 유지합니다.false
items[].values.re_Exam_Result2string조건부·선택시험 2 재시험 결과입니다. 생략하면 유지합니다."예시"
items[].values.re_Exam3boolean조건부·선택시험 3의 재시험 대상 여부입니다. 생략하면 유지합니다.false
items[].values.re_Exam_Result3string조건부·선택시험 3 재시험 결과입니다. 생략하면 유지합니다."예시"
items[].valueItemsarray필수같은 수업의 항목 제목·결과 안내·슬롯 번호와 학생 결과를 명시적으로 연결한 읽기 전용 자료입니다. 배열 순서로 의미나 단위를 추정하지 마세요. 수정할 때는 field에 대응하는 values 필드를 사용하세요.하위 필드·본문 예시 참조
items[].valueItems[].fieldstring필수저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요."예시"
items[].valueItems[].categorystring필수과제, 도전, 시험 중 항목 종류입니다."예시"
items[].valueItems[].positioninteger필수같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다.1
items[].valueItems[].titlestring필수같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요."예시"
items[].valueItems[].contentstring필수같은 수업 설정의 과제·시험 내용 원문입니다."예시"
items[].valueItems[].resultGuidestring필수같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요."예시"
items[].valueItems[].valuestring필수해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다."예시"
items[].valueItems[].valueStatestring필수present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다."예시"
items[].valueItems[].examIdinteger필수같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다.1
items[].attendanceNamestring필수attendanceCode와 같은 원본 코드표의 출결 명칭입니다."예시 이름"
items[].datestring필수수업 등록일입니다. yyyy-MM-dd 형식입니다."2026-01-15"
items[].teamIdinteger필수해당 수업의 수강반 번호입니다.1
items[].scheduleIdinteger필수수업 시간표 번호입니다.1
items[].teacherIdinteger필수담당 선생님 번호입니다.1
items[].titlestring필수수업·과제장 제목입니다."예시"
items[].seasonstring필수학기·기간 구분입니다."예시"
items[].orderinteger필수수업 회차입니다.1
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/attendance/checks학생 입퇴실 체크 내역

attendance.read · attendance.checks.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
fromquery필수조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery필수조회 종료일입니다. yyyy-MM-dd 형식입니다.
studentIdquery선택GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
items[].studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
items[].studentNamestring필수학생 이름입니다."예시 이름"
items[].dateinteger필수입퇴실 확인일입니다. yyyyMMdd 정수입니다.20260115
items[].timestring필수한국 시간 HH:mm입니다."14:00"
items[].kindinteger필수입실 0, 퇴실 1입니다.1
items[].sourceinteger필수기존 패드와 호환되는 확인 경로 코드입니다.1
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
POST/v1/attendance/checks현재 시각 입실·퇴실 기록(수업 출석 아님·발송 없음)

attendance.write · attendance.checks.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
kindinteger조건부·선택입실은 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/attendance/checks/{checkId}학생 입퇴실 기록 삭제

attendance.write · attendance.checks.delete

경로 · 검색 파라미터

이름위치필수설명
checkIdpath필수GET /v1/attendance/checks 응답 data.items[].id의 입퇴실 기록 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/attendance/daily반·날짜별 학생 이름·출결 상태·검사 조회. teamId와 from/to로 직접 조회하며 lessonId 불필요. 출결 단순 조회에 우선 사용

attendance.read · attendance.daily.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
teamIdquery선택GET /v1/teams 응답 data.items[].id의 정수 번호로 결과를 제한합니다. 검색 조건에서 생략하면 전체 반입니다.
fromquery필수조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery필수조회 종료일입니다. yyyy-MM-dd 형식입니다.
scheduleIdquery선택GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다.
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.
studentIdquery선택GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].teamNamestring필수해당 수업의 실제 수강반 이름입니다. 학생의 다른 반이나 보강 원래 반의 이름이 아닙니다."예시 이름"
items[].idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
items[].lessonIdinteger필수과제장 수업 번호입니다.1
items[].studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
items[].studentNamestring필수학생 이름입니다."예시 이름"
items[].attendanceCodeinteger필수출결 코드입니다. 0 무결(무단결석), 4 인정결석(인결), 5 출석, 6 인강, 7 보강완료, 8 타반에서 온 보강생입니다.1
items[].absentboolean필수무결 또는 인정결석이면 true입니다.false
items[].originalTeamIdinteger필수보강생의 원래 반 번호입니다. 일반 학생과 보강완료 학생은 0입니다.1
items[].originalLessonIdinteger필수보강 연결의 원래 결석 수업 번호입니다. 연결이 없으면 0입니다.1
items[].valuesobject필수과제·시험 결과와 메모입니다.하위 필드·본문 예시 참조
items[].values.nes1string조건부·선택과제 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.nes2string조건부·선택과제 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.nes3string조건부·선택과제 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.nes4string조건부·선택과제 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.nes5string조건부·선택과제 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.nes6string조건부·선택과제 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.cag1string조건부·선택도전 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.cag2string조건부·선택도전 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.exam1string조건부·선택시험 1 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.exam2string조건부·선택시험 2 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.exam3string조건부·선택시험 3 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.exam4string조건부·선택시험 4 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.exam5string조건부·선택시험 5 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.exam6string조건부·선택시험 6 검사 결과입니다. null 또는 생략하면 기존 값을 유지하고 빈 문자열은 값을 지웁니다."예시"
items[].values.etcstring조건부·선택학생별 기타 검사 결과입니다. 생략하면 유지합니다."예시"
items[].values.commentstring조건부·선택학생별 수업 메모입니다. yyyy-MM-dd HH:mm 날짜를 포함하면 기존 규칙으로 재검사 일정을 인식합니다."예시"
items[].values.re_Exam1boolean조건부·선택시험 1의 재시험 대상 여부입니다. 생략하면 유지합니다.false
items[].values.re_Exam_Result1string조건부·선택시험 1 재시험 결과입니다. 생략하면 유지합니다."예시"
items[].values.re_Exam2boolean조건부·선택시험 2의 재시험 대상 여부입니다. 생략하면 유지합니다.false
items[].values.re_Exam_Result2string조건부·선택시험 2 재시험 결과입니다. 생략하면 유지합니다."예시"
items[].values.re_Exam3boolean조건부·선택시험 3의 재시험 대상 여부입니다. 생략하면 유지합니다.false
items[].values.re_Exam_Result3string조건부·선택시험 3 재시험 결과입니다. 생략하면 유지합니다."예시"
items[].valueItemsarray필수같은 수업의 항목 제목·결과 안내·슬롯 번호와 학생 결과를 명시적으로 연결한 읽기 전용 자료입니다. 배열 순서로 의미나 단위를 추정하지 마세요. 수정할 때는 field에 대응하는 values 필드를 사용하세요.하위 필드·본문 예시 참조
items[].valueItems[].fieldstring필수저장 필드 키입니다. 예: Nes1, Exam1. 표시 순서나 다른 필드와 혼동하지 마세요."예시"
items[].valueItems[].categorystring필수과제, 도전, 시험 중 항목 종류입니다."예시"
items[].valueItems[].positioninteger필수같은 종류 안의 1부터 시작하는 슬롯 번호입니다. 시험 문항 번호가 아닙니다.1
items[].valueItems[].titlestring필수같은 수업 설정의 실제 항목 제목입니다. 빈 값은 제목 미설정이며 결과값으로 제목을 만들지 마세요."예시"
items[].valueItems[].contentstring필수같은 수업 설정의 과제·시험 내용 원문입니다."예시"
items[].valueItems[].resultGuidestring필수같은 수업 설정의 결과 표시 안내 원문입니다. 단위·만점이 없으면 값만 보고 점수·백분율로 추정하지 마세요."예시"
items[].valueItems[].valuestring필수해당 학생의 저장 결과 원문입니다. 숫자처럼 보여도 점수·비율인지 추정하지 마세요. null은 값 없음, 빈 문자열은 저장 빈 값입니다."예시"
items[].valueItems[].valueStatestring필수present=값 있음, blank=빈 값, missing=값 없음입니다. 0은 빈 값이 아닙니다."예시"
items[].valueItems[].examIdinteger필수같은 슬롯에 명시적으로 연결된 정답지 번호입니다. 0은 연결 없음이며 다른 시험 번호를 재사용하지 않습니다.1
items[].attendanceNamestring필수attendanceCode와 같은 원본 코드표의 출결 명칭입니다."예시 이름"
items[].datestring필수수업 등록일입니다. yyyy-MM-dd 형식입니다."2026-01-15"
items[].teamIdinteger필수해당 수업의 수강반 번호입니다.1
items[].scheduleIdinteger필수수업 시간표 번호입니다.1
items[].teacherIdinteger필수담당 선생님 번호입니다.1
items[].titlestring필수수업·과제장 제목입니다."예시"
items[].seasonstring필수학기·기간 구분입니다."예시"
items[].orderinteger필수수업 회차입니다.1
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/attendance/students기간 내 전체 또는 선택 반의 학생별 출결 합계·결석 학생 명단 조회. 무결·유결 합계로 결석 구분, 타반 보강생 제외

attendance.read · attendance.students.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
teamIdquery선택GET /v1/teams 응답 data.items[].id의 정수 번호로 결과를 제한합니다. 검색 조건에서 생략하면 전체 반입니다.
fromquery필수조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery필수조회 종료일입니다. yyyy-MM-dd 형식입니다.
scheduleIdquery선택GET /v1/teams/{teamId}/schedules 응답 data[].id 중 해당 반의 시간표 번호입니다.
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.
studentIdquery선택GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
items[].studentNamestring필수학생 이름입니다."예시 이름"
items[].totalinteger필수조회 기간의 일반 출석 기록 수입니다. 타반에서 온 보강생 기록은 제외합니다.1
items[].unexcusedinteger필수무결 횟수입니다.1
items[].excusedinteger필수인정결석 횟수입니다.1
items[].presentinteger필수출석 횟수입니다.1
items[].videointeger필수인강 횟수입니다.1
items[].makeupCompletedinteger필수원래 반에서 보강완료로 연결된 횟수입니다.1
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/clinic-appointments클리닉 실제 예약·입실·퇴실·불참·취소 학생 명단 조회(상태 동기화나 메시지 발송 없음)

teaching.read · clinic.appointments.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
fromquery필수조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery필수조회 종료일입니다. yyyy-MM-dd 형식입니다.
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.
studentIdquery선택GET /v1/students 응답 data.items[].id의 학생 번호 문자열입니다. 앞자리 0을 유지합니다. 검색 조건에서 생략하면 전체 학생입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].idinteger필수예약 학생 기록 번호입니다.1
items[].clinicIdinteger필수클리닉 일정 번호입니다.1
items[].studentIdstring필수학생 번호입니다."00000001"
items[].studentNamestring필수실제 학생 이름입니다."예시 이름"
items[].teacherIdinteger필수예약 담당 선생님 번호입니다.1
items[].titlestring필수클리닉 일정 이름입니다."예시"
items[].startsAtstring필수저장된 한국 시각 기준 예약 일시입니다."예시"
items[].statusstring필수저장된 예약·입실·퇴실·불참 상태입니다."예시"
items[].cancelledAtstring필수예약 취소 일시입니다. 미취소이면 null입니다."2026-01-15T00:00:00Z"
items[].enteredAtstring필수저장된 입실 일시입니다."2026-01-15T00:00:00Z"
items[].exitedAtstring필수저장된 퇴실 일시입니다."2026-01-15T00:00:00Z"
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/clinic-message-templates클리닉 문자 작성에서 저장된 문구 목록 조회(발송 없음)웹 관리 기능

웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요
teaching.read · clinic.templates.message

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idinteger필수저장된 문구 번호입니다.1
[].titlestring필수저장된 문구 제목입니다."예시"
[].categorystring필수문구의 분류명입니다."예시"
[].contentstring필수저장된 원문입니다. 조회만으로 치환하거나 발송하지 않습니다."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/clinic-review-templates클리닉 리뷰 등록에서 저장된 리뷰 문구 목록 조회

teaching.read · clinic.templates.review

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idinteger필수저장된 문구 번호입니다.1
[].titlestring필수저장된 문구 제목입니다."예시"
[].categorystring필수문구의 분류명입니다."예시"
[].contentstring필수저장된 원문입니다. 조회만으로 치환하거나 발송하지 않습니다."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/clinic-reviews기간별 클리닉 리뷰 목록

teaching.read · teaching.clinics.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
teamIdquery선택GET /v1/teams 응답 data.items[].id의 정수 번호로 결과를 제한합니다. 검색 조건에서 생략하면 전체 반입니다.
fromquery필수조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery필수조회 종료일입니다. yyyy-MM-dd 형식입니다.
teacherIdquery선택GET /v1/teams/teachers 응답 data[].id의 선생님 번호입니다. 검색 조건에서 0 또는 생략은 전체입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
items[].studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
items[].studentNamestring필수학생 이름입니다."예시 이름"
items[].teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.1
items[].scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.1
items[].teacherIdinteger필수GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.1
items[].datestring필수수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다."2026-01-15"
items[].timestring필수클리닉 시각입니다. HH:mm 또는 빈 문자열입니다."14:00"
items[].lessonIdinteger필수연결된 과제장 번호입니다.1
items[].titlestring필수제목입니다."예시"
items[].reviewstring필수클리닉 리뷰 본문입니다."예시"
items[].memostring필수내부 메모입니다."예시"
items[].statusstring필수클리닉 처리 결과입니다."예시"
items[].nextDatestring필수변경 일자입니다."2026-01-15"
items[].retestboolean필수재시험 여부입니다.false
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/teaching/clinic-reviews/{reviewId}클리닉 리뷰 상세

teaching.read · teaching.clinics.get

경로 · 검색 파라미터

이름위치필수설명
reviewIdpath필수GET /v1/teaching/clinic-reviews 응답 data.items[].id의 클리닉 리뷰 번호입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
studentNamestring필수학생 이름입니다."예시 이름"
teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.1
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.1
teacherIdinteger필수GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.1
datestring필수수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다."2026-01-15"
timestring필수클리닉 시각입니다. HH:mm 또는 빈 문자열입니다."14:00"
lessonIdinteger필수연결된 과제장 번호입니다.1
titlestring필수제목입니다."예시"
reviewstring필수클리닉 리뷰 본문입니다."예시"
memostring필수내부 메모입니다."예시"
statusstring필수클리닉 처리 결과입니다."예시"
nextDatestring필수변경 일자입니다."2026-01-15"
retestboolean필수재시험 여부입니다.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"
  }
}
Explorer에서 요청 구성 →
POST/v1/teaching/clinic-reviews클리닉 리뷰 등록

teaching.write · teaching.clinics.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.1
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.1
teacherIdinteger필수GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.1
datestring필수수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다."2026-01-15"
timestring조건부·선택클리닉 시각입니다. HH:mm 형식이며 빈 문자열이면 미지정입니다."14:00"
lessonIdinteger조건부·선택연결된 과제장 번호입니다. 0이면 독립 리뷰입니다.0
titlestring필수제목입니다."예시"
reviewstring조건부·선택클리닉 리뷰 본문입니다. 일반 텍스트로 입력합니다."예시"
memostring조건부·선택내부 메모입니다."예시"
statusstring조건부·선택클리닉 처리 결과입니다. 예약·입실·완료·취소·불참·변경 또는 빈 문자열입니다."예시"
nextDatestring조건부·선택변경된 클리닉 일자입니다. 빈 문자열이면 수업일을 사용합니다."2026-01-15"
retestboolean조건부·선택재시험 대상 여부입니다.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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/teaching/clinic-reviews/{reviewId}클리닉 리뷰 전체 수정

teaching.write · teaching.clinics.update

경로 · 검색 파라미터

이름위치필수설명
reviewIdpath필수GET /v1/teaching/clinic-reviews 응답 data.items[].id의 클리닉 리뷰 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
teamIdinteger필수GET /v1/teams 응답 data.items[].id에서 선택한 수강반 번호입니다. 반 이름이 아닌 정수 id를 전달합니다.1
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.1
teacherIdinteger필수GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.1
datestring필수수업 또는 처리 날짜입니다. yyyy-MM-dd 형식의 한국 날짜입니다."2026-01-15"
timestring조건부·선택클리닉 시각입니다. HH:mm 형식이며 빈 문자열이면 미지정입니다."14:00"
lessonIdinteger조건부·선택연결된 과제장 번호입니다. 0이면 독립 리뷰입니다.0
titlestring필수제목입니다."예시"
reviewstring조건부·선택클리닉 리뷰 본문입니다. 일반 텍스트로 입력합니다."예시"
memostring조건부·선택내부 메모입니다."예시"
statusstring조건부·선택클리닉 처리 결과입니다. 예약·입실·완료·취소·불참·변경 또는 빈 문자열입니다."예시"
nextDatestring조건부·선택변경된 클리닉 일자입니다. 빈 문자열이면 수업일을 사용합니다."2026-01-15"
retestboolean조건부·선택재시험 대상 여부입니다.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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/teaching/clinic-reviews/{reviewId}클리닉 리뷰 삭제

teaching.write · teaching.clinics.delete

경로 · 검색 파라미터

이름위치필수설명
reviewIdpath필수GET /v1/teaching/clinic-reviews 응답 data.items[].id의 클리닉 리뷰 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
[].namestring필수직원 이름입니다."예시 이름"
[].rolestring필수등록된 직원 직무입니다."예시"
[].startDateinteger필수입사일입니다. yyyyMMdd 정수입니다.20260115
[].endDateinteger필수퇴사일입니다. 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/attendance/staff/{staffId}직원 기본정보 상세(비밀번호·급여 제외)

staff.read · staff.get

경로 · 검색 파라미터

이름위치필수설명
staffIdpath필수GET /v1/attendance/staff 응답 data[].id의 직원 번호입니다. 검색 조건에서 0 또는 생략하면 전체입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
namestring필수직원 이름입니다."예시 이름"
rolestring필수등록된 직원 직무입니다."예시"
startDateinteger필수입사일입니다. yyyyMMdd 정수입니다.20260115
endDateinteger필수퇴사일입니다. 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"
  }
}
Explorer에서 요청 구성 →
POST/v1/attendance/staff직원 기본정보 등록(로그인 비밀번호 발급 없음)

staff.manage · staff.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
namestring필수출퇴근용 직원 이름입니다. 최대 20바이트(한글 10자·영문 20자)이며 저장할 수 없는 문자는 거절합니다. 로그인 비밀번호·급여는 설정하지 않습니다."예시 직원"
rolestring조건부·선택직무 표시명입니다. 예: 조교. 최대 10바이트(한글 5자·영문 10자)이며 권한 그룹·로그인 권한 코드가 아닙니다."조교"
startDatestring필수입사일입니다. 한국 날짜 yyyy-MM-dd 형식입니다."2026-01-15"
endDatestring조건부·선택퇴사일입니다. 한국 날짜 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
namestring필수직원 이름입니다."예시 이름"
rolestring필수등록된 직원 직무입니다."예시"
startDateinteger필수입사일입니다. yyyyMMdd 정수입니다.20260115
endDateinteger필수퇴사일입니다. 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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/attendance/staff/{staffId}직원 기본정보·입퇴사일 수정

staff.manage · staff.update

경로 · 검색 파라미터

이름위치필수설명
staffIdpath필수GET /v1/attendance/staff 응답 data[].id의 직원 번호입니다. 검색 조건에서 0 또는 생략하면 전체입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
namestring필수출퇴근용 직원 이름입니다. 최대 20바이트(한글 10자·영문 20자)이며 저장할 수 없는 문자는 거절합니다. 로그인 비밀번호·급여는 설정하지 않습니다."예시 직원"
rolestring조건부·선택직무 표시명입니다. 예: 조교. 최대 10바이트(한글 5자·영문 10자)이며 권한 그룹·로그인 권한 코드가 아닙니다."조교"
startDatestring필수입사일입니다. 한국 날짜 yyyy-MM-dd 형식입니다."2026-01-15"
endDatestring조건부·선택퇴사일입니다. 한국 날짜 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
namestring필수직원 이름입니다."예시 이름"
rolestring필수등록된 직원 직무입니다."예시"
startDateinteger필수입사일입니다. yyyyMMdd 정수입니다.20260115
endDateinteger필수퇴사일입니다. 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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/attendance/staff/{staffId}직원 퇴사 처리(근무 이력 보존)

staff.manage · staff.stop

경로 · 검색 파라미터

이름위치필수설명
staffIdpath필수GET /v1/attendance/staff 응답 data[].id의 직원 번호입니다. 검색 조건에서 0 또는 생략하면 전체입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
namestring필수직원 이름입니다."예시 이름"
rolestring필수등록된 직원 직무입니다."예시"
startDateinteger필수입사일입니다. yyyyMMdd 정수입니다.20260115
endDateinteger필수퇴사일입니다. 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"
  }
}
Explorer에서 요청 구성 →
GET/v1/attendance/staff/journals기간별 직원 출퇴근·근무일지

staff.read · staff.journals.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
fromquery필수조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery필수조회 종료일입니다. yyyy-MM-dd 형식입니다.
staffIdquery선택GET /v1/attendance/staff 응답 data[].id의 직원 번호입니다. 검색 조건에서 0 또는 생략하면 전체입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
items[].staffIdinteger필수직원 번호입니다.1
items[].namestring필수직원 이름입니다."예시 이름"
items[].inAtstring필수한국 현지 시각의 출근일시입니다."2026-01-15T14:00:00"
items[].outAtstring필수한국 현지 시각의 퇴근일시입니다. null이면 미퇴근입니다."2026-01-15T14:00:00"
items[].titlestring필수근무일지 제목입니다."예시"
items[].journalstring필수근무일지 일반 텍스트입니다."예시"
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/attendance/staff/journals/{journalId}직원 출퇴근·근무일지 상세

staff.read · staff.journals.get

경로 · 검색 파라미터

이름위치필수설명
journalIdpath필수GET /v1/attendance/staff/journals 응답 data.items[].id의 근무일지 번호입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
staffIdinteger필수직원 번호입니다.1
namestring필수직원 이름입니다."예시 이름"
inAtstring필수한국 현지 시각의 출근일시입니다."2026-01-15T14:00:00"
outAtstring필수한국 현지 시각의 퇴근일시입니다. null이면 미퇴근입니다."2026-01-15T14:00:00"
titlestring필수근무일지 제목입니다."예시"
journalstring필수근무일지 일반 텍스트입니다."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
POST/v1/attendance/staff/journals직원 출근·퇴근·근무일지 등록

staff.write · staff.journals.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
staffIdinteger필수GET /v1/attendance/staff 응답 data[].id에서 선택한 직원 번호입니다. 직원 이름이 아닌 정수 id를 전달하세요.1
inAtstring필수출근일시입니다. 한국 현지 시각 yyyy-MM-ddTHH:mm:ss를 전달하며 미래 날짜는 허용하지 않습니다."2026-01-15T14:00:00"
outAtstring조건부·선택퇴근일시입니다. 출근 이후 같은 날짜여야 하며 미퇴근은 null입니다."2026-01-15T14:00:00"
titlestring조건부·선택근무일지 제목입니다."예시"
journalstring조건부·선택일반 텍스트 근무일지입니다. 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/attendance/staff/journals/{journalId}직원 출퇴근·근무일지 수정

staff.write · staff.journals.update

경로 · 검색 파라미터

이름위치필수설명
journalIdpath필수GET /v1/attendance/staff/journals 응답 data.items[].id의 근무일지 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
staffIdinteger필수GET /v1/attendance/staff 응답 data[].id에서 선택한 직원 번호입니다. 직원 이름이 아닌 정수 id를 전달하세요.1
inAtstring필수출근일시입니다. 한국 현지 시각 yyyy-MM-ddTHH:mm:ss를 전달하며 미래 날짜는 허용하지 않습니다."2026-01-15T14:00:00"
outAtstring조건부·선택퇴근일시입니다. 출근 이후 같은 날짜여야 하며 미퇴근은 null입니다."2026-01-15T14:00:00"
titlestring조건부·선택근무일지 제목입니다."예시"
journalstring조건부·선택일반 텍스트 근무일지입니다. 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/attendance/staff/journals/{journalId}직원 출퇴근 기록 삭제

staff.write · staff.journals.delete

경로 · 검색 파라미터

이름위치필수설명
journalIdpath필수GET /v1/attendance/staff/journals 응답 data.items[].id의 근무일지 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/attendance/staff/summary직원별 근무 일수·시간 합계

staff.read · staff.summary

경로 · 검색 파라미터

이름위치필수설명
fromquery필수조회 시작일입니다. yyyy-MM-dd 형식이며 종료일과 최대 366일 차이입니다.
toquery필수조회 종료일입니다. yyyy-MM-dd 형식입니다.
staffIdquery선택GET /v1/attendance/staff 응답 data[].id의 직원 번호입니다. 검색 조건에서 0 또는 생략하면 전체입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
[].staffIdinteger필수직원 번호입니다.1
[].namestring필수직원 이름입니다."예시 이름"
[].workDaysinteger필수조회 기간의 출근 일수입니다.1
[].workHoursnumber필수퇴근까지 기록된 총 근무 시간입니다. 미퇴근은 계산하지 않습니다.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"
  }
}
Explorer에서 요청 구성 →

교재관리

GET/v1/books교재비 항목 목록

books.read · books.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
searchquery선택검색어입니다. 최대 100자이며 생략하면 전체를 조회합니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
items[].namestring필수교재비 항목 이름입니다."예시 이름"
items[].subjectstring필수과목 이름입니다."예시"
items[].gradestring필수학년 구분입니다."예시"
items[].levelstring필수수준 구분입니다."예시"
items[].teacherIdinteger필수GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.1
items[].priceinteger필수기본 출고 금액입니다. 원 단위입니다.1
items[].activeboolean필수사용 중인지 나타냅니다.false
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/books/{bookId}교재비 항목 상세

books.read · books.get

경로 · 검색 파라미터

이름위치필수설명
bookIdpath필수GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
namestring필수교재비 항목 이름입니다."예시 이름"
subjectstring필수과목 이름입니다."예시"
gradestring필수학년 구분입니다."예시"
levelstring필수수준 구분입니다."예시"
teacherIdinteger필수GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.1
priceinteger필수기본 출고 금액입니다. 원 단위입니다.1
activeboolean필수사용 중인지 나타냅니다.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"
  }
}
Explorer에서 요청 구성 →
POST/v1/books교재비 항목 등록

books.write · books.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
namestring필수교재비 항목 이름입니다."예시 교재"
subjectstring필수교재 과목 이름입니다."수학"
gradestring조건부·선택학년 구분입니다."예시"
levelstring조건부·선택수준 구분입니다."예시"
teacherIdinteger필수GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.1
priceinteger조건부·선택기본 출고 금액입니다. 원 단위의 0 이상 정수입니다.0
activeboolean조건부·선택사용 여부입니다.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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/books/{bookId}교재비 항목 수정

books.write · books.update

경로 · 검색 파라미터

이름위치필수설명
bookIdpath필수GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
namestring필수교재비 항목 이름입니다."예시 교재"
subjectstring필수교재 과목 이름입니다."수학"
gradestring조건부·선택학년 구분입니다."예시"
levelstring조건부·선택수준 구분입니다."예시"
teacherIdinteger필수GET /v1/teams/teachers 응답 data[].id에서 선택한 담당 선생님 번호입니다. 목록 id를 정수로 변환해 전달하세요. 0은 기본 선생님 번호가 아니며 대표 계정도 목록의 실제 id를 사용합니다.1
priceinteger조건부·선택기본 출고 금액입니다. 원 단위의 0 이상 정수입니다.0
activeboolean조건부·선택사용 여부입니다.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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/books/{bookId}사용 이력이 없는 교재비 항목 삭제

books.write · books.delete

경로 · 검색 파라미터

이름위치필수설명
bookIdpath필수GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/books/{bookId}/issues원본 교재 번호(books.list/get id)별 출고·반품·수납 현황

books.read · books.issues.list

경로 · 검색 파라미터

이름위치필수설명
bookIdpath필수GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다.
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
items[].studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
items[].studentNamestring필수학생 이름입니다."예시 이름"
items[].scheduleIdinteger필수현재 조회 시간표 번호입니다.1
items[].issuedScheduleIdinteger필수처음 출고된 시간표 번호입니다.1
items[].itemstring필수출고한 부교재 이름입니다."예시"
items[].issuedboolean필수출고 여부입니다.false
items[].returnedboolean필수반품 여부입니다.false
items[].excludedboolean필수출고 대상 제외 여부입니다.false
items[].amountinteger필수출고 금액입니다. 원 단위입니다.1
items[].paymentTypestring필수수납 구분입니다."예시"
items[].memostring필수출고 메모입니다."예시"
items[].issuedAtstring필수출고일시입니다."2026-01-15T00:00:00Z"
items[].returnedAtstring필수과거 반품 처리 시각입니다. 반품 해제 후에도 남을 수 있으며 현재 반품 상태는 returned가 기준입니다."2026-01-15T00:00:00Z"
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/books/{bookId}/issues/{issueId}원본 교재·출고 번호의 학생별 현재 지급·반품·제외·금액·수납·메모 조회

books.read · books.issues.get

경로 · 검색 파라미터

이름위치필수설명
bookIdpath필수GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다.
issueIdpath필수GET /v1/books/{bookId}/issues 응답 data.items[].id의 출고 기록 번호입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수자료의 고유 번호입니다. 생성 시에는 서버가 발급합니다.1
studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
studentNamestring필수학생 이름입니다."예시 이름"
scheduleIdinteger필수현재 조회 시간표 번호입니다.1
issuedScheduleIdinteger필수처음 출고된 시간표 번호입니다.1
itemstring필수출고한 부교재 이름입니다."예시"
issuedboolean필수출고 여부입니다.false
returnedboolean필수반품 여부입니다.false
excludedboolean필수출고 대상 제외 여부입니다.false
amountinteger필수출고 금액입니다. 원 단위입니다.1
paymentTypestring필수수납 구분입니다."예시"
memostring필수출고 메모입니다."예시"
issuedAtstring필수출고일시입니다."2026-01-15T00:00:00Z"
returnedAtstring필수과거 반품 처리 시각입니다. 반품 해제 후에도 남을 수 있으며 현재 반품 상태는 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"
  }
}
Explorer에서 요청 구성 →
POST/v1/books/{bookId}/issues원본 교재 번호·학생·시간표로 학생별 교재 출고 등록

books.write · books.issues.create

경로 · 검색 파라미터

이름위치필수설명
bookIdpath필수GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.1
itemstring필수부교재 이름입니다. 공통 교재는 공통으로 입력합니다."예시"
issuedboolean조건부·선택출고 여부입니다.false
returnedboolean조건부·선택반품 여부입니다.false
excludedboolean조건부·선택출고 대상에서 제외할지 여부입니다.false
amountinteger조건부·선택현재 출고 금액입니다. 원 단위입니다.0
paymentTypestring필수미납·현금·카드·이체·수표·상품권·인터넷 결제·토스 프런트 중 하나입니다. 수납 내역을 기록하며 실제 결제는 실행하지 않습니다."예시"
memostring조건부·선택출고 관리 메모입니다."예시"
요청 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/books/{bookId}/issues/{issueId}원본 출고 조회 후 전체 값 수정(반품 해제·원복은 returned=false, 제외 해제·원복은 excluded=false, 다른 현재 값 보존)

books.write · books.issues.update

경로 · 검색 파라미터

이름위치필수설명
bookIdpath필수GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다.
issueIdpath필수GET /v1/books/{bookId}/issues 응답 data.items[].id의 출고 기록 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
studentIdstring필수GET /v1/students 응답 data.items[].id에서 선택한 학생 번호 문자열입니다. 이름·전화번호 대신 응답 id를 쓰고 앞자리 0을 유지하세요."00000001"
scheduleIdinteger필수GET /v1/teams/{teamId}/schedules 응답 data[].id에서 선택합니다. 지정한 반에 속한 시간표 번호를 전달하세요.1
itemstring필수부교재 이름입니다. 공통 교재는 공통으로 입력합니다."예시"
issuedboolean조건부·선택출고 여부입니다.false
returnedboolean조건부·선택반품 여부입니다.false
excludedboolean조건부·선택출고 대상에서 제외할지 여부입니다.false
amountinteger조건부·선택현재 출고 금액입니다. 원 단위입니다.0
paymentTypestring필수미납·현금·카드·이체·수표·상품권·인터넷 결제·토스 프런트 중 하나입니다. 수납 내역을 기록하며 실제 결제는 실행하지 않습니다."예시"
memostring조건부·선택출고 관리 메모입니다."예시"
요청 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/books/{bookId}/issues/{issueId}청구에 사용하지 않은 출고 기록 삭제

books.write · books.issues.delete

경로 · 검색 파라미터

이름위치필수설명
bookIdpath필수GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다.
issueIdpath필수GET /v1/books/{bookId}/issues 응답 data.items[].id의 출고 기록 번호입니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →
GET/v1/books/{bookId}/items기존 출고 부교재 이름 목록

books.read · books.items

경로 · 검색 파라미터

이름위치필수설명
bookIdpath필수GET /v1/books 응답 data.items[].id의 실제 교재비 항목 번호입니다. 교재명 속 숫자와는 별개입니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
응답 data JSON 스키마
{
  "type": "array",
  "items": {
    "type": "string"
  }
}

성공 응답 예시

{
  "data": [
    "예시"
  ],
  "meta": {
    "requestId": "example-request-id"
  }
}
Explorer에서 요청 구성 →

문자·알림톡

GET/v1/messages/template-examples공유 문자 예제 제목·분류·원문 조회(제목순·삭제 제외)웹 관리 기능

웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요
messages.read · messages.templates.examples

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
searchquery선택검색어입니다. 최대 100자이며 생략하면 전체를 조회합니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].idinteger필수저장된 문구 번호입니다.1
items[].titlestring필수저장된 문구 제목입니다."예시"
items[].categorystring필수문구의 분류명입니다."예시"
items[].contentstring필수저장된 원문입니다. 조회만으로 치환하거나 발송하지 않습니다."예시"
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
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"
  }
}
Explorer에서 요청 구성 →
GET/v1/messages/templates현재 학원이 저장한 문자 문구 목록(공유 예제·AI 프롬프트 제외)웹 관리 기능

웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요
messages.read · messages.templates.list

경로 · 검색 파라미터

이름위치필수설명
pagequery선택페이지 번호입니다. 기본값 1, 1~100000입니다.
pageSizequery선택페이지당 결과 수입니다. 기본값 30, 최대 100입니다.
searchquery선택검색어입니다. 최대 100자이며 생략하면 전체를 조회합니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
itemsarray필수현재 페이지의 조회 결과 배열입니다.하위 필드·본문 예시 참조
items[].idinteger필수저장된 문구 번호입니다.1
items[].titlestring필수저장된 문구 제목입니다."예시"
items[].categorystring필수문구의 분류명입니다."예시"
items[].contentstring필수저장된 원문입니다. 조회만으로 치환하거나 발송하지 않습니다."예시"
pageinteger필수현재 페이지 번호입니다. 1부터 시작합니다.1
pageSizeinteger필수한 페이지에 반환하는 자료 수입니다. 1~100입니다.1
totalinteger필수검색 조건에 맞는 전체 자료 수입니다.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"
  }
}
Explorer에서 요청 구성 →
GET/v1/messages/templates/{templateId}저장된 문자 문구 원문·현재 변경 검증 version 조회웹 관리 기능

웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요
messages.read · messages.templates.get

경로 · 검색 파라미터

이름위치필수설명
templateIdpath필수현재 학원이 저장한 문자 문구 목록에서 확인한 실제 문구 번호입니다. 공용 예제 번호를 전달하지 않습니다.

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수학원이 저장한 문구 번호입니다.1
titlestring필수문구 제목입니다."예시"
categorystring필수문구 분류명입니다."예시"
contentstring필수저장된 치환변수를 유지한 문구 원문입니다."예시"
versionstring필수수정·삭제 시 그대로 보내는 현재 변경 검증 값입니다."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
POST/v1/messages/templates학원 문자 문구 신규 저장(발송·AI 호출 없음)웹 관리 기능

웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요
messages.write · messages.templates.create

Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
titlestring필수문구 제목입니다. 화면과 동일하게 100바이트까지 저장합니다."예시"
categorystring조건부·선택분류명입니다. null이면 수정 시 기존 분류를 보존하며 빈 문자열이면 비웁니다. 최대 200바이트입니다."예시"
contentstring필수문구 원문입니다. 치환변수를 유지하며 최대 2000바이트입니다."예시"
versionstring조건부·선택수정 시 상세 조회에서 받은 현재 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수학원이 저장한 문구 번호입니다.1
titlestring필수문구 제목입니다."예시"
categorystring필수문구 분류명입니다."예시"
contentstring필수저장된 치환변수를 유지한 문구 원문입니다."예시"
versionstring필수수정·삭제 시 그대로 보내는 현재 변경 검증 값입니다."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
PUT/v1/messages/templates/{templateId}현재 학원의 문자 문구 제목·분류·내용 수정(현재 version 검증·공유 예제 수정 불가)웹 관리 기능

웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요
messages.write · messages.templates.update

경로 · 검색 파라미터

이름위치필수설명
templateIdpath필수현재 학원이 저장한 문자 문구 목록에서 확인한 실제 문구 번호입니다. 공용 예제 번호를 전달하지 않습니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
titlestring필수문구 제목입니다. 화면과 동일하게 100바이트까지 저장합니다."예시"
categorystring조건부·선택분류명입니다. null이면 수정 시 기존 분류를 보존하며 빈 문자열이면 비웁니다. 최대 200바이트입니다."예시"
contentstring필수문구 원문입니다. 치환변수를 유지하며 최대 2000바이트입니다."예시"
versionstring조건부·선택수정 시 상세 조회에서 받은 현재 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 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger필수학원이 저장한 문구 번호입니다.1
titlestring필수문구 제목입니다."예시"
categorystring필수문구 분류명입니다."예시"
contentstring필수저장된 치환변수를 유지한 문구 원문입니다."예시"
versionstring필수수정·삭제 시 그대로 보내는 현재 변경 검증 값입니다."예시"
응답 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"
  }
}
Explorer에서 요청 구성 →
DELETE/v1/messages/templates/{templateId}현재 학원 문자 문구 삭제(현재 version 검증·소프트 삭제)웹 관리 기능

웹 관리 기능 · 해당 웹 구독 등급과 관리자 권한 필요
messages.write · messages.templates.delete

경로 · 검색 파라미터

이름위치필수설명
templateIdpath필수현재 학원이 저장한 문자 문구 목록에서 확인한 실제 문구 번호입니다. 공용 예제 번호를 전달하지 않습니다.
Idempotency-Key는 호출자가 직접 생성하는 중복 방지용 헤더입니다. 서버에서 발급받지 않으며 API 인증 키와 별개입니다. 영문·숫자·하이픈·밑줄 8~100자(UUID 권장)를 사용하세요. 새 작업에는 새 키를, 동일 요청 재시도에는 같은 키·경로·본문을 사용합니다. 예: 550e8400-e29b-41d4-a716-446655440000. 생성 방법과 재시도 규칙 →

요청 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
versionstring필수직전 문구 상세 조회에서 받은 정확한 version입니다."예시"
요청 JSON 스키마
{
  "type": "object",
  "properties": {
    "version": {
      "type": "string",
      "description": "직전 문구 상세 조회에서 받은 정확한 version입니다.",
      "nullable": false,
      "minLength": 1,
      "pattern": "^[A-F0-9]{64}$"
    }
  },
  "required": [
    "version"
  ]
}

응답 data 필드

필드자료형필수 여부값 출처 · 입력 방법예시 값
idinteger|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"
  }
}
Explorer에서 요청 구성 →

웹 관리자 문자 API 웹 관리 기능

호출 서버는 klasslab.com(Web)입니다. 관리자 로그인 세션과 문자 메뉴 권한이 필요하고 POST에는 CSRF 토큰이 필요합니다. 외부 API 키·공개 MCP에서는 사용할 수 없습니다.

메서드·경로내용
GET /internal/assistant/messages/connections연동·사용 중지 상태와 등록 발신번호 조회. 인증정보는 반환하지 않습니다.
POST /internal/assistant/messages/previewprovider, sender, title, message, studentIds, contact를 검증해 학생 이름·번호·실제 연락처와 보호된 발송 확인 토큰을 반환합니다.
POST /internal/assistant/messages/sendpreviewToken과 confirm=true로 확인한 발송만 실행합니다. 학생 연락처·연동 상태·토큰 유효기간을 다시 검증하며 업체 요금이 적용됩니다.
GET /internal/assistant/messages/status/{id}실제 발송 응답에서 받은 요청 UUID로 업체 접수 결과를 조회합니다. 실제 휴대폰 전달 완료와는 구분합니다.

요청에 넣을 값 준비하기

요청 필드의 필수는 반드시 보내야 한다는 뜻입니다. 응답 data 표의 필수는 서버가 반환하는 항목이며 요청에 넣을 값이 아닙니다. 자료의 ID는 먼저 조회하거나 생성한 응답에서 가져오고, 파일 바이트는 호출하는 프로그램이 읽어 준비합니다. 아래와 본문의 숫자·UUID·파일 주소는 형식을 설명하는 합성 예시입니다. 실제 계정의 응답 값으로 바꾸세요.

입력 필드값을 얻는 방법
studentIdGET /v1/students의 data.items[].id. 학생 이름·전화번호가 아닌 문자열 ID이며 앞자리 0을 유지합니다.
teamId · scheduleIdGET /v1/teams의 data.items[].id로 반을 선택한 뒤 GET /v1/teams/{teamId}/schedules의 data[].id로 해당 반의 시간표를 선택합니다.
teacherId · teacherIdsGET /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 · examIdsGET /v1/grading/exams의 data.items[].id. 시험 번호이며 OMR 양식 번호(예: 120)와 다릅니다.
fileId · fileIdsPDF 업로드 응답 data.files[].id를 페이지 순서대로 전달합니다. 이미지·XLSX 단일 업로드는 data.id를 사용합니다. 직접 만든 UUID나 로컬 파일 경로는 사용하지 않습니다.
expectedUnitCredits · consentexpectedUnitCredits는 이전 연동 호환용으로 생략하거나 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/uploadsPNG·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필수값·자료형·범위를 확인하세요.
401API 키를 확인하세요.
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를 유지하세요.

페이지

API 구독 · 크레딧API 키 관리API 사용량 · 호출 로그문의 · 증액 신청

문서

MCP 연결KlassLab API · v1선생님 개발 가이드KlassLab API · v1KlassLab API 소개KlassLab API · v1빠른 시작KlassLab API · v1API 키KlassLab API · v1API 레퍼런스KlassLab API · v1제공 기능 · 요금KlassLab API · v1API ExplorerKlassLab API · v1

API 레퍼런스

등록된 온라인 과제·재시험 조회(온라인 번호·구분·진행 상태)온라인 과제·재시험 · GET /grading/online-exams온라인 시험 구분·응시대상 설정 현황온라인 과제·재시험 · GET /grading/online-exams/{onlineExamId}온라인 시험 구분 변경(연결된 재시험은 먼저 연결 해제)온라인 과제·재시험 · PATCH /grading/online-exams/{onlineExamId}/kind과제장 재시험 연결·해제할 등록 번호 조회과제장 재시험 연결 · GET /teaching/lessons/{lessonId}/retest재시험 연결·선택한 과제장 학생 응시 등록·재시험 대상 체크(원자적 저장)과제장 재시험 연결 · PUT /teaching/lessons/{lessonId}/retest조회한 연결 해제·개별 응시 등록 제거(공유 학생·반 등록·성적·출결 보존)과제장 재시험 연결 · DELETE /teaching/lessons/{lessonId}/retest미제출 명단 조회(재시험은 지정 응시대상, 통합은 두 시험 모두 성적 없음)미제출 명단 · GET /grading/exams/{examId}/missing-submissions직원 기본정보 상세(비밀번호·급여 제외)직원 출퇴근 · GET /attendance/staff/{staffId}직원 기본정보 등록(로그인 비밀번호 발급 없음)직원 출퇴근 · POST /attendance/staff직원 기본정보·입퇴사일 수정직원 출퇴근 · PUT /attendance/staff/{staffId}직원 퇴사 처리(근무 이력 보존)직원 출퇴근 · DELETE /attendance/staff/{staffId}전반 취소(새 반 수강번호 지정·이전 반 복원·취소 이력 보존)수강생관리 · POST /students/{id}/enrollments/{enrollmentId}/cancel-transfer수강 등록일 수정수강생관리 · PATCH /students/{id}/enrollments/{enrollmentId}수강 등록 삭제(출결·과제 기록이 있으면 거절)수강생관리 · DELETE /students/{id}/enrollments/{enrollmentId}학생 단일 필드 수정수강생관리 · PATCH /students/{id}퇴원 취소수강생관리 · POST /students/{id}/enrollments/{enrollmentId}/restore수강반 전반(원 수강 종료와 신규 등록을 함께 저장)수강생관리 · POST /students/{id}/enrollments/{enrollmentId}/moveTeaching teacher names and IDs, including teachers without classes; shared by classes, lessons and exams. Not employee time-clock staff.수강반관리 · GET /teams/teachers상담 담당자 선택 목록상담예약관리 · GET /consultations/staff생활기록 분류 목록학생생활기록 · GET /life-records/categories수강반·담당·시간표 목록. status=open 미종강(미래 개강·종강 포함), closed 종강, all 전체. 한국 오늘 기준. sort=id_desc 최신 등록번호순, begin_date_asc/desc 개강일순. appliedSort/appliedStatus 확인수강반관리 · GET /teams예정 수업·담당자·시각·고유 재원 인원. date의 하루 조회; lookAheadDays>0이면 그날부터 범위 안 첫 수업일 조회. 개강·종강·시간표 기간 적용, 저장 출석부 아님수강반관리 · GET /teams/daily-plan수강반 상세수강반관리 · GET /teams/{id}수강반 등록수강반관리 · POST /teams새 수강반과 시간표를 함께 등록(원자적 저장·하나라도 실패하면 전체 취소)수강반관리 · POST /teams/with-schedules수강반 수정 · 종강/종강 취소수강반관리 · PUT /teams/{id}수강반 삭제(재원생이 있으면 거절)수강반관리 · DELETE /teams/{id}수강반의 시간표 목록(id는 teamId이며 scheduleId 아님)수강반관리 · GET /teams/{id}/schedules시간표 등록수강반관리 · POST /teams/{id}/schedules시간표 수정수강반관리 · PUT /teams/{id}/schedules/{scheduleId}시간표 삭제(수업·재원생이 있으면 거절)수강반관리 · DELETE /teams/{id}/schedules/{scheduleId}학생 검색 · 목록(공백으로 구분한 이름·학생번호·연락처 중 하나라도 일치)수강생관리 · GET /students학생 기본정보수강생관리 · GET /students/{id}학생 기본정보 등록(수강 등록은 별도)수강생관리 · POST /students학생 기본정보 수정(전체 필드 교체)수강생관리 · PUT /students/{id}학생 삭제(재원 중이면 거절)수강생관리 · DELETE /students/{id}학생 수강 이력수강생관리 · GET /students/{id}/enrollments기존 학생 수강 등록수강생관리 · POST /enrollments퇴원 처리수강생관리 · PUT /students/{id}/enrollments/{enrollmentId}/end기간별 상담 예약상담예약관리 · GET /consultations상담 예약 상세상담예약관리 · GET /consultations/{id}상담 예약 등록상담예약관리 · POST /consultations상담 예약 변경 · 완료 · 취소상담예약관리 · PUT /consultations/{id}상담 예약 삭제상담예약관리 · DELETE /consultations/{id}생활기록 항목 정의학생생활기록 · GET /life-records/fields생활기록 항목 설정학생생활기록 · PUT /life-records/fields수강 시간표별 학생 생활기록학생생활기록 · GET /life-records학생 생활기록 저장(항목 값 병합)학생생활기록 · PUT /life-records학생 생활기록 삭제학생생활기록 · DELETE /life-records/{id}채점 과목 목록채점 과목 · GET /grading/subjects과목별 대분류 목록채점 과목 · GET /grading/subjects/{subject}/sections과목·대분류 등록채점 과목 · POST /grading/sections과목 내 대분류 수정채점 과목 · PUT /grading/sections/{sectionId}대분류 삭제(사용 중이면 거절)채점 과목 · DELETE /grading/sections/{sectionId}대분류의 소분류 목록채점 과목 · GET /grading/sections/{sectionId}/patterns소분류 등록채점 과목 · POST /grading/sections/{sectionId}/patterns소분류 수정채점 과목 · PUT /grading/sections/{sectionId}/patterns/{patternId}소분류 삭제(사용 중이면 거절)채점 과목 · DELETE /grading/sections/{sectionId}/patterns/{patternId}공식 OMR 양식별 총 칸 수·종류 목록·PDF/이미지 제공 정보. 개별 문항 번호·답안 종류·정답 입력 틀은 grading.answer-template.get에 있음. answerTypes는 필요한 종류 교집합 필터(0 객관식, 1 단답형 정답 비교, 2 서술형 획득점수). 미지정 필터는 생략. 양식 코드는 학원 시험 이름이 아님OMR 양식 정보 · GET /grading/omr-templates공식 빈 OMR PDF·이미지 원본 다운로드OMR 양식 정보 · GET /grading/omr-templates/{code}/files/{format}지정한 OMR 양식의 문항별 번호(number)·답안 종류(answerType)·정답·배점 입력 틀 배열. 특정 문항 범위의 종류 확인에도 사용. 0 객관식, 1 단답형 정답 비교, 2 서술형 획득점수. 실제 시험·채점 점수 조회가 아님정답지 등록 · GET /grading/omr-templates/{code}/answers시험·정답지 검색·목록(제목·회차·연도·학년으로 구별, 수강반 목록과 다름)정답지 등록 · GET /grading/exams시험과 전체 문항별 정답 상세정답지 등록 · GET /grading/exams/{examId}새 시험·정답지 등록(학생 답안 채점 아님)정답지 등록 · POST /grading/exams정답지 전체 교체(성적표 설정·문항 이미지 연결 보존)정답지 등록 · PUT /grading/exams/{examId}시험 삭제(채점 자료가 있으면 거절)정답지 등록 · DELETE /grading/exams/{examId}채점 점수·답안·코멘트 조회. 오답·보충·만점 대비 비율 분석은 includeAnalysis=true로 서버 판정을 사용. 빈 답안은 실제 무응답으로 단정하지 않고 미식별 학생은 추측하지 않음채점 자료 수정 · GET /grading/exams/{examId}/scores기존 시험에 학생 수기·엑셀 답안 채점·저장(결과는 학생별 번호 배열)채점 자료 수정 · POST /grading/exams/{examId}/scores개별·일괄 기존 채점 답안 수정 및 재채점. 기존 미식별 답안은 행 id와 빈 studentId로 학생 연결·인식 이름을 보존하며 수정. 정답지와 원본 marks 전체를 조회해 요청하지 않은 답안은 유지채점 자료 수정 · PUT /grading/exams/{examId}/scores채점 행 삭제채점 자료 수정 · DELETE /grading/exams/{examId}/scores/{scoreId}학생별 성적 개별 코멘트 저장채점 자료 수정 · PATCH /grading/exams/{examId}/scores/{scoreId}/commentOMR PDF 원본 업로드(최대 50MB·100쪽 / 페이지 자동 변환)작업 파일 · POST /grading/pdf-uploads채팅 첨부 OMR PDF 업로드(최대 50MB·100쪽 / 이미지·XLSX도 지원)작업 파일 · POST /grading/attachments보조 업로드: PNG·JPG 스캔 이미지·XLSX 답안 파일(파일당 5MB)작업 파일 · POST /grading/uploads단일·두 회차 OMR 채점 작업 등록(구독 OMR 장수 집계)OMR 채점 · POST /grading/omr-jobsXLSX 답안 등록 작업 생성엑셀 채점 등록 · POST /grading/exams/{examId}/excel-imports데이터 작업 진행 상태·인식 결과 조회작업 상태 · GET /grading/jobs/{jobId}정답 변경 후 점수·통계 재계산 작업 생성채점 자료 수정 · POST /grading/recalculation-jobs현재 API 호출·OMR 장수의 사용량과 구독 한도 확인OMR 채점 · GET /grading/usage날짜·반별 수업 기록·과제장 목록(수강반 목록 아님)수업·과제장 · GET /teaching/lessons과제장 수업과 항목 상세수업·과제장 · GET /teaching/lessons/{lessonId}수업·과제장 내용과 숙제 정의 등록(학생별 출석·과제완료는 학생별 결과 변경으로 별도 처리)수업·과제장 · POST /teaching/lessons수업·과제장 전체 수정수업·과제장 · PUT /teaching/lessons/{lessonId}수업·과제장 삭제와 연결 출석 정리수업·과제장 · DELETE /teaching/lessons/{lessonId}수업 목록의 lessonId로 저장된 출석·검사 조회(반·시간표 번호 아님, 빈 명단은 roster.add 후 기록)수업·과제장 · GET /teaching/lessons/{lessonId}/students수강 등록에서 선택한 일반 학생을 출석부에 추가수업·과제장 · POST /teaching/lessons/{lessonId}/students수업 학생 출석·결석·검사결과 부분 수정(입퇴실·수강등록 아님). 학생 코멘트는 rows[].values.comment에 전달하고 생략 항목은 보존수업·과제장 · PATCH /teaching/lessons/{lessonId}/results명단 학생 삭제(연결된 원래 결석 복원)수업·과제장 · DELETE /teaching/lessons/{lessonId}/students/{studentId}수업의 저장된 출석부 삭제수업·과제장 · DELETE /teaching/lessons/{lessonId}/attendance보강완료 연결 후보(같은 학생·타반·수업일 ±10일)수업·과제장 · GET /teaching/lessons/{lessonId}/students/{studentId}/makeup-candidates원래 수업의 현재 보강 연결·복원 출결 조회(해제 전 필수 확인)수업·과제장 · GET /teaching/lessons/{lessonId}/students/{studentId}/makeup-link조회한 보강 연결만 해제하고 보존된 원래 출결 복원. 보강생 행·과제·코멘트는 보존하며 확인값이 달라지면 거절수업·과제장 · PATCH /teaching/lessons/{lessonId}/students/{studentId}/makeup-link목적지 보강 수업 lessonId로 원래 결석 후보 조회(응답 originalLessonId에서 선택)수업·과제장 · GET /teaching/lessons/{lessonId}/absence-candidates목적지 lessonId에 선택한 원래 결석 originalLessonId를 연결해 보강생(8) 추가·원반 보강완료(7) 처리수업·과제장 · POST /teaching/lessons/{lessonId}/makeups연결된 OMR 점수를 과제장에 동기화수업·과제장 · POST /teaching/lessons/{lessonId}/score-sync선택 과제장의 학기·기간 일괄 변경수업·과제장 · PUT /teaching/seasons기간별 재검사 일정 목록재검사 일정 · GET /teaching/todos재검사 일정 상세재검사 일정 · GET /teaching/todos/{todoId}재검사 메모·날짜·처리 결과 저장재검사 일정 · PUT /teaching/todos/{todoId}기간별 누적 과제·시험·출결 결과. valueItems가 같은 수업의 제목·슬롯·표시 안내·결과를 연결. 값만으로 만점·단위를 추측하지 않음과제장 누적 성적표 · GET /teaching/cumulative-results반·날짜별 학생 이름·출결 상태·검사 조회. teamId와 from/to로 직접 조회하며 lessonId 불필요. 출결 단순 조회에 우선 사용수업일별 출석부 · GET /attendance/daily기간 내 전체 또는 선택 반의 학생별 출결 합계·결석 학생 명단 조회. 무결·유결 합계로 결석 구분, 타반 보강생 제외수강생별 출결현황 · GET /attendance/students학생 입퇴실 체크 내역입퇴실 체크 · GET /attendance/checks현재 시각 입실·퇴실 기록(수업 출석 아님·발송 없음)입퇴실 체크 · POST /attendance/checks학생 입퇴실 기록 삭제입퇴실 체크 · DELETE /attendance/checks/{checkId}기간별 클리닉 리뷰 목록클리닉 리뷰 · GET /teaching/clinic-reviews클리닉 리뷰 상세클리닉 리뷰 · GET /teaching/clinic-reviews/{reviewId}클리닉 리뷰 등록클리닉 리뷰 · POST /teaching/clinic-reviews클리닉 리뷰 전체 수정클리닉 리뷰 · PUT /teaching/clinic-reviews/{reviewId}클리닉 리뷰 삭제클리닉 리뷰 · DELETE /teaching/clinic-reviews/{reviewId}Time-clock employee identities, excluding passwords/payroll. Never use as the teaching teacher roster or teacher IDs.직원 출퇴근 · GET /attendance/staff기간별 직원 출퇴근·근무일지직원 출퇴근 · GET /attendance/staff/journals직원 출퇴근·근무일지 상세직원 출퇴근 · GET /attendance/staff/journals/{journalId}직원 출근·퇴근·근무일지 등록직원 출퇴근 · POST /attendance/staff/journals직원 출퇴근·근무일지 수정직원 출퇴근 · PUT /attendance/staff/journals/{journalId}직원 출퇴근 기록 삭제직원 출퇴근 · DELETE /attendance/staff/journals/{journalId}직원별 근무 일수·시간 합계직원 출퇴근 · GET /attendance/staff/summary교재비 항목 목록교재 출고 · GET /books교재비 항목 상세교재 출고 · GET /books/{bookId}교재비 항목 등록교재 출고 · POST /books교재비 항목 수정교재 출고 · PUT /books/{bookId}사용 이력이 없는 교재비 항목 삭제교재 출고 · DELETE /books/{bookId}기존 출고 부교재 이름 목록교재 출고 · GET /books/{bookId}/items원본 교재 번호(books.list/get id)별 출고·반품·수납 현황교재 출고 · GET /books/{bookId}/issues원본 교재·출고 번호의 학생별 현재 지급·반품·제외·금액·수납·메모 조회교재 출고 · GET /books/{bookId}/issues/{issueId}원본 교재 번호·학생·시간표로 학생별 교재 출고 등록교재 출고 · POST /books/{bookId}/issues원본 출고 조회 후 전체 값 수정(반품 해제·원복은 returned=false, 제외 해제·원복은 excluded=false, 다른 현재 값 보존)교재 출고 · PUT /books/{bookId}/issues/{issueId}청구에 사용하지 않은 출고 기록 삭제교재 출고 · DELETE /books/{bookId}/issues/{issueId}학생 이름 클릭 통합정보: 기본정보·수강 전체·최근 상담·시험성적·클리닉 요약학생 통합 정보 · GET /students/{id}/detail학생 통합정보 기본정보 조회(이름·번호·연락처·학교·학년·메모, 비밀번호 제외)학생 통합 정보 · GET /students/{id}/detail/profile학생 통합정보의 수강·퇴원·전반·종강·전반취소 이력과 이전 수강반 조회학생 통합 정보 · GET /students/{id}/detail/enrollments지정 학생 1명의 수업일별 출결·보강 이력(0=무결·4=유결은 결석, 5=출석·6=인강·7=보강완료·8=보강생과 구별)학생 통합 정보 · GET /students/{id}/detail/attendance학생 과제·시험 검사결과와 수업 회차·출결·코멘트. valueItems가 같은 수업의 실제 항목 제목·안내·결과를 연결, 빈 값은 미완료로 추측하지 않음학생 통합 정보 · GET /students/{id}/detail/homework학생 시험별 점수·평균·만점·등수 이력(오답 미제공, 공개 성적표 링크 발급 없음)학생 통합 정보 · GET /students/{id}/detail/scores학생의 원문 상담 내역·예약 유형·담당자·진행 상태 조회학생 통합 정보 · GET /students/{id}/detail/notes선택 학생의 특정 상담 원문·담당자·예약 일시·변경 검증 version 조회학생 통합 정보 · GET /students/{id}/detail/notes/{noteId}학생 통합정보에서 상담 기록 등록(선택한 담당자·유형·명시한 예약일만 사용)학생 통합 정보 · POST /students/{id}/detail/notes상담 원문·담당자·유형·예약 수정(생략한 값 보존·학원/학생/현재 version 원자적 검증)학생 통합 정보 · PATCH /students/{id}/detail/notes/{noteId}선택 학생의 상담 기록 삭제(현재 version 확인·소프트 삭제)학생 통합 정보 · DELETE /students/{id}/detail/notes/{noteId}학생 통합정보 상담 편집에서 실제 선택 가능한 담당자·예약 유형 목록학생 통합 정보 · GET /students/detail/note-options학생별 생활기록 이력과 실제 사용 설정된 항목 이름·값·도표 설정 조회학생 통합 정보 · GET /students/{id}/detail/life학생의 클리닉 예약·완료·취소·불참과 리뷰·메모 이력 조회학생 통합 정보 · GET /students/{id}/detail/clinics학생 통합정보의 할인율·형제 할인 연결 학생 이름과 번호 조회학생 통합 정보 · GET /students/{id}/detail/discounts학생별 문자·알림톡 발송 내용·수신번호·요청번호 이력 조회(발송 실행 없음)학생 통합 정보 · GET /students/{id}/detail/messages학생별 로그인 시각·접속 주소·구분 이력 조회학생 통합 정보 · GET /students/{id}/detail/logins반별 최근 학기·다음 회차와 실제 시간표에서 계산한 다음 수업일 후보(저장·자동 지정 없음)수업·과제장 · GET /teaching/teams/{id}/registration-defaults선택 과제장 제목과 현재 학생 공개 상태 조회수업·과제장 · GET /teaching/lessons/{lessonId}/publication학생에게 과제장 공개·비공개 변경(직전 공개 상태 일치 확인·수업 내용 보존)수업·과제장 · PATCH /teaching/lessons/{lessonId}/publication반별 전체 수강 이력(종료 포함·재원 인원 아님). 현재 학생 명단·인원은 students.list의 teamId 사용. 학생·수강번호·퇴원/전반/종강 사유수강반 관리 · GET /teams/{id}/detail/students과제장 등록에서 실제 선택 가능한 담당 선생님 이름과 번호수업·과제장 · GET /teaching/options/teachers실제 저장된 과제장 학기·기간 선택 목록수업·과제장 · GET /teaching/options/seasons담당 선생님의 복사 원본 과제장 선택 목록(조회만 하며 새 과제장을 만들지 않음)수업·과제장 · GET /teaching/options/copy-sources공유 템플릿 불러오기에서 실제 선택 가능한 과제장 목록수업·과제장 · GET /teaching/options/templates과제장의 시험 항목에 연결 가능한 담당 선생님의 채점지 이름과 번호수업·과제장 · GET /teaching/options/exams선택 수강반의 실제 시간표 목록(요일에 맞는 시간표를 임의 지정하지 않음)수업·과제장 · GET /teaching/teams/{id}/schedules반별 과제장 분류·교과·저장 양식과 실제 적용 양식 조회(시간표 자동 선택 없음)수업·과제장 · GET /teaching/teams/{id}/course반별 과제장 성적표 저장값·실제 적용 양식·이름·version 조회(미지정 0 등은 당일형 80, 82는 누적형)과제장 성적표 양식 설정 · GET /teaching/teams/{id}/report-settings반별 과제장 성적표를 당일형 80/누적형 82로 변경(현재 version 확인·다른 반 설정 보존)과제장 성적표 양식 설정 · PATCH /teaching/teams/{id}/report-settings클리닉 실제 예약·입실·퇴실·불참·취소 학생 명단 조회(상태 동기화나 메시지 발송 없음)클리닉 리뷰 · GET /teaching/clinic-appointments클리닉 리뷰 등록에서 저장된 리뷰 문구 목록 조회클리닉 리뷰 · GET /teaching/clinic-review-templates클리닉 문자 작성에서 저장된 문구 목록 조회(발송 없음)클리닉 리뷰 · GET /teaching/clinic-message-templates공유 문자 예제 분류 목록(학원 저장 문구와 분리)문자·알림톡 문구 · GET /messages/template-examples/categories공유 문자 예제 제목·분류·원문 조회(제목순·삭제 제외)문자·알림톡 문구 · GET /messages/template-examples현재 학원이 저장한 문자 문구 목록(공유 예제·AI 프롬프트 제외)문자·알림톡 문구 · GET /messages/templates저장된 문자 문구 원문·현재 변경 검증 version 조회문자·알림톡 문구 · GET /messages/templates/{templateId}학원 문자 문구 신규 저장(발송·AI 호출 없음)문자·알림톡 문구 · POST /messages/templates현재 학원의 문자 문구 제목·분류·내용 수정(현재 version 검증·공유 예제 수정 불가)문자·알림톡 문구 · PUT /messages/templates/{templateId}현재 학원 문자 문구 삭제(현재 version 검증·소프트 삭제)문자·알림톡 문구 · DELETE /messages/templates/{templateId}통계 조회 가능한 수강반·시간표 key 목록수강생 통계 조회 · GET /students/statistics/teams월별·연간 신규·재원·퇴원 고유 인원(명시 선택한 수강반 기준 전환)수강생 통계 조회 · GET /students/statistics/summary기간별 퇴원 명단. basis=academy는 학원 최종 퇴원, enrollment는 반별 퇴원 이력(다른 반 계속 수강도 포함). 반별 명단은 enrollment 사용. 원본 학생·반명·퇴원일, 전반·종강·전반취소 제외수강생 통계 조회 · GET /students/statistics/withdrawals통계 학생별 상세(학생 이름·번호 포함, month=0은 연간 월별 집합 합집합)수강생 통계 조회 · GET /students/statistics/students