템플릿으로 서명 요청하기

미리 만들어 둔 템플릿을 기반으로 전자계약을 시작하고, 참여자에게 서명 요청 알림을 자동으로 발송하는 기능입니다. 템플릿에 이미 설정된 문서 양식·참여자 역할·입력란을 그대로 활용하면서, 요청할 때마다 달라지는 정보(참여자 이름·연락처, 추가내용 입력값, 첨부파일 등)만 동적으로 채워 서명 요청을 보낼 수 있습니다.

📘

시작하기 전에 꼭 이해하기

이 API를 쓰려면 두 가지 개념을 먼저 알아 두면 좋습니다.

  • 템플릿(Template) — 반복해서 쓰는 계약서 양식을 모두싸인 웹서비스에 미리 만들어 둔 것입니다. 참여자 역할, 서명·입력 위치, 추가 인증 등이 저장돼 있어 매번 새로 만들 필요가 없습니다.
  • 데이터 라벨(Data Label) — 템플릿 안의 각 입력란·첨부파일 요청을 API에서 지목하기 위한 이름표입니다. API 요청 본문에서 이 라벨로 "어느 칸에 무엇을 넣을지"를 지정합니다. (예전 방식인 customId는 deprecated 되었으니 dataLabel을 사용하세요.)

전체 흐름

템플릿을 웹서비스에서 준비한 뒤, 서명 요청 API 한 번으로 문서 생성부터 참여자 알림 발송까지 처리됩니다. 아래 흐름도에서 파랑은 서버·API가 처리하는 단계, 민트는 사용자 화면·완료 단계를 의미합니다.

  1. 템플릿 준비 — 모두싸인 웹서비스에서 템플릿을 만들고, 참여자 역할과 데이터 라벨을 설정한 뒤 템플릿 ID를 확인합니다.
  2. POST /documents/request-with-template — 템플릿 ID와 동적으로 채울 정보를 담아 서명 요청을 보냅니다.
  3. 문서 생성 & 알림 발송 — 문서가 생성되고 첫 번째 차례의 참여자에게 서명 요청 알림이 발송됩니다. 문서 상태는 ON_GOING이 됩니다.
  4. 서명 완료 — 모든 참여자가 서명을 마치면 문서 상태가 COMPLETED로 바뀝니다. (진행 상황은 Webhook으로 추적할 수 있습니다.)

1. 템플릿 준비하기

서명 요청 API를 호출하기 전에, 웹서비스에서 템플릿을 먼저 준비해야 합니다.

템플릿 생성

반복해서 사용할 계약서 양식을 템플릿으로 만들어 둡니다. 템플릿은 모두싸인 웹서비스에 로그인해 생성할 수 있습니다. 자세한 방법은 템플릿 이용방법 바로가기를 참고하세요.

참여자 역할 설정

템플릿을 만들 때 참여자의 **역할(role)**을 지정합니다. 역할은 참여자의 이름·이메일·전화번호, 추가 인증, 남길 말, 서명 유효 기간 등을 API에서 매핑할 때 기준이 됩니다.

데이터 라벨 설정

API로 템플릿의 추가내용 입력첨부파일 요청을 동적으로 채우려면, 각 입력란에 데이터 라벨을 지정해 두어야 합니다. 데이터 라벨은 템플릿 수정 페이지에서 확인·설정할 수 있습니다.

  • 텍스트 입력란을 클릭하면 오른쪽 상단에서 데이터 라벨을 설정할 수 있습니다.

  • 첨부파일 요청 버튼을 클릭해 첨부파일 요청 항목에도 데이터 라벨을 지정합니다.

🌟

안내사항

API 기능은 이용이 허용된 사용자에게만 제공됩니다. 이용 문의는 모두싸인 고객센터로 연락해 주세요.

템플릿 ID 확인

서명 요청에는 사용할 템플릿의 ID가 필요합니다. 템플릿 ID는 템플릿 리스트 조회 API로 확인하거나, 템플릿 수정 페이지의 주소창에서 확인할 수 있습니다.


2. 서명 요청 API 호출하기

준비한 템플릿 ID와 동적으로 채울 정보를 담아 아래 엔드포인트로 요청합니다.

curl -X POST 'https://api.modusign.co.kr/documents/request-with-template' \
  -H 'Authorization: Basic {인코딩된 API-KEY}' \
  -H 'Content-Type: application/json' \
  -d '{
    "templateId": "{TEMPLATE_ID}",
    "document": {
      "title": "2020_근로계약서_홍길동",
      "participantMappings": [
        {
          "role": "근로자",
          "name": "김모두",
          "signingMethod": { "type": "EMAIL", "value": "[email protected]" }
        }
      ]
    }
  }'

주요 요청 항목

항목설명필수
templateId미리 만들어 둔 템플릿의 ID필수
document.title생성될 문서의 제목 (1~100자)필수
document.participantMappings[]템플릿에 설정된 참여자 역할에 실제 정보를 매핑 (최대 30개)선택
document.requesterInputMappings[]추가내용 입력란에 넣을 값 (데이터 라벨로 지정)선택
document.requesterAttachmentMappings[]요청자 첨부파일 매핑 (최대 30개, 파일 업로드 API 사용)선택
document.carbonCopies[]문서 참조자 연락처 (최대 30개)선택
document.metadatas[]문서 분류용 메타데이터 (최대 10개)선택
brandId문서에 적용할 맞춤 브랜드 ID선택

participantMappings의 주요 하위 항목은 다음과 같습니다.

항목설명
role템플릿에 설정해 둔 참여자 역할 (필수)
name참여자 이름 (2~30자)
signingMethod.type참여 수단: EMAIL, KAKAO, SECURE_LINK
signingMethod.value이메일 주소 또는 휴대전화번호
signingDuration참여 유효 기간(분). 60~525600, 미지정 시 기본 20160분(14일)
verification추가 인증 설정(접근 암호·휴대폰 본인 인증·법인 공동인증서)
attachmentRequests[]첨부파일 요청의 제외(excluded)·필수 여부(required) 조정
excludedtrue이면 해당 참여자를 이번 요청에서 제외

응답 예시

요청이 성공하면 201과 함께 생성된 문서 정보가 반환됩니다. 문서 상태(status)는 서명 진행 중을 뜻하는 ON_GOING입니다.

{
  "id": "DOCUMENT_ID",
  "title": "2020_근로계약서_홍길동",
  "status": "ON_GOING",
  "requester": {
    "email": "[email protected]",
    "name": "요청자"
  },
  "participants": [
    {
      "id": "PARTICIPANT_ID",
      "type": "SIGNER",
      "name": "김모두",
      "signingOrder": 1,
      "signingMethod": { "type": "EMAIL", "value": "[email protected]" },
      "locale": "ko"
    }
  ],
  "currentSigningOrder": 1,
  "createdAt": "2026-07-14"
}
📘

문서 상태(status)는 진행 상황에 따라 DRAFT(작성 중), SCHEDULED(전송 예약), ON_GOING(진행 중), APPROVAL_PENDING(결재 대기), ABORTED(중단), COMPLETED(완료) 등으로 바뀝니다.


3. 요청 시나리오별 예시

자주 쓰는 요청 형태를 document 본문 기준으로 정리했습니다.

참여자만 변경하여 요청하기

템플릿에 설정된 값은 그대로 두고 참여자 정보만 바꿔 요청합니다.

{
  "templateId": "{TEMPLATE_ID}",
  "document": {
    "title": "2020_근로계약서_홍길동",
    "participantMappings": [
      {
        "role": "근로자",
        "name": "김모두",
        "signingMethod": { "type": "EMAIL", "value": "[email protected]" }
      }
    ]
  }
}

특정 참여자를 요청에서 제외하기

템플릿에 설정된 참여자 중 이번 요청에서 뺄 참여자는 excluded: true로 지정합니다.

{
  "templateId": "{TEMPLATE_ID}",
  "document": {
    "title": "2020_근로계약서_홍길동",
    "participantMappings": [
      {
        "role": "근로자",
        "name": "김모두",
        "signingMethod": { "type": "EMAIL", "value": "[email protected]" }
      },
      {
        "role": "근로자2",
        "excluded": true
      }
    ]
  }
}

참여자에게 추가 인증 적용하기

참여자에게 접근 암호와 휴대폰 본인 인증을 적용합니다. 휴대폰 본인 인증 옵션은 allowOptionsSMS_OR_PASS, SIMPLE_AUTH를 지정합니다.

{
  "templateId": "{TEMPLATE_ID}",
  "document": {
    "title": "2020_근로계약서_홍길동",
    "participantMappings": [
      {
        "role": "근로자",
        "name": "김모두",
        "signingMethod": { "type": "EMAIL", "value": "[email protected]" },
        "verification": {
          "password": { "value": "1234" },
          "mobileIdentification": {
            "name": "김모두",
            "phoneNumber": "01012345678",
            "allowOptions": ["SIMPLE_AUTH", "SMS_OR_PASS"]
          }
        }
      }
    ]
  }
}
⚠️

휴대폰 본인 인증(mobileIdentification)과 법인 공동인증서 인증(dCert)은 한 참여자에게 함께 설정할 수 없습니다. 또한 인증 옵션 키는 allowOptions입니다. (allOptions가 아닙니다.)

추가내용 입력을 동적으로 적용하기

템플릿에 설정된 추가내용 입력란에 데이터 라벨로 값을 채웁니다. 텍스트는 문자열, 체크박스는 true/false로 지정합니다.

{
  "templateId": "{TEMPLATE_ID}",
  "document": {
    "title": "2020_근로계약서_홍길동",
    "participantMappings": [
      {
        "role": "근로자",
        "name": "김모두",
        "signingMethod": { "type": "EMAIL", "value": "[email protected]" }
      }
    ],
    "requesterInputMappings": [
      { "dataLabel": "주소", "value": "서울특별시 마포구 123-5번지" },
      { "dataLabel": "동의", "value": true }
    ]
  }
}

첨부파일 요청의 필수·포함 여부 수정하기

템플릿에 설정된 첨부파일 요청의 포함 여부(excluded)와 필수 여부(required)를 데이터 라벨 단위로 조정합니다.

{
  "templateId": "{TEMPLATE_ID}",
  "document": {
    "title": "2020_근로계약서_홍길동",
    "participantMappings": [
      {
        "role": "근로자",
        "name": "김모두",
        "signingMethod": { "type": "EMAIL", "value": "[email protected]" },
        "attachmentRequests": [
          { "dataLabel": "사업자등록증 사본", "excluded": true },
          { "dataLabel": "주민등록증 사본", "required": false },
          { "dataLabel": "통장 사본", "required": true }
        ],
        "locale": "ko"
      }
    ]
  }
}
🚧

요청자 첨부파일은 파일 업로드 API를 사용하세요

요청자 첨부파일(requesterAttachmentMappings)은 파일을 base64로 본문에 담지 않고, 먼저 파일 업로드 API(POST /files)로 업로드한 뒤 응답으로 받은 fileId·token을 참조하는 방식입니다.

  • base64 인라인은 인코딩이 조금만 어긋나도 This file is invalid 오류가 나기 쉽습니다.
  • base64는 원본보다 약 33% 커져 요청 용량 제한·응답 지연 위험이 있습니다.
  • 모두싸인의 파일 관련 기능은 파일 업로드 API 중심으로 개선되고 있어 호환성·안정성 측면에서도 권장됩니다.
{
  "requesterAttachmentMappings": [
    {
      "dataLabel": "첨부파일_1",
      "file": {
        "fileId": "2752f600-c6fc-11ed-b2e3-b5476bd20f82",
        "token": "01GVZ3BGGT2D9BSEVXJJ2V00SP",
        "name": "첨부파일_1"
      }
    }
  ]
}

파일 업로드로 받은 fileId·token의 유효기간은 2시간입니다.


4. API 호출 시 주의사항

  • 템플릿 준비가 선행되어야 합니다. 템플릿 생성, 참여자 역할, 데이터 라벨 설정, 템플릿 ID 확인이 모두 끝나야 요청할 수 있습니다.
  • API KEY는 서버사이드 전용입니다. 브라우저 등 클라이언트에 노출하지 마세요.
  • 참여 수단(signingMethod.type)은 EMAIL, KAKAO, SECURE_LINK 지원합니다.
  • 추가 인증 조합 제한 — 휴대폰 본인 인증과 법인 공동인증서 인증은 한 참여자에게 함께 설정할 수 없습니다.
  • 요청자 첨부파일은 파일 업로드 API 사용을 권장합니다. (base64 인라인 대신 fileId·token 참조)
  • 개수 제한participantMappings·requesterAttachmentMappings·carbonCopies는 최대 30개, metadatas는 최대 10개, labelIds는 최대 5개입니다.
  • Rate Limit — Standard는 분당 300·초당 10, High-cost는 분당 150·초당 5입니다. 파일 업로드(POST /files)는 High-cost이며, 초과 시 429X-Retry-After(초)가 반환되므로 지수 백오프를 권장합니다.

자주 발생하는 오류

응답에러 메시지원인해결 방법
401UnauthorizedAPI KEY 또는 인증 헤더 오류API KEY와 Authorization 헤더(Basic 인코딩) 확인
403Usage limit exceededAPI 사용량 소진사용량 한도 확인 또는 플랜 업그레이드
404Not found존재하지 않는 템플릿 ID 또는 잘못된 URLtemplateId와 요청 URL 확인
422This file is invalid첨부파일 무효 / base64 인코딩 오류파일 업로드 API로 업로드 후 fileId·token 사용
429Too Many RequestsRate Limit 초과X-Retry-After(초)만큼 대기 후 재시도, 지수 백오프 권장

5. 자주 묻는 질문

FAQ

템플릿에 설정한 값을 API에서 바꿀 수 있나요?

네. 참여자 이름·연락처·참여 수단, 추가 인증, 추가내용 입력값, 첨부파일 요청의 포함·필수 여부 등을 요청 본문에서 동적으로 덮어쓸 수 있습니다. 바꾸지 않은 항목은 템플릿에 저장된 값이 그대로 적용됩니다.

데이터 라벨과 customId는 무엇이 다른가요?

둘 다 템플릿의 입력란·첨부파일 요청을 지목하는 식별자이지만, customId는 deprecated 되었습니다. 신규 연동에서는 dataLabel을 사용하세요.

특정 참여자만 빼고 요청하려면 어떻게 하나요?

해당 참여자의 매핑에 excluded: true를 지정하면 이번 요청에서 제외됩니다.

allOptions로 인증 옵션을 넣었는데 적용되지 않습니다.

휴대폰 본인 인증 옵션의 정확한 키는 allowOptions입니다. allOptions는 잘못된 키이므로 인증 옵션이 적용되지 않습니다.

응답 예시:

{
  "statusCode": 422,
  "message": "Validation failed"
}
  • 키 이름을 allowOptions로 수정하고, 값은 SMS_OR_PASS 또는 SIMPLE_AUTH를 사용하세요.
첨부파일을 base64로 보냈더니 This file is invalid 오류가 납니다.

요청자 첨부파일은 파일 업로드 API로 먼저 업로드한 뒤 fileId·token을 참조해야 합니다.

응답 예시:

{
  "statusCode": 422,
  "message": "This file is invalid"
}
  • 파일 업로드 API(POST /files)로 파일을 올리고, 응답의 fileId·tokenrequesterAttachmentMappings[].file에 넣으세요.
  • fileId·token의 유효기간은 2시간입니다.
429 Too Many Requests 오류가 발생합니다.

요청 횟수 제한(Rate Limit)을 초과했을 때 발생합니다.

응답 예시:

{
  "statusCode": 429,
  "message": "Too Many Requests"
}
  • 응답의 X-Retry-After 헤더(초)만큼 기다린 후 재시도하세요.
  • 연속 호출 시 요청 사이에 간격을 두거나 지수 백오프를 적용하세요.
👍

더 자세한 API 내용은 API References에서 확인하세요!

템플릿으로 서명 요청 API의 요청·응답 스키마를 확인하세요.


🚧

유의사항

  • 서명 요청 전 템플릿 준비(생성·역할·데이터 라벨·ID 확인)를 반드시 완료하세요.
  • 요청자 첨부파일은 base64 대신 파일 업로드 API로 처리하는 것을 권장합니다.
  • 문서 진행 상황(서명 완료·중단 등)은 Webhook으로 실시간 추적할 수 있습니다.


Did this page help you?