> ## 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.

# API reference

> Complete type reference for the GBGBridge Web SDK.

Complete reference for every public type, method, and property in the GBGBridge Web SDK. Both the core package (`@gbg/go-bridge-web`) and the React adapter (`@gbg/go-bridge-web-react`) are covered.

**Packages:** `@gbg/go-bridge-web` (core), `@gbg/go-bridge-web-react` (React 19 wrapper)
**Browsers:** ES2020 / modern evergreen
**TypeScript:** 5.x

***

## Table of contents

* [Primary entry points](#primary-entry-points)
  * [BridgeHost](#bridgehost)
  * [BridgeHostProvider](#bridgehostprovider) — React
* [React hooks](#react-hooks)
  * [useBridgeHost](#usebridgehost)
  * [useBridgeCapability](#usebridgecapability)
  * [useBridgeHostEvent](#usebridgehostevent)
  * [useBridgeHostError](#usebridgehosterror)
* [Configuration types](#configuration-types)
  * [BridgeHostOptions](#bridgehostoptions)
  * [BridgeHostProviderProps](#bridgehostproviderprops)
  * [RespondOptions](#respondoptions)
* [Capability types](#capability-types)
  * [CapabilityInfo](#capabilityinfo)
  * [CapabilityMap](#capabilitymap)
  * [CapabilityId](#capabilityid)
  * [Environment](#environment)
  * [CAPABILITY\_IDS](#capability_ids)
* [Message models](#message-models)
  * [BridgeMessage](#bridgemessage)
  * [BridgeMessageType](#bridgemessagetype)
  * [RequestPayload](#requestpayload)
  * [RequestOptions](#requestoptions)
  * [ResponsePayload](#responsepayload)
  * [ResponseStatus](#responsestatus)
  * [ResponseError](#responseerror)
  * [EventPayload](#eventpayload)
* [Actions](#actions)
  * [BridgeActions](#bridgeactions)
* [Errors](#errors)
  * [BridgeError](#bridgeerror)
  * [BridgeErrorCode](#bridgeerrorcode)
  * [toBridgeErrorCode](#tobridgeerrorcode)
* [Interfaces](#interfaces)
  * [BridgeCapabilityHandler](#bridgecapabilityhandler)
  * [BridgeHostDelegate](#bridgehostdelegate)
* [Classes](#classes)
  * [BridgeResponder](#bridgeresponder)
* [Built-in handlers](#built-in-handlers)
  * [CapabilityQueryHandler](#capabilityqueryhandler)
* [React context](#react-context)
  * [BridgeHostContext](#bridgehostcontext)
  * [BridgeHostContextValue](#bridgehostcontextvalue)
  * [BridgeHostEventListener](#bridgehosteventlistener)
  * [BridgeHostErrorListener](#bridgehosterrorlistener)

***

## Primary entry points

These are the types you interact with directly to wire the bridge into your app. Non-React hosts use `BridgeHost` directly; React hosts wrap it in `BridgeHostProvider` and consume via hooks.

### BridgeHost

The central coordinator that manages message routing between an `<iframe>` and your host page.

```typescript theme={null}
export class BridgeHost {
  static readonly PROTOCOL_VERSION: '1.0';
  readonly hostVersion: string;
  delegate: BridgeHostDelegate | undefined;
}
```

**Why it exists:** `BridgeHost` decodes incoming messages from the journey iframe, validates origins, routes requests to registered handlers, tracks pending requests, and sends responses and events back to the iframe. It is the only object you must construct to use the SDK without React.

**Threading:** JavaScript is single-threaded — there is no thread enforcement, but all calls happen on the main thread by definition.

#### Constructor

```typescript theme={null}
constructor(options: BridgeHostOptions)
```

Constructs a host and immediately attaches it to the iframe. A built-in `CapabilityQueryHandler` is automatically registered for the `"capability.query"` action.

| Parameter | Type                                      | Description                                                                         |
| --------- | ----------------------------------------- | ----------------------------------------------------------------------------------- |
| `options` | [`BridgeHostOptions`](#bridgehostoptions) | iframe element, allowed origins, optional host version, capabilities, and delegate. |

**Example:**

```typescript theme={null}
import { BridgeHost } from "@gbg/go-bridge-web";

const host = new BridgeHost({
  iframe: document.getElementById("journey-frame") as HTMLIFrameElement,
  allowedOrigins: ["https://journey.example.com"],
  hostVersion: "1.0.0",
  capabilities: {
    "camera.document": { supported: true, version: "1.0" },
  },
});
```

#### Static properties

Constants exposed on the `BridgeHost` class itself, not on instances.

##### PROTOCOL\_VERSION

```typescript theme={null}
static readonly PROTOCOL_VERSION: '1.0'
```

The wire protocol version this SDK speaks. Exposed for integrator telemetry. The host warns and continues on inbound version mismatch rather than failing.

***

#### Properties

| Property           | Type                              | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------ | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `hostVersion`      | `string`                          | The host app version. Reported to the journey in `capability.query` responses. Defaults to `"0.0.0"` if not provided to the constructor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `delegate`         | `BridgeHostDelegate \| undefined` | Mutable. Set after construction to observe bridge activity.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `pendingRequests`  | `ReadonlyArray<BridgeMessage>`    | Inbound requests with no registered handler. Capped at 50; overflow drops oldest. Respond via [`respond()`](#respond) to remove.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `receivedMessages` | `ReadonlyArray<BridgeMessage>`    | Every validated inbound message. Capped at 200; oldest trimmed on overflow.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `capabilities`     | `Readonly<CapabilityMap>`         | The effective capability map (constructor `capabilities` merged with `registerCustomCapability` entries). Computed on read.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `lastError`        | `string \| null`                  | The most recent error message, or `null`. Set when send fails, delegate throws, or handler exceptions occur. Call [`clearError()`](#clearerror) to reset. **Diverges from iOS:** on web `lastError` is a thin wrapper around `delegate.onError` — every error that fires `onError` also surfaces here. iOS sets `lastError` from six independent triggers (decode failures, encode failures, leak warnings, send-while-detached, async-JS failures, envelope-encode failures); web doesn't have those triggers because send-while-detached is silently dropped Android-style and there's no JS-evaluation path. |

***

#### Methods

Imperative operations on a `BridgeHost` instance — attaching and detaching the iframe, registering handlers, sending events, and responding to requests.

##### attach

```typescript theme={null}
attach(iframe: HTMLIFrameElement): void
```

Re-attaches the host to a new iframe. Used internally by the constructor; rarely called directly. Preserves `pendingRequests` and `receivedMessages` buffers across the re-attach.

| Parameter | Type                | Description           |
| --------- | ------------------- | --------------------- |
| `iframe`  | `HTMLIFrameElement` | The iframe to attach. |

***

##### detach

```typescript theme={null}
detach(): void
```

Removes the `window` `message` listener and tears down the transport channel. Idempotent. After detach, inbound messages are no longer received and outbound sends are silently dropped.

Call this when the iframe is removed from the page. `BridgeHostProvider` calls it automatically on unmount.

***

##### registerHandler

```typescript theme={null}
registerHandler(action: string, handler: BridgeCapabilityHandler): void
```

Registers a handler for a specific action ID. If a handler is already registered for the same action, it is replaced.

This only attaches the handler — it does **not** declare the capability as supported. Use the `capabilities` constructor option or [`registerCustomCapability()`](#registercustomcapability) for declaration.

| Parameter | Type                                                  | Description                                                |
| --------- | ----------------------------------------------------- | ---------------------------------------------------------- |
| `action`  | `string`                                              | The action identifier (e.g., `"camera.document.capture"`). |
| `handler` | [`BridgeCapabilityHandler`](#bridgecapabilityhandler) | Object with a `handle(request, responder)` method.         |

***

##### getHandler

```typescript theme={null}
getHandler(action: string): BridgeCapabilityHandler | undefined
```

Returns the handler currently registered for the given action, or `undefined`. Used internally by [`useBridgeCapability`](#usebridgecapability) to verify ownership before unregistering on unmount.

***

##### unregister

```typescript theme={null}
unregister(action: string): void
```

Removes the handler for the given action. Subsequent requests for that action will be added to `pendingRequests` and `delegate.onUnhandledRequest` will fire.

Unregistering `"capability.query"` removes the SDK's auto-registered handler — the SDK warns when this happens. Capability queries will stop receiving responses unless you register a replacement.

| Parameter | Type     | Description                          |
| --------- | -------- | ------------------------------------ |
| `action`  | `string` | The action identifier to unregister. |

***

##### registerCustomCapability

```typescript theme={null}
registerCustomCapability(
  id: string,
  version?: string,
  handler?: BridgeCapabilityHandler,
): void
```

Declares a capability AND optionally registers a handler in a single call. The capability appears in `capability.query` responses, and if `handler` is provided, requests for the matching action ID are routed to it.

This is the closest web equivalent to iOS/Android's "set handler on typed slot" pattern — both declaration and registration in one step.

| Parameter | Type                                                  | Default | Description                                                                 |
| --------- | ----------------------------------------------------- | ------- | --------------------------------------------------------------------------- |
| `id`      | `string`                                              | —       | The capability/action identifier (e.g., `"nfc.read"`). Empty strings throw. |
| `version` | `string`                                              | `"1.0"` | Version string emitted in query responses.                                  |
| `handler` | [`BridgeCapabilityHandler`](#bridgecapabilityhandler) | —       | Optional handler to register for `id` as an action.                         |

***

##### sendEvent

```typescript theme={null}
sendEvent(action: string, data?: Record<string, unknown>): void
```

Sends an event message to the journey iframe. Events are fire-and-forget — no response is expected. Generates a unique correlation ID in the format `web-event-{uuid}`.

| Parameter | Type                      | Default | Description                                            |
| --------- | ------------------------- | ------- | ------------------------------------------------------ |
| `action`  | `string`                  | —       | Event action identifier (e.g., `"host.theme.update"`). |
| `data`    | `Record<string, unknown>` | `{}`    | Event payload.                                         |

***

##### respond

```typescript theme={null}
respond(options: RespondOptions): void
```

Sends a manual response to a pending request. Used to respond from outside a registered handler — for example, when handling a request asynchronously via `delegate.onUnhandledRequest`.

If `options.action` is omitted, the SDK looks up the original request in `pendingRequests` and uses its action. On success, the request is removed from `pendingRequests`.

| Parameter | Type                                | Description                                               |
| --------- | ----------------------------------- | --------------------------------------------------------- |
| `options` | [`RespondOptions`](#respondoptions) | Correlation ID, status, optional action, data, and error. |

The host enforces at-most-once delivery on terminal statuses (`success`, `error`, `cancelled`, `unsupported`). Subsequent calls with the same `correlationId` and a terminal status are dropped. `acknowledged` is interim and may precede a terminal status.

***

##### clearError

```typescript theme={null}
clearError(): void
```

Resets `lastError` to `null`.

***

### BridgeHostProvider

React provider that owns the `BridgeHost` lifecycle. Wrap your iframe-rendering subtree in this provider and use the hooks to interact with the bridge.

```typescript theme={null}
export function BridgeHostProvider(props: BridgeHostProviderProps): JSX.Element
```

**Why it exists:** Bridges React's component lifecycle with the imperative `BridgeHost` API. Holds the host in component state, sets up the underlying transport, exposes context to descendant hooks, and tears down on unmount.

**Lifecycle:**

1. Mounts with `iframe={null}` — no host yet.
2. iframe element appears (via `ref={setIframe}` callback). Provider instantiates `BridgeHost` and snapshots `allowedOrigins`, `hostVersion`, and `capabilities` props.
3. Re-renders that change props **do not** rebuild the host. Force a remount (key change) to apply runtime config updates.
4. Unmount: cleanup calls `host.detach()` and clears the host from state.

#### Props

See [`BridgeHostProviderProps`](#bridgehostproviderprops).

**Example:**

```tsx theme={null}
import { BridgeHostProvider } from "@gbg/go-bridge-web-react";
import { useState } from "react";

function App() {
  const [iframe, setIframe] = useState<HTMLIFrameElement | null>(null);

  return (
    <BridgeHostProvider
      iframe={iframe}
      allowedOrigins={["https://journey.example.com"]}
      hostVersion="1.0.0"
      capabilities={{ "camera.document": { supported: true, version: "1.0" } }}
    >
      <YourComponents />
      <iframe ref={setIframe} src="https://journey.example.com" allow="camera" />
    </BridgeHostProvider>
  );
}
```

***

## React hooks

All hooks must be called inside a `BridgeHostProvider`. Outside the provider they no-op and log a one-time `console.warn`.

### useBridgeHost

Returns the underlying `BridgeHost` instance, or `null` while the iframe hasn't attached.

```typescript theme={null}
function useBridgeHost(): BridgeHost | null
```

**Why it exists:** Lets descendants access imperative methods (`sendEvent`, `registerCustomCapability`, `clearError`, etc.) that don't have dedicated hooks.

**Example:**

```tsx theme={null}
function EmitHelloOnMount() {
  const host = useBridgeHost();
  useEffect(() => {
    host?.sendEvent("host.ready", { timestamp: Date.now() });
  }, [host]);
  return null;
}
```

***

### useBridgeCapability

Registers a `BridgeCapabilityHandler` for the lifetime of the calling component.

```typescript theme={null}
function useBridgeCapability(
  action: string,
  handler: BridgeCapabilityHandler,
): void
```

The hook wraps `handler` in a stable proxy: identity never changes across renders, but the proxy delegates to the latest handler via a ref. An inline `{ handle: ... }` object literal does **not** re-register on every render — only `action` changes (or a host swap) trigger re-registration.

On unmount, the hook unregisters only if its own proxy is still the active handler. This prevents two components racing on the same action from accidentally removing each other's installations.

| Parameter | Type                                                  | Description                                        |
| --------- | ----------------------------------------------------- | -------------------------------------------------- |
| `action`  | `string`                                              | The action ID this handler responds to.            |
| `handler` | [`BridgeCapabilityHandler`](#bridgecapabilityhandler) | Object with a `handle(request, responder)` method. |

This only registers the handler. To declare the capability as supported, pass an entry in the provider's `capabilities` prop or call `host.registerCustomCapability(id, version, handler)` directly. See [Concepts → Declaring vs. Registering](/docs/go-v2/developer-integration/sdks/web/concepts#declaring-vs-registering-capabilities).

**Example:**

```tsx theme={null}
function DocumentCaptureHandler() {
  useBridgeCapability("camera.document.capture", {
    handle: async (request, responder) => {
      const image = await captureDocument();
      responder.success({ image });
    },
  });
  return null;
}
```

***

### useBridgeHostEvent

Subscribes to events emitted by the journey iframe with a specific action ID. The listener is invoked with the event's `data` payload.

```typescript theme={null}
function useBridgeHostEvent(
  action: string,
  listener: BridgeHostEventListener,
): void
```

| Parameter  | Type                                                  | Description                                                     |
| ---------- | ----------------------------------------------------- | --------------------------------------------------------------- |
| `action`   | `string`                                              | The event action to subscribe to (e.g., `"journey.completed"`). |
| `listener` | [`BridgeHostEventListener`](#bridgehosteventlistener) | Function receiving the event's `data` payload.                  |

Listener identity affects the effect dependency array — wrap inline listeners in `useCallback` if you want a stable subscription across renders.

**Example:**

```tsx theme={null}
function CompletionRouter() {
  const navigate = useNavigate();
  useBridgeHostEvent("journey.completed", (data) => {
    navigate(`/success?journey=${data.journeyId}`);
  });
  return null;
}
```

***

### useBridgeHostError

Subscribes to internal SDK errors — handler exceptions, send failures, delegate throws, and other errors routed via `BridgeHost.fireError`.

```typescript theme={null}
function useBridgeHostError(listener: BridgeHostErrorListener): void
```

| Parameter  | Type                                                  | Description                     |
| ---------- | ----------------------------------------------------- | ------------------------------- |
| `listener` | [`BridgeHostErrorListener`](#bridgehosterrorlistener) | Function receiving the `Error`. |

This subscribes to errors raised by the host itself. Errors returned to the journey via `responder.error(...)` are not surfaced here — they're outbound responses, not internal failures.

***

## Configuration types

The interfaces below configure `BridgeHost` and `BridgeHostProvider` at construction time. All are plain TypeScript interfaces — no classes or constructors.

### BridgeHostOptions

Constructor argument for `BridgeHost`.

```typescript theme={null}
export interface BridgeHostOptions {
  iframe: HTMLIFrameElement;
  allowedOrigins: string[];
  delegate?: BridgeHostDelegate;
  hostVersion?: string;
  capabilities?: CapabilityMap;
}
```

| Field            | Type                 | Default     | Description                                                                                                                                                                                         |
| ---------------- | -------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `iframe`         | `HTMLIFrameElement`  | —           | The iframe to attach. Must be in the DOM when the host is constructed.                                                                                                                              |
| `allowedOrigins` | `string[]`           | —           | Origins permitted to source bridge messages. Must be non-empty — empty arrays throw at construction. Each entry must be a valid origin string (scheme + host + optional non-default port; no path). |
| `delegate`       | `BridgeHostDelegate` | `undefined` | Observer for inbound messages, outbound sends, unhandled requests, and errors.                                                                                                                      |
| `hostVersion`    | `string`             | `"0.0.0"`   | Reported in capability query responses.                                                                                                                                                             |
| `capabilities`   | `CapabilityMap`      | `{}`        | Capabilities declared up front. Merged with later `registerCustomCapability` entries when building query responses.                                                                                 |

***

### BridgeHostProviderProps

Props for `BridgeHostProvider`.

```typescript theme={null}
export interface BridgeHostProviderProps {
  iframe: HTMLIFrameElement | null;
  allowedOrigins: string[];
  hostVersion?: string;
  capabilities?: CapabilityMap;
  delegate?: BridgeHostDelegate;
  children: ReactNode;
}
```

| Field            | Type                        | Description                                                                                                                                                                                               |
| ---------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `iframe`         | `HTMLIFrameElement \| null` | Track in component state and pass `setIframe` as the iframe element's `ref` callback. `useRef` does **not** work — refs are not reactive, so the provider's effect would not fire when the iframe mounts. |
| `allowedOrigins` | `string[]`                  | See `BridgeHostOptions.allowedOrigins`. Snapshotted at attach time.                                                                                                                                       |
| `hostVersion`    | `string`                    | Snapshotted at attach time.                                                                                                                                                                               |
| `capabilities`   | `CapabilityMap`             | Snapshotted at attach time. To add capabilities at runtime, call `host.registerCustomCapability` directly via `useBridgeHost()`.                                                                          |
| `delegate`       | `BridgeHostDelegate`        | Read from the **latest** render — the provider reads the delegate ref each time, not at attach. Safe to change between renders.                                                                           |
| `children`       | `ReactNode`                 | Subtree that can use the hooks. The iframe element typically lives inside this subtree.                                                                                                                   |

***

### RespondOptions

Argument to `BridgeHost.respond`.

```typescript theme={null}
export interface RespondOptions {
  correlationId: string;
  action?: string;
  status: ResponseStatus;
  data?: Record<string, unknown>;
  error?: ResponseError;
}
```

| Field           | Type                                | Description                                                                                                                                                                        |
| --------------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `correlationId` | `string`                            | The correlation ID of the request being responded to.                                                                                                                              |
| `action`        | `string`                            | Optional. When omitted, the SDK resolves the action from the matching entry in `pendingRequests`. If the request isn't pending and no action is provided, the response is dropped. |
| `status`        | [`ResponseStatus`](#responsestatus) | Response status.                                                                                                                                                                   |
| `data`          | `Record<string, unknown>`           | Optional response data.                                                                                                                                                            |
| `error`         | [`ResponseError`](#responseerror)   | Optional error details. Typically set when `status === 'error'`.                                                                                                                   |

***

## Capability types

Types and constants for declaring capabilities the host can fulfil. `CapabilityInfo` is per-capability metadata; `CapabilityMap` is the shape you pass to the constructor; `CAPABILITY_IDS` lists standard identifiers.

### CapabilityInfo

Metadata about a single capability.

```typescript theme={null}
export interface CapabilityInfo {
  supported: boolean;
  version?: string;
  constraints?: Record<string, unknown>;
  permissionState?: string;
}
```

| Field             | Type                      | Description                                                                                                                                                                                                                                                                                                                                            |
| ----------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `supported`       | `boolean`                 | Whether the host can fulfil this capability.                                                                                                                                                                                                                                                                                                           |
| `version`         | `string`                  | Optional version string. Emitted as `null` in query responses when unset.                                                                                                                                                                                                                                                                              |
| `constraints`     | `Record<string, unknown>` | Optional key-value constraints (e.g., `{ maxResolution: 4096 }`). **Stripped from the `capability.query` wire payload** to match iOS/Android — neither platform emits `constraints` either. Use the field for host-side metadata only; to advertise constraints to the journey, encode them inside `version` or coordinate a separate protocol change. |
| `permissionState` | `string`                  | Optional permission state (e.g., `"granted"`, `"prompt"`, `"denied"`). Included in query responses when present.                                                                                                                                                                                                                                       |

***

### CapabilityMap

A map of capability IDs to `CapabilityInfo`.

```typescript theme={null}
export type CapabilityMap = Record<string, CapabilityInfo>
```

***

### CapabilityId

A type alias for the values in `CAPABILITY_IDS`. Useful when you want compile-time enforcement that a string is a standard capability identifier.

```typescript theme={null}
export type CapabilityId = (typeof CAPABILITY_IDS)[keyof typeof CAPABILITY_IDS]
```

***

### Environment

The platform reported in `capability.query` responses. Always `"web"` from this SDK.

```typescript theme={null}
export type Environment = 'ios' | 'android' | 'web' | 'standalone'
```

| Value          | When emitted                                                                                                                                                                                                |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `"ios"`        | iOS Bridge SDK is the host.                                                                                                                                                                                 |
| `"android"`    | Android Bridge SDK is the host.                                                                                                                                                                             |
| `"web"`        | Web Bridge SDK is the host (this SDK always emits this).                                                                                                                                                    |
| `"standalone"` | The journey is running without a host SDK — e.g., loaded directly in a browser tab outside an iframe. Emitted by the iframe-side SDK when no bridge host is detected. Host-side SDKs never emit this value. |

The union is shared with the iframe-side SDK for type compatibility; host SDKs only ever emit their own platform's value.

***

### CAPABILITY\_IDS

Standard capability identifiers, **standardized across iOS, Android, and Web** — the same string values appear in `CAPABILITY_IDS` on all three platforms, and on the iframe-side SDK. Use the constants rather than magic strings to avoid typos and to track value changes through TypeScript's reference graph.

```typescript theme={null}
export const CAPABILITY_IDS = {
  CAMERA_DOCUMENT: 'camera.document',
  CAMERA_SELFIE: 'camera.selfie',
  NFC_READ: 'nfc.read',
  BIOMETRIC_AUTH: 'biometric.auth',
  DEVICE_ATTESTATION: 'device.attestation',
  LOCATION_GPS: 'location.gps',
  STORAGE_SECURE: 'storage.secure',
  ANALYTICS_FORWARD: 'analytics.forward',
} as const;
```

| Constant             | Capability ID        | Description                                                                                                                                           |
| -------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CAMERA_DOCUMENT`    | `camera.document`    | Native document capture (the host provides the camera UI; the journey requests via `camera.document.capture` action).                                 |
| `CAMERA_SELFIE`      | `camera.selfie`      | Native selfie/liveness capture. Action: `camera.selfie.capture`.                                                                                      |
| `NFC_READ`           | `nfc.read`           | NFC document reading (e-Passport, etc.). Web hosts typically cannot fulfil this — declare it `supported: false` if you want to make absence explicit. |
| `BIOMETRIC_AUTH`     | `biometric.auth`     | Face ID / Touch ID / Fingerprint. Web equivalent is WebAuthn.                                                                                         |
| `DEVICE_ATTESTATION` | `device.attestation` | Device integrity verification.                                                                                                                        |
| `LOCATION_GPS`       | `location.gps`       | GPS coordinates. Web equivalent is `navigator.geolocation`.                                                                                           |
| `STORAGE_SECURE`     | `storage.secure`     | Secure enclave storage. Web equivalent is limited; declare `supported: false` if no equivalent.                                                       |
| `ANALYTICS_FORWARD`  | `analytics.forward`  | Forward analytics events from the journey to the host's telemetry pipeline.                                                                           |

***

## Message models

Every value that crosses the bridge is wrapped in a `BridgeMessage` envelope.

### BridgeMessage

A structured envelope for all bridge communication.

```typescript theme={null}
export interface BridgeMessage {
  version: '1.0';
  correlationId: string;
  type: BridgeMessageType;
  timestamp: number;
  payload: RequestPayload | ResponsePayload | EventPayload;
}
```

| Field           | Type                                                | Description                                                                                                 |
| --------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `version`       | `'1.0'`                                             | Protocol version literal. Mismatched inbound versions produce a `console.warn` and continue processing.     |
| `correlationId` | `string`                                            | Unique identifier. Requests generate one; responses copy the request's; events generate `web-event-{uuid}`. |
| `type`          | `BridgeMessageType`                                 | Discriminator for `payload`.                                                                                |
| `timestamp`     | `number`                                            | Unix milliseconds.                                                                                          |
| `payload`       | `RequestPayload \| ResponsePayload \| EventPayload` | Typed by `type`.                                                                                            |

***

### BridgeMessageType

```typescript theme={null}
export type BridgeMessageType = 'request' | 'response' | 'event'
```

| Value        | Direction     | Purpose                                         |
| ------------ | ------------- | ----------------------------------------------- |
| `'request'`  | Iframe → Host | The journey asks the host to perform an action. |
| `'response'` | Host → Iframe | The host's reply to a request.                  |
| `'event'`    | Either        | Fire-and-forget notification.                   |

***

### RequestPayload

```typescript theme={null}
export interface RequestPayload {
  action: string;
  data: Record<string, unknown>;
  options?: RequestOptions;
}
```

| Field     | Type                      | Description                                            |
| --------- | ------------------------- | ------------------------------------------------------ |
| `action`  | `string`                  | Action identifier (e.g., `"camera.document.capture"`). |
| `data`    | `Record<string, unknown>` | Request parameters.                                    |
| `options` | `RequestOptions`          | Optional request options (timeout, fallback hints).    |

***

### RequestOptions

```typescript theme={null}
export interface RequestOptions {
  timeout?: number;
  fallbackAllowed?: boolean;
}
```

| Field             | Type      | Description                                                                                                                       |
| ----------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `timeout`         | `number`  | Milliseconds. Recommended bound for the host's handler. The SDK does not enforce timeouts — handlers are expected to honour them. |
| `fallbackAllowed` | `boolean` | When `true`, the journey is willing to fall back to an iframe-side alternative if the host responds with `unsupported`.           |

***

### ResponsePayload

```typescript theme={null}
export interface ResponsePayload {
  action: string;
  status: ResponseStatus;
  data?: Record<string, unknown>;
  error?: ResponseError;
}
```

| Field    | Type                      | Description                            |
| -------- | ------------------------- | -------------------------------------- |
| `action` | `string`                  | Mirrors the request's action.          |
| `status` | `ResponseStatus`          | Terminal or interim status.            |
| `data`   | `Record<string, unknown>` | Present on `success` / `acknowledged`. |
| `error`  | `ResponseError`           | Present on `error`.                    |

***

### ResponseStatus

```typescript theme={null}
export type ResponseStatus =
  | 'success'
  | 'error'
  | 'cancelled'
  | 'unsupported'
  | 'acknowledged'
```

| Value            | Meaning                                                           |
| ---------------- | ----------------------------------------------------------------- |
| `'success'`      | The operation completed. Check `data` for the result.             |
| `'error'`        | The operation failed. Check `error` for details.                  |
| `'cancelled'`    | The user cancelled the operation.                                 |
| `'unsupported'`  | The capability is not available on this host.                     |
| `'acknowledged'` | Interim. The request was received; a terminal status will follow. |

***

### ResponseError

```typescript theme={null}
export interface ResponseError {
  code: string;
  message: string;
  recoverable: boolean;
}
```

| Field         | Type      | Description                                                                                                                                                      |
| ------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `code`        | `string`  | Machine-readable error code. Values from [`BridgeErrorCode`](#bridgeerrorcode), or implementation-specific codes (e.g., `"HANDLER_FAILURE"`, `"CAMERA_DENIED"`). |
| `message`     | `string`  | Human-readable description.                                                                                                                                      |
| `recoverable` | `boolean` | Whether the journey can retry.                                                                                                                                   |

***

### EventPayload

```typescript theme={null}
export interface EventPayload {
  action: string;
  data: Record<string, unknown>;
}
```

| Field    | Type                      | Description                                     |
| -------- | ------------------------- | ----------------------------------------------- |
| `action` | `string`                  | Event identifier (e.g., `"journey.completed"`). |
| `data`   | `Record<string, unknown>` | Event payload.                                  |

***

## Actions

Standard action identifiers for events the journey emits and commands the host sends. Use the constants to avoid magic strings that drift.

### BridgeActions

Known action identifiers used in events. Imported as `BridgeActions` and typed as `BridgeAction`.

```typescript theme={null}
export const BridgeActions = {
  // Journey lifecycle (iframe → host)
  JOURNEY_STARTED: 'journey.started',
  JOURNEY_COMPLETED: 'journey.completed',
  JOURNEY_FAILED: 'journey.failed',
  JOURNEY_ABANDONED: 'journey.abandoned',
  JOURNEY_ERROR: 'journey.error',
  JOURNEY_PAGE_CHANGED: 'journey.page.changed',
  JOURNEY_SUBMISSION_STARTED: 'journey.submission.started',
  JOURNEY_SUBMISSION_COMPLETED: 'journey.submission.completed',
  JOURNEY_SUBMISSION_FAILED: 'journey.submission.failed',

  // Capture lifecycle (iframe → host)
  CAPTURE_STARTED: 'capture.started',
  CAPTURE_COMPLETED: 'capture.completed',
  CAPTURE_FAILED: 'capture.failed',
  CAPTURE_RETRIED: 'capture.retried',

  // Host commands (host → iframe)
  HOST_NAVIGATION_BACK: 'host.navigation.back',
  HOST_NAVIGATION_CLOSE: 'host.navigation.close',
  HOST_THEME_UPDATE: 'host.theme.update',
  HOST_LOCALE_UPDATE: 'host.locale.update',
} as const;

export type BridgeAction = (typeof BridgeActions)[keyof typeof BridgeActions];
```

See [Messaging](/docs/go-v2/developer-integration/sdks/web/messaging) for the full bridge event catalogue with payload shapes.

***

## Errors

A typed error class and enum for use in your own handler code when emitting structured errors — plus a helper to normalise unknown codes.

### BridgeError

A typed error class for use in your own host code when emitting structured errors.

```typescript theme={null}
export class BridgeError extends Error {
  readonly code: BridgeErrorCode;
  readonly recoverable: boolean;
  readonly correlationId?: string;

  constructor(
    code: BridgeErrorCode,
    message: string,
    options?: { recoverable?: boolean; correlationId?: string },
  );
}
```

The SDK does not throw `BridgeError` internally — it's a helper for your handler code. Catch it in your own error-handling and forward to `responder.error({ code, message, recoverable })`.

**Example:**

```typescript theme={null}
try {
  // ...
} catch (err) {
  if (err instanceof BridgeError) {
    responder.error({ code: err.code, message: err.message, recoverable: err.recoverable });
  } else {
    responder.error({ code: BridgeErrorCode.INTERNAL_ERROR, message: String(err), recoverable: false });
  }
}
```

***

### BridgeErrorCode

```typescript theme={null}
export enum BridgeErrorCode {
  UNSUPPORTED = 'UNSUPPORTED',
  PERMISSION_DENIED = 'PERMISSION_DENIED',
  CANCELLED = 'CANCELLED',
  TIMEOUT = 'TIMEOUT',
  BUSY = 'BUSY',
  INVALID_REQUEST = 'INVALID_REQUEST',
  INTERNAL_ERROR = 'INTERNAL_ERROR',
  VERSION_MISMATCH = 'VERSION_MISMATCH',
}
```

| Code                | Meaning                                                       |
| ------------------- | ------------------------------------------------------------- |
| `UNSUPPORTED`       | The host does not support this action.                        |
| `PERMISSION_DENIED` | The user or browser denied the required permission.           |
| `CANCELLED`         | The user cancelled the operation.                             |
| `TIMEOUT`           | The request timed out.                                        |
| `BUSY`              | The host is already handling another request for this action. |
| `INVALID_REQUEST`   | The request payload was malformed.                            |
| `INTERNAL_ERROR`    | An unexpected error in the handler.                           |
| `VERSION_MISMATCH`  | Protocol version mismatch.                                    |

The SDK additionally emits `HANDLER_FAILURE` (string literal, not in this enum) when a registered handler throws an uncaught exception and hasn't already responded.

***

### toBridgeErrorCode

```typescript theme={null}
export function toBridgeErrorCode(code: string | undefined): BridgeErrorCode
```

Validates that a string matches a known `BridgeErrorCode`, falling back to `INTERNAL_ERROR` otherwise. Useful when receiving error codes from external sources (e.g., parsing a response from the iframe).

| Parameter | Type                  | Description             |
| --------- | --------------------- | ----------------------- |
| `code`    | `string \| undefined` | The string to validate. |

**Returns:** A `BridgeErrorCode` enum value.

***

## Interfaces

Contracts your host code implements — one for capability handlers, one for observing bridge activity.

### BridgeCapabilityHandler

The contract for objects that handle bridge request actions.

```typescript theme={null}
export interface BridgeCapabilityHandler {
  handle(
    request: BridgeMessage,
    responder: BridgeResponder,
  ): void | Promise<void>;
}
```

A handler may be synchronous or asynchronous. Returning a Promise that rejects has the same effect as throwing synchronously — the host's exception handler kicks in.

If the handler throws or its returned Promise rejects, and the responder has not been called, the host automatically sends an `error` response with `code: "HANDLER_FAILURE"` and `recoverable: false` so the journey is never left waiting.

**Example:**

```typescript theme={null}
const documentCaptureHandler: BridgeCapabilityHandler = {
  handle: async (request, responder) => {
    const data = (request.payload as RequestPayload).data;
    const side = data.side as string; // "front" | "back"
    const image = await captureDocument(side);
    responder.success({ image });
  },
};

host.registerHandler("camera.document.capture", documentCaptureHandler);
```

***

### BridgeHostDelegate

An observer interface for monitoring bridge activity. All methods are optional.

```typescript theme={null}
export interface BridgeHostDelegate {
  onMessage?(host: BridgeHost, message: BridgeMessage): void;
  onUnhandledRequest?(host: BridgeHost, request: BridgeMessage): void;
  onMessageSent?(host: BridgeHost, message: BridgeMessage): void;
  onError?(host: BridgeHost, error: Error): void;
}
```

| Method               | When called                                                                                                                         |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `onMessage`          | Every validated inbound message (after origin and envelope checks pass).                                                            |
| `onUnhandledRequest` | A `request`-type message arrived but no handler is registered for its action. The message is also pushed to `host.pendingRequests`. |
| `onMessageSent`      | Every outbound message — responses and events. Fires even when the underlying transport drops the message (e.g., iframe detached).  |
| `onError`            | An internal error occurred — handler exception, delegate exception, send failure, etc.                                              |

Delegate method exceptions are caught: a throw from `onMessage` or `onUnhandledRequest` is routed to `onError`. A throw from `onError` is logged via `console.warn` and swallowed (preventing recursion).

***

## Classes

Concrete classes exposed by the SDK. Integrators use them but don't instantiate them directly — the host creates them and hands them to your handlers.

### BridgeResponder

Handed to handlers as the second argument. Used to send a response to the originating request.

```typescript theme={null}
export class BridgeResponder {
  get hasResponded(): boolean;
  acknowledge(): this;
  success(data?: Record<string, unknown>): void;
  error(error: ResponseError): void;
  cancelled(reason?: string): void;
  unsupported(reason?: string): void;
}
```

**Why it exists:** Decouples the handler from the host. Handlers don't need to know about `postMessage` or correlation IDs — they just call a terminal method.

You don't instantiate `BridgeResponder` directly. The host creates one per inbound request and passes it to the handler.

#### Properties

State exposed on the responder instance.

##### hasResponded

```typescript theme={null}
get hasResponded(): boolean
```

`true` after a terminal method (`success`, `error`, `cancelled`, `unsupported`) has been called. `acknowledge` does not set this to `true`.

***

#### Methods

One interim method (`acknowledge`) and four terminal methods — call exactly one terminal per request.

##### acknowledge

```typescript theme={null}
acknowledge(): this
```

Sends an interim `acknowledged` response to signal "I got it, working on it". Chainable. At-most-once on the wire — no-op after a prior `acknowledge` or after a terminal status.

Use this for long-running operations to confirm receipt before the terminal response. The journey-side SDK uses acknowledgment to distinguish "host received but slow" from "host never received" timeout cases.

**Returns:** The responder itself, for chaining.

***

##### success

```typescript theme={null}
success(data?: Record<string, unknown>): void
```

Sends a terminal `success` response. Subsequent calls on this responder are no-ops.

| Parameter | Type                      | Default     | Description             |
| --------- | ------------------------- | ----------- | ----------------------- |
| `data`    | `Record<string, unknown>` | `undefined` | Optional response data. |

***

##### error

```typescript theme={null}
error(error: ResponseError): void
```

Sends a terminal `error` response with the given error details.

| Parameter | Type                              | Description                                |
| --------- | --------------------------------- | ------------------------------------------ |
| `error`   | [`ResponseError`](#responseerror) | Error code, message, and recoverable flag. |

***

##### cancelled

```typescript theme={null}
cancelled(reason?: string): void
```

Sends a terminal `cancelled` response. When `reason` is provided, the response includes an `error` payload with `code: "CANCELLED"` and `recoverable: true`.

| Parameter | Type     | Description                   |
| --------- | -------- | ----------------------------- |
| `reason`  | `string` | Optional cancellation reason. |

***

##### unsupported

```typescript theme={null}
unsupported(reason?: string): void
```

Sends a terminal `unsupported` response. When `reason` is provided, the response includes an `error` payload with `code: "UNSUPPORTED"` and `recoverable: false`.

| Parameter | Type     | Description      |
| --------- | -------- | ---------------- |
| `reason`  | `string` | Optional reason. |

***

## Built-in handlers

Handlers the SDK auto-registers for you. Documented here so you know what to look for in `capability.query` responses and how to override them if needed.

### CapabilityQueryHandler

The handler for `"capability.query"` requests. Automatically registered by `BridgeHost` — you do not register this yourself.

```typescript theme={null}
export class CapabilityQueryHandler implements BridgeCapabilityHandler {
  constructor(
    hostVersion: string,
    capabilitiesProvider: () => CapabilityMap,
  );
  handle(request: BridgeMessage, responder: BridgeResponder): void;
}
```

**Why it exists:** Capability negotiation is a fundamental part of the protocol. The handler is auto-registered so journeys can always discover capabilities without integrator setup.

#### Response format

```json theme={null}
{
  "environment": "web",
  "hostVersion": "1.0.0",
  "capabilities": {
    "camera.document": {
      "supported": true,
      "version": "1.0",
      "permissionState": "granted"
    }
  }
}
```

| Field          | Type                                                       | Description                                                                                            |
| -------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `environment`  | `"web"`                                                    | Always `"web"` for this SDK. iOS reports `"ios"`, Android reports `"android"`.                         |
| `hostVersion`  | `string`                                                   | The host version from `BridgeHostOptions`.                                                             |
| `capabilities` | `Record<string, { supported, version, permissionState? }>` | The effective capability map. `version` is `null` when unset. `permissionState` is omitted when unset. |

The handler is constructed automatically by `BridgeHost` with a provider that returns the current `buildEffectiveCapabilities()` map (`capabilities` option merged with `registerCustomCapability` entries). Calling `unregister('capability.query')` removes it and stops automatic responses — the SDK warns when this happens.

***

## React context

These are the low-level context types exported from `@gbg/go-bridge-web-react`. Most integrators do not interact with them directly — the hooks wrap them. Exposed for advanced cases (custom providers, testing).

### BridgeHostContext

```typescript theme={null}
export const BridgeHostContext: React.Context<BridgeHostContextValueInternal>
```

The React context that `BridgeHostProvider` populates. The default value (used outside any provider) is a marker that lets hooks detect missing providers and issue a one-time warning.

***

### BridgeHostContextValue

```typescript theme={null}
export interface BridgeHostContextValue {
  host: BridgeHost | null;
  subscribeEvent(action: string, listener: BridgeHostEventListener): () => void;
  subscribeError(listener: BridgeHostErrorListener): () => void;
}
```

| Field                              | Description                                                                                                     |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `host`                             | The current `BridgeHost`, or `null` while the iframe hasn't attached.                                           |
| `subscribeEvent(action, listener)` | Subscribe to a specific event action. Returns an unsubscribe function. Used internally by `useBridgeHostEvent`. |
| `subscribeError(listener)`         | Subscribe to internal errors. Returns an unsubscribe function. Used internally by `useBridgeHostError`.         |

***

### BridgeHostEventListener

```typescript theme={null}
export type BridgeHostEventListener = (data: Record<string, unknown>) => void
```

Listener signature for event subscriptions. Receives the event's `data` payload — the `action` is implicit (it's the action you subscribed with).

***

### BridgeHostErrorListener

```typescript theme={null}
export type BridgeHostErrorListener = (error: Error) => void
```

Listener signature for error subscriptions.

***

## Next steps

* [Concepts](/docs/go-v2/developer-integration/sdks/web/concepts) — Architecture and design rationale behind these types.
* [Embedding](/docs/go-v2/developer-integration/sdks/web/embedding) — Integration patterns by framework.
* [Messaging](/docs/go-v2/developer-integration/sdks/web/messaging) — Event catalogue and request/response semantics.
* [Capability Handling](/docs/go-v2/developer-integration/sdks/web/capability-handling) — Declaring, registering, and dynamic capabilities.
