# Getting help URL: https://www.hey.support/docs/getting-help The fastest paths to an answer, and to a human when you need one. Most questions are answered somewhere in these docs. The sidebar covers everything from your first agent to billing and the API. For everything else, here's how to reach us. ## Ask the bot first The chatbot on this site is trained on the whole site, including these docs. For most questions it's the fastest way to an answer: it cites where the answer came from and tells you when it doesn't know. Try asking it things like: * How do I add a knowledge source? * What's the difference between Growth and Scale? * Can I deploy this on Shopify? ## Two paths to a human **Already a customer.** Email [hello@hey.support](mailto:hello@hey.support) with your workspace name. Including the agent name and roughly when something happened gets you a useful answer in one reply rather than three. **Pre-sales question.** The chatbot on this page, or [hello@hey.support](mailto:hello@hey.support) with the subject "Sales". We read everything, and a real person replies within one business day (UTC+05:30). ## Reporting something broken Tell us what you expected, what happened instead, and where. A workspace name, an agent name and an approximate time are enough for us to find the conversation. --- # Hey Support docs URL: https://www.hey.support/docs Build an AI support agent trained on your own content, then deploy it in one line and manage it from your dashboard. Hey Support is an AI chatbot you train on your website, docs, and files. It answers customer questions in your voice, captures leads, hands off to a human when it needs to, and runs on any site with a single line of code. These docs walk through the whole thing: setting up your first agent, teaching it what it needs to know, shaping how it talks, launching it, and running the conversations that come in. ## Start here ## How the pieces fit You work inside a **workspace**. A workspace holds one or more **agents**, your team, and your plan. Each agent has two sides, and the toggle in the top navigation switches between them. **Build** is where you set it up. **Inbox** is where you handle real traffic — replying in the [Inbox](/docs/conversations/inbox), tracking [Leads](/docs/conversations/leads) and [Bookings](/docs/conversations/bookings), watching [Live visitors](/docs/conversations/live-visitors), and reading [Insights](/docs/conversations/insights). You do not need to finish everything before going live. Train the agent on one URL, launch it, and refine from there. ## Who this is for These docs assume you are a workspace owner or a team member setting up or running an agent. If you get stuck, [Getting help](/docs/getting-help) has the fastest paths to a human. Looking for the developer surface? The [embed script](/docs/build/embed-script), [webhooks](/docs/webhooks) and the [public API](/docs/api) have their own section. Every page here is also available as Markdown — add `.md` to any docs URL, or use **Copy page** at the top of a page. --- # Language URL: https://www.hey.support/docs/agent-settings/language One setting decides what the agent writes in and what the widget's own buttons say. Open the agent's **Settings**, then the Language card. ## Assistant language Pick one language from the list. It does two things: 1. **The agent answers in it** by default. 2. **The widget's own chrome is translated into it** — buttons, labels, placeholders, the AI disclosure. Twenty-eight languages are supported. ## Follow the visitor A checkbox under the picker. On by default. * **On** — the agent answers in your language by default, and switches when a visitor clearly writes in another one. The widget's buttons and labels stay in your language either way. * **Off** — the agent answers in your language throughout, even when a visitor writes in something else. The chrome deliberately never follows the visitor. It has to paint before anyone has typed, so there is nothing to detect yet, and re-labelling buttons mid-conversation under someone's cursor is worse than one consistent language. ## How switching actually works There is no language detector. The **model** decides, reading the whole conversation rather than one message in isolation — which makes it far better at this than a statistical guess on a short string. It is told to ignore the things that used to cause false switches: a name, a place, a currency symbol, a single foreign word quoted inside an otherwise English sentence. When in doubt it stays in your language. The visitor's browser language is used as a hint to disambiguate very short messages, never as a trigger on its own. Their country is deliberately not used at all — where someone is says very little about what they want to read. If you previously set a "forced language", it was carried over as your language with **Follow the visitor switched off** — the same behaviour you had. Nothing to redo. --- # Legal and branding URL: https://www.hey.support/docs/agent-settings/legal-and-branding The consent notice visitors see, the AI disclosure that is always on, and removing "Powered by Hey Support". Two cards on the agent's **Settings** page, both about what a visitor sees rather than how the agent behaves. ## Legal and disclosure Add a short consent line above the composer — typically pointing at your terms and privacy policy. The card previews the real widget component as you type. The notice **persists until the visitor dismisses it**. It does not clear on the first message and it is not on a timer: the copy says "by chatting here, you agree", so removing it the moment it becomes operative would defeat the point. ### The AI disclosure is always on Separately from anything you configure, the widget always tells visitors they are talking to an AI assistant. It sits in the identity pill at the top of the conversation, in the visitor's language. You cannot switch it off, and removing branding does not remove it — they are deliberately not the same switch. This is the EU AI Act Article 50 obligation, in force since 2 August 2026. It lands on the **deployer** of the AI system, which is you, so the product discharges it for you rather than leaving it as a setting somebody forgets. When a human takes over the conversation the disclosure is **replaced**, not dropped — it becomes the agent's name and a live indicator. Once a person is answering, "AI assistant" is no longer true. ## Branding Turn off the small "Powered by Hey Support" line in the widget footer. Available on **Growth and above**. On Free and Starter the card is locked and names the plan you need. Your stored preference is kept either way, so upgrading turns it off without you setting it again. --- # Agent settings URL: https://www.hey.support/docs/agent-settings/overview Status, timezone, and deleting an agent — the settings that belong to one agent rather than the workspace. Agent settings are the controls that belong to a single agent. Open **Settings** from the agent's top navigation. Six cards, each doing one thing: Status, Timezone, [Language](/docs/agent-settings/language), [Legal & disclosure and Branding](/docs/agent-settings/legal-and-branding), and Delete. These are per-agent. Settings that apply to your whole workspace — members, billing, the default timezone, canned responses — live in [workspace settings](/docs/billing/workspace-settings). ## Status Pause the agent. A paused agent stops answering on every site it is embedded on: the widget does not load and the API stops serving its config. Nothing is deleted. Knowledge, conversations, leads and settings are all exactly where you left them, and un-pausing brings it straight back. Use it when you are mid-rewrite of the knowledge base and would rather nobody talked to the agent until you are done. ## Timezone The agent's own timezone. It overrides the workspace default for this agent. It matters most for [human handoff availability](/docs/capabilities/human-handoff) — the hours you draw are interpreted in this zone. If you never set it, the workspace default is used. This does **not** affect billing. Every usage window — conversations, voice minutes, action calls — is the UTC calendar month regardless of what you set here. ## Delete Deleting an agent is permanent and takes its knowledge, conversations, leads and settings with it. You have to type the agent's name to confirm, and the dialog shows you exactly what is about to go. If you only want it to stop answering, pause it instead. --- # Authentication URL: https://www.hey.support/docs/api/authentication Create an API key, send it as a bearer token, and keep it out of your client code. The API authenticates with a workspace API key sent as a bearer token. ## Create a key Go to **Settings → Developer** and create a key. You must be the workspace **owner**, and the workspace must be on **Scale or above**. A key looks like: ``` hs_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ``` The key is shown **once**, at creation. We store only a hash of it, so we cannot show it to you again — copy it then. If you lose it, revoke it and create another. ## Send it Pass it in the `Authorization` header on every request: ```bash curl https://www.hey.support/api/v1/me \ -H 'Authorization: Bearer hs_live_…' ``` `GET /me` is the cheapest way to check a key works — it returns the workspace the key belongs to. ## Scope A key is scoped to the **workspace** that created it, not to a single agent. It can read and write every resource in that workspace, so treat it as a full credential. Requests for resources in any other workspace return `404`. ## Rate limits Limits are per key, per hour. Once a key is accepted, every response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` — successes included, not only the request that gets refused — so you can pace a job instead of waiting to be told no. Read `Remaining` as you go rather than counting requests yourself. (A rejected key returns `401` with no rate headers, since there is no key to report on.) Going over returns `429`. See [Errors](/docs/api/errors) for the ceiling and the retry advice. ## Keep it server-side An API key is a secret. Never ship one in browser JavaScript, a mobile app, or anything else a user can read — anyone holding it has your workspace's data. If you need to put the chat widget on a page, that is the [embed script](/docs/build/embed-script), which needs no key at all. ## Revoking Revoke a key from **Settings → Developer**. Revocation takes effect immediately, and any request using it then gets a `401`. Revoke and replace if a key is ever pasted into a shared document, a ticket, a log, or a repository. ## If your plan changes API access is a **Scale** feature. Dropping below Scale does not delete your keys, but requests start returning `403` — including any [Zapier](/docs/integrations/zapier) automations, which run on this same API. Upgrading restores them without you re-creating anything. --- # Errors URL: https://www.hey.support/docs/api/errors One envelope for every failure, with a stable code to branch on. Every failing request — on this API and on every other HTTP endpoint we serve — returns the same JSON envelope. ```json { "error": "Invalid API key.", "code": "unauthorized", "docs_url": "https://www.hey.support/docs/api" } ``` ## Branch on `code`, never on `error` `code` is a stable symbol. It is part of the contract and will not change under `v1`. `error` is prose written for a human reading a log. **It may be reworded at any time**, so matching on its text will break without warning. `docs_url` points at the page explaining that failure. This is deliberately not RFC 9457 `problem+json`. Changing the content type and body shape would break every existing consumer — the Zapier app, the WordPress plugin and the mobile client all read `.error` — and buys nothing over a stable `code`. ## Codes | HTTP | `code` | What it means | | ---- | -------------------- | ---------------------------------------------------------------------- | | 400 | `bad_request` | The body or query failed validation. The message names the field. | | 401 | `unauthorized` | Missing, malformed, or revoked API key. | | 403 | `forbidden` | The key is valid but the workspace's plan does not include API access. | | 404 | `not_found` | No such resource — **or** it belongs to another workspace. | | 405 | `method_not_allowed` | Wrong verb for that path. | | 406 | `not_acceptable` | We cannot produce the representation you asked for. | | 429 | `rate_limited` | Over 1,000 requests in the hour. Check `X-RateLimit-Reset`. | | 5xx | `internal_error` | Our fault. Safe to retry with backoff. | ## 404 versus 403 A resource in another workspace returns **`404`**, not `403`. That is intentional: a `403` would confirm the id exists, which turns the API into a way to enumerate other people's data. So a `404` means one of two things — the id is wrong, or it is not yours. ## Retrying `429` and `5xx` are worth retrying with exponential backoff. `4xx` other than `429` will fail identically however many times you send it — fix the request instead. --- # Introduction URL: https://www.hey.support/docs/api A REST API over your workspace — conversations, leads, bookings, knowledge, and analytics. The Hey Support API is organised around REST. It has predictable resource-oriented URLs, accepts JSON request bodies, returns JSON responses, and uses standard HTTP status codes, authentication, and verbs. It is available on **Scale and above**. Every endpoint is listed in the sidebar with its method and shape. ## Base URL All requests go to: ``` https://www.hey.support/api/v1 ``` Use the `www` host. The bare apex redirects with a 308, and while browsers follow that, several HTTP clients drop the body and the `Authorization` header on a redirected `POST`. ## Versioning The version is in the path. `v1` is the current version and we will not make breaking changes within it — new fields may be added to responses, so parse defensively and ignore what you do not recognise. ## Authentication Every request needs an API key as a bearer token. See [Authentication](/docs/api/authentication). ```bash curl https://www.hey.support/api/v1/me \ -H 'Authorization: Bearer hs_live_…' ``` ## Rate limiting **1,000 requests per hour, per key.** Every response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` so you can pace yourself rather than discover the ceiling. Over the limit you get a `429`. ## IDs IDs are short encoded strings — the same ones in your dashboard URLs — not raw integers. Treat them as opaque. Requesting a resource that belongs to another workspace returns **`404`, not `403`**, so the API cannot be used to probe whether an id exists. ## Pagination List endpoints use offset pagination and share one envelope: ```json { "data": [], "pagination": { "limit": 20, "offset": 0, "total": 0, "has_more": false } } ``` `limit` defaults to 20 and caps at 100. Page with `offset`, and stop when `has_more` is `false`. ## Timestamps All timestamps are ISO 8601 in UTC, for example `2026-08-26T09:30:00Z`. ## Errors Every failure shares one envelope with a stable `code` to branch on. See [Errors](/docs/api/errors). ## OpenAPI The machine-readable spec is served at: ``` https://www.hey.support/api/v1/openapi.json ``` Every page in this reference is generated from it, so the two cannot disagree. Point a client generator or an agent toolchain straight at that URL. Prefer no code? The [Zapier integration](/docs/integrations/zapier) runs on this same API, with triggers and actions you can wire up without writing anything. --- # Plans URL: https://www.hey.support/docs/billing/plans The five plans, what each includes, and how to change plan. Hey Support has five plans: Free, Starter, Growth, Scale, and Enterprise. Pricing is flat. You get a generous monthly pool of conversations, and you are never charged per resolution. Your billing page and the [pricing page](https://hey.support/pricing) are the source of truth for current prices. Billing is in USD via Stripe worldwide. In India, monthly plans are billed in INR by UPI AutoPay via Razorpay — INR prices are exclusive of GST, so 18% GST is added to each charge. Annual plans in India are invoiced. ## Price | | Free | Starter | Growth | Scale | Enterprise | | ----------------- | ---- | ------- | ------ | ------ | ---------- | | Billed monthly | $0 | $23 | $59 | $155 | Custom | | Billed annually | $0 | $228 | $588 | $1,548 | Custom | | Annual, per month | $0 | $19 | $49 | $129 | Custom | Annual billing is roughly two months free. The monthly and annual toggle is on the pricing and change-plan screens. ## What each plan includes | | Free | Starter | Growth | Scale | Enterprise | | --------------------------- | ---- | ------- | --------- | --------- | ---------- | | Conversations / month | 50 | 1,000 | 5,000 | 20,000 | Unlimited | | Chatbots | 1 | 1 | 3 | 10 | Unlimited | | Team seats | 1 | 1 | 5 | 15 | Unlimited | | Domains per agent | 1 | 1 | Unlimited | Unlimited | Unlimited | | Knowledge chunks / agent | 500 | 2,500 | 25,000 | 50,000 | Unlimited | | Voice minutes / month | None | None | 500 | 2,000 | Custom | | AI Action calls / month | None | None | 1,000 | 10,000 | Unlimited | | Live chat handoff | No | No | Yes | Yes | Yes | | Email handoff | Yes | Yes | Yes | Yes | Yes | | Remove branding | No | No | Yes | Yes | Yes | | Messaging channels | No | No | Yes | Yes | Yes | | Knowledge auto-update | None | None | Weekly | Daily | Daily | | API access | No | No | No | Yes | Yes | | White label + custom domain | No | No | No | Yes | Yes | | SSO and SCIM | No | No | No | No | Yes | Two rows are easy to misread: * **Handoff is split.** Every plan, Free included, can hand a conversation to your team **by email**. What Growth adds is **live chat** — the visitor waits in the widget and a teammate replies in real time. See [Human handoff](/docs/capabilities/human-handoff). * **Only the Free conversation pool is enforced.** Paid pools are generous stated allowances and are deliberately not metered — that is the flat-pricing promise. Voice minutes are the one separately metered resource. ## Picking a plan * **Free** is a real resting plan, not a trial. Use it to try the product and run a small site. * **Starter** raises your conversation pool and your knowledge limit. Good for a single small site. * **Growth** is the common choice once you want live chat handoff, voice, messaging channels, AI Actions, multiple agents, and your widget without our branding. * **Scale** adds API access — which is also what [Zapier](/docs/integrations/zapier) needs — white label, a custom domain, and daily knowledge refresh. * **Enterprise** is for large teams that need SSO, SCIM, and no limits. ## Changing plan Change plan from **Settings, Billing**, inside the dashboard. * **Upgrades** take effect immediately, with a prorated charge for the rest of your cycle. * **Downgrades** take effect at the end of your current cycle, so you keep what you are paying for until then. Before a downgrade, we show you exactly what will change against your current usage. Nothing is deleted when you downgrade. Anything already over the new plan's limit keeps working; you just cannot create more of it. Only workspace owners can change plan. --- # Privacy and data requests URL: https://www.hey.support/docs/billing/privacy-and-data How a visitor asks for their data to be erased, what you have to do, and what we delete. If someone who chatted with your agent asks you to delete their data, this is the path. Open **Settings**, then **Privacy** (owners only). ## Who is responsible For conversations on your site, **you are the controller** and we are the processor. That means a visitor's erasure request is yours to action, and we route it to you rather than acting on it ourselves. We deliberately do not delete a visitor's records on our own initiative. Doing so would destroy your records without your instruction, and our data processing agreement commits us to notify you rather than to respond to the visitor directly. ## How a request arrives A visitor asks at **[hey.support/delete-my-data](https://hey.support/delete-my-data)**. 1. They enter their email address. 2. We email that address a single-use confirmation link. Nothing happens until they click it, and the page only reads — the request is sent by a button, so a link scanner cannot fire it. 3. We find every workspace holding data for that address and open one request against each. 4. The owners of each workspace are emailed and the request appears on the Privacy tab. The form gives the same answer to every submission — a known address, an unknown one, or a repeat. That is on purpose: a different response would turn it into a way of testing whether a given person is one of your customers. ## Actioning a request The Privacy tab lists open requests. Erasing deletes, for that person in your workspace: * their conversations and every message in them * any leads created from those conversations * any bookings tied to them We delete rather than anonymise. Visitors routinely put their name, address and order details in the message body, so blanking an email field would not actually anonymise anything. When the last workspace holding their data has actioned the request, the visitor gets a written confirmation. ## What is not covered Some things genuinely cannot be found or are yours rather than theirs, and we say so rather than implying otherwise: * **Anonymous conversations.** Someone who chatted without ever giving an email cannot be identified from an email address. * **Content you wrote.** A quick answer you authored after seeing a question, or a knowledge chunk you added, belongs to your workspace and has no link back to the person who prompted it. ## Backups Backups roll on a seven-day window, so a deleted row falls out of every surviving backup well inside the timeframe we commit to. If a backup is ever restored, re-applying completed erasures is a required step of that restore. --- # Team and roles URL: https://www.hey.support/docs/billing/team-and-roles Invite teammates, understand the two roles, and manage who can do what. A workspace can have more than one person in it. You manage the team from **Settings, Members**. ## The two roles * **Owner** can do everything, including billing, members, and roles. This is you if you created the workspace. * **Member** can build and run agents, handle the inbox, and work leads, but cannot touch billing, members, or roles. Give teammates who need to answer conversations or edit agents the member role. Keep billing and account control with owners. ## Inviting people Invite a teammate by email from **Settings, Members**. They get an invitation link that is good for seven days. If it expires or gets lost, use **Resend**. When they accept, they join the workspace with the role you chose. ## Managing members From the same page you can change a member's role or remove them. Two guardrails protect the workspace: * You cannot remove or demote the only owner, so a workspace always has someone in control. * You cannot change your own role. ## Transferring ownership To hand the workspace to someone else, promote them to owner. A workspace can have more than one owner, so there is never a moment with nobody in charge. ## Seats Your plan sets how many people can be in a workspace. Free and Starter are single-seat; Growth includes 5, Scale includes 15, and Enterprise is unlimited. See [Plans](/docs/billing/plans). --- # Usage and limits URL: https://www.hey.support/docs/billing/usage-and-limits The metered resources, how they are measured, and what happens as you approach a cap. Each plan includes monthly allowances for a few resources. You track them all on **Settings, Billing**, where each has a meter showing usage against your limit. ## Conversations A conversation is one visitor's chat session. Every plan states a monthly number, from 50 on Free up to unlimited on Enterprise. The window is the **UTC calendar month** — it resets on the 1st, not on your billing anniversary. **Only the Free pool is enforced.** Paid pools are deliberately unmetered: the flat-pricing promise is that you are never charged per resolution and never cut off mid-month for being popular. Treat the paid numbers as the size we built the plan for, not as a shutoff. On Free, once the pool is used up, new visitors see a message instead of a live agent until the 1st. You can customize that message in [Experience](/docs/experience/messages-and-prompts). ## Knowledge chunks Measured per agent, not per workspace. This is how much trained content an agent can hold. See [Knowledge limits](/docs/knowledge/limits) for the full detail. ## Voice minutes Voice is metered in minutes per month, separate from your conversation pool. Growth includes 500 minutes, Scale includes 2,000, and Enterprise is custom. Free and Starter do not include voice. See [Voice](/docs/capabilities/voice). ### How voice minutes are counted Voice usage is measured in **active speaking time** only, across your workspace, per calendar month (UTC). * **What counts:** the seconds a visitor is actually speaking (measured per utterance from speech start to speech stop, minimum 1 second), plus the seconds of speech your AI generates in reply (estimated from the spoken text at a natural speaking rate, minimum 1 second per segment). * **What never counts:** silence while the microphone is open, AI "thinking" or processing time, network delays, time the voice screen sits idle, and voice previews you play in the dashboard. * **Interruptions:** AI speech counts when it is generated. If a visitor interrupts, the AI stops generating new speech right away. Only what was already generated counts. Muted replies generate no speech and count nothing. * **Abandoned sessions:** nothing accrues after the last captured or generated speech. * **Rounding:** usage is tracked in whole seconds and shown in minutes. A single voice conversation is capped at 60 minutes of combined speech. ### At the cap A voice conversation already in progress is **never** cut off. When your workspace reaches its monthly allowance, in-progress conversations finish naturally and new voice sessions pause until the allowance resets on the 1st (UTC), unless you turn on overage. ### Voice overage (opt-in) On Growth and Scale you can turn on **voice overage** so voice keeps working past your included allowance. Overage is billed monthly in arrears at **$0.10 per additional minute**, and you can set an optional monthly budget that caps the maximum overage charge. It is off by default and enabled per workspace in [billing settings](/docs/billing/plans). We never bill voice overage unless you turn it on. ## AI Action calls Each run of an [AI Action](/docs/capabilities/ai-actions) counts as a call. Growth includes 1,000 per month, Scale includes 10,000, and Enterprise is unlimited. Free and Starter do not include AI Actions. ## Approaching a cap When you cross 80 percent of a metered limit, the workspace owner gets an email so there are no surprises. Meters on the billing page turn from green to amber as you get close, and red at the limit. Hitting a cap never deletes anything and never takes your widget down. Text chat keeps working; only voice pauses new sessions at its cap (and even then, an active call always finishes, and overage can keep voice running, as covered above). When you are regularly near a limit, that is the signal to move up a plan. See [Plans](/docs/billing/plans). --- # Workspace settings URL: https://www.hey.support/docs/billing/workspace-settings The eight settings tabs, split between what is yours and what is shared with your team. Workspace settings are organised by **blast radius**: some things affect only you, the rest affect everyone in the workspace. ## The tabs **Yours alone** | Tab | What is there | | ------------ | ------------------------------------------------------------------------------------ | | **Account** | Your name, password, your email notification preferences, and the terms you accepted | | **Activity** | Your own audit trail — what you changed and when | **Shared with the workspace** | Tab | What is there | | --------------- | --------------------------------------------------------------------------------------------------- | | **Workspace** | Name, default timezone, canned responses, delete workspace | | **Members** | Invite, remove, and change roles — see [Team and roles](/docs/billing/team-and-roles) | | **Billing** | Plan, usage meters, invoices, payment method — owners only | | **Developer** | API keys, webhooks, and secrets — owners only | | **Privacy** | Data-subject erasure requests — owners only. See [Privacy and data](/docs/billing/privacy-and-data) | | **Connections** | Apps you authorize once for the whole workspace | ## Timezone, in three places The word appears three times and they are genuinely different: * **Workspace timezone** (here) is the default for new agents and decides when daily and weekly summary emails go out. * **Agent timezone** ([agent settings](/docs/agent-settings/overview)) overrides it for one agent, and is what handoff availability hours are read in. * **Booking availability timezone** is set inside the Book a meeting tool. None of them affect billing. Every usage window — conversations, voice minutes, action calls — is the **UTC calendar month**, no matter what any timezone is set to. ## Notifications Each person controls their own, on the **Account** tab. Five kinds: * **Lead alerts** when a lead is captured * **Handoff alerts** when a visitor asks for a human * **Booking alerts** when a meeting is booked * **Daily digest** summarising the day * **Weekly analytics** each Monday Defaults: **owners** get lead, handoff, booking and weekly on, daily digest off. **Members** get the three instant alerts — lead, handoff and booking. Every recurring email has one-click unsubscribe, and empty periods are skipped so you are never sent a report of nothing. ## Canned responses Saved replies your team drops into the [Inbox](/docs/conversations/inbox) by typing `/`. They live on the **Workspace** tab, and any member can edit them — it is an inbox tool, so gating it to owners would take it away from the people who use it. A canned response can carry placeholders like the visitor's name, which fill in automatically. An unknown or empty placeholder is left visible rather than silently collapsing, so you fix it instead of sending "Hi there,". ## Connections vs Integrations Two similarly-named surfaces doing different jobs: * **Connections** (here, workspace level) is where you **authorize an app once** — Shopify, HubSpot, Slack, Google. Inbound. * **Integrations** (on each agent) is where you **route that agent's activity** — which Slack channel, which store. Outbound. Connect once, route per agent. --- # Embed script URL: https://www.hey.support/docs/build/embed-script The script tag, its data attributes, and how to pass live page context into the widget. The widget loads from one script. This page covers its attributes and how to feed it context from your page, for teams that want more control than the one-click installs give. ## The script ```html ``` The script is a thin injector. It reads its attributes, mounts the widget in an iframe, and does nothing else. All of the agent's configuration (theme, greeting, tools) lives server-side against the Chatbot ID, so this tag never needs to change when you edit the agent. ## Attributes | Attribute | Required | Purpose | | ----------------- | -------- | -------------------------------------------------- | | `data-chatbot-id` | Yes | Your agent's Chatbot ID, from the Deploy page. | | `data-auto-open` | No | Open the widget automatically on load. | | `data-context` | No | Pass page context as URL-encoded JSON (see below). | ## Passing context `data-context` lets you tell the agent about the current page or visitor, so it can answer with that in mind. Pass URL-encoded JSON: ```html ``` The decoded value there is `{"plan":"growth","order_id":"1234"}`. ## Updating context after load For context that changes without a page reload, like a cart that updates as the visitor shops, send a `postMessage` to the window: ```js window.postMessage( { type: 'HS_SET_CONTEXT', payload: { cart_total: 4200, cart_item_count: 3 }, }, '*', ); ``` The widget picks it up and merges it into the visitor's context. This is the same bridge the Shopify and WordPress installs use under the hood, so the agent always has current page context. Context is a hint for the agent, not a place for secrets. Do not pass anything you would not want visible in the browser. --- # Overview URL: https://www.hey.support/docs/build Put the widget on your site, and feed it what your page already knows. Everything here is about running the agent on your own surface, rather than reading or writing your data. ## Which surface do I want? | I want to… | Go to | | ----------------------------------- | ----------------------------------------------------- | | Put the chat widget on my site | [Embed script](/docs/build/embed-script) | | Install without writing code | [One-click installs](/docs/launch/one-click-installs) | | Read or write my workspace data | [API reference](/docs/api) | | Get notified when something happens | [Webhooks](/docs/webhooks) | | Wire it to other apps without code | [Zapier](/docs/integrations/zapier) | ## No key needed The embed script is public by design. It takes a **chatbot id**, not an API key — the id is visible in your page source and that is fine, because it grants nothing but the ability to chat with an agent you chose to publish. Never put an [API key](/docs/api/authentication) in front-end code. Those are workspace-wide credentials. ## Which domains can embed it An agent can be locked to specific domains under **Preview & Launch → Allowed domains**. With none set, the widget serves anywhere — which is the right default while you are testing, and worth closing once you go live. --- # Instructions and rules URL: https://www.hey.support/docs/behavior/instructions-and-rules Hard rules the agent must always follow, free-form custom instructions, and how creative its answers are. Two controls let you steer the agent beyond its role and tone: hard rules for the lines it must not cross, and custom instructions for everything else. ## Hard rules Hard rules are short, absolute statements the agent always follows. Keep them tight and specific: * "Never discuss competitor pricing." * "Always ask for an order number before checking a return." * "Do not promise delivery dates." You can set up to five. That cap is deliberate. A short list of clear rules works; a long list of vague ones does not, and it starts to conflict with itself. ## Custom instructions Custom instructions are free-form guidance in your own words. This is the highest-priority input the agent gets, so use it for the nuances that do not fit anywhere else: * How to greet people * When to offer a demo or a discount * How to handle an angry customer * What to do when it does not know an answer There is an 800-character limit, which is plenty for focused guidance. If you find yourself writing a policy document here, that content belongs in [Knowledge](/docs/knowledge/overview) instead. ### Polish Next to the instructions field is **Polish**, an AI rewrite helper. Write your instructions roughly, then ask it to make them shorter, more professional, more casual, or to fix the grammar. It shows you the rewrite so you can accept or revert. There are also snippet chips that append common instructions, like capturing an email before sharing pricing or escalating urgent issues to a human. ## Answer style Answer style controls how much the agent sticks to the script: * **Focused** keeps answers tight and close to your content. Best for support, where accuracy matters most. * **Balanced** is the middle ground and a good default. * **Creative** lets the agent be more expressive. Better for sales or a playful brand. If the agent is going off-script or inventing details, move answer style toward Focused and tighten your hard rules. --- # Behavior overview URL: https://www.hey.support/docs/behavior/overview Shape how the agent thinks and talks, its role, its voice, and the business details it speaks from. Behavior is where you set the agent's personality. Knowledge decides what it knows; Behavior decides how it uses that knowledge and how it sounds. Open **Behavior** from the top navigation. At the top of the page a plain-English summary sentence describes the current setup, with the key choices highlighted, so you can read the agent's personality at a glance. A health pill tells you how complete the setup is, from Not set up through to Tuned. ## Identity This is who the agent is. * **Name** is shown here but you edit it in [Experience](/docs/experience/identity-and-launcher). The name lives in one place so it never gets out of sync. * **Role** sets the job: Support, Sales, Lead qualification, Product, or Custom. The role shapes how the agent frames answers. A support agent explains and reassures; a sales agent nudges toward a next step. * **Voice** sets the tone: Friendly, Professional, Concise, Detailed, or Fun. Pick the one that matches how your brand talks. * **Description** is a short blurb about your business. It gives the agent context for its opening line and how it introduces itself. ## Business contact details Give the agent your real contact details so it can share them when a visitor asks: * Email * Phone * Website URL * Meeting or booking link The agent uses these when someone wants to reach a human or book time, so keep them current. ## What lives elsewhere Four things you might expect here live on their own pages: * **Hard rules and custom instructions** are in [Instructions and rules](/docs/behavior/instructions-and-rules). * **Topic boundaries** are in [Topic boundaries](/docs/behavior/topics-and-language). * **Language** moved to [agent settings](/docs/agent-settings/language). * **Resolution feedback** moved to [Capabilities](/docs/capabilities/resolution-feedback) — it puts something on screen for the visitor, so it belongs with the other capabilities rather than with the agent's personality. --- # Topic boundaries URL: https://www.hey.support/docs/behavior/topics-and-language Keep the agent from wandering into subjects you do not want it to touch. Topic boundaries keep the agent off subjects you would rather it left alone. You list the off-limits topics, and you choose how it reacts when someone raises one anyway. Open **Behavior**, then the topic boundaries section. ## Listing topics Add off-limits topics as tags. Common ones: * Competitor products * Medical advice * Legal advice * Personal opinions ## When asked anyway Two options: * **Redirect politely** steers the conversation back to what the agent is for. This is the default. * **Decline** has the agent say plainly that it cannot help with that. For a support agent on a regulated product, declining medical or legal questions is usually the safe choice. For a general assistant, redirecting politely keeps things smooth without feeling like a wall. Boundaries are about subjects to avoid, not facts to teach. To tell the agent what it should know, use [Knowledge](/docs/knowledge/overview). To shape how it talks, use [Instructions and rules](/docs/behavior/instructions-and-rules). ## Looking for language? Which language the agent replies in is set on the agent's own settings, not here. See [Language](/docs/agent-settings/language). --- # AI Actions URL: https://www.hey.support/docs/capabilities/ai-actions Let the agent do things mid-conversation, like looking up an order or calling your own API, with secrets, approvals, and an audit trail. AI Actions let the agent take an action during a chat instead of just answering. It can look up an order, find a contact in your CRM, or call your own API and use the result in its reply. There is no trigger to configure: the model decides when to run an action based on the conversation. You decide what actions exist and what they are allowed to do. Open **Capabilities**, then **AI Actions**. AI Actions are available on Growth and above, with a monthly cap on action calls. Free and Starter do not include them. See [Plans](/docs/billing/plans). ## Two kinds of action ### Marketplace apps Pre-built actions for services we support, like looking up a Shopify or WooCommerce order or finding a HubSpot contact. You connect the app once for your workspace (see [Integrations](/docs/integrations/overview)), then enable the actions you want. The agent handles the rest. Actions that depend on a connected store show up first when that store is connected, so the relevant ones are easy to find. ### Custom HTTP actions A custom action calls any HTTP API you point it at. You define: * The **parameters** the agent should collect or infer (for example an order number) * The **request**: method, URL, and headers * How to turn the response into an answer You can test an action with sample inputs before you turn it on, so you see exactly what the agent will send and get back. ## Secrets APIs need keys, and you should never paste a key into a prompt. Store them as **secrets** in workspace settings, then reference them in an action's headers as `{{secret.NAME}}`. Secrets are encrypted, only ever used in request headers, and are stripped from the action's audit log. See [Workspace settings](/docs/billing/workspace-settings). ## Approvals Some actions should not run without a human saying yes, like issuing a large discount. Mark an action as requiring approval, and when the agent wants to run it, the request lands in your [Inbox](/docs/conversations/inbox) as a card. A teammate approves or denies it, and the visitor waits for the result. ## The audit log Every action run is recorded: what ran, the inputs, a trimmed excerpt of the response, and how long it took. Secrets are never stored in the log. This gives you a clear history of everything the agent did on your behalf. ## Usage Action runs count against your plan's monthly cap. The AI Actions page shows a usage meter and your top actions so you can see what is getting used. --- # Book a meeting URL: https://www.hey.support/docs/capabilities/booking Let a visitor pick a time from the chat, using your existing scheduling link. Book a meeting gives the agent a way to get a visitor onto your calendar when they ask for a demo, a call, or a time. Open **Capabilities**, then **Book a meeting**. ## Scheduling link Add any https booking URL — Cal.com, Calendly, SavvyCal, whatever you already use. The chat then shows a **Pick a time** button that opens it in a new tab, with the visitor's name and email prefilled when the agent already knows them. This is the mode available on every account today. The URL must be `https`. A link-mode booking that fails validation switches the capability off rather than showing the visitor a dead button. ## Live scheduling Live scheduling books a real meeting inside the chat — the agent reads your actual availability, offers time chips, and confirms without the visitor leaving the conversation. **It is in limited release.** It runs on Google Calendar, and our Google OAuth app is still going through verification for calendar access, so the connect flow cannot be completed on a normal account yet. The provider picker only offers it to Hey Support staff until that clears. Use a scheduling link in the meantime. ## When it appears The agent offers the scheduler when a visitor wants to meet — asking for a demo, a call, or a time. There is no timing setting. If a visitor's message could equally mean "leave my details" or "talk to a human", and those are also available, the agent offers the choice instead of picking for them. ## After a booking A booked meeting also creates a lead quietly, so you have the contact without a duplicate notification. Bookings appear on the [Bookings](/docs/conversations/bookings) page. --- # Custom buttons URL: https://www.hey.support/docs/capabilities/custom-buttons Up to three buttons the agent offers when the conversation calls for them — you write the button, the agent picks the moment. Custom buttons are shortcuts you want visitors to be able to take: book a demo, open pricing, start a trial, read a guide. You define up to **three**, and the agent decides which one — if any — fits the reply it is about to send. Open **Capabilities**, then **Custom buttons**. This replaced the old single "Primary call to action". If your agent had one configured, it was carried over as your first button; nothing was lost. ## Writing a button Each button has: * **Label** — the text on the button. Required. * **URL** — where it goes. Required. Must be `https:`, `mailto:` or `tel:`. * **Title** and **Description** — optional. Supply them and the button renders as a full card with a headline and a line of explanation. Leave them out and it renders as a compact pill. * **Icon** — optional, from a fixed set: Calendar, Chat, Email, Phone, Pricing, Features, Docs, Demo, Shop, Document, Support, Link. * **When to suggest** — optional but the most valuable field on the page. See below. The preview beside the editor is the real widget component under a real theme, so what you see is what a visitor gets. ## "When to suggest" is the trigger There is no timing rule. The **agent** is the trigger: it is shown your buttons along with whatever you wrote in *When to suggest*, and it picks one when the conversation matches. Write that field as an instruction to a colleague: * "When someone asks about price or plans" * "When someone wants to see the product before committing" * "Only when the visitor mentions migrating from another tool" Leave it blank and the agent has only your label to go on, which usually means the button appears less often than you would like. Only one button can appear per reply, and never on a turn where the agent is already showing a form, a scheduler or product results — those answer the question the visitor actually asked. A button is an offer, not an interruption. ## What a visitor sees A full-width card whose whole surface is the link — icon, headline, description, and a trailing arrow — or a compact pill if you only set a label and URL. Either way it takes its colour from your brand, and it is restored if the visitor comes back to the conversation later. --- # Ecommerce URL: https://www.hey.support/docs/capabilities/ecommerce Answer from your live product catalog and hand the visitor a filled cart, on Shopify or WooCommerce. Ecommerce lets the agent answer product questions from your **live store** rather than from indexed pages, and hand a visitor off to checkout with the item already in their cart. Open **Capabilities**, then **Ecommerce**. ## Connecting a store Connect is one field — the store address. Neither backend needs credentials from you. **Shopify** — enter your `.myshopify.com` domain. If you installed the Hey Support app from the Shopify App Store, this is connected for you automatically as part of the install. **WooCommerce** — enter your site URL. An agent uses exactly **one** store. Connecting a second one reassigns it rather than adding to it. One store can power several agents. ## What you can turn on * **Product suggestions** — the agent searches your catalog and shows results as cards. Set how many products to show, and whether out-of-stock items are included. * **Add to cart** — the cards carry an add button and the agent can add by name. Off by default. Add to cart works on its own, without product suggestions, because the agent can look a product up by name when it needs to. ## What visitors see A horizontal carousel of product cards — image, name, price, and one full-width action. Prices come from the store and are formatted in its own currency and decimal setting. Tapping **Add** hands off to your storefront: * On **WooCommerce** the item is added to the visitor's own session cart, so it merges with anything they already had. * On **Shopify** the chat builds its own cart and hands over a checkout link. It does not merge with a cart the visitor built on the storefront. Variable products with options are not added directly — the card links out to the product page instead, because picking the variant is the visitor's decision. ## Two things worth knowing **A product answer never offers a human.** The agent only measures the knowledge base when deciding whether it is stuck, and your catalog deliberately is not in the knowledge base. Without this, a successful product answer would be followed by "talk to our team", which reads as failure. **WooCommerce search is title-only.** That is a limit of the WooCommerce Store API, not something we can configure around: it matches product titles and SKUs, never descriptions or categories. So "anything in leather?" will not find a product called "Milano Tote". The agent falls back to narrowing the search and then to showing popular items, clearly labelled as suggestions rather than matches. Shopify's catalog search does not have this limitation. ## Shipping and returns questions Those are answered from your [knowledge base](/docs/knowledge/overview), not from the store. Shopify retired the endpoint that served store policies to agents on 31 August 2026, so make sure your policy pages are indexed. --- # Human handoff URL: https://www.hey.support/docs/capabilities/human-handoff Hand the conversation to a person — live in the Inbox, or by email — with availability hours and the contact details you need. Human handoff is how a conversation stops being the agent's and becomes yours. Open **Capabilities**, then **Human handoff**. ## Two channels **Hey Support Inbox (live chat)** — the visitor waits in the widget and a teammate replies from the [Inbox](/docs/conversations/inbox). Available on **Growth and above**. **Email** — the request is emailed to your team and the visitor is told someone will get back to them. Available on **every plan, including Free**. It is the *live chat* half that needs Growth, not handoff itself. A Free or Starter agent with an email address configured still shows visitors a "message the team" card — it just does not put them in a live queue waiting for someone who has not been paged. Slack and webhooks are notification routes rather than channels: a handoff request posts to any Slack channel you have routed and fires the `handoff.requested` webhook regardless of which channel the visitor used. ## When it happens There are no triggers to configure. The agent offers a human when: * the visitor asks for one * it cannot find an answer — your knowledge base has content, but nothing in it was close enough to the question * the visitor asks the same thing again, rephrased The third case is the one operators underestimate. A repeated question usually means the first answer missed, and that is exactly when a person should step in. A conversation that a tool already answered — a product lookup, a booking — does not trigger a handoff, even though the knowledge base had nothing to say about it. The catalog and the calendar are deliberately not in the knowledge base. ## Availability Set when a live handoff is possible: **always**, **business hours**, or a **custom** week you draw yourself. Outside those hours the visitor is told so, and asked to leave details instead of being put in a queue nobody is watching. Hours are interpreted in the agent's timezone — the one on [agent settings](/docs/agent-settings/overview), falling back to the workspace default. Availability is a courtesy, not a lock. If the schedule cannot be read for any reason the agent assumes you are available rather than turning handoff off. ## Contact details Choose what to collect before handing off — name, email, phone, company — each **required**, **optional**, or **off**. Email is always at least optional, so you have some way to reply. Collecting details is on by default. Outside your hours they are always collected, since there is nobody to answer live. ## What the visitor sees A card offering a person. If live chat is on and you are available, they wait in the widget and see replies land. Otherwise they leave details and get a confirmation. Phone and company answers are saved onto the [lead](/docs/conversations/leads). --- # Sales lead capture URL: https://www.hey.support/docs/capabilities/lead-capture Collect a visitor's details mid-conversation, pre-filled from what they already told the agent. Sales lead capture puts a short form in the chat so you can follow up. It is **on by default**, asking for name and email. Open **Capabilities**, then **Sales lead capture**. ## Choosing fields Three fields are offered up front: * Name * Email * Phone Four more sit under **Advanced**: * Company * Project details * Budget * Timeline Ask for the fewest fields you actually need. Every extra field costs you completions, and the agent can always ask a follow-up question in conversation instead. ## When it appears The form appears when a visitor shows buying interest: asking about pricing, requesting a demo, or asking how to get in touch. There is no timing setting. If the visitor already typed their details earlier in the conversation, the form appears **pre-filled** and the agent asks them to confirm rather than to type it all again. That confirm version never appears empty — if the agent cannot extract anything, it shows the plain form instead. Once a lead is captured, the form is not offered again in that conversation. ## Where leads go Captured leads land on the [Leads](/docs/conversations/leads) board. They also: * fire the `lead.created` [webhook](/docs/webhooks) * post to any Slack channel you have routed * email teammates who have lead alerts switched on A meeting booked through [Book a meeting](/docs/capabilities/booking) also creates a lead, quietly — you get the booking notification rather than two separate alerts for the same person. --- # Capabilities overview URL: https://www.hey.support/docs/capabilities/overview The seven things your agent can do mid-conversation, and how it decides when to do them. Capabilities are the things the agent can surface to a visitor mid-chat: a form, a scheduler, a handoff to a person, a button, a product, a voice call. Open **Capabilities** from the top navigation. Each row has an on/off switch you can flip without opening anything; clicking the row opens that capability's own page, with its switch at the top, its settings below, and a live preview of what the visitor will see. ## The seven capabilities ## Placement is automatic There is nothing to schedule and no "show after N messages" setting. Those controls existed once and were removed, because they made the agent interrupt at fixed intervals regardless of what the visitor was doing. Instead the agent makes one decision per reply. It looks at what the visitor just asked, which capabilities are on and configured, and what has already happened in the conversation. A visitor whose details you already captured is never asked again. A card never lands on top of the one before it. Two consequences worth knowing: * **The reply and the card always agree.** The agent is told which card is appearing before it writes, so it never says "fill in the form below" when there is no form. If a card cannot render — because your plan does not include it, or it is not configured — the agent is not told about it and does not mention it. * **When several fit, it asks.** If a visitor says something that could mean "leave my details", "book a meeting" or "talk to a human", and all three are available, the agent offers the choice rather than guessing. ## Capabilities and AI Actions are different things Capabilities are what the agent **offers to the visitor**. [AI Actions](/docs/capabilities/ai-actions) are what the agent **does on its own** — looking up an order, checking a CRM, calling your API. Actions run in the background and report back; capabilities put something on screen. --- # Resolution feedback URL: https://www.hey.support/docs/capabilities/resolution-feedback Ask the visitor once, at the end of a conversation, whether the chat actually helped. Resolution feedback asks a closing question — did this help? — so you find out whether conversations are landing, rather than inferring it from the fact that nobody complained. Open **Capabilities**, then **Resolution feedback**. ## When it appears Once per conversation, at the end, and only when the agent has nothing more useful to offer. Specifically: * the visitor said something that reads as closing — thanks, that's all, goodbye * nothing else is on screen: no form, no scheduler, no products, no handoff * the agent has actually replied at least once * the conversation is not live with a human, and is not already closed It also appears if a conversation simply goes quiet for a while, on the same terms. Either way it is asked once and never repeated. It is never spoken during a [voice](/docs/capabilities/voice) call. ## Where the answers go Answers roll up into [Insights](/docs/conversations/insights) alongside resolution rate, so you can compare what the agent recorded against what visitors said. This is different from the thumbs up and down on individual replies. Those rate one answer and feed [Improve answer](/docs/conversations/inbox); this rates the conversation. --- # Voice URL: https://www.hey.support/docs/capabilities/voice Let visitors talk to the agent out loud and hear it reply, using the same knowledge and guardrails as text. Voice lets a visitor speak to the agent instead of typing, and hear the answer back. Open **Capabilities**, then **Voice**. Voice is available on **Growth and above**. On Free and Starter the panel shows an upgrade prompt. See [Plans](/docs/billing/plans). ## Settings * **Voice** — pick one from the list and use **Preview** to hear it before you ship. Three dropdowns above the list narrow it down by gender, language and style; they filter what you are choosing from, they are not settings in their own right. * **Spoken greeting** — an optional line the agent says when a call starts. Keep it to one sentence. * **Usage meter** — minutes used this month against your allowance. ## Same brain, different mouth Voice runs the same pipeline as text: your knowledge base, your instructions, your topic boundaries, your capabilities. It transcribes what the visitor said, runs the agent, and speaks the reply. Two things are deliberately different: * **Replies are shorter.** The agent is told to answer in one to three short sentences and never to read a URL aloud. That instruction sits after your custom instructions, so it survives them. * **Cards still work.** If the agent decides to show a lead form, a scheduler or a handoff during a call, it says so out loud and the card appears in the widget. Custom buttons are the exception — they appear in the transcript but are never spoken about. A visitor can end a call at any time and carry on typing; the transcript and any cards stay where they are. ## How it is metered Voice is billed in **minutes of active speaking time** — the visitor's speech plus the agent's, and nothing else. Silence, thinking time, network delay and dashboard previews do not count. It is metered separately from your conversation pool. A call that is already running is never cut off mid-sentence: the allowance is checked when a call starts, not while it is in progress. Growth and Scale can opt in to overage, with a budget you set, to keep voice working past the allowance. Full counting rules and allowances are in [Usage and limits](/docs/billing/usage-and-limits). --- # Bookings URL: https://www.hey.support/docs/conversations/bookings Meetings booked through the chat, upcoming and past. Bookings lists the meetings visitors scheduled through the agent. Open the **Inbox** toggle in the top navigation, then **Bookings**. ## The list Split into **upcoming** and **past**, with search and a status filter. Each row shows who booked, when, and which provider it came through. A booking also creates a [lead](/docs/conversations/leads) quietly, so you have the contact without a duplicate notification for the same person. ## Notifications When a meeting is booked, we: * fire the `booking.created` [webhook](/docs/webhooks) * post to any Slack channel you have routed * email teammates who have booking alerts switched on Booking alerts are **on by default** for both owners and members. Change that on your account's notification preferences. `booking.rescheduled` and `booking.canceled` fire on the corresponding changes. ## Rescheduling and cancelling Rows created by live scheduling can be rescheduled or cancelled from here, and the visitor is emailed about the change. Rows created from a [scheduling link](/docs/capabilities/booking) are managed wherever the link points — we recorded the meeting, but your scheduler owns it. --- # Agent dashboard URL: https://www.hey.support/docs/conversations/dashboard The first screen in the Inbox context — what needs you right now, and how the agent is doing. The dashboard is where the Inbox side of an agent opens. It answers two questions: is anything waiting on me, and is the agent healthy. Open the **Inbox** toggle in the top navigation, then **Dashboard**. ## What needs you The top of the page is work: conversations where a visitor asked for a human and nobody has picked it up yet, and any [AI Action](/docs/capabilities/ai-actions) waiting on an approval. The same count drives the badge on the Inbox tab, so you can see it without leaving the Build side. "Waiting for a human" means the visitor asked and no teammate has joined — not that the conversation is in a particular status. An email-only handoff on a Free plan counts exactly the same as a live-chat request on Growth. ## How it is doing Below that, the headline numbers for the agent: conversations, resolution, leads captured, and recent trend. This is the short version. [Insights](/docs/conversations/insights) is the same data with a date range and the breakdowns. ## Where to go next * Something waiting → [Inbox](/docs/conversations/inbox) * Someone browsing right now → [Live visitors](/docs/conversations/live-visitors) * Resolution slipping → [Unanswered questions](/docs/knowledge/unanswered-questions) --- # Inbox URL: https://www.hey.support/docs/conversations/inbox Read every conversation, jump in as a human, add notes and tags, and improve answers over time. The Inbox is where you see what the agent is actually doing. Every visitor conversation lands here, whether the agent handled it on its own or a visitor asked for a person. Open **Inbox** from the top navigation. The left side is the list of conversations; the right side is the thread you have open. ## Status Each conversation has a status: * **Open** is active or unresolved. * **Waiting** means it is waiting for a human reply after a handoff. * **Resolved** means it is done. The agent can resolve simple chats on its own, and you can set the status by hand. ## Taking over When a visitor needs a person, or you just want to step in, you can take over the conversation and reply yourself. The visitor sees that a human joined. While you are handling it, the agent stays out of the way. This is the other half of [human handoff](/docs/capabilities/overview). ## Replying The composer has two modes: * **Reply** sends a message to the visitor. * **Note** adds an internal note that only your team sees. Notes are good for context, like "called back, left a voicemail." They do not count toward the conversation's message total. Two tools speed up replies: * **Canned responses.** Type `/` to pull up saved replies and insert one. They can fill in the visitor's name and other details automatically. Manage them in [Workspace settings](/docs/billing/workspace-settings). * **Tags.** Label conversations so you can filter them later. Tags come from a shared library that grows as your team uses them, and the agent can suggest tags for a conversation. ## Improve this answer When the agent gives a weak answer, open **Improve this answer** on that message. You provide the correct response, and it feeds straight back into the agent's knowledge, either as a quick answer or as a knowledge chunk. Over time this is how the agent gets sharper on the questions your customers actually ask. ## Visitor details The sidebar next to a thread shows what we know about the visitor: their device, location, where they came from, when they first and last visited, and any details they gave, like a phone number or a captured lead. If the conversation is on a connected Shopify or WooCommerce store, their order context shows here too. ## Approvals If an [AI Action](/docs/capabilities/ai-actions) needs a human to approve it, the request appears in the thread as a card. Approve or deny it, and the visitor gets the result. --- # Insights URL: https://www.hey.support/docs/conversations/insights How the agent is performing, when people chat, and what it cannot answer yet. Insights turns your conversations into numbers you can act on. Open **Insights** from the top navigation. It is a single page with a date range at the top — Today, Last 7 days, Last 30 days, or a custom range. Everything below reflects that range. ## What is on the page **At a glance.** Conversation count, resolution, leads and the other headline numbers. **Resolved.** The single best health check. If it is high the agent is doing its job; if it drops, something changed — usually your content or your traffic. **Conversation volume.** The same count over time, so you can see direction rather than a snapshot. Watch volume and resolution together: rising volume with steady resolution is growth, rising volume with falling resolution means the agent is getting questions it cannot handle. **Busiest hours.** When your customers actually need you, which is when a teammate should be around for handoffs. **Resolution outcomes.** How conversations ended. **Top questions.** What people actually ask, most first. **Unanswered questions.** A preview of the questions the agent could not answer, linking through to the full queue. ## Fixing what it surfaces The unanswered-questions card is a preview. The work happens in [Unanswered questions](/docs/knowledge/unanswered-questions) under Knowledge, because fixing one means writing a quick answer or adding a source — both Knowledge jobs. Treat that queue as a to-do list. Each row is a question a real customer asked and did not get an answer to. ## Getting a real resolution signal For the resolution numbers to mean something, turn on [Resolution feedback](/docs/capabilities/resolution-feedback) under Capabilities. It asks visitors whether the chat helped, so you are measuring outcomes rather than inferring them from message counts. --- # Leads URL: https://www.hey.support/docs/conversations/leads A simple pipeline for the people your agent captured, from first contact to won or lost. Every time the agent captures someone's details, they become a lead. The Leads board is a lightweight CRM for working those leads without leaving Hey Support. Open **Leads** from the top navigation. ## The pipeline Leads sit in a board with five stages you drag them through: * **New** * **Contacted** * **Qualified** * **Converted** * **Lost** Move a lead as you work it. The board gives you an at-a-glance view of where everyone is. ## A lead's details Open a lead to see everything about it, across a few tabs: * **Chat** is the conversation the lead came from, so you have the full context. * **Details** holds their name, email, phone, company, intent, source, and when they were captured. * **Notes** is for your internal notes about the lead. * **Tasks** tracks follow-ups. * **Activity** is the history of what happened with this lead. ## Adding a lead by hand Most leads arrive on their own from conversations. If you take one over the phone or by email, add it with **Add lead** and fill in the details yourself. ## Turning capture on Sales lead capture is on by default, collecting name and email. Choose which fields to collect (or turn it off) in [Capabilities](/docs/capabilities/overview). --- # Live visitors URL: https://www.hey.support/docs/conversations/live-visitors Who is on your site right now, what page they are on, and taking a conversation over. Live visitors shows the people on your site at this moment — including the ones who have not typed anything yet. Open the **Inbox** toggle in the top navigation, then **Live visitors**. ## Three groups The rail on the left splits everyone into: * **Needs you** — asked for a human, nobody has picked it up * **In conversation** — actively chatting with the agent * **Browsing** — on the site with the widget loaded, not chatting That third group is the reason this page exists. It used to only show people who had already sent a message, which is a small fraction of the people on your site at any moment. ## How presence works The widget sends a quiet heartbeat while the tab is visible. When someone closes the tab or navigates away, they drop off within about a minute. Two kinds of people appear here without a heartbeat, and they are marked differently: * Someone who asked for a human and then closed the tab. They still need answering. * Anyone chatting on a [messaging channel](/docs/integrations/telegram) — there is no widget on their screen to send a heartbeat. ## The map Visitors are placed on a map from their approximate location. It is city-level and derived from the network request, not from anything the visitor gave you, so several people in the same city collapse onto one pin. The map needs a Google Maps key to be configured. Without one the rest of the page works exactly as normal and the map area explains itself. ## Taking over **Take over** claims the conversation and drops you into the [Inbox](/docs/conversations/inbox) to reply. There is deliberately no second composer here — one place to type. If a teammate claims the same conversation a moment before you, you are told who has it rather than silently reassigning it. --- # Appearance URL: https://www.hey.support/docs/experience/appearance Styles, light and dark mode, and your brand color for the chat widget. Experience is where you set how the widget looks and feels. Open **Experience** from the top navigation. A live preview sits next to the controls so you see every change as you make it. ## Styles Start from one of three styles. Each is a complete look — shapes, type, spacing, and motion: * **Clean** is a quiet neutral look with a pill composer and easy space. It is the default and works almost anywhere. * **Glass** uses translucent surfaces that let your site show through behind the conversation. * **Friendly** rounds every shape and switches to the Nunito typeface for a warmer, approachable feel. Every style comes in **Light** and **Dark** — flip between them with the toggle beside the style tiles. The preview tiles render with your actual brand color and mode, so what you see on the tile is what deploys. ## Brand color Your **Brand color** is one hex value that recolors the whole widget: the send button, action buttons, the visitor's message bubble, and the text tints all derive from it automatically. Pick a swatch or enter any hex. Everything derived from your brand color picks readable text automatically — light accents carry dark text, dark accents carry white — so you never end up with pale text on a pale button. Backgrounds and surfaces stay neutral so the conversation always reads clearly. Picking a style never changes your brand color, and changing your brand color never changes the style. The two are independent. ## The rest of Experience Appearance is one part of Experience. The other pages cover: * [Identity and launcher](/docs/experience/identity-and-launcher): the widget's name, subtitle, avatar, and the button that opens it. * [Messages and prompts](/docs/experience/messages-and-prompts): the opening message and suggested prompts. * [Home screen](/docs/experience/welcome-screen): the rich home tab. * [Sound and voice](/docs/experience/sound-and-haptics): audio feedback and the voice add-on. --- # Identity and launcher URL: https://www.hey.support/docs/experience/identity-and-launcher The widget's name and avatar, and the launcher button visitors click to open it. ## Identity * **Title** is the agent's name in the widget. Use a customer-facing name like "Acme Assistant". * **Avatar** is the image beside it. Upload your logo mark or a friendly face. If you created the agent from a URL, we set this from your site's favicon. There is no subtitle field. It was removed in July 2026 — the widget's header is now a compact identity pill rather than a band, and a second line of text there competed with the greeting immediately below it. ## Launcher The launcher is the button in the corner of your site that opens the widget. Three types. ### Icon A glyph on a coloured disc. Eight icons — chat bubble, question, headset, sparkles, bot, hand wave, message square, help — each with an **Animated** toggle, so choosing motion no longer means giving up the glyph you wanted. You can also upload your own image (JPG, PNG, SVG or WebP, up to 2 MB). A custom upload should read clearly at a small size. ### Blob An animated shader. Six presets: **Glow**, **Halftone**, **Aurora**, **Prism**, **Nebula**, **Gooey**. Glow and Halftone follow your brand colour. The other four carry their own palettes — the palette is the preset, so recolouring them would just make them a worse version of something else. The picker marks which is which. ### Interactive A small character that looks around, blinks, and reacts. Pick its shape: Circle, Pebble, Squircle or Bubble. ## Size Small (56px), Medium (64px) or Large (72px). Small is the default and is what every existing agent uses. ## Two switches in the same panel * **Message preview bubble** — a short teaser beside the launcher showing your opening message, before anyone clicks. On by default. A visitor who dismisses it does not see it again for a week; opening the chat settles it for that visit. * **Floating chat window** — if a visitor switches to another tab mid-conversation, the chat pops into a small always-on-top window so they do not lose their place. Desktop Chrome, Edge and Firefox; it asks the visitor the first time and silently does nothing where it is unsupported. ## Position and open-on-load Position is set here. Opening the widget automatically on page load has **no toggle** — it interrupts, and no workspace was using it. If you specifically want it, add `data-auto-open` to the embed script tag. See [the embed script](/docs/build/embed-script). --- # Messages and prompts URL: https://www.hey.support/docs/experience/messages-and-prompts The opening message, suggested prompts, composer placeholder, and the message shown when a Free workspace is at its cap. The first impression controls set what a visitor sees the moment they open the widget, before they type anything. ## Opening messages The opening message is the agent's greeting. It is on by default, and a new agent is seeded with two bubbles so the greeting arrives in a couple of natural beats rather than one long paragraph. The greeting is the head of the conversation, not a separate screen: it renders as real messages at the top of the thread and animates in exactly like a reply would. Keep it warm and specific. "Hi, I can help with orders, returns, and product questions" tells a visitor what to ask far better than "How can I help you today?" Do not use the greeting to ask for a name or an email. Contact details are collected by [Sales lead capture](/docs/capabilities/lead-capture) at the moment they are relevant, in a real form that pre-fills — asking up front is a pre-chat form by another name, and it measurably costs you conversations. ## Suggested prompts Suggested prompts are the tappable bubbles under the greeting. They are the fastest way to show visitors what the agent is good at. Add up to five. Each prompt is **one field**: what the chip says is what gets sent. There used to be a separate label, and all it ever did was let the visible chip and the message the agent received drift apart. Good prompts mirror your top real questions: * "Where is my order?" * "What is your return policy?" * "Do you ship internationally?" Prompts are on by default with generic examples. Replace them with yours. ## Composer placeholder The composer placeholder is the grey hint text in the message box. Use it to invite a question, like "Ask about pricing, features, or setup." ## Cap-reached message On the Free plan, when a workspace uses up its monthly conversation pool, new visitors see a message instead of a live agent. You can customize that message here so it stays on-brand, for example pointing people to email until the pool resets. Paid plans have large enough pools that most workspaces never see this. See [Usage and limits](/docs/billing/usage-and-limits). --- # Sound and haptics URL: https://www.hey.support/docs/experience/sound-and-haptics The small piece of feedback the widget gives when messages send and arrive. The widget can acknowledge a message with a short sound or a small buzz. Open **Experience**, then the sound and haptics section. ## One list, six options It is a single choice, not two settings: | Option | What it does | | ----------- | ------------------------------------------------ | | **Chime** | Warm, rounded tones | | **Studio** | Crisp pluck with a deep reply | | **Deep** | Low, physical thumps | | **Air** | Light, airy ticks | | **Haptics** | A subtle buzz on phones, a soft click on desktop | | **Off** | Nothing | Haptics is the default for a new agent. ## Notes Audio only starts after the visitor has interacted with the page, so nothing ever plays uninvited. If the browser blocks it, the widget carries on silently rather than blocking the conversation. Pick to match the brand rather than to be noticed: a calm support brand is usually better with Haptics, a consumer one can carry a sound pack. Looking for spoken conversations? That is [Voice](/docs/capabilities/voice), which lives under Capabilities. --- # Welcome screen URL: https://www.hey.support/docs/experience/welcome-screen The pre-chat surface visitors land on — a stack of blocks you arrange, from a greeting to FAQs to product cards. The welcome screen is what a visitor sees when they open the widget before they have said anything. You build it from a stack of blocks. Open **Experience**, then **Welcome screen** under More customization. It opens as its own page with the live preview beside it. This used to be called the Home Screen. Same idea, rebuilt: more block types, templates to start from, and click-to-edit on the preview. ## Starting from a template An empty welcome screen offers four templates — **Support**, **Sales**, **Ecommerce**, **Booking** — plus **Start from scratch**. Nothing is seeded until you pick. That is deliberate: a screen that seeded itself on load would leave you on an already-dirty page warning about changes you never made. ## The nine blocks | Block | What it is | | ------------------- | -------------------------------------------------------------------------------------------------------------------- | | **Welcome** | The greeting at the top. Pinned first, one only, and you can delete it if you would rather open with something else. | | **Announcement** | A short highlighted notice — a launch, an outage, opening hours. | | **Quick questions** | Tappable questions that open the chat with that question already sent. | | **Buttons** | Links out to your own pages. | | **FAQ** | Question and answer pairs that expand in place, without starting a chat. | | **Booking** | A prompt to schedule, wired to your [Book a meeting](/docs/capabilities/booking) setup. | | **Products** | Product cards you author. | | **Contact** | Your contact details. | | **Divider** | A rule, with an optional label. | Drag to reorder. A block that would render empty — a Buttons block with no URLs, an FAQ with no pairs — is marked **Not showing** in the editor and is left out of the widget rather than rendering as a gap. ## Click to edit Clicking a block in the preview selects it in the editor, and selecting a block in the editor highlights it in the preview. The preview is the real widget, so clicks on links and quick questions are intercepted rather than followed — otherwise editing a Buttons block would navigate the preview away. ## Conversation history A switch in the block list rather than a buried setting, because it changes the widget's shape: turning it off removes the resume card, the bottom tab bar and the history item from the menu. You can see it happen in the preview beside you. Session resume is separate and stays on — a visitor coming back within 24 hours still lands in their conversation. ## Advanced Only the entry-button labels — the wording on the button that opens the chat. --- # Core concepts URL: https://www.hey.support/docs/getting-started/core-concepts The handful of ideas that everything else builds on: workspace, chatbot, knowledge, conversation, and lead. A few terms come up everywhere in Hey Support. Here is what each one means. ## Workspace Your workspace is the top-level container. It holds your chatbots, your team members, your plan, and your billing. When you sign up, you get one workspace. You can belong to more than one, and you switch between them from the sidebar. Owners manage billing, members, and roles. Members can build and run agents but cannot touch billing. See [Team and roles](/docs/billing/team-and-roles). ## Chatbot A chatbot (we also call it an agent) is a single assistant with its own knowledge, personality, look, tools, and install. Most workspaces run one. Higher plans let you run several, for example one per brand or one per language. Your plan sets how many chatbots you can create. See [Plans](/docs/billing/plans). ## Knowledge Knowledge is what the agent knows. It comes from two kinds of source: * **Trained sources** (websites, files, and text) are broken into chunks and searched at answer time. The agent pulls the most relevant pieces into each reply. This is retrieval. * **Direct sources** (quick answers and quick links) are handed to the agent verbatim. Use these for exact facts you never want paraphrased, like prices or opening hours. More in [Knowledge](/docs/knowledge/overview). ## Conversation A conversation is one visitor's chat session. It has a status (open, waiting, or resolved), a running message count, and any tags you add. Conversations show up in the [Inbox](/docs/conversations/inbox), where you can read them, jump in, and reply as a human. Your plan includes a monthly pool of conversations. See [Usage and limits](/docs/billing/usage-and-limits). ## Lead A lead is a person the agent captured contact details for, usually a name and email. Leads land in the [Leads](/docs/conversations/leads) board, a simple pipeline you move from New to Converted. Turn capture on in [Capabilities](/docs/capabilities/overview). ## How they connect A workspace holds chatbots. A chatbot has knowledge, tools, and a look. When a visitor chats, that is a conversation. When the agent captures their details, that is a lead. Everything you do in the docs sits somewhere on that chain. --- # Create your agent URL: https://www.hey.support/docs/getting-started/create-your-agent The setup screen, the thirteen templates, and what happens after you paste a URL. Every agent starts at **New chatbot**. It is one card: a website, a name, and a template. ## The setup card **Website URL.** Paste your homepage. We read it straight away, index it, and pull your logo. It also fills in the agent name for you — `grandworks.co` becomes "GrandWorks" — which you can then overwrite. **Agent name.** What your customers see, so "Acme Assistant" rather than an internal label. **Template.** Collapsed by default, showing the current pick. Open it to choose from thirteen. Select **Create chatbot** to finish. You land on the agent's Knowledge page, watching the first page get read. Leaving the website blank is fine. You get the template's defaults and add knowledge by hand from [Knowledge](/docs/knowledge/overview). ## Templates Templates pre-fill a starting role, tone, opening messages, draft quick answers, and the capabilities that make sense for that kind of business. Pick the closest match and edit afterwards. * **Custom** — a blank agent with no presets * **Customer support** * **Ecommerce** * **Sales & Leads** * **SaaS** * **Restaurants** * **Hotels** * **Travel agencies** * **Real estate** * **Medical practices** * **Salons & spas** * **Fitness studios** * **Law firms** ## Template quick answers arrive as drafts A template seeds a handful of quick answers, and they are marked **Draft**. A draft is visible to you in the builder and is **never used by the agent** until you publish it. This is on purpose. Template copy has to say something plausible about a business it knows nothing about — opening hours, payment methods, compliance claims — and an agent asserting invented facts about you is worse than one saying it does not know. Review each one, correct it, and save to publish. If you gave us a URL, most of them are replaced automatically: once the crawl finishes we generate quick answers grounded in your actual site and swap them in, as long as you have not edited them yourself. ## What happens after the first crawl For an agent created with a URL, we do a one-time setup pass over what we read: * Fill in the business description if it is still empty * Add site-specific notes to the instructions * Turn on capabilities the site clearly needs * Replace the template's quick answers with grounded ones * Replace the generic greeting with one that names what you actually do * Set the avatar from your site's favicon It runs once per agent, ever, and it never overwrites something you have edited yourself. There is no "apply a different template later". Templates are a starting point at creation time only. To change direction afterwards, edit [Behavior](/docs/behavior/overview) and [Capabilities](/docs/capabilities/overview) directly — which is all a template does anyway. --- # Quickstart URL: https://www.hey.support/docs/getting-started/quickstart Create an agent, train it on your website, and put it live in about five minutes. This is the fastest path from a blank account to a working agent on your site. You can refine everything later. ## 1. Create your account Go to [hey.support](https://hey.support) and sign up with your name, work email, and a password, or use **Continue with Google**. You start on the Free plan, so there is nothing to pay. If you signed up with email and password, check your inbox and confirm your address. You can look around the dashboard right away, but you need a verified email before you can deploy an agent. ## 2. Create your first agent New workspaces open on the setup screen. Pick a template that matches your business (or **Custom** for a blank start), give the agent a name, and paste your website URL. We train on your homepage right away and grab your logo. You add more pages, files, and sitemaps later from Knowledge, so one URL is enough to begin. Select **Create chatbot**. You land on the agent dashboard. ## 3. Train it on more of your site Open **Knowledge** from the top navigation. Select **Add**, then **Website**. You have three choices: * **Crawl a whole site.** We scan your pages first and show you what we found, then you pick which pages to index. * **Paste a sitemap URL.** Point us at your `sitemap.xml` and we read the list of pages from it. * **Index a single page.** Add one URL on its own. For a first pass, crawl your site, review the list, and index the pages that answer real customer questions (pricing, docs, product, contact, FAQs). Skip blog archives and legal pages unless customers ask about them. ## 4. Try it before you ship Open **Preview & Launch**. The live preview beside the form is the real agent with your real settings — chat with it exactly as a visitor would. Ask a few real questions and check the answers against your site. If an answer is thin, that usually means the page it needs is not indexed yet. Go back to Knowledge and add it, or write a [quick answer](/docs/knowledge/quick-answers-and-links) for the exact response you want. ## 5. Put it live Still on **Preview & Launch**, copy the embed snippet. It is one line: ```html ``` Paste it before the closing `` tag on your site. Then add your site's domain under **Allowed domains**. The agent goes live on that domain the first time real traffic reaches it, and the domain flips from Pending to Verified on its own. That is the whole loop. From here, shape how the agent talks in [Behavior](/docs/behavior/overview), style the widget in [Experience](/docs/experience/appearance), and turn on tools like lead capture and human handoff in [Capabilities](/docs/capabilities/overview). --- # Integrations overview URL: https://www.hey.support/docs/integrations/overview How connecting apps works, the two sides of it, and where each one lives. Integrations connect Hey Support to the other tools you run: your store, your CRM, your team chat, your automation stack. There are two sides to it, and keeping them straight makes everything easier. ## Connect in, route out * **Connections** is where you authorize an app for your whole workspace, once. This is the front door: you connect Shopify, WooCommerce, HubSpot, or Slack here, and it stays connected for every agent in the workspace. Find it under **Settings, Connections**. * **Integrations** on each agent is where you route that agent's activity out. This is per-agent: which Slack channel gets this agent's alerts, which email address, which webhook, which store powers its order lookups. Find it under **Integrations** in the agent's Build navigation. The short version: connect an app once in the workspace, then wire each agent to it. A store you connect once can power several agents. ## What you can connect The Integrations catalog groups apps by what they do: * **Messaging channels**: Telegram (live), with WhatsApp, Messenger, and Instagram on the way * **Team alerts**: Slack, email, and more * **E-commerce**: Shopify and WooCommerce * **CRM and support**: HubSpot, with others coming * **Automation**: Zapier and outbound webhooks ## Detailed guides For the developer surface (webhooks and the public API), see [Developers](/docs/webhooks). --- # Shopify URL: https://www.hey.support/docs/integrations/shopify Install on your Shopify store, show the widget on your storefront, and answer order questions with real data. The Shopify integration does three things: it puts the widget on your storefront, it connects your live catalog, and it lets the agent look up real order data. ## Install Install the Hey Support app from Shopify. The app install is the connection, so there is nothing extra to authorize. Once installed, enable the theme app embed to show the widget on your storefront. If you install from Shopify before you have a Hey Support account, we hold the connection and link it to your workspace when you sign up. The install also connects your **storefront catalog** automatically, so product search and add-to-cart work without you typing your store address anywhere. Turn them on under [Ecommerce](/docs/capabilities/ecommerce). ## Link the store to an agent A connected store can power more than one agent. From the agent's **Integrations** page, link the store you want this agent to use. Linking is what lets the agent answer questions using that store's data. ## What the agent can do With a store connected, the agent can run order-related actions, such as: * Looking up an order's status * Recommending products * Listing a customer's recent orders * Creating a discount code These are [AI Actions](/docs/capabilities/ai-actions), so they run only when the conversation calls for them, and some (like a large discount) can require your approval first. ## Storefront context On your storefront, the widget knows the page context: the shop, the logged-in customer, and their cart. That lets the agent give answers grounded in what the visitor is actually looking at, and it shows in the [Inbox](/docs/conversations/inbox) visitor sidebar. Some order actions need protected data access. If an action shows that it needs a permission like read orders, re-authorize the store to grant it. The agent turns those actions on automatically once the permission is granted. ## Shipping and returns Answered from your [knowledge base](/docs/knowledge/overview), not from Shopify. The endpoint that served store policies to agents was retired on 31 August 2026, so index your policy pages like any other content. --- # Slack URL: https://www.hey.support/docs/integrations/slack Get agent activity in Slack, and route each agent's events to the channels you choose. Connect Slack to get notified in your team's workspace when something happens: a new lead, a handoff request, an action that needs approval. ## Connect Slack Go to **Settings, Connections** and connect Slack. You authorize the Hey Support Slack app for your workspace once. This is the workspace-level step. ## Route events per agent Once Slack is connected, open **Integrations** on an agent to decide what goes where. For each event you care about, pick the Slack channel it should post to. Different agents can post to different channels, so a support agent's handoffs and a sales agent's leads do not land in the same place. Events you can route include: * New leads * Handoff requests * Actions that need approval Connecting Slack is workspace-wide, but routing is per-agent. If nothing is posting, check that the specific agent has a channel set under its Integrations page, not just that Slack is connected. ## Disconnecting Disconnect Slack from the Connections hub. That removes it for the whole workspace, and any per-agent routes stop firing. --- # Telegram URL: https://www.hey.support/docs/integrations/telegram Run the same agent on Telegram, with conversations landing in the same inbox. Connecting Telegram lets the same agent answer on Telegram, with the same knowledge, behaviour and capabilities as your website widget. Those conversations land in the same [Inbox](/docs/conversations/inbox). Messaging channels are available on **Growth and above**. See [Plans](/docs/billing/plans). ## Setting it up 1. In Telegram, message [@BotFather](https://t.me/botfather) and send `/newbot`. Follow the prompts to name your bot. 2. BotFather replies with an **API token**. Copy it. 3. In Hey Support, open the agent's **Integrations** page and find Telegram under Messaging channels. 4. Paste the token and connect. We verify the token with Telegram before storing it, so a bad paste fails immediately rather than silently. Once connected the card shows your bot's `@username`. Tokens are encrypted at rest. ## How it behaves One Telegram bot connects to one agent. A visitor messaging your bot gets the same answers your website visitors get. Two differences from the widget, both structural: * **The conversation has no expiry.** Messaging is a persistent one-to-one surface, so there is no 24-hour resume window — the thread just continues. * **Cards become text.** A Telegram message cannot render a booking card or a lead form, so the agent shares the same information inline instead. Inbox rows from Telegram carry a channel chip so you can tell at a glance where a conversation came from. Replying from the Inbox sends back to Telegram; [internal notes](/docs/conversations/inbox) stay internal. ## Disconnecting Disconnect from the same card. The bot stops relaying immediately. Existing conversations stay in your inbox. ## Other channels WhatsApp, Messenger and Instagram appear as coming-soon in the dashboard. One agent, many front doors. Whatever you set in Knowledge, Behavior and [Capabilities](/docs/capabilities/overview) applies everywhere the agent runs — a channel is not a second agent to maintain. --- # WooCommerce URL: https://www.hey.support/docs/integrations/woocommerce Connect a WooCommerce store with API keys so the agent can answer order questions. WooCommerce connects to your store so the agent can look up orders and answer from your live catalog, the same way it does on Shopify. ## Connect a store Go to **Settings, Connections** and open the WooCommerce connect dialog. Enter your store URL and approve the connection **inside your own WordPress admin** — one click, no keys to copy. The same approval also connects your storefront catalog, so [Ecommerce](/docs/capabilities/ecommerce) works straight away. ### If the one-click approval will not work Two situations need the manual path, and the dialog offers it: * WordPress cannot reach a site on `localhost` or a non-standard port, so local development has to paste keys. * A store on **Plain** permalinks does not expose the approval endpoint. For those, generate a **consumer key** and **consumer secret** in your WordPress admin under WooCommerce, Settings, Advanced, REST API — read access is enough for order lookups — and paste them with your store URL. Your secret is encrypted at rest and is only ever used to call your store's API. ## Link the store to an agent Like Shopify, a connected WooCommerce store can power several agents. Link it to a specific agent from that agent's **Integrations** page. ## What the agent can do With a store connected, the agent can: * Look up an order * Update a shipping address * Create a coupon These run as [AI Actions](/docs/capabilities/ai-actions). A coupon, being a money action, can require your approval first. If you run WooCommerce, you can also connect it straight from the [WordPress plugin](/docs/integrations/wordpress), which hands the details over for you. --- # WordPress URL: https://www.hey.support/docs/integrations/wordpress Install the official plugin to put the agent on a WordPress site, with optional WooCommerce. The Hey Support plugin puts the widget on any WordPress site without touching theme code. ## Install the plugin Install the official Hey Support plugin from your WordPress admin. In the plugin settings, enter your **Chatbot ID** (copy it from the agent's [Deploy](/docs/launch/embed) page). Save, and the widget appears across your site. The plugin gives you three ways to place the widget: * Automatically in the site footer, on every page * With a shortcode, to place it on specific pages * As a block in the WordPress editor ## Connect WooCommerce If your site runs WooCommerce, the plugin can connect your store to Hey Support so the agent can answer order questions. It hands the store details over for you, so you do not have to copy API keys by hand. See [WooCommerce](/docs/integrations/woocommerce) for what the agent can do once connected. The plugin only ever carries your Chatbot ID to the widget, never your account credentials, so it is safe to keep installed. --- # Zapier URL: https://www.hey.support/docs/integrations/zapier Connect Hey Support to thousands of other apps with no code. Zapier connects Hey Support to thousands of other apps. Use it to push leads into a spreadsheet, alert a Slack channel, add a row to a CRM, or anything else you can wire up in Zapier, without writing code. Zapier runs on the public API, which is available on **Scale and above**. On lower plans you cannot create an API key, and an existing key stops being accepted — so a Zap built on Scale stops working if the workspace moves down a plan. See [Plans](/docs/billing/plans). ## Connect In Zapier, add Hey Support and authenticate with an **API key**. Create the key in **Settings, Developer** (owner only). See [Workspace settings](/docs/billing/workspace-settings). ## Triggers Triggers start a Zap when something happens in Hey Support: * **New lead** * **New conversation** * **Handoff requested** For example, "New lead" into "Create a row in Google Sheets" gives you a running log of every lead with no manual export. ## Actions Actions let a Zap do something in Hey Support: * **Create a lead** * **Tag a conversation** * **Add an internal note** to a conversation Zapier runs on the public API, so it inherits the same auth and rate limits. If you would rather build a direct integration, see the [API](/docs/api). --- # Embed on your site URL: https://www.hey.support/docs/launch/embed Copy the one-line snippet, add your domain, and put the agent live. The agent goes on your site with a single script tag. Open **Preview & Launch** from the top navigation. ## Copy the snippet The embed is one line. Copy it from the Deploy page: ```html ``` Paste it into your site just before the closing `` tag. On most platforms there is a place to add a custom script or footer code; that is where this goes. The `defer` attribute means it loads without slowing your page down. The theme, position, greeting, and everything else are set in your dashboard, so the snippet never changes when you tweak the agent. It stays exactly this thin. ## Your Chatbot ID The Deploy page also shows your **Chatbot ID** on its own, with a copy button. It is the same ID that appears in the snippet. Some installs, like the WordPress plugin, ask for the ID directly rather than the whole script. ## Allowed domains Add every domain the agent should run on under **Allowed domains**. This is what makes the agent live. Domains verify themselves. The first time real traffic reaches the agent from a domain you added, it flips from **Pending** to **Verified**. You do not paste a token or edit DNS. The "Live on N sites" count at the top reflects the domains actually serving traffic. You need a verified email address before you can deploy. If you signed up with email and password and have not confirmed your address yet, the Deploy page prompts you to do so. ## Test before you ship The page carries a **live preview** beside the form — the real agent with your real settings, not a mock — so you can talk to it exactly as a visitor would before the snippet goes anywhere. There is also a **Live demo** card with a shareable link to a hosted version of the agent. That is the one to send a colleague for a second opinion; it needs no login. Ask your real top questions and check the answers. If one is weak, the fix is almost always in [Knowledge](/docs/knowledge/overview). ## Other ways to install If you are on Shopify, WordPress, or a site builder, you may not need to paste the script by hand. See [One-click installs](/docs/launch/one-click-installs). --- # One-click installs URL: https://www.hey.support/docs/launch/one-click-installs Install the agent on Shopify, WordPress, and site builders without pasting code by hand. If your site runs on a platform we support, you can skip the manual script. The Deploy page has a one-click install for each. You still add your domain under Allowed domains the same way. ## Shopify Install through the Shopify theme app embed. Once connected, the widget shows on your storefront with no theme code to edit. The Shopify install also unlocks order-lookup actions, so the agent can answer "where is my order" questions using real store data. See [Shopify](/docs/integrations/shopify). ## WordPress Install the official Hey Support plugin. Enter your Chatbot ID in the plugin settings and the widget appears across your site. The plugin can also connect a WooCommerce store. See [WordPress](/docs/integrations/wordpress). ## Webflow and Framer Both are marked **Coming soon** in the dashboard — the tabs are there so you can see what is planned, but there is no one-click install for either yet. Both work today with the standard [embed snippet](/docs/launch/embed): paste it into the site's custom code area. ## Which to use If a one-click install exists for your platform, use it; it is less to maintain. If not, the [embed snippet](/docs/launch/embed) works on any site that lets you add a script tag. --- # Auto-update URL: https://www.hey.support/docs/knowledge/auto-update Keep website sources fresh on a schedule so the agent stays current as your site changes. Your site changes. Prices move, pages get rewritten, products come and go. Auto-update re-fetches your website sources on a schedule so the agent does not fall behind. You control it from the **Refresh** dropdown in the Knowledge toolbar. ## Two things live here * **Re-index all now** re-fetches every website source immediately. Use it after a big site update when you do not want to wait for the schedule. * **Auto-update websites** sets a recurring schedule: **Off**, **Weekly**, or **Daily**. Auto-update applies to website sources only. Files, text, and quick answers never change on their own, so there is nothing to refresh. ## What a refresh does On each run we re-fetch your website sources and compare them to what we already have. Pages that have not changed are skipped, so a refresh is cheap and does not re-process unchanged content. Pages that changed are re-indexed. If a page fails to load, we keep the existing version rather than deleting it, so a temporary outage never wipes your knowledge. The toolbar shows when the agent was last refreshed. ## Plan limits Auto-update cadence depends on your plan: | Cadence | Available on | | ------- | ---------------- | | Off | Every plan | | Weekly | Growth and above | | Daily | Scale and above | If your plan does not include a cadence, the option is shown but locked with the plan you would need. Downgrading does not clear a schedule you set earlier; it just pauses until you are back on a plan that allows it. See [Plans](/docs/billing/plans). --- # Files URL: https://www.hey.support/docs/knowledge/files Upload documents the agent should learn from. PDF, Office, OpenDocument, EPUB, text, Markdown, JSON, and CSV. Files are the right choice for content that does not live on a public web page: product manuals, policy documents, price sheets, internal FAQs you have exported, and anything a crawl cannot reach. Open **Knowledge**, select **Add**, then **Files**. ## What you can upload | | Extensions | | ------------ | ---------------------- | | PDF | `.pdf` | | Word | `.doc`, `.docx` | | PowerPoint | `.ppt`, `.pptx` | | Excel | `.xlsx` | | OpenDocument | `.odt`, `.ods`, `.odp` | | Rich text | `.rtf` | | EPUB | `.epub` | | Plain text | `.txt`, `.csv` | | Markdown | `.md`, `.markdown` | | JSON | `.json` | Each file can be up to 10 MB. Upload several at once. Word documents keep their heading structure when the file carries real heading styles, which gives the agent better context about where an answer came from. A document formatted with manually-enlarged bold text instead of Heading 1 reads as flat paragraphs. ## How files are used We read the text out of each file, break it into chunks, and store them the same way we store website pages. The agent searches those chunks at answer time and pulls in what is relevant. A file counts toward your knowledge chunk limit like any other trained source. See [Limits](/docs/knowledge/limits). A PDF that is a scanned image with no selectable text has nothing for us to read, and the upload will tell you so. If you can select and copy the text in your PDF viewer, we can read it. If you cannot, run it through OCR first, export a text version, or paste the content as [text](/docs/knowledge/text). ## Updating a file To replace a file, upload the new version with the same source. It overwrites the old chunks rather than adding a second copy, so re-uploading a corrected document does not leave stale answers behind. --- # Knowledge limits URL: https://www.hey.support/docs/knowledge/limits How the knowledge budget works, what a chunk is, and what happens when you hit the cap. Each plan includes a knowledge budget per agent, measured in chunks. ## What a chunk is When we train on a website, file, or text source, we break it into small pieces of roughly 1,500 characters each. Each piece is a chunk. A short page might be one chunk; a long document might be dozens. The chunk count on each source in your Knowledge list tells you how much of your budget it uses. Quick answers and quick links do not count against the chunk budget. They are direct sources, stored separately. ## The limit per plan | Plan | Chunks per agent | | ---------- | ---------------- | | Free | 500 | | Starter | 2,500 | | Growth | 25,000 | | Scale | 50,000 | | Enterprise | Unlimited | The stat strip at the top of the Knowledge page shows your current usage against the limit. ## Hitting the cap If an ingest would push you over the limit, it is stopped before anything is written, and you see an upgrade prompt. A few things soften this: * **Re-saving a source is not blocked.** Replacing a file or text source swaps its chunks in place, so a re-ingest does not fail just because you were already near the cap. * **Scanning is always free.** A website scan never counts against your budget. Only the pages you confirm to index do, so you can scan widely and index selectively. If you are regularly near the cap, that is usually the signal to move up a plan. See [Plans](/docs/billing/plans). --- # Knowledge overview URL: https://www.hey.support/docs/knowledge/overview What the agent knows and how it uses it. The five source types and when to reach for each. Knowledge is the single most important part of a good agent. An agent with the right knowledge answers confidently and stays on topic. An agent missing a page guesses or says it does not know. You manage it all from **Knowledge** in the top navigation. Select **Add** to open the panel, then pick a source type. ## The five source types ## Trained versus direct The five types split into two groups, and the difference matters. **Website, Files, and Text are trained sources.** We break the content into small chunks and store them. When a visitor asks something, the agent searches those chunks and pulls the most relevant pieces into its answer. This is how it handles questions you never wrote out by hand. The tradeoff is that the agent paraphrases, so the exact wording of a reply can vary. **Quick answers and Quick links are direct sources.** They are handed to the agent as-is. A quick answer is used verbatim when a question matches it. A quick link is offered as a clickable link. Reach for these when the wording has to be exact, like a refund policy, a price, or opening hours. Train the agent on your site and key files so it can handle the long tail of questions. Then add a handful of quick answers for the facts you cannot afford to have paraphrased. ## Seeing what is indexed The Knowledge page lists every source with its type and a chunk count. The stat strip at the top shows how many sources and chunks you have against your plan's limit, plus an **Unanswered** tile — the questions visitors asked that the agent could not answer. That tile is the way into [Unanswered questions](/docs/knowledge/unanswered-questions), and it is the most useful number on the page. You can open any source to view the exact chunks it produced, or view the compiled document. ## Keeping it fresh Website sources can refresh themselves on a schedule so the agent stays current as your site changes. Files, text, and quick answers stay exactly as you left them until you edit them. See [Auto-update](/docs/knowledge/auto-update). --- # Quick answers and links URL: https://www.hey.support/docs/knowledge/quick-answers-and-links Exact responses and labelled links the agent uses word for word, without paraphrasing. Quick answers and quick links are direct sources. Unlike websites, files, and text, they are not searched and paraphrased. They are handed to the agent as-is. Use them when the wording has to be exact. ## Quick answers A quick answer is a question paired with the exact response you want. When a visitor asks something that matches, the agent uses your answer word for word. Open **Knowledge**, select **Add**, then **Quick answer**. Good candidates: * Prices and plan details * Opening hours * Return and refund policy * Shipping timelines * Anything you have been burned by an AI rephrasing Quick answers take priority over trained content for the questions they cover. If your site says one thing and a quick answer says another, the quick answer wins. ## Quick links A quick link is a label paired with a URL. The agent offers it as a clickable link when it fits the conversation, so visitors reach the right page instead of getting a wall of text. Open **Knowledge**, select **Add**, then **Quick link**. Examples: * "Book a demo" pointing at your scheduling page * "Track your order" pointing at your order status page * "Download the app" pointing at your app store listing Links must be `https`. The agent renders them as proper links, so a visitor can click straight through. ## Why they are separate from training Trained sources are great at breadth. They let the agent answer the questions you never wrote down. Direct sources are great at precision. They guarantee a specific answer or a specific link. Most agents use both: training for coverage, quick answers and links for the facts that have to be right. --- # Text URL: https://www.hey.support/docs/knowledge/text Paste notes, policies, or product details straight into the agent as a named source. Text is the quickest way to give the agent knowledge that is not on your site and not in a file. Paste it in, give it a name, and it becomes a searchable source. Open **Knowledge**, select **Add**, then **Text**. ## When to use it Reach for text when you have knowledge in your head or in a chat thread and no clean document to upload: * Talking points you use with customers * A policy you have not published yet * Product details, specs, or comparisons * Answers to questions your site does not cover ## How it works Give the source a **title** and paste your content. We break it into chunks and store it like any other trained source, so the agent can pull from it in answers. The title matters. It labels the source in your Knowledge list and it is how we match a re-save to the right source. If you save a new text source with the same title, it replaces the old one rather than creating a duplicate. Your original pasted text is kept, so when you open a text source to edit it, the full text loads back exactly as you wrote it. Each text source holds up to about 25,000 characters. Text sources are trained, not verbatim. The agent paraphrases them into its answers. If you need an exact response every time, use a [quick answer](/docs/knowledge/quick-answers-and-links) instead. --- # Unanswered questions URL: https://www.hey.support/docs/knowledge/unanswered-questions The queue of things visitors asked that your agent could not answer — and the fastest way to fix each one. Unanswered questions is the loop that makes an agent better over time. It collects the questions your agent could not answer from your knowledge, groups them, and gives you a one-click way to fix each one. Open **Knowledge**, then the **Unanswered** tile at the top of the page. ## What lands here A question arrives when the agent searched your knowledge and found nothing close enough to answer from. Plenty of things are deliberately filtered out, so the list stays worth reading: * Questions a **tool** answered — a product lookup, a booking. Your catalog and calendar are not supposed to be in the knowledge base. * Non-questions: greetings, "thanks", single words. * Replies sent because a Free workspace hit its conversation cap. * Anything with no visitor question before it. ## Questions, not messages The list groups by **question**, not by message. Twenty people asking "do you ship to Canada" in twenty different phrasings is one row with a count of twenty, not twenty rows. That matters for what the buttons mean: dismissing a question also suppresses the next person who asks the same thing, and resolving one stays checkable afterwards. ## Fixing one Open a row to get a side panel with the real conversations behind it. From there: * **Draft an answer.** We first check whether your knowledge actually does cover it — if so you are offered *Mark resolved* rather than a redundant answer. If not, we draft one from your closest content, leaving `[PLACEHOLDER]` wherever we would otherwise be inventing a fact. Edit it and save. * **Save as a quick answer.** The edited draft becomes a [quick answer](/docs/knowledge/quick-answers-and-links) and the row resolves itself, with an Undo. * **Add a source instead.** If the real fix is a page that was never indexed, add it in [Knowledge](/docs/knowledge/website). * **Dismiss.** For things you have no intention of answering. ## Reopening A resolved question **comes back**, flagged as reopened, if somebody asks it again after you resolved it. That is the signal your fix did not take — usually a quick answer that reads well but does not match how people actually phrase the question. Dismissed questions never come back on their own, but you can find them again under the Dismissed filter. ## Filters Filter by time window — 7, 30 or 90 days, or everything. Counts always cover the whole set rather than the filtered view, so switching filters does not change what you are being told about the size of the problem. --- # Website URL: https://www.hey.support/docs/knowledge/website Crawl a whole site, read a sitemap, or add a single page, then choose exactly what gets indexed. Most agents get the bulk of their knowledge from a website. Open **Knowledge**, select **Add**, then **Website**. ## Choose a scope Enter a URL and pick how much of the site the agent should learn from: * **Entire site.** Every page we can find, starting from your sitemap and falling back to following links. * **This section only.** Just the pages under the path you entered, so `yoursite.com/docs` reads your docs and nothing else. This option appears only when the URL has a path. * **Just this page.** One URL, indexed straight away with no scan step. You can also paste a `sitemap.xml` directly. We read the list of pages from it instead of following links. There is no page-count setting. You cannot know how many pages your site has before we look, so we look first. ## What happens next Scanning is free and never counts against your plan. What happens after depends on the size of your site. **Small sites just work.** If your site comfortably fits your plan, we read it, index it, and tell you what we found. There is nothing to confirm. **Large sites ask first.** If your site is bigger than one scan reads, or would not fit your plan, we stop and show you what we found before reading anything: * **The real number.** "We found 1,181 pages" — the true total, not a capped one. * **What that costs you.** We read a few pages first to measure how much content this particular site puts on a page, then tell you roughly how many pages your plan fits. * **A sensible starting selection.** Pages are ranked so the ones a visitor actually asks about — `/faqs`, `/about`, `/contact` — are picked before the thousandth product listing. Sitemaps often list those last. * **Your call.** Group by section, filter by path, and check or uncheck in bulk. Only the pages you keep are read. Nothing is added to your knowledge base until the pages have been read and you confirm what to index. ## Other options * **Exclude URLs.** Skip sections you do not want, like `/blog` or `/legal`. We suggest common ones to exclude. * **How long it takes.** Reading pages happens while the tab is open, so we tell you the rough time up front. If you leave, the scan pauses and picks up where it left off when you come back. ## When a page cannot be read Some pages cannot be indexed. The scan tells you why, per page, so you can decide what to do: | Reason | What it means | | ------------ | --------------------------------------------------------------------------- | | Not found | The page returned a 404. | | Timed out | The page took too long to respond. | | Rate limited | The site asked us to slow down. | | Unreachable | We could not connect, or a firewall blocked us. | | Not HTML | The URL is a file or feed, not a web page. | | No text | The page loaded but had no readable content (often a JavaScript-only page). | | HTTP error | The server returned an error status. | | Index failed | We read the page but could not process it. | If a page is blocked by a firewall or renders only with JavaScript, the scan cannot read it. Upload the content as a [file](/docs/knowledge/files) or paste it as [text](/docs/knowledge/text) instead. ## Resuming a scan A scan keeps running in the background. If you close the tab, it pauses, and the scan card picks up where it left off when you come back. Scans expire after 24 hours, and each agent runs one scan at a time. --- # Delivery and retries URL: https://www.hey.support/docs/webhooks/delivery How many times we try, what marks an endpoint unhealthy, and how to make your handler safe. ## What counts as success Return a **2xx** within **10 seconds**. Anything else — a 4xx, a 5xx, a timeout, a connection error — is a failure and gets retried. The 10-second timeout is the reason to acknowledge first and work afterwards: read the body, verify the signature, return `200`, then do the slow part on your own time. A handler that calls three other APIs before responding will eventually time out and be retried, which produces duplicates rather than reliability. ## Retries We attempt each delivery up to **four times**: the first immediately, then after **1s**, **5s** and **30s**. After the fourth failure that delivery is given up on. It stays visible in the delivery log so you can see what happened. ## Unhealthy endpoints Failures against the same endpoint accumulate. After **10 consecutive failures** we: 1. mark the endpoint **unhealthy**, 2. **disable** it, so we stop sending, and 3. email the workspace owner. A single success resets the counter. Test deliveries never count toward it, so you can debug freely. Re-enable an endpoint from **Settings → Developer** once the receiving end is fixed. ## Be idempotent Delivery is **at-least-once**. A retry after a timeout that actually succeeded on your side, or a resend, means the same event can arrive twice. Key your handler on `event_id`: ```js async function handle(event) { if (await seen(event.event_id)) return; // already processed await process(event); await remember(event.event_id); } ``` `event_id` is stable for one logical event across retries and across endpoints. `id` changes per delivery attempt, so it is the wrong key for deduplication — use it for tracing a single attempt in your logs. ## Ordering Events are **not** ordered. `message.sent` for a second message can arrive before the first, and `conversation.ended` can beat a `message.sent` that preceded it. Where order matters, use the timestamps inside `data` rather than arrival order. ## URL rules We re-validate the destination on **every** delivery, not only when you save it: * `https` is required in production. * Localhost, private ranges, link-local and cloud metadata addresses are rejected. An endpoint that starts resolving to a private address — for instance because a DNS record changed — stops receiving deliveries. To develop locally, use a tunnel that gives you a public `https` URL. --- # Overview URL: https://www.hey.support/docs/webhooks Signed HTTP callbacks the moment something happens, instead of polling the API. Webhooks push events to your own endpoint as they happen. Anything you would otherwise poll the [API](/docs/api) for — a new lead, a booking, a visitor asking for a human — arrives instead within a second or so. ## Set one up Go to **Settings → Developer** (owner only) and add an endpoint. You give us: * **A URL.** Must be `https` in production, and must not resolve to a private or link-local address — we check on every delivery, not just at creation. * **The events** you want. Subscribe to what you handle; unsubscribed events are never sent. * **A scope.** An endpoint is either workspace-wide or scoped to a single agent. You get back a **signing secret**, which is how you prove a delivery came from us. See [Verifying signatures](/docs/webhooks/signature). ## The envelope Every delivery is a JSON `POST` with the same outer shape. Only `data` varies by event. ```json { "id": "3f1c…", "event_id": "b47e…", "event": "lead.created", "api_version": "2026-04-27", "created_at": "2026-08-26T10:00:00.000Z", "workspace_id": 42, "chatbot_id": 17, "data": {} } ``` | Field | Meaning | | ------------- | ----------------------------------------------------------------------------------------- | | `id` | This delivery attempt. Stable across retries of the same attempt. | | `event_id` | The logical event. **Dedupe on this.** Shared across endpoints, different across resends. | | `event` | The event name, e.g. `lead.created`. | | `api_version` | Payload contract version. Currently `2026-04-27`. | | `chatbot_id` | Present when the event belongs to one agent. | | `data` | The event-specific body. | ## Headers | Header | Purpose | | -------------------------- | ------------------------------------------------- | | `X-HeySupport-Signature` | HMAC-SHA256 of the raw body, as `sha256=`. | | `X-HeySupport-Delivery-Id` | Matches `id`. Unique per delivery attempt. | | `X-HeySupport-Event-Id` | Matches `event_id`. Use it to dedupe. | | `X-HeySupport-Event` | The event name, so you can route without parsing. | ## Events Delivery is **at-least-once**. The same event can arrive more than once, so make your handler idempotent on `event_id`. See [Delivery and retries](/docs/webhooks/delivery). --- # Verifying signatures URL: https://www.hey.support/docs/webhooks/signature Check the HMAC before you trust a payload, and use the raw body when you do it. Your endpoint URL is public. Anyone who learns it can POST whatever they like to it, so **verify the signature before you act on a delivery**. ## How it works Each endpoint has a signing secret. We compute `HMAC-SHA256(raw_body, secret)` and send it as: ``` X-HeySupport-Signature: sha256= ``` You recompute it with your own copy of the secret and compare. If they differ, the request did not come from us. ## Node ```js import crypto from 'node:crypto'; export function verify(rawBody, signatureHeader, secret) { const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex'); const a = Buffer.from(signatureHeader ?? ''); const b = Buffer.from(expected); // Lengths must match before timingSafeEqual, which throws otherwise. return a.length === b.length && crypto.timingSafeEqual(a, b); } ``` ## Express ```js import express from 'express'; const app = express(); // express.raw, NOT express.json — see below. app.post( '/hey-support', express.raw({ type: 'application/json' }), (req, res) => { if (!verify(req.body, req.get('X-HeySupport-Signature'), process.env.HS_WEBHOOK_SECRET)) { return res.sendStatus(401); } const event = JSON.parse(req.body.toString('utf8')); // Acknowledge fast, work afterwards. res.sendStatus(200); void handle(event); }, ); ``` ## Next.js route handler ```ts export async function POST(req: Request) { const raw = await req.text(); if (!verify(raw, req.headers.get('x-heysupport-signature'), process.env.HS_WEBHOOK_SECRET!)) { return new Response('bad signature', { status: 401 }); } const event = JSON.parse(raw); return Response.json({ ok: true }); } ``` ## Use the raw body Sign against the **exact bytes we sent**, never a re-serialized object. `JSON.parse` followed by `JSON.stringify` can reorder keys, change number formatting and drop whitespace — all of which produce a different HMAC and a signature that never matches. This is by far the commonest reason a working secret appears to fail. Most frameworks parse JSON for you by default, which destroys the raw body before your handler sees it. Turn that off for the webhook route specifically, as above. ## Rotating the secret You can rotate a signing secret from the same settings page. There is a **24-hour overlap** during which we sign with both the new and the previous secret, so deliveries already in flight keep verifying while you deploy the new value. Verify against either during that window, then drop the old one. ## Compare in constant time Use `timingSafeEqual` or your language's equivalent rather than `===`. A plain string comparison returns early on the first differing byte, which leaks the correct signature a byte at a time to anyone willing to measure. --- # Identify the calling API key URL: https://www.hey.support/docs/api/account/get-current-key Returns metadata about the workspace and key behind the request. Use it to verify credentials and to discover your workspace id before calling other endpoints — it is the cheapest way to test that a key works, and integrations such as Zapier call it to label connections. ## Response `200` ### Errors * `401` — Missing or invalid API key * `429` — Rate limit exceeded Every error shares [one envelope](/docs/api/errors). ## Example ```bash curl https://www.hey.support/api/v1/me \ -H 'Authorization: Bearer hs_live_…' ``` --- # Last-30-days rollup URL: https://www.hey.support/docs/api/analytics/get-analytics-summary Returns aggregate counts for the trailing 30 days — conversations, messages, leads captured, and resolution rate — for the workspace, or for one chatbot when `chatbot_id` is supplied. ## Query parameters ## Response `200` ### Errors * `401` — Missing or invalid API key * `429` — Rate limit exceeded Every error shares [one envelope](/docs/api/errors). ## Example ```bash curl https://www.hey.support/api/v1/analytics/summary \ -H 'Authorization: Bearer hs_live_…' ``` --- # List bookings URL: https://www.hey.support/docs/api/bookings/list-bookings Returns meetings booked through the agent, paginated — both natively scheduled meetings on your connected Google Calendar and Cal.com bookings, each carrying its provider, start and end time, attendee timezone, and status. Read-only: bookings are created by visitors in the widget. ## Query parameters ## Response `200` Returns a `data` array with a `pagination` object. Each item: ### Errors * `401` — Missing or invalid API key * `429` — Rate limit exceeded Every error shares [one envelope](/docs/api/errors). ## Example ```bash curl https://www.hey.support/api/v1/bookings \ -H 'Authorization: Bearer hs_live_…' ``` --- # List chatbots URL: https://www.hey.support/docs/api/chatbots/list-chatbots Returns the workspace’s chatbots, newest first, with their sqid-encoded ids. Call this first to discover the `chatbot_id` that every other scoped endpoint expects. ## Query parameters ## Response `200` Returns a `data` array with a `pagination` object. Each item: ### Errors * `401` — Missing or invalid API key * `429` — Rate limit exceeded Every error shares [one envelope](/docs/api/errors). ## Example ```bash curl https://www.hey.support/api/v1/chatbots \ -H 'Authorization: Bearer hs_live_…' ``` --- # Add an internal note to a conversation URL: https://www.hey.support/docs/api/conversations/create-conversation-note Inserts a `note` message visible only in the operator dashboard. Notes are never shown to the visitor and are not sent to the AI. The role is always `note` — this endpoint cannot post a reply on the agent’s behalf. ## Path parameters ## Request body ## Response `200` ### Errors * `400` — Invalid request body * `401` — Missing or invalid API key * `404` — Not found * `429` — Rate limit exceeded Every error shares [one envelope](/docs/api/errors). ## Example ```bash curl -X POST \ https://www.hey.support/api/v1/conversations//messages \ -H 'Authorization: Bearer hs_live_…' \ -H 'Content-Type: application/json' \ -d '{"content":""}' ``` --- # Get a conversation with its messages URL: https://www.hey.support/docs/api/conversations/get-conversation Returns one conversation and its full message transcript, including visitor messages, AI replies, human agent replies, and internal notes. Responds 404 if the conversation belongs to another workspace, so ids cannot be enumerated. ## Path parameters ## Response `200` ### Errors * `401` — Missing or invalid API key * `404` — Not found * `429` — Rate limit exceeded Every error shares [one envelope](/docs/api/errors). ## Example ```bash curl https://www.hey.support/api/v1/conversations/ \ -H 'Authorization: Bearer hs_live_…' ``` --- # List conversations URL: https://www.hey.support/docs/api/conversations/list-conversations Returns a paginated list of chat conversations for the workspace, newest first. Filter by chatbot, lead status, resolved state, lifecycle status, language, or start date. Messages are not included — fetch a single conversation to read its transcript. ## Query parameters ## Response `200` Returns a `data` array with a `pagination` object. Each item: ### Errors * `401` — Missing or invalid API key * `429` — Rate limit exceeded Every error shares [one envelope](/docs/api/errors). ## Example ```bash curl https://www.hey.support/api/v1/conversations \ -H 'Authorization: Bearer hs_live_…' ``` --- # Update a conversation (tags, resolved state) URL: https://www.hey.support/docs/api/conversations/update-conversation Updates the operator-owned fields of a conversation. Tags REPLACE the existing array rather than merging, so send the full list you want. Does not emit a webhook — automation-driven edits deliberately do not echo back out. ## Path parameters ## Request body ## Response `200` ### Errors * `400` — Invalid request body * `401` — Missing or invalid API key * `404` — Not found * `429` — Rate limit exceeded Every error shares [one envelope](/docs/api/errors). ## Example ```bash curl -X PATCH \ https://www.hey.support/api/v1/conversations/ \ -H 'Authorization: Bearer hs_live_…' \ -H 'Content-Type: application/json' \ -d '{"tags":[],"is_resolved":true}' ``` --- # List knowledge sources for a chatbot URL: https://www.hey.support/docs/api/knowledge/list-knowledge-sources Returns what one chatbot has been trained on — crawled pages, uploaded files, text snippets, and Q&A pairs — with the number of indexed chunks each contributed. Requires the `chatbot_id` query parameter. ## Query parameters ## Response `200` Returns a `data` array with a `pagination` object. Each item: ### Errors * `400` — chatbot\_id is required * `401` — Missing or invalid API key * `404` — Chatbot not found * `429` — Rate limit exceeded Every error shares [one envelope](/docs/api/errors). ## Example ```bash curl https://www.hey.support/api/v1/knowledge/sources \ -H 'Authorization: Bearer hs_live_…' ``` --- # Create a lead URL: https://www.hey.support/docs/api/leads/create-lead Records a lead against a chatbot, optionally linked to a conversation, and emits the `lead.created` webhook. Deduplicated per conversation: when `conversation_id` is provided and a lead already exists for it, the existing lead is returned with `existing: true` rather than a duplicate being created. ## Request body ## Response `200` ### Errors * `400` — Invalid request body * `401` — Missing or invalid API key * `404` — Chatbot or conversation not found * `429` — Rate limit exceeded Every error shares [one envelope](/docs/api/errors). ## Example ```bash curl -X POST \ https://www.hey.support/api/v1/leads \ -H 'Authorization: Bearer hs_live_…' \ -H 'Content-Type: application/json' \ -d '{"chatbot_id":""}' ``` --- # Get a lead URL: https://www.hey.support/docs/api/leads/get-lead Returns one captured lead by its sqid-encoded id. Responds 404 rather than 403 when the lead belongs to another workspace, so ids cannot be enumerated. ## Path parameters ## Response `200` ### Errors * `401` — Missing or invalid API key * `404` — Not found * `429` — Rate limit exceeded Every error shares [one envelope](/docs/api/errors). ## Example ```bash curl https://www.hey.support/api/v1/leads/ \ -H 'Authorization: Bearer hs_live_…' ``` --- # List leads URL: https://www.hey.support/docs/api/leads/list-leads Returns contact details captured by the agent — from the lead form, a human handoff, or a booking — newest first. Filter by chatbot, status, or capture date. ## Query parameters ## Response `200` Returns a `data` array with a `pagination` object. Each item: ### Errors * `401` — Missing or invalid API key * `429` — Rate limit exceeded Every error shares [one envelope](/docs/api/errors). ## Example ```bash curl https://www.hey.support/api/v1/leads \ -H 'Authorization: Bearer hs_live_…' ``` --- # Action events URL: https://www.hey.support/docs/webhooks/events/action action.requires_approval — an AI Action is waiting for a person to approve it. ## `action.requires_approval` Fires when the agent wants to run an [AI Action](/docs/capabilities/ai-actions) that is marked **requires approval**. Nothing runs until someone approves it in the Inbox, and the visitor is told their request is being checked. ```json { "actionId": 91, "actionName": "issue_refund", "actionDescription": "Refund an order", "executionId": 4471, "conversationId": 8214, "chatbotId": 17, "inputArgs": { "order_id": "1042", "amount": 39.0 }, "requestedAt": "2026-08-26T10:12:00.000Z" } ``` This payload is **camelCase**, while every other event on this page is snake\_case. That is a real inconsistency in the current API version, not a typo in these docs — parse it as written. It will be aligned in a future `api_version`, and the version field on the envelope is how you will know. `inputArgs` is exactly what the model wants to call the action with. It is the useful part: it lets you show an approver the actual arguments — which order, which amount — rather than just the action's name. ## What to do with it The approval itself happens in the Inbox; this event exists so it does not have to be *noticed* there. Typical use is routing it somewhere a human already is: * post it to the channel that owns that decision, * page whoever is on shift when `actionName` is one of the expensive ones, * record every request for audit, approved or not. ## Approvals are not delivered There is deliberately no `action.approved` or `action.denied` event. The outcome is written to the action's execution log and, when it succeeds, shows up in the conversation itself. If you need the outcome, read it from the conversation — the approval decision is an operator action, and echoing it back as a webhook would let an integration mistake its own effect for a customer event. --- # Booking events URL: https://www.hey.support/docs/webhooks/events/booking booking.created, booking.rescheduled and booking.canceled. All three carry the same `booking` object. The two change events add one field describing what changed. ## The booking object ```json { "booking": { "id": "5e9c…", "chatbot_id": 17, "conversation_id": 8214, "name": "Ada Lovelace", "email": "ada@example.com", "event_label": "Intro call", "provider": "native", "external_uid": "abc123…", "start_at": "2026-09-02T14:00:00.000Z", "end_at": "2026-09-02T14:30:00.000Z", "attendee_timezone": "Europe/Dublin", "status": "confirmed", "created_at": "2026-08-26T10:05:00.000Z", "meet_url": "https://meet.google.com/…" } } ``` | Field | Notes | | --------------------- | ------------------------------------------------------------------------------------------- | | `provider` | `native` for our own scheduling on your Google Calendar, `calcom` for a Cal.com connection. | | `external_uid` | The Google event id, or the Cal.com booking uid. | | `start_at` / `end_at` | UTC. Use `attendee_timezone` to render the visitor's local time. | | `meet_url` | Present for native bookings with a Google Meet location; `null` otherwise. | | `status` | `confirmed` or `canceled`. | ## `booking.created` Fires when a meeting is booked, whether the visitor picked a slot from the booking card or asked the agent to book it in conversation. ## `booking.rescheduled` Adds the previous start so you can update an existing record rather than guess: ```json { "booking": { "…": "…" }, "previous_start_at": "2026-09-01T09:00:00.000Z" } ``` The `id` does not change on a reschedule — it is the same booking at a new time. ## `booking.canceled` Adds the reason, when one was given: ```json { "booking": { "…": "…" }, "cancel_reason": "Something came up" } ``` `cancel_reason` is `null` when the booking was cancelled without one. The booking object's `status` reads `canceled`. For native bookings we already email the visitor a confirmation, a reschedule notice, a cancellation and 24-hour and 1-hour reminders. You do not need a webhook to cover that — use these events for **your** systems, not for the visitor's messages. --- # Conversation events URL: https://www.hey.support/docs/webhooks/events/conversation conversation.started, message.sent and conversation.ended. ## `conversation.started` Fires once, when a visitor's first message creates a conversation. It does not fire when a visitor resumes an existing one. ```json { "conversation": { "id": 8214, "chatbot_id": 17, "visitor_id": "v_9f21…", "status": "ai", "created_at": "2026-08-26T10:00:00.000Z" } } ``` `status` is `ai` at this point by definition — a conversation cannot start already handed off. ## `message.sent` Fires for each message added to a conversation, from either side. ```json { "conversation_id": 8214, "chatbot_id": 17, "message": { "id": 55129, "role": "user", "content": "Do you ship to Ireland?", "created_at": "2026-08-26T10:00:01.000Z" } } ``` `role` is `user` for the visitor and `assistant` for the agent. Internal notes are **not** delivered — they are private to your team, so a note added in the Inbox never reaches your endpoint. This is the highest-volume event by a wide margin: a busy agent fires two per exchange. Subscribe to it only if you actually need message-level data — for "a conversation happened", `conversation.ended` is one event instead of dozens. ## `conversation.ended` Fires when a conversation is resolved, by the visitor or by an operator. ```json { "conversation": { "id": 8214, "chatbot_id": 17, "visitor_id": "v_9f21…", "previous_status": "ai", "message_count": 6, "is_lead": true } } ``` `previous_status` tells you what it was before resolution — `ai`, `human_active` or `pending_handoff` — which is how you distinguish a conversation the agent finished from one a person had to take. `is_lead` reflects whether contact details were captured at any point. --- # Handoff events URL: https://www.hey.support/docs/webhooks/events/handoff handoff.requested and handoff.resolved — a visitor wanted a person. ## `handoff.requested` Fires when a visitor asks for a human, whether they tapped the handoff card or the agent offered it after failing to answer. ```json { "conversation_id": 8214, "chatbot_id": 17, "channel": "live_chat", "visitor": { "visitor_id": "v_9f21…", "name": "Ada Lovelace", "email": "ada@example.com", "phone": null, "company": null, "message": "I need to change my order" }, "requested_at": "2026-08-26T10:07:00.000Z" } ``` **`channel` is the field that matters.** It is: * **`live_chat`** — someone is being paged and the visitor is waiting in the widget right now. This is urgent. * **`email`** — nobody is being paged. Either the workspace is outside its configured hours, or live chat is not on its plan. The visitor has been told a person will follow up, and is not sitting there waiting. Treating both the same is the mistake this field exists to prevent: routing an `email` handoff to a pager wakes someone for a message that expects a reply tomorrow, and treating a `live_chat` one as an email leaves a visitor waiting in an open widget. Every field under `visitor` can be `null` — which fields are collected is configured per agent. ## `handoff.resolved` Fires when a handed-off conversation is closed. ```json { "conversation_id": 8214, "chatbot_id": 17, "previous_status": "human_active", "resolved_at": "2026-08-26T10:31:00.000Z" } ``` `previous_status` distinguishes the two endings: * **`human_active`** — an operator joined and finished the conversation. * **`pending_handoff`** — it was resolved while still queued, so **nobody ever picked it up**. A rising count of `pending_handoff` resolutions is a staffing signal, not a success metric. `handoff.resolved` only fires for conversations that were actually in a handoff state. An ordinary conversation being resolved fires [`conversation.ended`](/docs/webhooks/events/conversation) alone. --- # Lead events URL: https://www.hey.support/docs/webhooks/events/lead lead.created — a visitor left contact details. ## `lead.created` Fires when contact details are captured, from any of the routes that can produce a lead: * the visitor submits the **lead form**, * they leave details as part of a **human handoff**, * the agent **auto-captures** an address the visitor typed in conversation, * a lead is created through the [API](/docs/api/leads/create-lead). ```json { "lead": { "id": 3312, "chatbot_id": 17, "conversation_id": 8214, "name": "Ada Lovelace", "email": "ada@example.com", "phone": null, "company": "Analytical Engines", "source": "widget", "status": "new", "created_at": "2026-08-26T10:02:00.000Z" } } ``` Every field except `id`, `chatbot_id`, `status` and `created_at` can be `null` — what you get depends on which fields the agent was configured to ask for, and what the visitor chose to give. ## Deduplication A conversation produces **at most one** lead. If details are captured again in the same conversation, the existing lead is updated rather than a second one created, and no second `lead.created` fires. Across conversations there is no dedupe: the same person returning next week produces a new lead with a new `conversation_id`. Match on `email` if you need to collapse those. ## Bookings do not double-fire When a visitor books a meeting, we create the lead silently and fire **`booking.created` only**. The booking is the event worth acting on, and firing both would make every meeting look like two things happening. If you want a record for every captured contact including bookings, subscribe to [`booking.created`](/docs/webhooks/events/booking) as well.