A trigger starts a session with no person present. A cron schedule fires it on the clock; a signed webhook fires it on an event. Either way it runs like a session you start by hand, on the project’s cloud computer, and its work comes back through the same review.
The 1st of the month at 06:30
0 30 6 1 * *
A trigger is a clock or a signature. Everything else about it — which agent it runs as, what it says, which session it lands in — is the same config either way.
A 6-field cron expression — second, minute, hour, day, month, weekday — in any IANA timezone. Or a single run_at timestamp, for something that should happen once and then stay quiet.
An external service POSTs to the trigger URL. SingulaComp checks the signature, renders the payload into the prompt, and starts the session. A payload that fails your filter is accepted and ignored.
Every trigger in a project is one row: what it is called, when it fires, in whose timezone, as which agent, and which session that fire lands in. Nothing about it is hidden state you have to click into.
| Trigger | Cron | Timezone | Agent | Session |
|---|---|---|---|---|
| daily-digest | 0 0 9 * * 1-5Weekdays at 09:00 | America/Los_Angeles | singulacomp | fresh |
| invoice-sweep | 0 30 6 1 * *The 1st of the month at 06:30 | Europe/Berlin | finance | reuse |
| oncall-handoff | 0 0 17 * * 5Fridays at 17:00 | UTC | support | fresh |
| roadmap-review | 0 0 8 * * 1Mondays at 08:00 | America/New_York | planner | pinned |
Triggers live in singulacomp.yaml next to your agents and sandbox images. Each one names its agent, its schedule or its secret, and the prompt template that becomes the session’s first message.
# fires on the clocktriggers: - slug: daily-digest type: cron agent: singulacomp cron: "0 0 9 * * 1-5" timezone: America/Los_Angeles session_mode: fresh prompt: | Summarize yesterday’s commits. Open a change request against main. # fires on an event - slug: new-lead type: webhook agent: sales secret_env: WEBHOOK_SECRET prompt: >- A new lead arrived: {{ body.name }} ({{ body.email }}). Add it to the CRM.# the change request that adds the trigger merges;# from then on: 09:00 America/Los_Angeles, weekdays # each fire is a normal session in the project$ git branch --show-current5e71a9d4-c188-4a6f-b0c2-9f4c2b7e1d83 # the prompt template, rendered for this fireSummarize yesterday’s commits.Open a change request against main. → session finished · change request opened toward mainA prompt renders {{ token.dotted.path }} against the payload that fired it. A webhook fire gets {{ body.* }} and the request headers; a cron fire gets {{ cron.schedule }}, {{ cron.timezone }} and {{ cron.scheduled_for }}. A value that is not there renders as nothing — no error, no leftover braces in the message your agent reads.
Every webhook trigger names a project secret that signs it. A trigger without one is rejected at validation — there is no unauthenticated webhook to forget to lock down later.
POST /v1/webhooks/projects/{projectId}/{slug}
X-SingulaComp-Signature: sha256=<hmac>
HMAC-SHA256 over the raw request body, compared in constant time. The GitHub-compatible X-Hub-Signature-256 header works too, so a repo webhook needs no adapter.
A filter is a dotted path matched against the same payload the prompt sees. It exists to break loops: a source that reports both sides of a conversation would otherwise fire the agent on its own reply.
By default every fire is a clean slate. When the work is a running thread rather than a fresh errand, a trigger can re-prompt a session it already owns. SingulaComp tries the modes in order and falls through on failure, so a fire never simply disappears.
Re-prompt one exact session, named by id. If that session is gone or failed, fall through.
Render a key from the payload, then re-prompt the most recent healthy session stamped with that exact key. One customer, one thread. It never falls through into another key’s session.
Re-prompt the most recent healthy session this trigger created. A pinned trigger falls back here before falling further.
Cut a new branch and boot a new cloud computer. This is the default, and the last resort for every other mode.
A triggered session is visible to the whole project, not private to whoever configured the trigger. It stops itself after 5 minutes idle, so an automation that runs at 3am is not a machine billing until morning.
An automation gets no privileges a person would not get. The same isolation, the same scoped reach, the same one road back to main.
Start with one job and grow from there.
Free to start · No credit card required