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

# SDK integration

> Tenant integration guide for embedding Narrative SDK with secure token exchange.

<Info>
  Use this page for the end-to-end embedded implementation path. For authentication pattern selection across embedded, standalone, and API auth, use [Authentication](/sdk/authentication). For field-by-field parameter definitions, use [Configuration reference](/sdk/configuration). For embed-runtime decisions, use [Tenant embedding guide](/sdk/tenant-embedding-guide).
</Info>

## Integration handoff map

<Columns cols={3}>
  <Card title="Tenant backend" icon="https://mintcdn.com/narrative-b13c445c/qi6sqKB_OLTe8ty2/SVG/lock.svg?fit=max&auto=format&n=qi6sqKB_OLTe8ty2&q=85&s=be29c8f389110e9dd5032501c0e8f00b" width="64" height="64" data-path="SVG/lock.svg">
    Holds the Connected App secret, validates the tenant user session, and mints the short-lived Embed Token.
  </Card>

  <Card title="Tenant frontend" icon="https://mintcdn.com/narrative-b13c445c/qi6sqKB_OLTe8ty2/SVG/frontend-shell.svg?fit=max&auto=format&n=qi6sqKB_OLTe8ty2&q=85&s=13c676d362a2a3a7a60bfa0fae245ad6" width="64" height="64" data-path="SVG/frontend-shell.svg">
    Loads the SDK script, renders the container, fetches the Embed Token, and hands it to the runtime.
  </Card>

  <Card title="Narrative SDK" icon="https://mintcdn.com/narrative-b13c445c/qi6sqKB_OLTe8ty2/SVG/server.svg?fit=max&auto=format&n=qi6sqKB_OLTe8ty2&q=85&s=4a767cfdcb6585e74810e5c286495132" width="64" height="64" data-path="SVG/server.svg">
    Verifies the token exchange and boots the embedded product surface with tenant-scoped session state.
  </Card>
</Columns>

## Prerequisites

| Requirement                                | Why you need it                                                 | Detailed reference                                    |
| ------------------------------------------ | --------------------------------------------------------------- | ----------------------------------------------------- |
| Connected App provisioned in Narrative SDK | Supplies the client id and secret used for Embed Token signing. | [Configuration reference](/sdk/configuration)         |
| Backend token endpoint in the tenant app   | Mints short-lived Embed Tokens for the current tenant user.     | [Tenant embedding guide](/sdk/tenant-embedding-guide) |
| Frontend host page or mount target         | Gives the SDK a place to render the embedded experience.        | [Configuration reference](/sdk/configuration)         |

<Warning>
  Never mint Embed Tokens in frontend code. Keep the signing secret in your backend secret manager only.
</Warning>

## When to use this page

This page is specific to embedded integration where a tenant backend issues the Embed Token and a tenant-owned frontend hosts the SDK runtime.

* If your user signs in through the Azure AD OIDC flow instead of receiving an Embed Token, start with [Authentication](/sdk/authentication) and [Authentication guide](/sdk/api-auth) instead.
* If you need request-level handling for access tokens, refresh, and sign-out, use [Authentication guide](/sdk/api-auth).

<Steps>
  <Step title="Load the SDK script">
    ```html theme={null}
    <script>
      (function (w, d, s, u, n) {
        w[n] = w[n] || function () { (w[n].q = w[n].q || []).push(arguments) }
        var js = d.createElement(s); js.async = true; js.src = u
        d.head.appendChild(js)
      })(window, document, 'script', '<NSDK_BASE_URL>/nsdk-loader.js', 'NSDK')
    </script>
    ```
  </Step>

  <Step title="Render a container">
    <CodeGroup>
      ```html Static HTML theme={null}
      <div id="nsdk-container" data-nsdk="true" data-nsdk-widget="insights"></div>
      ```

      ```tsx React theme={null}
      <div id="nsdk-container" data-nsdk="true" data-nsdk-widget="insights" />
      ```
    </CodeGroup>
  </Step>

  <Step title="Provide the Embed Token">
    ```js Browser theme={null}
    const { embed_token } = await fetch('/your-embed-token-endpoint').then((r) => r.json())
    document.getElementById('nsdk-container')?.setAttribute('data-nsdk-token', embed_token)
    ```
  </Step>
</Steps>

## What happens across the boundary

```mermaid theme={null}
sequenceDiagram
  participant Frontend as Tenant frontend
  participant Backend as Tenant backend
  participant SDK as Narrative SDK

  Frontend->>Backend: Fetch Embed Token for current user
  Backend-->>Frontend: Short-lived Embed Token
  Frontend->>SDK: Load nsdk-loader.js and provide token
  SDK->>SDK: Verify token claims and signature
  SDK-->>Frontend: Render embedded widget
```

## Integration checkpoints

<AccordionGroup>
  <Accordion title="1. Loader script is reachable">
    Confirm that `<NSDK_BASE_URL>/nsdk-loader.js` loads successfully from the tenant frontend before debugging token or render issues.
  </Accordion>

  <Accordion title="2. Token endpoint is authenticated and server-side only">
    The token route must run on the tenant backend, validate the current tenant user, and sign the token with the Connected App secret.
  </Accordion>

  <Accordion title="3. Container exists before token handoff">
    In declarative mode, the `data-nsdk` container must exist before the SDK runtime reads the token and boots the widget.
  </Accordion>

  <Accordion title="4. Token exchange succeeds before API-level testing">
    Only after the widget can boot cleanly should you move on to downstream auth and surface API validation.
  </Accordion>
</AccordionGroup>

## Delivery checklist

| Check                                          | Expected result                                                           |
| ---------------------------------------------- | ------------------------------------------------------------------------- |
| Loader script loads from `NSDK_BASE_URL`       | Browser loads `nsdk-loader.js` with no origin or CSP failures.            |
| Token endpoint returns a fresh Embed Token     | Response includes a short-lived token for the current tenant user.        |
| SDK container renders                          | Embedded widget mounts without token or config errors.                    |
| Protected APIs succeed after boot              | Authenticated requests can reach downstream Coach, Money, or Growth APIs. |
| Token and secret handling are server-side only | No Connected App secret or signing logic appears in frontend code.        |

## Common errors and troubleshooting

<AccordionGroup>
  <Accordion title="CORS blocks token endpoint">
    Use same-origin route, proxy, or explicit CORS with credentials configuration.
  </Accordion>

  <Accordion title="Invalid signature">
    Ensure token is signed with the Connected App secret matching `iss`.
  </Accordion>

  <Accordion title="Invalid audience">
    Set `aud` exactly to `nsdk-embed`.
  </Accordion>

  <Accordion title="Clock skew or wrong time unit">
    Use Unix seconds (not milliseconds) and keep server time synchronized.
  </Accordion>

  <Accordion title="Need exact claim, field, or boot parameter definitions">
    Use [Configuration reference](/sdk/configuration) for the detailed parameter table and [Tenant embedding guide](/sdk/tenant-embedding-guide) for runtime boot choices.
  </Accordion>
</AccordionGroup>

<Info>
  For the complete troubleshooting guide covering all common integration issues, see [Troubleshooting](/sdk/troubleshooting). For common questions, see [FAQ](/sdk/faq).
</Info>
