Complete passkey MFA enrollment
curl --request POST \
--url https://api.privy.io/v1/users/{user_id}/mfa/passkey/enrollment/verify \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/json' \
--header 'privy-app-id: <privy-app-id>' \
--header 'privy-user-token: <privy-user-token>' \
--data '
{
"credential": {
"id": "<string>",
"raw_id": "<string>",
"response": {
"client_data_json": "<string>",
"attestation_object": "<string>",
"authenticator_data": "<string>",
"transports": [
"<string>"
],
"public_key_algorithm": 123,
"public_key": "<string>"
},
"client_extension_results": {
"app_id": true,
"cred_props": {
"rk": true
},
"hmac_create_secret": true
},
"type": "public-key",
"authenticator_attachment": "<string>"
}
}
'HttpResponse<String> response = Unirest.post("https://api.privy.io/v1/users/{user_id}/mfa/passkey/enrollment/verify")
.header("privy-app-id", "<privy-app-id>")
.header("privy-user-token", "<privy-user-token>")
.header("Authorization", "Basic <encoded-value>")
.header("Content-Type", "application/json")
.body("{\n \"credential\": {\n \"id\": \"<string>\",\n \"raw_id\": \"<string>\",\n \"response\": {\n \"client_data_json\": \"<string>\",\n \"attestation_object\": \"<string>\",\n \"authenticator_data\": \"<string>\",\n \"transports\": [\n \"<string>\"\n ],\n \"public_key_algorithm\": 123,\n \"public_key\": \"<string>\"\n },\n \"client_extension_results\": {\n \"app_id\": true,\n \"cred_props\": {\n \"rk\": true\n },\n \"hmac_create_secret\": true\n },\n \"type\": \"public-key\",\n \"authenticator_attachment\": \"<string>\"\n }\n}")
.asString();const options = {
method: 'POST',
headers: {
'privy-app-id': '<privy-app-id>',
'privy-user-token': '<privy-user-token>',
Authorization: 'Basic <encoded-value>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
credential: {
id: '<string>',
raw_id: '<string>',
response: {
client_data_json: '<string>',
attestation_object: '<string>',
authenticator_data: '<string>',
transports: ['<string>'],
public_key_algorithm: 123,
public_key: '<string>'
},
client_extension_results: {app_id: true, cred_props: {rk: true}, hmac_create_secret: true},
type: 'public-key',
authenticator_attachment: '<string>'
}
})
};
fetch('https://api.privy.io/v1/users/{user_id}/mfa/passkey/enrollment/verify', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.privy.io/v1/users/{user_id}/mfa/passkey/enrollment/verify",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'credential' => [
'id' => '<string>',
'raw_id' => '<string>',
'response' => [
'client_data_json' => '<string>',
'attestation_object' => '<string>',
'authenticator_data' => '<string>',
'transports' => [
'<string>'
],
'public_key_algorithm' => 123,
'public_key' => '<string>'
],
'client_extension_results' => [
'app_id' => true,
'cred_props' => [
'rk' => true
],
'hmac_create_secret' => true
],
'type' => 'public-key',
'authenticator_attachment' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Basic <encoded-value>",
"Content-Type: application/json",
"privy-app-id: <privy-app-id>",
"privy-user-token: <privy-user-token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.privy.io/v1/users/{user_id}/mfa/passkey/enrollment/verify"
payload := strings.NewReader("{\n \"credential\": {\n \"id\": \"<string>\",\n \"raw_id\": \"<string>\",\n \"response\": {\n \"client_data_json\": \"<string>\",\n \"attestation_object\": \"<string>\",\n \"authenticator_data\": \"<string>\",\n \"transports\": [\n \"<string>\"\n ],\n \"public_key_algorithm\": 123,\n \"public_key\": \"<string>\"\n },\n \"client_extension_results\": {\n \"app_id\": true,\n \"cred_props\": {\n \"rk\": true\n },\n \"hmac_create_secret\": true\n },\n \"type\": \"public-key\",\n \"authenticator_attachment\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("privy-app-id", "<privy-app-id>")
req.Header.Add("privy-user-token", "<privy-user-token>")
req.Header.Add("Authorization", "Basic <encoded-value>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"token": "<string>",
"expires_at": 1,
"user": {
"id": "did:privy:cm3np4u9j001rc8b73seqmqqk",
"created_at": 1731974895,
"linked_accounts": [
{
"address": "[email protected]",
"type": "email",
"first_verified_at": 1674788927,
"latest_verified_at": 1674788927,
"verified_at": 1674788927
},
{
"type": "farcaster",
"fid": 4423,
"owner_address": "0xE6bFb4137F3A8C069F98cc775f324A84FE45FdFF",
"username": "payton",
"display_name": "payton ↑",
"bio": "engineering at /privy. building pixelpool.xyz, the first Farcaster video client. nyc. 👨💻🍎🏳️🌈 nf.td/payton",
"profile_picture": "https://supercast.mypinata.cloud/ipfs/QmNexfCxdnFzWdJqKVgrjd27UGLMexNaw5FXu1XKR3cQF7?filename=IMG_2799.png",
"profile_picture_url": "https://supercast.mypinata.cloud/ipfs/QmNexfCxdnFzWdJqKVgrjd27UGLMexNaw5FXu1XKR3cQF7?filename=IMG_2799.png",
"verified_at": 1740678402,
"first_verified_at": 1740678402,
"latest_verified_at": 1741194370
},
{
"type": "passkey",
"credential_id": "Il5vP-3Tm3hNmDVBmDlREgXzIOJnZEaiVnT-XMliXe-BufP9GL1-d3qhozk9IkZwQ_",
"authenticator_name": "1Password",
"public_key": "pQECAyYgASFYIKdGwx5XxZ/7CJJzT8d5L6jyLNQdTH7X+rSZdPJ9Ux/QIlggRm4OcJ8F3aB5zYz3T9LxLdDfGpWvYkHgS4A8tPz9CqE=",
"created_with_browser": "Chrome",
"created_with_os": "Mac OS",
"created_with_device": "Macintosh",
"enrolled_in_mfa": true,
"verified_at": 1741194420,
"first_verified_at": 1741194420,
"latest_verified_at": 1741194420
}
],
"mfa_methods": [
{
"type": "passkey",
"verified_at": 1741194420
}
],
"has_accepted_terms": true,
"is_guest": false
}
}Passkey
Complete passkey MFA enrollment
Enrolls a passkey in MFA using the WebAuthn registration response.
POST
/
v1
/
users
/
{user_id}
/
mfa
/
passkey
/
enrollment
/
verify
Complete passkey MFA enrollment
curl --request POST \
--url https://api.privy.io/v1/users/{user_id}/mfa/passkey/enrollment/verify \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/json' \
--header 'privy-app-id: <privy-app-id>' \
--header 'privy-user-token: <privy-user-token>' \
--data '
{
"credential": {
"id": "<string>",
"raw_id": "<string>",
"response": {
"client_data_json": "<string>",
"attestation_object": "<string>",
"authenticator_data": "<string>",
"transports": [
"<string>"
],
"public_key_algorithm": 123,
"public_key": "<string>"
},
"client_extension_results": {
"app_id": true,
"cred_props": {
"rk": true
},
"hmac_create_secret": true
},
"type": "public-key",
"authenticator_attachment": "<string>"
}
}
'HttpResponse<String> response = Unirest.post("https://api.privy.io/v1/users/{user_id}/mfa/passkey/enrollment/verify")
.header("privy-app-id", "<privy-app-id>")
.header("privy-user-token", "<privy-user-token>")
.header("Authorization", "Basic <encoded-value>")
.header("Content-Type", "application/json")
.body("{\n \"credential\": {\n \"id\": \"<string>\",\n \"raw_id\": \"<string>\",\n \"response\": {\n \"client_data_json\": \"<string>\",\n \"attestation_object\": \"<string>\",\n \"authenticator_data\": \"<string>\",\n \"transports\": [\n \"<string>\"\n ],\n \"public_key_algorithm\": 123,\n \"public_key\": \"<string>\"\n },\n \"client_extension_results\": {\n \"app_id\": true,\n \"cred_props\": {\n \"rk\": true\n },\n \"hmac_create_secret\": true\n },\n \"type\": \"public-key\",\n \"authenticator_attachment\": \"<string>\"\n }\n}")
.asString();const options = {
method: 'POST',
headers: {
'privy-app-id': '<privy-app-id>',
'privy-user-token': '<privy-user-token>',
Authorization: 'Basic <encoded-value>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
credential: {
id: '<string>',
raw_id: '<string>',
response: {
client_data_json: '<string>',
attestation_object: '<string>',
authenticator_data: '<string>',
transports: ['<string>'],
public_key_algorithm: 123,
public_key: '<string>'
},
client_extension_results: {app_id: true, cred_props: {rk: true}, hmac_create_secret: true},
type: 'public-key',
authenticator_attachment: '<string>'
}
})
};
fetch('https://api.privy.io/v1/users/{user_id}/mfa/passkey/enrollment/verify', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.privy.io/v1/users/{user_id}/mfa/passkey/enrollment/verify",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'credential' => [
'id' => '<string>',
'raw_id' => '<string>',
'response' => [
'client_data_json' => '<string>',
'attestation_object' => '<string>',
'authenticator_data' => '<string>',
'transports' => [
'<string>'
],
'public_key_algorithm' => 123,
'public_key' => '<string>'
],
'client_extension_results' => [
'app_id' => true,
'cred_props' => [
'rk' => true
],
'hmac_create_secret' => true
],
'type' => 'public-key',
'authenticator_attachment' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Basic <encoded-value>",
"Content-Type: application/json",
"privy-app-id: <privy-app-id>",
"privy-user-token: <privy-user-token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.privy.io/v1/users/{user_id}/mfa/passkey/enrollment/verify"
payload := strings.NewReader("{\n \"credential\": {\n \"id\": \"<string>\",\n \"raw_id\": \"<string>\",\n \"response\": {\n \"client_data_json\": \"<string>\",\n \"attestation_object\": \"<string>\",\n \"authenticator_data\": \"<string>\",\n \"transports\": [\n \"<string>\"\n ],\n \"public_key_algorithm\": 123,\n \"public_key\": \"<string>\"\n },\n \"client_extension_results\": {\n \"app_id\": true,\n \"cred_props\": {\n \"rk\": true\n },\n \"hmac_create_secret\": true\n },\n \"type\": \"public-key\",\n \"authenticator_attachment\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("privy-app-id", "<privy-app-id>")
req.Header.Add("privy-user-token", "<privy-user-token>")
req.Header.Add("Authorization", "Basic <encoded-value>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"token": "<string>",
"expires_at": 1,
"user": {
"id": "did:privy:cm3np4u9j001rc8b73seqmqqk",
"created_at": 1731974895,
"linked_accounts": [
{
"address": "[email protected]",
"type": "email",
"first_verified_at": 1674788927,
"latest_verified_at": 1674788927,
"verified_at": 1674788927
},
{
"type": "farcaster",
"fid": 4423,
"owner_address": "0xE6bFb4137F3A8C069F98cc775f324A84FE45FdFF",
"username": "payton",
"display_name": "payton ↑",
"bio": "engineering at /privy. building pixelpool.xyz, the first Farcaster video client. nyc. 👨💻🍎🏳️🌈 nf.td/payton",
"profile_picture": "https://supercast.mypinata.cloud/ipfs/QmNexfCxdnFzWdJqKVgrjd27UGLMexNaw5FXu1XKR3cQF7?filename=IMG_2799.png",
"profile_picture_url": "https://supercast.mypinata.cloud/ipfs/QmNexfCxdnFzWdJqKVgrjd27UGLMexNaw5FXu1XKR3cQF7?filename=IMG_2799.png",
"verified_at": 1740678402,
"first_verified_at": 1740678402,
"latest_verified_at": 1741194370
},
{
"type": "passkey",
"credential_id": "Il5vP-3Tm3hNmDVBmDlREgXzIOJnZEaiVnT-XMliXe-BufP9GL1-d3qhozk9IkZwQ_",
"authenticator_name": "1Password",
"public_key": "pQECAyYgASFYIKdGwx5XxZ/7CJJzT8d5L6jyLNQdTH7X+rSZdPJ9Ux/QIlggRm4OcJ8F3aB5zYz3T9LxLdDfGpWvYkHgS4A8tPz9CqE=",
"created_with_browser": "Chrome",
"created_with_os": "Mac OS",
"created_with_device": "Macintosh",
"enrolled_in_mfa": true,
"verified_at": 1741194420,
"first_verified_at": 1741194420,
"latest_verified_at": 1741194420
}
],
"mfa_methods": [
{
"type": "passkey",
"verified_at": 1741194420
}
],
"has_accepted_terms": true,
"is_guest": false
}
}Authorizations
Basic Auth header with your app ID as the username and your app secret as the password.
Headers
ID of your Privy app.
Access token or custom authentication JWT for the user the request acts on.
Minimum string length:
1Path Parameters
Body
application/json
Completes passkey MFA enrollment with a WebAuthn registration response.
WebAuthn registration response as defined by the Web Authentication specification.
Show child attributes
Show child attributes
Response
200 - application/json
Passkey MFA enrolled.
An MFA token and the current user after completing an MFA ceremony.
JWT proving the user completed MFA.
Minimum string length:
1Unix timestamp in seconds when the MFA token expires.
Required range:
x >= 0A Privy user object.
Show child attributes
Show child attributes
Example:
{
"id": "did:privy:cm3np4u9j001rc8b73seqmqqk",
"created_at": 1731974895,
"linked_accounts": [
{
"address": "[email protected]",
"type": "email",
"first_verified_at": 1674788927,
"latest_verified_at": 1674788927,
"verified_at": 1674788927
},
{
"type": "farcaster",
"fid": 4423,
"owner_address": "0xE6bFb4137F3A8C069F98cc775f324A84FE45FdFF",
"username": "payton",
"display_name": "payton ↑",
"bio": "engineering at /privy. building pixelpool.xyz, the first Farcaster video client. nyc. 👨💻🍎🏳️🌈 nf.td/payton",
"profile_picture": "https://supercast.mypinata.cloud/ipfs/QmNexfCxdnFzWdJqKVgrjd27UGLMexNaw5FXu1XKR3cQF7?filename=IMG_2799.png",
"profile_picture_url": "https://supercast.mypinata.cloud/ipfs/QmNexfCxdnFzWdJqKVgrjd27UGLMexNaw5FXu1XKR3cQF7?filename=IMG_2799.png",
"verified_at": 1740678402,
"first_verified_at": 1740678402,
"latest_verified_at": 1741194370
},
{
"type": "passkey",
"credential_id": "Il5vP-3Tm3hNmDVBmDlREgXzIOJnZEaiVnT-XMliXe-BufP9GL1-d3qhozk9IkZwQ_",
"authenticator_name": "1Password",
"public_key": "pQECAyYgASFYIKdGwx5XxZ/7CJJzT8d5L6jyLNQdTH7X+rSZdPJ9Ux/QIlggRm4OcJ8F3aB5zYz3T9LxLdDfGpWvYkHgS4A8tPz9CqE=",
"created_with_browser": "Chrome",
"created_with_os": "Mac OS",
"created_with_device": "Macintosh",
"enrolled_in_mfa": true,
"verified_at": 1741194420,
"first_verified_at": 1741194420,
"latest_verified_at": 1741194420
}
],
"mfa_methods": [
{
"type": "passkey",
"verified_at": 1741194420
}
],
"has_accepted_terms": true,
"is_guest": false
}
Was this page helpful?

