콘텐츠로 이동

서명 세션과 서명 링크

수신자는 Bona Fide의 서명 페이지에서 서명합니다. https://sign.bonafidesign.com/s/…의 호스팅 페이지이거나, <bf-signing>으로 자사 제품에 임베드한 같은 페이지입니다. 수신자에게는 계정이 필요 없습니다. 수신자가 서명 페이지에 들어올 수 있게 해 주는 것은 서명 세션입니다.

이메일 전달에서는 세션이 자동으로 만들어집니다(이메일 속 링크). 임베드 서명이나 직접 전달하는 서명의 경우에는 백엔드에서 세션을 발급하세요.

터미널 창
curl https://api.bonafidesign.com/v1/envelopes/env_8Gm2kQ4rT1/sessions \
-H "Authorization: Bearer $BONA_FIDE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{ "recipient": "rcp_5Jw0pLs9Xe", "mode": "embedded", "allowedOrigins": ["https://app.example.com"], "ttlSeconds": 600 }'
{
"id": "ses_2Hq8vNw3Kd",
"token": "bfs_…",
"url": "https://sign.bonafidesign.com/s/?embed=1#session=bfs_…",
"expiresAt": "2026-10-13T14:08:04.512Z"
}
필드 설명
recipient 아직 서명할 수 있는 봉투의 수신자(CC가 아니고 완료하지 않은 수신자)
mode embedded(기본값) 또는 hosted. 호스팅 url은 …/s/<token> 형식이며, 리디렉션하거나 직접 보낼 수 있습니다
allowedOrigins 임베드 페이지를 프레임에 넣을 수 있는 출처. 최대 10개
returnUrl 서명을 마친 서명자를 호스팅 페이지가 보낼 위치
ttlSeconds 60~3600, 기본값 600

세션은 일회용입니다. 수신자가 제출하면 세션은 소진되며, 사용했거나 만료된 세션은 410 Gone을 반환합니다. 페이지를 렌더링할 때마다 새 세션을 발급하세요. 세션은 봉투가 sent 상태일 때만 만들 수 있으며, 봉투를 무효화하면 모든 세션이 종료됩니다.

서명 페이지(그리고 같은 API로 직접 만든 UI)는 다음 단계를 따릅니다.

  1. 교환: POST /v1/signing/exchange { "token": "bfs_…" }는 메모리에 보관되는 단기 액세스 토큰(bfa_…)을 반환합니다. 쿠키를 사용하지 않으므로 iframe에서 서드 파티 쿠키가 차단되어도 문제가 없습니다.
  2. 로드: GET /v1/signing/session은 서명자 화면 정보(봉투 제목, 발신자, 수신자의 역할과 필드, 미리 채워진 값, 소비자 고지)를 반환하고, 처음 호출될 때 recipient.viewed를 기록합니다. GET /v1/signing/document는 표시할 PDF입니다.
  3. 인증(email_otp인 경우에만): POST /v1/signing/otp는 6자리 코드(10분간 유효)를 이메일로 보내고, POST /v1/signing/otp/verify는 그 코드를 확인합니다. 코드가 틀리면 남은 시도 횟수와 함께 verified: false가 반환됩니다. 수신자의 방식에 코드가 필요 없으면 화면 정보의 verification.verified는 처음부터 true입니다.
  4. 제출: POST /v1/signing/submit으로 필드 values(그리거나, 입력하거나, 업로드한 서명), 고지에 대한 동의, 그리고 viewedDocumentHash(표시된 바로 그 PDF의 SHA-256)를 보냅니다. 그 사이에 문서가 변경되었으면 제출이 거부됩니다(409).
  5. 또는 거절: POST /v1/signing/decline { "reason": "…" }는 봉투를 종료합니다(envelope.declined).

이전의 모든 라우팅 그룹이 끝나야 수신자의 차례가 됩니다. 그 전까지 화면 정보는 canSign: false이고, 제출하면 409 not-your-turn이 반환됩니다.

각 수신자에게는 verification 방식이 있습니다. 봉투에서 수신자별로 재정의하지 않는 한(발송 화면 또는 recipients[].verification) 역할의 방식(템플릿 디자이너의 역할 패널에서 설정)이 사용됩니다.

방식 서명자가 하는 일 사용하는 경우
none(기본값) 고유한 서명 링크를 열고 서명합니다 링크가 이메일로 전송되는 경우: 그 받은편지함에 접근할 수 있는 사람만 링크를 가집니다
email_otp 링크를 연 다음, 같은 주소로 전송된 6자리 코드를 입력합니다 서명하는 시점에 새로운 두 번째 증명이 필요한 경우(고액 계약, 공유 받은편지함)
integrator_asserted 자사 제품에서 서명하며, 제품이 본인임을 보증합니다(externalUserId) 자사 로그인 뒤에서 이루어지는 임베드 서명

none이 기본값인 이유는 Bona Fide가 이메일로 보내는 링크 자체가 수신자마다 고유하고 추측할 수 없기 때문입니다. 링크를 연다는 것은 그 이메일 주소를 통제하고 있음을 보여 주며, 이는 전자 서명 관련 법률이 근거로 삼는 귀속 요건입니다(미국의 ESIGN법 / UETA, eIDAS의 단순 전자 서명). 유사한 제품들도 이를 기본값으로 사용합니다. email_otp로 게시된 템플릿은 그 설정을 유지하며, 명시적으로 지정한 email_otp는 어디서나 계속 작동합니다.

다음 두 흐름은 링크만으로 인증하지 않습니다.

  • 상시 서명 링크(/l/…): 방문자가 자신의 주소를 직접 입력하므로, 템플릿 설정과 관계없이 봉투가 만들어지기 전에 항상 이메일로 받은 코드를 확인합니다.
  • 직접 발급한 세션(POST /v1/envelopes/{id}/sessions)에는 이메일 주소에 대한 증명이 전혀 없습니다. 그것은 자사 로그인의 몫이므로, 이 경우에는 integrator_asserted(externalUserId와 함께) 또는 email_otp를 사용하세요.

완료 인증서에는 서명자별로 실제 사용된 방식이 기록됩니다.

기록되는 내용 조건
이메일 링크(주소로 보낸 고유 링크) none, 이메일 링크에서 서명한 경우
이메일 링크 + 일회용 코드(주소로 전송) email_otp, 이메일 링크에서 서명한 경우
서명 링크 + 일회용 코드(주소로 전송) 상시 링크 방문자
일회용 코드(주소로 전송) 직접 발급한 세션에서의 email_otp
발신자가 발급한 서명 세션 직접 발급한 세션에서의 none
연동 업체의 보증 integrator_asserted

공개 검증 요약에는 주소를 제외한 같은 라벨이 표시됩니다.

서명 페이지, 관련 이메일(요청, 알림, 코드, 완료, 무효화), 상시 링크 페이지, 열람자 상태 페이지는 50개 언어로 제공됩니다. 서명자에게는 다음 우선순위에 따라 언어가 표시됩니다.

  1. 서명자가 페이지의 언어 메뉴에서 선택한 언어(해당 기기에 저장됨)
  2. <bf-signing locale="…">(임베드 서명) 또는 호스팅 링크의 ?locale=
  3. 봉투를 만들 때 설정한 수신자의 locale(recipients[].locale, 또는 자체 값이 없는 모든 사람을 위한 봉투의 locale)
  4. 브라우저 언어

이메일은 누군가 페이지를 열기 전에 언어가 정해져야 하므로 수신자의 locale을 사용하며, 값이 없으면 영어로 전송됩니다. 상시 링크는 방문자의 페이지에 표시된 언어로 코드 이메일을 보냅니다.

{
"template": "tpl_…",
"locale": "es-419",
"recipients": [
{ "role": "client", "name": "Ana Souza", "email": "ana@example.com", "locale": "pt-BR" },
{ "role": "company", "name": "Lee Park", "email": "lee@example.com" }
]
}

비슷한 태그는 허용되며 대응하는 언어로 저장됩니다(de-AT → de, es-MX → es-419, zh-TW → zh-Hant). 그 밖의 값은 검증 오류입니다. 번역된 동의 고지에는 영어 원문이 적용된다는 안내가 있으며, 서명자는 영어 원문으로 전환할 수 있습니다. 고지를 읽은 언어는 서명과 함께 기록됩니다 (recipient.signed 감사 이벤트의 consentLocale).

코드 언어 현지어 이름
ar 아랍어 العربية 오른쪽에서 왼쪽
hy 아르메니아어 Հայերեն
bn 벵골어 বাংলা
bg 불가리아어 Български
zh-Hans 중국어(간체) 简体中文
zh-Hant 중국어(번체) 繁體中文
hr 크로아티아어 Hrvatski
cs 체코어 Čeština
da 덴마크어 Dansk
nl 네덜란드어 Nederlands
en-GB 영어(영국) English (UK)
en-US 영어(미국) English (US)
et 에스토니아어 Eesti
fil 필리핀어 Filipino
fi 핀란드어 Suomi
fr 프랑스어 Français
fr-CA 프랑스어(캐나다) Français (Canada)
de 독일어 Deutsch
el 그리스어 Ελληνικά
he 히브리어 עברית 오른쪽에서 왼쪽
hi 힌디어 हिन्दी
hu 헝가리어 Magyar
id 인도네시아어 Bahasa Indonesia
it 이탈리아어 Italiano
ja 일본어 日本語
ko 한국어 한국어
lv 라트비아어 Latviešu
lt 리투아니아어 Lietuvių
ms 말레이어 Bahasa Melayu
mr 마라티어 मराठी
nb 노르웨이어 Norsk bokmål
fa 페르시아어 فارسی 오른쪽에서 왼쪽
pl 폴란드어 Polski
pt-BR 포르투갈어(브라질) Português (Brasil)
pt-PT 포르투갈어(포르투갈) Português (Portugal)
ro 루마니아어 Română
ru 러시아어 Русский
sr-Latn 세르비아어(라틴 문자) Srpski
sk 슬로바키아어 Slovenčina
sl 슬로베니아어 Slovenščina
es-419 스페인어(라틴 아메리카) Español (Latinoamérica)
es-ES 스페인어(스페인) Español (España)
sw 스와힐리어 Kiswahili
sv 스웨덴어 Svenska
te 텔루구어 తెలుగు
th 태국어 ไทย
tr 튀르키예어 Türkçe
uk 우크라이나어 Українська
ur 우르두어 اردو 오른쪽에서 왼쪽
vi 베트남어 Tiếng Việt

서명 링크는 많은 사람이 같은 방식으로 서명하는 계약을 위한 영구 URL입니다. 예를 들어 권리 포기서, 계약자 계약서, 파일럿 이용 약관 등입니다. 링크에서 서명을 완료한 방문자마다 각자의 봉투가 만들어집니다.

터미널 창
curl https://api.bonafidesign.com/v1/signing-links \
-H "Authorization: Bearer $BONA_FIDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template": "tpl_…",
"visitorRole": "contractor",
"countersign": { "role": "company", "mode": "auto" },
"limits": { "perEmailPerDay": 3, "perIpPerHour": 20, "dailyCap": 200, "allowedEmailDomains": ["example.com"] }
}'
  • visitorRole은 방문자가 맡는 서명자 역할입니다. 링크는 방문자 한 명과 최대 한 명의 연서명자를 지원합니다. mode: "auto"는 Bona Fide 플랫폼 봉인으로 자동 연서명하고, mode: "person"은 지정된 email로 봉투를 라우팅합니다. 그 밖의 CC가 아닌 역할에는 수신자가 없게 되므로 그런 템플릿은 거부됩니다.
  • 방문자는 이름, 이메일, 템플릿 변수를 입력한 다음, 무엇이든 만들어지기 전에 이메일 코드를 확인합니다 (POST /v1/links/{id}/start, 이어서 POST /v1/links/{id}/verify).
  • limits는 이메일별 하루 사용 횟수(기본값 3), IP별 시간당 사용 횟수(기본값 20), 전체 하루 사용 횟수, 그리고 이메일 도메인으로 사용을 제한합니다. dedupe(기본값 켜짐)를 사용하면 이미 서명한 이메일 주소에는 409 already-signed가 반환됩니다.
  • PATCH /v1/signing-links/{id}는 링크를 일시 중지(active: false), 재개하거나 새 버전으로 옮깁니다. 링크를 삭제해도 그 링크로 만들어진 봉투는 유지됩니다. 링크가 사용될 때마다 signing_link.used가 발생합니다.