Skip to main content

Create a challenge for a passkey login

POST/v2/passkey-challenges
API version
v2
Request method
POST
Operation ID
user-create-passkey-challenge

The challenge is bound to the Origin header of the request.

Request​

No request parameters.

Responses​

Format
application/json
Description

The challenge has been created.

  • challengeIdstring (uuid)required
  • optionsobjectrequired

    Options for signing in with a passkey, as WebAuthn Level 3 PublicKeyCredentialRequestOptionsJSON‍. Pass the object unchanged to PublicKeyCredential.parseRequestOptionsFromJSON()‍ and the result as publicKey to navigator.credentials.get(). Send the resulting credential back as credential.toJSON()‍ together with the challengeId the options came with. Binary values are base64url-encoded without padding.

    • allowCredentialsarray of objectrequired

      The passkeys of the user for this relying party. Empty for the passkey login, so the browser offers every passkey it has for the relying party.

      • Array[

        A passkey of the user, as WebAuthn Level 3 PublicKeyCredentialDescriptorJSON‍.

        • *object

          A passkey of the user, as WebAuthn Level 3 PublicKeyCredentialDescriptorJSON‍.

          • idstringrequired

            The credential id, base64url-encoded without padding.

          • transportsarray of string

            How the browser can reach the authenticator, as reported at registration (internal, hybrid, usb, nfc, ble, smart-card).

            • Array[
              • *string
              ]
          • typestringrequired

            The credential type, always public-key.

        ]
    • challengestringrequired

      32 random bytes, base64url-encoded without padding. Can be used once.

    • extensionsobject
    • hintsarray of string

      Hints for the browser which authenticator to offer. Not set by this API.

      • Array[
        • *string
        ]
    • rpIdstringrequired

      The relying party, selected from the Origin header of the request that created the challenge.

    • timeoutintegerrequired

      Milliseconds until the challenge expires.

    • userVerificationstringrequired

      Always required; the authenticator has to verify the user (biometrics or device PIN).

Content-Type: application/json

{
"challengeId": "6a1f0b1e-7d0c-4a43-9c1f-4f6c9b0f7a11",
"options": {
"allowCredentials": [
{
"id": "AN29uP9UVfVZ1X0WLKg3zA",
"transports": [
"hybrid",
"internal"
],
"type": "public-key"
}
],
"challenge": "rcUa1634YUaCsBeasroTVudBb4jNSnKzTGzJ9EdLlrA",
"rpId": "mittwald.de",
"timeout": 300000,
"userVerification": "required"
}
}
{
"description": "A challenge for signing in or confirming an action with a passkey. Run `navigator.credentials.get()` with\n`options` and send `challengeId` together with the resulting `credential.toJSON()`. The challenge can be used\nonce.\n",
"properties": {
"challengeId": {
"example": "6a1f0b1e-7d0c-4a43-9c1f-4f6c9b0f7a11",
"format": "uuid",
"type": "string"
},
"options": {
"description": "Options for signing in with a passkey, as WebAuthn Level 3\n[`PublicKeyCredentialRequestOptionsJSON`](https://www.w3.org/TR/webauthn-3/#dictdef-publickeycredentialrequestoptionsjson).\nPass the object unchanged to\n[`PublicKeyCredential.parseRequestOptionsFromJSON()`](https://www.w3.org/TR/webauthn-3/#sctn-parseRequestOptionsFromJSON)\nand the result as `publicKey` to `navigator.credentials.get()`. Send the resulting credential back as\n[`credential.toJSON()`](https://www.w3.org/TR/webauthn-3/#dom-publickeycredential-tojson) together with the\n`challengeId` the options came with. Binary values are base64url-encoded without padding.\n",
"example": {
"allowCredentials": [
{
"id": "AN29uP9UVfVZ1X0WLKg3zA",
"transports": [
"hybrid",
"internal"
],
"type": "public-key"
}
],
"challenge": "rcUa1634YUaCsBeasroTVudBb4jNSnKzTGzJ9EdLlrA",
"rpId": "mittwald.de",
"timeout": 300000,
"userVerification": "required"
},
"properties": {
"allowCredentials": {
"description": "The passkeys of the user for this relying party. Empty for the passkey login, so the browser offers every\npasskey it has for the relying party.\n",
"items": {
"description": "A passkey of the user, as WebAuthn Level 3\n[`PublicKeyCredentialDescriptorJSON`](https://www.w3.org/TR/webauthn-3/#dictdef-publickeycredentialdescriptorjson).\n",
"example": {
"id": "AN29uP9UVfVZ1X0WLKg3zA",
"transports": [
"hybrid",
"internal"
],
"type": "public-key"
},
"properties": {
"id": {
"description": "The credential id, base64url-encoded without padding.",
"example": "AN29uP9UVfVZ1X0WLKg3zA",
"type": "string"
},
"transports": {
"description": "How the browser can reach the authenticator, as reported at registration (`internal`, `hybrid`, `usb`,\n`nfc`, `ble`, `smart-card`).\n",
"example": [
"hybrid",
"internal"
],
"items": {
"type": "string"
},
"type": "array"
},
"type": {
"description": "The credential type, always `public-key`.",
"example": "public-key",
"type": "string"
}
},
"required": [
"type",
"id"
],
"type": "object"
},
"type": "array"
},
"challenge": {
"description": "32 random bytes, base64url-encoded without padding. Can be used once.",
"example": "rcUa1634YUaCsBeasroTVudBb4jNSnKzTGzJ9EdLlrA",
"type": "string"
},
"extensions": {
"description": "WebAuthn Level 3\n[`AuthenticationExtensionsClientInputsJSON`](https://www.w3.org/TR/webauthn-3/#dictdef-authenticationextensionsclientinputsjson).\n",
"type": "object"
},
"hints": {
"description": "Hints for the browser which authenticator to offer. Not set by this API.",
"items": {
"type": "string"
},
"type": "array"
},
"rpId": {
"description": "The relying party, selected from the `Origin` header of the request that created the challenge.",
"example": "mittwald.de",
"type": "string"
},
"timeout": {
"description": "Milliseconds until the challenge expires.",
"example": 300000,
"type": "integer"
},
"userVerification": {
"description": "Always `required`; the authenticator has to verify the user (biometrics or device PIN).",
"example": "required",
"type": "string"
}
},
"required": [
"challenge",
"rpId",
"allowCredentials",
"timeout",
"userVerification"
],
"type": "object"
}
},
"required": [
"challengeId",
"options"
],
"type": "object"
}

Usage examples​

$ curl \
--fail \
--location \
-X POST \
-H "Authorization: Bearer $MITTWALD_API_TOKEN" \
https://api.mittwald.de/v2/passkey-challenges
import { MittwaldAPIV2Client } from "@mittwald/api-client";
import { assertStatus } from "@mittwald/api-client-commons";

const client = MittwaldAPIClient.newWithToken(process.env.MITTWALD_API_TOKEN);
const response = await client.user.createPasskeyChallenge({});

assertStatus(response, 201);

use \Mittwald\ApiClient\Generated\V2\Clients\User\CreatePasskeyChallenge\CreatePasskeyChallengeRequest;

$client = MittwaldAPIClient::newWithToken(getenv('MITTWALD_API_TOKEN'));

$request = (new CreatePasskeyChallengeRequest());
$response = $client->user()->createPasskeyChallenge($request);

var_dump($response->getBody();

On this page