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.
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.
| Connection | What to provide |
|---|---|
adapter | Catalogue 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.
import { handleGlassHouse } from './glasshouse.server'
export const GET = handleGlassHouse
export const POST = handleGlassHouseUse 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.
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.
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
curl https://store.example/api/glasshouse/configYou 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.