The most secure integration method. Your server fetches the widget HTML from Returning.AI, injects the JWT token server-side, and serves it to the browser. The API key never touches the client.
Every request flows through your backend. The browser never communicates directly with the Returning.AI API.
Browser -> Your Server -> Returning.AI API
|
1. POST /widget/{id}/signin (get JWT)
2. GET /{widget-type}/{widgetId} (get HTML)
3. Inject token into HTML
|
Browser <- Modified HTML with embedded tokenA clear separation between server-side secrets and browser-visible data.
| Stays on your server | Goes to the browser |
|---|---|
WIDGET_API_KEY | JWT (short-lived, user-scoped) |
WIDGET_COMMUNITY_ID | Widget ID |
| Returning.AI API requests | Rendered widget HTML (with token embedded) |
Five steps from zero to a working server-side proxy.
Keep your API key and community ID in environment variables. They must never be included in client-side code or HTML responses.
WIDGET_BASE_URL=https://prod-widgets.returning.ai
WIDGET_API_KEY=your-api-key
WIDGET_COMMUNITY_ID=your-community-id
WIDGET_ID=your-widget-id
WIDGET_TYPE=storeThe email must come from your verified session or auth middleware - never from a query parameter or request body that the client controls directly.
POST the user's email along with your API key to the signin endpoint.
POST /widget/{communityId}/signin
Headers:
Content-Type: application/json
returningai-api-key: YOUR_API_KEY
email: user@example.com
Response:
{ "token": "eyJhbGciOiJIUzI1NiIs..." }GET the widget page. The HTML comes with an empty token placeholder in the __WIDGET_INIT__ config.
GET /{widget-type}/{widgetId}?color=light
Response:
<!DOCTYPE html>
<html>
<head>...</head>
<body>
<script>
window.__WIDGET_INIT__ = { token: "", ... };
</script>
...
</body>
</html>Replace the empty token placeholder with the JWT, then send the modified HTML to the browser.
// Replace the empty token placeholder with the real JWT
html = html.replace(/token:\s*""/, `token: "${safeToken}"`);How this differs from Widget SDK and Iframe
Unlike the Widget SDK or Iframe methods, the server-side proxy gives you complete control over the authentication flow but requires more backend work. The tradeoff is maximum security for additional implementation effort.