| name | ds-int-tokens |
| description | Splunk Dashboard Studio token reference — how dashboards pass user-facing values into searches and visualization options. Covers $token$ syntax, $token.subfield$ for timerange tokens, $row.<field>.value$ inside drilldowns, $click.value$, token filters (|h, |u, |s for multiselect IN-clauses), and the most common "tokens don't resolve" debugging steps. Use when the user asks about tokens, $tok$, why a panel isn't updating, multiselect into IN(), token filters, or how inputs wire to data sources in Splunk Dashboard Studio. |
ds-int-tokens — token reference
Verified against Splunk Enterprise 10.2.1.
Live test bench: splunk-knowledge-testing/ds_interactivity_core_dark
§1 Token echo panel.
What a token is
A named value that lives on the dashboard. Inputs write tokens
when the user picks a value. Searches and viz options read tokens
via $token_name$ syntax. When a token's value changes, every search
and option that references it re-evaluates.
No declaration block. Tokens come into existence when an input
declares one in options.token, or when a drilldown writes one via
drilldown.setToken. There is no tokens: { ... } top-level key.
The 4 places tokens come from
- Inputs —
inputs.<id>.options.token: "name" declares a
writeable token.
- Drilldown setToken —
eventHandlers[].type: "drilldown.setToken"
captures click context (row.<field>.value, click.value,
click.value2) into a named token.
- URL parameters —
drilldown.linkToDashboard passes form.<name>
URL params that populate matching input tokens on load.
- Defaults —
defaults.tokens.default initialises tokens to
stable values before first interaction.
Reading a token
# In SPL (ds.search.options.query)
| stats count by host | search status=$status$ index=$selected_index$
"options": { "majorValue": "$selected_count$" }
Inside DOS strings, escape literal $:
"options": {
"majorValue": "> primary | seriesByName('count') | lastPoint() | prefix('\\$')"
}
Do / Don't
| ✅ Do | ❌ Don't |
|---|
Multiselect into SPL IN(): IN ($status|s$). Quotes each value. | IN ($status$) — joins with commas, no quotes; web-01,web-02 parses literally and chokes on the dash. |
Multiselect "All" sentinel: WHERE x IN ($tok|s$) OR ("$tok$" = "*"). | Skip the OR clause — selecting "*" produces invalid SPL. |
Timerange: $global_time.earliest$ / $global_time.latest$. | Bare $global_time$ — not useful, returns a non-string container. |
| URL drilldown: ` | ufilter mandatory insidecustomUrl`. |
| Markdown XSS-safe: ` | h` filter when interpolating user-controlled tokens. |
Initial state: seed tokens via defaults.tokens.default. | Read tokens before any input has written — you'll get blank or break visibility conditions. |
Drilldown token capture: drilldown.setToken to persist row.* / click.* after the click. | Try to read $row.<field>.value$ outside an event handler — scoped to the click only. |
| Token names: match exactly across reads + writes. | $selected_index$ vs $select_index$ — typos = silent no-update. |
Reserved namespaces: avoid form.*, row.*, click.*, <token>.earliest / .latest for your own tokens. | Reuse reserved names — they collide with framework. |
Token filters
Append |<filter> to transform value at substitution time:
| Filter | What it does | Use case |
|---|
|s | Quote each value (string-quote) | Multiselect → SPL IN() |
|h | HTML escape | Inside splunk.markdown (XSS-safe) |
|u | URL encode | drilldown.customUrl, any URL interpolation |
Default (no filter) emits raw value: a string for single tokens; a
comma-separated joined list for multiselect arrays (no quoting).
Subfield accessors (timerange only)
| Token | Value |
|---|
$global_time.earliest$ | Earliest expression (e.g. -24h@h). |
$global_time.latest$ | Latest expression (e.g. now). |
Wired into searches via the defaults block — see ds-int-defaults.
Drilldown context tokens (event-scoped)
| Token | Meaning |
|---|
$row.<field>.value$ | Value of <field> in clicked row (table/event panels). |
$click.value$ | Category / x-axis value the user clicked (charts). |
$click.value2$ | Series / second axis value (scatter, bubble, sankey). |
$click.name$ / $click.name2$ | Field names where applicable. |
These do not persist after the click. Use drilldown.setToken to
copy them into a named token. See ds-int-drilldowns.
"Panel not updating" — debug ladder
In order from most-likely to least-likely:
- Token name typo. Cmd-F across the JSON; must appear exactly
the same wherever read or written.
- Input never wrote the token. Verify
inputs.<id>.options.token matches what searches read.
- Input is not on the layout. Declared but not listed in
layout.globalInputs or tabs.layoutDefinitions[].inputs →
doesn't render → can't be changed → token stays at defaultValue.
- Search does not actually reference the token. Hardcoded value
may be overriding where you think the token goes.
enableSmartSources is off. Required for DOS-typed dynamic
dropdown items to refresh on upstream changes.
- Scope problem with timerange. Use
$token.earliest$ /
$token.latest$, never bare $token$.
The §1 Token echo panel in the live bench is purpose-built for step 4
— if the value shows up there, the token is resolving. If not, the
wiring is broken upstream.
Quick recipes
Echo every token to a single panel (debug)
"ds_token_demo": {
"type": "ds.search",
"options": {
"query": "| makeresults | eval msg=\"index=$selected_index$ status=$status$ filter=$search_text$ host=$host_filter$ time=$global_time.earliest$..$global_time.latest$\" | table msg"
}
},
"viz_token_echo": {
"type": "splunk.markdown",
"options": {
"markdown": "**Resolved**: `index=$selected_index$ status=$status$ time=$global_time.earliest$..$global_time.latest$`"
}
}
Markdown form is preferred — supports token interpolation natively
without an SPL round-trip.
Multiselect inside a search
| stats count by host | where status IN ($status|s$) OR ("$status$" = "*")
status declared as input.multiselect with defaultValue: ["200","201"].
Pass tokens to another dashboard
{
"type": "drilldown.linkToDashboard",
"options": {
"app": "search",
"dashboard": "host_detail_view",
"tokens": [
{ "token": "host", "value": "row.host.value" },
{ "token": "earliest", "value": "global_time.earliest" }
]
}
}
tokens is an array of {token, value} objects, NOT a map.
Receiving dashboard must declare inputs with matching token names.
See also
ds-int-inputs — declaring widgets that write tokens.
ds-int-defaults — wiring tokens (especially global_time) into every
ds.search.
ds-int-drilldowns — click-time tokens (row.*, click.*) +
setToken action.
ds-int-visibility — using token state to show/hide panels.
ds-ref-syntax — JSON envelope.