Create Monitor
Action type: actions/monitors/create.
Use this action when an agent (or workflow) needs to be woken up later — when a document changes, at a point in time, or when something outside AutoTalk reaches a state you care about.
A monitor is a registered watch plus a reminder note. The step returns immediately with a monitorId; when a check matches, AutoTalk posts a monitor event to the conversation and the agent can continue through the normal message pipeline. Its history is bounded by the context budget and may be trimmed. The event replays your note as a reminder for the next run.
Best for
- Delivering the result of a long job (a transcription, a transcode) into the same conversation when it finishes — without polling
- "Remind me in 30 minutes" style self-wakes
- Watching something outside AutoTalk — a ticket status, a price, an external job — by re-running one of the agent's own read-only tools on a schedule
The three watch types
| Watch type | Watches | Wake latency | Needs |
|---|---|---|---|
dynadata_doc | One of your company's documents (e.g. a transcription_jobs row, or a ct: custom type document) until a CEL condition over it holds | Expedited checks after transcription/transcode completion; periodic sweeps for other changes. Checks may queue, fail or retry; latency is not guaranteed | itemType + itemId + condition |
time | The clock | The next sweeper minute after fireAt | fireAt or delayMinutes |
agent_tool | The result of one of the agent's own tools, re-run on a schedule | The first poll whose condition holds — polls run at intervalMinutes (minimum 5) | toolName + condition (+ toolArgs, intervalMinutes) |
Use document watches for data AutoTalk owns. A transcription job, transcode job or company document can use dynadata_doc; completion can request an expedited check. agent_tool polls on a schedule and is intended for external data read through an agent tool. Keep credentials in the tool's step configuration, not the prompt. All checks can queue, fail or retry.
Main fields
| Field | What it does |
|---|---|
| watchType | CEL resolving to dynadata_doc, time, or agent_tool |
| itemType / itemId | dynadata_doc only: the watched document's type and _id (e.g. workflow.step(0).jobId). Only tenant-readable published types and ct: custom types can be watched |
| condition | A native CEL descriptor {expr: "..."} (not evaluated at create time — only parse-checked) the sweeper evaluates later. For dynadata_doc it runs over doc (the watched document); for agent_tool see the arena below |
| fireAt / delayMinutes | time only: when to fire — an ISO datetime, or minutes from now |
| agentId / toolName / toolArgs | agent_tool only: which tool to re-run. agentId defaults to the agent running the step; toolName must be unique on that agent (a duplicate name is refused rather than guessed); toolArgs is an object of scalar arguments checked against the tool's declared parameters at create time |
| intervalMinutes | agent_tool only: how often to poll. Clamped to 5–1440 and jittered — never faster than 5 minutes |
| note | Your reminder, replayed verbatim in the wake. Write what the agent should do when the watch fires |
| conversationId | Which conversation to wake. Defaults to the conversation the run is in — a workflow run has no conversation, so workflow steps must set it |
| ttlMinutes | How long the watch stays armed. Default 1440 (24 h), maximum 10080 (7 days). Past it the monitor expires without firing |
What later steps can use
workflow.step(N).monitorId— the armed monitor's id (poll it via the read-onlymonitorsdata type)workflow.step(N).monitorState—armedat create timeworkflow.step(N).expiresAtIso— when the watch dies unfired
Writing the condition
A missing field is an evaluation error. An unguarded condition such as doc.outputs.txt != '' fails while outputs or txt is absent and counts toward the evaluation-failure limit. Three consecutive failures stop the monitor with error and notify your team. To keep waiting for optional data, use a presence guard such as has(doc.status) && doc.status == 'ready', or read a safe default: maps.get(doc, 'outputs.txt', '') != ''. A condition that successfully evaluates to false keeps the monitor armed.
For dynadata_doc, the condition sees doc — the watched document.
For agent_tool, the condition sees the tool's own declared output:
| Variable | What it is |
|---|---|
output | The tool's rendered output.main result |
outputText | The same, always as a string |
data | The tool output parsed as JSON, when it is a JSON object or array — otherwise null. Parsed from the full output before the display truncation, so data stays usable even when outputText is cut |
steps | Per-step {ok, status, error} — ok is true for a completed step whose HTTP status, if it has one, is 2xx |
now | The evaluation time |
Example: data.atingiu == true, or steps[0].status == 200. Per-step payloads are deliberately not exposed — the condition sees only what the tool's own output.main projects, and the watched tool must declare an output.main (a tool without one is refused: its condition could never become true).
The condition descriptor is stored without evaluating it at creation; its runtime arena includes declared bindings. Put the moving part in toolArgs instead and have the tool compute the verdict — for example a limite parameter the tool compares against, so the condition is just data.atingiu == true.
What a watched tool may do
An agent_tool watch re-runs the tool headless — no model, no conversation, unattended, for up to seven days. So the tool may only read:
- Every step must be a read-only action (HTTP request, fetch/search/count company data, resolve variables). Anything that writes data, sends messages, spends money, or mints credentials is refused — at create time and re-checked on every poll.
- At most 5 steps, and the whole tool must finish within 25 seconds per poll — a tool that is fine as an LLM tool (an HTTP step alone allows 120 s) can exceed that as a watch; three consecutive overruns end the watch.
- A step that answers with an HTTP 4xx/5xx counts as completed data (
steps[i].okfalse,statusset) and the watch keeps polling — so a condition can watch for recovery. A poll counts toward the error strikes only when a step cannot run at all (DNS failure, connection refused, timeout) and no step in the chain completed — one completed step means the poll parks as not-met instead. To detect a persistently failing later step, putsteps[i].okinto your condition.
Editing the watched tool ends the watch
The watch records a fingerprint of the tool's executable surface as it was when armed — its name, parameters, steps, and output expression. If any of those change, or the tool is removed or duplicated by name, the monitor stops immediately with a notification to your team — it does not silently keep running an older version, and it does not guess between two tools with the same name. Cosmetic edits (the description, hiding the tool) do not end the watch. Re-arm after finishing behavioral edits.
Limits
- 10 armed monitors per conversation, 50 per account, and 10 armed
agent_toolwatches per account (each one is a recurring poll). A monitor you no longer need can be canceled with Cancel Monitor — canceling frees its armed slot immediately - 20 fires per conversation per day — every fire is a billable agent run; a monitor that hits the cap takes the error path rather than resuming the next day
- A run that was itself woken by a monitor may arm one more monitor (depth 1); chaining further is refused, so watch → wake → watch → wake loops cannot run away
- Three consecutive evaluation failures flip the monitor to
errorand notify your team
Tips
- End the run normally after arming — send the user an interim reply ("I'll get back to you when it's ready"). The wake continues the conversation later with history retained within its context budget; the monitor is how you stop polling, not another thing to wait on.
- The wake arrives as a monitor event message carrying your note and a snapshot of what matched. Add a system prompt telling the agent how to treat these events — see Async wakes.
- Read the create result via
workflow.step(N).monitorId, notworkflow.step(N).status—statusis reserved for HTTP status codes.