Two ways to identify users in Returning.AI widgets. Both are legitimate strategies with different tradeoffs.
Pass user identity directly via HTML attributes (data-email, data-userId, etc.) or URL query parameters. No backend required. Security through stacking: the more attributes you add, the harder to spoof. Can include custom fields for additional security layers.
Your backend calls Returning.AI's signin endpoint with your API key and the user's email. It receives a short-lived token that the widget uses for authenticated API calls. The API key never touches the client.
The token authentication flow follows a four-step process:
Your backend authenticates the user
The user logs in through your existing authentication system (session, JWT, OAuth, etc.).
Your backend calls the Returning.AI signin endpoint
Your server sends a POST request to https://prod-widgets.returning.ai/widget/{community_id}/signin with the user's email and your API key in the headers.
Returning.AI returns a session token
The API responds with a short-lived token that identifies the user session.
The token is passed to the widget
For the Widget SDK, this happens automatically via the auth-url attribute. For iframe embeds, the token is exchanged via postMessage. For server proxy, the token is injected into the HTML server-side.
// Simplified token auth flow (Node.js 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 })
})Session tokens are short-lived and will expire. How token refresh is handled depends on your integration method:
| Method | Token Refresh |
|---|---|
| Widget SDK | Automatic. The SDK monitors token expiry and re-calls your auth-url endpoint to refresh. |
| Iframe Embed | Manual. The widget iframe sends a RETURNINGAI_WIDGET_REQUEST_TOKEN postMessage when the token expires. Your page must listen for this event and respond with a fresh token. |
| Server Proxy | Server-managed. Your backend fetches a new token on each page load or when the cached token expires. |
Both methods are valid authentication strategies. Choose based on your requirements:
| Attribute Auth | Token Auth | |
|---|---|---|
| Backend required | No | Yes |
| API key exposure | Not applicable | Server-side only |
| Identity verification | Client-provided attributes | Server-verified via API key |
| Spoofing resistance | Increases with more stacked attributes | High (server-side verification) |
Never expose your API key
When using token authentication, never include your API key in client-side code. Always use a server-side proxy endpoint. If your key is compromised, rotate it immediately from the Returning.AI admin panel.
Choose the guide that matches your integration method:
Pass identity via data-* attributes on the widget element.
Use the auth-url attribute for automatic token management.
Pass identity via URL query parameters on the iframe source.
Use postMessage to exchange tokens between your page and the widget iframe.