> ## Documentation Index
> Fetch the complete documentation index at: https://docs.authsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Flows overview

> Design multi-step authentication journeys in the Authsignal Portal and run them with the pre-built UI.

Flows let you design multi-step authentication journeys. You choose the steps a user goes through and how the journey branches for each user. Your backend starts the flow, Authsignal's [pre-built UI](https://docs.authsignal.com/implementation-options/prebuilt-ui/overview.md) runs it, and your backend checks the result.

![A flow with a verification step, a method branch, a second verification step and an optional passkey enrollment step](https://mintcdn.com/authsignal-23/wPTVXdR08lavcXQp/images/docs/flows/multi-step-sign-in-flow.png?fit=max\&auto=format\&n=wPTVXdR08lavcXQp\&q=85\&s=acbf229c2c60d0b9cbe095436adc53df)

A flow that verifies users, then asks users who didn't use a passkey for a second step

## Quickstart

**1. Create a Flows action**

On the [actions page](https://portal.authsignal.com/actions), select **New action**, enter a
name such as `signIn` and choose **Flows** as the type.

**2. Build and publish the flow**

Choose a template or start from scratch. Select **Publish** to make the flow live, then select **Test flow** to run it as a test user.

**3. Start the flow**

In your backend, call [Start Flow](https://docs.authsignal.com/sdks/server/flows.md#start-flow) with the action code, the user
and a `redirectUrl`. Then redirect the user to the `challengeUrl` in the response.

```ts Node.js theme={null}
const response = await authsignal.startFlow({
  actionCode: "signIn",
  user: {
    userId: "69904f34-8286-4f35-9484-006a5a22ea1a",
  },
  redirectUrl: "https://yourapp.com/callback",
});

const { challengeUrl } = response;
```

```csharp C# theme={null}
var request = new StartFlowRequest(
    ActionCode: "signIn",
    User: new UserLookup(UserId: "69904f34-8286-4f35-9484-006a5a22ea1a"),
    RedirectUrl: "https://yourapp.com/callback"
);

var response = await authsignal.StartFlow(request);

var challengeUrl = response.ChallengeUrl;
```

```java Java theme={null}
StartFlowRequest request = new StartFlowRequest();
request.actionCode = "signIn";
request.user = new UserLookup();
request.user.userId = "69904f34-8286-4f35-9484-006a5a22ea1a";
request.redirectUrl = "https://yourapp.com/callback";

StartFlowResponse response = authsignal.startFlow(request).get();

String challengeUrl = response.challengeUrl;
```

```ruby Ruby theme={null}
response = Authsignal.start_flow(
  action_code: "signIn",
  user: {
    user_id: "69904f34-8286-4f35-9484-006a5a22ea1a"
  },
  redirect_url: "https://yourapp.com/callback"
)

challenge_url = response[:challenge_url]
```

```python Python theme={null}
response = authsignal.start_flow(
    action_code="signIn",
    user={
        "userId": "69904f34-8286-4f35-9484-006a5a22ea1a"
    },
    redirect_url="https://yourapp.com/callback"
)

challenge_url = response["challenge_url"]
```

```php PHP theme={null}
$response = Authsignal::startFlow([
    'actionCode' => 'signIn',
    'user' => [
        'userId' => '69904f34-8286-4f35-9484-006a5a22ea1a'
    ],
    'redirectUrl' => 'https://yourapp.com/callback'
]);

$challengeUrl = $response['challengeUrl'];
```

```go Go theme={null}
userId := "69904f34-8286-4f35-9484-006a5a22ea1a"
redirectUrl := "https://yourapp.com/callback"

response, err := client.StartFlow(
    StartFlowRequest{
        ActionCode:  "signIn",
        User:        &UserLookup{UserId: &userId},
        RedirectUrl: &redirectUrl,
    },
)

challengeUrl := response.ChallengeUrl
```

**4. Verify the result**

When the flow ends, the pre-built UI sends the user to your `redirectUrl` with a
`challenge_token` query parameter. Pass it to [Verify Flow](https://docs.authsignal.com/sdks/server/flows.md#verify-flow), and
only treat the user as verified when the action state is `CHALLENGE_SUCCEEDED`.

```ts Node.js theme={null}
const response = await authsignal.verifyFlow({
  actionCode: "signIn",
  challengeToken,
});

const isVerified = response.action.state === "CHALLENGE_SUCCEEDED";
```

```csharp C# theme={null}
var request = new VerifyFlowRequest(
    ActionCode: "signIn",
    ChallengeToken: challengeToken
);

var response = await authsignal.VerifyFlow(request);

var isVerified = response.Action.State == FlowState.CHALLENGE_SUCCEEDED;
```

```java Java theme={null}
VerifyFlowRequest request = new VerifyFlowRequest();
request.actionCode = "signIn";
request.challengeToken = challengeToken;

VerifyFlowResponse response = authsignal.verifyFlow(request).get();

boolean isVerified = response.action.state == FlowState.CHALLENGE_SUCCEEDED;
```

```ruby Ruby theme={null}
response = Authsignal.verify_flow(
  action_code: "signIn",
  challenge_token: challenge_token
)

is_verified = response[:action][:state] == "CHALLENGE_SUCCEEDED"
```

```python Python theme={null}
response = authsignal.verify_flow(
    action_code="signIn",
    challenge_token=challenge_token
)

is_verified = response["action"]["state"] == "CHALLENGE_SUCCEEDED"
```

```php PHP theme={null}
$response = Authsignal::verifyFlow([
    'actionCode' => 'signIn',
    'challengeToken' => $challengeToken
]);

$isVerified = $response['action']['state'] === 'CHALLENGE_SUCCEEDED';
```

```go Go theme={null}
response, err := client.VerifyFlow(
    VerifyFlowRequest{
        ActionCode:     "signIn",
        ChallengeToken: challengeToken,
    },
)

isVerified := response.Action.State == FlowStateChallengeSucceeded
```

## Next steps

* [Enroll an authentication method](https://docs.authsignal.com/flows/use-cases/enroll-authentication-method.md)
* [Multi-step sign-in](https://docs.authsignal.com/flows/use-cases/multi-step-sign-in.md)
* [Risk-based sign-in](https://docs.authsignal.com/flows/use-cases/risk-based-sign-in.md)
* [Manage methods](https://docs.authsignal.com/flows/use-cases/manage-methods.md)
* [Server SDK Flows methods](https://docs.authsignal.com/sdks/server/flows.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.