Register a cron schedule
const url = 'https://example.com/v1/schedules';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"flowId":"example","flowVersion":"example","agentId":"example","agentVersion":"example","improve":{"agentId":"example","scope":{"kind":"tenant"}},"projectId":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","config":{"cronExpression":"example","timezone":"example","input":"example"},"catchUp":"latest","overlap":"skip","startingDeadlineSeconds":1,"label":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/v1/schedules \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "flowId": "example", "flowVersion": "example", "agentId": "example", "agentVersion": "example", "improve": { "agentId": "example", "scope": { "kind": "tenant" } }, "projectId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "config": { "cronExpression": "example", "timezone": "example", "input": "example" }, "catchUp": "latest", "overlap": "skip", "startingDeadlineSeconds": 1, "label": "example" }'Registers a kind=cron trigger. nextFireAt is precomputed from the cron expression at register time; the cron scheduler in the runtime fires due triggers. Malformed cron expressions return 400 trigger-invalid-config without registering.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”Caller-supplied idempotency key, scoped to the caller: the same key from someone else in the tenant is their own request (from 0.1.5). Retries with the same key return the original response byte-identical (per docs/API-ROUTE-CONVENTIONS.md §3.1). A retry sent while the first request still runs is answered 409 idempotency-key-in-flight with Retry-After, on a runtime whose store holds keys (from 0.1.5); retry after it, and you get the first request’s answer. An answer that carries a secret (a new API key or public run token, a session token, a generated signing secret) isn’t kept: a retry gets 409 idempotency-key-replay-withheld, with the first request’s status and when it succeeded (from 0.1.5).
Request Bodyrequired
Section titled “Request Bodyrequired”Name what it runs: flowId with flowVersion, agentId (with an optional agentVersion), or improve (improvement passes). Registering needs write on the project and execute on what it runs (publish on the agent for improve); its runs act as the caller.
object
Run a flow (with flowVersion).
Run an agent (instead of a flow): at agentVersion, else its live version.
Start an improvement pass instead of a run (instead of flowId or agentId). Its config.input is the pass options; registering needs publish on the agent.
object
The agent’s default for the whole tenant.
object
An org’s projects.
object
One project.
object
A segment path within a project: it covers every run whose path starts with it.
object
object
Lowercase, like an identifier: company, contact-role.
The schedule’s project. Absent → the tenant’s default project.
object
What each run gets. An agent schedule’s runs take the agent payload, { userMessage, parameters? }, so it needs userMessage; a flow’s take the flow’s input. An improve schedule’s is ImproveScheduleInput, kept with its defaults applied.
Default latest.
Default skip.
Default 600.
Responses
Section titled “Responses”Schedule registered.
A schedule: what it runs (a flow at a version, or an agent), when (a cron expression in a timezone), as whom (its owner), and what it does after a gap or while a run is still going.
object
Domain-friendly alias for triggerId — the trigger id (a UUID). Use interchangeably in admin URLs.
A schedule that runs a flow: the flow, at flowVersion.
A schedule that runs an agent: the agent, at agentVersion, else its version live for the schedule’s project (else the latest), as a run that names none.
A schedule that starts improvement passes: on this agent, for this scope, when enough new trusted “no” judgments have come in (input: the threshold, the monthly cap and the pass options).
object
The agent’s default for the whole tenant.
object
An org’s projects.
object
One project.
object
A segment path within a project: it covers every run whose path starts with it.
object
object
Lowercase, like an identifier: company, contact-role.
The schedule’s project: its runs are this project’s.
Who its runs act as: whoever registered it, until an admin takes it over (POST …/owner). Checked again at every fire.
object
The owner’s name at the time of the response: the person’s display name, or the service account’s name. Absent when it can’t be read (no directory, a removed account) and from a runtime before Kindgi 0.1.6: show the id then.
5- or 6-field cron expression (croner-compatible). 6-field enables second precision.
IANA timezone (e.g. UTC, America/New_York). Absent → UTC.
Static input handed to the run on every fire. Absent → {}.
After a gap (the runtime was down, or a fire is later than startingDeadlineSeconds): latest runs once, for the latest missed occurrence, and its fire says how many it missed; skip drops the missed occurrences. Never a run per missed occurrence. A tenant’s suspension isn’t caught up either way: once the tenant is restored, a schedule that’s on fires next at its first occurrence after the restore.
When an occurrence comes while the previous run of this schedule is still running: skip records the fire as skipped; allow starts another run.
How late a fire may start and still count as on time; past it, catchUp applies.
Lifecycle status. Only active triggers fire. Tombstoned rows are excluded from every read path.
Why the runtime paused it: repeated fires that were refused (the owner lost access) or failed. Skipped fires (an overlap, an erasure in progress) never count.
Wall-clock time of the next scheduled fire. null on paused rows if the cron scheduler never re-armed.
The next occurrences, when the request asked for them (?upcoming=N).
Example
{ "improve": { "scope": { "kind": "tenant" } }, "owner": { "kind": "user" }, "catchUp": "latest", "overlap": "skip", "status": "active"}Malformed request body. Or reference-out-of-scope: what it runs isn’t registered in the schedule’s project, its org or the tenant (details.issues).
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}Missing / malformed / expired / revoked bearer token.
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}Idempotency-Key was reused with a different body, or resource-state conflict.
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}The request body is over the API’s limit (request-too-large; details.maxBytes says how much).
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}Server error (unmapped domain code or framework crash).
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}