Scheduled Jobs
Scheduled events run work on a timer without a session attached — invoke an agent, run a tool, or write to an AutessaDB table, once or on a recurring schedule. They are the right home for anything that must keep running after your terminal closes, which makes them the natural counterpart to building headless.
Key concepts
Two halves: when and what
Every scheduled event is a scheduleSpec (when it fires) plus an actionType and its one matching action config (what it does). Get either half's shape wrong and the create is rejected — these are the two things worth reading carefully before your first call.
autessa scheduled-events create \
--eventName "..." \
--scheduleSpec '{...}' \
--actionType INVOKE_TOOL \
--toolConfig '{...}'
Schedules are tagged objects
scheduleSpec sets a pattern plus the one nested object matching it. There are three:
| Pattern | Shape | Use |
|---|---|---|
CRON | {"pattern":"CRON","cron":{"expression":"0 9 * * ? *","timezone":"America/Los_Angeles"}} | A recurring wall-clock schedule |
EVERY | {"pattern":"EVERY","every":{"value":6,"unit":"HOURS"}} | A fixed interval — MINUTES, HOURS or DAYS |
ONCE | {"pattern":"ONCE","once":{"at":"2026-12-01T07:00:00","timezone":"America/Los_Angeles"}} | A single future run |
Three rules that cause most first-attempt failures:
cronis a nested object, not a bare string. Passing"cron":"0 9 * * ? *"fails.- The expression is a 6-field Quartz cron —
minute hour day-of-month month day-of-week year— with nocron(...)wrapper, and?in exactly one of day-of-month or day-of-week. ONCEtakes local wall-clock ISO-8601 with noZand no offset, and it must be in the future.
EVERY needs no timezone — it is interval-based. CRON and ONCE are evaluated in the IANA timezone you name, so always set one rather than relying on a default.Action configs nest their request
This is the second common trap. The agent or tool id does not go directly on the action config — it goes inside a nested request object:
// INVOKE_AGENT
{ "agentExecutionRequest": {
"agentId": "K2UYSwk3Yy4i",
"input": [{ "inputType": "TEXT", "content": "Summarize yesterday's tickets." }]
} }
// INVOKE_TOOL
{ "toolExecutionRequest": {
"toolId": "8rkuLgfJaGFuG",
"variables": { "window": "24h" }
} }
Both accept continueOnError (default false) and description as siblings of the nested request. Note that an agent's input is a list of multimodal-input parts — one TEXT element for a plain prompt, not a bare string.
How to schedule a tool
autessa scheduled-events create \
--eventName "docs_nightly_scratch" \
--description "Scratch event for CLI docs." \
--scheduleSpec '{"pattern":"CRON","cron":{"expression":"0 9 * * ? *","timezone":"America/Los_Angeles"}}' \
--actionType INVOKE_TOOL \
--toolConfig '{"toolExecutionRequest":{"toolId":"8rkuLgfJaGFuG","variables":{}}}'
{
"scheduledEvent": {
"eventId": "f2126a21-22ed-4ef6-98c7-215b3d46b099",
"eventName": "docs_nightly_scratch",
"resourceType": "TOOL",
"resourceId": "8rkuLgfJaGFuG",
"isRecurring": true,
"enabled": true,
"completed": false,
"cronExpression": "cron(0 9 * * ? *)",
"scheduleSpec": {
"pattern": "CRON",
"cron": { "expression": "0 9 * * ? *", "timezone": "America/Los_Angeles" }
},
"timezone": "America/Los_Angeles",
"nextExecutionAt": "2026-09-11T09:00:00",
"executionCount": 0,
"sharingLevel": "PRIVATE",
"userPermission": "ADMIN",
"actionType": "INVOKE_TOOL",
"toolConfig": {
"toolExecutionRequest": { "variables": {}, "toolId": "8rkuLgfJaGFuG" },
"continueOnError": false
}
},
"eventId": "f2126a21-22ed-4ef6-98c7-215b3d46b099",
"scheduleArn": "..."
}
nextExecutionAt is the field to sanity-check — if it is not when you expected, your cron expression or timezone is wrong, and it is much cheaper to catch that here than after a missed run.
How to schedule an agent
autessa scheduled-events create \
--eventName "Daily ticket digest" \
--description "Emails a digest of yesterday's tickets each morning." \
--scheduleSpec '{"pattern":"CRON","cron":{"expression":"0 16 * * ? *","timezone":"America/Los_Angeles"}}' \
--actionType INVOKE_AGENT \
--agentConfig '{
"agentExecutionRequest": {
"agentId": "bMR35XZD37Ol",
"input": [{"inputType":"TEXT","content":"Summarize the tickets filed today and email me the digest."}]
},
"continueOnError": false
}'
The agent runs its published version, exactly as a one-shot agents execute would — but with no session and no caller, so anything it needs must come from its instructions, its tools, or the prompt you set here.
How to schedule a database write
UPDATE_AUTESSADB performs a static write to one table when the event fires:
autessa scheduled-events create \
--eventName "Archive stale tickets" \
--scheduleSpec '{"pattern":"EVERY","every":{"value":1,"unit":"DAYS"}}' \
--actionType UPDATE_AUTESSADB \
--autessaDbConfig '{
"operation": "UPDATE",
"targetTableId": "ayXduiaLeFKh",
"values": {
"status": { "columnType": "SINGLE_SELECT", "textValue": "archived" }
},
"whereGroups": [
{ "logicalOperator": "AND",
"conditions": [{ "columnName": "status", "operator": "EQUALS", "value": "closed" }] }
],
"groupsLogicalOperator": "AND"
}'
operationis one ofINSERT,BULK_INSERT,UPDATE,UPSERT.valuesuses the same typed column values as every other AutessaDB write —columnTypeplus the one matching field (textValue,integerValue,floatValue,booleanValue,multiSelectValue,filePath, orvariableValue).- For
UPDATE, choose rows with eitherrecordId(a single row) orwhereGroups— they are mutually exclusive, andINSERTaccepts neither. skipIfTargetTableMissingturns a missing target table into a logged warning instead of an error.
How to list, inspect and change events
autessa scheduled-events all --output table
eventId eventName resourceType isRecurring enabled cronExpression nextExecutionAt executionCount actionType
------------------------------------ -------------------- ------------ ----------- ------- ------------------ ------------------- -------------- ------------
ee33c922-d174-47f0-93a9-ee23777423bd Daily message digest AGENT true true cron(0 16 * * ? *) 2026-09-10T16:00:00 4 INVOKE_AGENT
Results are grouped by owned, company-shared and shared-with-you. --full opts out of the trimmed listing summary.
autessa scheduled-events get --scheduledEventId <id>
autessa scheduled-events update --scheduledEventId <id> --scheduleSpec '{...}'
autessa scheduled-events delete --scheduledEventId <id>
update takes the same fields as create — send only what changes, but if you change actionType you must supply the matching action config alongside it.
Pausing instead of deleting
autessa scheduled-events toggle --scheduledEventId <id> --enabled false
{ "eventId": "f2126a21-22ed-4ef6-98c7-215b3d46b099", "enabled": false }
Reach for toggle while debugging. delete is permanent, and re-creating an event loses its execution history.
Sharing
autessa scheduled-events get-sharing-details --scheduledEventId <id>
autessa scheduled-events share --scheduledEventId <id> --level COMPANY
autessa scheduled-events share --scheduledEventId <id> --level SPECIFIC_MEMBER \
--usersToAdd '[{"userEmail":"teammate@example.com","accessLevel":"READ"}]'
Same sharing model as tools, agents and tables, though the flags differ slightly — this command takes --level plus per-user accessLevel inside usersToAdd, with no top-level --accessLevel. Ownership transfer is done in the web app.
How to read execution history
autessa scheduled-events history --scheduledEventId <id> --year 2026 --month 9
{
"executions": [
{
"id": "b45b2f61-853e-4ab6-b319-898f921e1577",
"scheduledEventId": "f2126a21-22ed-4ef6-98c7-215b3d46b099",
"eventName": "docs_nightly_scratch",
"resourceType": "TOOL",
"resourceId": "8rkuLgfJaGFuG",
"startedAt": "2026-09-10T09:56:26.005409",
"endedAt": "2026-09-10T09:56:28.810326",
"durationMs": 2804,
"status": "SUCCESS",
"scheduledFireTime": "2026-09-10T09:56:25.515",
"actualFireTime": "2026-09-10T09:56:26.005",
"attemptNumber": 1,
"payloadJson": "{\"metadata\":{...},\"payload\":{\"toolExecutionRequest\":{...}}}",
"responseJson": "{\"status\":\"success\",\"responseData\":{...}}"
}
],
"totalElements": 1
}
History is paginated by month and year, with a 0-based --page. The fields that matter when something went wrong:
scheduledFireTimevsactualFireTime— the gap is dispatch lag. A large one points at queue pressure, not at your action.attemptNumber— greater than 1 means the run was retried.payloadJson— exactly what was dispatched, so you can confirm the event carried the config you meant.responseJson— what the action returned, including the error on a failure.
Because the action itself also records a run, a scheduled tool invocation appears in autessa tools history list too — tagged source: "SCHEDULED", which is how you tell a timer-driven run from an interactive one. The same data backs the History page described in Scheduled jobs.
Why this matters for headless work
autessa login mints a tenant-scoped credential that expires in roughly eight hours, with no silent refresh. That makes the CLI a poor place to host recurring work — a cron job wrapping autessa will start failing the moment the session lapses.
Scheduled events sidestep that entirely: they run server-side with no session to expire. The durable pattern is to use the CLI to create the schedule and let the platform run it:
#!/usr/bin/env bash
set -euo pipefail
TOOL_ID=$(autessa tools create --toolName nightly_rollup --toolDescription "..." | jq -r '.tool.toolId')
autessa tools update --toolId "$TOOL_ID" --updatedTool '{...}'
autessa tools publish --toolId "$TOOL_ID"
EVENT_ID=$(autessa scheduled-events create \
--eventName "Nightly rollup" \
--scheduleSpec '{"pattern":"CRON","cron":{"expression":"0 2 * * ? *","timezone":"UTC"}}' \
--actionType INVOKE_TOOL \
--toolConfig "{\"toolExecutionRequest\":{\"toolId\":\"$TOOL_ID\"}}" \
| jq -r '.eventId')
echo "scheduled $EVENT_ID"
The script exits, your session eventually expires, and the job keeps running. Table triggers and inbound webhooks fill the same role for event-driven rather than time-driven work.
Full command reference
| Command | What it does |
|---|---|
| autessa scheduled-events all | List the scheduled events you can access, grouped by owned, company-shared, and shared-with-you. |
| autessa scheduled-events create | Create a scheduled event. |
| autessa scheduled-events delete | Delete a scheduled event. |
| autessa scheduled-events get | Fetch one scheduled event by id. |
| autessa scheduled-events get-sharing-details | Read who a scheduled event is shared with, the company-wide permission, and your own access level. |
| autessa scheduled-events history | List a scheduled event's execution history (each run's status, timing, and payload), paginated by month/year. |
| autessa scheduled-events share | Share a scheduled event with company members, or with the whole company. |
| autessa scheduled-events toggle | Enable or disable a scheduled event without deleting it. |
| autessa scheduled-events transfer-ownership | Web appScheduled-event ownership is transferred from the web app. |
| autessa scheduled-events update | Update a scheduled event's name, description, schedule, or action. |
Related
- Autessa CLI
- Tools and Agents
- AutessaDB
- Scheduled jobs in the builder
- Scheduled events API