Tell the assistant which role a page is about
An assistant that knows which role the visitor is looking at can answer "is this remote?" without asking them which job they mean. Declaring the role is one attribute, and it is the most useful thing you can add after the snippet itself.
Declare the role
Put the role's ATS id on any element. It applies to that element and everything inside it:
<body data-voyse-ats-id="4821">
On a job detail page, <body> is the right place — every trigger on the page
then inherits it, including the launcher. Voyse careers sites do this
automatically; on your own site it is yours to set.
On a listing or search-results page, mark up each card instead, and any trigger inside a card inherits that card's role:
<article data-voyse-ats-id="4821">
<h3>Senior Platform Engineer</h3>
<button type="button" data-voyse-open>Ask about this role</button>
</article>
A trigger can also name a role itself, as the value of data-voyse-open:
<button type="button" data-voyse-open="4821">Ask about this role</button>
The id is the one your ATS uses for the job — the same value Voyse imported the role under. It is read as an opaque string: trimmed, capped at 100 characters, and rejected if it contains control characters.
How the role is resolved
For any interaction, the first of these that produces an id wins:
- An id on the trigger —
data-voyse-open="…", oratsIdpassed tovoyse.open(). - The nearest
[data-voyse-ats-id]ancestor of the trigger. data-voyse-ats-idon<body>or<html>.- The URL, matched against the job URL pattern in the assistant's
settings — the pattern contains
{atsId}once, and the embed builds a regular expression from it against the full page URL.
Prefer the attribute. URL inference exists for hosts that cannot add markup, and it is the less reliable of the two: careers URLs often carry a job-post id rather than the ATS job id the assistant looks roles up by, in which case the pattern matches and yields the wrong role.
An explicit id always beats inference, which is what lets a search-results page open a specific role even though the page's own URL matches no pattern.
Add a line of page context
data-voyse-ask-context gives the assistant a sentence about where the question
came from. Like the role, the nearest declaring ancestor wins:
<section data-voyse-ask-context="Benefits page, parental leave section">
<button type="button" data-voyse-open data-voyse-ask-text="How long is parental leave?">
Ask about parental leave
</button>
</section>
It is a hint, not content. The embed collapses it to a single line, strips control characters, and caps it at 500 characters; the question itself can be much longer. Use it where the same question means different things in different places — "how does this work?" on a benefits page versus a relocation page.
Treat it as visitor-supplied text, because from the assistant's side that is exactly what it is: it is carried as untrusted context for that turn, not as instruction.
What the assistant does with it
The declared id is sent to the assistant — by message into the desktop panel, or
as ?atsId= on the mobile tab — and the assistant looks the role up. If it
finds it, that role becomes the frame for the conversation: answers are given
about that job, and the composer's placeholder changes to Ask about this
role.... If the lookup finds nothing, the conversation falls back to the
assistant's general context rather than failing.
So a wrong id is not an error you will see. It is a conversation that quietly answers about the wrong job, or about nothing in particular — which is why the value being the ATS job id matters.
Check it worked
Open the assistant from a page that declares a role. The composer should read Ask about this role... rather than the general placeholder. If it does not:
- Confirm the attribute is on an ancestor of the trigger, not a sibling.
- Confirm the value is the ATS job id, not a slug or a post id.
- Check the
jobUrlPatternfield in the configuration response — if a pattern is set and matches your URL, it may be supplying an id you did not expect. The attribute wins wherever it is present, so declaring it is the fix.