Documentation
Overview
MatchWiser is an AI lead qualification widget you embed on your website. Visitors open a chat, the AI qualifies them naturally, and only the best-fit leads receive your call-to-action.
The system has two parts:
The widget
A JavaScript file you embed on your site. Handles the chat UI, sends messages to your proxy, and triggers the CTA on qualification.
The proxy server
A Node.js server you deploy on your own infrastructure. Holds your LLM API key, validates requests, and streams AI responses. Visitor data never leaves your server.
Quick start
From purchase to live widget in under 15 minutes.
Configure your widget
Purchase and download
Deploy the proxy
Embed the widget
MatchWiser.init() call into your HTML just before </body>. Your widget is live.Embedding the widget
Add a container element and the widget script to your HTML. Everything below is pre-filled in your download — you only need to copy and paste.
1. Add a container
Place an empty <div> where you want the widget to appear. The id must match containerId in your config.
<div id="my-widget"></div>
2. Load the script and initialise
<script src="/matchwiser.iife.js"></script>
<script>
MatchWiser.init({
widgetId: "your-widget-id",
propId: "your-prop-id",
widgetToken: "your-widget-token",
containerId: "my-widget",
name: "Your Company",
mode: "embedded",
language: "en",
llm: {
provider: "anthropic",
model: "claude-sonnet-4-6",
proxyUrl: "https://your-proxy.railway.app",
},
theme: {
primaryColor: "#8833FF",
colorScheme: "dark",
},
// ... rest of your generated config
});
</script>matchwiser.iife.js on your own server or CDN — do not hotlink it from matchwiser.com. The file is included in your download.Deploying the proxy
The proxy is a Node.js (Express) server included in your download as a Railway-ready template. It acts as a secure intermediary between your widget and the LLM provider — your API key stays on the server, never in the browser.
Deploy to Railway
Click the deploy button
Set environment variables
WIDGET_TOKEN_SECRET and your LLM API key. See the Environment variables section below for the full list.Copy your public URL
llm.proxyUrl in your widget's init config.Environment variables
Set these in your Railway project's Variables tab (or in a .env file for local development).
| Variable | Required | Description |
|---|---|---|
| WIDGET_TOKEN_SECRET | Yes | Secret used to verify widget JWTs. Must match the secret used when your widget token was generated. Keep this private. |
| ANTHROPIC_API_KEY | If using Anthropic | Your Anthropic API key. Get one at console.anthropic.com. |
| OPENAI_API_KEY | If using OpenAI | Your OpenAI API key. Get one at platform.openai.com. |
| ALLOWED_ORIGINS | Recommended | Comma-separated list of allowed CORS origins, e.g. https://yoursite.com. Restricts which domains can call your proxy. |
| PORT | No | HTTP port. Railway sets this automatically — you don't need to set it manually. |
WIDGET_TOKEN_SECRET or API keys in client-side code. These live only in your server environment.Widget options
The full list of fields accepted by MatchWiser.init(). All required fields are generated for you during onboarding.
Root
| Field | Type | Description |
|---|---|---|
| widgetId | string (UUID) | Unique ID for this widget. Generated during onboarding. |
| propId | string | Identifier for the property (website) that owns this widget. |
| widgetToken | string | Signed JWT that authenticates this widget to your proxy. |
| containerId | string | ID of the DOM element where the widget renders. |
| name | string | Your company or product name. Shown in the widget header. |
| mode | 'embedded' | 'fullscreen' | embedded renders a section on your page. fullscreen takes over the viewport. |
| language | string (BCP 47) | Default conversation language, e.g. "en", "pt-BR", "ja". The AI auto-detects and follows the visitor's language after their first message. |
theme
| Field | Type | Description |
|---|---|---|
| primaryColor | hex string | Brand color for buttons and accents. Default: #8833FF. |
| backgroundColor | hex | 'transparent' | Chat panel background. transparent inherits the page background. |
| colorScheme | 'dark' | 'light' | Controls text and UI colours inside the widget. |
| borderRadius | number (0–32) | Corner radius in px for chat bubbles and the panel. |
| fontFamily | string | CSS font-family. Use any font already loaded on the page. |
| logoUrl | URL string | Optional company logo shown in the widget header. |
| maxWidth | CSS string | Max width of the embedded section, e.g. "600px". |
| sectionHeight | CSS string | Fixed height of the embedded section, e.g. "480px". Defaults to auto. |
flow
| Field | Type | Description |
|---|---|---|
| greeting | string | Opening message shown before the visitor types. |
| typingIndicatorText | string | Text shown while the AI is generating a response. |
| maxTurns | number | Max conversation turns before the CTA is shown. Default: 10. |
| customInstructions | string | Free-text instructions injected into the system prompt. Define persona, tone, and product-specific rules here. |
| knowledgeBaseUrls | string[] | Up to 5 URLs the proxy fetches at session start and injects as context. See Knowledge base. |
Lead webhooks
When a visitor qualifies (or clicks your CTA), the proxy can POST the lead data to any URL you control — your CRM, a Slack webhook, Airtable, Make, Zapier, or your own endpoint. Set the LEADS_WEBHOOK_URL environment variable on your proxy to enable it.
Payload
{
"event": "lead.qualified" | "lead.converted",
"timestamp": "2026-01-01T00:00:00.000Z",
"widgetId": "...",
"sessionId": "...",
"company": {
"name": "Acme Inc.",
"domain": "acme.com",
"industry": "Software",
"employeeCount": 120,
"country": "US",
"technologies": ["React", "Salesforce"]
},
"qualification": {
"fitResult": "qualified" | "unqualified" | "unknown",
"matchedSignals": ["company size", "industry"],
"missingSignals": []
}
}The lead.qualified event fires when the AI determines the visitor matches your ICP. lead.converted fires when the visitor clicks your CTA button.
Signature verification
Set LEADS_WEBHOOK_SECRET on your proxy to sign every request. Each delivery will include an X-MatchWiser-Signature header containing an HMAC-SHA256 of the raw request body. Verify it on your endpoint to confirm the payload came from your proxy and was not tampered with.
| Variable | Description |
|---|---|
LEADS_WEBHOOK_URL | URL the proxy POSTs lead events to. Any HTTP/HTTPS endpoint. |
LEADS_WEBHOOK_SECRET | Optional HMAC-SHA256 signing secret. Included as X-MatchWiser-Signature on each request. |
Knowledge base
Pass URLs in flow.knowledgeBaseUrls to give the AI access to product-specific information. The proxy fetches each URL at session start, strips the HTML, and injects the plain text into the AI's system prompt.
Good URLs to include
- Your product features or use-cases page
- Pricing page
- FAQ or support page
- Case studies or customers page
- Integration or API documentation
Limits
| Limit | Value |
|---|---|
| Max URLs | 5 |
| Max characters per URL | 12,000 |
| Total max context | ~60,000 characters |
Language support
MatchWiser supports multilingual conversations. Set a default language for the AI's opening messages — it automatically switches to whatever language your visitor uses.
Setting the default language
MatchWiser.init({
// ...
language: "pt-BR", // opens in Brazilian Portuguese
});Supported languages
| Tag | Language |
|---|---|
| en | English (default) |
| pt-BR | Portuguese (Brazil) |
| es | Spanish |
| fr | French |
| de | German |
| it | Italian |
| nl | Dutch |
| pl | Polish |
| ja | Japanese |
| ko | Korean |
| zh-CN | Chinese (Simplified) |
| ar | Arabic |
| hi | Hindi |
| ru | Russian |
| tr | Turkish |
| sv | Swedish |
| da | Danish |
| fi | Finnish |
Updating your widget
There are two kinds of updates: changing your configuration and updating the widget JS version. Both can be done at any time without re-purchasing.
Updating your configuration
Your configuration lives entirely inside the MatchWiser.init({ ... }) call in your HTML. Edit it directly — change the greeting, update your ICP description, adjust colors, add knowledge base URLs. The change takes effect on the next page load with no re-deployment required.
widgetId, propId, and widgetToken fields are generated and must not be changed. Everything else is editable.Updating the JS file
When a new version of the widget is available, replace matchwiser.iife.js on your server with the new file. No configuration changes are required unless the release notes say otherwise.
matchwiser-1.2.0.iife.js) so you can roll back instantly by changing one line of HTML.Updating the proxy
The proxy source code is included in your download. When a new proxy version is released, update the files in your GitHub repo and Railway will redeploy automatically.
FAQ
Still have questions?
We're a small team and we read every message.