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,您只需連結到它們即可。
| 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 金鑰,因此可直接從瀏覽器呼叫。注意:目前的回應除了有效/無效的標記外,還包含被驗證者的姓名以及文件類型/國家,請勿將此連結提供給您不希望其看到這些資訊的第三方。 |
| GET /v1/pricing/{country} | X-Api-Key | 依兩位字母的 ISO 3166-1 國家代碼查詢各國定價。 |
| /v/{session_id} | 託管的驗證頁面,即工作階段回傳的 verification_url。桌面版會顯示 QR code;掃描後,申請人的手機會開啟相同連結,以拍攝證件與自拍照。 |
|---|---|
| /c/{session_id} | 針對單一已驗證工作階段的公開、免驗證憑證檢查頁面。注意:目前的回應除了有效/無效的標記外,還包含被驗證者的姓名以及文件類型/國家,請勿將此連結提供給您不希望其看到這些資訊的第三方。 |
| /docs | 針對您帳戶 API 來源的即時互動式 OpenAPI 參考文件。 |
建立 session
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,必填 — 簽署後結果的傳送位置。請參閱下方的 Webhooks。 |
| expected_name | string,必填 — 您預期出現在文件上的姓名,用於與證件實際內容交叉比對。 |
| expected_dob / expected_address | string,選填 — 若有提供,會與文件交叉比對;執行驗證時並非必填。 |
| locale | string,選填 — "en" 或 "fr"。設定申請人所見託管頁面的語言。 |
| metadata | object,選填 — 您自己的參考資料,例如申請 ID、租戶 ID,或任何您希望在結果與 webhook 中原樣回傳的內容。 |
結果
GET /v1/sessions/{id}/result — 回應結構。
webhook payload 採用相同的結構,因此您幾乎不需要輪詢此端點。
| session_id | 您所建立的 ID。 |
|---|---|
| status | PENDING、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 | 建立工作階段時您傳送的任何內容,原封不動回傳。 |
{
"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 | 所有檢查皆已執行,結果已就緒。此為最終狀態,請呼叫結果端點或讀取 webhook。 |
| 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。 |
Webhooks
簽署、送達、重試。
當工作階段達到 VERIFIED 或 FAILED 時,ShieldID 會以 POST 將上述格式的內容傳送至您的 webhook_url。
- 以 POST 送達,內文為符合上述結果格式的 JSON。
- 以 HMAC-SHA256 對原始請求內文簽署,並透過 X-Bio-Signature 標頭傳送。在信任內容之前,請先以您的 webhook 密鑰驗證。
- 若您的端點未回應 2xx 狀態碼,最多會以線性退避方式重試三次。
- 即將推出:FAILED 工作階段的重試功能,在重試完成後會送出第二個 webhook。目前請以每個工作階段一個 webhook 為準。
- 此處的欄位名稱與本參考文件一致。若實際收到的內容不同,請以線上實際內容為準,並告知我們;欄位清單是配合 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");
});冪等性與重試
請建置重複執行也安全的處理程式。
目前在建立工作階段或 webhook 送達時,尚無專用的冪等性金鑰。
- 重試的 webhook 可能會針對同一個工作階段重複送達多次。請以 session_id + status 作為處理程式的鍵值,並讓寫入結果的操作具備冪等性。
- 逾時時請勿盲目重試 POST /v1/sessions,請先確認工作階段是否已建立,否則同一位申請人可能會產生兩個工作階段。
- 已規劃在建立工作階段時提供專用的 Idempotency-Key 標頭。
即將推出建立工作階段時支援 Idempotency-Key
常見問題