Journey-flow API for native clients

Strivacity’s Journey-flow API for Native Clients allows a brand’s developers to leverage all of the power of Strivacity login and registration flows inside of their native mobile and web applications. Brands can achieve this while their developers maintain full control of the presentation layer code. Strivacity provides SDKs to cover enable developers to implement into their native applications.

Benefits

Our native app SDK approach ensures the full capabilities of Strivacity are available to native clients. This includes full support for:

  • Policy-defined workflows
  • Custom Journey-builder workflows
  • Identity Verification
  • A/B Testing
  • Lifecycle Event Hooks
  • Any step or flow our hosted components can display

Our SDK approach allows brands to make cloud-side policy changes that are reflected in the native app without having to update any native app code. Essentially, brands can change the entire login or registration experience without their developers having to make any code changes or wait till users adopt a new version. This comes in handy in many situations, for example when performing A/B testing where different users get different experiences. Brand managers can rapidly iterate through experiments and experience changes without having to involve their native app development team.

Further, if the native app encounters any UI it cannot render from the API call, the SDK will fail-over to Strivacity no-code components to handle that step of the workflow. This gives brands the ability to add new features in an agile fashion.

Approach

Strivacity’s approach provides access to our policy-driven login and registration flows via these native SDKs. The process works like this:

  1. A native application kicks off an OIDC login flow via a function call in the SDK. The SDK then makes a REST API call to the Strivacity Journey-flow API to start the login flow.
  2. The Strivacity returns a JSON payload to the app that describes what UI widgets to render in the UI (e.g. logo, email address input field, and a continue button), and what information the app needs to return (e.g. email address)
  3. The app then interprets the payload, renders the UI, collects the information and returns any needed data via the SDK
  4. If the native application cannot render the UI described in the payload, it will fail over to hosted components
  5. The SDK will ask for a web view from the Strivacity server and
  6. Fail over to Strivacity no-code components instead of the native app rendering that step

As long as the native app knows how to render the needed widgets for any given step, the app can handle various combinations of screen definitions that may be passed to it by Strivacity. If a brand admin changes a policy for that app, the app will either render it with the proper experience or fail over to Strivacity no-code components to finish the task.

Key Concepts

Each journey is a stateful sequence of screens driven by the Strivacity backend. Clients fetch the current screen, render its forms natively, and post form submissions back to advance the flow.

  • Screens: Encapsulate one or more forms and their widgets.
  • Forms: Contain user inputs to be collected (username, password, etc.).
  • Widgets: Typed elements (input fields, checkboxes) for rendering.
  • Flow State: Progresses step by step; each server response dictates the next screen.
  • Fallback URL: If a client cannot render a step, a web-hosted fallback URL (hostedUrl) is provided.

How to configure in Strivacity

The Journey-flow API is implemented by adding the client for OIDC using the Journey-flow API to an existing application.

To configure in the Strivacity admin console:

  1. Go to Applications > (your application) > Clients > Create client

  2. Select the "OIDC using the Journey-flow API" client type

  3. Configure the client according to your needs (see configuring Clients for more information)

  4. Be sure to include a callback URL in the client configuration to point back to the application

  5. This client is already configured to support the OIDC PKCE flow, which is required to use this API.

Once that client has been configured and saved, you are ready to begin incorporating it into your native application.

SDKs & integration options

Strivacity provides SDKs that abstract the lower‑level OAuth/OIDC and flow mechanics for the Journey-flow API.

  • Mobile SDKs (iOS & Android): PKCE, secure storage, redirect handling, biometrics
  • Flutter SDK: Cross‑platform; render screens natively with full control
  • React Native SDK: Hybrid; hosted UI or native journey rendering
  • Web SDKs (React/Angular/Vue…): Hosted UI or full journey rendering in SPAs

How to choose an SDK

ScenarioRecommended SDKWhy
Building a fully native iOS appiOS SDKHandles PKCE, token lifecycle, deep linking, and secure Keychain storage natively with Apple best practices
Building a fully native Android appAndroid SDKManages PKCE, tokens, secure SharedPreferences, and integrates seamlessly with Android custom tabs
Building a cross-platform mobile app in FlutterFlutter SDKSingle codebase for iOS/Android, full control over native rendering of screens and widgets, with fallback to hosted components if needed
Building a hybrid mobile app with React NativeReact Native SDKOffers a flexible balance: hosted UI or native journey rendering, with automatic redirect handling and fallback logic
Building a web SPA (React, Angular, Vue, etc.)Web SDK (JavaScript)Simplifies integration into browser environments, handling OIDC flows, tokens, and session management securely
You prefer minimal code and a faster integrationHosted Components (no-code)Lets you drop in Strivacity-hosted login and registration UIs without building your own screens

❗️

Why prefer SDKs over direct API integration?

Strivacity SDKs handle flow orchestration (screen → form → screen), token lifecycle + PKCE, redirects/fallbacks, and widget semantics. Your frontend stays decoupled from backend flow logic: if policies or steps change (e.g., adding MFA), the app keeps working without redeploying.

Bottom line: SDKs are secure, maintainable, and future‑proof as your flows evolve.

How to use the API

Initialize an OIDC flow

Strivacity's Journey-flow API begins with an OIDC PKCE flow.

Start the journey

Call the init API to start a new session and receive the initial Screen.

POST /flow/api/v1/init

Render and collect input

Each screen includes one or more forms with typed widgets (input, password, select, etc.). Render these natively, collect values by widget id, apply validators, and surface any messages.global.

Submit forms

Advance the flow by posting the collected values to the form endpoint for the current formId.

POST /flow/api/v1/form/{formId}

Handle validation & errors

If validation fails, the response includes messages.global (e.g., “Incorrect password”). Display these to the user.

Complete the journey

When complete, the Screen includes a finalizeUrl you follow to finalize authorization obtain your token.

Reset when needed

Reset the journey to the initial state:

POST /flow/api/v1/form/reset

Screen model (reference)

FieldDescription
screenName/ID of the current screen
formsArray of forms to render
layoutLayout guidance
messagesError/success feedback
hostedUrlWeb fallback URL
finalizeUrlURL to finalize the flow (if present)

Forms

forms is an array of widget elements such as:

  • input, password, select, checkbox, static, submit

Falling back to no-code components

For brands who prefer to use no-code components rather than building their own native experiences, or when the native application encounters any functionality it doesn't understand, it can redirect to the fallback URL provided in the response to start or finish the flow using no-code components instead of native user interfaces.

No-code components flow

In this flow, the web view in the native application displays no-code components to the customer who interacts with the hosted login until the flow is complete and a code token is returned.

Sample flow

GET /oauth2/auth

GET https://{{tenant}}/oauth2/auth
  ?client_id={{clientId}}
  &redirect_uri={{redirectUrl}}
  &scope=openid
  &response_type=code
  &response_mode=query
  &code_challenge_method=S256
  &code_challenge={{code_challenge}}
  &state={{state}}
  &nonce={{nonce}}

> {%
    client.global.set("loginProvider", response.headers.valueOf('Location'))
%}

GET /provider/login

GET {{loginProvider}}

> {%
    let nativeUrl = response.headers.valueOf('Location');
    client.global.set("nativeUrl", nativeUrl)
    client.global.set('sessionId', new URLSearchParams(nativeUrl.substring(nativeUrl.indexOf('?') + 1)).get('session_id'))
%}

POST /flow/api/v1/init

POST https://{{tenant}}/flow/api/v1/init
Authorization: Bearer {{sessionId}}

> {%
    console.log('init response: ' + JSON.stringify(response.body, null, 4))
    console.log('Fallback url: ' + response.body.hostedUrl)
%}

POST /flow/api/v1/form/identifier

POST https://{{tenant}}/flow/api/v1/form/identifier
Authorization: Bearer {{sessionId}}
Content-Type: application/json

{
  "identifier": "[email protected]"
}

> {%
    console.log('identifier response: ' + JSON.stringify(response.body, null, 4))
%}

POST /flow/api/v1/form/password

POST https://{{tenant}}/flow/api/v1/form/password
Authorization: Bearer {{sessionId}}
Content-Type: application/json

{
  "password": "{{password}}"
}

> {%
    console.log('password response: ' + JSON.stringify(response.body, null, 4))
    client.global.set("finalizeUrl", response.body.finalizeUrl)
%}

GET auth post login

GET {{finalizeUrl}}

> {%
    client.global.set("consentProvider",  response.headers.valueOf('Location'))
%}

GET consent provider

GET {{consentProvider}}

> {%
    client.global.set("hydraFinish",  response.headers.valueOf('Location'))
%}

GET auth post consent

GET {{hydraFinish}}

> {%
    console.log('result: ' + response.headers.valueOf('Location'))

    let callbackUrl = response.headers.valueOf('Location');
    client.global.set('codeToken', new URLSearchParams(callbackUrl.substring(callbackUrl.indexOf('?') + 1)).get('code'))
%}

POST token endpoint

POST https://{{tenant}}/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&client_id={{clientId}}
&code_verifier=VC9aHmX1Oe8C3jeAAmBVKvFTfugtt1rKFXoCmNOKBJc
&code={{codeToken}}
&redirect_uri={{redirectUrl}}

> {%
    console.log('result: ' + JSON.stringify(response.body, null, 4))
%}

Resources