diff --git a/en/asgardeo/requirements.txt b/en/asgardeo/requirements.txt index 9d5d5819e6..1d2365dd09 100644 --- a/en/asgardeo/requirements.txt +++ b/en/asgardeo/requirements.txt @@ -12,6 +12,6 @@ mkdocs-exclude==1.0.2 markdown-include==0.8.1 jinja2==3.1.6 mkdocs-glightbox==0.3.4 -mkdocs-include-markdown-plugin==6.0.0 +mkdocs-include-markdown-plugin>=6.0.0 mkdocs-macros-plugin==1.2.0 mkdocs-exclude==1.0.2 diff --git a/en/identity-server/next/docs/guides/flows/flow-execution-api.md b/en/identity-server/next/docs/guides/flows/flow-execution-api.md new file mode 100644 index 0000000000..8f8554f5c0 --- /dev/null +++ b/en/identity-server/next/docs/guides/flows/flow-execution-api.md @@ -0,0 +1 @@ +{% include "../../../../../includes/guides/flows/flow-execution-api.md" %} diff --git a/en/identity-server/next/docs/guides/flows/flow-execution-components.md b/en/identity-server/next/docs/guides/flows/flow-execution-components.md new file mode 100644 index 0000000000..aa51500933 --- /dev/null +++ b/en/identity-server/next/docs/guides/flows/flow-execution-components.md @@ -0,0 +1 @@ +{% include "../../../../../includes/guides/flows/flow-execution-components.md" %} diff --git a/en/identity-server/next/mkdocs.yml b/en/identity-server/next/mkdocs.yml index 60ddf0aee3..00375ed705 100644 --- a/en/identity-server/next/mkdocs.yml +++ b/en/identity-server/next/mkdocs.yml @@ -716,6 +716,8 @@ nav: - Self Registration: guides/flows/self-registration.md - Password Recovery: guides/flows/password-recovery.md - Invited User Registration: guides/flows/invited-user-registration.md + - Use the Flow Execution API: guides/flows/flow-execution-api.md + - Understand Flow Execution components: guides/flows/flow-execution-components.md - Troubleshooting: guides/flows/troubleshooting.md - User self-service: - User self-service: guides/user-self-service/index.md diff --git a/en/identity-server/next/requirements.txt b/en/identity-server/next/requirements.txt index 750492e9b8..596ed577d4 100644 --- a/en/identity-server/next/requirements.txt +++ b/en/identity-server/next/requirements.txt @@ -11,4 +11,4 @@ mkdocs-exclude==1.0.2 markdown-include==0.8.1 jinja2==3.1.6 mkdocs-glightbox==0.3.4 -mkdocs-include-markdown-plugin==6.0.0 \ No newline at end of file +mkdocs-include-markdown-plugin>=6.0.0 \ No newline at end of file diff --git a/en/includes/guides/flows/flow-execution-api.md b/en/includes/guides/flows/flow-execution-api.md new file mode 100644 index 0000000000..50aee1a2f9 --- /dev/null +++ b/en/includes/guides/flows/flow-execution-api.md @@ -0,0 +1,222 @@ +# Use the Flow Execution API + +Use the Flow Execution API to run user journeys that you design in the Flow Builder of {{product_name}} directly from your client application. The API returns every step in the flow so that you can render the right experience without embedding the hosted Flow Runner UI. + +!!! info + The Flow Execution API is exposed at `{{base_path}}/api/server/v1/flow/execute`. This endpoint is open and does not require an authorization header. Always call it over HTTPS to safeguard the flow data exchanged. + +The API drives the flow in a loop: + +1. Start the flow by creating a new execution instance. +2. Interpret the `type` in each response and guide the user through the required step. +3. Post the user input or action result back to the same endpoint until the server returns `flowStatus: COMPLETE`. + +## Before you begin + +- [Build and enable the flow]({{base_path}}/guides/flows/build-a-flow/) that you want to expose through your app. +- Decide how your client persists the `flowId` between requests. Treat it as sensitive data because anyone with the `flowId` can continue the flow. + +## Start a flow execution + +Call `POST /flow/execute` with the `flowType` of the flow that should be executed. + +=== "Sample request" + + ```bash + curl --location '{{api_base_path}}/flow/execute' \ + --header 'Content-Type: application/json' \ + --data '{ + "flowType": "" + }' + ``` + +=== "Example request" + + ```bash + curl --location 'https://localhost:9443/api/server/v1/flow/execute' \ + --header 'Content-Type: application/json' \ + --data '{ + "flowType": "REGISTRATION" + }' + ``` + +The value for `flowType` must match a flow that is enabled in your tenant. + +| `flowType` value | Description | +|------------------|-------------| +| `REGISTRATION` | Self-registration flow. | +| `PASSWORD_RECOVERY` | Password recovery flow. | +| `INVITED_USER_REGISTRATION` | Invite user to register flow. | + +=== "Example response" + + ```json + { + "flowId": "c8e06de8-7123-44ac-8209-02be5b55387e", + "flowType": "REGISTRATION", + "flowStatus": "INCOMPLETE", + "type": "VIEW", + "data": { + "components": [ + { + "id": "form_1", + "type": "FORM", + "components": [ + { + "id": "email", + "type": "INPUT", + "variant": "EMAIL", + "config": { + "identifier": "email", + "label": "Email", + "required": true + } + }, + { + "id": "password", + "type": "INPUT", + "variant": "PASSWORD", + "config": { + "identifier": "password", + "label": "Password", + "required": true + } + }, + { + "id": "submit", + "type": "BUTTON", + "actionId": "submit-registration", + "variant": "PRIMARY", + "config": { + "text": "Continue" + } + } + ] + } + ], + "requiredParams": [ + "email", + "password" + ] + } + } + ``` + +- `flowId` uniquely identifies the execution instance. Persist it securely and include it in every subsequent call to the API. +- `flowStatus` indicates the current status of the flow. Valid values are `INCOMPLETE` and `COMPLETE`. +- `type` determines how your client should proceed. The `data` object contains the payload that is specific to the `type`. +- `components` describe the UI blueprint for the step. See [Understand Flow Execution components]({{base_path}}/guides/flows/flow-execution-components/) for details. + +### Response types + +| `type` | When you receive it | Expected client action | Typical data fields | +|--------|---------------------|------------------------|---------------------| +| `VIEW` | The server needs the user to interact with a UI form, list, or confirmation step. | Render the view described in `data.components`, capture user input, and send it back with the provided action identifier. | `components`, `requiredParams` | +| `REDIRECTION` | A third-party system must complete part of the flow (for example, identity verification or payment). | Redirect the browser or web view to `data.url` and resume the flow from your callback endpoint. | `url` | +| `WEBAUTHN` | The user must complete a WebAuthn ceremony. | Call `navigator.credentials.{create|get}` with the information in `data.publicKeyCredentialCreation` or `data.publicKeyCredentialRequest`, then submit the encoded response. | `publicKeyCredentialCreation` | +| `INTERNAL_PROMPT` | The client app, not the end user, must respond. | Call the API with the requested parameters. | `requiredParams` | + +## Continue a flow execution + +After executing the user action, call the same endpoint with the `flowId` and the data that corresponds to the step you just completed. + +### Submit a view + +When the response `type` is `VIEW`, locate the component that exposes an `actionId` (for example, the primary button) and use that identifier when you submit the user's input. + +```bash +curl --location '{{api_base_path}}/flow/execute' \ +--header 'Content-Type: application/json' \ +--data '{ + "flowId": "c8e06de8-7123-44ac-8209-02be5b55387e", + "actionId": "submit-registration", + "params": { + "email": "sasha@example.com", + "password": "MyP@ssw0rd!" + } +}' +``` + +- If the API returns validation `messages`, render them in your UI and prompt the user to correct the input before resubmitting. + +### Resume after a redirect + +When you receive `type: "REDIRECTION"`: + +1. Redirect the user agent to `data.url`. +2. Handle the callback at the `returnUrl` that you registered in Flow Builder. The callback contains the `flowId` (and any provider-specific data such as `code` or `state`). +3. Call `/flow/execute` with the same `flowId`, the proper `actionId`, and the callback parameters in the `params` payload. + +```json +{ + "flowId": "5f31ce20-872d-4334-8f9f-3572710dbc57", + "actionId": "federation-complete", + "params": { + "code": "4/0AfJohX...", + "state": "g5kZMl" + } +} +``` + +### Complete a WebAuthn ceremony + +For `type: "WEBAUTHN"`: + +1. Extract `data.publicKeyCredentialCreation`. +2. Call the WebAuthn browser APIs. +3. Base64url-encode the resulting credential and post it back in the `params` object under the key listed in `requiredParams`. + +```json +{ + "flowId": "5f31ce20-872d-4334-8f9f-3572710dbc57", + "actionId": "passkey-finish", + "params": { + "tokenResponse": "eyJpZCI6IjR..." + } +} +``` + +### Handle internal prompts + +For `type: "INTERNAL_PROMPT"`, inspect `data.requiredParams` to determine the values you must provide. This type is typically used for steps such as sending a magic link or triggering an action. + +```json +{ + "flowId": "5f31ce20-872d-4334-8f9f-3572710dbc57", + "actionId": "send-notification", + "params": { + "origin": "mobile-app", + "deviceId": "3e83f937-4ad0-4a67-a920-7e5af338c9ed" + } +} +``` + +## Complete a flow + +The API signals the outcome in `flowStatus`. + +- `COMPLETE`: The flow finished successfully. The `data` object contains the outcome of the flow (for example, a `userId` or `resetTicket`). Use it to move the application forward. +- `INCOMPLETE`: More steps remain. Continue looping. + +```json +{ + "flowId": "5f31ce20-872d-4334-8f9f-3572710dbc57", + "flowStatus": "COMPLETE", + "flowType": "REGISTRATION", + "data": { + "userId": "00d9b675-9da3-4fa6-9ef4-1a61ac6e9788" + } +} +``` + +## Error handling and resilience + +- Always guard the `flowId` and never log it in plain text. +- Use exponential backoff for transient network errors. Do not retry requests that returned validation errors. +- Capture the `messages` array and present it to the user for troubleshooting. + +## Next steps + +- Review the flow-specific guides for additional design examples: [Self-registration]({{base_path}}/guides/flows/self-registration/), [Password recovery]({{base_path}}/guides/flows/password-recovery/), and [Invited user registration]({{base_path}}/guides/flows/invited-user-registration/). +- Dive deeper into the response schema in [Understand Flow Execution components]({{base_path}}/guides/flows/flow-execution-components/). +- If you need to embed the hosted UI instead of building your own components, see [Build a flow]({{base_path}}/guides/flows/build-a-flow/). diff --git a/en/includes/guides/flows/flow-execution-components.md b/en/includes/guides/flows/flow-execution-components.md new file mode 100644 index 0000000000..9820af3d35 --- /dev/null +++ b/en/includes/guides/flows/flow-execution-components.md @@ -0,0 +1,67 @@ +# Understand Flow Execution components + +When the Flow Execution API returns `type: "VIEW"`, the response includes a `data.components` array. Each entry describes how your client should render the current step in the flow. + +## Component structure + +Every component shares the following core properties: + +| Field | Description | +|-------|-------------| +| `id` | Stable identifier of the component within the current step. | +| `type` | The UI element category (for example, `FORM`, `INPUT`, `BUTTON`, `TYPOGRAPHY`, or `RICH_TEXT`). | +| `variant` | Optional modifier that distinguishes subtypes (for example, `EMAIL` or `PASSWORD` for inputs). | +| `config` | A map of properties specific to the component type, such as labels, placeholders, validation rules, or button text. | +| `components` | (For container types such as `FORM` or `SECTION`) Children that should be rendered inside the container. | + +## Inputs and identifiers + +Input components expose an `identifier` in `config`. Use this value as the key when you send user data back to `/flow/execute`. The server lists the expected keys under `data.requiredParams`. + +```json +{ + "id": "email", + "type": "INPUT", + "variant": "EMAIL", + "config": { + "identifier": "email", + "label": "Email", + "required": true + } +} +``` + +## Actions and `actionId` + +Interactive components, such as primary buttons, provide an `actionId`. Echo this value in the `actionId` field when you continue the flow. + +```json +{ + "id": "submit", + "type": "BUTTON", + "actionId": "submit-registration", + "variant": "PRIMARY", + "config": { + "text": "Continue" + } +} +``` + +If multiple actions are available, the response can contain more than one component with an `actionId`. Present them to the user and pass the matching identifier depending on the option selected. + +## Validation rules + +Some inputs include a `validations` array within `config`. Each entry describes a rule the client can use to provide early feedback before calling the API. + +```json +{ + "type": "RULE", + "name": "LengthValidator", + "conditions": [ + { "key": "min.length", "value": "8" }, + { "key": "max.length", "value": "64" } + ] +} +``` + +Your client can choose to enforce these rules locally or rely on server-side validation. Regardless of local handling, always submit the user input back to the Flow Execution API to progress the flow. diff --git a/en/includes/guides/flows/index.md b/en/includes/guides/flows/index.md index 368fc1dc52..de5e9d9bbf 100644 --- a/en/includes/guides/flows/index.md +++ b/en/includes/guides/flows/index.md @@ -13,6 +13,7 @@ Design and customize key user journeys in your application with Flows. A flow de Building with starter templates, widgets, and other components provides complete control over how users interact with the application, all without writing complex code. ## Start building flows +For specific examples of building flows, refer to [Self-registration]({{base_path}}/guides/flows/self-registration/), [Password recovery]({{base_path}}/guides/flows/password-recovery/), and [Invited user registration]({{base_path}}/guides/flows/invited-user-registration/). To execute the flows from a custom client application, see [Use the Flow Execution API]({{base_path}}/guides/flows/flow-execution-api/) and explore the view schema in [Understand Flow Execution components]({{base_path}}/guides/flows/flow-execution-components/). - To learn the fundamentals of building a flow, refer to the [get started]({{base_path}}/guides/flows/build-a-flow/) guide. - For detailed examples of specific use cases, see the guides on [Self registration]({{base_path}}/guides/flows/self-registration/), [Password recovery]({{base_path}}/guides/flows/password-recovery/) and [Invited user registration]({{base_path}}/guides/flows/invited-user-registration/).