Legacy approach
For new integrations, use the Widget SDK with Access Key Embed.
Migrating to Access Key Embed
Use this migration checklist before changing an installed integration. The following token-auth changes do not establish drop-in compatibility for every old loader, widget ID or bundle. Ask Returning.AI to confirm the supplied setup, including permitted legacy maintenance and support scope; retained documentation is not a support deadline.
If you are currently using auth-url token auth, here is what changes:
- Endpoint: Replace your
POST /widget/{id}/signincall withPOST /v2/api/widget-access-keys/token. - Attribute: Replace
auth-urlwithembed-tokenon the widget tag. - Refresh: Legacy
auth-urlcan auto-refresh using refresh tokens. Access Key Embed does not call your backend for a newembed-token; fetch a fresh token and update the attribute. The SDK watches this attribute (added in 1.4.2); use the current release 1.8.11, with reload as an older-build fallback.
See the Access Key guide for the full walkthrough.
- Inventory the installation. Record the actual loader and SDK versions, widget ID, URL, rendering mode, public attributes, callbacks, listeners/storage, identity mapping and credential dependencies. Store secret values separately.
- Confirm the replacement. Obtain the approved widget ID and matching bundle URL. Copy IDs unchanged; do not translate old attributes or recreate users by guessing. Have the setup owner confirm which configuration and user history must carry across.
- Prove the same-user journey before cutover. Confirm usable membership, identity, saved state and the expected widget view. Test logout/account switch and the bundle's display refresh separately from token renewal.
- Confirm cleanup and rollback before cutover. Identify exactly how the old loader releases its listeners, callbacks and owned storage. Keep only one active host integration as a default, not as proof that the two implementations are compatible. Do not clear unrelated browser storage.
- Keep a usable return path. Save the approved prior configuration and verify its identity/credential dependencies still work. A revoked credential or changed mapping can invalidate rollback; never restore compromised credentials. Unknown cleanup, continuity or rollback dependencies stop cutover until the responsible owner supplies evidence.
- Record approval and switch. Name the cutover owner, pause condition and verified rollback action in the handover decision gates. Referral integrations also need their relationship and qualification checks.
Rendering and authentication are separate choices. Confirm Access Key and iframe compatibility for the actual supplied widget/version before retaining iframe mode; this checklist does not certify an unknown legacy loader.
Auth - Token
Sign users in server-side so the widget loads pre-authenticated. The user never sees a login screen - the token is fetched behind the scenes before the widget renders.
Attribute auth vs token auth
| Attribute authentication | Token authentication | |
|---|---|---|
| User identity | Client-side via data-* attributes (email, userId, etc.) | Server-verified via API key |
| Backend required | No | Yes |
| Token flow | None - attributes passed directly | Your backend calls Returning.AI, returns a short-lived token |
| User experience | Seamless - user identified by attributes | Seamless - already signed in |
| Best for | Quick integrations, internal tools, controlled environments | Logged-in areas, client portals, trader dashboards |
Step 1 - Create a backend endpoint
Your server calls the Returning.AI sign-in API with your secret API key and the current user's email. It receives a short-lived token that the SDK will use to authenticate the widget session.
Keep your API key server-side
Never expose WIDGET_API_KEY in client-side code. It should only exist in environment variables on your backend.
app.post('/api/widget-auth', async (req, res) => {
const response = await fetch(
'https://prod-widgets.returning.ai/widget/{community_id}/signin',
{
method: 'POST',
headers: {
'returningai-api-key': process.env.WIDGET_API_KEY,
'email': req.user.email,
'Content-Type': 'application/json',
},
}
)
const data = await response.json()
res.json({ token: data.token })
})Step 2 - Point the widget to your endpoint
Add the auth-url attribute to your widget tag. The SDK will POST to that URL on load, receive the token, and authenticate automatically.
<rai-channel-widget
community-id="YOUR_COMMUNITY_ID"
widget-url="YOUR_WIDGET_URL"
auth-url="/api/widget-auth"
></rai-channel-widget>How the flow works
- Widget mounts and detects the
auth-urlattribute. - SDK sends a POST request to your backend endpoint.
- Your backend verifies the user and calls the Returning.AI sign-in API.
- Your backend returns the token to the SDK.
- SDK passes the token into the widget iframe - the user is signed in.
Token expiry and refresh
Tokens are short-lived (typically around 5 minutes). The SDK handles renewal automatically - when a token is about to expire, it re-calls your auth-url endpoint to fetch a fresh one. No extra code is needed on your side.
If the refresh fails (e.g. the user's session has expired on your backend), the widget fires an rai-error event that you can listen for to prompt re-authentication.