Scheduled Runs
Configuring the four schedule types—CRON / INTERVAL / ONE_TIME / DELAYED_COMPLETION—along with time zone handling and chained workflow triggers.
Braidrun's scheduler supports four trigger types: CRON (a recurring expression), INTERVAL (a fixed interval), ONE_TIME (one-off), and DELAYED_COMPLETION (chained from a workflow). All schedules are managed centrally by the platform's scheduling service and keep firing on their own timetables after a service restart.
Concept: Schedule And Execution
A schedule describes "when to trigger"; each trigger creates one execution. A schedule is a long-lived object, while an execution is a one-time run record. A schedule can carry a static set of inputs (key-value pairs) that serve as the execution's input variables on every trigger.
Each schedule stores its own timezone (an IANA name like Asia/Shanghai), and the server computes trigger times against it. Creating via the web UI defaults to your account's current timezone; when creating via the API, always pass timezone explicitly.
The Four Schedule Types
| Type | Key Fields | Behavior |
|---|---|---|
CRON | cronExpression, timezone | Fires recurringly by a 5-field cron expression, down to minute granularity |
INTERVAL | interval, startTime, endTime | Fires every fixed number of milliseconds, with optional start and end times |
ONE_TIME | startTime | Fires once at the set time, then auto-disables |
DELAYED_COMPLETION | triggerWorkflowId, delaySeconds | Fires N seconds after an upstream workflow completes successfully, for workflow chains |
The four types share a common set of fields: enabled (whether active), maxRuns (max trigger count), and inputs (static input variables). When endTime has passed or the trigger count reaches maxRuns, the schedule is auto-disabled but not deleted.
Create A CRON Schedule
curl -X POST https://braidrun.com/api/schedules \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"workflowId": "<workflow-id>",
"name": "Daily 9 AM report",
"scheduleType": "CRON",
"cronExpression": "0 9 * * *",
"timezone": "Asia/Shanghai",
"inputs": {
"environment": "production"
}
}'The cron expression is 5-field: minute hour day-of-month month day-of-week. It supports *, lists (1,3,5), ranges (1-5), and steps (*/6); Sunday can be written as 0 or 7. Trigger times are computed against the schedule's own timezone.
| Expression | Meaning |
|---|---|
0 9 * * * | Everyday 09:00 |
0 9 * * 1-5 | Weekdays 09:00 |
0 */6 * * * | every 6 hours |
30 14 1 * * | 14:30 on the 1st of every month |
In a multi-instance deployment, a distributed lock deduplicates each trigger point: only one node actually starts the execution, so adding nodes doesn't cause duplicate triggers.
Interval: Fixed Interval
The request body goes to POST /api/schedules just like CRON, only the fields differ:
{
"workflowId": "<workflow-id>",
"name": "每 5 分钟同步一次",
"scheduleType": "INTERVAL",
"interval": 300000,
"startTime": 1785542400000,
"endTime": 1788220800000,
"maxRuns": 500
}interval— The trigger interval in milliseconds; values under 1 second are raised to 1 secondstartTime/endTime— Optional, an epoch-millisecond timestamp; if startTime is set it waits until that moment before starting, and it auto-disables once endTime has passedmaxRuns— Optional; auto-disables after firing this many times
ONE_TIME: One-Off
{
"workflowId": "<workflow-id>",
"name": "上线前补跑一次",
"scheduleType": "ONE_TIME",
"startTime": 1785546000000
}startTime is an epoch-millisecond timestamp. After firing once at that time, the schedule auto-disables; in a multi-instance deployment, a one-time lock ensures it fires only once.
Chained Scheduling (DELAYED_COMPLETION)
DELAYED_COMPLETION chains two workflows: each time upstream workflow A finishes with COMPLETED status, it waits delaySeconds seconds and then automatically triggers workflow B bound to this schedule. Typical use: run the report workflow automatically 10 minutes after the data-pull workflow finishes.
{
"workflowId": "<workflow-B-id>",
"name": "A 完成 10 分钟后跑 B",
"scheduleType": "DELAYED_COMPLETION",
"triggerWorkflowId": "<workflow-A-id>",
"delaySeconds": 600,
"maxRuns": 10
}- It counts whether A was triggered manually, by Webhook, by schedule, or by a chain — as long as it completes successfully; failed or cancelled executions don't trigger the downstream
delaySeconds— Required, 0 to 30 days (2592000 seconds); 0 means trigger immediately on completionmaxRuns— Omit for unlimited; 1 chains only once; N chains at most N times, then auto-disablestriggerWorkflowId— It can't equal workflowId (self-triggering would loop forever), and the creator needs view permission on the upstream workflow- Pending delayed triggers are stored durably and survive a service restart or rolling release: they fire as usual when the time comes
Managing Schedules
| Endpoint | Purpose |
|---|---|
GET /api/schedules | List all visible schedules |
GET /api/schedules/{id} | View a single one |
PUT /api/schedules/{id} | Update; the fields are the same as for creation, and changing the type revalidates against the new type |
DELETE /api/schedules/{id} | Delete |
POST /api/schedules/{id}/toggle | Enable / disable |
POST /api/schedules/{id}/run | Run once immediately, bypassing the schedule |
GET /api/schedules/{id}/history | Trigger history |
GET /api/schedules/workflows/{workflowId} | List all schedules under a given workflow |
# 立即执行一次(返回这次 execution)
curl -X POST https://braidrun.com/api/schedules/<schedule-id>/run \
-H "Authorization: Bearer <token>"
# 停用(enabled=true 则启用;不带参数则在两者间切换)
curl -X POST "https://braidrun.com/api/schedules/<schedule-id>/toggle?enabled=false" \
-H "Authorization: Bearer <token>"
# 最近 50 条触发历史
curl "https://braidrun.com/api/schedules/<schedule-id>/history?limit=50" \
-H "Authorization: Bearer <token>"toggle's enabled can go in a query parameter or the JSON body; if neither is passed, it flips between enabled and disabled. Each history record includes the status, success flag, and start and end times; limit defaults to 50, max 500.
Shared Inputs and Parameter Presets
Besides setting inputs directly on a schedule, you can create "parameter presets" for a workflow: run the same workflow under different presets for different configurations.
# 创建一个参数预设
curl -X POST https://braidrun.com/api/workflows/<wf>/presets \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "生产环境",
"description": "生产环境参数",
"variables": {
"environment": "production",
"debug_mode": "false",
"max_retries": "3"
}
}'
# 用预设触发执行
curl -X POST https://braidrun.com/api/workflows/<wf>/presets/<id>/execute \
-H "Authorization: Bearer <token>"Multiple Workflow Batch Concurrency
Select multiple items from the workflow list and click "Concurrent Execution" to start a batch of executions at a time.
- Each selected workflow will create its own execution record
- Execution exceeding maxConcurrency will first enter PENDING
- After the previously running execution is completed, the next one in the queue is automatically converted to RUNNING
0Indicates no limit and starts the entire batch at the same time
The concurrency at the top level of Workflow controls the same-layer concurrency within a single workflow's internal DAG; the two do not interfere with each other.
Behavior After Service Restart
- Triggered execution: Default is INTERRUPTED unless automatic continuation is enabled (seeRestart And Automatic Resume)
- CRON / INTERVAL / ONE_TIME schedules that haven't come due: fire as usual after a restart
- Pending DELAYED_COMPLETION delayed triggers: already persisted, they keep waiting and fire on time after a restart
- Missed trigger points during downtime: no make-up (to avoid the risk of double writing)