GlassHouse Docs Support
Custom stores

Connect your server

Use your existing backend to connect GlassHouse to products and shopper sessions.

Create the handler

Install the same GlassHouse package in your server project. Create your SuperSeeded API key and save it as GLASSHOUSE_MERCHANT_TOKEN in your server environment. Set STORE_ORIGIN to the store’s canonical HTTPS origin.

glasshouse.server.ts
import { createGlassHouseHandler } from '@superseeded/glasshouse/server'
import {
  adapter,
  resolveShopper,
  rateLimit,
  consumeNonce,
} from './store-integration'

export const handleGlassHouse = createGlassHouseHandler({
  origin: process.env.STORE_ORIGIN!,
  merchantToken: process.env.GLASSHOUSE_MERCHANT_TOKEN!,
  adapter,
  resolveShopper,
  rateLimit,
  consumeNonce,
})

./store-integration is your application code. Implement the four functions below using your catalogue, sessions and shared storage.

ConnectionWhat to provide
adapterCatalogue and product lookups, plus an optional cart connection.
resolveShopper(request)Return a stable shopper ID from your verified session, or null when no session exists. Create guest sessions in your store middleware.
rateLimit(key, limit, windowSeconds)Atomically count requests in shared storage. Return true when the request is allowed.
consumeNonce(key, ttlSeconds)Atomically insert a key with expiry. Return true only on its first use.

Serve the route

Route all /api/glasshouse/* requests to the handler, including /api/glasshouse/agent-tools. The handler accepts a standard Request and returns a Response.

Web-standard route
import { handleGlassHouse } from './glasshouse.server'

export const GET = handleGlassHouse
export const POST = handleGlassHouse

Use this pattern in a framework that accepts Web Request/Response route handlers. Place the file in that framework’s catch-all route for /api/glasshouse/*.

Node HTTP or Express

Wrap the handler with the Node bridge. In Express, register it before any JSON/body parser and before middleware that rewrites the URL.

Node handler
import { createNodeHandler } from '@superseeded/glasshouse/node'
import { handleGlassHouse } from './glasshouse.server'

export const glasshouseRoute = createNodeHandler(
  handleGlassHouse,
  process.env.STORE_ORIGIN!,
)
// In your server router, send /api/glasshouse/* requests
// to glasshouseRoute(req, res).

Run shopper-session middleware before the bridge. The incoming URL must retain the full /api/glasshouse/… path.

Register the store

Run registration once from trusted server code during setup. Use the exact origin that hosts your storefront.

Store registration
import { registerGlassHouseStore } from '@superseeded/glasshouse/server'

await registerGlassHouseStore({
  origin: process.env.STORE_ORIGIN!,
  merchantToken: process.env.GLASSHOUSE_MERCHANT_TOKEN!,
  label: 'My nursery',
})

Check the connection

Terminal
curl https://store.example/api/glasshouse/config

You should receive capabilities and agentUrl. Then mount the browser interface and open a conversation from your store.

Sessions, storage and signed callbacks

Keep merchant credentials on the server. The browser receives a short-lived shopper token. Browser writes use the same origin and the store’s existing session.

Use atomic, shared storage for request limits and callback nonces, including across serverless instances. A process-local map does not provide that guarantee.

SuperSeeded sends signed product requests to agent-tools. The handler verifies their signatures and replay protection. Keep that route reachable from the service; it uses signed authentication instead of shopper cookies.

Deployment choices

The Node bridge targets Node.js 22+. The standard handler uses Fetch and Web Crypto and can be connected to compatible function or worker runtimes. Supply environment values through your runtime’s server configuration.

For a static storefront, place the server routes behind the storefront’s origin. For local development, the handler accepts HTTP on localhost; connected chat requires a registered HTTPS store the service can reach.

Tab to a result, then press Enter to open it.