메타데이터로 문서와 템플릿 분류하기
메타데이터(metadata)는 문서나 템플릿에 붙이는 검색용 이름표입니다. 문서 종류, 담당 팀, 가맹점 코드처럼 나중에 다시 찾을 기준을 key와 value의 쌍으로 저장할 수 있습니다.
예를 들어 인사팀의 근로계약서에는 teamCode=HR, documentType=EMPLOYMENT_CONTRACT를 붙일 수 있습니다. 이후 이 두 조건으로 목록을 조회하면 해당 조건을 모두 만족하는 문서만 찾을 수 있습니다.
시작하기 전에 꼭 이해하기
key는 어떤 기준으로 나눌지를 나타냅니다. 예:teamCode,storeCode,documentTypevalue는 그 문서가 어느 분류에 속하는지를 나타냅니다. 예:HR,SEOUL_001,EMPLOYMENT_CONTRACT메타데이터는 문서를 분류하고 검색하는 기능입니다. 사용자 접근 권한을 제어하는 기능은 아닙니다.
전체 흐름
사내 시스템이 사용자의 소속을 확인하고, 서버에서 알맞은 메타데이터를 추가한 뒤 모두싸인 API를 호출합니다. 목록을 조회할 때도 같은 분류 조건을 적용합니다.
- 사용자가 사내 시스템에 로그인합니다.
- 서버가 사용자의 소속 팀이나 가맹점을 확인하고 메타데이터를 결정합니다.
- 서버가 모두싸인 API로 문서·템플릿을 생성하거나, 메타데이터 조건으로 목록을 조회합니다.
논리적 분류와 접근 권한은 다릅니다메타데이터 필터를 적용하면 업무 화면에서 팀별·가맹점별 목록을 나누어 보여줄 수 있습니다. 하지만 메타데이터 자체가 다른 문서에 대한 접근을 차단하지는 않습니다.
API Key는 중앙 서버에만 보관하고, 사내 시스템이 로그인 사용자의 권한을 별도로 확인해야 합니다. 사용자가 API Key를 직접 사용하거나 조회 조건을 임의로 바꿀 수 있게 해서는 안 됩니다.
1. 분류 기준 설계하기
API를 호출하기 전에 어떤 기준으로 문서와 템플릿을 찾을지 먼저 정합니다. 처음부터 모든 정보를 넣기보다, 실제 업무에서 반복해서 검색할 기준을 고르는 것이 좋습니다.
좋은 분류 기준의 조건
| 원칙 | 설명 | 예시 |
|---|---|---|
| 의미가 분명한 이름 사용 | key만 보고도 무엇을 뜻하는지 알 수 있게 합니다. | teamCode, storeCode |
| 안정적인 코드 사용 | 팀명이나 매장명이 바뀌어도 유지할 수 있는 내부 코드를 사용합니다. | HR, SEOUL_001 |
| 표기 방식 통일 | 같은 값을 여러 표기로 섞지 않습니다. | HR로 통일하고 hr, 인사팀 혼용 금지 |
| 한 키에는 한 가지 의미만 저장 | 여러 정보를 한 문자열에 합치지 않습니다. | teamCode=HR, contractYear=2026 |
| 자주 조회하는 기준부터 선택 | 한 문서나 템플릿에는 메타데이터를 최대 10개까지 등록할 수 있습니다. | 조직, 문서 종류, 연도 등 |
권장 예시와 피해야 할 예시
| 목적 | 권장 예시 | 피해야 할 예시 |
|---|---|---|
| 담당 팀 | teamCode=HR | team=인사팀, team=HR, team=hr 혼용 |
| 가맹점 | storeCode=SEOUL_001 | store=서울점처럼 변경·중복될 수 있는 이름만 사용 |
| 문서 종류 | documentType=EMPLOYMENT_CONTRACT | type=계약처럼 범위가 모호한 값 |
| 계약 연도 | contractYear=2026 | year=26, year=2026년 혼용 |
2. 사례 1: 하나의 API Key로 사내 여러 팀 분류하기
한 회사의 인사팀, 영업팀, 법무팀이 하나의 사내 계약 시스템과 하나의 API Key를 사용한다고 가정해 보겠습니다.
API Key는 같지만 문서와 템플릿에 teamCode를 붙이면 목록을 팀별로 논리적으로 나눌 수 있습니다.
이 예시는 하나의 연동 계정이 대상 문서·템플릿을 생성하고 관리하며, 해당 API Key가 그 리소스에 접근할 수 있는 구조를 전제로 합니다. 중앙 연동 서버는 이 범위 안에서 업무 데이터를 추가로 분류합니다.
| 팀 | teamCode | documentType 예시 |
|---|---|---|
| 인사팀 | HR | EMPLOYMENT_CONTRACT |
| 영업팀 | SALES | SALES_CONTRACT |
| 법무팀 | LEGAL | NDA |
인사팀 근로계약서에 넣을 메타데이터는 다음과 같습니다.
{
"metadatas": [
{
"key": "teamCode",
"value": "HR"
},
{
"key": "documentType",
"value": "EMPLOYMENT_CONTRACT"
},
{
"key": "contractYear",
"value": "2026"
}
]
}서버에서 팀 코드를 결정하세요
안전한 흐름은 다음과 같습니다.
- 사용자가 사내 시스템에 로그인합니다.
- 사내 시스템이 사용자의 소속 팀을 확인합니다.
- 서버가 소속 팀에 맞는
teamCode를 결정합니다. - 서버가 문서나 템플릿을 만들 때
teamCode를 자동으로 추가합니다. - 목록을 조회할 때도 서버가 사용자의
teamCode를 자동으로 필터에 넣습니다.
인사팀 문서만 조회하기
metadatas에는 JSON 문자열을 전달합니다. curl의 --data-urlencode를 사용하면 JSON 문자열을 직접 URL 인코딩하지 않아도 됩니다.
아래 예시의 {YOUR_BASE64_CREDENTIALS}에는 사용자 이메일:API_KEY를 Base64로 인코딩한 값을 사용합니다.
curl --get 'https://api.modusign.co.kr/documents' \
-H 'Accept: application/json' \
-H 'Authorization: Basic {YOUR_BASE64_CREDENTIALS}' \
--data-urlencode 'offset=0' \
--data-urlencode 'limit=10' \
--data-urlencode 'metadatas={"teamCode":"HR"}'인사팀의 근로계약서만 조회하려면 조건을 하나 더 추가합니다.
curl --get 'https://api.modusign.co.kr/documents' \
-H 'Accept: application/json' \
-H 'Authorization: Basic {YOUR_BASE64_CREDENTIALS}' \
--data-urlencode 'offset=0' \
--data-urlencode 'limit=10' \
--data-urlencode 'metadatas={"teamCode":"HR","documentType":"EMPLOYMENT_CONTRACT"}'두 개 이상의 메타데이터를 조회 조건으로 전달하면 모든 조건을 만족하는 문서만 조회됩니다. 위 요청에서는 teamCode=HR이면서 documentType=EMPLOYMENT_CONTRACT인 문서를 찾습니다.
팀별 템플릿 조회하기
템플릿도 같은 방식으로 분류할 수 있습니다.
curl --get 'https://api.modusign.co.kr/templates' \
-H 'Accept: application/json' \
-H 'Authorization: Basic {YOUR_BASE64_CREDENTIALS}' \
--data-urlencode 'offset=0' \
--data-urlencode 'limit=10' \
--data-urlencode 'metadatas={"teamCode":"HR"}'3. 사례 2: 프랜차이즈 가맹점별로 분류하기
프랜차이즈 본사가 하나의 연동 서버와 API Key로 여러 가맹점의 계약을 관리한다고 가정해 보겠습니다.
가맹점 이름은 변경되거나 비슷한 이름이 생길 수 있으므로, 내부 시스템에서 사용하는 안정적인 가맹점 코드를 storeCode로 저장하는 방식이 좋습니다.
이 예시도 하나의 연동 계정이 대상 문서·템플릿을 생성하고 관리하며, 해당 API Key가 그 리소스에 접근할 수 있는 구조를 전제로 합니다. 본사 서버는 이 범위 안에서 가맹점별 분류를 적용합니다.
| 분류 기준 | 권장 key | value 예시 |
|---|---|---|
| 브랜드 | brandCode | BRAND_A |
| 가맹점 | storeCode | SEOUL_001 |
| 권역 | regionCode | SEOUL_EAST |
| 문서 종류 | documentType | FRANCHISE_AGREEMENT |
| 계약 연도 | contractYear | 2026 |
서울 1호점의 가맹계약서에는 다음과 같이 메타데이터를 설정할 수 있습니다.
{
"metadatas": [
{
"key": "brandCode",
"value": "BRAND_A"
},
{
"key": "storeCode",
"value": "SEOUL_001"
},
{
"key": "regionCode",
"value": "SEOUL_EAST"
},
{
"key": "documentType",
"value": "FRANCHISE_AGREEMENT"
}
]
}가맹점 사용자의 목록 조회
가맹점 사용자가 로그인하면 사내 시스템은 사용자의 가맹점 코드를 확인하고 storeCode 조건을 자동으로 적용합니다.
curl --get 'https://api.modusign.co.kr/documents' \
-H 'Accept: application/json' \
-H 'Authorization: Basic {YOUR_BASE64_CREDENTIALS}' \
--data-urlencode 'offset=0' \
--data-urlencode 'limit=10' \
--data-urlencode 'metadatas={"storeCode":"SEOUL_001"}'서울 1호점의 가맹계약서만 조회하려면 다음 조건을 사용합니다.
{
"storeCode": "SEOUL_001",
"documentType": "FRANCHISE_AGREEMENT"
}권역 관리자는 regionCode, 본사 관리자는 내부 권한 정책에 따라 여러 가맹점이나 브랜드 범위를 조회하도록 설계할 수 있습니다. 이 범위 결정은 메타데이터가 아니라 연동 시스템의 권한 관리 기능이 담당해야 합니다.
4. 문서를 생성하면서 메타데이터 설정하기
서명 요청 API, 템플릿으로 서명 요청 API, 임베디드 초안 생성 API, 템플릿으로 임베디드 초안 생성 API에서 metadatas를 전달할 수 있습니다.
다음은 템플릿으로 인사팀 근로계약서를 요청하는 예시입니다.
curl -X POST 'https://api.modusign.co.kr/documents/request-with-template' \
-H 'Accept: application/json' \
-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]"
}
}
],
"metadatas": [
{
"key": "teamCode",
"value": "HR"
},
{
"key": "documentType",
"value": "EMPLOYMENT_CONTRACT"
},
{
"key": "contractYear",
"value": "2026"
}
]
}
}'
안내사항템플릿 메타데이터는 해당 템플릿으로 발송하는 문서에 자동으로 적용되지 않습니다. 문서 분류에 필요한 메타데이터는 서명 요청의
document.metadatas에 명시적으로 전달하도록 구현하십시오.
5. 기존 문서와 템플릿의 메타데이터 변경하기
문서 메타데이터는 PUT /documents/{documentId}/metadatas, 템플릿 메타데이터는 PUT /templates/{templateId}/metadatas로 변경합니다.
문서 메타데이터 변경
curl -X PUT 'https://api.modusign.co.kr/documents/{DOCUMENT_ID}/metadatas' \
-H 'Accept: application/json' \
-H 'Authorization: Basic {YOUR_BASE64_CREDENTIALS}' \
-H 'Content-Type: application/json' \
-d '{
"metadatas": [
{
"key": "teamCode",
"value": "HR"
},
{
"key": "documentType",
"value": "EMPLOYMENT_CONTRACT"
},
{
"key": "contractYear",
"value": "2027"
}
]
}'
변경 API는 배열 전체를 교체합니다
contractYear하나만 바꾸더라도 유지할teamCode,documentType을 포함한 전체 메타데이터 목록을 전달해야 합니다. 요청에서 빠진 메타데이터는 삭제됩니다.
템플릿 메타데이터 변경
템플릿도 같은 방식으로 전체 메타데이터 배열을 전달합니다. 다음 예시는 인사팀 템플릿으로 분류하는 요청입니다.
curl -X PUT 'https://api.modusign.co.kr/templates/{TEMPLATE_ID}/metadatas' \
-H 'Accept: application/json' \
-H 'Authorization: Basic {YOUR_BASE64_CREDENTIALS}' \
-H 'Content-Type: application/json' \
-d '{
"metadatas": [
{
"key": "teamCode",
"value": "HR"
},
{
"key": "documentType",
"value": "EMPLOYMENT_CONTRACT"
}
]
}'메타데이터 전체 삭제
빈 배열을 전달하면 기존 메타데이터가 모두 삭제됩니다.
curl -X PUT 'https://api.modusign.co.kr/documents/{DOCUMENT_ID}/metadatas' \
-H 'Accept: application/json' \
-H 'Authorization: Basic {YOUR_BASE64_CREDENTIALS}' \
-H 'Content-Type: application/json' \
-d '{
"metadatas": []
}'6. 접근 권한을 함께 설계하기
하나의 API Key로 여러 팀이나 가맹점을 처리할 때는 다음 두 층을 나누어 생각해야 합니다.
| 구분 | 담당 기능 |
|---|---|
| 메타데이터 | 문서·템플릿을 팀, 가맹점, 문서 종류 등의 기준으로 분류하고 목록을 필터링 |
| 사내 권한 관리 | 로그인 사용자가 어느 팀·가맹점의 문서에 접근할 수 있는지 판단하고 강제 |
권장 구조는 다음과 같습니다.
- API Key를 서버의 안전한 환경에만 저장합니다.
- 사내 시스템에서 사용자와 허용된
teamCode또는storeCode의 관계를 관리합니다. - 문서·템플릿 생성 시 서버가 분류용 메타데이터를 추가합니다.
- 목록 조회 시 서버가 허용된 메타데이터 조건을 자동으로 적용합니다.
- 문서 상세 조회·다운로드·변경 요청에서도 서버가 해당 문서에 대한 사용자 권한을 별도로 확인합니다.
- 브라우저나 모바일 앱에는 API Key를 전달하지 않습니다.
유의사항하나의 API Key를 여러 팀이나 가맹점에 직접 배포하면 사용자가 메타데이터 필터를 빼거나 다른 값으로 바꾸어 요청할 수 있습니다. 이 구조에서는 팀별·가맹점별 분리가 보장되지 않습니다.
API Key는 중앙 서버만 사용하고, 사용자가 볼 수 있는 범위는 사내 시스템이 강제해야 합니다.
7. API 호출 시 주의사항
- 문서 또는 템플릿 하나에 메타데이터는 최대 10개까지 등록할 수 있습니다.
- 메타데이터
key는 필수이며 1~40자,value는 문자열이며 최대 80자입니다. - 여러 메타데이터로 필터링하면 모든 조건을 만족하는 항목만 조회됩니다.
- 메타데이터 변경 API는 기존 배열 전체를 새 배열로 대체합니다.
- 변경 API에 빈 배열을 전달하면 메타데이터가 모두 삭제됩니다.
- 응답의 메타데이터 순서는 보장되지 않으므로 배열 위치에 의존하지 마세요.
- 메타데이터는 문서 분류와 검색에 사용하고, 사용자 접근 권한이나 보안 제어에는 사용하지 마세요.
- API Key는 서버사이드에서만 사용하고 브라우저 등 클라이언트에 노출하지 마세요.
자주 발생하는 실수
| 상황 | 원인 | 해결 방법 |
|---|---|---|
| 일부 메타데이터가 사라짐 | 변경 API에 수정할 항목만 전달함 | 유지할 항목을 포함한 전체 배열 전달 |
| 조회 결과가 없음 | 저장된 key·value와 조회 조건의 표기가 다름 | 대소문자와 코드 표기를 포함해 저장값 확인 |
| 다른 팀이나 가맹점 조건을 조회할 수 있음 | 클라이언트가 필터 값을 직접 결정함 | 서버에서 로그인 사용자의 허용 범위를 확인하고 조건 강제 |
| 같은 조직이 여러 그룹으로 나뉨 | HR, hr, 인사팀처럼 값을 혼용함 | 조직 전체에서 사용할 코드표 정의 |
8. 자주 묻는 질문
메타데이터를 설정하지 않아도 문서나 템플릿을 만들 수 있나요?
네. 메타데이터는 선택 항목입니다. 다만 팀별·가맹점별 목록 분류가 필요하다면 생성 시점부터 일관되게 설정하는 것이 좋습니다.
여러 메타데이터로 조회하면 OR 조건인가요, AND 조건인가요?
AND 조건입니다. teamCode=HR과 documentType=EMPLOYMENT_CONTRACT를 전달하면 두 조건을 모두 만족하는 항목만 조회됩니다.
특정 메타데이터 하나만 수정할 수 있나요?
변경 API는 기존 목록 전체를 새 목록으로 교체합니다. 하나만 바꾸더라도 유지할 메타데이터를 포함한 전체 배열을 전달해야 합니다.
메타데이터를 모두 삭제하려면 어떻게 하나요?
문서 또는 템플릿의 메타데이터 변경 API에 빈 배열을 전달하세요.
{
"metadatas": []
}하나의 API Key를 여러 팀이나 가맹점이 함께 사용해도 되나요?
중앙 서버가 API Key를 보관하고 모든 요청을 대신 처리하는 구조라면 메타데이터로 업무 데이터를 논리적으로 나눌 수 있습니다. 각 팀이나 가맹점 사용자에게 API Key를 직접 전달해서는 안 됩니다.
메타데이터만 설정하면 다른 팀의 문서 접근이 차단되나요?
아니요. 메타데이터는 필터링 기능이며 접근 권한을 강제하지 않습니다. 로그인 사용자의 소속과 권한을 사내 시스템에서 확인하고, 목록뿐 아니라 상세 조회·다운로드·변경 요청에도 권한 검사를 적용해야 합니다.
템플릿 메타데이터가 생성 문서에도 자동으로 적용되나요?
자동으로 적용되지 않습니다. 문서 분류에 사용할 메타데이터는 서명 요청 시 document.metadatas에 명시적으로 전달하세요.
Updated 1 day ago
