> For AI agents: [llms.txt](https://docs.trustedauth.com/llms.txt) provides a Markdown index of this documentation.

# External authentication with a second factor

Use this raw HTTP example when your application completes the first factor outside IDaaS and then uses the Authentication API to determine whether an IDaaS second factor is required.

Your application must verify the external first factor before starting this flow. Configure the Authentication API application's resource rule to use `EXTERNAL` as the first authentication step for the applicable risk level. The Authentication API does not perform the external authentication represented by this step.

The example assumes that the Authentication API application uses **Provided in the API** as its client IP source. Include the same end-user IP address in every request that can evaluate IP-based risk factors.

## Query the user's authenticators

- **Method:** `POST`
- **Path:** `/api/web/v2/authentication/users`
- **Content type:** `application/json`

```json
{
  "userId": "jsmith",
  "applicationId": "11111111-1111-1111-1111-111111111111",
  "clientIp": "<end-user-public-ip-address>"
}
```

The response identifies `EXTERNAL` and the second factors available to the user:

```json
{
  "authenticationTypes": ["EXTERNAL"],
  "availableSecondFactor": ["TOKENPUSH", "TOKEN", "OTP"],
  "token": "<external-authentication-token>"
}
```

## Complete the external first factor

- **Method:** `POST`
- **Path:** `/api/web/v1/authentication/users/authenticate/EXTERNAL/complete`
- **Authorization:** `Bearer <external-authentication-token>`
- **Content type:** `application/json`

```json
{
  "applicationId": "11111111-1111-1111-1111-111111111111",
  "clientIp": "<end-user-public-ip-address>"
}
```

If the resource rule requires a second factor, the response returns an intermediate token:

```json
{
  "authenticationCompleted": false,
  "token": "<first-factor-token>"
}
```

If no second factor is required, `authenticationCompleted` is `true`, and `token` contains the IDaaS authentication JWT:

```json
{
  "authenticationCompleted": true,
  "token": "<idaas-jwt>"
}
```

## Request the second-factor challenge

Select a value from `availableSecondFactor`. This example requests an OTP challenge.

- **Method:** `POST`
- **Path:** `/api/web/v2/authentication/users/authenticate/OTP`
- **Content type:** `application/json`

```json
{
  "applicationId": "11111111-1111-1111-1111-111111111111",
  "clientIp": "<end-user-public-ip-address>",
  "authToken": "<first-factor-token>"
}
```

Store the returned challenge token:

```json
{
  "authenticationCompleted": false,
  "token": "<second-factor-challenge-token>",
  "otpdeliveryType": "SMS"
}
```

## Complete the second factor

- **Method:** `POST`
- **Path:** `/api/web/v1/authentication/users/authenticate/OTP/complete`
- **Authorization:** `Bearer <second-factor-challenge-token>`
- **Content type:** `application/json`

```json
{
  "applicationId": "11111111-1111-1111-1111-111111111111",
  "response": "123456",
  "clientIp": "<end-user-public-ip-address>"
}
```

When the second factor succeeds, the response contains the IDaaS authentication JWT:

```json
{
  "firstName": "John",
  "lastName": "Smith",
  "authenticationCompleted": true,
  "token": "<idaas-jwt>"
}
```

For complete risk-context examples, including machine authentication, see [Risk-based authentication](/api/auth-api/rest-examples/risk-based-authentication.md).
