Skip to main content

SDK integration

This guide is for tenant engineers embedding Narrative SDK UI into an existing web application.

Prerequisites

You need:
  • a Connected App provisioned in Narrative SDK
  • a backend endpoint in your tenant app that mints Embed Tokens

Required values

ValueSuggested env varWhere it livesNotes
NSDK host base URLNSDK_BASE_URLTenant frontend configExample: https://sdk.narrativebanking.com
Connected App client idNSDK_CONNECTED_APP_CLIENT_IDTenant backend configUsed as JWT iss
Connected App secret keyNSDK_CONNECTED_APP_SECRET_KEYTenant backend onlyHS256 signing key, never expose to frontend
Never mint Embed Tokens in frontend code. Keep the signing secret in your backend secret manager only.
1

Load the SDK script

<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>
2

Render a container

<div id="nsdk-container" data-nsdk="true" data-nsdk-widget="insights"></div>
3

Provide the Embed Token

Browser
const { embed_token } = await fetch('/your-embed-token-endpoint').then((r) => r.json())
document.getElementById('nsdk-container')?.setAttribute('data-nsdk-token', embed_token)

Embed Token requirements

  • Standard: RFC 7519
  • Algorithm: HS256
  • Audience: nsdk-embed
  • Recommended expiry: 5-15 minutes
Required claims:
ClaimTypeRequirement
issstringConnected App client id
substringTenant user identifier
audstringMust be nsdk-embed
iatnumberUnix timestamp (seconds)
expnumberUnix timestamp (seconds)
jtistringUnique token id
Required nsdk fields:
  • nsdk.user.name
  • nsdk.user.email

Token minting endpoint example

import jwt from 'jsonwebtoken'
import crypto from 'crypto'

const CLIENT_ID = process.env.NSDK_CONNECTED_APP_CLIENT_ID
const SECRET_KEY = process.env.NSDK_CONNECTED_APP_SECRET_KEY

app.get('/your-embed-token-endpoint', (req, res) => {
  const user = req.user
  const now = Math.floor(Date.now() / 1000)

  const payload = {
    iss: CLIENT_ID,
    sub: user.id,
    aud: 'nsdk-embed',
    iat: now,
    exp: now + 900,
    jti: crypto.randomUUID(),
    nsdk: {
      user: { name: user.name, email: user.email },
      metadata: { source: 'tenant_app' }
    }
  }

  const embed_token = jwt.sign(payload, SECRET_KEY, { algorithm: 'HS256' })
  res.json({ embed_token, expires_in: 900, token_type: 'embed' })
})

Common errors and troubleshooting

Use same-origin route, proxy, or explicit CORS with credentials configuration.
Ensure token is signed with the Connected App secret matching iss.
Set aud exactly to nsdk-embed.
Use Unix seconds (not milliseconds) and keep server time synchronized.