모두CBT 오픈 API 가이드
내 공부 자료를 AI로 문제로 만들어 모두CBT 암기장에 등록하는 방법입니다. 사람과 AI가 함께 읽도록 썼습니다.
AI에게: 이 문서를 끝까지 읽은 뒤, [1. 한눈에 보기]의 순서대로 진행하세요. 문항은 [4. 문항 JSON 형식]과 [5~7. 작성 규칙]을 반드시 지켜야 화면에서 깨지지 않습니다. 확실하지 않은 사실·수치는 지어내지 말고, 등록 전에 항상
POST /open/v1/validate로 검사하세요.
- 문서 주소(마크다운):
https://api.moducbt.com/open/v1/docs - 형식·한도(JSON):
https://api.moducbt.com/open/v1/schema - 키 발급·붙여넣기 등록 화면:
https://www.moducbt.com/me/ai-import
1. 한눈에 보기
- 키 준비 — 모두CBT 로그인 → 마이페이지
AI로 문제 등록→API · AI 에이전트탭에서 키(mcbt_…)를 발급합니다. - 어디에 넣을지 정하기 — 사용자에게 물어봅니다.
- 새 암기장을 만들지, 기존 암기장에 시험지를 추가할지.
- 기존이면
GET /open/v1/categories로 목록을 보여 주고 고르게 한 뒤,GET /open/v1/categories/{id}로 이미 있는 시험지(회차) 제목을 확인해 같은 회차를 중복 등록하지 않게 합니다.
- 문항 만들기 — 이 문서의 형식·작성 규칙대로 JSON을 만듭니다. (그림이 있으면
POST /open/v1/images로 먼저 올립니다.) - 검사 —
POST /open/v1/validate.issues가 있으면 문항 번호별 사유대로 고쳐valid: true가 될 때까지 반복합니다. - 등록 — 가장 쉬운 방법은
POST /open/v1/import한 번입니다(새 암기장 또는 기존 암기장 + 시험지 여러 개 + 실전 모의고사 설정까지). 시험지 1개씩 넣으려면POST /open/v1/categories/{id}/exams.- 시험지(회차) 1개에 최대 300문항, 한 요청에 시험지 10개·문항 합계 300개까지. 넘으면 나눠서 보냅니다.
- (객관식, 선택) 실전 모의고사 설정 — 과목 구성·과락·합격 점수·제한 시간을 정하면 "실전 모의고사"로 실제 시험처럼 풀 수 있습니다. [8. 실전 모의고사 설정] 참고.
- (선택) 공개 — 사용자가 원할 때만
POST /open/v1/categories/{id}/visibility. [10. 공개 전환과 저작권]을 먼저 확인합니다.
키 없이 쓰는 방법도 있습니다. AI가 만든 JSON을
https://www.moducbt.com/me/ai-import의붙여넣기로 등록탭에 붙여 넣으면 됩니다.
1-1. MCP로 연결하기 (가장 쉬운 방법)
MCP를 지원하는 AI 도구라면 HTTP 요청을 직접 만들 필요 없이 도구로 씁니다. 주소는 https://api.moducbt.com/mcp 하나이고, 연결 방법은 두 가지입니다.
- 모두CBT 로그인으로 연결 (claude.ai·ChatGPT 등 커넥터): 앱의 커넥터(또는 "사용자 지정 커넥터") 추가에서 주소만 넣으면 모두CBT 로그인 화면이 열리고, 허용을 누르면 연결됩니다. API 키가 필요 없습니다. 연결 해제는 모두CBT
AI로 문제 등록 → API탭의 "연결된 앱"에서 합니다. - API 키로 연결 (Claude Code, Cursor, Codex 등): 아래처럼
X-API-Key헤더에 키를 넣습니다.
# Claude Code
claude mcp add --transport http moducbt https://api.moducbt.com/mcp --header "X-API-Key: mcbt_여기에_키"
// Cursor (.cursor/mcp.json) · Claude Desktop 등 헤더를 지원하는 설정
{ "mcpServers": { "moducbt": { "url": "https://api.moducbt.com/mcp", "headers": { "X-API-Key": "mcbt_여기에_키" } } } }
헤더를 못 넣는 클라이언트는 npx mcp-remote https://api.moducbt.com/mcp --header "X-API-Key: mcbt_여기에_키" 로 연결합니다.
| 도구 | 하는 일 |
|---|---|
get_guide |
이 문서 읽기 (먼저 호출) |
get_exam · update_questions · add_questions · delete_questions |
기존 시험지 보기 · 문항 고치기 · 추가 · 삭제(확인 후) |
list_revisions · restore_revision |
수정 기록 · 되돌리기 |
list_categories · get_category |
내 암기장 목록 · 시험지 목록/실전 모의고사 설정 |
validate_questions |
저장 없이 문항 검사 (issues·warnings) |
import_exams |
새/기존 암기장 + 시험지 여러 개 + 실전 모의고사 한 번에 |
create_exam · set_real_exam · set_visibility |
시험지 1개 · 실전 모의고사 설정 · 공개 전환 |
upload_image |
이미지(base64) 올려 url 받기 |
도구 입력은 아래 REST 본문과 같습니다. 실패하면 isError 결과에 한국어 사유가 옵니다 — 읽고 고쳐서 다시 호출하세요.
2. 인증
- 기본 주소:
https://api.moducbt.com - 헤더:
X-API-Key: mcbt_...(또는Authorization: Bearer mcbt_...) Content-Type: application/json- 키는 비밀번호처럼 다룹니다. 채팅·로그·저장소에 그대로 남기지 마세요. 새면 화면에서 폐기하고 새로 발급합니다.
3. 엔드포인트
| 요청 | 설명 |
|---|---|
GET /open/v1/schema |
문항 형식·한도 (인증 불필요) |
GET /open/v1/docs |
이 문서 (마크다운, 인증 불필요) |
GET /open/v1/categories |
내 암기장 목록(최근 100개) |
GET /open/v1/categories/{id} |
암기장 1개 — 시험지 목록(examId·제목·문항 수)·실전 모의고사 설정 |
POST /open/v1/import |
한 번에 등록 — 새/기존 암기장 + 시험지 여러 개 + 실전 모의고사 설정 |
POST /open/v1/categories |
암기장 만들기 — 항상 비공개 |
POST /open/v1/images |
이미지 올리기(자동 압축) → 주소 받기 |
POST /open/v1/validate |
저장 없이 문항 검사 |
POST /open/v1/categories/{id}/exams |
시험지(회차) + 문항 등록 |
POST /open/v1/categories/{id}/real-exam |
(객관식) 실전 모의고사 설정·해제 |
GET /open/v1/exams/{examId} |
시험지 문항 보기(questionId·번호 포함) |
POST /open/v1/exams/{examId}/questions/update |
문항 고치기(바꿀 칸만) |
POST /open/v1/exams/{examId}/questions/add |
문항 추가(시험지 끝) |
POST /open/v1/exams/{examId}/questions/delete |
문항 삭제(confirm: true 필수) |
GET /open/v1/exams/{examId}/revisions · POST /open/v1/revisions/{id}/restore |
수정 기록 · 되돌리기 |
POST /open/v1/categories/{id}/visibility |
공개·비공개 전환 |
한 번에 등록 (권장)
새 암기장을 만들면서 시험지 2개를 넣고 실전 모의고사까지 설정하는 예:
POST /open/v1/import
{
"category": { "name": "내 전기기능사 필기", "examType": "OBJECTIVE" },
"exams": [
{ "title": "1회차", "questions": [ ... ] },
{ "title": "2회차", "questions": [ ... ] }
],
"realExam": {
"subjects": [
{ "name": "전기이론", "numberFrom": 1, "numberTo": 20, "cutoffScore": 40 },
{ "name": "전기기기", "numberFrom": 21, "numberTo": 40, "cutoffScore": 40 },
{ "name": "전기설비", "numberFrom": 41, "numberTo": 60, "cutoffScore": 40 }
],
"overallPassScore": 60,
"timeLimitMinutes": 60
}
}
기존 암기장에 시험지를 추가할 때는 category 대신 "categoryId": 123을 보냅니다(암기장 유형은 그 암기장을 따릅니다).
- 모든 문항을 먼저 검사하고, 틀린 곳이 있으면 아무것도 만들지 않고
issues: [{ exam, index, message }](시험지 번호·문항 번호)를 돌려줍니다. - 응답:
{ ok, category: { id, created }, exams: [{ examId, title, questionCount, url }], realExam? } - 드물게 중간에 멈추면(하루 한도 등) 앞에서 저장된 시험지는
createdExams로 알려 줍니다. 나머지만categoryId로 다시 보내세요.
암기장 1개 보기
GET /open/v1/categories/123
→ { ok, category: { id, name, examType, isPublic, url,
exams: [{ examId, title, questionCount }], realExam: {...} | null } }
암기장 만들기
POST /open/v1/categories
{ "name": "내 전기기능사 요약 문제", "examType": "OBJECTIVE", "description": "선택" }
examType:"OBJECTIVE"(객관식·필기) 또는"SUBJECTIVE"(주관식·실기). 한 암기장에는 한 유형만 넣을 수 있습니다.- 이름이 이미 있으면
(2),(3)…이 자동으로 붙습니다. "필기 기출문제", "기출복원"처럼 공식 암기장과 헷갈리는 이름은 쓸 수 없습니다. 응답:{ ok, category: { id, name, examType, isPublic: false, url } }
이미지 올리기
curl -s -X POST https://api.moducbt.com/open/v1/images \
-H "X-API-Key: $KEY" -F "file=@circuit.png"
multipart/form-data의file필드로 한 번에 1장, 원본 최대 15MB (JPG·PNG·WebP·GIF·AVIF).- 큰 사진도 그대로 보내면 됩니다. 서버가 긴 변 1600px·약 500KB 이하의 WebP로 자동 압축하고, 위치정보(EXIF)는 지웁니다.
- 응답:
{ ok, image: { url, width, height, bytes, originalBytes, resized } }→url을 문항의images또는explanationImages에 넣습니다. - 이미지를 여러 장 올린 뒤 시험지를 등록하는 순서입니다. 쓰지 않은 이미지는 문항에 연결되지 않습니다.
- 이미지 업로드는 API 키로만 됩니다(로그인 쿠키 불가). 문항에는 이 API가 돌려준
url만 그대로 넣으세요.
검사(저장 안 함)
POST /open/v1/validate
{ "examType": "OBJECTIVE", "questions": [ ... ] }
응답: { ok, valid, questionCount, issues: [{ index, message }], warnings: [{ index, message }] } — index는 1부터 시작하는 문항 번호(0은 전체).
issues는 반드시 고쳐야 등록되는 오류입니다: 형식, 수식(KaTeX로 실제로 그려 보고 실패하면 알려 줌),$…$·<tex>밖 수식, 같은 시험지 안 중복 문항, 한 문항 안 같은 보기, base64, script 글자 등.warnings는 등록은 되지만 고치면 더 좋아지는 것입니다: 해설이 보기 번호로 답을 가리킴, 정답 위치 쏠림, 주관식 답안 항목이 한 줄에 붙음. 사용자에게 알려 주거나 고쳐서 다시 검사하세요.
시험지 등록
POST /open/v1/categories/{id}/exams
{ "title": "1회차", "questions": [ ... ] }
- 제목 앞에 항상
[암기장 이름]이 자동으로 붙고(직접 붙일 필요 없음), 겹치면(2)가 붙습니다. 응답의exam.title이 실제 저장된 제목입니다. - 하나라도 형식 오류가 있으면 아무것도 저장하지 않고 400과
issues를 돌려줍니다. - 같은 암기장에 같은 제목이 이미 있으면 409와
existingExamId를 돌려줍니다. 응답을 못 받고 다시 보낸 경우라면 이미 저장된 것이니GET /open/v1/categories/{id}로 확인하세요. 일부러 한 벌 더 만들 때만"allowDuplicateTitle": true를 보냅니다. - 요청은 하나씩 순서대로 보내세요. 이전 쓰기 요청이 끝나기 전에 보내면 429가 납니다.
- 응답:
{ ok, exam: { examId, title, questionCount, url } }
공개·비공개 전환
POST /open/v1/categories/{id}/visibility
{ "isPublic": true, "acknowledgeCopyright": true }
- 공개하려면
acknowledgeCopyright: true가 필수입니다. 비공개로 되돌릴 때는{ "isPublic": false }. - 공개·비공개는 암기장을 만든 사람만 바꿀 수 있습니다(공동편집자 불가).
4. 문항 JSON 형식
{
"questions": [
{
"type": "OBJECTIVE",
"question": "옴의 법칙에서 전류 I를 구하는 식은?",
"choices": ["<tex>V/R</tex>", "<tex>VR</tex>", "<tex>R/V</tex>", "<tex>V+R</tex>"],
"answer": 1,
"explanation": "전류는 전압에 비례하고 저항에 반비례하므로 <tex>I = V/R</tex> 이다."
},
{
"type": "SUBJECTIVE",
"question": "산업안전보건법상 안전보건표지의 종류 4가지를 쓰시오.",
"answer": "① 금지표지\n② 경고표지\n③ 지시표지\n④ 안내표지",
"explanation": "선택. 모범답안 아래에 [해설]로 붙습니다."
}
]
}
| 필드 | 객관식(OBJECTIVE) | 주관식(SUBJECTIVE) |
|---|---|---|
type |
"OBJECTIVE" |
"SUBJECTIVE" |
question |
필수, 최대 5,000자 | 필수 |
choices |
필수, 보기 2~6개 문자열 배열(권장 4개) | 사용 안 함 |
answer |
필수, 정답 보기 번호(1부터 시작하는 정수) | 필수, 모범답안 텍스트 |
explanation |
선택, 해설 | 선택, 모범답안 아래 [해설]로 붙음 |
images |
선택, 문제 그림 주소 배열(최대 5개) | 같음 |
explanationImages |
선택, 해설 그림 주소 배열(최대 5개) | 같음 |
- 그림은
POST /open/v1/images로 먼저 올리고 받은 주소만images/explanationImages에 넣습니다. 다른 사이트 주소, 다른 사람이 올린 주소는 거부됩니다. - 이미지를 base64 문자열(
data:image/...;base64,…)로 본문에 넣지 마세요. 검사에서 거부됩니다. - 그림은 문제 글 아래에 표시됩니다. 문제 글에 "다음 그림에서…"처럼 그림을 가리키는 말을 넣으세요.
- 표·수식으로 쓸 수 있는 것(간단한 표, 공식)은 그림보다
<table>·<tex>가 선명하고 검색도 됩니다.
5. 화면 서식 규칙 (에디터 특성)
모두CBT는 문항을 HTML 조각으로 저장하고 그대로 그립니다. 아래 규칙을 지키면 화면에서 깔끔하게 보입니다.
- 줄바꿈은
\n— 서버가<br>로 바꿉니다. 블록 사이(질문과 보기·조건 사이)는\n\n으로 한 줄 더 띄우세요. - 허용 태그:
b strong i em u s sup sub br p div span ul ol li table thead tbody tr th td code pre blockquote hr tex. 나머지 태그와 모든 속성(style·class·링크·이미지)은 지워집니다. 표 칸 합치기(colspan,rowspan)만 허용됩니다. - 꺾쇠: 허용 태그가 아닌
<는 서버가 글자로 보존합니다(예:A<B<C,<Ctrl>+C).<tex>안의<·>는\lt·\gt로 바뀝니다. 헷갈리지 않게 처음부터<>또는 수식<tex>a \lt b</tex>로 쓰는 것을 권합니다. - 표·목록 태그 앞뒤 줄바꿈은 서버가 지웁니다(표 안에 빈 줄이 생기지 않게). 표는 한 줄로 이어 써도 됩니다.
- 표는
<table>로 만들 수 있습니다. 3열 이하가 휴대폰에서 읽기 좋습니다.<table><tr><th>구분</th><th>값</th></tr><tr><td>정격전압</td><td>220V</td></tr></table> - 화학식·단위 첨자: 아래첨자
<sub>, 위첨자<sup>. 예)CO<sub>2</sub>,H<sub>2</sub>SO<sub>4</sub>,m<sup>2</sup>,10<sup>-3</sup> - 번호 기호: 순서·빈칸·항목 기호는
① ② ③ ④ …로 통일합니다(a b c,ㄱ ㄴ ㄷ,(1)(2)→①②③). 빈칸은(①),(②)로 표시합니다. - 조건·보기가 있는 문제의 권장 구조:
(질문 문장)\n\n[조건] 전압 220V, 저항 10Ω\n\n① …\n② … 같은 공백 엔티티로 줄을 맞추지 마세요. 줄마다\n으로 나눕니다.
6. 수식 규칙 (KaTeX)
수식은 <tex>…</tex> 태그 안에 쓴 KaTeX(LaTeX 문법)만 수식으로 그려집니다.
| 해야 할 것 | 하지 말 것 |
|---|---|
<tex>\dfrac{V}{R}</tex> |
$\dfrac{V}{R}$, \(…\), $$…$$ — 인식되지 않아 기호가 그대로 보임 |
한 줄 수식. 여러 식은 <tex>를 여러 개로 나누고 사이에 글 |
\begin{aligned}, \\ 줄바꿈 같은 여러 줄 환경 |
천 단위 콤마 1{,}000{,}000 |
1,000,000 (수식 안에서 간격이 깨짐) |
단위는 태그 밖: <tex>v = 6.54</tex> m/s |
단위까지 전부 태그 안에 넣기 |
부등호는 \lt, \gt, \le, \ge |
태그 안에 <, > 그대로 |
| 한글 설명은 태그 밖에 | \text{…} 안에 긴 한글 문장 |
⚠️ JSON 안에서는 백슬래시를 두 번 써야 합니다. JSON 문자열에서 \f, \t, \b, \n, \r는 제어문자로 바뀌어 \frac, \times, \beta가 조용히 깨집니다.
{ "question": "<tex>\\dfrac{1}{2} \\times 4 = 2</tex> 가 맞는가?" }
(화면에는 ½ × 4 = 2 로 보입니다. 검사 API가 한 번만 쓴 백슬래시를 찾아 알려 줍니다.)
계산 문제 예시
question: "전압 220V, 저항 10Ω 회로의 전류는 몇 A인가?"
choices: ["11", "22", "2.2", "220"] answer: 2
explanation: "<tex>I = \\dfrac{V}{R} = \\dfrac{220}{10} = 22</tex> A"
7. 좋은 암기장을 만드는 작성 규칙
공통
- 자료에 있는 내용만 씁니다. 수치·법령·기준값을 지어내지 마세요. 애매하면 그 문제는 빼세요.
- 문제는 짧고 분명하게. 판단에 필요한 조건·보기·구분은 문제 안에 넣습니다(해설로 빼면 문제가 성립하지 않습니다).
- 정답이 되는 용어는 원문 표기 그대로 씁니다. 임의 괄호 풀이·동의어를 덧붙이지 마세요. 예)
제노그램✅ /제노그램(직업가계도)❌ - 같은 내용을 묻는 문제를 반복하지 마세요.
객관식
- 보기는 4개를 권장합니다. 정답 위치(1~4)를 고르게 섞고, 오답도 그럴듯하게 만드세요.
- 해설은 1~3문장으로 왜 그 답인지 씁니다. "③번이 정답"처럼 보기 번호로 가리키지 말고 내용으로 씁니다. 예) "전류는 저항에 반비례하므로 V/R 이다."
- 계산 문제는 입력 수치를 직접 정하고 답을 한 번 더 계산해 검산하세요. 보기 안에 정답이 정확히 하나만 있어야 합니다.
- 해설 서식: 첫 문장에 정답 근거를 쓰고, 핵심어 2~4곳만
<b>로 강조합니다. 오답 이유를 여러 개 적을 때는<ul><li>…</li></ul>로 나눕니다. - 정답이 둘 이상이거나(복수정답) 모두 정답인 문제는
answer에 대표 번호 하나만 넣고, 해설 첫 줄에 "복수정답: ①, ③"처럼 적습니다. - 변수 첨자는 수식으로 씁니다: V₁ →
<tex>V_1</tex>. 화학식·단위는<sub>·<sup>(예:CO<sub>2</sub>,m<sup>2</sup>).
주관식 — 모범답안은 AI 쌤 채점 기준이 됩니다.
- 핵심어 위주로 간결하게. 서술형 법령 문장은 "핵심 동사구"로 줄입니다. 예) "근로자가 관리감독자의 지휘에 따라 작업하도록 할 것" → "관리감독자 지휘에 따라 작업"
- 여러 항목은 한 줄에 하나씩 번호를 붙입니다:
① 금지표지\n② 경고표지\n③ 지시표지. 빈칸형은①: 31\n②: 4처럼 빈칸 번호와 맞춥니다. - "N가지 쓰시오"는 N개 이상을 씁니다(대체 정답이 있으면 함께).
- 채점 키워드(용어·수치·단위·순서)는 절대 바꾸지 않습니다. 줄여도 되는 것은 어미·조사·군더더기뿐입니다.
- 모범답안 칸에 "(각 2가지씩 작성)" 같은 안내 문구를 넣지 마세요.
8. 실전 모의고사 설정 (객관식)
실전 모의고사는 암기장의 시험지들에서 과목별로 문제를 뽑아 실제 시험처럼 풀고, 과목별 과락과 평균 합격 점수로 합격·불합격을 알려 주는 기능입니다. 설정은 암기장을 만든 사람만 할 수 있습니다.
방식 ① 번호 범위 (대부분 이걸 씁니다) — 회차 시험지마다 전 과목이 순서대로 들어 있을 때. 예) 1회차 60문항 중 120번 = 1과목, 2140번 = 2과목…
POST /open/v1/categories/123/real-exam
{
"subjects": [
{ "name": "전기이론", "numberFrom": 1, "numberTo": 20, "cutoffScore": 40 },
{ "name": "전기기기", "numberFrom": 21, "numberTo": 40, "cutoffScore": 40 },
{ "name": "전기설비", "numberFrom": 41, "numberTo": 60, "cutoffScore": 40 }
],
"overallPassScore": 60,
"timeLimitMinutes": 60
}
- 문항 번호는 시험지에 넣은 순서(1부터) 입니다. 그래서 모든 회차 시험지를 같은 과목 순서·같은 문항 수로 만들어야 합니다.
- 각 과목은 모든 회차의 해당 번호 범위에서
questionCount개(기본 = 범위 안 문항 수)를 뽑습니다. - 출제에 쓸 시험지는 기본으로 이 암기장의 모든 시험지입니다. 일부만 쓰려면
"examIds": [시험지 id…]를 함께 보냅니다.
방식 ② 과목별 시험지 — 과목마다 시험지를 따로 만들었을 때. 예) "전기이론 문제은행", "전기기기 문제은행"
{
"subjects": [
{ "name": "전기이론", "examIds": [501], "questionCount": 20, "cutoffScore": 40 },
{ "name": "전기기기", "examIds": [502, 503], "questionCount": 20, "cutoffScore": 40 }
],
"overallPassScore": 60
}
| 필드 | 뜻 | 기본값·범위 |
|---|---|---|
subjects[].name |
과목명 | 필수, 40자 |
subjects[].numberFrom·numberTo |
(방식 ①) 과목 문항 번호 범위 | 1 이상, 시작 ≤ 끝 |
subjects[].examIds |
(방식 ②) 과목 출제 시험지 id | 이 암기장 안의 시험지만 |
subjects[].questionCount |
과목당 출제 수 | ① 기본 = 범위 크기 / ② 필수, 1~200 |
subjects[].cutoffScore |
과목 과락(100점 만점, 미만이면 과락) | 기본 40 |
overallPassScore |
전체 평균 합격 점수 | 기본 60 |
timeLimitMinutes |
제한 시간(분) | 선택, 1~600 |
notice |
응시자 안내문(평문) | 선택, 300자 |
- 과목은 1~10개. 한 설정 안에서는 한 가지 방식만 씁니다.
- 끄려면
{ "off": true }. 현재 설정은GET /open/v1/categories/{id}의realExam에서 봅니다. - ⚠️ 설정은 저장할 때의 시험지 목록을 기준으로 합니다. 나중에 시험지를 추가하면 이 설정을 한 번 더 보내야 새 시험지가 출제에 들어갑니다(시험지 등록 응답에
realExamNotice로 알려 줍니다).import에realExam을 같이 보내면 자동으로 다시 저장됩니다. - 응답의
warnings(예: 어떤 과목의 문항이 모자람)를 사용자에게 알려 주세요. - 실제 시험 기준(과목 구성·과락·합격 점수·시간)을 모르면 지어내지 말고 사용자에게 물어보세요. 많은 국가기술자격 필기는 과목당 40점 미만 과락·평균 60점 이상 합격이지만, 시험마다 다릅니다.
8-1. 기존 시험지 고치기
이미 등록한 시험지의 문제를 고치거나, 문항을 더하거나 지울 수 있습니다. 내가 만든 시험지(또는 공동편집 암기장의 시험지)만, 공식 암기장은 불가합니다.
GET /open/v1/categories/{id}→exams에서 시험지 id 확인GET /open/v1/exams/{examId}→ 문항마다questionId·number와 등록 때와 같은 형식의 내용- 고치기 — 바꿀 칸만 보냅니다. 문항 id가 그대로라 학생 풀이 기록·북마크·오답노트가 유지됩니다.
POST /open/v1/exams/29070/questions/update
{ "questions": [
{ "questionId": 1201, "explanation": "전류는 전압에 비례하고 저항에 반비례하므로 <tex>I = V/R</tex> 이다." },
{ "questionId": 1203, "choices": ["2", "4", "6", "8"], "answer": 2 }
] }
- 합쳐진 결과를 새 등록과 같은 규칙으로 검사하고, 하나라도 틀리면 아무것도 바꾸지 않습니다. 한 번에 100개까지.
- 바꾸기 전 내용은 백업됩니다.
GET …/revisions로 기록을 보고POST /open/v1/revisions/{id}/restore로 되돌립니다.
- 추가 —
POST …/questions/add { "questions": [...] }(시험지 끝에 붙음, 한도는 새 등록과 같음) - 삭제 —
POST …/questions/delete { "questionIds": [...], "confirm": true }. 되돌릴 수 없고 학생 풀이 기록도 사라지므로 반드시 사용자에게 먼저 확인하세요.confirm없이 보내면 영향(풀이 기록 수)만 알려 줍니다. 내용만 바꿀 땐 삭제 대신 고치기를 쓰세요.
- 실전 모의고사(번호 범위)를 쓰는 암기장에 문항을 추가·삭제하면 번호 범위가 달라질 수 있어요. 필요하면 실전 모의고사 설정을 다시 저장하세요.
9. 한도와 오류 처리
| 항목 | 한도 |
|---|---|
| 시험지 1개당 문항 | 300문항 |
| 한 번에 등록(import) | 시험지 10개 · 문항 합계 300개 |
| 암기장 1개당 시험지 | 300개 |
| 하루 등록 | 2,000문항 · 암기장 20개 |
| 호출 | 등록 분당 10회 · 시간당 120회 · 조회 분당 60회 |
| 문항 1개(문제+보기+답+해설 합계) | 10,000자 |
| 하루 등록 글자 수 | 3,000,000자 |
| 요청 크기 | 2MB (이미지는 15MB) |
| 이미지 | 분당 30장 · 하루 300장 · 한 번에 1장 |
| API 키 | 계정당 5개 |
| 응답 | 뜻 | 할 일 |
|---|---|---|
400 + issues |
문항 형식 오류 — 아무것도 저장 안 됨 | 번호별 사유대로 고쳐 다시 보냄 |
401 |
키 없음·틀림·폐기 | 키 확인, 필요하면 재발급 |
403 |
내 암기장이 아님 / 저작권 게시중단 암기장 / 실전 모의고사는 만든 사람만 | 내 암기장 id 사용 |
413 |
요청이 너무 큼 | 문항을 나눠 보냄 |
409 |
같은 암기장에 같은 제목의 시험지가 이미 있음 | 이미 저장됐는지 확인. 새 제목을 쓰거나 allowDuplicateTitle: true |
415 |
JSON 이 아닌 본문 | Content-Type: application/json 으로 보냄 |
429 |
호출 제한 · 이전 요청 처리 중 | 60초 기다린 뒤(처리 중이면 응답 받은 뒤) 다시 시도 |
503 |
이미지 업로드 일시 중지 | 잠시 후 다시 시도, 급하면 그림 없이 등록 |
모든 오류는 한국어 message를 담고 있습니다. AI는 message와 issues를 읽고 스스로 고치세요.
10. 공개 전환과 저작권
⚠️ 공개 전환 시 저작권에 유의해 주세요. 교재·강의·타 사이트의 문제와 해설을 그대로 옮긴 암기장은 공개할 수 없으며, 저작권 신고가 들어오면 게시가 중단되고 이용이 제한될 수 있어요.
- API로 만든 암기장은 항상 비공개로 시작합니다. 비공개 암기장은 나만 볼 수 있습니다.
- 공개는 사용자가 원할 때만,
acknowledgeCopyright: true와 함께 따로 요청합니다. - 직접 정리한 노트, 강의 필기처럼 내가 쓸 권리가 있는 자료로 만드세요. 교재·타 사이트 문제를 그대로 옮기는 것은 비공개라도 권하지 않습니다.
- 저작권 신고로 게시가 중단된 암기장은 다시 공개할 수 없습니다(
403).
11. 전체 예시 (curl)
KEY="mcbt_여기에_발급받은_키"
# 1) 암기장 만들기
curl -s -X POST https://api.moducbt.com/open/v1/categories \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"name":"내 전기기능사 요약 문제","examType":"OBJECTIVE"}'
# 2) (그림이 있으면) 이미지 올리기 → 응답의 image.url 을 문항 images 에
curl -s -X POST https://api.moducbt.com/open/v1/images \
-H "X-API-Key: $KEY" -F "file=@circuit.png"
# 3) 검사
curl -s -X POST https://api.moducbt.com/open/v1/validate \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d @questions.json
# 4) 등록 ({id}는 1번 응답의 category.id)
curl -s -X POST https://api.moducbt.com/open/v1/categories/{id}/exams \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"title":"1회차","questions":[{"type":"OBJECTIVE","question":"전압 220V, 저항 10Ω 회로의 전류는 몇 A인가?","choices":["11","22","2.2","220"],"answer":2,"explanation":"<tex>I = \\dfrac{220}{10} = 22</tex> A"}]}'
12. AI에게 맡길 때 쓰는 지시문 예시
모두CBT 오픈 API로 내 암기장에 문제를 등록해 줘.
1) https://api.moducbt.com/open/v1/docs 를 먼저 끝까지 읽고 그 규칙을 지켜.
2) 인증 헤더: X-API-Key: mcbt_…
3) 새 암기장을 만들지, 기존 암기장(GET /open/v1/categories)에 시험지를 추가할지 먼저 나한테 물어봐.
아래 자료로 문제를 만들어 validate 로 검사한 뒤 POST /open/v1/import 로 등록해.
객관식이면 실전 모의고사 설정(과목·과락·합격 점수·시간)을 할지도 물어보고, 기준은 지어내지 마.
그림이 필요한 문제는 POST /open/v1/images 로 그림을 먼저 올리고 받은 url 을 images 에 넣어.
4) 한 시험지는 최대 300문항, 429면 60초 기다렸다 재시도.
5) 공개 전환은 내가 요청할 때만. 끝나면 암기장 주소와 등록한 문항 수를 알려 줘.
[자료]
(여기에 자료)