跳至主要內容
ShieldID

API 參考文件

身分驗證 API 參考文件。

您可以呼叫的每個端點、會收到的每個欄位,以及 webhook 送達後該如何處理。若需確切的欄位型別,請以您自己 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 端點,另有一個託管頁面和一個公開的憑證檢查頁面,這兩者完全不是 JSON,您只需連結到它們即可。

位於 /v1 之下的 JSON 端點。
EndpointAuthWhat it does
POST /v1/sessionsX-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}/resultX-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 金鑰,因此可直接從瀏覽器呼叫。注意:目前的回應除了有效/無效的標記外,還包含被驗證者的姓名以及文件類型/國家,請勿將此連結提供給您不希望其看到這些資訊的第三方。
GET /v1/pricing/{country}X-Api-Key依兩位字母的 ISO 3166-1 國家代碼查詢各國定價。
提供給您連結的頁面,而非需要解析的 JSON。
/v/{session_id}託管的驗證頁面,即工作階段回傳的 verification_url。桌面版會顯示 QR code;掃描後,申請人的手機會開啟相同連結,以拍攝證件與自拍照。
/c/{session_id}針對單一已驗證工作階段的公開、免驗證憑證檢查頁面。注意:目前的回應除了有效/無效的標記外,還包含被驗證者的姓名以及文件類型/國家,請勿將此連結提供給您不希望其看到這些資訊的第三方。
/docs針對您帳戶 API 來源的即時互動式 OpenAPI 參考文件。

建立 session

POST /v1/sessions,完整流程。

請求內容,以及確切的回應內容。

bash
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" }
  }'

POST /v1/sessions — 請求欄位。
return_urlstring,必填 — 申請人完成後被導回的位置。必須是 http 或 https。
webhook_urlstring,必填 — 簽署後結果的傳送位置。請參閱下方的 Webhooks。
expected_namestring,必填 — 您預期出現在文件上的姓名,用於與證件實際內容交叉比對。
expected_dob / expected_addressstring,選填 — 若有提供,會與文件交叉比對;執行驗證時並非必填。
localestring,選填 — "en" 或 "fr"。設定申請人所見託管頁面的語言。
metadataobject,選填 — 您自己的參考資料,例如申請 ID、租戶 ID,或任何您希望在結果與 webhook 中原樣回傳的內容。

結果

GET /v1/sessions/{id}/result — 回應結構。

webhook payload 採用相同的結構,因此您幾乎不需要輪詢此端點。

頂層欄位。
session_id您所建立的 ID。
statusPENDING、IN_PROGRESS、VERIFIED、FAILED 或 EXPIRED。
environment"sandbox" 或 "production",與建立該工作階段的金鑰相符。
person從文件讀取的欄位:姓名、出生日期、文件類型、文件所屬國家與管轄區、地址。
checks每項檢查各有一個判定結果,請見下方說明。絕不會是單一而不透明的分數。
confidence驗證的單一整體數值。各項檢查(包括臉部比對)仍會依固定的判定門檻individually回報,此欄位並不會取代它們。
verified_until在 VERIFIED 工作階段上,結果被視為有效的期間。
failure_reason在 FAILED 工作階段上設定,例如 FACE_MATCH_BELOW_THRESHOLD 或 CANCELLED_BY_API;其他情況為 null。
metadata建立工作階段時您傳送的任何內容,原封不動回傳。
json
{
  "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)屬於附加功能,僅在啟用該功能的帳戶中出現。

工作階段生命週期

五種狀態,一條路徑。

工作階段會自行向前推進;您不需要驅動狀態機,只要讀取狀態即可。

status 值,依順序排列。
PENDING已建立。尚無人開啟 verification_url。
IN_PROGRESS申請人已開啟連結,目前處於拍攝流程中的某個步驟。
VERIFIED所有檢查皆已執行,結果已就緒。此為最終狀態,請呼叫結果端點或讀取 webhook。
FAILED至少有一項檢查未通過,failure_reason 會說明原因。即將推出:可將工作階段重設為 PENDING 的重試功能;在此之前,請將 FAILED 視為最終狀態,若申請人想再試一次,請建立新的工作階段。
EXPIRED無人在時限內完成。工作階段會在預設時間(30 分鐘)後自動過期;請建立新的工作階段重新嘗試。

DELETE /v1/sessions/{id} 可提前取消處於 PENDING 或 IN_PROGRESS 狀態的工作階段。已達到 VERIFIED、FAILED 或 EXPIRED 的工作階段無法取消,因為它已經結束了。

錯誤

需要預先規劃的事項。

這是目前值得依據來撰寫程式的精簡清單。完整且最新的錯誤碼與回應內容,記載於 /docs 的線上 OpenAPI 中。

HTTP 狀態碼、錯誤碼及其意義。
StatusCodeMeaning
401UNAUTHORIZED缺少 X-Api-Key 標頭。
401INVALID_KEY_FORMAT金鑰不是以 vk_sand_ 或 vk_live_ 開頭,或與帳戶中的任何金鑰都不相符。
403FORBIDDEN金鑰有效,但無權存取您所請求的工作階段或資源。
404NOT_FOUND找不到具有該 id 的工作階段、憑證或資源。
409CONFLICT工作階段目前的狀態不允許執行此操作,例如取消一個已經是 VERIFIED 的工作階段。
422VALIDATION_ERROR缺少必要欄位或格式不正確,例如 return_url 不是有效的 http 或 https URL。

Webhooks

簽署、送達、重試。

當工作階段達到 VERIFIED 或 FAILED 時,ShieldID 會以 POST 將上述格式的內容傳送至您的 webhook_url。

  • 以 POST 送達,內文為符合上述結果格式的 JSON。
  • 以 HMAC-SHA256 對原始請求內文簽署,並透過 X-Bio-Signature 標頭傳送。在信任內容之前,請先以您的 webhook 密鑰驗證。
  • 若您的端點未回應 2xx 狀態碼,最多會以線性退避方式重試三次。
  • 即將推出:FAILED 工作階段的重試功能,在重試完成後會送出第二個 webhook。目前請以每個工作階段一個 webhook 為準。
  • 此處的欄位名稱與本參考文件一致。若實際收到的內容不同,請以線上實際內容為準,並告知我們;欄位清單是配合 API 而更新,而非反過來。

驗證簽章

javascript
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");
});

冪等性與重試

請建置重複執行也安全的處理程式。

目前在建立工作階段或 webhook 送達時,尚無專用的冪等性金鑰。

  • 重試的 webhook 可能會針對同一個工作階段重複送達多次。請以 session_id + status 作為處理程式的鍵值,並讓寫入結果的操作具備冪等性。
  • 逾時時請勿盲目重試 POST /v1/sessions,請先確認工作階段是否已建立,否則同一位申請人可能會產生兩個工作階段。
  • 已規劃在建立工作階段時提供專用的 Idempotency-Key 標頭。

即將推出建立工作階段時支援 Idempotency-Key

掌握最新動態

本參考文件會持續變動,請留意變更記錄。

欄位新增、新的錯誤碼與端點變更,會先在變更記錄中公告,之後才會更新到此處。

常見問題

參考文件常見問題。

下一步

將本參考文件付諸實作。

請依照快速入門的順序,從 sandbox 金鑰一路完成已驗證的工作階段與已簽署的 webhook。