Run an App on a schedule
Author an app, run it once by hand, then put it on a timetable with a trigger that fires it unattended at a fixed interval.
A scheduled app is a piece of work you have already taught Kortecx to do, set to happen on its own at an interval you choose. You write it once, watch it run once, and then hand it a timetable. After that it runs without you.
This page walks the whole lane end to end: author, run, schedule.
What you need first
An app you can run, and a model available to run its steps. On this service at least one step must use a tool: an app of model steps only, like the bare example below, is refused when it runs, so give a step a tool before you schedule it.
The three pieces
An app is a saved, reusable unit of work — a kortecx.app/v1 file holding a
workflow (the steps and how they connect), by-reference pointers to the context, tools
and connections it may use, and its steering settings. It carries no authority of its
own: every time it runs, the runtime re-resolves what it is allowed to do from your
grants.
A trigger binds an app to a way of starting it. A cron trigger carries a timetable;
a manual trigger fires only when you ask.
The timetable is kept by the runtime, not by you. It looks every 30 seconds for triggers whose scheduled moment has arrived, and fires them.
Author the workflow
A workflow is the shape of the work: the steps, and which step feeds which.
Fill in the project files
An app can also have a small project tree — the written material behind it: what it is for, how it should behave, what it must refuse.
For a scheduled app the structure is fixed. These five files are the skeleton:
prompts
rules
skills
README.md says what the app does. app.json describes it as data. prompts/system.md
is a system prompt for the app. rules/guardrails.md is the scope, safety and refusal
rules. skills/main.md is the primary instruction plus the tools it may use.
The project tree is source, not wiring
These files live in the app's branch, where you can read and edit them. Scaffolding a
rules/guardrails.md does not by itself change what a run does, and an app that points at
prompts, rules or context by reference is refused when it runs. See
Editing an app.
Run it once, by hand
Never schedule something you have not watched run.
Put it on a timetable
Now bind a cron trigger to the app. This is the end state:
In the console you describe the app in plain language, review the steps it proposes, edit them, and run it — authoring, editing and running are all first-class there. Once it is scheduled, every unattended run shows up in its history beside the ones you started by hand, with the same record of what each step did.
Binding the timetable itself is done from the command line or an SDK, using the tabs beside this one.
The app fires unattended as you, with the tools it names; an app that declares connections or a secret scope is refused, as a pressed run is.
Writing the schedule
The schedule field accepts one shape today, a whole number of seconds. A crontab expression
is refused with trigger_cron_expr_unsupported.
Some things worth knowing before you write one:
- At least 30 seconds, at most 30 days. A shorter or longer interval is rejected rather than rounded.
- UTC only. An interval is counted in UTC; there is no time-zone setting.
- Strictly forward. The next fire is always computed as strictly after now, so a job that is due at this exact instant schedules for its next occurrence, never the one happening now.
- Zero is not an interval. A schedule of 0 seconds is rejected.
- A typo fails immediately. A schedule that is not a whole number of seconds is rejected when you register the trigger — not silently turned into a trigger that never fires.
A duplicate tick fires once
Kortecx does not just call your app on a timer and hope. Each scheduled moment starts at most one run, so neither a slow start nor the following tick can pick the same moment up twice.
If the same scheduled moment somehow arrives twice, the second one is recognised as the same event and returns the run the first one already started. One scheduled moment, one run: done exactly once, and safe to re-run.
What this does not promise
The runtime looks for due triggers every 30 seconds, so a run starts close to its scheduled minute rather than exactly on it. And if a fire is refused, that is one missed run, and the missed occurrence is not made up later; after three refused fires in a row the trigger stops, with the reason, until you save it again. What a schedule promises is that a duplicate or raced tick does not double-fire. The runtime also has to be reachable at the scheduled moment: nothing fires an occurrence that passed while it was down.
A restart picks the schedule back up where it left off.
When a scheduled run goes wrong
Nobody is watching at 09:00. So the runtime keeps the record for you.
- Run history. Scheduled runs show in the app's history, beside the ones you started by hand.
- Failures. Each trigger keeps a log of its fires: the run each one started and how it ended, and why a refused one was refused.
- Spend. Each run's record carries its token counts, and a cost where a served rate prices its model — an estimate, not a bill.
- Everything else. To see what a scheduled run actually did, step by step, read Observability.
Notes and limits
- A trigger runs as you. The run binds to the identity of whoever registered it — never to something the client claims.
- A trigger carries no secret: attaching one to a trigger is not served. Secrets are referenced by name only — see Secrets.
- A cron trigger fires the app with an empty payload. If your app needs inputs, put them in the app itself rather than expecting them from the tick.
- For what a schedule does and does not guarantee once it is unattended, read What you can rely on.