One line to install.
Full API when you need it.
Drop in a script tag and you're live. Use the JavaScript API to identify users, share context with agents, and control the widget programmatically.
Install
All plansPaste before the closing </body> tag on every page. Replace YOUR_SITE_ID with the ID from your dashboard.
<script src="https://api.ghostchat.dev/widget.js" data-site="YOUR_SITE_ID"></script>~10KB gzipped. No cookies, no tracking, no external dependencies. Read the source →
JavaScript API
All plansControl the widget programmatically. The GhostChat global is available after the script loads.
// Open / close / toggle the widget
GhostChat.open()
GhostChat.close()
GhostChat.toggle()
// Pre-fill visitor info (shown to your agents)
GhostChat.identify({
name: "Jane Doe",
email: "jane@example.com"
})
// Listen for events
GhostChat.on("open", () => console.log("widget opened"))
GhostChat.on("close", () => console.log("widget closed"))
GhostChat.on("message", (msg) => console.log("new message:", msg))identify()
Pre-fills visitor name and email shown in your dashboard. Call after login or when the user's identity is known.
on(event, callback)
Events: open, close, message. Use to trigger analytics, surveys, or custom UI.
Embed Mode
All plansRender the chat inline instead of as a floating bubble — useful for support pages or help centers. The widget auto-detects the container and hides the floating button.
<!-- Add this anywhere on the page — no extra script needed -->
<div id="ghostchat-embed" style="width: 400px; height: 600px;"></div>Works on WordPress, Shopify, static HTML, and any traditional multi-page site. Not supported in SPAs with client-side navigation (React, Next.js app router).
Visitor Context API
Pro+Push any data to your agents in real-time — cart contents, user plan, page type, or anything else. Context appears as purple pills in the conversation header so your team knows what the visitor needs before they ask.
WooCommerce keys: cart_items, cart_total, product_name, cart_count, page_type
Any custom keys via setContext()
// Share cart contents, page info, or any custom data
GhostChat.setContext({
cart: ["Brake Pad Kit", "Oil Filter"],
vehicle: "2022 Can-Am Maverick X3",
page: "checkout"
})
// Merge more context later — previous keys are kept
GhostChat.setContext({ coupon: "SAVE10" })
// Clear a key by setting it to null
GhostChat.setContext({ coupon: null })Merge behavior
Each call merges with existing context. Nested objects are replaced (shallow merge), not deep-merged.
Limits
Max 10 keys per session. 4KB total payload. Updates throttled to once per 5 seconds.
Lifecycle
Context persists for the session. Cleared when the conversation is deleted or session expires.
WooCommerce — zero config
Our WordPress plugin auto-sends these keys on every page load and cart update:
page_typeproduct_namecart_itemscart_totalcart_countShopify — manual
No auto-integration. Call setContext() from your theme's JS with Liquid variables.
Webhooks
BusinessReceive a POST request every time a visitor sends a message. Connect to Slack, your CRM, a support ticket system, or any custom automation.
// POST sent to your URL on each visitor message
{
"event": "message.new",
"siteId": "cl194a6c5368cc4cceb600c436",
"siteName": "My Store",
"sessionId": "sess_abc123",
"messageId": "msg_xyz789",
"content": "Hi, I need help with my order",
"visitorEmail": "jane@example.com",
"visitorName": "Jane",
"pageUrl": "https://mystore.com/checkout",
"referrer": "https://mystore.com/cart",
"country": "US",
"createdAt": "2026-03-16T12:00:00Z"
}Configure your webhook URL in Dashboard → Sites → [your site] → Webhook URL. Available on the Business plan ($25/mo). View pricing →
FAQ
When is the GhostChat API available to call?
The API is ready once the widget script has loaded. For SPAs, call GhostChat.identify() or GhostChat.setContext() after your user data is available — both methods queue calls if the widget isn't ready yet.
Does GhostChat work with React or Next.js?
Yes. Add the script tag once in your root layout (or use the useEffect pattern shown above). Embed mode works on traditional multi-page sites only — SPA client-side navigation is not supported for embed mode.
Can I trigger the widget from a custom button?
Yes. Call GhostChat.open() from any click handler. You can hide the default floating bubble by adding CSS: #ghostchat-root .ghostchat-bubble { display: none; } — then drive opens entirely from your own UI.
How do I test webhooks locally?
Use a tool like ngrok to expose your local server, then paste the ngrok URL as your webhook URL in Dashboard → Sites → [site] → Webhook URL. Webhooks require the Business plan.
Ready to integrate?
Free forever for 1 site. No credit card required. Get your Site ID in 30 seconds.