Triggers
Executions can be started directly through the client, CLI, or API, or automatically through Triggers.
A Trigger is a project deployment resource. It is not part of the TCC Program artifact and it does not create a different kind of Execution. client.start and POST /v1/executions stay as they are.
Ways to start an Execution
Section titled “Ways to start an Execution”| Mechanism | What it does |
|---|---|
| Direct start | Starts an Execution explicitly |
| Webhook trigger | Starts a new Execution from HTTP |
| Cron trigger | Starts a new Execution on a schedule |
| Event | Resumes an existing waiting Execution |
Timer / sleep | Resumes an existing Execution later |
A cron trigger is not sleep. A webhook trigger is not event delivery. See Events and Timers.
Direct start
Section titled “Direct start”const execution = await client.start("research-agent", { topic: "durable execution",});This requires no trigger. The JSON object is the Program input. The CLI equivalent for Cloud is trigora start <program> --remote.
Webhook triggers
Section titled “Webhook triggers”[[triggers]]name = "github"type = "webhook"program = "github-handler"Deploy assigns a URL:
https://hooks.trigora.dev/t_...There is no path and no alias. t_… is the public id. It is not written into trigora.toml. A webhook trigger has no input field. The JSON body is the program input.
POST /t_...Content-Type: application/json
{ "action": "opened" }That JSON is the Program input. The platform does not wait for the Program result.
| Response | When |
|---|---|
202 { "executionId" } | The body is valid JSON |
400 | The body is not JSON, or it is larger than 1 MiB |
405 | The method is not POST |
404 | The public id is unknown |
The request body is not logged.
Cron triggers
Section titled “Cron triggers”[[triggers]]name = "nightly-report"type = "cron"program = "report"schedule = "0 2 * * *"timezone = "UTC"
[triggers.input]period = "daily"schedule is a 5-field cron expression. timezone defaults to UTC when you omit it. [triggers.input] is optional static JSON. Nested tables and arrays are allowed. TOML datetimes are not.
Each tick starts a new Execution. Overlap is allowed: a tick does not wait for an earlier Execution to finish.
If a start fails, that tick stays due and the next minute retries it. The retry key is cron:<triggerId>:<scheduledAt>. The same tick returns the same Execution. The next tick starts a new one.
Deploying triggers
Section titled “Deploying triggers”Triggers are declared in trigora.toml. trigora deploy discovers Programs, deploys them, then reconciles the full trigger list for that project.
name is the reconcile identity. program must be a discovered program id. Platform ids (trg_…, t_…) are never written into the file. A file with no [[triggers]] replaces the project’s triggers with an empty list.
Trigger lifecycle
Section titled “Trigger lifecycle”A firing starts the Program’s current deployed version. The Execution pins that version.
Changing or deleting a trigger does not alter an Execution that already exists. Removing a trigger from trigora.toml removes that trigger on the next deploy. The webhook URL is stable while the trigger name stays.
Observability
Section titled “Observability”Ingress context is stored on the Execution. It is not the Program entry’s identity.
{ "type": "webhook", "triggerId": "trg_…", "publicId": "t_…" }{ "type": "cron", "triggerId": "trg_…", "scheduledAt": "…" }The dashboard Program page lists each trigger’s name, type, status, and either the webhook URL or schedule · timezone.