{"openapi":"3.1.0","info":{"title":"Docuel REST API","version":"1.0.0","description":"도큐엘(Docuel) 문서 플랫폼 API — 문서·양식·입력 데이터·가져오기·디렉터리·로그"},"servers":[{"url":"https://docuel.com/api/v1"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"문서","description":"양식(template)과 작성 문서(document)를 만들고 조회·수정합니다. 둘은 같은 객체이며 kind 로 구분합니다."},{"name":"입력 데이터","description":"문서 구조는 그대로 두고 필드 값만 읽고 씁니다. 외부 시스템 연동의 핵심입니다."},{"name":"양식으로 문서 만들기","description":"양식에 데이터를 넣어 새 문서를 만듭니다."},{"name":"휴지통","description":"삭제한 문서는 휴지통에 보관되며 복원하거나 영구 삭제할 수 있습니다."},{"name":"버전","description":"저장할 때마다 버전이 기록되며, 이전 버전으로 되돌릴 수 있습니다."},{"name":"파일","description":"첨부 필드·이미지에 사용할 파일을 올리고 내려받습니다."},{"name":"가져오기 (AI 변환)","description":"이미지·엑셀·워드·HTML·LML 을 구조화 문서로 변환합니다. 비동기로 처리됩니다."},{"name":"데이터 연동 (외부 API)","description":"양식에 연결한 외부 API 를 실행해 응답의 단독 값은 필드로, 배열은 반복 행으로 채웁니다. 연동 설정은 콘솔의 양식 › 연동 화면에서 합니다."},{"name":"작성 요청 (모바일)","description":"양식을 작업일지·점검표·신청서로 배포하고, 수신자별 모바일 링크로 값 입력·체크·사진 첨부·서명을 받습니다. 매일/평일 반복이면 날짜마다 새 문서가 만들어집니다. 안전관리·현장관리 플랫폼은 받은 링크를 자기 앱 푸시·문자로 보내면 됩니다."},{"name":"전자결재","description":"작성된 문서를 결재선(결재·합의·참조·수신)에 따라 상신하고 승인·반려합니다. 결재자는 디렉터리(외부 플랫폼 회원·부서·직책)에서 지정하며, 승인하면 문서의 결재란에 도장(또는 서명)이 찍히고 최종 승인 시 문서가 봉인됩니다. 외부 결재자는 단계별 링크로 모바일에서 바로 처리합니다."},{"name":"디렉터리","description":"외부 플랫폼의 회원·부서·직위·직책을 동기화합니다. 전자결재 결재선과 권한에 사용됩니다."},{"name":"계정·사용량","description":"API 키 정보, 요금제와 사용량을 확인합니다."},{"name":"로그","description":"조직에서 일어난 모든 행위를 조회합니다."}],"paths":{"/documents":{"get":{"operationId":"list-documents","tags":["문서"],"summary":"문서 목록","description":"조직의 문서·양식을 최근 수정 순으로 조회합니다.\n\n본문(content)과 데이터(data)는 포함하지 않습니다. 개별 조회를 사용하세요.\n\n다음 페이지는 응답의 nextCursor 를 before 로 넘겨 조회합니다.\n\n필요 권한: `documents:read`","parameters":[{"name":"kind","in":"query","required":false,"description":"document · template · all (기본 document)","schema":{"type":"string","enum":["document","template","all"]},"example":"all"},{"name":"q","in":"query","required":false,"description":"제목·분류 부분 일치 검색","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"상태 필터","schema":{"type":"string","enum":["draft","published","submitted","in_approval","approved","rejected","completed","archived"]}},{"name":"category","in":"query","required":false,"description":"분류 정확히 일치","schema":{"type":"string"}},{"name":"templateId","in":"query","required":false,"description":"특정 양식으로 만든 문서만","schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"description":"1~200, 기본 50","schema":{"type":"integer"},"example":"20"},{"name":"before","in":"query","required":false,"description":"커서 — 이전 응답의 nextCursor","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"목록","content":{"application/json":{"example":{"data":{"items":[{"id":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","kind":"document","title":"11월 출장비 정산","category":"경비","status":"draft","version":3,"templateId":"c4b836b9-eb85-4b68-9887-c6cbb3087519","createdBy":"user:…","updatedBy":"api_key:…","createdAt":"2026-11-03T12:00:00.000Z","updatedAt":"2026-11-03T12:00:00.000Z","deletedAt":null,"deletedBy":null}],"nextCursor":null}}}}}}},"post":{"operationId":"create-document","tags":["문서"],"summary":"문서 만들기","description":"빈 문서, 양식, 또는 양식에서 시작하는 문서를 만듭니다.\n\n양식(kind=template)을 만들려면 templates:write 권한이 필요합니다.\n\n계산식 필드의 결과는 저장 시 data 에 자동으로 채워집니다.\n\n필요 권한: `documents:write`","parameters":[],"responses":{"200":{"description":"생성된 문서 객체","content":{"application/json":{"example":{"data":{"id":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","orgId":"1f0b6c2e-3d4a-4e5f-8a9b-0c1d2e3f4a5b","kind":"document","title":"11월 출장비 정산","description":null,"category":"경비","folderId":null,"templateId":"c4b836b9-eb85-4b68-9887-c6cbb3087519","status":"draft","content":{"schema":"zdoc/1","page":{"size":"A4","orientation":"portrait","margin":{"top":15,"right":15,"bottom":15,"left":15}},"style":{"fontFamily":"Pretendard","fontSize":10,"lineHeight":1.5,"color":"#111111"},"header":null,"footer":null,"body":{"type":"doc","content":[{"type":"heading","attrs":{"level":1,"textAlign":"center"},"content":[{"type":"text","text":"지 출 결 의 서"}]},{"type":"table","content":["…"]}]}},"data":{"docNo":"EXP-2026-0042","dept":"플랫폼개발팀","writer":"홍길동","kind":"법인카드","items":[{"no":1,"date":"2026-11-03","desc":"KTX 서울↔부산","qty":1,"amount":59800},{"no":2,"date":"2026-11-04","desc":"숙박","qty":1,"amount":92000}],"total":151800},"version":3,"contentHash":"3b1f…","tags":[],"ownerUserId":null,"ownerDirectoryId":null,"createdBy":"api_key:a9fc8451-dbb2-4fa2-911a-8bd8de2a84d0","updatedBy":"api_key:a9fc8451-dbb2-4fa2-911a-8bd8de2a84d0","sealedAt":null,"createdAt":"2026-11-03T12:00:00.000Z","updatedAt":"2026-11-03T12:00:00.000Z","deletedAt":null,"deletedBy":null}}}}},"429":{"description":"rate_limited: 요금제의 문서 수 한도 초과","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","description":"작성 문서 또는 양식. 기본 document (\"document\" | \"template\")"},"title":{"type":"string","description":"제목 (1~200자). 기본 \"제목 없는 문서\""},"description":{"type":"string","description":"설명 (string | null)"},"category":{"type":"string","description":"분류 (목록 필터에 사용) (string | null)"},"content":{"type":"object","description":"문서 구조. 생략하면 빈 A4 문서 (templateId 가 있으면 양식 구조를 복사)"},"data":{"type":"object","description":"필드 입력값. 필드 key 를 속성으로, 반복 행은 배열로"},"templateId":{"type":"string","description":"양식에서 시작할 때 양식 ID — 구조와 기본값을 복사 (uuid | null)"},"tags":{"type":"array","description":"태그 (최대 20개)"}}},"example":{"kind":"document","title":"API 로 만든 문서","category":"테스트"}}}}}},"/documents/{id}":{"get":{"operationId":"get-document","tags":["문서"],"summary":"문서 조회","description":"문서 구조(content)와 입력값(data)을 포함한 전체 객체를 조회합니다.\n\ninclude=fields 를 지정하면 문서 안의 입력 필드 목록과 반복 행 키를, include=schema 를 지정하면 data 의 JSON Schema 를 함께 돌려줍니다. 외부 시스템이 어떤 값을 보내야 하는지 자동으로 파악할 때 사용합니다.\n\n필요 권한: `documents:read`","parameters":[{"name":"id","in":"path","required":true,"description":"문서 ID","schema":{"type":"string","format":"uuid"},"example":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00"},{"name":"include","in":"query","required":false,"description":"fields, schema (쉼표 구분)","schema":{"type":"string"},"example":"fields,schema"}],"responses":{"200":{"description":"문서 객체","content":{"application/json":{"example":{"data":{"id":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","orgId":"1f0b6c2e-3d4a-4e5f-8a9b-0c1d2e3f4a5b","kind":"document","title":"11월 출장비 정산","description":null,"category":"경비","folderId":null,"templateId":"c4b836b9-eb85-4b68-9887-c6cbb3087519","status":"draft","content":{"schema":"zdoc/1","page":{"size":"A4","orientation":"portrait","margin":{"top":15,"right":15,"bottom":15,"left":15}},"style":{"fontFamily":"Pretendard","fontSize":10,"lineHeight":1.5,"color":"#111111"},"header":null,"footer":null,"body":{"type":"doc","content":[{"type":"heading","attrs":{"level":1,"textAlign":"center"},"content":[{"type":"text","text":"지 출 결 의 서"}]},{"type":"table","content":["…"]}]}},"data":{"docNo":"EXP-2026-0042","dept":"플랫폼개발팀","writer":"홍길동","kind":"법인카드","items":[{"no":1,"date":"2026-11-03","desc":"KTX 서울↔부산","qty":1,"amount":59800},{"no":2,"date":"2026-11-04","desc":"숙박","qty":1,"amount":92000}],"total":151800},"version":3,"contentHash":"3b1f…","tags":[],"ownerUserId":null,"ownerDirectoryId":null,"createdBy":"api_key:a9fc8451-dbb2-4fa2-911a-8bd8de2a84d0","updatedBy":"api_key:a9fc8451-dbb2-4fa2-911a-8bd8de2a84d0","sealedAt":null,"createdAt":"2026-11-03T12:00:00.000Z","updatedAt":"2026-11-03T12:00:00.000Z","deletedAt":null,"deletedBy":null,"fields":[{"key":"dept","type":"text","label":"부서","required":false,"repeat":null},{"key":"amount","type":"currency","label":"금액","repeat":"items"}],"repeats":["items"],"dataSchema":{"type":"object","properties":{"dept":{"type":"string","title":"부서"},"items":{"type":"array","items":{"type":"object","properties":{"amount":{"type":"number","title":"금액"}}}}}}}}}}},"404":{"description":"not_found: 없거나 다른 조직의 문서, 또는 휴지통에 있는 문서","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"update-document","tags":["문서"],"summary":"문서 수정","description":"제목·상태·구조·입력값을 수정합니다. 보낸 항목만 바뀝니다.\n\ncontent 를 바꾸려면 양식은 templates:write, 문서는 documents:write 권한이 필요합니다.\n\n동시 편집 충돌을 막으려면 baseVersion 에 편집을 시작한 버전을 보내세요. 그 사이 다른 저장이 있었다면 409 를 돌려줍니다.\n\n결재가 완료되어 봉인(sealedAt)된 문서는 content·data 를 바꿀 수 없습니다.\n\n필요 권한: `documents:write`","parameters":[{"name":"id","in":"path","required":true,"description":"문서 ID","schema":{"type":"string","format":"uuid"},"example":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00"}],"responses":{"200":{"description":"수정된 문서 객체","content":{"application/json":{"example":{"data":{"id":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","orgId":"1f0b6c2e-3d4a-4e5f-8a9b-0c1d2e3f4a5b","kind":"document","title":"11월 출장비 정산 (최종)","description":null,"category":"경비","folderId":null,"templateId":"c4b836b9-eb85-4b68-9887-c6cbb3087519","status":"completed","content":{"schema":"zdoc/1","page":{"size":"A4","orientation":"portrait","margin":{"top":15,"right":15,"bottom":15,"left":15}},"style":{"fontFamily":"Pretendard","fontSize":10,"lineHeight":1.5,"color":"#111111"},"header":null,"footer":null,"body":{"type":"doc","content":[{"type":"heading","attrs":{"level":1,"textAlign":"center"},"content":[{"type":"text","text":"지 출 결 의 서"}]},{"type":"table","content":["…"]}]}},"data":{"docNo":"EXP-2026-0042","dept":"플랫폼개발팀","writer":"홍길동","kind":"법인카드","items":[{"no":1,"date":"2026-11-03","desc":"KTX 서울↔부산","qty":1,"amount":59800},{"no":2,"date":"2026-11-04","desc":"숙박","qty":1,"amount":92000}],"total":151800},"version":4,"contentHash":"3b1f…","tags":[],"ownerUserId":null,"ownerDirectoryId":null,"createdBy":"api_key:a9fc8451-dbb2-4fa2-911a-8bd8de2a84d0","updatedBy":"api_key:a9fc8451-dbb2-4fa2-911a-8bd8de2a84d0","sealedAt":null,"createdAt":"2026-11-03T12:00:00.000Z","updatedAt":"2026-11-03T12:00:00.000Z","deletedAt":null,"deletedBy":null}}}}},"403":{"description":"forbidden: 양식 구조 수정 권한(templates:write) 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"conflict: baseVersion 불일치 또는 봉인된 문서","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"제목"},"status":{"type":"string","description":"draft · published · submitted · in_approval · approved · rejected · completed · archived"},"description":{"type":"string","description":"설명 (string | null)"},"category":{"type":"string","description":"분류 (string | null)"},"content":{"type":"object","description":"문서 구조 전체 (부분 수정 불가)"},"data":{"type":"object","description":"입력값 전체 (병합하려면 /data PATCH 사용)"},"tags":{"type":"array","description":"태그"},"baseVersion":{"type":"integer","description":"낙관적 잠금 — 현재 버전과 다르면 409"},"reason":{"type":"string","description":"버전 기록에 남길 사유"}}},"example":{"title":"11월 출장비 정산 (최종)","status":"completed"}}}}},"delete":{"operationId":"delete-document","tags":["문서"],"summary":"문서 삭제","description":"문서를 휴지통으로 옮깁니다. permanent=true 이면 휴지통에 있는 문서를 영구 삭제합니다.\n\n필요 권한: `documents:write`","parameters":[{"name":"id","in":"path","required":true,"description":"문서 ID","schema":{"type":"string","format":"uuid"},"example":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00"},{"name":"permanent","in":"query","required":false,"description":"true: 휴지통 문서 영구 삭제 (되돌릴 수 없음)","schema":{"type":"boolean","enum":["true"]}}],"responses":{"200":{"description":"처리됨","content":{"application/json":{"example":{"ok":true}}}},"400":{"description":"bad_request: 휴지통에 없는 문서를 permanent=true 로 삭제","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/documents/{id}/copy":{"post":{"operationId":"copy-document","tags":["문서"],"summary":"문서 복사","description":"구조와 입력값을 그대로 복사한 새 문서를 만듭니다.\n\n양식을 kind=document 로 복사하면 그 양식에서 시작한 문서가 됩니다 (templateId 연결).\n\n필요 권한: `documents:write`","parameters":[{"name":"id","in":"path","required":true,"description":"문서 ID","schema":{"type":"string","format":"uuid"},"example":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00"}],"responses":{"200":{"description":"새 문서 객체","content":{"application/json":{"example":{"data":{"id":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","orgId":"1f0b6c2e-3d4a-4e5f-8a9b-0c1d2e3f4a5b","kind":"document","title":"11월 출장비 정산 (사본)","description":null,"category":"경비","folderId":null,"templateId":"c4b836b9-eb85-4b68-9887-c6cbb3087519","status":"draft","content":{"schema":"zdoc/1","page":{"size":"A4","orientation":"portrait","margin":{"top":15,"right":15,"bottom":15,"left":15}},"style":{"fontFamily":"Pretendard","fontSize":10,"lineHeight":1.5,"color":"#111111"},"header":null,"footer":null,"body":{"type":"doc","content":[{"type":"heading","attrs":{"level":1,"textAlign":"center"},"content":[{"type":"text","text":"지 출 결 의 서"}]},{"type":"table","content":["…"]}]}},"data":{"docNo":"EXP-2026-0042","dept":"플랫폼개발팀","writer":"홍길동","kind":"법인카드","items":[{"no":1,"date":"2026-11-03","desc":"KTX 서울↔부산","qty":1,"amount":59800},{"no":2,"date":"2026-11-04","desc":"숙박","qty":1,"amount":92000}],"total":151800},"version":1,"contentHash":"3b1f…","tags":[],"ownerUserId":null,"ownerDirectoryId":null,"createdBy":"api_key:a9fc8451-dbb2-4fa2-911a-8bd8de2a84d0","updatedBy":"api_key:a9fc8451-dbb2-4fa2-911a-8bd8de2a84d0","sealedAt":null,"createdAt":"2026-11-03T12:00:00.000Z","updatedAt":"2026-11-03T12:00:00.000Z","deletedAt":null,"deletedBy":null}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"새 제목 (기본: 원래 제목 + \" (사본)\")"},"kind":{"type":"string","description":"바꿀 종류 (기본: 원본과 동일) (\"document\" | \"template\")"}}},"example":{"title":"11월 출장비 정산 (사본)"}}}}}},"/documents/{id}/data":{"get":{"operationId":"get-data","tags":["입력 데이터"],"summary":"입력값 조회","description":"문서의 필드 입력값만 조회합니다. 계산식 결과(합계 등)도 포함됩니다.\n\n필요 권한: `documents:read`","parameters":[{"name":"id","in":"path","required":true,"description":"문서 ID","schema":{"type":"string","format":"uuid"},"example":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00"}],"responses":{"200":{"description":"data 객체","content":{"application/json":{"example":{"data":{"docNo":"EXP-2026-0042","dept":"플랫폼개발팀","writer":"홍길동","kind":"법인카드","items":[{"no":1,"date":"2026-11-03","desc":"KTX 서울↔부산","qty":1,"amount":59800},{"no":2,"date":"2026-11-04","desc":"숙박","qty":1,"amount":92000}],"total":151800}}}}}}},"patch":{"operationId":"patch-data","tags":["입력 데이터"],"summary":"입력값 병합","description":"보낸 키만 덮어씁니다. 나머지 값은 유지됩니다.\n\n최상위 키 단위로 병합합니다. 반복 행 배열(items 등)은 통째로 교체되므로, 행을 덧붙이려면 /rows 를 사용하세요.\n\n필드 key 는 GET /documents/{id}?include=fields 로 확인할 수 있습니다.\n\n필요 권한: `documents:write`","parameters":[{"name":"id","in":"path","required":true,"description":"문서 ID","schema":{"type":"string","format":"uuid"},"example":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00"}],"responses":{"200":{"description":"병합 후 data","content":{"application/json":{"example":{"data":{"docNo":"EXP-2026-0042","dept":"플랫폼개발팀","writer":"홍길동","kind":"법인카드","items":[{"no":1,"date":"2026-11-03","desc":"KTX 서울↔부산","qty":1,"amount":59800},{"no":2,"date":"2026-11-04","desc":"숙박","qty":1,"amount":92000}],"total":151800}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"필드 값. 숫자·금액은 number, 날짜는 YYYY-MM-DD, 체크박스(복수)는 string[], 첨부는 [{ id, name, size }]"},"example":{"dept":"플랫폼개발팀","writer":"홍길동","kind":"법인카드"}}}}},"put":{"operationId":"put-data","tags":["입력 데이터"],"summary":"입력값 교체","description":"data 전체를 보낸 값으로 바꿉니다. 보내지 않은 키는 지워집니다.\n\n필요 권한: `documents:write`","parameters":[{"name":"id","in":"path","required":true,"description":"문서 ID","schema":{"type":"string","format":"uuid"},"example":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00"}],"responses":{"200":{"description":"교체 후 data","content":{"application/json":{"example":{"data":{"docNo":"EXP-2026-0042","dept":"플랫폼개발팀","writer":"홍길동","kind":"법인카드","items":[{"no":1,"date":"2026-11-03","desc":"KTX 서울↔부산","qty":1,"amount":59800},{"no":2,"date":"2026-11-04","desc":"숙박","qty":1,"amount":92000}],"total":151800}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"전체 입력값"},"example":{"docNo":"EXP-2026-0042","dept":"플랫폼개발팀","writer":"홍길동","kind":"법인카드","items":[{"no":1,"date":"2026-11-03","desc":"KTX 서울↔부산","qty":1,"amount":59800},{"no":2,"date":"2026-11-04","desc":"숙박","qty":1,"amount":92000}],"total":151800}}}}}},"/documents/{id}/rows":{"post":{"operationId":"append-rows","tags":["입력 데이터"],"summary":"반복 행 추가","description":"표의 반복 행(예: 품목 목록)에 행을 덧붙이거나 전체를 교체합니다.\n\n반복 행은 양식 디자인에서 표의 행에 데이터 키(예: items)를 지정해 만듭니다. 행 안의 필드 key 가 각 객체의 속성이 됩니다.\n\n행이 많아 페이지를 넘기면 미리보기·인쇄에서 자동으로 다음 페이지로 이어지고, 머리행은 페이지마다 반복됩니다.\n\n필요 권한: `documents:write`","parameters":[{"name":"id","in":"path","required":true,"description":"문서 ID","schema":{"type":"string","format":"uuid"},"example":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00"}],"responses":{"200":{"description":"결과","content":{"application/json":{"example":{"data":{"id":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","version":5,"repeat":"items","count":3}}}}},"400":{"description":"bad_request: 문서에 없는 repeat 키","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"repeat":{"type":"string","description":"반복 행 키 (예: items) — 문서에 없으면 400"},"rows":{"type":"array","description":"추가할 행 (1~5,000개)"},"mode":{"type":"string","description":"append(기본): 뒤에 추가 · replace: 전체 교체 (\"append\" | \"replace\")"}},"required":["repeat","rows"]},"example":{"repeat":"items","rows":[{"date":"2026-11-05","desc":"택시","qty":1,"amount":18400}],"mode":"append"}}}}}},"/templates/{id}/instantiate":{"post":{"operationId":"instantiate-template","tags":["양식으로 문서 만들기"],"summary":"양식 + 데이터 → 문서","description":"양식 구조에 데이터를 넣은 새 문서를 만듭니다. 외부 시스템에서 문서를 자동 생성하는 가장 일반적인 방법입니다.\n\ndata 의 반복 행 배열 길이만큼 표 행이 늘어납니다.\n\n응답의 url 로 사용자가 바로 열어 확인·수정할 수 있습니다.\n\n필요 권한: `documents:write`","parameters":[{"name":"id","in":"path","required":true,"description":"양식 ID","schema":{"type":"string","format":"uuid"},"example":"c4b836b9-eb85-4b68-9887-c6cbb3087519"}],"responses":{"200":{"description":"생성된 문서 요약","content":{"application/json":{"example":{"data":{"id":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","title":"11월 출장비 정산","version":1,"url":"https://docuel.com/app/d/8f2c41d0-…"}}}}},"400":{"description":"bad_request: id 가 양식이 아닌 문서","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"문서 제목 (기본: 양식 제목)"},"data":{"type":"object","description":"입력값 (필드 key 기준) — 연동 값보다 우선"},"sources":{"type":"array","description":"추가로 실행할 연동 이름·ID (자동 실행 연동은 항상 실행)"},"params":{"type":"object","description":"연동 변수 값 (예: { date, site })"}}},"example":{"title":"11월 출장비 정산","data":{"dept":"플랫폼개발팀","writer":"홍길동","kind":"법인카드","items":[{"no":1,"date":"2026-11-03","desc":"KTX 서울↔부산","qty":1,"amount":59800},{"no":2,"date":"2026-11-04","desc":"숙박","qty":1,"amount":92000}]}}}}}}},"/trash":{"get":{"operationId":"list-trash","tags":["휴지통"],"summary":"휴지통 목록","description":"삭제된 문서·양식을 삭제 순으로 조회합니다.\n\n필요 권한: `documents:read`","parameters":[{"name":"limit","in":"query","required":false,"description":"1~200, 기본 50","schema":{"type":"integer"},"example":"20"}],"responses":{"200":{"description":"목록","content":{"application/json":{"example":{"data":{"items":[{"id":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","kind":"document","title":"11월 출장비 정산","category":"경비","status":"draft","version":3,"templateId":"c4b836b9-eb85-4b68-9887-c6cbb3087519","createdBy":"user:…","updatedBy":"api_key:…","createdAt":"2026-11-03T12:00:00.000Z","updatedAt":"2026-11-03T12:00:00.000Z","deletedAt":"2026-11-03T12:00:00.000Z","deletedBy":"user:…"}],"nextCursor":null}}}}}}},"delete":{"operationId":"empty-trash","tags":["휴지통"],"summary":"휴지통 비우기","description":"휴지통의 모든 문서를 영구 삭제합니다. 되돌릴 수 없습니다.\n\n필요 권한: `documents:write`","parameters":[],"responses":{"200":{"description":"삭제 수","content":{"application/json":{"example":{"data":{"purged":4}}}}}}}},"/documents/{id}/restore":{"post":{"operationId":"restore-document","tags":["휴지통"],"summary":"휴지통에서 복원","description":"휴지통의 문서를 되살립니다.\n\n필요 권한: `documents:write`","parameters":[{"name":"id","in":"path","required":true,"description":"휴지통 문서 ID","schema":{"type":"string","format":"uuid"},"example":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00"}],"responses":{"200":{"description":"복원된 문서","content":{"application/json":{"example":{"data":{"id":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","orgId":"1f0b6c2e-3d4a-4e5f-8a9b-0c1d2e3f4a5b","kind":"document","title":"11월 출장비 정산","description":null,"category":"경비","folderId":null,"templateId":"c4b836b9-eb85-4b68-9887-c6cbb3087519","status":"draft","content":{"schema":"zdoc/1","page":{"size":"A4","orientation":"portrait","margin":{"top":15,"right":15,"bottom":15,"left":15}},"style":{"fontFamily":"Pretendard","fontSize":10,"lineHeight":1.5,"color":"#111111"},"header":null,"footer":null,"body":{"type":"doc","content":[{"type":"heading","attrs":{"level":1,"textAlign":"center"},"content":[{"type":"text","text":"지 출 결 의 서"}]},{"type":"table","content":["…"]}]}},"data":{"docNo":"EXP-2026-0042","dept":"플랫폼개발팀","writer":"홍길동","kind":"법인카드","items":[{"no":1,"date":"2026-11-03","desc":"KTX 서울↔부산","qty":1,"amount":59800},{"no":2,"date":"2026-11-04","desc":"숙박","qty":1,"amount":92000}],"total":151800},"version":3,"contentHash":"3b1f…","tags":[],"ownerUserId":null,"ownerDirectoryId":null,"createdBy":"api_key:a9fc8451-dbb2-4fa2-911a-8bd8de2a84d0","updatedBy":"api_key:a9fc8451-dbb2-4fa2-911a-8bd8de2a84d0","sealedAt":null,"createdAt":"2026-11-03T12:00:00.000Z","updatedAt":"2026-11-03T12:00:00.000Z","deletedAt":null,"deletedBy":null}}}}}}}},"/documents/{id}/versions":{"get":{"operationId":"list-versions","tags":["버전"],"summary":"버전 기록","description":"저장 이력을 최신순으로 최대 200개 조회합니다.\n\n필요 권한: `documents:read`","parameters":[{"name":"id","in":"path","required":true,"description":"문서 ID","schema":{"type":"string","format":"uuid"},"example":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00"}],"responses":{"200":{"description":"버전 목록","content":{"application/json":{"example":{"data":[{"version":3,"title":"11월 출장비 정산","reason":"rows:items","createdBy":"api_key:…","createdAt":"2026-11-03T12:00:00.000Z"},{"version":1,"title":"11월 출장비 정산","reason":"create","createdBy":"user:…","createdAt":"2026-11-03T12:00:00.000Z"}]}}}}}}},"/documents/{id}/versions/{version}/restore":{"post":{"operationId":"restore-version","tags":["버전"],"summary":"버전 되돌리기","description":"지정한 버전의 구조·입력값·제목으로 되돌립니다. 현재 내용은 이전 버전으로 보존되고, 되돌린 결과가 새 버전이 됩니다.\n\n필요 권한: `documents:write`","parameters":[{"name":"id","in":"path","required":true,"description":"문서 ID","schema":{"type":"string","format":"uuid"},"example":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00"},{"name":"version","in":"path","required":true,"description":"되돌릴 버전 번호","schema":{"type":"integer"},"example":"1"}],"responses":{"200":{"description":"되돌린 문서","content":{"application/json":{"example":{"data":{"id":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","orgId":"1f0b6c2e-3d4a-4e5f-8a9b-0c1d2e3f4a5b","kind":"document","title":"11월 출장비 정산","description":null,"category":"경비","folderId":null,"templateId":"c4b836b9-eb85-4b68-9887-c6cbb3087519","status":"draft","content":{"schema":"zdoc/1","page":{"size":"A4","orientation":"portrait","margin":{"top":15,"right":15,"bottom":15,"left":15}},"style":{"fontFamily":"Pretendard","fontSize":10,"lineHeight":1.5,"color":"#111111"},"header":null,"footer":null,"body":{"type":"doc","content":[{"type":"heading","attrs":{"level":1,"textAlign":"center"},"content":[{"type":"text","text":"지 출 결 의 서"}]},{"type":"table","content":["…"]}]}},"data":{"docNo":"EXP-2026-0042","dept":"플랫폼개발팀","writer":"홍길동","kind":"법인카드","items":[{"no":1,"date":"2026-11-03","desc":"KTX 서울↔부산","qty":1,"amount":59800},{"no":2,"date":"2026-11-04","desc":"숙박","qty":1,"amount":92000}],"total":151800},"version":6,"contentHash":"3b1f…","tags":[],"ownerUserId":null,"ownerDirectoryId":null,"createdBy":"api_key:a9fc8451-dbb2-4fa2-911a-8bd8de2a84d0","updatedBy":"api_key:a9fc8451-dbb2-4fa2-911a-8bd8de2a84d0","sealedAt":null,"createdAt":"2026-11-03T12:00:00.000Z","updatedAt":"2026-11-03T12:00:00.000Z","deletedAt":null,"deletedBy":null}}}}},"404":{"description":"not_found: 없는 버전","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/files":{"post":{"operationId":"upload-file","tags":["파일"],"summary":"파일 업로드","description":"첨부 필드나 이미지에 쓸 파일을 올립니다 (최대 25MB).\n\n첨부(file) 필드 값은 [{ id, name, size }] 배열입니다. 업로드 응답을 그대로 넣으면 됩니다.\n\n필요 권한: `documents:write`","parameters":[],"responses":{"201":{"description":"파일 정보","content":{"application/json":{"example":{"data":{"id":"b87882f7-2c1e-4d7a-8f50-6a1d9e3c4b21","name":"영수증.pdf","size":182344,"mime":"application/pdf","sha256":"9c1e…","createdAt":"2026-11-03T12:00:00.000Z"}}}}}},"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"업로드할 파일"},"purpose":{"type":"string","description":"attachment(기본) · image · signature"}},"required":["file"]}}}}}},"/files/{id}":{"get":{"operationId":"download-file","tags":["파일"],"summary":"파일 내려받기","description":"파일 원본을 내려받습니다. 이미지·PDF 는 inline, 그 외는 attachment 로 응답합니다.\n\n필요 권한: `documents:read`","parameters":[{"name":"id","in":"path","required":true,"description":"파일 ID","schema":{"type":"string","format":"uuid"},"example":"b87882f7-2c1e-4d7a-8f50-6a1d9e3c4b21"}],"responses":{"200":{"description":"파일 바이너리 (Content-Type, Content-Disposition 포함)","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}}}}},"/imports":{"post":{"operationId":"create-import","tags":["가져오기 (AI 변환)"],"summary":"가져오기 요청","description":"파일·HTML·LML 을 구조화 문서로 변환합니다. 즉시 202 를 돌려주고 백그라운드에서 처리합니다.\n\n지원 형식 — 이미지(PNG·JPG·WEBP, AI 변환), XLSX(병합·테두리·채우기 보존), DOCX, HTML(워드·엑셀·한글 복사 내용), LML JSON.\n\n이미지는 관리자 콘솔에서 지정한 LLM(기본 자체 LLM)이 표·필드 구조를 분석합니다. 수십 초~수 분 걸릴 수 있습니다.\n\nJSON 으로 보낼 때는 html · lml · base64 중 하나를 사용합니다.\n\n필요 권한: `imports:write`","parameters":[],"responses":{"202":{"description":"접수됨","content":{"application/json":{"example":{"data":{"id":"488679f6-97c7-4666-9ccf-79950aaef999","status":"queued","sourceType":"xlsx"}}}}},"400":{"description":"bad_request: 지원하지 않는 형식 (HWP·PDF 는 준비 중 — 캡처 이미지로 대체)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: 요금제의 AI 변환 한도 초과","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"이미지·xlsx·docx·html·json(LML)"},"kind":{"type":"string","description":"만들 종류 (기본 template) (\"template\" | \"document\")"},"title":{"type":"string","description":"제목 (생략 시 파일·문서에서 추출)"},"hint":{"type":"string","description":"AI 추가 지시 (예: 품목 표는 반복 행으로)"}},"required":["file"]}},"application/json":{"examples":{"HTML":{"value":{"kind":"template","title":"붙여넣기 표","html":"<table><tr><th>성명</th><td></td></tr><tr><th>부서</th><td></td></tr></table>"}},"LML":{"value":{"kind":"template","lml":{"title":"간단 신청서","blocks":[{"type":"heading","text":"신 청 서","level":1,"align":"center"},{"type":"table","columns":[20,80],"rows":[{"cells":[{"text":"성명","header":true},{"field":{"type":"text","key":"name","label":"성명"}}]},{"cells":[{"text":"신청일","header":true},{"field":{"type":"date","key":"date","label":"신청일"}}]}]}]}}}}}}}},"get":{"operationId":"list-imports","tags":["가져오기 (AI 변환)"],"summary":"가져오기 목록","description":"최근 50건을 조회합니다.\n\n필요 권한: `documents:read`","parameters":[],"responses":{"200":{"description":"목록","content":{"application/json":{"example":{"data":[{"id":"488679f6-97c7-4666-9ccf-79950aaef999","sourceType":"xlsx","status":"succeeded","documentId":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","error":null,"fileName":"견적서.xlsx","createdAt":"2026-11-03T12:00:00.000Z","finishedAt":"2026-11-03T12:00:00.000Z"}]}}}}}}},"/imports/{id}":{"get":{"operationId":"get-import","tags":["가져오기 (AI 변환)"],"summary":"가져오기 상태","description":"queued → running → succeeded(documentId) 또는 failed(error). 1~2초 간격으로 조회하세요.\n\n필요 권한: `documents:read`","parameters":[{"name":"id","in":"path","required":true,"description":"가져오기 ID","schema":{"type":"string","format":"uuid"},"example":"488679f6-97c7-4666-9ccf-79950aaef999"}],"responses":{"200":{"description":"가져오기 객체","content":{"application/json":{"example":{"data":{"id":"488679f6-97c7-4666-9ccf-79950aaef999","sourceType":"image","status":"succeeded","documentId":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","error":null,"result":{"model":"zeroai-chat","attempt":1},"createdAt":"2026-11-03T12:00:00.000Z","finishedAt":"2026-11-03T12:00:00.000Z"}}}}}}}},"/documents/{id}/data-sources":{"get":{"operationId":"list-sources","tags":["데이터 연동 (외부 API)"],"summary":"연동 목록","description":"문서(와 그 문서가 시작한 양식)에 연결된 외부 API 연동과 변수 정의를 조회합니다.\n\n필요 권한: `documents:read`","parameters":[{"name":"id","in":"path","required":true,"description":"문서 ID","schema":{"type":"string","format":"uuid"},"example":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00"}],"responses":{"200":{"description":"연동 목록","content":{"application/json":{"example":{"data":[{"id":"5d2f8a10-…","name":"현장 작업 현황","method":"GET","url":"https://erp.example.com/api/work-log","params":[{"name":"date","label":"작업일자","type":"date","default":"{{today}}"},{"name":"site","label":"현장","type":"select","options":["A","B"],"default":"A"}],"autoRun":true,"mapping":{"fields":[{"target":"site","path":"$.site.name"},{"target":"weather","path":"$.weather"}],"repeats":[{"repeat":"tasks","path":"$.tasks","fields":[{"target":"task","path":"name"},{"target":"workers","path":"workers","transform":"number"}]}]},"lastRunAt":"2026-11-03T12:00:00.000Z","lastStatus":200,"lastError":null}]}}}}}}},"/documents/{id}/data-sources/{sourceId}/run":{"post":{"operationId":"run-source","tags":["데이터 연동 (외부 API)"],"summary":"연동 실행","description":"외부 API 를 호출하고 매핑 규칙대로 값을 만들어 문서 data 에 반영합니다(apply=false 면 결과만).\n\n변수(params)는 URL·쿼리·헤더·본문의 {{이름}} 에 들어갑니다. 생략하면 기본값을 씁니다 — {{today}}·{{month}}, 문서 값 {{data.필드키}}, 작성 요청 수신자 {{recipient.name}} 도 사용할 수 있습니다.\n\nSaaS 에서는 내부망(사설 IP) 주소를 호출할 수 없습니다. 설치형은 사내 API 를 그대로 연결할 수 있습니다.\n\n양식으로 문서를 만들 때(instantiate)와 모바일 작성 요청이 열릴 때 '자동 실행' 연동이 먼저 실행됩니다.\n\n필요 권한: `documents:write`","parameters":[{"name":"id","in":"path","required":true,"description":"문서 ID","schema":{"type":"string","format":"uuid"},"example":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00"},{"name":"sourceId","in":"path","required":true,"description":"연동 ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"매핑 결과","content":{"application/json":{"example":{"data":{"patch":{"site":"A현장 (판교 물류센터 신축)","weather":"맑음","tasks":[{"task":"철근 배근","workers":8}]},"warnings":[],"stats":{"fields":2,"rows":{"tasks":1}},"status":200,"ms":182,"params":{"date":"2026-11-03","site":"A"}}}}}},"400":{"description":"private_network: SaaS 에서 내부망 주소 호출","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"upstream_error: 외부 API 오류·시간 초과·JSON 아님","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"params":{"type":"object","description":"변수 값 { 이름: 값 }"},"apply":{"type":"boolean","description":"true(기본): 문서에 저장 · false: 결과만"}}},"example":{"params":{"date":"2026-11-03","site":"A"},"apply":true}}}}}},"/directory":{"get":{"operationId":"get-directory","tags":["디렉터리"],"summary":"디렉터리 조회","description":"부서와 회원 전체를 조회합니다.\n\n필요 권한: `directory:read`","parameters":[],"responses":{"200":{"description":"부서·회원","content":{"application/json":{"example":{"data":{"departments":[{"id":"…","externalId":"D11","name":"플랫폼개발팀","parentId":"…","active":true}],"members":[{"id":"…","externalId":"E001","name":"홍길동","departmentId":"…","position":"과장","title":"팀장","rank":3,"active":true}]}}}}}}}},"/directory/departments":{"put":{"operationId":"sync-departments","tags":["디렉터리"],"summary":"부서 동기화","description":"externalId 기준으로 부서를 추가·갱신합니다.\n\n필요 권한: `directory:write`","parameters":[],"responses":{"200":{"description":"결과","content":{"application/json":{"example":{"data":{"upserted":2}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"externalId":{"type":"string","description":"외부 플랫폼의 부서 ID"},"name":{"type":"string","description":"부서명"},"parentExternalId":{"type":"string","description":"상위 부서 ID"},"code":{"type":"string","description":"부서 코드 (문서번호 채번 등)"},"sort":{"type":"integer","description":"정렬 순서"},"active":{"type":"boolean","description":"사용 여부"}},"required":["externalId","name"]},"description":"부서 목록 (최대 5,000)"}},"required":["items"]},"example":{"items":[{"externalId":"D10","name":"개발본부"},{"externalId":"D11","name":"플랫폼개발팀","parentExternalId":"D10"}]}}}}}},"/directory/users":{"put":{"operationId":"sync-users","tags":["디렉터리"],"summary":"회원 동기화","description":"externalId 기준으로 회원을 추가·갱신합니다. deactivateMissing=true 로 전체 동기화하면 목록에 없는 회원을 비활성화합니다.\n\n부서 ID 대신 departmentName 만 보내면 같은 이름의 부서를 자동으로 만듭니다.\n\n주기적으로 호출(예: 매일 새벽)하거나 인사 변경 시점에 호출하세요.\n\n필요 권한: `directory:write`","parameters":[],"responses":{"200":{"description":"결과","content":{"application/json":{"example":{"data":{"created":1,"updated":0,"deactivated":0}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"externalId":{"type":"string","description":"외부 플랫폼 회원 ID"},"name":{"type":"string","description":"이름"},"email":{"type":"string","description":"이메일"},"phone":{"type":"string","description":"전화"},"departmentExternalId":{"type":"string","description":"부서 ID"},"departmentName":{"type":"string","description":"부서명 (ID 대신)"},"position":{"type":"string","description":"직위 (과장 등)"},"title":{"type":"string","description":"직책 (팀장 등)"},"rank":{"type":"integer","description":"서열 — 작을수록 상위. 결재선 자동 지정에 사용"},"roles":{"type":"array","description":"외부 플랫폼 역할 (문서 권한에 사용)"},"active":{"type":"boolean","description":"재직 여부"}},"required":["externalId","name"]},"description":"회원 목록 (최대 20,000)"},"deactivateMissing":{"type":"boolean","description":"true: 목록에 없는 기존 회원 비활성화 (전체 동기화)"}},"required":["items"]},"example":{"items":[{"externalId":"E001","name":"홍길동","email":"hong@example.com","departmentExternalId":"D11","position":"과장","title":"팀장","rank":3}],"deactivateMissing":false}}}}}},"/me":{"get":{"operationId":"me","tags":["계정·사용량"],"summary":"키 정보·사용량","description":"현재 API 키, 조직, 요금제 한도와 이번 달 사용량을 확인합니다. 연결 확인용으로 먼저 호출해 보세요.","parameters":[],"responses":{"200":{"description":"키·사용량","content":{"application/json":{"example":{"data":{"key":{"id":"a9fc8451-…","label":"API 키 그룹웨어 연동 (dcl_live_znf7…)","scopes":["documents:read","documents:write"]},"orgId":"1f0b6c2e-…","usage":{"plan":{"code":"business","name":"Business"},"items":[{"metric":"documents","used":128,"limit":null},{"metric":"apiCalls","used":5321,"limit":500000}]}}}}}}}}},"/audit-logs":{"get":{"operationId":"audit-logs","tags":["로그"],"summary":"감사 로그","description":"누가(사용자·API 키·외부 회원·시스템) 무엇을 했는지 최신순으로 조회합니다.\n\naction 은 접두어 일치입니다. 예: document. (문서 관련 전체), import., auth.login\n\n필요 권한: `logs:read`","parameters":[{"name":"action","in":"query","required":false,"description":"행위 접두어","schema":{"type":"string"},"example":"document."},{"name":"targetId","in":"query","required":false,"description":"대상 ID 정확히 일치","schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"시작 시각 (ISO 8601)","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":false,"description":"종료 시각","schema":{"type":"string","format":"date-time"}},{"name":"before","in":"query","required":false,"description":"커서 — 이전 응답의 nextCursor","schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"description":"1~200, 기본 50","schema":{"type":"integer"},"example":"20"}],"responses":{"200":{"description":"로그","content":{"application/json":{"example":{"data":{"items":[{"id":1042,"orgId":"…","actorType":"api_key","actorId":"a9fc…","actorLabel":"API 키 그룹웨어 연동","action":"document.fill","targetType":"document","targetId":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","ip":"203.0.113.10","userAgent":"node","requestId":"4c1e…","meta":{"version":3,"data":["items"]},"createdAt":"2026-11-03T12:00:00.000Z"}],"nextCursor":1041}}}}}}}},"/requests":{"post":{"operationId":"create-request","tags":["작성 요청 (모바일)"],"summary":"작성 요청 만들기","description":"양식을 수신자별 모바일 작성 링크로 배포합니다. 응답의 recipients[].link 를 문자·알림톡·앱 푸시로 보내세요.\n\nmode=assigned 는 수신자마다 고유 링크(로그인 불필요)를 만들고, mode=open 은 누구나 쓸 수 있는 공용 링크(openLink) 하나를 만들어 제출할 때마다 새 문서가 생깁니다.\n\nschedule=daily·weekdays 이면 같은 링크로 날짜(Asia/Seoul)마다 새 문서가 만들어져 작업일지·일일 점검표에 맞습니다.\n\n양식에 자동 실행 데이터 연동이 있으면 문서가 만들어질 때 외부 API 값(예: 오늘 투입 인원)이 미리 채워집니다.\n\n사진은 각 조직의 저장 용량 한도에 포함됩니다. photoStamp 를 켜면 촬영 일시(·위치)가 사진에 새겨집니다.\n\nsettings.contextPath(작업 위치 경로, 예: 송도 > B 생산라인 > B-1 라인 > 5축 머시닝센터)는 작성 화면 맨 위에 표시되고 제출 내역·웹훅에 함께 남습니다. 문자열(\">\" 구분) 또는 배열로 보낼 수 있고, recipients[].contextPath 로 수신자마다 다르게 줄 수 있습니다.\n\n양식의 날짜·시간 필드에 autoNow 가 있으면 open = 작성 화면을 처음 열 때, submit = [완료]를 누를 때 Asia/Seoul 시각이 자동으로 기록됩니다 (비어 있을 때만).\n\n필요 권한: `documents:write`","parameters":[],"responses":{"201":{"description":"요청 상세 (수신자별 링크 포함)","content":{"application/json":{"example":{"data":{"id":"5d2f7c10-8e4b-4a3d-9b61-0f2e7a9c4d11","templateId":"c4b836b9-eb85-4b68-9887-c6cbb3087519","templateTitle":"작업일보","title":"A현장 일일 작업일보","description":null,"mode":"assigned","schedule":"daily","status":"active","dueAt":null,"expiresAt":"2026-12-31T14:59:59.000Z","settings":{"photoStamp":true,"collectLocation":true,"allowEdit":false,"instructions":"작업 종료 후 18시까지 제출","contextPath":["송도","B 생산라인","B-1 라인"]},"contextPath":["송도","B 생산라인","B-1 라인"],"openLink":null,"period":"2026-11-03","recipients":[{"id":"a1e0…","name":"홍길동","phone":"010-1234-5678","email":null,"externalId":"E001","link":"https://docuel.com/f/q7Wm2xZ4pK9aT1cV3bN8","contextPath":["송도","B 생산라인","B-1 라인","5축 머시닝센터"],"status":"submitted","documentId":"8f2c41d0-…","submittedAt":"2026-11-03T08:30:00.000Z"},{"id":"b2f1…","name":"김철수","phone":"010-9876-5432","email":null,"externalId":"E002","link":"https://docuel.com/f/Hc8Lx…","contextPath":null,"status":"pending","documentId":null,"submittedAt":null}],"stats":{"recipients":2,"opened":1,"started":1,"submitted":1},"createdAt":"2026-11-03T08:30:00.000Z"}}}}},"400":{"description":"bad_request: 양식이 아니거나, 지정 수신자 방식인데 수신자가 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"templateId":{"type":"string","format":"uuid","description":"배포할 양식 ID (kind=template)"},"title":{"type":"string","description":"요청 제목 (문서 제목 앞부분)"},"description":{"type":"string","description":"설명"},"mode":{"type":"string","description":"지정 수신자(기본) · 공용 링크 (\"assigned\" | \"open\")"},"schedule":{"type":"string","description":"1회(기본) · 매일 · 평일 — 반복이면 날짜별 문서 (\"once\" | \"daily\" | \"weekdays\")"},"dueAt":{"type":"string","description":"작성 기한 (안내용) (date | datetime)"},"expiresAt":{"type":"string","description":"링크 만료 — 이후 접속 시 410 (date | datetime)"},"settings":{"type":"object","properties":{"photoStamp":{"type":"boolean","description":"사진에 촬영 일시·위치 표시"},"collectLocation":{"type":"boolean","description":"제출 시 GPS 위치 기록"},"allowEdit":{"type":"boolean","description":"제출 후 수정 허용"},"instructions":{"type":"string","description":"작성 화면 상단 안내문"},"webhookUrl":{"type":"string","description":"제출될 때마다 POST 로 알림 (request.submitted)"},"contextPath":{"type":"array","description":"작업 위치 경로 — [\"송도\", \"B 생산라인\"] 또는 \"송도 > B 생산라인\" (최대 8단계) (string | string[])"}},"description":"작성 화면 옵션"},"recipients":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"이름"},"phone":{"type":"string","description":"휴대폰 (발송용)"},"email":{"type":"string","description":"이메일"},"externalId":{"type":"string","description":"외부 플랫폼 회원 ID — 감사 로그·웹훅에 표시"},"contextPath":{"type":"array","description":"이 수신자만 다른 작업 위치 (없으면 settings.contextPath) (string | string[])"}},"required":["name"]},"description":"수신자 (직접 지정)"},"directoryUserIds":{"type":"array","description":"디렉터리 회원 ID — 이름·연락처를 디렉터리에서 가져옴"}},"required":["templateId","title"]},"example":{"templateId":"c4b836b9-eb85-4b68-9887-c6cbb3087519","title":"A현장 일일 작업일보","mode":"assigned","schedule":"daily","expiresAt":"2026-12-31","settings":{"photoStamp":true,"collectLocation":true,"instructions":"작업 종료 후 18시까지 제출","contextPath":["송도","B 생산라인","B-1 라인"]},"recipients":[{"name":"홍길동","phone":"010-1234-5678","externalId":"E001","contextPath":"송도 > B 생산라인 > B-1 라인 > 5축 머시닝센터"},{"name":"김철수","phone":"010-9876-5432","externalId":"E002"}]}}}}},"get":{"operationId":"list-requests","tags":["작성 요청 (모바일)"],"summary":"작성 요청 목록","description":"요청과 오늘(반복 요청) 또는 전체(1회 요청) 기준 제출 현황을 조회합니다.\n\n필요 권한: `documents:read`","parameters":[],"responses":{"200":{"description":"목록","content":{"application/json":{"example":{"data":[{"id":"5d2f7c10-8e4b-4a3d-9b61-0f2e7a9c4d11","title":"A현장 일일 작업일보","templateTitle":"작업일보","mode":"assigned","schedule":"daily","status":"active","stats":{"recipients":2,"opened":1,"period":"2026-11-03","started":1,"submitted":1,"submittedAllTime":37}}]}}}}}}},"/requests/{id}":{"get":{"operationId":"get-request","tags":["작성 요청 (모바일)"],"summary":"작성 요청 상세","description":"수신자별 링크와 현재 기간의 상태(pending · opened · in_progress · submitted), 작성 중인 문서 ID 를 돌려줍니다. contextPath 는 요청의 작업 위치, recipients[].contextPath 는 수신자별 위치(null = 요청 값)입니다.\n\n필요 권한: `documents:read`","parameters":[{"name":"id","in":"path","required":true,"description":"작성 요청 ID","schema":{"type":"string","format":"uuid"},"example":"5d2f7c10-8e4b-4a3d-9b61-0f2e7a9c4d11"}],"responses":{"200":{"description":"요청 상세","content":{"application/json":{"example":{"data":{"id":"5d2f7c10-8e4b-4a3d-9b61-0f2e7a9c4d11","templateId":"c4b836b9-eb85-4b68-9887-c6cbb3087519","templateTitle":"작업일보","title":"A현장 일일 작업일보","description":null,"mode":"assigned","schedule":"daily","status":"active","dueAt":null,"expiresAt":"2026-12-31T14:59:59.000Z","settings":{"photoStamp":true,"collectLocation":true,"allowEdit":false,"instructions":"작업 종료 후 18시까지 제출","contextPath":["송도","B 생산라인","B-1 라인"]},"contextPath":["송도","B 생산라인","B-1 라인"],"openLink":null,"period":"2026-11-03","recipients":[{"id":"a1e0…","name":"홍길동","phone":"010-1234-5678","email":null,"externalId":"E001","link":"https://docuel.com/f/q7Wm2xZ4pK9aT1cV3bN8","contextPath":["송도","B 생산라인","B-1 라인","5축 머시닝센터"],"status":"submitted","documentId":"8f2c41d0-…","submittedAt":"2026-11-03T08:30:00.000Z"},{"id":"b2f1…","name":"김철수","phone":"010-9876-5432","email":null,"externalId":"E002","link":"https://docuel.com/f/Hc8Lx…","contextPath":null,"status":"pending","documentId":null,"submittedAt":null}],"stats":{"recipients":2,"opened":1,"started":1,"submitted":1},"createdAt":"2026-11-03T08:30:00.000Z"}}}}},"404":{"description":"not_found: 없는 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/requests/{id}/recipients":{"post":{"operationId":"add-request-recipients","tags":["작성 요청 (모바일)"],"summary":"수신자 추가","description":"진행 중인 요청에 수신자를 추가하고 새 링크를 받습니다. 이미 있는 사람(디렉터리 ID·외부 ID·이름+전화)은 건너뜁니다.\n\n필요 권한: `documents:write`","parameters":[{"name":"id","in":"path","required":true,"description":"작성 요청 ID","schema":{"type":"string","format":"uuid"},"example":"5d2f7c10-8e4b-4a3d-9b61-0f2e7a9c4d11"}],"responses":{"200":{"description":"추가된 수신자와 링크","content":{"application/json":{"example":{"data":[{"id":"c3a2…","name":"박민수","phone":"010-5555-1234","externalId":"E004","contextPath":["송도","C 생산라인","C-2 라인","사출기 3호"],"link":"https://docuel.com/f/Zt3Qp…"}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"recipients":{"type":"array","description":"{ name, phone?, email?, externalId?, contextPath? }"},"directoryUserIds":{"type":"array","description":"디렉터리 회원 ID"},"contextPath":{"type":"array","description":"이번에 추가하는 수신자 전체의 작업 위치 (각 recipients[].contextPath 가 우선, 없으면 요청 값) (string | string[])"}}},"example":{"recipients":[{"name":"박민수","phone":"010-5555-1234","externalId":"E004","contextPath":["송도","C 생산라인","C-2 라인","사출기 3호"]}]}}}}}},"/requests/{id}/close":{"post":{"operationId":"close-request","tags":["작성 요청 (모바일)"],"summary":"요청 마감","description":"링크 사용을 중지합니다. 이후 접속하면 마감 안내가 표시됩니다(410). /reopen 으로 다시 열 수 있습니다.\n\n필요 권한: `documents:write`","parameters":[{"name":"id","in":"path","required":true,"description":"작성 요청 ID","schema":{"type":"string","format":"uuid"},"example":"5d2f7c10-8e4b-4a3d-9b61-0f2e7a9c4d11"}],"responses":{"200":{"description":"마감된 요청","content":{"application/json":{"example":{"data":{"id":"5d2f7c10-8e4b-4a3d-9b61-0f2e7a9c4d11","templateId":"c4b836b9-eb85-4b68-9887-c6cbb3087519","templateTitle":"작업일보","title":"A현장 일일 작업일보","description":null,"mode":"assigned","schedule":"daily","status":"closed","dueAt":null,"expiresAt":"2026-12-31T14:59:59.000Z","settings":{"photoStamp":true,"collectLocation":true,"allowEdit":false,"instructions":"작업 종료 후 18시까지 제출","contextPath":["송도","B 생산라인","B-1 라인"]},"contextPath":["송도","B 생산라인","B-1 라인"],"openLink":null,"period":"2026-11-03","recipients":[{"id":"a1e0…","name":"홍길동","phone":"010-1234-5678","email":null,"externalId":"E001","link":"https://docuel.com/f/q7Wm2xZ4pK9aT1cV3bN8","contextPath":["송도","B 생산라인","B-1 라인","5축 머시닝센터"],"status":"submitted","documentId":"8f2c41d0-…","submittedAt":"2026-11-03T08:30:00.000Z"},{"id":"b2f1…","name":"김철수","phone":"010-9876-5432","email":null,"externalId":"E002","link":"https://docuel.com/f/Hc8Lx…","contextPath":null,"status":"pending","documentId":null,"submittedAt":null}],"stats":{"recipients":2,"opened":1,"started":1,"submitted":1},"createdAt":"2026-11-03T08:30:00.000Z"}}}}}}}},"/requests/{id}/submissions":{"get":{"operationId":"list-request-submissions","tags":["작성 요청 (모바일)"],"summary":"제출 내역","description":"제출(및 작성 중) 문서와 입력값을 조회합니다. 외부 플랫폼이 작업일지 값을 가져갈 때 사용합니다.\n\n사진·첨부 필드 값은 [{ id, name, size }] 이며 파일은 GET /files/{id} 로 내려받습니다.\n\nmeta 에는 제출 위치(location)·IP·기기 정보가 들어갑니다.\n\ncontextPath 는 문서가 만들어질 때의 작업 위치 경로입니다 (수신자별 → 요청 순).\n\nstartedAt·completedAt 은 양식의 autoNow 날짜·시간 필드 값(open = 처음 열 때, submit = 완료 때)이고, 없으면 openedAt(처음 연 시각)·submittedAt 을 씁니다. elapsedSeconds 는 그 사이 소요 시간(초)입니다.\n\n필요 권한: `documents:read`","parameters":[{"name":"id","in":"path","required":true,"description":"작성 요청 ID","schema":{"type":"string","format":"uuid"},"example":"5d2f7c10-8e4b-4a3d-9b61-0f2e7a9c4d11"},{"name":"period","in":"query","required":false,"description":"기간 (YYYY-MM-DD, 1회 요청은 빈 값)","schema":{"type":"string"},"example":"2026-11-03"},{"name":"status","in":"query","required":false,"description":"draft · submitted","schema":{"type":"string","enum":["draft","submitted"]}}],"responses":{"200":{"description":"제출 목록","content":{"application/json":{"example":{"data":[{"id":"9e1d…","recipientName":"홍길동","externalId":"E001","period":"2026-11-03","status":"submitted","contextPath":["송도","B 생산라인","B-1 라인","5축 머시닝센터"],"openedAt":"2026-11-03T00:12:31.000Z","startedAt":"2026-11-03T00:12:00.000Z","completedAt":"2026-11-03T02:47:00.000Z","elapsedSeconds":9300,"submittedAt":"2026-11-03T02:47:12.000Z","documentId":"8f2c41d0-…","documentStatus":"submitted","meta":{"location":{"lat":37.3895,"lng":126.6439,"accuracy":12},"contextPath":["송도","B 생산라인","B-1 라인","5축 머시닝센터"]},"data":{"worker":"홍길동","workType":"부품교체","startedAt":"2026-11-03T09:12","completedAt":"2026-11-03T11:47","workDetail":"스핀들 베어링 소음 확인 후 교체\n윤활유 보충하고 시운전","parts":[{"partName":"스핀들 베어링","qty":2}],"photos":[{"id":"b878…","name":"작업후.jpg","size":412233}],"remarks":"다음 정기점검 때 진동 재측정"}}]}}}}}}},"/approvals":{"post":{"operationId":"submit-approval","tags":["전자결재"],"summary":"결재 상신","description":"문서를 결재선에 올립니다. 첫 결재자의 차례가 되고 문서 상태는 in_approval 이 됩니다.\n\n결재자는 directoryUserId(디렉터리 회원) · userId(내부 계정) · approver(이름만 있는 외부 결재자) 중 하나로 지정합니다.\n\nfieldKey 를 생략하면 결재란의 서명 필드에 자동으로 연결합니다 — 직책·직위가 라벨과 같은 칸(팀장·본부장…) → 남은 칸 순서. 기안자 도장은 '담당·기안' 칸에 찍힙니다.\n\n연속된 합의(agree) 단계는 동시에 진행되고, 참조(cc)는 상신 즉시, 수신(receive)은 최종 승인 시 통보됩니다.\n\n외부 결재자에게는 응답의 steps[].link 를 문자·메신저로 보내면 모바일에서 바로 승인·반려할 수 있습니다.\n\n필요 권한: `approvals:write`","parameters":[],"responses":{"201":{"description":"생성된 결재 (단계·외부 결재 링크 포함)","content":{"application/json":{"example":{"data":{"id":"7b1e0c42-3a9d-4f6e-8c21-5d0a9e3f1b77","documentId":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","title":"모니터 구매 요청","status":"in_progress","drafter":{"name":"김철수","title":null,"position":"대리","department":"플랫폼개발팀","externalId":"E002"},"drafterFieldKey":"signStaff","currentSeq":1,"note":"신규 입사자 장비","submittedAt":"2026-11-03T09:00:00.000Z","completedAt":null,"document":{"id":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","title":"물품구매요청서 — 모니터","status":"in_approval","version":3,"sealedAt":null},"steps":[{"id":"0c9d1a11-…","seq":1,"kind":"approve","approverDirectoryId":"d1e21…","approver":{"name":"홍길동","title":"팀장","position":"과장","department":"플랫폼개발팀","externalId":"E001"},"status":"pending","comment":null,"fieldKey":"signTeamLead","signature":null,"actedBy":null,"actedAt":null,"link":"https://docuel.com/a/Xk2…1","mine":false},{"id":"0c9d2a11-…","seq":2,"kind":"approve","approverDirectoryId":"d1e22…","approver":{"name":"이영희","title":"본부장","position":"상무","department":"개발본부","externalId":"E003"},"status":"waiting","comment":null,"fieldKey":"signHead","signature":null,"actedBy":null,"actedAt":null,"link":"https://docuel.com/a/Xk2…2","mine":false}],"permissions":{"canAct":false,"canWithdraw":true,"canProxy":false}}}}}},"400":{"description":"bad_request: 양식 문서이거나 결재자를 찾을 수 없음, 결재·합의 단계 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"conflict: 이미 결재 진행 중이거나 봉인된 문서","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid","description":"결재할 문서 (양식이 아닌 작성 문서)"},"title":{"type":"string","description":"결재 제목 (기본: 문서 제목)"},"note":{"type":"string","description":"상신 의견"},"steps":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","description":"결재 · 합의 · 참조 · 수신 (기본 approve) (\"approve\" | \"agree\" | \"cc\" | \"receive\")"},"directoryUserId":{"type":"string","format":"uuid","description":"디렉터리 회원 ID"},"userId":{"type":"string","format":"uuid","description":"내부 계정 ID"},"approver":{"type":"string","description":"디렉터리에 없는 외부 결재자"},"fieldKey":{"type":"string","description":"도장을 찍을 서명 필드 키 (생략=자동, null=찍지 않음) (string | null)"}}},"description":"결재선 (순서대로, 최대 30)"},"drafter":{"type":"string","description":"기안자 (API 로 상신할 때 지정, 생략 시 키 이름)"},"drafterFieldKey":{"type":"string","description":"기안자 도장 칸 (생략=자동, null=찍지 않음) (string | null)"}},"required":["documentId","steps"]},"example":{"documentId":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","title":"모니터 구매 요청","note":"신규 입사자 장비","steps":[{"kind":"approve","directoryUserId":"d1e21…"},{"kind":"agree","approver":{"name":"정하늘","title":"경영지원팀장","email":"jung@example.com"}},{"kind":"approve","directoryUserId":"d1e22…"},{"kind":"cc","directoryUserId":"d1e23…"}],"drafter":{"directoryUserId":"d1e20…"}}}}}},"get":{"operationId":"list-approvals","tags":["전자결재"],"summary":"결재 목록","description":"조직의 결재를 최근 상신 순으로 조회합니다. 현재 결재자와 진행률을 함께 돌려줍니다.\n\n필요 권한: `approvals:read`","parameters":[{"name":"status","in":"query","required":false,"description":"상태","schema":{"type":"string","enum":["in_progress","approved","rejected","withdrawn"]}},{"name":"documentId","in":"query","required":false,"description":"특정 문서의 결재 이력","schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"description":"1~200, 기본 100","schema":{"type":"integer"},"example":"20"}],"responses":{"200":{"description":"목록","content":{"application/json":{"example":{"data":[{"id":"7b1e0c42-3a9d-4f6e-8c21-5d0a9e3f1b77","title":"모니터 구매 요청","status":"in_progress","documentId":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","documentTitle":"물품구매요청서 — 모니터","drafter":"김철수","submittedAt":"2026-11-03T09:00:00.000Z","completedAt":null,"current":[{"kind":"approve","name":"홍길동"}],"progress":{"done":0,"total":2},"line":[{"name":"홍길동","title":"팀장","kind":"approve","status":"pending"},{"name":"이영희","title":"본부장","kind":"approve","status":"waiting"}]}]}}}}}}},"/approvals/{id}":{"get":{"operationId":"get-approval","tags":["전자결재"],"summary":"결재 조회","description":"결재 단계(상태·의견·처리 시각·실제 처리자)와 외부 결재 링크를 조회합니다.\n\nsteps[].actedBy 에 실제 처리자가 기록됩니다 — 관리자 대결이면 onBehalfOf 에 원래 결재자, API 처리면 via: api.\n\n필요 권한: `approvals:read`","parameters":[{"name":"id","in":"path","required":true,"description":"결재 ID","schema":{"type":"string","format":"uuid"},"example":"7b1e0c42-3a9d-4f6e-8c21-5d0a9e3f1b77"}],"responses":{"200":{"description":"결재","content":{"application/json":{"example":{"data":{"id":"7b1e0c42-3a9d-4f6e-8c21-5d0a9e3f1b77","documentId":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","title":"모니터 구매 요청","status":"in_progress","drafter":{"name":"김철수","title":null,"position":"대리","department":"플랫폼개발팀","externalId":"E002"},"drafterFieldKey":"signStaff","currentSeq":1,"note":"신규 입사자 장비","submittedAt":"2026-11-03T09:00:00.000Z","completedAt":null,"document":{"id":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","title":"물품구매요청서 — 모니터","status":"in_approval","version":3,"sealedAt":null},"steps":[{"id":"0c9d1a11-…","seq":1,"kind":"approve","approverDirectoryId":"d1e21…","approver":{"name":"홍길동","title":"팀장","position":"과장","department":"플랫폼개발팀","externalId":"E001"},"status":"pending","comment":null,"fieldKey":"signTeamLead","signature":null,"actedBy":null,"actedAt":null,"link":"https://docuel.com/a/Xk2…1","mine":false},{"id":"0c9d2a11-…","seq":2,"kind":"approve","approverDirectoryId":"d1e22…","approver":{"name":"이영희","title":"본부장","position":"상무","department":"개발본부","externalId":"E003"},"status":"waiting","comment":null,"fieldKey":"signHead","signature":null,"actedBy":null,"actedAt":null,"link":"https://docuel.com/a/Xk2…2","mine":false}],"permissions":{"canAct":false,"canWithdraw":true,"canProxy":false}}}}}},"404":{"description":"not_found: 없거나 다른 조직의 결재","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/approvals/{id}/actions":{"post":{"operationId":"approval-action","tags":["전자결재"],"summary":"승인·반려·회수","description":"현재 차례의 단계를 승인·반려하거나, 진행 중인 결재를 회수합니다.\n\napprove — 결재란에 도장(또는 signature 로 보낸 서명 이미지)을 찍고 다음 차례로 넘깁니다. 마지막 승인이면 문서가 approved 로 바뀌고 봉인되어 더 이상 수정할 수 없습니다.\n\nreject — 결재가 반려되고 문서는 rejected 상태가 됩니다. 수정 후 다시 상신하면 새 결재가 시작됩니다.\n\nwithdraw — 기안자 회수. 찍힌 도장을 지우고 문서를 작성 중(draft)으로 되돌립니다.\n\nskip — 부재 등으로 현재 단계를 건너뜁니다 (관리자·API).\n\nAPI 키로 처리하면 연동 시스템이 결재자를 대신해 처리한 것으로 기록됩니다. stepId 를 생략하면 현재 차례의 첫 단계를 처리합니다.\n\n필요 권한: `approvals:write`","parameters":[{"name":"id","in":"path","required":true,"description":"결재 ID","schema":{"type":"string","format":"uuid"},"example":"7b1e0c42-3a9d-4f6e-8c21-5d0a9e3f1b77"}],"responses":{"200":{"description":"처리 결과 (in_progress · approved · rejected · withdrawn) 와 갱신된 결재","content":{"application/json":{"example":{"data":{"result":"in_progress","approval":{"id":"7b1e0c42-3a9d-4f6e-8c21-5d0a9e3f1b77","documentId":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","title":"모니터 구매 요청","status":"in_progress","drafter":{"name":"김철수","title":null,"position":"대리","department":"플랫폼개발팀","externalId":"E002"},"drafterFieldKey":"signStaff","currentSeq":2,"note":"신규 입사자 장비","submittedAt":"2026-11-03T09:00:00.000Z","completedAt":null,"document":{"id":"8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00","title":"물품구매요청서 — 모니터","status":"in_approval","version":3,"sealedAt":null},"steps":[{"id":"0c9d1a11-…","seq":1,"kind":"approve","approverDirectoryId":"d1e21…","approver":{"name":"홍길동","title":"팀장","position":"과장","department":"플랫폼개발팀","externalId":"E001"},"status":"approved","comment":"확인했습니다.","fieldKey":"signTeamLead","signature":"data:image/svg+xml;base64,…","actedBy":{"type":"api_key","name":"API 키 그룹웨어 연동","via":"api"},"actedAt":"2026-11-03T09:00:00.000Z","link":"https://docuel.com/a/Xk2…1","mine":false},{"id":"0c9d2a11-…","seq":2,"kind":"approve","approverDirectoryId":"d1e22…","approver":{"name":"이영희","title":"본부장","position":"상무","department":"개발본부","externalId":"E003"},"status":"pending","comment":null,"fieldKey":"signHead","signature":null,"actedBy":null,"actedAt":null,"link":"https://docuel.com/a/Xk2…2","mine":false}],"permissions":{"canAct":false,"canWithdraw":true,"canProxy":false}}}}}}},"403":{"description":"forbidden: 본인 차례가 아님 (관리자는 대결로 처리됨)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"conflict: 이미 끝난 결재이거나 처리할 단계가 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"type":"string","description":"처리 (\"approve\" | \"reject\" | \"withdraw\" | \"skip\")"},"stepId":{"type":"string","format":"uuid","description":"처리할 단계 (생략 시 현재 차례)"},"comment":{"type":"string","description":"의견 · 반려 사유"},"signature":{"type":"string","description":"서명 이미지 data URL (data:image/png;base64,…) — 없으면 이름 도장"}},"required":["action"]},"example":{"action":"approve","comment":"확인했습니다."}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"dcl_live_ 로 시작하는 API 키"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}}}}}}