Learn how to start the login flow from your frontend.
While you can’t skip hitting your backend completely, you can change up the flow a little.When logging in, instead of going frontend → backend → Passkey API, you can let the frontend talk to the Passkey API directly.The /login/initialize and /login/finalize endpoints do not require you to send the secret API key.When using the Passkey API, after calling the /login/finalize endpoint as shown above, you will receive a JSON Web Token (JWT) in the response. This JWT contains the user_id and username that your backend sent back when the passkey was registered.To verify that the JWT was issued by the Passkey API, you can use the JWKS* located at /{tenant_id}/.well-known/jwks.json. The JWKS contains the public keys used for signing the JWTs.
* JWKS are a set of keys (random strings) that are intended to let you verify where a JWT comes from.For example, with the JWKS at /AcmeCorp/.well-known/jwks.json, you can check whether a JWT was issued by AcmeCorp or not.(There are libraries in most languages that help you do this!)
Once you have verified the JWT on your backend, you can exchange it for a session.This way, your backend doesn’t come into play until the user has successfully authenticated with a passkey.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Hanko","description":"Documentation for Hanko’s open-source authentication products. Build secure authentication with passkeys, passwords, MFA, social login, SSO, and push authentication.","colors":{"primary":"#6575FF","light":"#6575FF","dark":"#0D001D"},"logo":{"light":"https://mintcdn.com/hanko/cvvCniGfSDqJRest/logo/light.svg?fit=max\u0026auto=format\u0026n=cvvCniGfSDqJRest\u0026q=85\u0026s=c11abcf43f80ac4a882d948d9a697da6","dark":"https://mintcdn.com/hanko/cvvCniGfSDqJRest/logo/dark.svg?fit=max\u0026auto=format\u0026n=cvvCniGfSDqJRest\u0026q=85\u0026s=2cbd45a5f965459329fa577fe505b871"},"favicon":"https://mintcdn.com/hanko/nDll7gWf2olRVk-k/favicon.png?fit=max\u0026auto=format\u0026n=nDll7gWf2olRVk-k\u0026q=85\u0026s=0220747b414c9c1af17f71869d87269a","api":{"playground":{"display":"interactive"}},"background":{"image":"https://mintcdn.com/hanko/nDll7gWf2olRVk-k/images/background.png?fit=max\u0026auto=format\u0026n=nDll7gWf2olRVk-k\u0026q=85\u0026s=cb6d5948c52e06bab12e957123881b4b","decoration":"gradient","color":{"dark":"#000000"}},"navbar":{"links":[{"href":"https://discord.gg/tAG6RrRqJD","label":"Discord"}],"primary":{"type":"button","label":"Hanko Cloud Console","href":"https://cloud.hanko.io"}},"footer":{"socials":{"x":"https://x.com/hanko_io","github":"https://github.com/teamhanko","linkedin":"https://www.linkedin.com/company/teamhanko"}},"fonts":{"family":"Geist"},"icons":{"library":"fontawesome"},"integrations":{"plausible":{"domain":"docs.hanko.io"}},"errors":{"404":{"redirect":false}},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"thumbnails":{"fonts":{"family":"Geist"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"hanko","hasAudioNarration":false,"actualSubdomain":"hanko","customDomains":["docs.hanko.io"],"gitSource":{"type":"github","owner":"teamhanko","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae130142e7b9f2a4eb1451d","collectionId":"e51a69b0-9d1a-4cbb-828c-c20cc6c4b68c","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae130142e7b9f2a4eb1451d"},"feedback":{"thumbs":true,"edits":true,"issues":true},"entitlements":{},"buildId":"6ae130142e7b9f2a4eb1451d","clientVersion":"0.0.4054","searchFilterCounts":[{"language":"default","tag":"Hanko Docs","count":127},{"language":"default","tag":"Resources","count":68},{"language":"default","tag":"API reference","count":64},{"language":"default","tag":"Admin","count":49},{"language":"default","tag":"Guides","count":41},{"language":"default","tag":"Hanko Authenticator Docs","count":28},{"language":"default","tag":"Getting started","count":27},{"language":"default","tag":"Quickstarts","count":26},{"language":"default","tag":"Passkey API Docs","count":24},{"language":"default","tag":"API Reference","count":22}]},"assistantConfig":{"deflection":{"enabled":true,"email":"support@hanko.io"}},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"privacy":{"consentBanner":{"enabled":true}},"googleFontsInlined":true},"customCss":[],"page":{"pagePath":"passkey-api/client-first-login-flow","slug":"/passkey-api/client-first-login-flow","pageMetadata":{"title":"Client-first login flow","description":"Learn how to start the login flow from your frontend.","href":"/passkey-api/client-first-login-flow"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Learn how to start the login flow from your frontend.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={code:`code`,p:`p`,strong:`strong`,..._provideComponents(),...props.components},{Tip}=_components;if(!Tip)_missingMdxReference(`Tip`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`While you can’t skip hitting your backend completely, you can change up the flow a little.`}),`\n`,_jsx(_components.p,{children:`When logging in, instead of going frontend → backend → Passkey API, you can let the frontend talk to the Passkey API directly.`}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`/login/initialize`}),` and `,_jsx(_components.code,{children:`/login/finalize`}),` endpoints `,_jsx(_components.strong,{children:`do not require you to send the secret API key.`})]}),`\n`,_jsxs(_components.p,{children:[`When using the Passkey API, after calling the `,_jsx(_components.code,{children:`/login/finalize`}),` endpoint as shown above, you will receive a JSON Web Token (JWT) in the response. This JWT contains the `,_jsx(_components.code,{children:`user_id`}),` and `,_jsx(_components.code,{children:`username`}),` that your backend sent back when the passkey was registered.`]}),`\n`,_jsxs(_components.p,{children:[`To verify that the JWT was issued by the Passkey API, you can use the JWKS* located at `,_jsx(_components.code,{children:`/{tenant_id}/.well-known/jwks.json`}),`. The JWKS contains the public keys used for signing the JWTs.`]}),`\n`,_jsxs(Tip,{children:[_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`*`}),` JWKS are a set of keys (random strings) that are intended to let you verify where a JWT comes from.`]}),_jsxs(_components.p,{children:[`For example, with the JWKS at `,_jsx(_components.code,{children:`/AcmeCorp/.well-known/jwks.json`}),`, you can check whether a JWT was issued by AcmeCorp or not.`]}),_jsx(_components.p,{children:`(There are libraries in most languages that help you do this!)`})]}),`\n`,_jsx(_components.p,{children:`Once you have verified the JWT on your backend, you can exchange it for a session.`}),`\n`,_jsx(_components.p,{children:`This way, your backend doesn’t come into play until the user has successfully authenticated with a passkey.`})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Client-first login flow","description":"Learn how to start the login flow from your frontend.","href":"/passkey-api/client-first-login-flow"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"subdomain":"hanko","siteName":"Hanko","title":"Client-first login flow - Hanko","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2025-08-26T14:13:28.247Z","originalFileLocation":"passkey-api/client-first-login-flow.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Learn how to start the login flow from your frontend.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Hanko\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/hanko/E70FYFIuCUxDugor/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/hanko/E70FYFIuCUxDugor/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/hanko/E70FYFIuCUxDugor/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/hanko/E70FYFIuCUxDugor/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/hanko/E70FYFIuCUxDugor/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/hanko/E70FYFIuCUxDugor/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/hanko/E70FYFIuCUxDugor/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/hanko/E70FYFIuCUxDugor/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/hanko/E70FYFIuCUxDugor/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Client-first login flow - Hanko\">\u003cmeta data-mint-head property=\"og:description\" content=\"Learn how to start the login flow from your frontend.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Hanko\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.hanko.io/passkey-api/client-first-login-flow\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://hanko.mintlify.app/_mintlify/api/og/v2?division=Getting+started\u0026amp;title=Client-first+login+flow\u0026amp;description=Learn+how+to+start+the+login+flow+from+your+frontend.\u0026amp;theme=0019bde39b8e96d0b6d738b4\u0026amp;signature=4e5ad4eea1e4490ffcd580c88ee033618c35600b55cc171d896962855bbc8f4e\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Client-first login flow - Hanko\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Learn how to start the login flow from your frontend.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://hanko.mintlify.app/_mintlify/api/og/v2?division=Getting+started\u0026amp;title=Client-first+login+flow\u0026amp;description=Learn+how+to+start+the+login+flow+from+your+frontend.\u0026amp;theme=0019bde39b8e96d0b6d738b4\u0026amp;signature=4e5ad4eea1e4490ffcd580c88ee033618c35600b55cc171d896962855bbc8f4e\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/hanko/E70FYFIuCUxDugor/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Hanko\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#6575FF\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.hanko.io/passkey-api/client-first-login-flow\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/passkey-api/client-first-login-flow.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.hanko.io/#organization\",\"name\":\"Hanko\",\"url\":\"https://docs.hanko.io\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/hanko/cvvCniGfSDqJRest/logo/light.svg?fit=max\u0026auto=format\u0026n=cvvCniGfSDqJRest\u0026q=85\u0026s=c11abcf43f80ac4a882d948d9a697da6\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.hanko.io#website\",\"name\":\"Hanko\",\"url\":\"https://docs.hanko.io\",\"publisher\":{\"@id\":\"https://docs.hanko.io/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.hanko.io/passkey-api/client-first-login-flow#webpage\",\"url\":\"https://docs.hanko.io/passkey-api/client-first-login-flow\",\"name\":\"Client-first login flow\",\"description\":\"Learn how to start the login flow from your frontend.\",\"dateModified\":\"2025-08-26T14:13:28.247Z\",\"isPartOf\":{\"@id\":\"https://docs.hanko.io#website\"},\"breadcrumb\":{\"@id\":\"https://docs.hanko.io/passkey-api/client-first-login-flow#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.hanko.io/passkey-api/client-first-login-flow#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Getting started\",\"item\":\"https://docs.hanko.io/passkey-api/introduction\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Client-first login flow\",\"item\":\"https://docs.hanko.io/passkey-api/client-first-login-flow\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.hanko.io/passkey-api/client-first-login-flow#article\",\"headline\":\"Client-first login flow\",\"name\":\"Client-first login flow\",\"description\":\"Learn how to start the login flow from your frontend.\",\"url\":\"https://docs.hanko.io/passkey-api/client-first-login-flow\",\"mainEntityOfPage\":{\"@id\":\"https://docs.hanko.io/passkey-api/client-first-login-flow#webpage\"},\"dateModified\":\"2025-08-26T14:13:28.247Z\",\"publisher\":{\"@id\":\"https://docs.hanko.io/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.hanko.io#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Hanko\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Hanko","nav":{"global":null,"tabs":[{"tab":"Hanko Docs","pages":[{"title":"Hanko Docs","href":"/introduction"}]},{"tab":"Passkey API Docs","groups":[{"group":"Getting started","pages":[{"title":"Introduction to Passkey API","sidebarTitle":"Introduction","mode":"wide","href":"/passkey-api/introduction"},{"sidebarTitle":"Set up Passkey API project","title":"Setting up a Passkey API project on Hanko Cloud","href":"/passkey-api/setup-passkey-project"},{"title":"Example implementation","href":"/passkey-api/example-implementation"},{"title":"Passkey MFA","href":"/passkey-api/mfa"},{"title":"Example payment transaction","description":"Learn how to use passkeys to secure a payment transaction.","href":"/passkey-api/example-transaction"},{"title":"Client-first login flow","href":"/passkey-api/client-first-login-flow"}]},{"group":"Integrations","pages":[{"title":"JavaScript/TypeScript SDK","description":"A lean, type-safe, `fetch`-based API client for the Hanko Passkey API","href":"/passkey-api/js-sdk"}]},{"group":"Resources","pages":[{"title":"Examples","href":"/passkey-api/resources/examples"},{"title":"Tutorials","href":"/passkey-api/resources/tutorials"}]},{"group":"API Reference","pages":[{"group":"Signup","pages":[{"openapi":"openapi-passkeys post /{tenant_id}/registration/initialize","title":"Start Passkey Registration","href":"/passkey-api/reference/credentials/start-passkey-registration"},{"openapi":"openapi-passkeys post /{tenant_id}/registration/finalize","title":"Finish Passkey Registration","href":"/passkey-api/reference/credentials/finish-passkey-registration"}]},{"group":"Login","pages":[{"openapi":"openapi-passkeys post /{tenant_id}/login/initialize","title":"Start Login","href":"/passkey-api/reference/start-login"},{"openapi":"openapi-passkeys post /{tenant_id}/login/finalize","title":"Finish Login","href":"/passkey-api/reference/finish-login"}]},{"group":"Credentials","pages":[{"openapi":"openapi-passkeys get /{tenant_id}/credentials","title":"List Credentials","href":"/passkey-api/reference/credentials/list-credentials"},{"openapi":"openapi-passkeys patch /{tenant_id}/credentials/{credential_id}","title":"Update Credential","href":"/passkey-api/reference/credentials/update-credential"},{"openapi":"openapi-passkeys delete /{tenant_id}/credentials/{credential_id}","title":"Remove Credential","href":"/passkey-api/reference/remove-credential"}]},{"group":"Transactions","pages":[{"openapi":"openapi-passkeys post /{tenant_id}/transaction/initialize","title":"Initialize a transaction","href":"/passkey-api/reference/initialize-a-transaction"},{"openapi":"openapi-passkeys post /{tenant_id}/transaction/finalize","title":"Finalize transaction","href":"/passkey-api/reference/finalize-transaction"}]},{"group":"MFA","pages":[{"openapi":"openapi-passkeys post /{tenant_id}/mfa/login/initialize","title":"Start MFA Login","href":"/passkey-api/reference/credentials/start-mfa-login"},{"openapi":"openapi-passkeys post /{tenant_id}/mfa/login/finalize","title":"Finish MFA Login","href":"/passkey-api/reference/credentials/finish-mfa-login"},{"openapi":"openapi-passkeys post /{tenant_id}/mfa/registration/initialize","title":"Start MFA Registration","href":"/passkey-api/reference/credentials/start-mfa-registration"},{"openapi":"openapi-passkeys post /{tenant_id}/mfa/registration/finalize","title":"Finish MFA Registration","href":"/passkey-api/reference/credentials/finish-mfa-registration"}]},{"group":"Audit Logs","pages":[{"openapi":"openapi-passkeys get /{tenant_id}/audit_logs","title":"List audit log entries","href":"/passkey-api/reference/list-audit-logs"}]},{"openapi":"openapi-passkeys get /{tenant_id}/.well-known/jwks.json","title":"Well-known JWKS","href":"/passkey-api/reference/credentials/well-known-jwks"}]}]},{"tab":"Hanko Authenticator Docs","pages":[{"title":"Hanko Authenticator Docs","href":"/hanko-authenticator/introduction"}]}]},"basePath":"","title":"Client-first login flow - Hanko","buildId":"dpl_345ReqzYaAjzS9QpeJemsKdb7KDj","deploymentId":"dpl_345ReqzYaAjzS9QpeJemsKdb7KDj","dynamics":[],"chunks":[]}