Hand-off actions
A hand-off action is a route to a person or service that the AI assistant offers with an answer. Examples are a contact form, a phone number, or a live-chat window. You define actions per site. The assistant offers at most one with each reply.
Action types
| Type | The visitor sees |
|---|---|
link | A button that opens an https URL. |
phone | A button that dials the number. The number is shown as visible text next to the button. |
email | A button that opens a new email to the address. The address is shown as visible text next to the button. |
message | A block of text you wrote. There is no button. |
event | A button that fires a JavaScript event on your page. Your own code decides what happens. |
Quant Search does not integrate with any live-chat product. For live chat, use an event action and write the few lines of JavaScript that open your chat product.
Write the label as what the button does
The assistant refers to the button by its label, for example "Use the "Chat with an adviser" button below." Write a label that says what happens when the visitor presses it: "Chat with an adviser", "Call us", "Open the complaints form". Do not use a label such as "Click here" or "More". The assistant knows what each type of button does (a link opens a page, a phone button shows a number to call), but it does not know what your page does with an event. The label is the only description it has.
How the assistant decides
The assistant checks these in order and stops at the first action that applies.
- Phrases. If the visitor's question contains one of an action's
phrases, the assistant offers that action. Matching is by whole words, ignores case and punctuation, and is not a substring match: the phrase "rate" does not match "accurate". If several actions match, the one earlier in your list wins. A phrase overrides the assistant's own judgement. - Intent. If an action has an
intent(a plain-words description of when to offer it) and the assistant judges that the question fits, the assistant offers the action. An action with nointentis never chosen this way. The assistant is told to keep the intent private, but a visitor may be able to make it repeat the text. Write the intent as if visitors can see it: do not put internal information in it. - No answer. If the assistant has no answer, it offers the action marked
onNoAnswer. One action per site can have this flag.
Usually the assistant writes its answer as normal and adds the action. If the visitor only asks for a person (for example "I want to talk to a person"), the reply is a short sentence that points to the button, then the action'sresponse if you set one. When a phrase matched, the reply starts with a sentence such as "Use the "Open the form" button below to open the page." For an event action matched by a phrase, that sentence is the whole reply. For a message action, the reply introduces the message and the message follows. A disabled action is never offered.
The assistant offers no action in these cases:
- A crisis question (self-harm, family violence and similar). The answer shows the emergency-services line, as described in AI Answer Safety.
- A question that the answer-safety screen blocks, or a site whose plan allowance is used up.
- A reply where the answer-safety grounding check replaced the answer. Only the
onNoAnsweraction can appear. - Search groups. Groups do not offer actions. Only single sites do.
Phrases match only the words the visitor typed
Phrases are matched against the question after personal details are masked (seeAI Answer Safety). A masked detail, such as a phone number or an address, is removed before matching, so a phrase never matches it. A phrase such as "phone number" matches only when the visitor typed those words.
Business hours
Set hours to offer an action only when your team is available. The check runs on the server.
timezoneis an IANA name such asAustralia/Melbourne. Times inweekare 24-hour local times in that zone.- Each window includes
fromand excludesto. A weekday with no entry is closed all day. - A window whose
fromis later thanto(for example 22:00 to 06:00) crosses midnight. It belongs to the day it starts on. - A date in
closedDatesis a local date intimezone. It also closes the after-midnight part of a window that started on that date, because the window belongs to its start day. tois exclusive. Use"to": "24:00"for the end of the day: a window of 00:00 to 24:00 is open all day. 24:00 is accepted astoonly. A window of 00:00 to 23:59 leaves the last minute of the day closed.fromandtomust differ: a window with equal times is rejected on save. In the dashboard, a time field cannot show 24:00, so enter From 00:00 To 00:00 for all day. The dashboard saves it as 00:00 to 24:00.- When the action that would be offered is closed, the reply shows
outsideHoursResponseinstead of the action. This applies whether a phrase matched it, the assistant chose it, or it is the no-answer fallback. If you do not setoutsideHoursResponse, nothing is offered for that action while it is closed. - If a stored
hoursvalue is malformed, the action is treated as always open. The API rejects a malformed value on save, so this applies only to records edited outside the API.
The quantsearch:action event
When a visitor activates an event action, the widget dispatches a quantsearch:action event ondocument. The event bubbles and is cancelable.
e.detail.action; // the eventName, for example "live_chat"
e.detail.actionId; // for example "act_7f3k29xq1a"
e.detail.widget; // "chat" | "modal" | "search-page"
e.detail.siteId;
e.detail.question; // the masked question, or null (see below)
e.detail.data; // the action's eventData, or {}
- Call
e.preventDefault(). This tells the widget that your page handled the event. If no handler calls it, the widget opens the action'sfallbackUrlin a new tab. This covers a script that failed to load, was blocked, or is not deployed on that page. questionisnullunless the action setsincludeQuestionInEvent: true. When it is on,questionholds the question after your organisation's answer-safety guardrail masked personal details in it (see AI Answer Safety). Each masked detail appears as plain words, for example "an email address". It is not the text in the input box. If the guardrail did not run for that question, for example because the guardrail call failed,questionisnull. Write your handler so that it works without the question.- Treat
e.detailas untrusted input. Any script on the page can dispatch aquantsearch:actionevent with anydetail, and a handler cannot tell it from a real one. Checkactionagainst the event names you expect. Do not insertdetailvalues into the page as HTML. - The event carries only the current question. It never carries the conversation.
- A second activation of the same button within one second is ignored.
- The same event fires from the chat widget, the modal and the search page. Read
widgetif your handler must tell them apart.
Worked example: a live-chat product
The action below shows a button on weekdays between 09:00 and 17:00 Melbourne time. It sends the masked question and a queue name to your chat product. includeQuestionInEvent is on so that the adviser sees what the visitor asked.
{
"name": "Live chat",
"type": "event",
"label": "Chat with an adviser",
"response": "An adviser can help with this.",
"eventName": "live_chat",
"fallbackUrl": "https://agency.example.gov.au/contact",
"includeQuestionInEvent": true,
"eventData": { "queue": "rates" },
"intent": "The visitor wants to talk to a person about their rates notice",
"phrases": ["speak to someone", "talk to an adviser"],
"hours": {
"timezone": "Australia/Melbourne",
"week": {
"mon": [{ "from": "09:00", "to": "17:00" }],
"tue": [{ "from": "09:00", "to": "17:00" }]
},
"closedDates": ["2026-12-25"]
},
"outsideHoursResponse": "Our advisers are offline. Call 03 5555 0100 on a weekday."
}
Add the listener on every page that carries the widget.window.ExampleChat stands in for your own chat product's API.
document.addEventListener('quantsearch:action', (e) => {
if (e.detail.action !== 'live_chat') return;
// Tell the widget this page handled the event.
// Without this call the widget opens fallbackUrl in a new tab.
e.preventDefault();
window.ExampleChat.open({
queue: e.detail.data.queue,
firstMessage: e.detail.question, // masked text, or null; untrusted input
});
});
Save the action with PUT /api/sites/{siteId} in customActions. See theSites API for the limits on each field.
Common chat products
The listener below opens Intercom, Zendesk messaging or LiveChat, whichever is loaded on the page. If none is loaded, it does not call e.preventDefault(), so the widget opens fallbackUrl. Keep only the product you use. Vendors change their APIs: check each call against your vendor's current documentation.
document.addEventListener('quantsearch:action', (e) => {
if (e.detail.action !== 'live_chat') return;
const question = typeof e.detail.question === 'string' ? e.detail.question : '';
// Intercom: open the messenger with the question in the composer.
if (typeof window.Intercom === 'function') {
e.preventDefault();
window.Intercom('showNewMessage', question);
return;
}
// Zendesk messaging (Web Widget): open the messenger.
if (typeof window.zE === 'function') {
e.preventDefault();
window.zE('messenger', 'open');
return;
}
// LiveChat: open the chat window.
if (window.LiveChatWidget && typeof window.LiveChatWidget.call === 'function') {
e.preventDefault();
window.LiveChatWidget.call('maximize');
return;
}
// No chat product loaded on this page: do not call preventDefault,
// so the widget opens fallbackUrl.
});
- Intercom puts the question in the message composer. The visitor can edit it before they send it.
- Zendesk messaging and LiveChat open the chat window only. To give the adviser the question, use your vendor's own feature for conversation fields or visitor details, if your plan includes it.
- Put the vendor's own script on the page as the vendor tells you. Quant Search does not load it. The listener must run on every page that carries the widget.
Test your integration
Do these checks on a test page before you turn the action on for visitors.
- Ask a question that contains one of the action's phrases. The reply shows the button with your label.
- Press the button. Your chat product opens, and no new tab opens.
- If
includeQuestionInEventis on, ask a question that contains an email address. The adviser sees "an email address" in its place, not the address. - Remove the listener or block the chat product's script, then press the button again. The widget opens
fallbackUrlin a new tab. - Outside the action's
hours, ask the same question. The reply showsoutsideHoursResponseand no button. - Repeat the first two checks in each widget you use: the chat widget, the modal and the search page.
Behaviour to know about
- The chat widget restores earlier messages from the visitor's browser. A restored reply keeps its text, including the text of a
messageaction. It has no action button, link, phone number or email address, so a changed or disabled action never shows from an old reply. - The assistant offers at most one action per reply.
- Test the replies you depend on, on your site's answer-safety level.
Privacy
Quant Search puts the question in the event only when you turn on includeQuestionInEvent, and only when the answer-safety guardrail masked it. Quant Search does not send it to a third party and does not give your page the conversation. The chat widget keeps its history in the visitor's browser storage across page loads. On a shared device, the next person can see it. The stored history keeps the visitor's messages, the reply text and the reply's source links. It keeps no action control, no event and no question that an action carried.
The quantsearch:action event is a normal DOM event on document. Every script on your page can read it, including third-party scripts such as tag managers, analytics and session-replay tools. Do not put anything ineventData, or turn on includeQuestionInEvent, unless you accept that those scripts can read it. Any script on the page can also dispatch a fake event, so treat e.detail as untrusted input in your handler.
If your handler sends data to a chat vendor or any other service, that transfer is your disclosure to make. Update your privacy notice (APP 5). Assess the use and disclosure (APP 6). If the service is outside Australia, assess the cross-border disclosure (APP 8). Quant Search is not part of that data path.