Skip to content
Wetel
Go back

An AI employee that starts on its own: scheduled work, and what stops it running away

Every team has one: the colleague who sends the Monday report before anyone asks. Nobody messages them on Monday morning. They just know it is due, pull the numbers, and post it where people will see it.

What makes that colleague safe to rely on is not only that they remember. It is that they work inside limits. They have a company card with a ceiling on it. If the reporting system is down, they try a couple of times and then tell their manager, instead of retrying every five minutes all week. And their manager can see what they sent, and can tell them to stop.

An AI employee on Wetel can do the same kind of unprompted work through a scheduled workflow. This post is for the operations lead deciding what to hand over and the developer setting it up: what a schedule is, the three controls that stop it running away, and the one gap you must cover yourself today.

What is a schedule?

A schedule runs one AI employee’s published workflow on a timer, with no message from anyone. “Every weekday at 9am”, “every 15 minutes”, “the first of every month”: at each of those times the platform starts a run of that agent’s workflow, the same way an on-demand task run (runWorkflowTask) does.

A few facts set the boundaries:

What does a scheduled run look like?

It is a run with nobody on the other end, so it behaves differently from a chat. Plan the workflow around three properties.

There is no user message. The run starts with an empty message and no conversation history. Anything the workflow needs comes from the schedule’s own variables (a flat map of simple values you set once) or from steps that fetch it, such as an action or tool node calling your own systems.

Nobody is waiting for a reply. A response node’s text lands in the session’s transcript, but no chat window is listening. If the run should deliver something (post a digest, update a record, notify someone), the workflow has to send it outward itself, usually with a final webhook node or an action node.

Every fire is asynchronous. Creating or updating a schedule tells you nothing about whether any run succeeded. You read outcomes afterwards (more on that below).

flowchart LR
C["Clock reaches the cron time"] --> Q{"Spend cap reached?<br/>Agent active and published?"}
Q -- no --> F["Fire counts as failed<br/>(no run starts)"]
Q -- yes --> R["Run the agent's published workflow<br/>(no user message)"]
R --> A["action / webhook node<br/>sends the result outward"]
R --> S["Schedule row updated:<br/>lastRunAt, lastRunStatus"]
F --> S

An example: the weekday ops digest

This is the example from the reference, unchanged: a digest every weekday at 09:00 Kuala Lumpur time.

mutation CreateSchedule($input: CreateScheduledWorkflowInput!) {
createScheduledWorkflow(input: $input) {
id
name
status
cronExpression
timezone
nextRunAt
externalConversationIdTemplate
maxConsecutiveFailures
}
}
{
"input": {
"name": "Weekday morning ops digest",
"agentId": 12,
"cronExpression": "0 9 * * 1-5",
"timezone": "Asia/Kuala_Lumpur",
"variables": {
"reportType": "daily_ops",
"lookbackHours": 24
},
"externalConversationIdTemplate": "digest:{{date}}",
"maxConsecutiveFailures": 3
}
}

Reading it line by line:

The cron expression is checked strictly when you save, so a mistake fails at once rather than at 9am. It must have exactly five fields: the six-field form with seconds is refused, so the shortest interval is one minute. Shortcuts like @daily are refused too; write 0 0 * * * instead.

The three controls that stop it running away

A schedule has no person in the loop at the moment it fires, which makes it the easiest way to spend money by accident. Three controls apply to every schedule.

1. Plan quota: how many schedules you can hold

Your plan tier sets how many schedules your workspace may have. On the documented tiers that is 1 on DEV and 25 on PRO. Paused and auto-disabled schedules still count; only deleting a schedule frees its slot. Going over the limit is refused with a message that names your limit.

2. Monthly spend cap: checked before every fire

Every fire checks your workspace’s monthly language-model spend cap before it starts anything (the documented caps are $5 on DEV and $200 on PRO). If the cap is reached, the fire does not run, and it counts as a failed run for the next control. That is the company card with a ceiling.

3. Consecutive-failure auto-disable: stop after repeated failures

When a schedule fails maxConsecutiveFailures times in a row, it switches itself off: its status becomes AUTO_DISABLED, its next run time is cleared and it stops firing. The default is 3, and you can set anything from 1 to 20. Any successful run resets the count to zero, so one bad morning does not trip it; only a run of failures does.

What counts as a failure:

Runs that end COMPLETED, AWAITING_INPUT or INTERRUPTED count as successes.

The gap you must cover: an auto-disabled schedule tells nobody

When a schedule switches itself off, no notification is sent today: no email and no webhook. It simply stops. The only trace is on the schedule itself: status: AUTO_DISABLED, the consecutiveFailureCount, and lastRunStatus: "failed". The dashboard’s Schedules page highlights it, but only while someone has that page open.

So the colleague who stopped after three failed attempts does stop, but does not yet walk over to tell the manager. Until that alerting exists, check for it yourself. Two ways:

Poll the schedule list. This query is cheap, and you can run it on a timer from your own tooling and raise your own alert when any schedule reads AUTO_DISABLED:

query ScheduleHealth {
scheduledWorkflows(first: 100) {
totalCount
edges {
node {
id
name
status
lastRunAt
lastRunStatus
consecutiveFailureCount
nextRunAt
}
}
pageInfo {
endCursor
hasNextPage
}
}
}

Read the per-agent roll-up. agentActivitySummary includes schedule health (a schedulesAutoDisabled count), and its needsAttention flag turns true for an agent with a schedule that was switched off after repeated failures.

When you find one, fix the cause first, then call resumeScheduledWorkflow. Resuming resets the failure count and starts the timer again. If you resume without fixing anything, it will fail the same number of times and switch itself off again. Look at lastRunStatus, the failing session’s runs, and whether the workspace has hit its spend cap.

How to see what a scheduled run actually did

The schedule row gives you the headline:

For the step-by-step detail, find the fire’s session and read its runs. With the default template, every session for schedule 7 has an id starting scheduled:7:, so you can find them through sessions(agentId:) and then ask for the runs:

query ScheduleRuns($sessionId: Int!) {
workflowRuns(sessionId: $sessionId) {
id
status
errorMessage
nodeTrace
context
}
}

nodeTrace lists every step the run visited, in order, which is how you check “the report went out” against evidence rather than assumption. One catch: a fire that never started (spend cap reached, agent inactive, nothing published) has no run to read. For those, the schedule’s own lastRunStatus and failure count are the only record.

Before you switch one on

A short checklist, all from the reference:

  1. Publish the agent’s workflow first. Creating a schedule only checks that the agent exists in your workspace, not that it is active or has a published workflow. A schedule pointing at an unpublished agent is accepted, then fails every fire until the breaker trips.
  2. Make sure the workflow sends its result somewhere. A webhook or action node at the end, not only a response node.
  3. Gate any id before an outbound write. If a variable feeds a write to another system, put a condition node in front and test someId > 0, never someId != 0.
  4. Pick a failure limit you can live with. Three is the default. Lower means it stops sooner; higher means more failed attempts, each of which may cost money, before it does.
  5. Decide who checks on it, and how often, since nothing will tell them.

What is live today, and what is not built yet

Live today:

Not built yet:

A scheduled AI employee gets the colleague’s limits today. What is still missing is the colleague telling their manager when they had to stop, so for now a person on your team checks.

To set up your first one, start with the scheduled workflows reference.


Share this post:

Next Post
Hiring a ready-made role instead of building an AI employee from scratch
Previous Post
Reverse engineering is now a commodity: what REA means for platforms like Wetel