<!-- llms.txt: https://workos.com/llms.txt -->

# Authentication Challenge

An object representing a Challenge of an Authentication Factor.

## Challenge Factor

Creates a Challenge for an Authentication Factor.

:::code-group

```bash language="curl" title="Request" tab="1"
curl --request POST \
  --url "https://api.workos.com/auth/factors/auth_factor_01FVYZ5QM8N98T9ME5BCB2BBMJ/challenge" \
  --header "Authorization: Bearer sk_example_123456789" \
  --header "Content-Type: application/json" \
  -d @- <<'BODY'
    {
        "sms_template": "Your verification code is {{code}}."
    }
BODY
```

```js language="js" title="Request" tab="1"
import { WorkOS } from '@workos-inc/node';

const workos = new WorkOS('sk_example_123456789');

const challenge = await workos.mfa.challengeFactor({
  authenticationFactorId: 'auth_factor_01FZ4TS14D1PHFNZ9GF6YD8M1F',
  smsTemplate: 'Your code is {{code}}',
});
```

```rb language="ruby" title="Request" tab="1"
require "workos"

WorkOS.configure do |config|
  config.api_key = "sk_example_123456789"
end

WorkOS.client.multi_factor_auth.challenge_factor(id: "auth_factor_01FVYZ5QM8N98T9ME5BCB2BBMJ")
```

```py language="python" title="Request" tab="1"
from workos import WorkOSClient

client = WorkOSClient(api_key="sk_example_123456789", client_id="client_123456789")

client.multi_factor_auth.challenge_factor(id_="auth_factor_01FVYZ5QM8N98T9ME5BCB2BBMJ")
```

```go language="go" title="Request" tab="1"
package main

import (
	"context"

	"github.com/workos/workos-go/v10"
)

func main() {
	client := workos.NewClient("sk_example_123456789")

	_, err := client.MultiFactorAuth().ChallengeFactor(context.Background(), "auth_factor_01FVYZ5QM8N98T9ME5BCB2BBMJ")
	if err != nil {
		panic(err)
	}
}
```

```php language="php" title="Request" tab="1"
<?php

use WorkOS\WorkOS;

$workos = new WorkOS(
    apiKey: "sk_example_123456789",
    clientId: "client_123456789",
);

$workos
    ->multiFactorAuth()
    ->challengeFactor(id: "auth_factor_01FVYZ5QM8N98T9ME5BCB2BBMJ");
```

```java language="java" title="Request" tab="1"
import com.workos.WorkOS;

WorkOS workos = new WorkOS("sk_example_123456789");

workos.multiFactorAuth.challengeFactor("auth_factor_01FVYZ5QM8N98T9ME5BCB2BBMJ");
```

```cs language="dotnet" title="Request" tab="1"
using WorkOS;

var client = new WorkOSClient(new WorkOSOptions {
    ApiKey = "sk_example_123456789",
    ClientId = "client_123456789",
});

await client.MultiFactorAuth.ChallengeFactorAsync("auth_factor_01FVYZ5QM8N98T9ME5BCB2BBMJ");
```

```rust language="rust" title="Request" tab="1"
use workos::Client;

#[tokio::main]
async fn main() -> Result<(), workos::Error> {
    let client = Client::builder()
        .api_key("sk_example_123456789")
        .client_id("client_123456789")
        .build();

    let _result = client
        .multi_factor_auth()
        .challenge_factor("auth_factor_01FVYZ5QM8N98T9ME5BCB2BBMJ")
        .await?;

    Ok(())
}
```

```json language="json" title="Response" tab="2"
{
  "object": "authentication_challenge",
  "id": "auth_challenge_01FVYZ5QM8N98T9ME5BCB2BBMJ",
  "expires_at": "2026-01-15T12:00:00.000Z",
  "code": "123456",
  "authentication_factor_id": "auth_factor_01FVYZ5QM8N98T9ME5BCB2BBMJ",
  "created_at": "2026-01-15T12:00:00.000Z",
  "updated_at": "2026-01-15T12:00:00.000Z"
}
```

:::

## Verify Challenge

Verifies an Authentication Challenge.

:::code-group

```bash language="curl" title="Request" tab="1"
curl --request POST \
  --url "https://api.workos.com/auth/challenges/auth_challenge_01FVYZ5QM8N98T9ME5BCB2BBMJ/verify" \
  --header "Authorization: Bearer sk_example_123456789" \
  --header "Content-Type: application/json" \
  -d @- <<'BODY'
    {
        "code": "123456"
    }
BODY
```

```js language="js" title="Request" tab="1"
import { WorkOS } from '@workos-inc/node';

const workos = new WorkOS('sk_example_123456789');

const { challenge, valid } = await workos.mfa.verifyChallenge({
  authenticationChallengeId: 'auth_challenge_01FVYZWQTZQ5VB6BC5MPG2EYC5',
  code: '123456',
});
```

```rb language="ruby" title="Request" tab="1"
require "workos"

WorkOS.configure do |config|
  config.api_key = "sk_example_123456789"
end

WorkOS.client.multi_factor_auth.verify_challenge(
  id: "auth_challenge_01FVYZ5QM8N98T9ME5BCB2BBMJ",
  code: "123456"
)
```

```py language="python" title="Request" tab="1"
from workos import WorkOSClient

client = WorkOSClient(api_key="sk_example_123456789", client_id="client_123456789")

client.multi_factor_auth.verify_challenge(
    id_="auth_challenge_01FVYZ5QM8N98T9ME5BCB2BBMJ", code="123456"
)
```

```go language="go" title="Request" tab="1"
package main

import (
	"context"

	"github.com/workos/workos-go/v10"
)

func main() {
	client := workos.NewClient("sk_example_123456789")

	_, err := client.MultiFactorAuth().VerifyChallenge(context.Background(), "auth_challenge_01FVYZ5QM8N98T9ME5BCB2BBMJ", &workos.MultiFactorAuthVerifyChallengeParams{
		Code: "123456",
	})
	if err != nil {
		panic(err)
	}
}
```

```php language="php" title="Request" tab="1"
<?php

use WorkOS\WorkOS;

$workos = new WorkOS(
    apiKey: "sk_example_123456789",
    clientId: "client_123456789",
);

$workos
    ->multiFactorAuth()
    ->verifyChallenge(
        id: "auth_challenge_01FVYZ5QM8N98T9ME5BCB2BBMJ",
        code: "123456",
    );
```

```java language="java" title="Request" tab="1"
import com.workos.WorkOS;
import com.workos.multifactorauth.MultiFactorAuthApi.VerifyChallengeOptions;

WorkOS workos = new WorkOS("sk_example_123456789");

VerifyChallengeOptions options = VerifyChallengeOptions.builder().code("123456").build();

workos.multiFactorAuth.verifyChallenge(
    "auth_challenge_01FVYZ5QM8N98T9ME5BCB2BBMJ", options);
```

```cs language="dotnet" title="Request" tab="1"
using WorkOS;

var client = new WorkOSClient(new WorkOSOptions {
    ApiKey = "sk_example_123456789",
    ClientId = "client_123456789",
});

await client.MultiFactorAuth.VerifyChallengeAsync("auth_challenge_01FVYZ5QM8N98T9ME5BCB2BBMJ",
                                                  new MultiFactorAuthVerifyChallengeOptions {
                                                      Code = "123456",
                                                  });
```

```rust language="rust" title="Request" tab="1"
use workos::Client;
use workos::multi_factor_auth::VerifyChallengeParams;

#[tokio::main]
async fn main() -> Result<(), workos::Error> {
    let client = Client::builder()
        .api_key("sk_example_123456789")
        .client_id("client_123456789")
        .build();

    let _result = client
        .multi_factor_auth()
        .verify_challenge(
            "auth_challenge_01FVYZ5QM8N98T9ME5BCB2BBMJ",
            VerifyChallengeParams {
                code: "123456".into(),
                ..Default::default()
            }
        )
        .await?;

    Ok(())
}
```

```json language="json" title="Response" tab="2"
{
  "challenge": {
    "object": "authentication_challenge",
    "id": "auth_challenge_01FVYZ5QM8N98T9ME5BCB2BBMJ",
    "expires_at": "2026-01-15T12:00:00.000Z",
    "code": "123456",
    "authentication_factor_id": "auth_factor_01FVYZ5QM8N98T9ME5BCB2BBMJ",
    "created_at": "2026-01-15T12:00:00.000Z",
    "updated_at": "2026-01-15T12:00:00.000Z"
  },
  "valid": true
}
```

:::

### authentication_challenge

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | "authentication_challenge" | Yes | Distinguishes the Authentication Challenge object. |
| `id` | string | Yes | The unique ID of the Authentication Challenge. |
| `expires_at` | string | No | The timestamp when the Challenge will expire. Does not apply to totp factors. |
| `code` | string | No | The one-time code for the challenge. |
| `authentication_factor_id` | string | Yes | The unique ID of the Authentication Factor the Challenge belongs to. |
| `created_at` | string | Yes | The timestamp when the Challenge was created. |
| `updated_at` | string | Yes | The timestamp when the Challenge was last updated. |

### POST /auth/factors/{id}/challenge

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `sms_template` | string | No | Optional template for SMS messages. Only applicable for `sms` Factors. Use the `{{code}}` token to inject the one-time code into the message. E.g., `Your Foo Corp one-time code is {{code}}.` |

#### Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The unique ID of the Authentication Factor to be challenged. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `authentication_challenge` | object | Distinguishes the authentication challenge object. |

### POST /auth/challenges/{id}/verify

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | string | Yes | The 6 digit code to be verified. |

#### Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The unique ID of the Authentication Challenge. |

#### Returns

| Field | Type | Description |
| --- | --- | --- |
| `challenge` | object | The relevant [Authentication Challenge](/reference/mfa/challenge). |
| `valid` | boolean | Indicates whether the code was correct. |