API v1
DOCUEL REST API · v1

도큐엘 API 레퍼런스

도큐엘 API 로 외부 플랫폼(그룹웨어·ERP·쇼핑몰·자체 서비스)에서 문서를 만들고, 양식에 데이터를 넣고, 표의 행을 반복해서 채우고, 이미지·엑셀·워드를 구조화 문서로 변환하고, 회원·부서를 동기화할 수 있습니다. 화면에서 할 수 있는 모든 일을 API 로도 할 수 있고, 모든 호출은 API 로그와 감사 로그에 남습니다.

REST 방식이며 요청·응답은 UTF-8 JSON 입니다. 인증은 조직별 API 키(Bearer)로 하며, 키는 반드시 서버에서만 사용하세요. 브라우저에 키를 노출하지 마세요 — 외부 회원이 브라우저에서 문서를 여는 기능은 임베드 SDK 로 제공됩니다.

OpenAPI 3.1 명세: /api/v1/openapi.json — Postman, Swagger UI, 코드 생성기에 그대로 가져올 수 있습니다.

기본 주소 (Base URL)
https://docuel.com/api/v1
연결 확인
curl https://docuel.com/api/v1/me \
  -H "Authorization: Bearer $DOCUEL_API_KEY"
이 페이지에서 바로 테스트
왼쪽 위에 API 키를 넣으면 각 엔드포인트의 [요청 보내기]로 실제 호출할 수 있습니다. 문서를 만들면 그 ID 가 다른 요청에 자동으로 채워집니다.
시작하기

빠른 시작 — 양식에 데이터를 넣어 문서 만들기

  1. API 키 발급 — 콘솔 › API 키·임베드 에서 발급합니다. 발급 직후 한 번만 표시되니 안전한 곳(서버 환경변수)에 저장하세요. 이 문서 페이지에서는 로그인 후 왼쪽 위 버튼으로 24시간 테스트 키를 받을 수 있습니다.
  2. 양식 준비 — 에디터에서 양식을 디자인하거나, 가져오기 로 기존 서식(이미지·엑셀·워드)을 변환합니다. 표의 반복 행에 데이터 키(예: items)를 지정해 두세요.
  3. 문서 생성 — 양식 + 데이터 → 문서 를 호출합니다. 필드 key 는 문서 조회 의 include=fields 로 확인합니다.
  4. 계속 채우기 — 입력값 병합·반복 행 추가 로 값을 갱신합니다. 합계 같은 계산식은 저장 시 자동으로 계산되어 data 에 들어갑니다.
  5. 사용자에게 보여주기 — 응답의 url 을 열면 미리보기(세로/가로·자동 페이지)·인쇄·수정이 가능합니다.
1. 키 확인
export DOCUEL_API_KEY=dcl_live_...
curl https://docuel.com/api/v1/me -H "Authorization: Bearer $DOCUEL_API_KEY"
2. 양식 ID 찾기
curl "https://docuel.com/api/v1/documents?kind=template" \
  -H "Authorization: Bearer $DOCUEL_API_KEY"
3. 데이터를 넣어 문서 생성
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}]}}'
4. 행 추가 → 합계 확인
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.

권한 목록

documents:read문서 조회
documents:write문서 작성·수정·삭제
templates:write양식 디자인
imports:write문서 가져오기(AI 변환)
directory:read디렉터리 조회
directory:write디렉터리 동기화
approvals:read결재 조회
approvals:write결재 상신·처리
embed:write임베드 세션 발급
webhooks:write웹훅 관리
logs:read로그 조회
keys:writeAPI 키 관리
members:write멤버 관리
org:write조직 설정
헤더
Authorization: Bearer dcl_live_XXXXXXXXXXXXXXXXXXXXXXXX

# 또는
X-API-Key: dcl_live_XXXXXXXXXXXXXXXXXXXXXXXX
401 응답
{
  "error": {
    "code": "unauthorized",
    "message": "유효하지 않은 API 키입니다."
  }
}
403 응답 (권한 부족)
{
  "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 기준으로 하세요.

400bad_request요청 형식이 올바르지 않음
400invalid_json본문 JSON 을 해석할 수 없음
400validation_error필드 검증 실패 — details 에 위치·사유
401unauthorizedAPI 키 없음·잘못됨·만료·폐기
403forbidden키 권한(스코프) 부족 또는 조직 정지
403ip_not_allowed키의 허용 IP 목록에 없는 요청
404not_found대상 없음 (다른 조직의 리소스도 404)
409conflict버전 충돌·봉인 문서 수정
429rate_limited요금제 한도 초과
500internal_error서버 오류 — x-request-id 를 알려주세요
503llm_unavailableAI 변환 엔진을 일시적으로 사용할 수 없음
429 한도 초과
{
  "error": {
    "code": "rate_limited",
    "message": "요금제 한도를 초과했습니다. (Business: apiCalls 500000/500000)"
  }
}
시작하기

한도·사용량

요금제별로 월 API 호출 수와 AI 변환 수, 문서 수가 정해져 있습니다. 한도를 넘으면 429 rate_limited 를 돌려줍니다. 현재 사용량은 GET /me 로 확인합니다. 설치형(Enterprise)은 한도가 없습니다.

요금제API 호출/월AI 변환/월문서
Free1,0001050
Pro50,0003002,000
Business500,0002,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 로는 값만 주고받을 수 있습니다.

page.size"A3" | "A4" | "A5" | "B4" | "B5" | "Letter" | "Legal"
용지 크기
page.orientation"portrait" | "landscape"
세로·가로. 바꾸면 미리보기·인쇄가 새 용지에 맞춰 다시 배치됩니다.
page.margin{ top, right, bottom, left } (mm)
여백
style{ fontFamily, fontSize(pt), lineHeight, color }
문서 기본 글자
bodyProseMirror JSON
본문 블록 트리 — 아래 노드로 구성

본문 노드

paragraph · heading
textAlign, lineHeight, indent, spacingBefore/After · heading.level(1~3)
text + marks
bold, italic, underline, strike, sub/superscript, highlight, textStyle(fontFamily, fontSize, color, backgroundColor, letterSpacing)
table
border(기본 선), width(본문 폭 %), align
tableRow
repeat(반복 데이터 키), repeatMin, headerRepeat(페이지마다 반복), height
tableCell · tableHeader
colspan, rowspan, colwidth, background, borderTop/Right/Bottom/Left, verticalAlign, padding, diagonal(사선)
field
입력 필드 — key, type, label, required, options, multiple, formula, readonly, width, align
image · pageBreak
이미지 · 강제 페이지 나눔
content (ZDoc) 예시
{
  "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 를 붙여 받을 수 있습니다.

text텍스트
string — 예: "홍길동"
textarea여러 줄
string (줄바꿈 \n) — 예: "1행\n2행"
number숫자
number — 예: 3
currency금액
number (원 단위 정수 권장) — 예: 59800
date날짜
string "YYYY-MM-DD" — 예: "2026-11-03"
time시간
string "HH:mm" — 예: "14:30"
datetime날짜·시간
string "YYYY-MM-DDTHH:mm" — 예: "2026-11-03T14:30"
checkbox체크박스
boolean (선택지 없음) · string (단일) · string[] (multiple) — 예: ["연차","병가"]
radio라디오
string (선택지 중 하나) — 예: "법인카드"
select선택 목록
string (선택지 중 하나) — 예: "서울"
email이메일
string — 예: "[email protected]"
phone전화번호
string — 예: "010-1234-5678"
file첨부파일
{ id, name, size }[] — POST /files 응답 — 예: [{"id":"b878…","name":"영수증.pdf","size":182344}]
signature서명
string (PNG data URL) — 예: "data:image/png;base64,…"
formula계산식
number — 읽기 전용, 저장 시 자동 계산 — 예: 151800
rule조건값
— 예:
data 예시
{
  "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
    }
  ]
}
조건 (Cond)
{
  "field": "result",
  "op": "eq",
  "value": "부적합"
}

op: eq ne gt gte lt lte contains notContains empty notEmpty
field: 키 · "@" = 이 칸/필드 자신
핵심 개념

Document 객체

양식과 작성 문서는 같은 객체이며 kind 로 구분합니다.

iduuid
문서 ID
orgIduuid
조직 ID
kind"document" | "template"
작성 문서 / 양식
titlestring
제목
descriptionstring | null
설명
categorystring | null
분류
templateIduuid | null
시작한 양식
statusstring
draft · published · submitted · in_approval · approved · rejected · completed · archived
contentZDoc
문서 구조 (용지·기본 서식·본문)
dataobject
입력값 (계산식 결과 포함)
versioninteger
저장할 때마다 1 증가
contentHashstring
content+data 해시 (위·변조 확인)
tagsstring[]
태그
createdBy · updatedBystring
행위자 참조 — user:<id> · api_key:<id> · external:<외부ID>
sealedAtdatetime | null
결재 완료로 봉인된 시각 (이후 수정 불가)
createdAt · updatedAtdatetime
ISO 8601 (UTC)
deletedAt · deletedBydatetime | null
휴지통으로 옮긴 시각·행위자
Document
{
  "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 } 로 보내도 됩니다.

blocks[].type"heading" | "paragraph" | "table" | "spacer" | "pageBreak"
블록 종류
table.columnsnumber[]
열 상대 너비 — 본문 폭에 맞게 환산
table.width · alignnumber(%) · left|center|right
결재란처럼 좁은 표
row.repeat · row.headerstring · boolean
반복 행 키 · 페이지마다 반복할 머리행
cell{ text | parts | field, colspan, rowspan, header, bg, align, valign, diagonal }
셀. parts 로 글자와 필드를 섞을 수 있음
field{ type, key, label, options?, multiple?, formula? }
입력 필드
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"
          }
        }
      ]
    }
  ]
}
API
문서

양식(template)과 작성 문서(document)를 만들고 조회·수정합니다. 둘은 같은 객체이며 kind 로 구분합니다.

문서 목록GET/api/v1/documents

조직의 문서·양식을 최근 수정 순으로 조회합니다.

본문(content)과 데이터(data)는 포함하지 않습니다. 개별 조회를 사용하세요.

다음 페이지는 응답의 nextCursor 를 before 로 넘겨 조회합니다.

필요 권한documents:read

쿼리 파라미터

kindstring
document · template · all (기본 document)— document template all
qstring
제목·분류 부분 일치 검색
statusstring
상태 필터— draft published submitted in_approval approved rejected completed archived
categorystring
분류 정확히 일치
templateIduuid
특정 양식으로 만든 문서만
limitinteger
1~200, 기본 50
beforedatetime
커서 — 이전 응답의 nextCursor

응답

200목록
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
  }
}
테스트GET /api/v1/documents
쿼리
kind
q
status
category
templateId
limit
before
cURL 로 복사

문서 만들기POST/api/v1/documents

빈 문서, 양식, 또는 양식에서 시작하는 문서를 만듭니다.

양식(kind=template)을 만들려면 templates:write 권한이 필요합니다.

계산식 필드의 결과는 저장 시 data 에 자동으로 채워집니다.

필요 권한documents:write

요청 본문 application/json

kind"document" | "template"
작성 문서 또는 양식. 기본 document
titlestring
제목 (1~200자). 기본 "제목 없는 문서"
descriptionstring | null
설명
categorystring | null
분류 (목록 필터에 사용)
contentZDoc
문서 구조. 생략하면 빈 A4 문서 (templateId 가 있으면 양식 구조를 복사)
dataobject
필드 입력값. 필드 key 를 속성으로, 반복 행은 배열로
templateIduuid | null
양식에서 시작할 때 양식 ID — 구조와 기본값을 복사
tagsstring[]
태그 (최대 20개)

응답

200생성된 문서 객체
429rate_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
  }
}
테스트POST /api/v1/documents
요청 본문
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

문서 조회GET/api/v1/documents/{id}

문서 구조(content)와 입력값(data)을 포함한 전체 객체를 조회합니다.

include=fields 를 지정하면 문서 안의 입력 필드 목록과 반복 행 키를, include=schema 를 지정하면 data 의 JSON Schema 를 함께 돌려줍니다. 외부 시스템이 어떤 값을 보내야 하는지 자동으로 파악할 때 사용합니다.

필요 권한documents:read

경로 변수

iduuid필수
문서 ID

쿼리 파라미터

includestring
fields, schema (쉼표 구분)

응답

200문서 객체
404not_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": "금액"
              }
            }
          }
        }
      }
    }
  }
}
테스트GET /api/v1/documents/{id}
경로 변수
id
쿼리
include
cURL 로 복사

문서 수정PATCH/api/v1/documents/{id}

제목·상태·구조·입력값을 수정합니다. 보낸 항목만 바뀝니다.

content 를 바꾸려면 양식은 templates:write, 문서는 documents:write 권한이 필요합니다.

동시 편집 충돌을 막으려면 baseVersion 에 편집을 시작한 버전을 보내세요. 그 사이 다른 저장이 있었다면 409 를 돌려줍니다.

결재가 완료되어 봉인(sealedAt)된 문서는 content·data 를 바꿀 수 없습니다.

필요 권한documents:write

경로 변수

iduuid필수
문서 ID

요청 본문 application/json

titlestring
제목
statusstring
draft · published · submitted · in_approval · approved · rejected · completed · archived
descriptionstring | null
설명
categorystring | null
분류
contentZDoc
문서 구조 전체 (부분 수정 불가)
dataobject
입력값 전체 (병합하려면 /data PATCH 사용)
tagsstring[]
태그
baseVersioninteger
낙관적 잠금 — 현재 버전과 다르면 409
reasonstring
버전 기록에 남길 사유

응답

200수정된 문서 객체
409conflict baseVersion 불일치 또는 봉인된 문서
403forbidden 양식 구조 수정 권한(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
  }
}
테스트PATCH /api/v1/documents/{id}
경로 변수
id
요청 본문
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

문서 삭제DELETE/api/v1/documents/{id}

문서를 휴지통으로 옮깁니다. permanent=true 이면 휴지통에 있는 문서를 영구 삭제합니다.

필요 권한documents:write

경로 변수

iduuid필수
문서 ID

쿼리 파라미터

permanentboolean
true: 휴지통 문서 영구 삭제 (되돌릴 수 없음)— true

응답

200처리됨
400bad_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
}
테스트DELETE /api/v1/documents/{id}
경로 변수
id
쿼리
permanent
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

문서 복사POST/api/v1/documents/{id}/copy

구조와 입력값을 그대로 복사한 새 문서를 만듭니다.

양식을 kind=document 로 복사하면 그 양식에서 시작한 문서가 됩니다 (templateId 연결).

필요 권한documents:write

경로 변수

iduuid필수
문서 ID

요청 본문 application/json

titlestring
새 제목 (기본: 원래 제목 + " (사본)")
kind"document" | "template"
바꿀 종류 (기본: 원본과 동일)

응답

200새 문서 객체
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
  }
}
테스트POST /api/v1/documents/{id}/copy
경로 변수
id
요청 본문
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

API
입력 데이터

문서 구조는 그대로 두고 필드 값만 읽고 씁니다. 외부 시스템 연동의 핵심입니다.

입력값 조회GET/api/v1/documents/{id}/data

문서의 필드 입력값만 조회합니다. 계산식 결과(합계 등)도 포함됩니다.

필요 권한documents:read

경로 변수

iduuid필수
문서 ID

응답

200data 객체
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
  }
}
테스트GET /api/v1/documents/{id}/data
경로 변수
id
cURL 로 복사

입력값 병합PATCH/api/v1/documents/{id}/data

보낸 키만 덮어씁니다. 나머지 값은 유지됩니다.

최상위 키 단위로 병합합니다. 반복 행 배열(items 등)은 통째로 교체되므로, 행을 덧붙이려면 /rows 를 사용하세요.

필드 key 는 GET /documents/{id}?include=fields 로 확인할 수 있습니다.

필요 권한documents:write

경로 변수

iduuid필수
문서 ID

요청 본문 application/json

<필드 key>any
필드 값. 숫자·금액은 number, 날짜는 YYYY-MM-DD, 체크박스(복수)는 string[], 첨부는 [{ id, name, size }]

응답

200병합 후 data
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
  }
}
테스트PATCH /api/v1/documents/{id}/data
경로 변수
id
요청 본문
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

입력값 교체PUT/api/v1/documents/{id}/data

data 전체를 보낸 값으로 바꿉니다. 보내지 않은 키는 지워집니다.

필요 권한documents:write

경로 변수

iduuid필수
문서 ID

요청 본문 application/json

<필드 key>any
전체 입력값

응답

200교체 후 data
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
  }
}
테스트PUT /api/v1/documents/{id}/data
경로 변수
id
요청 본문
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

반복 행 추가POST/api/v1/documents/{id}/rows

표의 반복 행(예: 품목 목록)에 행을 덧붙이거나 전체를 교체합니다.

반복 행은 양식 디자인에서 표의 행에 데이터 키(예: items)를 지정해 만듭니다. 행 안의 필드 key 가 각 객체의 속성이 됩니다.

행이 많아 페이지를 넘기면 미리보기·인쇄에서 자동으로 다음 페이지로 이어지고, 머리행은 페이지마다 반복됩니다.

필요 권한documents:write

경로 변수

iduuid필수
문서 ID

요청 본문 application/json

repeatstring필수
반복 행 키 (예: items) — 문서에 없으면 400
rowsobject[]필수
추가할 행 (1~5,000개)
mode"append" | "replace"
append(기본): 뒤에 추가 · replace: 전체 교체

응답

200결과
400bad_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
  }
}
테스트POST /api/v1/documents/{id}/rows
경로 변수
id
요청 본문
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

API
양식으로 문서 만들기

양식에 데이터를 넣어 새 문서를 만듭니다.

양식 + 데이터 → 문서POST/api/v1/templates/{id}/instantiate

양식 구조에 데이터를 넣은 새 문서를 만듭니다. 외부 시스템에서 문서를 자동 생성하는 가장 일반적인 방법입니다.

data 의 반복 행 배열 길이만큼 표 행이 늘어납니다.

응답의 url 로 사용자가 바로 열어 확인·수정할 수 있습니다.

필요 권한documents:write

경로 변수

iduuid필수
양식 ID

요청 본문 application/json

titlestring
문서 제목 (기본: 양식 제목)
dataobject
입력값 (필드 key 기준) — 연동 값보다 우선
sourcesstring[]
추가로 실행할 연동 이름·ID (자동 실행 연동은 항상 실행)
paramsobject
연동 변수 값 (예: { date, site })

응답

200생성된 문서 요약
400bad_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-…"
  }
}
테스트POST /api/v1/templates/{id}/instantiate
경로 변수
id
요청 본문
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

API
휴지통

삭제한 문서는 휴지통에 보관되며 복원하거나 영구 삭제할 수 있습니다.

휴지통 목록GET/api/v1/trash

삭제된 문서·양식을 삭제 순으로 조회합니다.

필요 권한documents:read

쿼리 파라미터

limitinteger
1~200, 기본 50

응답

200목록
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
  }
}
테스트GET /api/v1/trash
쿼리
limit
cURL 로 복사

휴지통에서 복원POST/api/v1/documents/{id}/restore

휴지통의 문서를 되살립니다.

필요 권한documents:write

경로 변수

iduuid필수
휴지통 문서 ID

응답

200복원된 문서
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
  }
}
테스트POST /api/v1/documents/{id}/restore
경로 변수
id
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

휴지통 비우기DELETE/api/v1/trash

휴지통의 모든 문서를 영구 삭제합니다. 되돌릴 수 없습니다.

필요 권한documents:write

응답

200삭제 수
curl -X DELETE "https://docuel.com/api/v1/trash" \
  -H "Authorization: Bearer $DOCUEL_API_KEY"
{
  "data": {
    "purged": 4
  }
}
테스트DELETE /api/v1/trash
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

API
버전

저장할 때마다 버전이 기록되며, 이전 버전으로 되돌릴 수 있습니다.

버전 기록GET/api/v1/documents/{id}/versions

저장 이력을 최신순으로 최대 200개 조회합니다.

필요 권한documents:read

경로 변수

iduuid필수
문서 ID

응답

200버전 목록
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"
    }
  ]
}
테스트GET /api/v1/documents/{id}/versions
경로 변수
id
cURL 로 복사

버전 되돌리기POST/api/v1/documents/{id}/versions/{version}/restore

지정한 버전의 구조·입력값·제목으로 되돌립니다. 현재 내용은 이전 버전으로 보존되고, 되돌린 결과가 새 버전이 됩니다.

필요 권한documents:write

경로 변수

iduuid필수
문서 ID
versioninteger필수
되돌릴 버전 번호

응답

200되돌린 문서
404not_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
  }
}
테스트POST /api/v1/documents/{id}/versions/{version}/restore
경로 변수
id
version
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

API
파일

첨부 필드·이미지에 사용할 파일을 올리고 내려받습니다.

파일 업로드POST/api/v1/files

첨부 필드나 이미지에 쓸 파일을 올립니다 (최대 25MB).

첨부(file) 필드 값은 [{ id, name, size }] 배열입니다. 업로드 응답을 그대로 넣으면 됩니다.

필요 권한documents:write

요청 본문 multipart/form-data

filefile필수
업로드할 파일
purposestring
attachment(기본) · image · signature

응답

201파일 정보
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"
  }
}
테스트POST /api/v1/files
요청 본문
file
purpose
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

파일 내려받기GET/api/v1/files/{id}

파일 원본을 내려받습니다. 이미지·PDF 는 inline, 그 외는 attachment 로 응답합니다.

필요 권한documents:read

경로 변수

iduuid필수
파일 ID

응답

200파일 바이너리 (Content-Type, Content-Disposition 포함)
curl -X GET "https://docuel.com/api/v1/files/b87882f7-2c1e-4d7a-8f50-6a1d9e3c4b21" \
  -H "Authorization: Bearer $DOCUEL_API_KEY" \
  -o 내려받은파일
테스트GET /api/v1/files/{id}
경로 변수
id
cURL 로 복사
API
가져오기 (AI 변환)

이미지·엑셀·워드·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

filefile필수
이미지·xlsx·docx·html·json(LML)
kind"template" | "document"
만들 종류 (기본 template)
titlestring
제목 (생략 시 파일·문서에서 추출)
hintstring
AI 추가 지시 (예: 품목 표는 반복 행으로)

JSON 으로도 보낼 수 있습니다: HTML · LML — 오른쪽 테스트에서 전환해 보세요.

응답

202접수됨
400bad_request 지원하지 않는 형식 (HWP·PDF 는 준비 중 — 캡처 이미지로 대체)
429rate_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"
  }
}
테스트POST /api/v1/imports
요청 본문
file
kind
title
hint
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

가져오기 상태GET/api/v1/imports/{id}

queued → running → succeeded(documentId) 또는 failed(error). 1~2초 간격으로 조회하세요.

필요 권한documents:read

경로 변수

iduuid필수
가져오기 ID

응답

200가져오기 객체
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/{id}
경로 변수
id
cURL 로 복사

가져오기 목록GET/api/v1/imports

최근 50건을 조회합니다.

필요 권한documents:read

응답

200목록
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"
    }
  ]
}
테스트GET /api/v1/imports
cURL 로 복사
API
데이터 연동 (외부 API)

양식에 연결한 외부 API 를 실행해 응답의 단독 값은 필드로, 배열은 반복 행으로 채웁니다. 연동 설정은 콘솔의 양식 › 연동 화면에서 합니다.

연동 목록GET/api/v1/documents/{id}/data-sources

문서(와 그 문서가 시작한 양식)에 연결된 외부 API 연동과 변수 정의를 조회합니다.

필요 권한documents:read

경로 변수

iduuid필수
문서 ID

응답

200연동 목록
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
    }
  ]
}
테스트GET /api/v1/documents/{id}/data-sources
경로 변수
id
cURL 로 복사

연동 실행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

경로 변수

iduuid필수
문서 ID
sourceIduuid필수
연동 ID

요청 본문 application/json

paramsobject
변수 값 { 이름: 값 }
applyboolean
true(기본): 문서에 저장 · false: 결과만

응답

200매핑 결과
502upstream_error 외부 API 오류·시간 초과·JSON 아님
400private_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"
    }
  }
}
테스트POST /api/v1/documents/{id}/data-sources/{sourceId}/run
경로 변수
id
sourceId
요청 본문
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

API
작성 요청 (모바일)

양식을 작업일지·점검표·신청서로 배포하고, 수신자별 모바일 링크로 값 입력·체크·사진 첨부·서명을 받습니다. 매일/평일 반복이면 날짜마다 새 문서가 만들어집니다. 안전관리·현장관리 플랫폼은 받은 링크를 자기 앱 푸시·문자로 보내면 됩니다.

작성 요청 만들기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

templateIduuid필수
배포할 양식 ID (kind=template)
titlestring필수
요청 제목 (문서 제목 앞부분)
descriptionstring
설명
mode"assigned" | "open"
지정 수신자(기본) · 공용 링크
schedule"once" | "daily" | "weekdays"
1회(기본) · 매일 · 평일 — 반복이면 날짜별 문서
dueAtdate | datetime
작성 기한 (안내용)
expiresAtdate | datetime
링크 만료 — 이후 접속 시 410
settingsobject
작성 화면 옵션
photoStampboolean
사진에 촬영 일시·위치 표시
collectLocationboolean
제출 시 GPS 위치 기록
allowEditboolean
제출 후 수정 허용
instructionsstring
작성 화면 상단 안내문
webhookUrlurl
제출될 때마다 POST 로 알림 (request.submitted)
contextPathstring | string[]
작업 위치 경로 — ["송도", "B 생산라인"] 또는 "송도 > B 생산라인" (최대 8단계)
recipientsobject[]
수신자 (직접 지정)
namestring필수
이름
phonestring
휴대폰 (발송용)
emailstring
이메일
externalIdstring
외부 플랫폼 회원 ID — 감사 로그·웹훅에 표시
contextPathstring | string[]
이 수신자만 다른 작업 위치 (없으면 settings.contextPath)
directoryUserIdsuuid[]
디렉터리 회원 ID — 이름·연락처를 디렉터리에서 가져옴

응답

201요청 상세 (수신자별 링크 포함)
400bad_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"
  }
}
테스트POST /api/v1/requests
요청 본문
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

작성 요청 목록GET/api/v1/requests

요청과 오늘(반복 요청) 또는 전체(1회 요청) 기준 제출 현황을 조회합니다.

필요 권한documents:read

응답

200목록
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
cURL 로 복사

작성 요청 상세GET/api/v1/requests/{id}

수신자별 링크와 현재 기간의 상태(pending · opened · in_progress · submitted), 작성 중인 문서 ID 를 돌려줍니다. contextPath 는 요청의 작업 위치, recipients[].contextPath 는 수신자별 위치(null = 요청 값)입니다.

필요 권한documents:read

경로 변수

iduuid필수
작성 요청 ID

응답

200요청 상세
404not_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"
  }
}
테스트GET /api/v1/requests/{id}
경로 변수
id
cURL 로 복사

수신자 추가POST/api/v1/requests/{id}/recipients

진행 중인 요청에 수신자를 추가하고 새 링크를 받습니다. 이미 있는 사람(디렉터리 ID·외부 ID·이름+전화)은 건너뜁니다.

필요 권한documents:write

경로 변수

iduuid필수
작성 요청 ID

요청 본문 application/json

recipientsobject[]
{ name, phone?, email?, externalId?, contextPath? }
directoryUserIdsuuid[]
디렉터리 회원 ID
contextPathstring | string[]
이번에 추가하는 수신자 전체의 작업 위치 (각 recipients[].contextPath 가 우선, 없으면 요청 값)

응답

200추가된 수신자와 링크
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…"
    }
  ]
}
테스트POST /api/v1/requests/{id}/recipients
경로 변수
id
요청 본문
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

요청 마감POST/api/v1/requests/{id}/close

링크 사용을 중지합니다. 이후 접속하면 마감 안내가 표시됩니다(410). /reopen 으로 다시 열 수 있습니다.

필요 권한documents:write

경로 변수

iduuid필수
작성 요청 ID

응답

200마감된 요청
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"
  }
}
테스트POST /api/v1/requests/{id}/close
경로 변수
id
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(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

경로 변수

iduuid필수
작성 요청 ID

쿼리 파라미터

periodstring
기간 (YYYY-MM-DD, 1회 요청은 빈 값)
statusstring
draft · submitted— draft submitted

응답

200제출 목록
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": "다음 정기점검 때 진동 재측정"
      }
    }
  ]
}
테스트GET /api/v1/requests/{id}/submissions
경로 변수
id
쿼리
period
status
cURL 로 복사
API
전자결재

작성된 문서를 결재선(결재·합의·참조·수신)에 따라 상신하고 승인·반려합니다. 결재자는 디렉터리(외부 플랫폼 회원·부서·직책)에서 지정하며, 승인하면 문서의 결재란에 도장(또는 서명)이 찍히고 최종 승인 시 문서가 봉인됩니다. 외부 결재자는 단계별 링크로 모바일에서 바로 처리합니다.

결재 상신POST/api/v1/approvals

문서를 결재선에 올립니다. 첫 결재자의 차례가 되고 문서 상태는 in_approval 이 됩니다.

결재자는 directoryUserId(디렉터리 회원) · userId(내부 계정) · approver(이름만 있는 외부 결재자) 중 하나로 지정합니다.

fieldKey 를 생략하면 결재란의 서명 필드에 자동으로 연결합니다 — 직책·직위가 라벨과 같은 칸(팀장·본부장…) → 남은 칸 순서. 기안자 도장은 '담당·기안' 칸에 찍힙니다.

연속된 합의(agree) 단계는 동시에 진행되고, 참조(cc)는 상신 즉시, 수신(receive)은 최종 승인 시 통보됩니다.

외부 결재자에게는 응답의 steps[].link 를 문자·메신저로 보내면 모바일에서 바로 승인·반려할 수 있습니다.

필요 권한approvals:write

요청 본문 application/json

documentIduuid필수
결재할 문서 (양식이 아닌 작성 문서)
titlestring
결재 제목 (기본: 문서 제목)
notestring
상신 의견
stepsobject[]필수
결재선 (순서대로, 최대 30)
kind"approve" | "agree" | "cc" | "receive"
결재 · 합의 · 참조 · 수신 (기본 approve)
directoryUserIduuid
디렉터리 회원 ID
userIduuid
내부 계정 ID
approver{ name, email?, externalId?, title?, position?, department? }
디렉터리에 없는 외부 결재자
fieldKeystring | null
도장을 찍을 서명 필드 키 (생략=자동, null=찍지 않음)
drafter{ directoryUserId? , name? }
기안자 (API 로 상신할 때 지정, 생략 시 키 이름)
drafterFieldKeystring | null
기안자 도장 칸 (생략=자동, null=찍지 않음)

응답

201생성된 결재 (단계·외부 결재 링크 포함)
400bad_request 양식 문서이거나 결재자를 찾을 수 없음, 결재·합의 단계 없음
409conflict 이미 결재 진행 중이거나 봉인된 문서
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
    }
  }
}
테스트POST /api/v1/approvals
요청 본문
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

결재 목록GET/api/v1/approvals

조직의 결재를 최근 상신 순으로 조회합니다. 현재 결재자와 진행률을 함께 돌려줍니다.

필요 권한approvals:read

쿼리 파라미터

statusstring
상태— in_progress approved rejected withdrawn
documentIduuid
특정 문서의 결재 이력
limitinteger
1~200, 기본 100

응답

200목록
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
쿼리
status
documentId
limit
cURL 로 복사

결재 조회GET/api/v1/approvals/{id}

결재 단계(상태·의견·처리 시각·실제 처리자)와 외부 결재 링크를 조회합니다.

steps[].actedBy 에 실제 처리자가 기록됩니다 — 관리자 대결이면 onBehalfOf 에 원래 결재자, API 처리면 via: api.

필요 권한approvals:read

경로 변수

iduuid필수
결재 ID

응답

200결재
404not_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
    }
  }
}
테스트GET /api/v1/approvals/{id}
경로 변수
id
cURL 로 복사

승인·반려·회수POST/api/v1/approvals/{id}/actions

현재 차례의 단계를 승인·반려하거나, 진행 중인 결재를 회수합니다.

approve — 결재란에 도장(또는 signature 로 보낸 서명 이미지)을 찍고 다음 차례로 넘깁니다. 마지막 승인이면 문서가 approved 로 바뀌고 봉인되어 더 이상 수정할 수 없습니다.

reject — 결재가 반려되고 문서는 rejected 상태가 됩니다. 수정 후 다시 상신하면 새 결재가 시작됩니다.

withdraw — 기안자 회수. 찍힌 도장을 지우고 문서를 작성 중(draft)으로 되돌립니다.

skip — 부재 등으로 현재 단계를 건너뜁니다 (관리자·API).

API 키로 처리하면 연동 시스템이 결재자를 대신해 처리한 것으로 기록됩니다. stepId 를 생략하면 현재 차례의 첫 단계를 처리합니다.

필요 권한approvals:write

경로 변수

iduuid필수
결재 ID

요청 본문 application/json

action"approve" | "reject" | "withdraw" | "skip"필수
처리
stepIduuid
처리할 단계 (생략 시 현재 차례)
commentstring
의견 · 반려 사유
signaturestring
서명 이미지 data URL (data:image/png;base64,…) — 없으면 이름 도장

JSON 으로도 보낼 수 있습니다: 승인 · 반려 · 회수 — 오른쪽 테스트에서 전환해 보세요.

응답

200처리 결과 (in_progress · approved · rejected · withdrawn) 와 갱신된 결재
403forbidden 본인 차례가 아님 (관리자는 대결로 처리됨)
409conflict 이미 끝난 결재이거나 처리할 단계가 없음
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
      }
    }
  }
}
테스트POST /api/v1/approvals/{id}/actions
경로 변수
id
요청 본문
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

API
디렉터리

외부 플랫폼의 회원·부서·직위·직책을 동기화합니다. 전자결재 결재선과 권한에 사용됩니다.

디렉터리 조회GET/api/v1/directory

부서와 회원 전체를 조회합니다.

필요 권한directory:read

응답

200부서·회원
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
      }
    ]
  }
}
테스트GET /api/v1/directory
cURL 로 복사

부서 동기화PUT/api/v1/directory/departments

externalId 기준으로 부서를 추가·갱신합니다.

필요 권한directory:write

요청 본문 application/json

itemsobject[]필수
부서 목록 (최대 5,000)
externalIdstring필수
외부 플랫폼의 부서 ID
namestring필수
부서명
parentExternalIdstring
상위 부서 ID
codestring
부서 코드 (문서번호 채번 등)
sortinteger
정렬 순서
activeboolean
사용 여부

응답

200결과
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
  }
}
테스트PUT /api/v1/directory/departments
요청 본문
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

회원 동기화PUT/api/v1/directory/users

externalId 기준으로 회원을 추가·갱신합니다. deactivateMissing=true 로 전체 동기화하면 목록에 없는 회원을 비활성화합니다.

부서 ID 대신 departmentName 만 보내면 같은 이름의 부서를 자동으로 만듭니다.

주기적으로 호출(예: 매일 새벽)하거나 인사 변경 시점에 호출하세요.

필요 권한directory:write

요청 본문 application/json

itemsobject[]필수
회원 목록 (최대 20,000)
externalIdstring필수
외부 플랫폼 회원 ID
namestring필수
이름
emailstring
이메일
phonestring
전화
departmentExternalIdstring
부서 ID
departmentNamestring
부서명 (ID 대신)
positionstring
직위 (과장 등)
titlestring
직책 (팀장 등)
rankinteger
서열 — 작을수록 상위. 결재선 자동 지정에 사용
rolesstring[]
외부 플랫폼 역할 (문서 권한에 사용)
activeboolean
재직 여부
deactivateMissingboolean
true: 목록에 없는 기존 회원 비활성화 (전체 동기화)

응답

200결과
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
  }
}
테스트PUT /api/v1/directory/users
요청 본문
cURL 로 복사

실제 조직 데이터에 반영됩니다. 데모 계정(demo1)의 테스트 키 사용을 권장합니다.

API
계정·사용량

API 키 정보, 요금제와 사용량을 확인합니다.

키 정보·사용량GET/api/v1/me

현재 API 키, 조직, 요금제 한도와 이번 달 사용량을 확인합니다. 연결 확인용으로 먼저 호출해 보세요.

필요 권한유효한 API 키

응답

200키·사용량
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/me
cURL 로 복사
API
로그

조직에서 일어난 모든 행위를 조회합니다.

감사 로그GET/api/v1/audit-logs

누가(사용자·API 키·외부 회원·시스템) 무엇을 했는지 최신순으로 조회합니다.

action 은 접두어 일치입니다. 예: document. (문서 관련 전체), import., auth.login

필요 권한logs:read

쿼리 파라미터

actionstring
행위 접두어
targetIdstring
대상 ID 정확히 일치
fromdatetime
시작 시각 (ISO 8601)
todatetime
종료 시각
beforeinteger
커서 — 이전 응답의 nextCursor
limitinteger
1~200, 기본 50

응답

200로그
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
  }
}
테스트GET /api/v1/audit-logs
쿼리
action
targetId
from
to
before
limit
cURL 로 복사
출시 예정 · M2

임베드 SDK — 내 서비스 화면에 에디터 넣기

외부 플랫폼의 회원이 자기 화면 안에서 문서를 열고 작성·결재할 수 있게 하는 SDK 입니다. iframe 을 직접 다루지 않고, 스크립트를 불러와 웹 컴포넌트(<docuel-document>)를 쓰거나 npm 패키지로 React·Vue 에서 바로 사용합니다.

  • API 키는 서버에만 두고, 브라우저에는 회원·문서·권한이 담긴 15분짜리 세션 토큰만 전달합니다.
  • Shadow DOM 으로 스타일이 격리되어 호스트 페이지 CSS 와 충돌하지 않고, 높이는 내용에 맞게 자동으로 늘어납니다.
  • 변경·저장·제출·결재 이벤트를 DOM 이벤트로 받고, 저장·인쇄·값 주입을 메서드로 호출합니다.
  • CSS 변수로 글꼴·색을 호스트 서비스에 맞출 수 있습니다.
  • 결재 서명처럼 호스트 페이지와 완전히 분리해야 하는 화면은 SDK 가 내부적으로 격리 프레임을 쓰는 보안 모드를 제공합니다 — 사용법은 같습니다.
  • 조직별 허용 도메인(Origin)에서만 동작합니다.
1. 고객사 서버: 회원별 세션 토큰 발급 (API 키 사용)
POST /api/v1/embed/sessions
{
  "documentId": "8f2c41d0-…",
  "permission": "fill",            // view · fill · edit
  "user": {
    "externalId": "E001", "name": "홍길동",
    "department": "플랫폼개발팀", "title": "팀장"
  },
  "ttl": 900
}
→ { "data": { "token": "eyJ…", "expiresAt": "…" } }
2. 브라우저: 스크립트 한 줄 + 웹 컴포넌트
<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>
React / Vue (npm)
npm i @docuel/sdk

import { DocuelDocument } from "@docuel/sdk/react";
<DocuelDocument token={token} mode="fill" onSubmit={save} />
출시 예정 · M2

웹훅

문서·결재·가져오기 이벤트를 고객사 서버로 알려줍니다. 서명 헤더로 위조를 검증하고, 실패하면 지수 백오프로 재시도합니다. 전송 기록은 콘솔에서 확인합니다.

이벤트: 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" }
더 보기

변경 이력

2026-11-03v1.0 — 문서·입력 데이터·반복 행·양식 생성·휴지통·버전·파일·가져오기(이미지·XLSX·DOCX·HTML·LML)·디렉터리·감사 로그·OpenAPI 공개

v1 안에서는 필드 추가처럼 하위 호환되는 변경만 합니다. 호환되지 않는 변경은 /api/v2 로 제공하고 v1 은 최소 12개월 유지합니다.