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

# Journey URL

> How to obtain and load a journey URL in your iOS app.

This guide explains where the journey URL comes from, how to obtain it, and what your iOS app needs to do with it.

## Overview

The journey URL is the web address that `BridgeWebView` loads to start an identity verification flow. It is not hardcoded — your backend generates it at runtime using the **GBG Go Core SDK** (`@gbg/go-core`).

```mermaid theme={null}
sequenceDiagram
    participant App as iOS App
    participant Backend as Your Backend
    participant Core as GBG Go Core SDK

    App->>Backend: 1. Request journey session
    Backend->>Core: 2. Create session
    Core-->>Backend: 3. Return instance ID + URL
    Backend-->>App: 4. Pass journey URL
```

The iOS app never calls the Core SDK directly. Session creation happens server-side, and the app receives the URL through whatever API your backend exposes.

## Core SDK setup

### Installation

```bash theme={null}
npm install @gbg/go-core
```

### Authentication

The Core SDK authenticates with a **customer access token** (Bearer). Generate one using the SDK's token endpoint:

```typescript theme={null}
import { Go } from "@gbg/go-core";

const go = new Go();

const auth = await go.tokens.generate({
  clientId: "your-client-id",
  clientSecret: "your-client-secret",
  username: "api-user@example.com",
  password: "your-password",
  grantType: "password",
});

// auth.accessToken is a Bearer token for subsequent calls
```

Then initialize the SDK with the token:

```typescript theme={null}
const go = new Go({
  customerAccess: auth.accessToken,
  serverIdx: 0, // 0 = EU, 1 = US, 2 = AU
});
```

### Regional servers

| Index | Region | Server                                         |
| ----- | ------ | ---------------------------------------------- |
| 0     | EU     | `https://eu.platform.go.gbgplc.com/v2/captain` |
| 1     | US     | `https://us.platform.go.gbgplc.com/v2/captain` |
| 2     | AU     | `https://au.platform.go.gbgplc.com/v2/captain` |

Select the appropriate region for your deployment using `serverIdx`, or provide a custom `serverURL`.

## Create a journey session

Journey URL generation is a two-step process.

### Step 1: Start the journey

Call `go.journeys.start()` with a **resource ID** that identifies which journey template to run:

```typescript theme={null}
const journey = await go.journeys.start({
  resourceId: "a4c68509c24789888eb466@latest",
  context: {
    subject: {
      identity: {
        firstName: "John",
        lastNames: ["Doe"],
        dateOfBirth: "1990-01-01",
      },
    },
  },
});
```

Response:

```typescript theme={null}
{
  instanceId: "PiIuACmx8Q8R7qPnAkLAqBAT",  // Unique journey instance (16–64 chars)
  instanceUrl?: "https://..."                 // Journey UI URL (present in some responses)
}
```

The `resourceId` uses the format `<id>@<version>` — use `@latest` to always get the current version of the journey template.

#### Pre-populate context (optional)

You can pass identity data, documents, biometrics, and consent records in the `context` field. This pre-populates the journey so the end user doesn't have to re-enter information you already have:

```typescript theme={null}
context: {
  subject: {
    identity: {
      firstName: "John",
      middleNames: ["Robert"],
      lastNames: ["Doe"],
      dateOfBirth: "1990-01-01",
      // ... additional fields as needed
    },
    documents: [],   // Pre-captured document data
    biometrics: [],  // Pre-captured biometric data
    consent: [],     // Consent records
    uid: "your-internal-user-id",
  },
},
```

### Step 2: Get a connect token

For native app integrations, generate a **connect token** that the device uses for authentication:

```typescript theme={null}
const device = await go.devices.add({
  instanceId: journey.instanceId,
  scope: ["mobile"],
});
```

Response:

```typescript theme={null}
{
  connectToken: "s4FUx8Ny8ijXRtFigz3x1_8rb9bd_5ZD",
  tokenType: "connect",
  expiresIn: 120,    // seconds
  scope: ["mobile"],
}
```

The `connectToken` is short-lived (typically 120 seconds). Your backend should return it to the iOS app immediately after generating it.

## Construct the URL

How you get the final URL to load in `BridgeWebView` depends on your integration pattern:

* If the `instanceUrl` is present in the Step 1 response, use it directly.
* Otherwise, your backend constructs the URL from the `instanceId` and `connectToken` according to your deployment's URL scheme.

In either case, your backend returns the URL to the iOS app through your own API.

## Load the URL in iOS

Once the iOS app has the URL from your backend, pass it to `BridgeWebView`:

```swift theme={null}
struct JourneyView: View {
    @StateObject private var host = BridgeHost(hostVersion: "1.0.0")
    let journeyURL: URL  // Received from your backend

    var body: some View {
        BridgeWebView(url: journeyURL, host: host)
            .onAppear { setupHandlers() }
    }
}
```

The bridge handles everything else — bootstrap script injection, message handler registration, and capability negotiation all happen automatically when the page loads.

## Complete backend example

A minimal Express endpoint that creates a journey session and returns the URL:

```typescript theme={null}
import { Go } from "@gbg/go-core";
import express from "express";

const app = express();
app.use(express.json());

app.post("/api/journey/start", async (req, res) => {
  const go = new Go({
    customerAccess: process.env.GO_CUSTOMER_ACCESS,
    serverIdx: 0,
  });

  // Step 1: Start journey
  const journey = await go.journeys.start({
    resourceId: req.body.resourceId ?? "a4c68509c24789888eb466@latest",
    context: {
      subject: {
        identity: req.body.identity,
      },
    },
  });

  // Step 2: Get connect token for the mobile device
  const device = await go.devices.add({
    instanceId: journey.instanceId,
    scope: ["mobile"],
  });

  res.json({
    instanceId: journey.instanceId,
    journeyUrl: journey.instanceUrl,
    connectToken: device.connectToken,
    expiresIn: device.expiresIn,
  });
});
```

And the corresponding iOS call:

```swift theme={null}
func startJourney() async throws -> URL {
    var request = URLRequest(url: URL(string: "https://your-backend.com/api/journey/start")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try JSONEncoder().encode(["resourceId": "a4c68509c24789888eb466@latest"])

    let (data, _) = try await URLSession.shared.data(for: request)
    let response = try JSONDecoder().decode(JourneyStartResponse.self, from: data)
    return response.journeyUrl
}
```

## Security considerations

* **Never embed the customer access token in the iOS app.** It is a server-side secret. The iOS app only ever sees the journey URL (and optionally the connect token).
* Always use **HTTPS** in production.
* Connect tokens are **short-lived** (typically 120 seconds) and **single-use**. Don't cache or persist them.
* The journey URL should be treated as sensitive — don't log it or store it beyond the current session.
* Fetch the URL over an **authenticated channel** between your app and your backend (e.g., behind your own auth middleware).

## Next steps

* [Integration Checklist](/docs/go-v2/developer-integration/sdks/ios/integration-checklist) — End-to-end setup walkthrough
* [Embedding Guide](/docs/go-v2/developer-integration/sdks/ios/embedding) — SwiftUI and UIKit patterns for displaying the journey
* [Stub Camera Views](/docs/go-v2/developer-integration/sdks/ios/stub-camera-views) — Get a working capture flow without SmartCapture SDKs
