Skip to content
POST /auth/passkey/authentication/options

Request Body

cf_tokenstring

Cloudflare Turnstile token from the sign-in page.

Response Body

optionsobject
required·

A bare PublicKeyCredentialRequestOptionsJSON — pass it straight to navigator.credentials.get({ publicKey }). Note rpId is flat here, unlike the nested rp object on registration options.

allowCredentialsobject[]

Always empty — sign-in is usernameless, so the browser offers whichever discoverable credential it holds for this rpId. Naming credentials here would leak which accounts exist.

challengestring

base64url challenge. Single-use, stored server-side for 5 minutes under handle.

Example: qsNjZMVirtbhRzdVbqWzyBiP224DB-Bu0X3_JqJJTNQ
rpIdstring

The environment's APP_URL host.

Example: app.truto.one
timeoutnumber
Example: 60000
userVerificationstring
Example: required
Possible values:
required
handlestring

Opaque key the challenge is stored under. Echo it on authentication/verify.

curl -X POST 'https://api.truto.one/auth/passkey/authentication/options' \
  -H 'Authorization: Bearer <your_api_token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "cf_token": "your_cf_token"
}'
const body = {
  "cf_token": "your_cf_token"
};

const response = await fetch('https://api.truto.one/auth/passkey/authentication/options', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer <your_api_token>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(body),
});

const data = await response.json();
console.log(data);
import requests

url = "https://api.truto.one/auth/passkey/authentication/options"
headers = {
    "Authorization": "Bearer <your_api_token>",
    "Content-Type": "application/json",
}
params = {
}
payload = {
    "cf_token": "your_cf_token"
}

response = requests.post(url, headers=headers, params=params, json=payload)
print(response.json())