SimpleAgentChat

A demo customer site embedding the XYZ AI chat widget

This page represents a customer's website that integrates the XYZ AI chat widget. In production, any site can embed the widget by including a small script snippet and a server-side token endpoint. The chat bubble in the bottom-right corner is the embedded widget in action.

Architecture

Credentials stay server-side — the appSecret never reaches the browser. The widget uses short-lived JWTs that are automatically refreshed.

Your Backend (server.js)        XYZ AI API                    Browser Widget
        |                            |                              |
        |  1. POST /api/v1/auth/token|                              |
        |    { appId, appSecret,     |                              |
        |      endUserId }           |                              |
        |--------------------------->|                              |
        |                            |                              |
        |    { token, expiresAt }    |                              |
        |<---------------------------|                              |
        |                            |                              |
        |  2. Return JWT to browser  |                              |
        |---------------------------------------------------------->|
        |                            |                              |
        |                            |  3. Chat via widget          |
        |                            |     Authorization: Bearer eyJ|
        |                            |<-----------------------------|
        |                            |                              |
        |                            |     Streaming response       |
        |                            |---------------------------->|
        |                            |                              |

TOKEN REFRESH (automatic)
=========================
Proactive: ~60s before expiry, the widget calls fetchToken()
Reactive:  on 401 response, the widget calls fetchToken() and retries once

        |                            |                              |
        |  4. Widget calls           |                              |
        |     fetchToken()           |                              |
        |<-----------------------------------------------------------
        |                            |                              |
        |  5. POST /api/v1/auth/token|                              |
        |    { appId, appSecret,     |                              |
        |      endUserId }           |                              |
        |--------------------------->|                              |
        |                            |                              |
        |    { new token }           |                              |
        |<---------------------------|                              |
        |                            |                              |
        |  6. Return new JWT         |                              |
        |---------------------------------------------------------->|
        |                            |                              |
        |                            |  Widget continues with       |
        |                            |  new token seamlessly        |
        |                            |                              |

Embed Snippet

Paste this into any page to add the chat widget. A JWT token is required — get one from POST /api/v1/auth/token with appId, appSecret, and endUserId:

<script>
  window.XYZChat = {
    token: 'JWT_TOKEN',
    host: 'https://xyzaimvp-production.up.railway.app',
    chatHost: 'https://xyzai-mvp.vercel.app',
    fetchToken: async function() {
      var res = await fetch('/api/your-token-endpoint', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ userId: 'END_USER_ID' })
      });
      return (await res.json()).data.token;
    }
  };
</script>
<script src="https://xyzaimvp-production.up.railway.app/widget/xyz-chat.js" async></script>