빠른 시작
이 안내에서는 게시된 템플릿을 서명되고 봉인된 PDF로 만드는 과정을 따라갑니다. 테스트 키를 사용하므로 요금이 청구되지 않으며,
모든 문서에 TEST 워터마크가 들어갑니다.
-
API 키 만들기
섹션 제목: “API 키 만들기”API 키는 대시보드의 설정 › API 키에서 만듭니다. 이 안내에서는 Test를 선택하세요. 키는
bf_test_로 시작합니다. 전체 키는 한 번만 표시되므로 환경 변수에 저장해 두세요.터미널 창 export BONA_FIDE_API_KEY=bf_test_…모든 요청은 이 키를
Authorization: Bearer …(또는x-api-key: …)로 보냅니다. 인증을 참조하세요. -
템플릿 찾기
섹션 제목: “템플릿 찾기”템플릿은 대시보드에서 설계한 다음(PDF 또는 Word 문서를 업로드하고 필드를 배치하거나, 문서 모드에서 작성) 게시합니다. 목록을 조회해 ID를 확인하세요.
터미널 창 curl https://api.bonafidesign.com/v1/templates \-H "Authorization: Bearer $BONA_FIDE_API_KEY"const res = await fetch('https://api.bonafidesign.com/v1/templates', {headers: { Authorization: `Bearer ${process.env.BONA_FIDE_API_KEY}` },});const { data } = await res.json(); // [{ id: 'tpl_…', name: 'Mutual NDA', latestVersion: 3, … }]import os, requestsAPI = "https://api.bonafidesign.com"headers = {"Authorization": f"Bearer {os.environ['BONA_FIDE_API_KEY']}"}templates = requests.get(f"{API}/v1/templates", headers=headers).json()["data"]GET /v1/templates/{id}/versions/latest는 해당 버전의roles,fields, 그리고variables의 JSON Schema를 반환합니다. 대시보드의 템플릿 페이지에 있는 API에서 사용 패널에서도 바로 그 버전에 맞춘 요청 예시를 확인할 수 있습니다. -
봉투 만들기
섹션 제목: “봉투 만들기”POST /v1/envelopes는 변수를 넣어 템플릿을 렌더링하고, 버전을 고정한 뒤 라우팅을 시작합니다. 역할마다 수신자를 한 명씩 지정하세요(CC 역할은 선택 사항). 재시도로 두 번 발송되지 않도록Idempotency-Key를 보내세요.터미널 창 curl https://api.bonafidesign.com/v1/envelopes \-H "Authorization: Bearer $BONA_FIDE_API_KEY" \-H "Content-Type: application/json" \-H "Idempotency-Key: onboarding-8841" \-d '{"template": "tpl_…","version": "latest","variables": {"client": { "name": "Acme Robotics, Inc." },"effective_date": "2026-10-13"},"recipients": [{ "role": "client", "name": "Jane Doe", "email": "jane@acme.dev" }],"delivery": "embedded","externalId": "user_8841","dedupeOn": "external_id"}'const res = await fetch('https://api.bonafidesign.com/v1/envelopes', {method: 'POST',headers: {Authorization: `Bearer ${process.env.BONA_FIDE_API_KEY}`,'Content-Type': 'application/json','Idempotency-Key': 'onboarding-8841',},body: JSON.stringify({template: 'tpl_…',version: 'latest',variables: { client: { name: 'Acme Robotics, Inc.' }, effective_date: '2026-10-13' },recipients: [{ role: 'client', name: 'Jane Doe', email: 'jane@acme.dev' }],delivery: 'embedded',externalId: 'user_8841',dedupeOn: 'external_id',}),});if (res.status === 422) {// RFC 9457 problem: one entry per error, each with a JSON Pointer such as /variables/client/nameconsole.error((await res.json()).errors);}const envelope = await res.json(); // { id: 'env_…', status: 'sent', recipients: [{ id: 'rcp_…', … }] }res = requests.post(f"{API}/v1/envelopes",headers={**headers, "Idempotency-Key": "onboarding-8841"},json={"template": "tpl_…","version": "latest","variables": {"client": {"name": "Acme Robotics, Inc."}, "effective_date": "2026-10-13"},"recipients": [{"role": "client", "name": "Jane Doe", "email": "jane@acme.dev"}],"delivery": "embedded","externalId": "user_8841","dedupeOn": "external_id",},)if res.status_code == 422:print(res.json()["errors"]) # [{"pointer": "/variables/client/name", "message": "…"}]envelope = res.json()응답은
201 Created이며 봉투가 반환됩니다.{"id": "env_8Gm2kQ4rT1","organization": "org_…","template": "tpl_…","templateVersion": 3,"status": "sent","seal": "not_started","testMode": true,"recipients": [{"id": "rcp_5Jw0pLs9Xe","role": "client","name": "Jane Doe","email": "jane@acme.dev","order": 1,"status": "sent","verification": "email_otp","completedAt": null}],"documentHash": "9f2c…","sealedDocumentHash": null,"externalId": "user_8841","metadata": {},"createdAt": "2026-10-13T13:58:04.512Z","completedAt": null}delivery는 수신자에게 전달하는 방식을 결정합니다.email(기본값)은 각 수신자의 차례가 되면 서명 링크를 이메일로 보냅니다.embedded와none은 이메일을 보내지 않으며, 서명 세션을 직접 엽니다(다음 단계). -
수신자가 서명하도록 하기
섹션 제목: “수신자가 서명하도록 하기”백엔드에서 수신자의 서명 세션을 발급합니다. 세션은 유효 기간이 짧고(
ttlSeconds, 60~3600, 기본값 600) 한 번만 사용할 수 있습니다.터미널 창 curl https://api.bonafidesign.com/v1/envelopes/env_8Gm2kQ4rT1/sessions \-H "Authorization: Bearer $BONA_FIDE_API_KEY" \-H "Content-Type: application/json" \-d '{"recipient": "rcp_5Jw0pLs9Xe","mode": "embedded","allowedOrigins": ["https://app.example.com"]}'반환된
token(bfs_…)을 페이지에 전달하고 웹 컴포넌트를 렌더링합니다.<script type="module" src="https://js.bonafidesign.com/v1"></script><bf-signing session="bfs_…"></bf-signing><script>document.querySelector('bf-signing').addEventListener('completed', (e) => console.log('signed', e.detail.envelope));</script>React 및 Vue 래퍼, 이벤트, 보안 모델은 임베드 서명을 참조하세요.
터미널 창 curl https://api.bonafidesign.com/v1/envelopes/env_8Gm2kQ4rT1/sessions \-H "Authorization: Bearer $BONA_FIDE_API_KEY" \-H "Content-Type: application/json" \-d '{ "recipient": "rcp_5Jw0pLs9Xe", "mode": "hosted", "returnUrl": "https://app.example.com/done" }'서명자를 반환된
url(https://sign.bonafidesign.com/s/bfs_…)로 리디렉션합니다. 호스팅 페이지는 모바일 우선으로 설계되었으며 계정이 필요 없습니다.기본값인
email_otp인증에서는 서명자가 제출하기 전에 이메일로 받은 6자리 코드를 확인합니다. 테스트 모드에서는 이메일이 조직 구성원에게만 전송되므로, 테스트하는 동안에는 본인 주소를 사용하세요. -
완료 알림 받기
섹션 제목: “완료 알림 받기”설정 › 웹훅에서(또는
POST /v1/webhook-endpoints로) 웹훅 엔드포인트를 등록하고whsec_…시크릿을 보관하세요. 마지막 수신자가 서명하면envelope.completed를 받게 되며,data.values에 모든 변수와 입력된 값이 담겨 있습니다. 이어서envelope.sealed로 봉인된 PDF가 준비되었음을 알려 줍니다.import express from 'express';import { Webhook } from 'standardwebhooks';const wh = new Webhook(process.env.BONA_FIDE_WEBHOOK_SECRET!);const app = express();app.post('/hooks/bona-fide', express.raw({ type: 'application/json' }), async (req, res) => {const event = wh.verify(req.body, req.headers as Record<string, string>) as { type: string; data: any };if (event.type === 'envelope.completed') await saveValues(event.data.envelope.id, event.data.values);if (event.type === 'envelope.sealed') await fetchSealedPdf(event.data.envelope.id);res.sendStatus(204);});봉인된 PDF(완료 인증서가 포함되고 타임스탬프가 적용된 문서)를 다운로드합니다.
터미널 창 curl -o signed.pdf "https://api.bonafidesign.com/v1/envelopes/env_8Gm2kQ4rT1/document?version=sealed" \-H "Authorization: Bearer $BONA_FIDE_API_KEY"전체 이벤트 목록, 재시도, 수동 검증은 웹훅을 참조하세요.
실서비스 전환
섹션 제목: “실서비스 전환”테스트 키를 bf_live_ 키로 바꾸세요. 라이브 봉투에는 워터마크가 들어가지 않고, 이메일은 모든 수신자에게 전송되며,
완료된 봉투는 플랜 사용량에 포함됩니다(플랜 및 한도). 키로 만든 모든 항목은 그 키의 모드를 따르고,
목록에는 해당 모드의 항목만 표시됩니다. 또한 테스트 봉투는 테스트 모드 웹훅 엔드포인트에만 알림을 보내므로,
라이브 엔드포인트도 등록하세요.