# Build the B2B journeys

> Build B2B journeys on Mosaic-hosted screens after completing the [shared B2B setup](/guides/user/b2b/b2b_setup-overview#step-8-set-members). This is the path for clients set to **Journey-orchestrated**; for **Application-controlled** clients, see [Implement B2B login with APIs](/guides/user/b2b/b2b_login_with_apis) instead.
Fill in the journeys you created earlier, then invite a member and check the flow end to end.


## Understand the B2B journeys

Everything up to this point describes **what** your Mosaic application allows: which authenticators, which roles, which organizations, which members. A journey describes **when** each of those comes into play, and lets you add your own logic around them.

A B2B application typically runs two journeys:

| Journey | When it runs | What it does |
|  --- | --- | --- |
| **Invite** | An invited member follows the magic link from the invitation email | Onboards the member into the organization they were invited to. The org context comes from the link. |
| **Login** | A member signs in to the application | Identifies the member's organization and authenticates them according to that organization's configuration. |


Both are set at application level: the invite journey in [Configure the invite flow](/guides/user/b2b/b2b_configure_b2b#1-configure-the-invite-flow), and the login journey on the client, under **Login Experience**. Neither is set per organization, so one of each serves every organization on the application. You created them there; this guide is where you give those journeys their steps. If your client uses **Application-controlled** login, build the invite journey here and follow [Implement B2B login with APIs](/guides/user/b2b/b2b_login_with_apis) for sign-in.

Two journey steps do the B2B-specific work:

- [Authenticate Member](/guides/orchestration/journeys/b2b_authenticate_member) resolves the member's organization and authenticates them.
- [Register Member Authenticators](/guides/orchestration/journeys/b2b_register_authenticators) registers the authenticators the application requires or offers, skipping the ones the member already has.


The login journey starts with **Authenticate Member**. The invite journey doesn't use it: the invitation link already identifies the member and their organization, so it goes straight to **Register Member Authenticators**.

The login journey runs as an SSO journey, so a member who already has a valid SSO session signs in without entering their credentials again. Authentication runs only when there's no usable session.

Because both read the configuration at runtime, one journey serves every organization on the application. You don't build a journey per organization, and you don't repeat the authentication rules inside the journey.

These steps need Mosaic-hosted screens
Both steps present their own screens, so the journey has to run on pages hosted by Mosaic. They aren't available where the client serves your own login pages, or in SDK-driven journeys.

## Build the journeys

Journeys are built in the journey editor, under **B2B Identity** > **Journeys**. For a walkthrough that builds both journeys step by step, see [Create B2B journeys](/guides/orchestration/getting-started/b2b_tutorial).

Journeys aren't configured through APIs
Applications, clients, organizations, members, roles, and role groups can all be managed through the APIs, and org admins can manage their own organization with an `OrgAdminAccessToken`. Journeys are the exception: they're built in the journey editor.

## Exchange the invite code for tokens

When the member completes onboarding, through your invite journey or the Mosaic hosted experience if no journey is selected, Mosaic redirects the member to the [**Application URI for inviting members**](/guides/user/b2b/b2b_configure_b2b#1-configure-the-invite-flow) with an authorization code in the `code` query parameter. On your backend, exchange it for an ID token and access token at the [OIDC token endpoint](/openapi/user/oidc.openapi).

Use the **Client for inviting members** credentials from the client settings in the Admin Portal, with the same application URI as `redirect_uri`. This client has PKCE disabled, so no `code_verifier` is needed.

```shell
curl -i -X POST \
  https://api.transmitsecurity.io/cis/oidc/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d client_id=INVITE_CLIENT_ID \
  -d client_secret=INVITE_CLIENT_SECRET \
  -d code=CODE \
  -d grant_type=authorization_code \
  -d redirect_uri=INVITE_REDIRECT_URI
```

[Validate the returned tokens](/guides/user/validate_tokens) before granting access.

## Connect the application

For **Journey-orchestrated** login, connect your customer-facing application to Mosaic SSO to launch the login journey and receive the authentication result. Follow the guide for the protocol configured on your client:

- **OIDC** — [Launch OIDC SSO](/guides/user/sso_orchestration/sso_quickstart_hosted_ui_oidc) to initiate login and exchange the returned authorization code for tokens.
- **SAML** — [Launch SAML SSO](/guides/user/sso_orchestration/sso_quickstart_hosted_ui_saml) to initiate login and receive and validate the SAML response.


## Test the flow

Now that organizations and members exist, you can run the invite flow for real:

1. Invite a member, from the organization's **Members** tab in the Admin Portal or from the [Organization admin portal](/guides/user/b2b/b2b_org_portal) — see [Set members](/guides/user/b2b/b2b_set_members).
2. Open the invitation email and follow the magic link.
3. Check that the invite journey runs, that the member is onboarded into the right organization, and that the authenticators presented match the ones the application marks as required or optional.


For **Journey-orchestrated** login, sign in as that member to exercise the login journey. If the member belongs to more than one organization, check that organization selection appears after authentication, not before.

[data-component-name="Markdown/Markdown"] blockquote {
        border-left: 4px solid #BBC5FF !important;
        border-radius: 2px;
        background-color: #F1F2FF !important;
        padding: 20px 10px 15px 10px;
        margin: 10px 1px;
    }