Setup

    Live in five minutes

    Install the SDK, mint a token, render the component.

    Step 01

    Install

    npm
    npm i @gtwy/chat        # web + React
    npm i @gtwy/chat-react-native
    Step 02

    Mint an embed token

    Server-side, one per user session. Never ship your API key to the browser.

    Your backend
    const token = jwt.sign(
      { user_id: "cus_4127" },
      process.env.GTWY_JWT_SECRET,
      { expiresIn: "1h" }
    );
    Step 03

    Render the component

    React
    import { GtwyChat } from "@gtwy/chat";
    
    <GtwyChat
      botId="bot_4127"
      token={token}
      theme={{ primary: "#0E9F6E", radius: 12 }}
      position="bottom-right"
      onMessage={(m) => track("chat_message", m)}
    />
    PropTypeDefaultNotes
    botIdstringRequired
    tokenstringSigned server-side, scoped to one user
    themeobjectlightprimary, radius, font, mode
    positionstringbottom-rightOr inline, to embed in a page
    threadIdstringautoResume a specific conversation
    openbooleanfalseControlled open state
    Step 04

    Threads, events and control

    Programmatic
    const chat = GtwyChat.instance();
    
    chat.open();
    chat.send("show me last quarter");
    chat.close();
    
    chat.on("message:sent",     (m) => {});
    chat.on("message:received", (m) => {});
    chat.on("tool:called",      (t) => {});
    chat.on("conversation:end", (c) => {});
    
    // resume where the user left off
    chat.setThread(user.lastThreadId);

    Customisation

    Making it yours.

    Themecolour, radius, font, light / dark
    Custom CSSfor anything tokens don’t cover
    Positioncorner launcher or inline in a page
    Launcher iconyour own asset
    Mobile behaviourfull-screen or sheet
    LocalisationUI strings per locale

    Knowledge and tools

    Giving it something to work with.

    Connect a knowledge base and it answers from your documents, citing what it used. Connect tools and it can act — look up an order, book a slot, open a ticket.

    GTWY Knowledge →
    Tools and integrations →

    Troubleshooting

    When it doesn’t appear.

    The widget isn’t showing up

    Check the script actually rendered in the page source, not just in your template. On most platforms the cause is a cached page or code pasted into a preview rather than the published site. Then confirm the bot ID matches a published bot — a draft bot loads nothing.

    Content Security Policy is blocking it

    Allow embed.gtwy.ai in script-src and connect-src. If you use a nonce, pass it on the script tag; the widget injects no inline styles that need unsafe-inline.

    Token errors — 401 or 403

    401 means the signature or expiry failed: check the secret matches and the clock on your server is right. 403 means the token is valid but scoped to a different user than the one being requested.

    Your styles are leaking into the widget

    The widget renders in a shadow root, so global CSS should not reach it. If it does, something is matching on * at the document level — usually a reset applying to every element including custom ones.

    It works on desktop, not on mobile

    Usually a viewport meta tag missing on the host page, or a fixed-position parent clipping the launcher. Set the widget to full-screen mode on small viewports.

    Get your embed token.

    Free forever tier, no card. Five minutes from here to live.