개발자 · MCP · API
전자계약을
코드와 AI에 연결하세요
API 키 하나로 REST와 MCP를 바로 연결하세요. 계약 생성·발송·상태 조회·체결본 다운로드를 지원하고, 실제 발송은 dry_run 미리보기 → confirmation_token 승인 게이트를 서버단에서 강제해요. 멱등키·OpenAPI·llms.txt 공개.
빠른 시작
가입 → 키 발급 → 첫 호출
API 키를 발급받아 설정에 넣고, dry-run으로 먼저 미리보기를 받으세요. 가입 시 100건 무료(1회성)가 제공돼요.
1 가입 후 키 발급
대시보드에서 live/test API 키를 발급받아요. 키는 서버 측 환경변수로 보관하고 클라이언트 노출을 피하세요.
2 MCP 또는 REST 선택
AI 클라이언트는 mcpServers에 등록하고, 자체 서버는 REST 엔드포인트를 호출해요. 백엔드는 동일해요.
3 첫 호출 (dry-run)
발송 tool을 dry_run=true로 호출해 미리보기와 confirmation_token을 먼저 받아요.
A. MCP 클라이언트 — mcpServers 설정
Claude Desktop·Codex 등 설정 파일(예: claude_desktop_config.json)에 추가하세요. 원격 MCP 서버를 Streamable HTTP로 연결해요.
{
"mcpServers": {
"signdeal": {
"type": "http",
"url": "https://mcp.signdeal.kr",
"headers": {
"Authorization": "Bearer <발급받은 API 키>"
}
}
}
}
로컬 stdio 브리지가 필요한 클라이언트는 mcp-remote로 원격 서버를 연결할 수 있어요.
{
"mcpServers": {
"signdeal": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.signdeal.kr"],
"env": {
"SIGNDEAL_API_KEY": "<발급받은 API 키>"
}
}
}
}
B. REST — 첫 호출 (cURL · dry-run)
발송 전 미리보기를 받는 호출이에요. 실제 발송은 일어나지 않고 confirmation_token이 반환돼요.
curl https://api.signdeal.kr/v1/contracts/{contract_id}/send \ -H "Authorization: Bearer $SIGNDEAL_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{ "channel": "kakao", "dry_run": true }'
- 지원 클라이언트: Claude(Desktop/Code) · Codex 등 MCP 호환 도구
- 전송: Streamable HTTP(원격) — 로컬 stdio는
mcp-remote브리지로 dry_run→confirmation_token의 2단계 안전 흐름이 서버단에서 강제 적용- 본인확인·타임스탬프·감사추적은 발송 tool에서 항상 적용
Tool 레퍼런스
MCP 10개 tool
싸인딜 MCP 서버가 노출하는 tool이에요. AI는 대화 맥락에 맞는 tool을 자동 선택해요. 발송·체결 계열은 항상 dry-run과 confirmation token을 거쳐야 실행돼요.
| Tool | 역할 | 주요 입력 (inputSchema) |
|---|---|---|
list_templates |
사용 가능한 계약 양식 목록 조회(차용증 등). 양식 ID·필수 필드를 반환해요. | type?: string |
generate_contract_from_text |
자연어에서 계약 슬롯·서명 앵커·검토 페이로드·리스크 경고를 생성해요. (참고용) | text: string, contract_type?: string |
create_draft |
검토된 본문·슬롯으로 계약 초안을 만들고 발송 준비 상태로 저장해요. | contract_type, title, body_markdown, slots? |
add_signer |
서명자를 추가하고 계약 유형·금액에 맞는 본인확인 하한을 자동 적용해요. | contract_id, name, phone_e164, role_label |
set_signature_fields_auto |
생성 시 저장된 역할 앵커를 기준으로 서명 필드를 좌표 없이 확정해요. | contract_id |
send_for_signature |
destructive. dry-run 미리보기와 confirmation token을 만들고, 승인 토큰이 있을 때만 실제 발송해요. | contract_id, channel?, dry_run, confirmation_token? |
check_status |
계약 상태와 서명자 진행 현황을 조회해요. | contract_id |
get_signed_document |
체결 완료 후 보존본 PDF와 문서 해시를 받아요. | contract_id |
계약 무효화(void)는 MCP에 노출되지 않아요 — 실수 방지를 위해 REST/웹앱 전용이에요. tool 이름·스키마는 안정화 과정에서 변경될 수 있어요. 정식 출시 시점에 OpenAPI/JSON 스키마를 이 문서에서 함께 공개해 드려요.
안전 모델 · HITL
발송은 항상 두 단계를 거쳐요
AI나 코드의 실수로 계약이 잘못 나가지 않도록, 발송은 미리보기와 명시적 승인을 분리했어요. 이 게이트는 서버단에서 강제되어 클라이언트가 끌 수 없어요.
1) 미리보기
send_for_signature가 발송 없이 수신자·채널·예상 결제가와 confirmation_token을 반환해요.
2) 승인 게이트
5분·1회·계약 스냅샷에 바인딩된 토큰이에요. 만료·내용 변경 시 무효가 되어 새로 미리보기를 받아야 해요.
3) 실제 발송
토큰을 다시 전달하면 카카오 알림톡이 나가요. 이때 본인확인·타임스탬프·감사추적이 함께 적용돼요.
서버단에서 강제되는 보호
- 본인확인·타임스탬프·감사추적인증서는 클라이언트가 끌 수 없어요.
- 금액이 큰 계약(예: 차용증 고액)은 본인확인 하한이 자동 상향돼요.
- 전자계약 불가 문서(유언·혼인신고·일부 등기)는 draft 단계에서 차단돼요.
- 계약 무효화(void)는 MCP에 노출되지 않고 REST/웹앱 전용이에요.
인증 · OAuth
현재는 API 키(Bearer) 인증을 지원해요.
- API 키(Bearer) — 대시보드에서 발급. 모든 요청에
Authorization: Bearer …헤더로 전달해요. - 키는 서버 측 환경변수로 관리하고 공개 저장소·클라이언트에 노출하지 마세요.
- OAuth 2.1 동적 인증은 준비 중이에요(MCP Authorization 규격). 예정
OAuth는 아직 제공 전이에요. 준비되는 대로 이 문서와 공지에서 알려드려요. 현재는 API 키(Bearer) 인증으로 연동해요.
REST API
REST 엔드포인트와 멱등키
자체 서버·백오피스에서 직접 호출하세요. 생성·발송 계열 요청에는 Idempotency-Key 헤더로 중복을 막을 수 있어요.
| 메서드 · 경로 | 설명 |
|---|---|
GET /v1/templates | 양식 목록 조회 |
POST /v1/contracts | 초안 생성(멱등키 권장) |
POST /v1/contracts/{id}/signers | 서명자 추가(본인확인 하한 자동 적용) |
POST /v1/contracts/{id}/send | 발송 — dry_run → confirmation_token(멱등키 권장) |
GET /v1/contracts/{id} | 상태·서명자 진행 조회 |
GET /v1/contracts/{id}/document | 보존본 PDF·문서 해시(체결 후) |
멱등키 사용
같은 Idempotency-Key로 재시도하면 중복 없이 동일 결과를 반환해요. 네트워크 재시도·타임아웃에 안전해요.
curl https://api.signdeal.kr/v1/contracts \ -H "Authorization: Bearer $SIGNDEAL_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 9f2c1b7e-…" \ -d '{ "contract_type": "loan_iou", "title": "차용증", "body_markdown": "…" }'
경로·필드명은 정식 출시 전 변경될 수 있어요. 확정 스펙은 OpenAPI 문서로 함께 공개해 드려요.
웹훅
체결·거절·만료 이벤트 수신
계약 상태가 바뀌면 등록한 엔드포인트로 이벤트를 보내드려요. 서명 시크릿으로 위변조를 검증하세요. 웹훅 예정
contract.completed
모든 서명자가 서명을 마쳐 체결이 완료된 시점이에요. 보존본을 내려받을 수 있어요.
contract.declined
서명자가 서명을 거절한 시점이에요. 사유와 서명자 정보가 함께 전달돼요.
contract.expired
유효기간 내 체결이 완료되지 않아 만료된 시점이에요.
서명 검증
요청 헤더의 서명(HMAC)을 등록한 시크릿으로 검증하세요. 검증에 실패한 요청은 폐기하세요.
POST /your/webhook X-Signdeal-Signature: sha256=<hmac> { "event": "contract.completed", "contract_id": "ct_…", "tracking_id": "…" }
웹훅은 현재 지원해요. 계약이 발송·체결·취소될 때 contract.sent·contract.completed·contract.voided 이벤트를 등록한 URL로 푸시하고, 요청 헤더 x-signdeal-signature에 HMAC-SHA256 서명을 담아 위·변조를 검증할 수 있어요. 구글시트·슬랙·노션·텔레그램 채널 연동도 함께 지원해요. OAuth 2.1 공개 연결은 준비 중이에요.
코드 샘플
언어별 발송 흐름 예시
dry-run으로 미리보고 confirmation_token으로 승인하는 같은 흐름을 cURL·JavaScript·Python으로 보여드려요.
cURL shell
curl https://api.signdeal.kr/v1/contracts/$CID/send \ -H "Authorization: Bearer $SIGNDEAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "channel": "kakao", "dry_run": true }' # → confirmation_token 수신 후 curl https://api.signdeal.kr/v1/contracts/$CID/send \ -H "Authorization: Bearer $SIGNDEAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "channel": "kakao", "confirmation_token": "ct_tok_…" }'
JavaScript node fetch
const base = "https://api.signdeal.kr/v1"; const headers = { Authorization: `Bearer ${process.env.SIGNDEAL_API_KEY}`, "Content-Type": "application/json", }; // 1) 미리보기 const preview = await fetch(`${base}/contracts/${cid}/send`, { method: "POST", headers, body: JSON.stringify({ channel: "kakao", dry_run: true }), }).then(r => r.json()); // 2) 승인 후 발송 await fetch(`${base}/contracts/${cid}/send`, { method: "POST", headers, body: JSON.stringify({ channel: "kakao", confirmation_token: preview.confirmation_token }), });
Python requests
import os, requests base = "https://api.signdeal.kr/v1" headers = { "Authorization": f"Bearer {os.environ['SIGNDEAL_API_KEY']}", "Content-Type": "application/json", } # 1) 미리보기 preview = requests.post( f"{base}/contracts/{cid}/send", headers=headers, json={"channel": "kakao", "dry_run": True}, ).json() # 2) 승인 후 발송 requests.post( f"{base}/contracts/{cid}/send", headers=headers, json={"channel": "kakao", "confirmation_token": preview["confirmation_token"]}, )
에러 · 레이트리밋 · 환경변수
운영에 필요한 것들
표준 HTTP 상태 코드와 일관된 에러 형식을 사용해요. 레이트리밋·환경변수 관례도 함께 안내해 드려요.
에러 코드
| 상태 | 의미 |
|---|---|
400 | 요청 형식 오류 — 필드·스키마 확인 |
401 | 인증 실패 — API 키(Bearer) 확인 |
403 | 권한 부족 — scope·테넌트(org) 격리 |
409 | 상태 충돌 — 토큰 만료/내용 변경 시 재미리보기 |
422 | 전자계약 불가 문서 등 비즈니스 규칙 위반 |
429 | 레이트리밋 초과 — 백오프 후 재시도 |
레이트리밋 · 환경변수
429응답 시Retry-After헤더를 존중하고 지수 백오프로 재시도하세요.- 조회(
check_status)는 폴링 대신 백오프 또는 웹훅을 권장해요. SIGNDEAL_API_KEY는 환경변수로 주입하고 저장소에 커밋하지 마세요.test키로 먼저 검증한 뒤live키로 전환하세요.
구체적 한도 수치는 정식 출시 시점에 문서에서 확정 공개해 드려요. 현재는 운영 관례만 안내해요.
기계 가독성 · AEO
llms.txt · OpenAPI
사람뿐 아니라 AI·도구가 싸인딜을 정확히 이해하도록, 기계 가독 문서를 함께 제공해요.
llms.txt
AI가 우선 참조하는 핵심 URL·요약을 정리한 파일이에요. 차용증·MCP·신뢰·본인확인·요금 페이지를 우선 노출해요.
OpenAPI 스펙
REST 엔드포인트·스키마를 기계 가독 형식으로 공개할 예정이에요. 클라이언트 코드 생성·검증에 쓸 수 있어요. 정식 출시 시 공개
llms.txt는 운영 페이지 기준으로 정직하게 갱신해요. OpenAPI 문서는 스펙 안정화 후 버전과 함께 공개해 드려요.
자주 묻는 질문
개발자가 자주 묻는 것
MCP 서버와 REST API 중 무엇을 써야 하나요?
실수로 계약이 발송되지 않게 막을 수 있나요?
send_for_signature는 기본이 dry_run=true이고, 발송에는 미리보기에서 발급된 confirmation_token이 필요해요. 이 2단계는 서버단에서 강제되어 클라이언트가 끌 수 없어요.같은 요청을 두 번 보내면 중복 발송되나요?
Idempotency-Key 헤더를 권장해요. 같은 키로 재시도하면 중복 없이 동일 결과를 반환해요.OAuth로 연결할 수 있나요?
요금은 어떻게 되나요?
키를 발급받고 첫 호출을 해보세요
가입하면 API 키와 무료 100건(1회성)이 함께 제공돼요. 통합 상담이 필요하면 기업·API 팀이 도와드려요.
싸인딜의 보안은 감사추적인증서·휴대폰 본인확인으로 뒷받침해요. tool 이름·스키마·엔드포인트는 정식 출시 전 변경될 수 있어요.