Skip to content

Prepare passkey deletion

Delete passkeys from your vault and prepare a short-lived token that lets the browser signal local passkey removal.

Delete by explicit Passlock passkey IDs:

HTTP Request
POST https://api.passlock.dev/v2/{tenancyId}/passkeys/delete HTTP/1.1
Authorization: Bearer {apiKey}
Accept: application/json
Content-Type: application/json
{
"passkeyIds": ["passkey_123", "passkey_456"]
}

Or delete every passkey for one application user:

HTTP Request
POST https://api.passlock.dev/v2/{tenancyId}/passkeys/delete HTTP/1.1
Authorization: Bearer {apiKey}
Accept: application/json
Content-Type: application/json
{
"userId": "tenant-user-id"
}
HTTP Response
HTTP/1.1 202 Accepted
Content-Type: application/json
{
"_tag": "PreparedPasskeyDeletion",
"deletePasskeysToken": "opaque-random-token",
"expiresAt": 1770123593000,
"warnings": []
}

The request must include exactly one selector: passkeyIds or userId. Empty passkeyIds lists are invalid. Missing passkeys are returned as warnings when they do not prevent deletion.

Send only deletePasskeysToken to your frontend, then call @passlock/browser’s deletePasskeys helper. The browser helper exchanges the token with:

Token Exchange Request
POST https://api.passlock.dev/v2/{tenancyId}/passkeys/delete/exchange HTTP/1.1
Accept: application/json
Content-Type: application/json
{
"deletePasskeysToken": "opaque-random-token"
}
Token Exchange Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"_tag": "PasskeyDeletionInstructions",
"instructions": [
{
"rpId": "example.com",
"userId": "MTVkMTFmdHM1Yzg0bDN0anpieG9w",
"credentialId": "bW9wN3IzenE0enJ5OXVnZXoxOWF4"
}
],
"warnings": []
}

Prefer @passlock/server where possible:

backend/delete-passkeys.ts
import { Passlock } from "@passlock/server";
const passlock = new Passlock({ tenancyId, apiKey });
const result = await passlock.deletePasskeys({
passkeyIds: ["passkey_123"],
});