Passkeys
Thogits supports passkeys (WebAuthn) for passwordless authentication. Users can register hardware security keys, platform authenticators (Touch ID, Windows Hello), or cross-device passkeys stored in password managers.
Registration Flow
Section titled “Registration Flow”- Begin: Call the registration begin endpoint to get a WebAuthn challenge.
- Create credential: Pass the challenge to
navigator.credentials.create()in the browser. - Complete: Send the credential response and a name for the passkey to the complete endpoint.
POST /auth/passkey/register/begin
Section titled “POST /auth/passkey/register/begin”Start passkey registration. Returns a WebAuthn CreationChallengeResponse to pass to the browser’s credential API.
Auth required: Yes
curl -X POST https://app.thogits.com/api/auth/passkey/register/begin \ -b cookies.txt -c cookies.txtResponse (200): A WebAuthn CreationChallengeResponse object containing the challenge, relying party info, and user info. Pass this directly to navigator.credentials.create({ publicKey: response }).
POST /auth/passkey/register/complete
Section titled “POST /auth/passkey/register/complete”Complete passkey registration with the credential created by the browser.
Auth required: Yes
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | A human-readable name for this passkey (e.g., “MacBook Touch ID”) |
credential | object | Yes | The PublicKeyCredential response from navigator.credentials.create() |
// Browser-side exampleconst beginResponse = await fetch('/api/auth/passkey/register/begin', { method: 'POST', credentials: 'include',});const options = await beginResponse.json();
const credential = await navigator.credentials.create({ publicKey: options });
await fetch('/api/auth/passkey/register/complete', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'MacBook Touch ID', credential: credential, }),});Response (200):
{"message": "Passkey registered"}Authentication Flow
Section titled “Authentication Flow”- Begin: Call the authentication begin endpoint with the user’s email.
- Get assertion: Pass the challenge to
navigator.credentials.get()in the browser. - Complete: Send the assertion response to the complete endpoint.
POST /auth/passkey/auth/begin
Section titled “POST /auth/passkey/auth/begin”Start passkey authentication. Returns a WebAuthn RequestChallengeResponse.
Auth required: No
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | The user’s email address |
curl -X POST https://app.thogits.com/api/auth/passkey/auth/begin \ -H "Content-Type: application/json" \ -b cookies.txt -c cookies.txt \ -d '{"email": "user@example.com"}'Response (200): A WebAuthn RequestChallengeResponse object. Pass this to navigator.credentials.get({ publicKey: response }).
POST /auth/passkey/auth/complete
Section titled “POST /auth/passkey/auth/complete”Complete passkey authentication with the browser’s assertion response.
Auth required: No
Request body: The PublicKeyCredential response from navigator.credentials.get().
// Browser-side exampleconst beginResponse = await fetch('/api/auth/passkey/auth/begin', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'user@example.com' }),});const options = await beginResponse.json();
const assertion = await navigator.credentials.get({ publicKey: options });
const authResponse = await fetch('/api/auth/passkey/auth/complete', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(assertion),});const userInfo = await authResponse.json();Response (200): The UserInfo object (login complete, session cookie set).
Managing Passkeys
Section titled “Managing Passkeys”GET /auth/passkeys
Section titled “GET /auth/passkeys”List all registered passkeys for the current user.
Auth required: Yes
curl https://app.thogits.com/api/auth/passkeys \ -b cookies.txt -c cookies.txtResponse (200):
[ { "credential_id": "abc123def456", "name": "MacBook Touch ID", "created_at": "2025-01-15T10:00:00Z" }, { "credential_id": "ghi789jkl012", "name": "YubiKey 5", "created_at": "2025-01-20T14:30:00Z" }]DELETE /auth/passkeys/{credential_id}
Section titled “DELETE /auth/passkeys/{credential_id}”Delete a registered passkey.
Auth required: Yes
curl -X DELETE https://app.thogits.com/api/auth/passkeys/abc123def456 \ -b cookies.txt -c cookies.txtResponse (200):
{"message": "Passkey deleted"}Errors:
| Status | Cause |
|---|---|
| 404 | Passkey not found or does not belong to the current user |