> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qoder.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 创建 Schedule

> 创建可重复触发或手动触发的 Template 执行配置。

`POST /api/v1/forward/schedules`

Schedule 绑定一个 Identity、一个 Template、初始事件、触发策略和执行策略。每次触发都会生成独立 Schedule Run。

## 请求头

| Header          | 是否必填 | 说明                 |
| --------------- | ---- | ------------------ |
| Authorization   | 是    | `Bearer <PAT>`     |
| Content-Type    | 是    | `application/json` |
| Idempotency-Key | 否    | 有副作用请求可选的幂等键。      |

## 请求体参数

| 参数              | 类型             | 是否必填 | 说明                               |
| --------------- | -------------- | ---- | -------------------------------- |
| identity\_id    | string         | 是    | Schedule 所属 Forward Identity ID。 |
| template\_id    | string         | 是    | 要执行的 Forward Template ID。        |
| name            | string         | 是    | Schedule 名称。                     |
| description     | string         | 否    | Schedule 描述。                     |
| initial\_events | array          | 是    | 每次执行注入的初始事件，当前支持 `user.message`。 |
| execution       | object         | 否    | 执行策略；省略时使用服务端默认值。                |
| trigger\_policy | object \| null | 否    | 触发策略；省略或 `null` 时按 `manual` 处理。  |
| environment\_id | string         | 是    | 执行环境。                            |
| metadata        | object         | 否    | 业务元数据，仅用于标签或透传。                  |

## 触发策略

`trigger_policy` 是按 `type` 分发的对象。创建和更新请求只接收配置字段：`type`、`expression`、`timezone`。`upcoming_runs_at`、`last_run_at` 是服务端计算出的响应字段。

| 字段                 | 类型             | 是否必填 | 说明                                                                                       |
| ------------------ | -------------- | ---- | ---------------------------------------------------------------------------------------- |
| type               | string         | 是    | `cron`、`once`、`interval` 或 `manual`。                                                     |
| expression         | string         | 条件必填 | 触发表达式；`cron`、`once`、`interval` 必填，`manual` 不需要。                                          |
| timezone           | string         | 条件必填 | IANA timezone，例如 `Asia/Shanghai`；`cron` 必填，`once` 在表达式不带时区时必填，`interval` 和 `manual` 可省略。 |
| upcoming\_runs\_at | array          | 响应返回 | 后续触发时间，UTC ISO 8601。当前实现返回 `[]` 或最多一个下一次计划触发时间。                                          |
| last\_run\_at      | string \| null | 响应返回 | 最近一次触发时间。                                                                                |

| type       | 创建/更新入参                           | 说明                                               |
| ---------- | --------------------------------- | ------------------------------------------------ |
| `cron`     | `type`、`expression`、`timezone`    | 使用 5 字段 cron 表达式按指定 IANA timezone 重复触发。          |
| `once`     | `type`、`expression`、可选 `timezone` | 按 ISO 8601 时间触发一次；表达式不带 offset 时必须提供 `timezone`。 |
| `interval` | `type`、`expression`               | 按 ISO 8601 duration 重复触发，例如 `PT15M`。             |
| `manual`   | `type`                            | 不自动触发，只能通过 Run Schedule 接口手动执行。                  |

| type       | expression 格式     | 示例                                             | 说明                         |
| ---------- | ----------------- | ---------------------------------------------- | -------------------------- |
| `cron`     | 标准 5 字段 cron      | `0 9 * * *`                                    | 分钟级日历规则；不支持秒字段和 6 字段 cron。 |
| `once`     | ISO 8601 绝对时间     | `2026-06-23T09:00:00` 或 `2026-06-23T01:00:00Z` | 目标时间必须至少晚于服务端当前时间 1 分钟。    |
| `interval` | ISO 8601 duration | `PT15M`、`PT1H`、`P1D`                           | 固定间隔触发，最小粒度 1 分钟。          |
| `manual`   | 省略或空字符串           | -                                              | 不产生计划触发时间。                 |

## 执行策略

| 字段                    | 类型      | 默认值           | 说明                                               |
| --------------------- | ------- | ------------- | ------------------------------------------------ |
| session\_mode         | string  | `new_session` | Session 使用方式，取值 `new_session` 或 `reuse_session`。 |
| max\_concurrent\_runs | integer | 1             | 同一个 Schedule 最大并发 Run 数。                         |
| max\_attempts         | integer | 1             | 预留字段；当前实现只记录、校验和回显，单个 Run 仍只执行一次。                |
| timeout\_ms           | integer | 300000        | 单次尝试超时时间。                                        |

| session\_mode   | 说明                                                                         |
| --------------- | -------------------------------------------------------------------------- |
| `new_session`   | 每次触发都创建新的执行 Session，不延续历史上下文。                                              |
| `reuse_session` | Forward 为该 Schedule 管理一个固定执行 Session，并在多次触发间持续使用；调用方不能指定任意已有 `session_id`。 |

## 示例请求

```bash theme={null}
curl -s -X POST 'https://api.qoder.com/api/v1/forward/schedules' \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
  "identity_id": "idn_019eabc123",
  "template_id": "tmpl_support",
  "name": "Daily tech brief",
  "description": "Generate a daily technology news summary",
  "initial_events": [
    {
      "type": "user.message",
      "content": "Summarize current technology news in five bullet points."
    }
  ],
  "trigger_policy": {
    "type": "cron",
    "expression": "0 9 * * *",
    "timezone": "Asia/Shanghai"
  },
  "execution": {
    "session_mode": "new_session",
    "max_concurrent_runs": 1,
    "max_attempts": 1,
    "timeout_ms": 300000
  },
  "environment_id": "env_019e64e01a137caf953ac2ac7b42ec5c"
}'
```

## 示例响应

**HTTP 200 OK**

```json theme={null}
{
  "id": "sched_019f00112233445566778899aabbccdd",
  "identity_id": "idn_019eabc123",
  "template_id": "tmpl_support",
  "name": "Daily tech brief",
  "description": "Generate a daily technology news summary",
  "status": "active",
  "initial_events": [
    {
      "type": "user.message",
      "content": "Summarize current technology news in five bullet points."
    }
  ],
  "execution": {
    "session_mode": "new_session",
    "max_concurrent_runs": 1,
    "max_attempts": 1,
    "timeout_ms": 300000
  },
  "trigger_policy": {
    "type": "cron",
    "expression": "0 9 * * *",
    "timezone": "Asia/Shanghai",
    "upcoming_runs_at": [
      "2026-06-23T01:00:00Z"
    ]
  },
  "environment_id": "env_019e64e01a137caf953ac2ac7b42ec5c",
  "sinks": [],
  "metadata": {},
  "created_at": "2026-06-22T10:00:00Z",
  "updated_at": "2026-06-22T10:00:00Z"
}
```

## 响应字段

| 字段  | 类型     | 说明                  |
| --- | ------ | ------------------- |
| 返回值 | object | 创建后的完整 Schedule 对象。 |

## 错误

| HTTP | Type                    | Code                           | 触发条件                    |
| ---- | ----------------------- | ------------------------------ | ----------------------- |
| 400  | `invalid_request_error` | `invalid_trigger_policy`       | 触发策略类型或表达式不合法。          |
| 400  | `invalid_request_error` | `trigger_policy_too_frequent`  | 触发粒度小于 1 分钟。            |
| 400  | `invalid_request_error` | `trigger_policy_time_too_soon` | `once` 目标时间过近。          |
| 400  | `invalid_request_error` | `unsupported_sinks_input`      | HTTP 创建请求不支持传入 `sinks`。 |
| 404  | `not_found_error`       | `identity_not_found`           | Identity 不存在。           |
| 404  | `not_found_error`       | `template_not_found`           | Template 不存在。           |
| 401  | `authentication_error`  | `authentication_required`      | PAT 无效或已过期。             |

## 注意事项

* HTTP 创建请求不接受 `sinks`；直接 API 创建的 Schedule 返回 `sinks: []`。
* `manual` Schedule 只能通过 Run Schedule 接口触发。
* `once` Schedule 的首次计划 Run 进入终态后会自动归档。

## 相关

<CardGroup cols={2}>
  <Card title="运行 Schedule" icon="play" href="/cloud-agents/api/forward/schedules/run" />

  <Card title="列出 Schedules" icon="list" href="/cloud-agents/api/forward/schedules/list" />
</CardGroup>
