Routines
Chain requests into a sequence with variables, captured values, assertions, conditions, polling, per-step connections and dry runs.
A routine is a named list of requests that run in order — a reindex, an alias swap, a health check before a deploy. Each step can use values from earlier steps, check the response, wait for a task, and stop the routine if something is wrong.
Creating a routine
- On the Routines screen, click New, then add steps.
- From the Query workspace, select blocks and click Add to routine — choose a new or existing routine.
- From the Mappings editor, Create reindex routine builds a complete, ready-to-review routine (see Mappings).
In the routine header:
- Runs on — the default connection. Any step can override it.
- Variables —
name = valuechips. Click to edit,×to remove, + variable to add (typename=valueand press ↵).
Steps
Click a step to edit it:
| Field | What it does |
|---|---|
| Name | Shown in the list and the run log. |
| Id | Used to refer to this step’s captured values: {{steps.<id>.<name>}}. Generated from the name. |
| Connection | Routine default, or another connection — e.g. read from staging, write to production. |
| Request | An inline request (method, path, JSON body), a saved query, or a saved ∑ aggregation pipeline. Saved queries are linked: editing the query in the library changes the routine. |
| Capture | name = expression, one per line — save values from the response, e.g. value = count or task = task. |
| Assert | An expression that must be true, e.g. status != 'red' or count == steps.count_source.value. |
| On failure | Stop the routine or Continue. |
| Run only when | Skip the step unless an expression on steps and vars is true, e.g. steps.count.value > 0. |
| Repeat until | Poll: re-run every N seconds until an expression is true, giving up after a timeout. Default: completed == true, every 10 s, for 30 min. |
| Ask before running | Show a confirmation before this step. |
Use Move up, Move down and Remove step to rearrange.
Variables and templating
Paths and bodies can use:
{{name}}— a routine variable.{{steps.<id>.<name>}}— a value captured by an earlier step. Objects and arrays are inserted as JSON.
POST {{source}}/_count
GET _tasks/{{steps.reindex.task}}
A step that uses a value that doesn’t exist yet fails with Unknown variable.
Routines don’t use the workspace’s environments — set the values in the routine’s Variables.
Expressions
Capture, assert, run only when and repeat until use JSONata, evaluated on the response body. Inside an expression you can also use steps and vars (or $steps and $vars). Both = and == mean equals.
| Expression | Meaning |
|---|---|
count | the count field of the response |
hits.total.value | a nested field |
status != 'red' | the cluster isn’t red |
completed = true | a task has finished |
count = steps.count_source.value | matches a value captured earlier |
$count(hits.hits) > 0 | at least one hit |
JSONata runs in a sandbox — it can read the response but can’t touch your Mac.
Aggregation pipeline steps
When a step runs a saved aggregation pipeline, its flattened result rows are available as rows — one row per bucket combination, up to 1,000:
top_city = rows[0]."city.name"
top_avg = rows[0].avg_price
They’re also captured automatically as steps.<id>.rows.
Running
- ▶ Run all — run every step.
- Step through — pause before each step; click Run next step to continue.
- Stop — end the run and cancel the request in flight.
- Dry run (reads only) — tick it before running. Steps that would change anything are not sent; the log says would run PUT listings-v8 on Search · Production. Reads still run for real, with their captures and assertions, so you can see whether the routine would get stuck.
For each step, in order: the run only when condition is checked, variables are filled in, the request runs (and polls if it repeats), an HTTP error fails the step, then the assertion is checked and values are captured.
Production safety. On a production connection every write step asks for confirmation in the native dialog — whatever the step’s own settings. Declining stops the routine. Read-only connections block writes entirely.
Run log and history
The Run log shows every step with a timestamp and ✓, ✗, ▶, ◌ (dry run) or ↷ (skipped), and Captured values lists everything the run saved. Each step shows its status, the first captured value or its time. The last 20 runs of each routine are kept; pick one from the run menu to review it.
Example: reindex and swap an alias
| # | Step | Request | Checks |
|---|---|---|---|
| 1 | Cluster is healthy | GET _cluster/health | assert status != 'red' |
| 2 | Count source documents | POST {{source}}/_count | capture value = count |
| 3 | Create the new index | PUT {{target}} | |
| 4 | Reindex | POST _reindex?wait_for_completion=false | capture task = task |
| 5 | Wait for the task | GET _tasks/{{steps.reindex.task}} | repeat until completed = true |
| 6 | Counts match | POST {{target}}/_count | assert count = steps.count.value |
| 7 | Move the alias | POST _aliases | ask before running |
With variables source = listings-v7 and target = listings-v8. Run it as a dry run first.