도큐엘 API 레퍼런스
도큐엘 API 로 외부 플랫폼(그룹웨어·ERP·쇼핑몰·자체 서비스)에서 문서를 만들고, 양식에 데이터를 넣고, 표의 행을 반복해서 채우고, 이미지·엑셀·워드를 구조화 문서로 변환하고, 회원·부서를 동기화할 수 있습니다. 화면에서 할 수 있는 모든 일을 API 로도 할 수 있고, 모든 호출은 API 로그와 감사 로그에 남습니다.
REST 방식이며 요청·응답은 UTF-8 JSON 입니다. 인증은 조직별 API 키(Bearer)로 하며, 키는 반드시 서버에서만 사용하세요. 브라우저에 키를 노출하지 마세요 — 외부 회원이 브라우저에서 문서를 여는 기능은 임베드 SDK 로 제공됩니다.
OpenAPI 3.1 명세: /api/v1/openapi.json — Postman, Swagger UI, 코드 생성기에 그대로 가져올 수 있습니다.
https://docuel.com/api/v1
curl https://docuel.com/api/v1/me \ -H "Authorization: Bearer $DOCUEL_API_KEY"
왼쪽 위에 API 키를 넣으면 각 엔드포인트의 [요청 보내기]로 실제 호출할 수 있습니다. 문서를 만들면 그 ID 가 다른 요청에 자동으로 채워집니다.
빠른 시작 — 양식에 데이터를 넣어 문서 만들기
- API 키 발급 — 콘솔 › API 키·임베드 에서 발급합니다. 발급 직후 한 번만 표시되니 안전한 곳(서버 환경변수)에 저장하세요. 이 문서 페이지에서는 로그인 후 왼쪽 위 버튼으로 24시간 테스트 키를 받을 수 있습니다.
- 양식 준비 — 에디터에서 양식을 디자인하거나, 가져오기 로 기존 서식(이미지·엑셀·워드)을 변환합니다. 표의 반복 행에 데이터 키(예:
items)를 지정해 두세요. - 문서 생성 — 양식 + 데이터 → 문서 를 호출합니다. 필드 key 는 문서 조회 의
include=fields로 확인합니다. - 계속 채우기 — 입력값 병합·반복 행 추가 로 값을 갱신합니다. 합계 같은 계산식은 저장 시 자동으로 계산되어
data에 들어갑니다. - 사용자에게 보여주기 — 응답의
url을 열면 미리보기(세로/가로·자동 페이지)·인쇄·수정이 가능합니다.
export DOCUEL_API_KEY=dcl_live_... curl https://docuel.com/api/v1/me -H "Authorization: Bearer $DOCUEL_API_KEY"
curl "https://docuel.com/api/v1/documents?kind=template" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
curl -X POST https://docuel.com/api/v1/templates/$TEMPLATE_ID/instantiate \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"11월 출장비 정산","data":{"dept":"플랫폼개발팀","items":[{"desc":"KTX","qty":1,"amount":59800}]}}'curl -X POST https://docuel.com/api/v1/documents/$DOC_ID/rows \
-H "Authorization: Bearer $DOCUEL_API_KEY" -H "Content-Type: application/json" \
-d '{"repeat":"items","rows":[{"desc":"택시","qty":1,"amount":18400}]}'
curl https://docuel.com/api/v1/documents/$DOC_ID/data \
-H "Authorization: Bearer $DOCUEL_API_KEY"
# → { "data": { …, "total": 78200 } }인증·권한
모든 요청에 Authorization: Bearer <API 키> 헤더를 붙입니다. 키는 dcl_live_ 로 시작하며 조직 단위로 발급됩니다. 서버에는 해시만 저장되므로 분실하면 새로 발급해야 합니다.
- 권한(스코프) — 키마다 필요한 권한만 부여하세요. 권한이 없는 호출은
403 forbidden. - 만료·폐기 — 만료일을 지정할 수 있고, 콘솔에서 즉시 폐기할 수 있습니다. 폐기된 키는
401. - 허용 IP — 키에 허용 IP 를 지정하면 다른 IP 의 요청은
403 ip_not_allowed. - 조직 정지 — 정지된 조직의 키는
403.
권한 목록
Authorization: Bearer dcl_live_XXXXXXXXXXXXXXXXXXXXXXXX # 또는 X-API-Key: dcl_live_XXXXXXXXXXXXXXXXXXXXXXXX
{
"error": {
"code": "unauthorized",
"message": "유효하지 않은 API 키입니다."
}
}{
"error": {
"code": "forbidden",
"message": "권한이 없습니다. (templates:write)"
}
}요청과 응답
- 본문은 JSON(
Content-Type: application/json), 파일 업로드만multipart/form-data. - 성공 응답은
{ data }, 실패는{ error: { code, message, details? } }. 본문이 필요 없는 성공은{ ok: true }. - ID 는 UUID, 시각은 ISO 8601 UTC 문자열입니다.
- 모든 응답에
x-request-id가 붙습니다. 요청에 직접 지정할 수도 있으며, 감사 로그·API 로그에서 같은 ID 로 추적됩니다. 문의 시 이 값을 알려주세요. - GET·PUT·DELETE 는 같은 요청을 반복해도 결과가 같습니다(멱등). POST 는 재시도 시 중복 생성될 수 있으니, 네트워크 오류 후에는 목록을 확인한 뒤 재시도하세요.
{
"data": {
"id": "8f2c41d0-…",
"title": "11월 출장비 정산",
"version": 3
}
}{
"error": {
"code": "validation_error",
"message": "입력값을 확인하세요.",
"details": [
{
"path": [
"title"
],
"message": "Too small: expected string to have >=1 characters"
}
]
}
}content-type: application/json x-request-id: 4c1e9a52-0f3b-4a77-9d6e-2b8c1f0e5a13 cache-control: no-store
오류 코드
HTTP 상태 코드와 함께 기계가 읽을 수 있는 error.code 를 돌려줍니다. 분기 처리는 code 기준으로 하세요.
{
"error": {
"code": "rate_limited",
"message": "요금제 한도를 초과했습니다. (Business: apiCalls 500000/500000)"
}
}한도·사용량
요금제별로 월 API 호출 수와 AI 변환 수, 문서 수가 정해져 있습니다. 한도를 넘으면 429 rate_limited 를 돌려줍니다. 현재 사용량은 GET /me 로 확인합니다. 설치형(Enterprise)은 한도가 없습니다.
| 요금제 | API 호출/월 | AI 변환/월 | 문서 |
|---|---|---|---|
| Free | 1,000 | 10 | 50 |
| Pro | 50,000 | 300 | 2,000 |
| Business | 500,000 | 2,000 | 무제한 |
| Unlimited | 무제한 | 무제한 | 무제한 |
| Enterprise 설치형 | 무제한 | 무제한 | 무제한 |
curl https://docuel.com/api/v1/me -H "Authorization: Bearer $DOCUEL_API_KEY"
페이지 나누기
목록은 커서 방식입니다. 응답의 nextCursor 를 다음 요청의 before 로 넘기고, nextCursor 가 null 이면 마지막입니다. 문서 목록은 수정 시각, 감사 로그는 로그 ID 가 커서입니다.
# 첫 페이지
curl "https://docuel.com/api/v1/documents?limit=50" -H "Authorization: Bearer $DOCUEL_API_KEY"
# → { "data": { "items": [...], "nextCursor": "2026-11-03T03:12:44.120Z" } }
# 다음 페이지
curl "https://docuel.com/api/v1/documents?limit=50&before=2026-11-03T03:12:44.120Z" \
-H "Authorization: Bearer $DOCUEL_API_KEY"문서 모델 (ZDoc)
문서 구조(content)는 용지 설정·기본 서식·본문으로 이루어진 JSON 이고, 입력값(data)은 따로 저장됩니다. 그래서 양식 디자인이 바뀌어도 데이터는 유지되고, API 로는 값만 주고받을 수 있습니다.
본문 노드
{
"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"
},
"body": {
"type": "doc",
"content": [
{
"type": "heading",
"attrs": {
"level": 1,
"textAlign": "center"
},
"content": [
{
"type": "text",
"text": "휴 가 신 청 서"
}
]
},
{
"type": "table",
"attrs": {
"border": "1px solid #222222",
"width": 100
},
"content": [
{
"type": "tableRow",
"content": [
{
"type": "tableHeader",
"attrs": {
"colwidth": [
110
],
"background": "#f3f4f6"
},
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "성명"
}
]
}
]
},
{
"type": "tableCell",
"attrs": {
"colwidth": [
570
]
},
"content": [
{
"type": "paragraph",
"content": [
{
"type": "field",
"attrs": {
"key": "name",
"type": "text",
"label": "성명",
"required": true
}
}
]
}
]
}
]
}
]
}
]
}
}입력 필드와 값 형식
필드는 문서 안의 입력 칸입니다. data 의 키는 필드의 key 이고, 값 형식은 필드 종류에 따라 다릅니다. 문서별 정확한 스키마는 문서 조회 에 include=schema 를 붙여 받을 수 있습니다.
"홍길동""1행\n2행"359800"2026-11-03""14:30""2026-11-03T14:30"["연차","병가"]"법인카드""서울""[email protected]""010-1234-5678"[{"id":"b878…","name":"영수증.pdf","size":182344}]"data:image/png;base64,…"151800{
"name": "홍길동",
"leaveType": [
"연차"
],
"from": "2026-11-10",
"fromTime": "09:00",
"reason": "가족 행사",
"attachment": [
{
"id": "b878…",
"name": "청첩장.pdf",
"size": 182344
}
]
}반복 행·열 · 계산식 · 조건
표의 한 행에 데이터 키(예: items)를 지정하면 반복 행이 됩니다. data.items 배열의 길이만큼 행이 복제되고, 행 안의 필드는 배열 요소의 속성을 표시합니다. 위쪽 셀이 세로로 병합(rowspan)되어 있으면 행 수만큼 자동으로 늘어납니다.
행이 많아 용지를 넘기면 미리보기·인쇄에서 다음 페이지로 이어지고, 머리행(headerRepeat)은 페이지마다 반복됩니다. 세로 병합으로 묶인 행들은 같은 페이지에 함께 놓입니다.
계산식 필드(formula)는 다른 필드 값으로 계산되며 읽기 전용입니다. 반복 행 안의 계산식은 같은 행의 값을, 바깥의 계산식은 items.amount 처럼 반복 데이터 전체를 참조합니다. 계산식이 다른 계산식을 참조할 수도 있고, 결과는 저장 시 data 에 기록되어 API 로 바로 조회됩니다.
반복 열 — 셀에 repeatCol(예: months)을 지정하면 그 열이 배열 항목 수만큼 가로로 늘어납니다(월별·일자별 표). 원래 열 폭을 나눠 쓰고, 위·옆 칸의 colspan 은 자동으로 늘어납니다. 데이터 모양은 반복 행과 같으며 반복 행 추가 API 로도 항목을 붙일 수 있습니다.
조건값 필드(rule)는 위에서부터 처음 맞는 조건의 문구를 표시합니다(예: 결과가 부적합이면 "조치 필요", 그 밖에 "정상"). 결과는 계산식처럼 저장 시 data 에 기록됩니다. 조건부 서식은 셀의 rules 로 조건이 맞을 때 배경·글자색·굵게·표시 문구를 바꾸고, 조건부 병합은 mergeV: "same"(위 칸과 같은 값) · mergeH: "empty"|"same"(왼쪽 칸과) 로 보기·인쇄에서 칸을 합칩니다.
{
"items": [
{
"desc": "KTX",
"qty": 1,
"unitPrice": 59800,
"amount": 59800
},
{
"desc": "숙박",
"qty": 2,
"unitPrice": 46000,
"amount": 92000
}
],
"total": 151800
}=qty*unitPrice 같은 행의 값 =SUM(items.amount) 반복 행 합계 =ROUND(total*0.1) 부가세 =total+ROUND(total*0.1) 합계 + 부가세 함수: SUM AVG MIN MAX COUNT ROUND
{
"months": [
{
"month": "1월",
"count": 12,
"fail": 2
},
{
"month": "2월",
"count": 10,
"fail": 0
}
]
}{
"field": "result",
"op": "eq",
"value": "부적합"
}
op: eq ne gt gte lt lte contains notContains empty notEmpty
field: 키 · "@" = 이 칸/필드 자신Document 객체
양식과 작성 문서는 같은 객체이며 kind 로 구분합니다.
{
"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
}LML — 가져오기용 중간 형식
LML(Layout Markup for LLM)은 AI 가 이미지에서 표·필드 구조를 읽어 낼 때 쓰는 단순한 JSON 입니다. 서버는 LML 을 검증하고 격자(병합·빠진 칸)를 보정한 뒤 ZDoc 으로 변환합니다. 직접 만든 LML 이나 다른 AI 의 결과를 가져오기 에 { lml } 로 보내도 됩니다.
{
"title": "휴가신청서",
"page": {
"orientation": "portrait",
"size": "A4"
},
"blocks": [
{
"type": "heading",
"text": "휴 가 신 청 서",
"level": 1,
"align": "center"
},
{
"type": "table",
"columns": [
15,
35,
15,
35
],
"border": "all",
"rows": [
{
"cells": [
{
"text": "성명",
"header": true
},
{
"field": {
"type": "text",
"key": "name",
"label": "성명"
}
},
{
"text": "소속",
"header": true
},
{
"field": {
"type": "text",
"key": "dept",
"label": "소속"
}
}
]
},
{
"cells": [
{
"text": "종류",
"header": true
},
{
"colspan": 3,
"field": {
"type": "checkbox",
"key": "leaveType",
"options": [
"연차",
"반차",
"병가"
],
"multiple": true
}
}
]
}
]
},
{
"type": "table",
"columns": [
10,
60,
30
],
"rows": [
{
"header": true,
"cells": [
{
"text": "No",
"header": true
},
{
"text": "내역",
"header": true
},
{
"text": "금액",
"header": true
}
]
},
{
"repeat": "items",
"cells": [
{
"field": {
"type": "number",
"key": "no"
}
},
{
"field": {
"type": "text",
"key": "desc"
}
},
{
"field": {
"type": "currency",
"key": "amount"
}
}
]
}
]
},
{
"type": "paragraph",
"align": "right",
"parts": [
{
"text": "신청인 "
},
{
"field": {
"type": "text",
"key": "applicant"
}
},
{
"text": " "
},
{
"field": {
"type": "signature",
"key": "sign"
}
}
]
}
]
}양식(template)과 작성 문서(document)를 만들고 조회·수정합니다. 둘은 같은 객체이며 kind 로 구분합니다.
문서 목록GET/api/v1/documents
조직의 문서·양식을 최근 수정 순으로 조회합니다.
본문(content)과 데이터(data)는 포함하지 않습니다. 개별 조회를 사용하세요.
다음 페이지는 응답의 nextCursor 를 before 로 넘겨 조회합니다.
필요 권한documents:read
쿼리 파라미터
document template alldraft published submitted in_approval approved rejected completed archived응답
curl -X GET "https://docuel.com/api/v1/documents?kind=all&limit=20" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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/api/v1/documents
빈 문서, 양식, 또는 양식에서 시작하는 문서를 만듭니다.
양식(kind=template)을 만들려면 templates:write 권한이 필요합니다.
계산식 필드의 결과는 저장 시 data 에 자동으로 채워집니다.
필요 권한documents:write
요청 본문 application/json
응답
rate_limited 요금제의 문서 수 한도 초과curl -X POST "https://docuel.com/api/v1/documents" \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"kind": "document",
"title": "API 로 만든 문서",
"category": "테스트"
}'{
"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
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
문서 조회GET/api/v1/documents/{id}
문서 구조(content)와 입력값(data)을 포함한 전체 객체를 조회합니다.
include=fields 를 지정하면 문서 안의 입력 필드 목록과 반복 행 키를, include=schema 를 지정하면 data 의 JSON Schema 를 함께 돌려줍니다. 외부 시스템이 어떤 값을 보내야 하는지 자동으로 파악할 때 사용합니다.
필요 권한documents:read
경로 변수
쿼리 파라미터
응답
not_found 없거나 다른 조직의 문서, 또는 휴지통에 있는 문서curl -X GET "https://docuel.com/api/v1/documents/8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00?include=fields%2Cschema" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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": "금액"
}
}
}
}
}
}
}
}문서 수정PATCH/api/v1/documents/{id}
제목·상태·구조·입력값을 수정합니다. 보낸 항목만 바뀝니다.
content 를 바꾸려면 양식은 templates:write, 문서는 documents:write 권한이 필요합니다.
동시 편집 충돌을 막으려면 baseVersion 에 편집을 시작한 버전을 보내세요. 그 사이 다른 저장이 있었다면 409 를 돌려줍니다.
결재가 완료되어 봉인(sealedAt)된 문서는 content·data 를 바꿀 수 없습니다.
필요 권한documents:write
경로 변수
요청 본문 application/json
응답
conflict baseVersion 불일치 또는 봉인된 문서forbidden 양식 구조 수정 권한(templates:write) 없음curl -X PATCH "https://docuel.com/api/v1/documents/8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00" \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "11월 출장비 정산 (최종)",
"status": "completed"
}'{
"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
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
문서 삭제DELETE/api/v1/documents/{id}
문서를 휴지통으로 옮깁니다. permanent=true 이면 휴지통에 있는 문서를 영구 삭제합니다.
필요 권한documents:write
경로 변수
쿼리 파라미터
true응답
bad_request 휴지통에 없는 문서를 permanent=true 로 삭제curl -X DELETE "https://docuel.com/api/v1/documents/8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"ok": true
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
문서 복사POST/api/v1/documents/{id}/copy
구조와 입력값을 그대로 복사한 새 문서를 만듭니다.
양식을 kind=document 로 복사하면 그 양식에서 시작한 문서가 됩니다 (templateId 연결).
필요 권한documents:write
경로 변수
요청 본문 application/json
응답
curl -X POST "https://docuel.com/api/v1/documents/8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00/copy" \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "11월 출장비 정산 (사본)"
}'{
"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
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
문서 구조는 그대로 두고 필드 값만 읽고 씁니다. 외부 시스템 연동의 핵심입니다.
입력값 조회GET/api/v1/documents/{id}/data
문서의 필드 입력값만 조회합니다. 계산식 결과(합계 등)도 포함됩니다.
필요 권한documents:read
경로 변수
응답
curl -X GET "https://docuel.com/api/v1/documents/8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00/data" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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/api/v1/documents/{id}/data
보낸 키만 덮어씁니다. 나머지 값은 유지됩니다.
최상위 키 단위로 병합합니다. 반복 행 배열(items 등)은 통째로 교체되므로, 행을 덧붙이려면 /rows 를 사용하세요.
필드 key 는 GET /documents/{id}?include=fields 로 확인할 수 있습니다.
필요 권한documents:write
경로 변수
요청 본문 application/json
응답
curl -X PATCH "https://docuel.com/api/v1/documents/8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00/data" \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dept": "플랫폼개발팀",
"writer": "홍길동",
"kind": "법인카드"
}'{
"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
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
입력값 교체PUT/api/v1/documents/{id}/data
data 전체를 보낸 값으로 바꿉니다. 보내지 않은 키는 지워집니다.
필요 권한documents:write
경로 변수
요청 본문 application/json
응답
curl -X PUT "https://docuel.com/api/v1/documents/8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00/data" \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"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
}'{
"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
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
반복 행 추가POST/api/v1/documents/{id}/rows
표의 반복 행(예: 품목 목록)에 행을 덧붙이거나 전체를 교체합니다.
반복 행은 양식 디자인에서 표의 행에 데이터 키(예: items)를 지정해 만듭니다. 행 안의 필드 key 가 각 객체의 속성이 됩니다.
행이 많아 페이지를 넘기면 미리보기·인쇄에서 자동으로 다음 페이지로 이어지고, 머리행은 페이지마다 반복됩니다.
필요 권한documents:write
경로 변수
요청 본문 application/json
응답
bad_request 문서에 없는 repeat 키curl -X POST "https://docuel.com/api/v1/documents/8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00/rows" \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"repeat": "items",
"rows": [
{
"date": "2026-11-05",
"desc": "택시",
"qty": 1,
"amount": 18400
}
],
"mode": "append"
}'{
"data": {
"id": "8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00",
"version": 5,
"repeat": "items",
"count": 3
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
양식에 데이터를 넣어 새 문서를 만듭니다.
양식 + 데이터 → 문서POST/api/v1/templates/{id}/instantiate
양식 구조에 데이터를 넣은 새 문서를 만듭니다. 외부 시스템에서 문서를 자동 생성하는 가장 일반적인 방법입니다.
data 의 반복 행 배열 길이만큼 표 행이 늘어납니다.
응답의 url 로 사용자가 바로 열어 확인·수정할 수 있습니다.
필요 권한documents:write
경로 변수
요청 본문 application/json
응답
bad_request id 가 양식이 아닌 문서curl -X POST "https://docuel.com/api/v1/templates/c4b836b9-eb85-4b68-9887-c6cbb3087519/instantiate" \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"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
}
]
}
}'{
"data": {
"id": "8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00",
"title": "11월 출장비 정산",
"version": 1,
"url": "https://docuel.com/app/d/8f2c41d0-…"
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
삭제한 문서는 휴지통에 보관되며 복원하거나 영구 삭제할 수 있습니다.
휴지통 목록GET/api/v1/trash
삭제된 문서·양식을 삭제 순으로 조회합니다.
필요 권한documents:read
쿼리 파라미터
응답
curl -X GET "https://docuel.com/api/v1/trash?limit=20" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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
}
}휴지통에서 복원POST/api/v1/documents/{id}/restore
휴지통의 문서를 되살립니다.
필요 권한documents:write
경로 변수
응답
curl -X POST "https://docuel.com/api/v1/documents/8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00/restore" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
휴지통 비우기DELETE/api/v1/trash
휴지통의 모든 문서를 영구 삭제합니다. 되돌릴 수 없습니다.
필요 권한documents:write
응답
curl -X DELETE "https://docuel.com/api/v1/trash" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"data": {
"purged": 4
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
저장할 때마다 버전이 기록되며, 이전 버전으로 되돌릴 수 있습니다.
버전 기록GET/api/v1/documents/{id}/versions
저장 이력을 최신순으로 최대 200개 조회합니다.
필요 권한documents:read
경로 변수
응답
curl -X GET "https://docuel.com/api/v1/documents/8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00/versions" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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"
}
]
}버전 되돌리기POST/api/v1/documents/{id}/versions/{version}/restore
지정한 버전의 구조·입력값·제목으로 되돌립니다. 현재 내용은 이전 버전으로 보존되고, 되돌린 결과가 새 버전이 됩니다.
필요 권한documents:write
경로 변수
응답
not_found 없는 버전curl -X POST "https://docuel.com/api/v1/documents/8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00/versions/1/restore" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
첨부 필드·이미지에 사용할 파일을 올리고 내려받습니다.
파일 업로드POST/api/v1/files
첨부 필드나 이미지에 쓸 파일을 올립니다 (최대 25MB).
첨부(file) 필드 값은 [{ id, name, size }] 배열입니다. 업로드 응답을 그대로 넣으면 됩니다.
필요 권한documents:write
요청 본문 multipart/form-data
응답
curl -X POST "https://docuel.com/api/v1/files" \ -H "Authorization: Bearer $DOCUEL_API_KEY" \ -F "file=@./파일.xlsx" \ -F "purpose=…"
{
"data": {
"id": "b87882f7-2c1e-4d7a-8f50-6a1d9e3c4b21",
"name": "영수증.pdf",
"size": 182344,
"mime": "application/pdf",
"sha256": "9c1e…",
"createdAt": "2026-11-03T12:00:00.000Z"
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
파일 내려받기GET/api/v1/files/{id}
파일 원본을 내려받습니다. 이미지·PDF 는 inline, 그 외는 attachment 로 응답합니다.
필요 권한documents:read
경로 변수
응답
curl -X GET "https://docuel.com/api/v1/files/b87882f7-2c1e-4d7a-8f50-6a1d9e3c4b21" \ -H "Authorization: Bearer $DOCUEL_API_KEY" \ -o 내려받은파일
이미지·엑셀·워드·HTML·LML 을 구조화 문서로 변환합니다. 비동기로 처리됩니다.
가져오기 요청POST/api/v1/imports
파일·HTML·LML 을 구조화 문서로 변환합니다. 즉시 202 를 돌려주고 백그라운드에서 처리합니다.
지원 형식 — 이미지(PNG·JPG·WEBP, AI 변환), XLSX(병합·테두리·채우기 보존), DOCX, HTML(워드·엑셀·한글 복사 내용), LML JSON.
이미지는 관리자 콘솔에서 지정한 LLM(기본 자체 LLM)이 표·필드 구조를 분석합니다. 수십 초~수 분 걸릴 수 있습니다.
JSON 으로 보낼 때는 html · lml · base64 중 하나를 사용합니다.
필요 권한imports:write
요청 본문 multipart/form-data
JSON 으로도 보낼 수 있습니다: HTML · LML — 오른쪽 테스트에서 전환해 보세요.
응답
bad_request 지원하지 않는 형식 (HWP·PDF 는 준비 중 — 캡처 이미지로 대체)rate_limited 요금제의 AI 변환 한도 초과curl -X POST "https://docuel.com/api/v1/imports" \ -H "Authorization: Bearer $DOCUEL_API_KEY" \ -F "file=@./파일.xlsx" \ -F "kind=template" \ -F "title=…" \ -F "hint=…"
{
"data": {
"id": "488679f6-97c7-4666-9ccf-79950aaef999",
"status": "queued",
"sourceType": "xlsx"
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
가져오기 상태GET/api/v1/imports/{id}
queued → running → succeeded(documentId) 또는 failed(error). 1~2초 간격으로 조회하세요.
필요 권한documents:read
경로 변수
응답
curl -X GET "https://docuel.com/api/v1/imports/488679f6-97c7-4666-9ccf-79950aaef999" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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"
}
}가져오기 목록GET/api/v1/imports
최근 50건을 조회합니다.
필요 권한documents:read
응답
curl -X GET "https://docuel.com/api/v1/imports" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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"
}
]
}양식에 연결한 외부 API 를 실행해 응답의 단독 값은 필드로, 배열은 반복 행으로 채웁니다. 연동 설정은 콘솔의 양식 › 연동 화면에서 합니다.
연동 목록GET/api/v1/documents/{id}/data-sources
문서(와 그 문서가 시작한 양식)에 연결된 외부 API 연동과 변수 정의를 조회합니다.
필요 권한documents:read
경로 변수
응답
curl -X GET "https://docuel.com/api/v1/documents/8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00/data-sources" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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
}
]
}연동 실행POST/api/v1/documents/{id}/data-sources/{sourceId}/run
외부 API 를 호출하고 매핑 규칙대로 값을 만들어 문서 data 에 반영합니다(apply=false 면 결과만).
변수(params)는 URL·쿼리·헤더·본문의 {{이름}} 에 들어갑니다. 생략하면 기본값을 씁니다 — {{today}}·{{month}}, 문서 값 {{data.필드키}}, 작성 요청 수신자 {{recipient.name}} 도 사용할 수 있습니다.
SaaS 에서는 내부망(사설 IP) 주소를 호출할 수 없습니다. 설치형은 사내 API 를 그대로 연결할 수 있습니다.
양식으로 문서를 만들 때(instantiate)와 모바일 작성 요청이 열릴 때 '자동 실행' 연동이 먼저 실행됩니다.
필요 권한documents:write
경로 변수
요청 본문 application/json
응답
upstream_error 외부 API 오류·시간 초과·JSON 아님private_network SaaS 에서 내부망 주소 호출curl -X POST "https://docuel.com/api/v1/documents/8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00/data-sources/{sourceId}/run" \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"params": {
"date": "2026-11-03",
"site": "A"
},
"apply": true
}'{
"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"
}
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
양식을 작업일지·점검표·신청서로 배포하고, 수신자별 모바일 링크로 값 입력·체크·사진 첨부·서명을 받습니다. 매일/평일 반복이면 날짜마다 새 문서가 만들어집니다. 안전관리·현장관리 플랫폼은 받은 링크를 자기 앱 푸시·문자로 보내면 됩니다.
작성 요청 만들기POST/api/v1/requests
양식을 수신자별 모바일 작성 링크로 배포합니다. 응답의 recipients[].link 를 문자·알림톡·앱 푸시로 보내세요.
mode=assigned 는 수신자마다 고유 링크(로그인 불필요)를 만들고, mode=open 은 누구나 쓸 수 있는 공용 링크(openLink) 하나를 만들어 제출할 때마다 새 문서가 생깁니다.
schedule=daily·weekdays 이면 같은 링크로 날짜(Asia/Seoul)마다 새 문서가 만들어져 작업일지·일일 점검표에 맞습니다.
양식에 자동 실행 데이터 연동이 있으면 문서가 만들어질 때 외부 API 값(예: 오늘 투입 인원)이 미리 채워집니다.
사진은 각 조직의 저장 용량 한도에 포함됩니다. photoStamp 를 켜면 촬영 일시(·위치)가 사진에 새겨집니다.
settings.contextPath(작업 위치 경로, 예: 송도 > B 생산라인 > B-1 라인 > 5축 머시닝센터)는 작성 화면 맨 위에 표시되고 제출 내역·웹훅에 함께 남습니다. 문자열(">" 구분) 또는 배열로 보낼 수 있고, recipients[].contextPath 로 수신자마다 다르게 줄 수 있습니다.
양식의 날짜·시간 필드에 autoNow 가 있으면 open = 작성 화면을 처음 열 때, submit = [완료]를 누를 때 Asia/Seoul 시각이 자동으로 기록됩니다 (비어 있을 때만).
필요 권한documents:write
요청 본문 application/json
응답
bad_request 양식이 아니거나, 지정 수신자 방식인데 수신자가 없음curl -X POST "https://docuel.com/api/v1/requests" \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"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"
}
]
}'{
"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"
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
작성 요청 목록GET/api/v1/requests
요청과 오늘(반복 요청) 또는 전체(1회 요청) 기준 제출 현황을 조회합니다.
필요 권한documents:read
응답
curl -X GET "https://docuel.com/api/v1/requests" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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
}
}
]
}작성 요청 상세GET/api/v1/requests/{id}
수신자별 링크와 현재 기간의 상태(pending · opened · in_progress · submitted), 작성 중인 문서 ID 를 돌려줍니다. contextPath 는 요청의 작업 위치, recipients[].contextPath 는 수신자별 위치(null = 요청 값)입니다.
필요 권한documents:read
경로 변수
응답
not_found 없는 요청curl -X GET "https://docuel.com/api/v1/requests/5d2f7c10-8e4b-4a3d-9b61-0f2e7a9c4d11" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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"
}
}수신자 추가POST/api/v1/requests/{id}/recipients
진행 중인 요청에 수신자를 추가하고 새 링크를 받습니다. 이미 있는 사람(디렉터리 ID·외부 ID·이름+전화)은 건너뜁니다.
필요 권한documents:write
경로 변수
요청 본문 application/json
응답
curl -X POST "https://docuel.com/api/v1/requests/5d2f7c10-8e4b-4a3d-9b61-0f2e7a9c4d11/recipients" \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"recipients": [
{
"name": "박민수",
"phone": "010-5555-1234",
"externalId": "E004",
"contextPath": [
"송도",
"C 생산라인",
"C-2 라인",
"사출기 3호"
]
}
]
}'{
"data": [
{
"id": "c3a2…",
"name": "박민수",
"phone": "010-5555-1234",
"externalId": "E004",
"contextPath": [
"송도",
"C 생산라인",
"C-2 라인",
"사출기 3호"
],
"link": "https://docuel.com/f/Zt3Qp…"
}
]
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
요청 마감POST/api/v1/requests/{id}/close
링크 사용을 중지합니다. 이후 접속하면 마감 안내가 표시됩니다(410). /reopen 으로 다시 열 수 있습니다.
필요 권한documents:write
경로 변수
응답
curl -X POST "https://docuel.com/api/v1/requests/5d2f7c10-8e4b-4a3d-9b61-0f2e7a9c4d11/close" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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"
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
제출 내역GET/api/v1/requests/{id}/submissions
제출(및 작성 중) 문서와 입력값을 조회합니다. 외부 플랫폼이 작업일지 값을 가져갈 때 사용합니다.
사진·첨부 필드 값은 [{ id, name, size }] 이며 파일은 GET /files/{id} 로 내려받습니다.
meta 에는 제출 위치(location)·IP·기기 정보가 들어갑니다.
contextPath 는 문서가 만들어질 때의 작업 위치 경로입니다 (수신자별 → 요청 순).
startedAt·completedAt 은 양식의 autoNow 날짜·시간 필드 값(open = 처음 열 때, submit = 완료 때)이고, 없으면 openedAt(처음 연 시각)·submittedAt 을 씁니다. elapsedSeconds 는 그 사이 소요 시간(초)입니다.
필요 권한documents:read
경로 변수
쿼리 파라미터
draft submitted응답
curl -X GET "https://docuel.com/api/v1/requests/5d2f7c10-8e4b-4a3d-9b61-0f2e7a9c4d11/submissions?period=2026-11-03" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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": "다음 정기점검 때 진동 재측정"
}
}
]
}작성된 문서를 결재선(결재·합의·참조·수신)에 따라 상신하고 승인·반려합니다. 결재자는 디렉터리(외부 플랫폼 회원·부서·직책)에서 지정하며, 승인하면 문서의 결재란에 도장(또는 서명)이 찍히고 최종 승인 시 문서가 봉인됩니다. 외부 결재자는 단계별 링크로 모바일에서 바로 처리합니다.
결재 상신POST/api/v1/approvals
문서를 결재선에 올립니다. 첫 결재자의 차례가 되고 문서 상태는 in_approval 이 됩니다.
결재자는 directoryUserId(디렉터리 회원) · userId(내부 계정) · approver(이름만 있는 외부 결재자) 중 하나로 지정합니다.
fieldKey 를 생략하면 결재란의 서명 필드에 자동으로 연결합니다 — 직책·직위가 라벨과 같은 칸(팀장·본부장…) → 남은 칸 순서. 기안자 도장은 '담당·기안' 칸에 찍힙니다.
연속된 합의(agree) 단계는 동시에 진행되고, 참조(cc)는 상신 즉시, 수신(receive)은 최종 승인 시 통보됩니다.
외부 결재자에게는 응답의 steps[].link 를 문자·메신저로 보내면 모바일에서 바로 승인·반려할 수 있습니다.
필요 권한approvals:write
요청 본문 application/json
응답
bad_request 양식 문서이거나 결재자를 찾을 수 없음, 결재·합의 단계 없음conflict 이미 결재 진행 중이거나 봉인된 문서curl -X POST "https://docuel.com/api/v1/approvals" \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"documentId": "8f2c41d0-5b7e-4c1a-9d3e-2a6b0c9e1f00",
"title": "모니터 구매 요청",
"note": "신규 입사자 장비",
"steps": [
{
"kind": "approve",
"directoryUserId": "d1e21…"
},
{
"kind": "agree",
"approver": {
"name": "정하늘",
"title": "경영지원팀장",
"email": "[email protected]"
}
},
{
"kind": "approve",
"directoryUserId": "d1e22…"
},
{
"kind": "cc",
"directoryUserId": "d1e23…"
}
],
"drafter": {
"directoryUserId": "d1e20…"
}
}'{
"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
}
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
결재 목록GET/api/v1/approvals
조직의 결재를 최근 상신 순으로 조회합니다. 현재 결재자와 진행률을 함께 돌려줍니다.
필요 권한approvals:read
쿼리 파라미터
in_progress approved rejected withdrawn응답
curl -X GET "https://docuel.com/api/v1/approvals?limit=20" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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"
}
]
}
]
}결재 조회GET/api/v1/approvals/{id}
결재 단계(상태·의견·처리 시각·실제 처리자)와 외부 결재 링크를 조회합니다.
steps[].actedBy 에 실제 처리자가 기록됩니다 — 관리자 대결이면 onBehalfOf 에 원래 결재자, API 처리면 via: api.
필요 권한approvals:read
경로 변수
응답
not_found 없거나 다른 조직의 결재curl -X GET "https://docuel.com/api/v1/approvals/7b1e0c42-3a9d-4f6e-8c21-5d0a9e3f1b77" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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
}
}
}승인·반려·회수POST/api/v1/approvals/{id}/actions
현재 차례의 단계를 승인·반려하거나, 진행 중인 결재를 회수합니다.
approve — 결재란에 도장(또는 signature 로 보낸 서명 이미지)을 찍고 다음 차례로 넘깁니다. 마지막 승인이면 문서가 approved 로 바뀌고 봉인되어 더 이상 수정할 수 없습니다.
reject — 결재가 반려되고 문서는 rejected 상태가 됩니다. 수정 후 다시 상신하면 새 결재가 시작됩니다.
withdraw — 기안자 회수. 찍힌 도장을 지우고 문서를 작성 중(draft)으로 되돌립니다.
skip — 부재 등으로 현재 단계를 건너뜁니다 (관리자·API).
API 키로 처리하면 연동 시스템이 결재자를 대신해 처리한 것으로 기록됩니다. stepId 를 생략하면 현재 차례의 첫 단계를 처리합니다.
필요 권한approvals:write
경로 변수
요청 본문 application/json
JSON 으로도 보낼 수 있습니다: 승인 · 반려 · 회수 — 오른쪽 테스트에서 전환해 보세요.
응답
forbidden 본인 차례가 아님 (관리자는 대결로 처리됨)conflict 이미 끝난 결재이거나 처리할 단계가 없음curl -X POST "https://docuel.com/api/v1/approvals/7b1e0c42-3a9d-4f6e-8c21-5d0a9e3f1b77/actions" \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "approve",
"comment": "확인했습니다."
}'{
"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
}
}
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
외부 플랫폼의 회원·부서·직위·직책을 동기화합니다. 전자결재 결재선과 권한에 사용됩니다.
디렉터리 조회GET/api/v1/directory
부서와 회원 전체를 조회합니다.
필요 권한directory:read
응답
curl -X GET "https://docuel.com/api/v1/directory" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"data": {
"departments": [
{
"id": "…",
"externalId": "D11",
"name": "플랫폼개발팀",
"parentId": "…",
"active": true
}
],
"members": [
{
"id": "…",
"externalId": "E001",
"name": "홍길동",
"departmentId": "…",
"position": "과장",
"title": "팀장",
"rank": 3,
"active": true
}
]
}
}부서 동기화PUT/api/v1/directory/departments
externalId 기준으로 부서를 추가·갱신합니다.
필요 권한directory:write
요청 본문 application/json
응답
curl -X PUT "https://docuel.com/api/v1/directory/departments" \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"externalId": "D10",
"name": "개발본부"
},
{
"externalId": "D11",
"name": "플랫폼개발팀",
"parentExternalId": "D10"
}
]
}'{
"data": {
"upserted": 2
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
회원 동기화PUT/api/v1/directory/users
externalId 기준으로 회원을 추가·갱신합니다. deactivateMissing=true 로 전체 동기화하면 목록에 없는 회원을 비활성화합니다.
부서 ID 대신 departmentName 만 보내면 같은 이름의 부서를 자동으로 만듭니다.
주기적으로 호출(예: 매일 새벽)하거나 인사 변경 시점에 호출하세요.
필요 권한directory:write
요청 본문 application/json
응답
curl -X PUT "https://docuel.com/api/v1/directory/users" \
-H "Authorization: Bearer $DOCUEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"externalId": "E001",
"name": "홍길동",
"email": "[email protected]",
"departmentExternalId": "D11",
"position": "과장",
"title": "팀장",
"rank": 3
}
],
"deactivateMissing": false
}'{
"data": {
"created": 1,
"updated": 0,
"deactivated": 0
}
}실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.
API 키 정보, 요금제와 사용량을 확인합니다.
키 정보·사용량GET/api/v1/me
현재 API 키, 조직, 요금제 한도와 이번 달 사용량을 확인합니다. 연결 확인용으로 먼저 호출해 보세요.
필요 권한유효한 API 키
응답
curl -X GET "https://docuel.com/api/v1/me" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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
}
]
}
}
}조직에서 일어난 모든 행위를 조회합니다.
감사 로그GET/api/v1/audit-logs
누가(사용자·API 키·외부 회원·시스템) 무엇을 했는지 최신순으로 조회합니다.
action 은 접두어 일치입니다. 예: document. (문서 관련 전체), import., auth.login
필요 권한logs:read
쿼리 파라미터
응답
curl -X GET "https://docuel.com/api/v1/audit-logs?action=document.&limit=20" \ -H "Authorization: Bearer $DOCUEL_API_KEY"
{
"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
}
}임베드 SDK — 내 서비스 화면에 에디터 넣기
외부 플랫폼의 회원이 자기 화면 안에서 문서를 열고 작성·결재할 수 있게 하는 SDK 입니다. iframe 을 직접 다루지 않고, 스크립트를 불러와 웹 컴포넌트(<docuel-document>)를 쓰거나 npm 패키지로 React·Vue 에서 바로 사용합니다.
- API 키는 서버에만 두고, 브라우저에는 회원·문서·권한이 담긴 15분짜리 세션 토큰만 전달합니다.
- Shadow DOM 으로 스타일이 격리되어 호스트 페이지 CSS 와 충돌하지 않고, 높이는 내용에 맞게 자동으로 늘어납니다.
- 변경·저장·제출·결재 이벤트를 DOM 이벤트로 받고, 저장·인쇄·값 주입을 메서드로 호출합니다.
- CSS 변수로 글꼴·색을 호스트 서비스에 맞출 수 있습니다.
- 결재 서명처럼 호스트 페이지와 완전히 분리해야 하는 화면은 SDK 가 내부적으로 격리 프레임을 쓰는 보안 모드를 제공합니다 — 사용법은 같습니다.
- 조직별 허용 도메인(Origin)에서만 동작합니다.
POST /api/v1/embed/sessions
{
"documentId": "8f2c41d0-…",
"permission": "fill", // view · fill · edit
"user": {
"externalId": "E001", "name": "홍길동",
"department": "플랫폼개발팀", "title": "팀장"
},
"ttl": 900
}
→ { "data": { "token": "eyJ…", "expiresAt": "…" } }<script type="module" src="https://docuel.com/sdk/v1/docuel.js"></script>
<docuel-document
token="eyJ…"
mode="fill"
orientation="portrait">
</docuel-document>
<script>
const el = document.querySelector("docuel-document");
el.addEventListener("docuel:change", (e) => console.log(e.detail.data));
el.addEventListener("docuel:submit", (e) => save(e.detail));
// await el.save(); el.print(); el.setData({...})
</script>npm i @docuel/sdk
import { DocuelDocument } from "@docuel/sdk/react";
<DocuelDocument token={token} mode="fill" onSubmit={save} />웹훅
문서·결재·가져오기 이벤트를 고객사 서버로 알려줍니다. 서명 헤더로 위조를 검증하고, 실패하면 지수 백오프로 재시도합니다. 전송 기록은 콘솔에서 확인합니다.
이벤트: document.created document.updated document.submitted document.trashed approval.requested approval.approved approval.rejected import.completed import.failed
POST https://고객사/webhooks/docuel
Docuel-Event: document.submitted
Docuel-Signature: t=1762142400,v1=5f2c…(HMAC-SHA256)
{ "event": "document.submitted",
"data": { "id": "8f2c41d0-…", "version": 4, "status": "submitted" },
"createdAt": "2026-11-03T12:00:00Z" }변경 이력
v1 안에서는 필드 추가처럼 하위 호환되는 변경만 합니다. 호환되지 않는 변경은 /api/v2 로 제공하고 v1 은 최소 12개월 유지합니다.