API 레퍼런스
신원 인증 API 레퍼런스입니다.
호출할 수 있는 모든 엔드포인트, 응답에서 보게 될 모든 필드, 웹훅이 도착했을 때 해야 할 일을 안내합니다. 정확한 필드 타입은 사용 중인 API 오리진의 /docs에 있는 라이브 OpenAPI 문서를 기준으로 삼으세요. 이 페이지는 쉬운 말로 풀어 쓴 버전입니다.
기본 URL 및 환경
기본 URL은 하나, 환경은 둘입니다.
모든 요청은 같은 호스트로 전송됩니다. 어느 환경에 있는지는 전송하는 API 키에 따라서만 결정됩니다.
| 기본 URL(이 문서 기준) | https://api.shieldid.ca — illustrative; your production API origin is published together with your API keys. |
|---|---|
| 인증 헤더 | 아래에 표시된 두 개의 공개 엔드포인트를 제외한 모든 요청에 X-Api-Key: <your key>를 포함해 주세요. |
| Sandbox 키 접두사 | vk_sand_… — 이 키로 생성한 세션에는 environment: "sandbox"가 지정되며 요금이 청구되지 않습니다. |
| 운영 키 접두사 | vk_live_… — 동일한 요청이지만 요금제에 따라 요금이 청구됩니다. |
| 콘텐츠 유형 | 모든 요청 본문과 응답에 application/json을 사용합니다. |
엔드포인트
v1 전체 구성입니다.
JSON 엔드포인트 6개와, JSON이 아닌 호스팅 페이지 및 공개 자격 증명 확인 페이지가 있으며, 이 둘은 링크만 연결하면 됩니다.
| Endpoint | Auth | What it does |
|---|---|---|
| POST /v1/sessions | X-Api-Key | 인증 세션을 생성합니다. return_url과 webhook_url이 필요합니다. session_id, verification_url, status: "PENDING"을 반환합니다. |
| GET /v1/sessions/{id} | X-Api-Key | 세션 하나의 상태와 주요 필드(status, confidence, environment)입니다. |
| GET /v1/sessions/{id}/result | X-Api-Key | 세션이 VERIFIED 또는 FAILED에 도달한 후의 전체 결과입니다: person, 검사별 판정, confidence, verified_until. |
| DELETE /v1/sessions/{id} | X-Api-Key | 아직 PENDING 또는 IN_PROGRESS 상태인 세션을 취소합니다. 이미 VERIFIED, FAILED 또는 EXPIRED 상태인 세션은 취소할 수 없습니다. |
| GET /v1/credentials/{token} | None — public | 인증된 자격 증명이 현재 유효한지 확인합니다. API 키가 필요 없어 브라우저에서도 호출할 수 있습니다. 참고: 현재 응답에는 유효/무효 표시뿐 아니라 인증된 사람의 이름과 문서 유형/국가도 포함됩니다. 해당 정보를 보여주고 싶지 않은 제3자에게는 이 링크를 전달하지 마세요. |
| GET /v1/pricing/{country} | X-Api-Key | 두 글자 ISO 3166-1 국가 코드별 요금입니다. |
| /v/{session_id} | 호스팅 인증 페이지로, 세션이 반환하는 verification_url입니다. 데스크톱에서는 QR 코드가 표시되며, 이를 스캔하면 신청자의 휴대폰에서 같은 링크가 열려 문서와 셀카를 촬영할 수 있습니다. |
|---|---|
| /c/{session_id} | 인증된 세션 하나에 대한 공개형 무인증 자격 증명 확인 페이지입니다. 참고: 현재 응답에는 유효/무효 표시뿐 아니라 인증된 사람의 이름과 문서 유형/국가도 포함됩니다. 해당 정보를 보여주고 싶지 않은 제3자에게는 이 링크를 전달하지 마세요. |
| /docs | 계정의 API 오리진에 대한 실시간 대화형 OpenAPI 레퍼런스입니다. |
세션 만들기
POST /v1/sessions, 처음부터 끝까지.
요청과 그에 대한 정확한 응답.
curl -X POST https://api.shieldid.ca/v1/sessions \
-H "X-Api-Key: vk_sand_your_key" \
-H "Content-Type: application/json" \
-d '{
"return_url": "https://yourapp.example/verified",
"webhook_url": "https://yourapp.example/hooks/shieldid",
"expected_name": "Jordan Smith",
"locale": "en",
"metadata": { "application_id": "app_9182" }
}'| return_url | string, 필수 — 신청자가 절차를 마친 후 돌아갈 위치입니다. http 또는 https여야 합니다. |
|---|---|
| webhook_url | string, 필수 — 서명된 결과가 전달되는 위치입니다. 아래 웹훅 항목을 참고하세요. |
| expected_name | string, 필수 — 문서에 기재되어 있을 것으로 예상하는 이름으로, 신분증에 실제로 적힌 내용과 대조하는 데 사용됩니다. |
| expected_dob / expected_address | string, 선택 — 제공하면 문서와 대조하며, 인증을 실행하는 데 필수는 아닙니다. |
| locale | string, 선택 — "en" 또는 "fr"입니다. 신청자에게 보이는 호스팅 페이지의 언어를 설정합니다. |
| metadata | object, 선택 — 고객님의 자체 참조 데이터입니다. 신청 ID, 테넌트 ID 등 결과와 웹훅에 변경 없이 그대로 되돌려 받고 싶은 값을 넣을 수 있습니다. |
결과
GET /v1/sessions/{id}/result — 응답 형식입니다.
웹훅 페이로드로도 동일한 형식이 전달되므로, 이 엔드포인트를 폴링할 일은 거의 없습니다.
| session_id | 생성하신 id입니다. |
|---|---|
| status | PENDING, IN_PROGRESS, VERIFIED, FAILED 또는 EXPIRED입니다. |
| environment | "sandbox" 또는 "production"이며, 세션을 생성한 키와 일치합니다. |
| person | 문서에서 읽은 필드: 이름, 생년월일, 문서 유형, 문서 발급 국가 및 관할, 주소. |
| checks | 검사마다 하나의 판정이 있습니다(아래 참조). 불투명한 단일 점수는 제공하지 않습니다. |
| confidence | 인증 전체에 대한 단일 종합 수치입니다. 얼굴 일치를 포함한 개별 검사는 고정된 판정 기준에 따라 여전히 각각 보고되며, 이 필드가 이를 대체하지 않습니다. |
| verified_until | VERIFIED 세션에서 결과가 유효한 것으로 간주되는 기간입니다. |
| failure_reason | FAILED 세션에 설정됩니다(예: FACE_MATCH_BELOW_THRESHOLD 또는 CANCELLED_BY_API). 그 외에는 null입니다. |
| metadata | 세션을 생성할 때 보낸 값이 변경 없이 그대로 반환됩니다. |
{
"session_id": "ses_9f2c1a",
"status": "VERIFIED",
"environment": "sandbox",
"person": {
"name": "Jordan Smith",
"dob": "1994-03-11",
"document_type": "drivers_licence",
"document_country": "CA",
"document_jurisdiction": "ON"
},
"checks": {
"document": "PASS",
"liveness": "PASS",
"antispoof": "PASS",
"face_match": "PASS"
},
"confidence": 88,
"verified_until": "2027-03-11T00:00:00Z",
"failure_reason": null,
"metadata": { "application_id": "app_9182" }
}Add-onchecks.document, checks.liveness, checks.antispoof, checks.face_match는 각각 PASS, FAIL 또는 SKIPPED로 확정됩니다. 감시 목록 스크리닝(checks.sanctions — CLEAR, MATCH 또는 SKIPPED)은 추가 기능이며 이를 켠 계정에만 표시됩니다.
세션 수명 주기
다섯 가지 상태, 하나의 경로.
세션은 스스로 앞으로 진행됩니다. 상태 머신을 직접 제어할 필요 없이 읽기만 하시면 됩니다.
| PENDING | 생성됨. 아직 아무도 verification_url을 열지 않았습니다. |
|---|---|
| IN_PROGRESS | 신청자가 링크를 열었고 촬영 흐름의 어딘가에 있습니다. |
| VERIFIED | 모든 검사가 실행되었고 결과가 준비되었습니다. 최종 상태이며, 결과 엔드포인트를 호출하거나 웹훅을 읽으세요. |
| FAILED | 하나 이상의 검사를 통과하지 못했습니다. failure_reason에서 사유를 확인할 수 있습니다. 출시 예정: 세션을 PENDING으로 되돌리는 재시도 기능. 그전까지는 FAILED를 최종 상태로 취급하고, 신청자가 다시 시도하려면 새 세션을 생성하세요. |
| EXPIRED | 제시간에 아무도 완료하지 않았습니다. 세션은 기본 시간(30분)이 지나면 자동으로 만료되며, 다시 시도하려면 새로 생성하세요. |
DELETE /v1/sessions/{id}는 PENDING 또는 IN_PROGRESS 상태의 세션을 조기에 취소합니다. 이미 VERIFIED, FAILED 또는 EXPIRED에 도달한 세션은 이미 종료되었으므로 취소할 수 없습니다.
오류
대비해야 할 사항입니다.
현재 코드로 대응할 만한 핵심 목록입니다. 전체 최신 오류 코드와 페이로드는 /docs의 라이브 OpenAPI에 문서화되어 있습니다.
| Status | Code | Meaning |
|---|---|---|
| 401 | UNAUTHORIZED | X-Api-Key 헤더가 없습니다. |
| 401 | INVALID_KEY_FORMAT | 키가 vk_sand_ 또는 vk_live_로 시작하지 않거나, 계정의 어떤 키와도 일치하지 않습니다. |
| 403 | FORBIDDEN | 키는 유효하지만 요청하신 세션이나 리소스에 대한 접근 권한이 없습니다. |
| 404 | NOT_FOUND | 해당 id의 세션, 자격 증명 또는 리소스가 존재하지 않습니다. |
| 409 | CONFLICT | 세션이 해당 작업을 허용하는 상태가 아닙니다. 예를 들어 이미 VERIFIED 상태인 세션을 취소하려는 경우입니다. |
| 422 | VALIDATION_ERROR | 필수 필드가 없거나 형식이 올바르지 않습니다. 예를 들어 return_url이 유효한 http 또는 https URL이 아닙니다. |
웹훅
서명, 전달, 재시도.
세션이 VERIFIED 또는 FAILED에 도달하면 ShieldID가 위에 문서화된 형태를 webhook_url로 POST합니다.
- 위의 결과 형태와 일치하는 JSON 본문을 담은 POST로 전달됩니다.
- 원본 요청 본문에 대한 HMAC-SHA256으로 서명되며 X-Bio-Signature 헤더로 전송됩니다. 페이로드를 신뢰하기 전에 웹훅 시크릿으로 검증하세요.
- 엔드포인트가 2xx 상태로 응답하지 않으면 선형 백오프로 최대 세 번 재시도합니다.
- 출시 예정: 해결되면 두 번째 웹훅을 전달하는 FAILED 세션 재시도 기능. 현재는 세션당 웹훅 하나를 기준으로 삼으세요.
- 여기의 필드 이름은 이 레퍼런스와 일치합니다. 실제로 도착하는 내용이 다르다면 이 페이지보다 라이브 페이로드를 신뢰하시고 저희에게 알려 주세요. 필드 목록은 API에 맞춰 관리되며, 그 반대가 아닙니다.
서명 확인하기
import crypto from "node:crypto";
function isValidShieldIdSignature(rawBody, signatureHeader, secret) {
const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
const provided = signatureHeader || "";
const a = Buffer.from(expected, "hex");
const b = Buffer.from(provided, "hex");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
// rawBody must be the exact, unparsed request body
app.post("/hooks/shieldid", express.raw({ type: "application/json" }), (req, res) => {
const ok = isValidShieldIdSignature(req.body, req.headers["x-bio-signature"], process.env.SHIELDID_WEBHOOK_SECRET);
if (!ok) return res.status(401).send("invalid signature");
const result = JSON.parse(req.body);
// result.session_id, result.status, result.checks, …
res.status(200).send("ok");
});멱등성 및 재시도
두 번 실행해도 안전한 핸들러를 만드세요.
세션 생성이나 웹훅 전달에는 아직 전용 멱등성 키가 없습니다.
- 재시도된 웹훅 전달이 같은 세션에 대해 두 번 이상 도착할 수 있습니다. 핸들러의 키를 session_id + status로 지정하고 결과 기록을 멱등하게 만드세요.
- 타임아웃이 발생했다고 해서 POST /v1/sessions를 무작정 재시도하지 마세요. 먼저 세션이 생성되었는지 확인하지 않으면 신청자 한 명에게 세션이 두 개 생길 수 있습니다.
- 세션 생성을 위한 전용 Idempotency-Key 헤더가 계획되어 있습니다.
출시 예정세션 생성 시 Idempotency-Key 지원
최신 정보 확인
이 레퍼런스는 변경됩니다. 변경 내역을 확인하세요.
필드 추가, 새로운 오류 코드, 엔드포인트 변경 사항은 이 페이지에 반영되기 전에 변경 내역에 먼저 공지됩니다.
문의
레퍼런스 FAQ.
다음
이 레퍼런스를 직접 활용해 보세요.
퀵스타트를 따라 sandbox 키 발급부터 인증된 세션, 서명된 웹훅까지 순서대로 진행해 보세요.