모두싸인 API QuickStart
모두싸인 API QuickStart
모두싸인 API를 사용하여 전자서명 요청을 보내는 방법을 단계별로 안내합니다. 이 가이드를 따라하면 인증 → 템플릿 조회 → 템플릿으로 서명 요청 → 문서 상태 확인까지의 전체 플로우를 직접 경험할 수 있습니다.
이 가이드를 완료하는 데 약 10분이 소요됩니다. 시작하기 전에 모두싸인 서비스에서 API Key를 발급받으세요.
사전 준비
시작하기 전에 아래 항목을 준비해 주세요.
| 항목 | 설명 |
|---|---|
| 모두싸인 계정 | 모두싸인에 가입된 계정이 필요합니다. |
| API 이용 승인 | API 메뉴는 이용이 승인된 사용자에게만 표시됩니다. 고객센터에 문의하여 API 사용을 신청하세요. |
| API Key | API KEY 발급 페이지에서 발급받은 키입니다. |
| 템플릿 | 모두싸인에서 미리 생성해둔 서명 요청 템플릿이 필요합니다. |
모두싸인 API의 Base URL은
https://api.modusign.co.kr입니다. 모든 요청에 이 URL을 사용합니다.
전체 플로우 개요
API Key 설정
템플릿 확인
서명 요청
상태 조회
Step 1. 인증 설정
모두싸인 API는 HTTP Basic 인증(RFC 7617)을 사용합니다. 모두싸인에서 발급받은 API Key와 사용자 이메일을 조합하여 인증 헤더를 생성합니다.
1-1. Authorization 헤더 생성
인증 헤더는 아래 3단계로 생성합니다.
| 단계 | 설명 | 예시 |
|---|---|---|
| 1. 결합 | 사용자 이메일과 API Key를 콜론(:)으로 연결 | [email protected]:your-api-key |
| 2. Base64 인코딩 | 결합된 문자열을 Base64로 인코딩 | cmVxdWVzdGVyQGV4YW1wbGUuY29tOnlvdXItYXBpLWtleQ== |
| 3. 헤더 추가 | Authorization 헤더에 Basic 접두사와 함께 전달 | Authorization: Basic dXNlckBjb21... |
인증 테스트
API Key가 정상적으로 작동하는지 간단한 문서 목록 조회로 확인해 보세요.
# 이메일과 API Key를 Base64로 인코딩하여 요청
curl -X GET "https://api.modusign.co.kr/documents?offset=0&limit=10" \
-H "Accept: application/json" \
-H "Authorization: Basic $(echo -n '[email protected]:your-api-key' | base64)"// 이메일과 API Key를 Base64로 인코딩
const email = '[email protected]';
const apiKey = 'your-api-key';
const credentials = btoa(`${email}:${apiKey}`);
const response = await fetch(
'https://api.modusign.co.kr/documents?offset=0&limit=10',
{
headers: {
'Accept': 'application/json',
'Authorization': `Basic ${credentials}`
}
}
);
const data = await response.json();
console.log('인증 성공! 문서 수:', data.totalCount);import requests
import base64
# 이메일과 API Key를 Base64로 인코딩
email = '[email protected]'
api_key = 'your-api-key'
credentials = base64.b64encode(f'{email}:{api_key}'.encode()).decode()
response = requests.get(
'https://api.modusign.co.kr/documents',
params={'offset': 0, 'limit': 10},
headers={
'Accept': 'application/json',
'Authorization': f'Basic {credentials}'
}
)
data = response.json()
print(f"인증 성공! 문서 수: {data['totalCount']}")API Key 보안 권장 사항
API Key 관리 및 보안 권장 사항은 API KEY 발급 페이지를 참고하세요.
OAuth 2.0 인증이 필요한 경우 (예: 서버 간 연동, 사용자 대리 인증 등), 별도의 OAuth 앱 등록 및 토큰 발급 절차가 필요합니다. 자세한 내용은 OAuth 인증 가이드를 참고하세요.
Step 2. 템플릿 준비 및 확인
서명 요청에 앞서 템플릿을 준비하고, 서명 요청에 필요한 템플릿 ID, 참여자 역할(role), 데이터 라벨(dataLabel) 을 확인합니다.
2-1. 템플릿 생성
모두싸인 웹서비스에 로그인한 뒤 템플릿 메뉴에서 문서를 업로드하고, 서명란·입력란·참여자 역할 등을 설정하여 템플릿을 생성합니다.
템플릿 생성 시 아래 항목을 설정해 두면 API 연동이 훨씬 수월합니다.
| 설정 항목 | 설명 | API에서의 활용 |
|---|---|---|
| 참여자 역할 | 각 참여자에게 부여하는 이름 (예: "근로자", "대표이사") | participantMappings[].role로 매핑 |
| 데이터 라벨 | 추가내용 입력란에 부여하는 식별 이름 (예: "주소", "계약시작일") | requesterInputMappings[].dataLabel로 매핑 |
| 첨부파일 라벨 | 참여자에게 요청하는 첨부파일의 식별 이름 (예: "신분증 사본") | attachmentRequests[].dataLabel로 매핑 |
데이터 라벨 설정 방법: 템플릿 수정 페이지에서 텍스트 입력란을 클릭하면 우측 상단에 데이터 라벨을 설정할 수 있습니다. 이 라벨은 API에서 값을 동적으로 주입할 때 식별자로 사용됩니다.
2-2. 템플릿 ID 확인
템플릿 ID는 두 가지 방법으로 확인할 수 있습니다.
모두싸인에서 해당 템플릿의 수정 페이지로 이동하면, 브라우저 주소창에서 템플릿 ID를 직접 확인할 수 있습니다.


위 이미지와 같이 주소창의 /template/ 뒤에 오는 UUID 형식의 값이 템플릿 ID 입니다.
https://app.modusign.co.kr/template/{TEMPLATE_ID}/...
↑ 이 부분이 템플릿 ID예시: https://app.modusign.co.kr/template/{TEMPLATE_ID}/step/1st
→ 템플릿 ID: {TEMPLATE_ID}
GET /templates API를 호출하여 템플릿 목록과 ID를 프로그래밍 방식으로 조회할 수 있습니다.
curl -X GET "https://api.modusign.co.kr/templates?offset=0&limit=10" \
-H "Accept: application/json" \
-H "Authorization: Basic YOUR_BASE64_CREDENTIALS"{
"count": 3,
"templates": [
{
"id": "{TEMPLATE_ID}",
"title": "2025_근로계약서",
"participants": [
{
"type": "SIGNER",
"role": "근로자",
"signingOrder": 1
}
],
"createdAt": "2025-12-01T09:00:00.000Z"
}
]
}2-3. 참여자 역할 및 데이터 라벨 확인 (선택)
서명 요청 시 정확한 role과 dataLabel 값이 필요합니다. 템플릿 수정 페이지 UI에서 직접 확인하거나, API로 상세 조회할 수 있습니다.
GET /templates/{templateId}
curl -X GET "https://api.modusign.co.kr/templates/{TEMPLATE_ID}" \
-H "Accept: application/json" \
-H "Authorization: Basic YOUR_BASE64_CREDENTIALS"// credentials는 Step 1에서 생성한 Base64 인코딩 값
const response = await fetch(
'https://api.modusign.co.kr/templates/{TEMPLATE_ID}',
{
headers: {
'Accept': 'application/json',
'Authorization': `Basic ${credentials}`
}
}
);
const template = await response.json();
console.log(`템플릿: ${template.title}`);
console.log('참여자 역할:', template.participants.map(p => p.role));
console.log('추가내용 입력:', template.requesterInputs.map(r => r.dataLabel));import requests
# credentials는 Step 1에서 생성한 Base64 인코딩 값
response = requests.get(
'https://api.modusign.co.kr/templates/{TEMPLATE_ID}',
headers={
'Accept': 'application/json',
'Authorization': f'Basic {credentials}'
}
)
template = response.json()
print(f"템플릿: {template['title']}")
print('참여자 역할:', [p['role'] for p in template['participants']])
print('추가내용 입력:', [r['dataLabel'] for r in template['requesterInputs']])
participants[].role값은 Step 3에서participantMappings[].role에 정확히 일치하도록 입력해야 합니다. 오타나 공백 차이가 있으면 매핑에 실패하므로, API 응답 값을 그대로 복사하여 사용하세요.
Step 3. 템플릿으로 서명 요청
미리 만들어 둔 템플릿을 기반으로 서명 요청을 보냅니다. 템플릿에 설정된 문서, 서명란, 입력란이 자동으로 적용되며, 참여자 이름과 연락처만 지정하면 됩니다.
요청
POST /documents/request-with-template
주요 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
templateId | string | Yes | 사용할 템플릿 ID |
document | object | Yes | 문서 설정 정보 (제목, 참여자 매핑 등) |
document.title | string | Yes | 문서 제목 (최대 100자) |
document.participantMappings | array | No | 참여자 매핑 정보 (이름, 연락처 등을 동적으로 지정) |
participantMappings 상세 파라미터
participantMappings는 템플릿에 설정된 참여자의 정보를 동적으로 덮어쓰는 역할을 합니다. 템플릿의 role 값으로 매핑합니다.
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
role | string | Yes | 템플릿에 설정된 참여자 역할 (예: "근로자") |
name | string | No | 참여자 이름 (2~30자) |
signingMethod.type | string | No | 참여 수단: EMAIL, KAKAO, SECURE_LINK |
signingMethod.value | string | No | 이메일 주소 또는 휴대전화번호 |
signingDuration | integer | No | 참여 유효 기간 (분, 기본값: 20160 = 14일) |
locale | string | No | 참여자 언어 (기본값: ko) |
excluded | boolean | No | 해당 참여자를 제외할지 여부 (기본값: false) |
requesterMessage | string | No | 참여자에게 전달할 메시지 (최대 1000자) |
requesterInputMappings (추가내용 입력)
템플릿에 설정된 요청자 입력란(텍스트, 체크박스, 이미지)에 값을 채웁니다. dataLabel로 매핑합니다.
{
"requesterInputMappings": [
{
"dataLabel": "계약시작일",
"value": "2026-04-01"
},
{
"dataLabel": "특이사항",
"value": "수습기간 3개월"
}
]
}| 입력 타입 | value 형식 | 설명 |
|---|---|---|
| TEXT | string | 텍스트 필드에 입력될 문자열 |
| CHECKBOX | boolean | 체크 여부 (true / false) |
| IMAGE | { "base64": "..." } | 3MB 이하 jpg/png 이미지의 Base64 인코딩 |
최소 요청 예시
아래는 근로자 역할의 참여자에게 이메일로 서명 요청을 보내는 가장 간단한 예시입니다.
curl -X POST https://api.modusign.co.kr/documents/request-with-template \
-H "Authorization: Basic YOUR_BASE64_CREDENTIALS" \
-H "Content-Type: application/json" \
-d '{
"templateId": "{TEMPLATE_ID}",
"document": {
"title": "2026_근로계약서_김모두",
"participantMappings": [
{
"role": "근로자",
"name": "김모두",
"signingMethod": {
"type": "EMAIL",
"value": "[email protected]"
}
}
]
}
}'// credentials는 Step 1에서 생성한 Base64 인코딩 값
const response = await fetch(
'https://api.modusign.co.kr/documents/request-with-template',
{
method: 'POST',
headers: {
'Authorization': `Basic ${credentials}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
templateId: '{TEMPLATE_ID}',
document: {
title: '2026_근로계약서_김모두',
participantMappings: [
{
role: '근로자',
name: '김모두',
signingMethod: {
type: 'EMAIL',
value: '[email protected]'
}
}
]
}
})
}
);
const doc = await response.json();
console.log(`Document ID: ${doc.id}, Status: ${doc.status}`);import requests
# credentials는 Step 1에서 생성한 Base64 인코딩 값
response = requests.post(
'https://api.modusign.co.kr/documents/request-with-template',
headers={
'Authorization': f'Basic {credentials}',
'Content-Type': 'application/json'
},
json={
'templateId': '{TEMPLATE_ID}',
'document': {
'title': '2026_근로계약서_김모두',
'participantMappings': [
{
'role': '근로자',
'name': '김모두',
'signingMethod': {
'type': 'EMAIL',
'value': '[email protected]'
}
}
]
}
}
)
doc = response.json()
print(f"Document ID: {doc['id']}, Status: {doc['status']}")
participantMappings의role은 템플릿에 설정된 역할명과 정확히 일치해야 합니다. Step 2에서 조회한participants[].role값을 그대로 사용하세요.
활용 예시
특정 참여자를 제외하고 서명 요청
템플릿에 여러 참여자가 설정되어 있지만, 특정 역할의 참여자를 제외하고 서명 요청을 보내려면 excluded: true를 설정합니다.
const body = {
templateId: '{TEMPLATE_ID}',
document: {
title: '2026_근로계약서_김모두',
participantMappings: [
{
role: '근로자',
name: '김모두',
signingMethod: { type: 'EMAIL', value: '[email protected]' }
},
{
role: '근로자2',
excluded: true
}
]
}
};추가 인증(비밀번호, 휴대폰 본인 인증) 적용
참여자에게 추가 인증을 요구하려면 verification 옵션을 설정합니다. 비밀번호 인증과 휴대폰 본인 인증을 함께 적용할 수 있습니다.
const body = {
templateId: '{TEMPLATE_ID}',
document: {
title: '2026_근로계약서_김모두',
participantMappings: [
{
role: '근로자',
name: '김모두',
signingMethod: { type: 'EMAIL', value: '[email protected]' },
verification: {
password: { value: '1234' },
mobileIdentification: {
name: '김모두',
phoneNumber: '01000000000',
allowOptions: ['SIMPLE_AUTH', 'SMS_OR_PASS']
}
}
}
]
}
};휴대폰 본인 인증과 법인 공동인증서 인증은 동시에 설정할 수 없습니다. 둘 중 하나만 선택하세요.
추가내용 입력 동적 적용 (requesterInputMappings)
템플릿에 설정된 데이터 라벨을 기반으로 텍스트, 체크박스 등의 값을 동적으로 채울 수 있습니다.
const body = {
templateId: '{TEMPLATE_ID}',
document: {
title: '2026_근로계약서_김모두',
participantMappings: [
{
role: '근로자',
name: '김모두',
signingMethod: { type: 'EMAIL', value: '[email protected]' }
}
],
requesterInputMappings: [
{ dataLabel: '주소', value: '서울특별시 마포구 123-5번지' },
{ dataLabel: '동의', value: true }
]
}
};첨부파일 요청 수정 (제외/필수 여부 변경)
템플릿에 설정된 첨부파일 요청을 제외하거나, 필수 여부를 변경할 수 있습니다.
const body = {
templateId: '{TEMPLATE_ID}',
document: {
title: '2026_근로계약서_김모두',
participantMappings: [
{
role: '근로자',
name: '김모두',
signingMethod: { type: 'EMAIL', value: '[email protected]' },
attachmentRequests: [
{ dataLabel: '사업자등록증 사본', excluded: true },
{ dataLabel: '주민등록증 사본', required: false },
{ dataLabel: '통장 사본', required: true }
]
}
]
}
};응답 예시
서명 요청이 성공하면 문서 정보가 반환됩니다. 이때 초기 상태는 ON_PROCESSING (문서 처리 중)입니다.
{
"id": "{DOCUMENT_ID}",
"title": "2026_근로계약서_김모두",
"status": "ON_PROCESSING",
"requester": {
"email": "[email protected]",
"name": "홍길동"
},
"participants": [
{
"id": "{PARTICIPANT_ID}",
"type": "SIGNER",
"name": "김모두",
"signingOrder": 1,
"signingDue": {
"valid": false,
"datetime": null
},
"signingMethod": {
"type": "EMAIL",
"value": "[email protected]"
},
"locale": "ko"
}
],
"currentSigningOrder": 0,
"signings": [],
"accessibleByParticipant": true,
"abort": null,
"file": {
"downloadUrl": "https://api.modusign.co.kr/documents/{DOCUMENT_ID}/file?signedUrlToken=..."
},
"auditTrail": null,
"metadatas": [],
"seal": {
"integritySeal": {
"enabled": false,
"position": null
}
},
"updatedAt": "2026-03-17T05:46:54.000Z",
"createdAt": "2026-03-17T05:46:53.000Z",
"brandId": "{BRAND_ID}"
}주요 응답 필드
| 필드 | 설명 |
|---|---|
id | 생성된 문서의 고유 ID (이후 상태 조회에 사용) |
title | 문서 제목 |
status | 현재 문서 상태 |
requester | 서명 요청자 정보 (이메일, 이름) |
participants | 참여자 목록 (ID, 타입, 참여 수단 등) |
currentSigningOrder | 현재 서명 차례 (0이면 아직 참여자에게 전달 전) |
signings | 서명 완료된 참여자 목록 (초기에는 빈 배열) |
file.downloadUrl | 문서 PDF 다운로드 링크 (유효시간 10분) |
문서 상태 전환 흐름
서명 요청 직후 문서는
ON_PROCESSING상태로 생성됩니다. 모두싸인 서버에서 문서 처리가 완료되면 자동으로ON_GOING상태로 전환되며, 이때부터 참여자에게 서명 요청이 발송됩니다.
POST 요청 직후 문서 처리 완료 참여자 서명 완료
│ │ │
▼ ▼ ▼
ON_PROCESSING ──────▶ ON_GOING ──────────▶ COMPLETED
(문서 처리 중) (서명 진행 중) (서명 완료)
| 전환 단계 | 상태 | 설명 |
|---|---|---|
| 응답 직후 | ON_PROCESSING | 문서가 생성되고 서버에서 처리 중입니다. currentSigningOrder가 0이고, signingDue.valid가 false입니다. |
| 처리 완료 | ON_GOING | 문서 처리가 완료되어 참여자에게 서명 요청이 발송됩니다. currentSigningOrder가 1 이상으로 변경됩니다. |
| 모든 서명 완료 | COMPLETED | 모든 참여자의 서명/열람이 완료된 상태입니다. file.downloadUrl에서 최종 서명 문서를 다운로드할 수 있습니다. |
ON_PROCESSING→ON_GOING전환은 보통 수 초 내에 완료됩니다. 실시간으로 상태 변경을 감지하려면 **웹훅(Webhook)**을 설정하거나, Step 4의 상태 조회 API를 폴링하세요.
Step 4. 문서 상태 확인
서명 요청 후 문서의 진행 상태를 조회합니다. Step 3에서 받은 id 값을 사용합니다.
요청
GET /documents/{documentId}
| 파라미터 | 위치 | 타입 | 필수 | 설명 |
|---|---|---|---|---|
documentId | path | string | Yes | 문서 ID |
curl -X GET https://api.modusign.co.kr/documents/{DOCUMENT_ID} \
-H "Authorization: Basic YOUR_BASE64_CREDENTIALS"const response = await fetch(
'https://api.modusign.co.kr/documents/{DOCUMENT_ID}',
{
headers: {
'Authorization': `Basic ${credentials}`
}
}
);
const document = await response.json();
console.log(`Status: ${document.status}`);
// 서명 완료 여부 확인
if (document.status === 'COMPLETED') {
console.log('모든 서명이 완료되었습니다!');
console.log(`PDF 다운로드: ${document.file.downloadUrl}`);
}import requests
response = requests.get(
'https://api.modusign.co.kr/documents/{DOCUMENT_ID}',
headers={'Authorization': f'Basic {credentials}'}
)
doc = response.json()
print(f"Status: {doc['status']}")
# 서명 완료 여부 확인
if doc['status'] == 'COMPLETED':
print('모든 서명이 완료되었습니다!')
print(f"PDF 다운로드: {doc['file']['downloadUrl']}")문서 상태 값
| 상태 | 설명 |
|---|---|
DRAFT | 작성 중 |
SCHEDULED | 전송 예약 중 |
ON_GOING | 서명/열람 진행 중 |
ON_PROCESSING | 문서 처리 중 |
COMPLETED | 모든 서명/열람 완료 |
ABORTED | 서명/열람 중단됨 |
PROCESSING_FAILED | 문서 처리 실패 |
문서 상태 변경을 실시간으로 수신하려면 **웹훅(Webhook)**을 설정하는 것을 권장합니다.
POST /webhooks엔드포인트를 통해 웹훅을 등록할 수 있습니다.
다음 단계
QuickStart를 완료했습니다! 이제 아래 심화 기능들을 살펴보세요.
자주 묻는 질문 (FAQ)
Q. 템플릿은 어디에서 만들 수 있나요?
모두싸인 서비스의 템플릿 메뉴에서 직접 문서를 업로드하고 서명란, 입력란 등을 설정하여 생성합니다. API로는 POST /templates 엔드포인트를 통해서도 생성할 수 있습니다.
Q. participantMappings의 role이 정확히 무엇인가요?
템플릿 생성 시 각 참여자에게 부여한 역할 이름입니다 (예: "근로자", "대표이사", "갑"). API 요청 시 이 값이 정확히 일치해야 해당 참여자에게 매핑됩니다. GET /templates/{templateId} 응답의 participants[].role에서 확인할 수 있습니다.
Q. 한 템플릿에 여러 서명자가 있을 때 어떻게 하나요?participantMappings 배열에 각 역할별로 매핑 정보를 추가하면 됩니다. 템플릿에 설정된 서명 순서(signingOrder)가 자동으로 적용됩니다.
Q. 이메일 외에 다른 서명 방식을 사용할 수 있나요?signingMethod.type을 KAKAO(카카오 알림톡) 또는 SECURE_LINK(보안 링크)로 설정할 수 있습니다.
Q. API Key가 만료되면 어떻게 하나요?
API Key 재발급, 폐기 및 만료 설정 방법은 API KEY 발급 페이지를 참고하세요.
Updated 19 days ago
