日程与目标 API
日程和参与者、日历订阅,以及目标。
由群历 REST API 的 OpenAPI 契约(openapi/qunli-api.yaml,qunli-api 提交 f18e40d)生成。路径都相对于 https://qunli.co;认证见认证,响应包装、分页和错误格式见约定。字段说明是契约里的英文原文。
日程
GET/api/v1/accounts/{account_id}/projects/{project_id}/schedules
Active schedules of the project overlapping [from, to) — starts_at < to AND ends_at > from — ordered by starts_at (all-day first on ties). Omit both from and to for the current month in Asia/Shanghai. Not paginated: at most 1000 items; narrow the window for more. Items carry every field (same shape as GET /schedules/{id}).
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
project_id | 路径 | string | 是 | |
content | 查询 | full | summary | 否 | full (default): rows carry their whole body. summary: rows leave out content_html, content_json, content_markdown and content_version and carry only preview_text / excerpt (documents: also preview_html); read one record for its body. Other values → 400 param_invalid.默认 full |
from | 查询 | string | 否 | Window start (inclusive). Date (YYYY-MM-DD) or ISO 8601 date-time; percent-encode a + offset as %2B (or use Z). Defaults with to to the current month. |
to | 查询 | string | 否 | Window end (exclusive). Date or date-time; percent-encode a + offset as %2B. |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | Schedules overlapping the window | data: Schedule[] |
400 | Malformed request or invalid parameter. | ProblemDetails |
401 | Missing or invalid authentication. | ProblemDetails |
404 | Resource does not exist or has been trashed. | ProblemDetails |
POST/api/v1/accounts/{account_id}/projects/{project_id}/schedules
Creates an active schedule. Timed events send schedule.starts_at (and optionally ends_at, default +1 hour); all-day events send all_day: true with starts_on (and optionally ends_on, inclusive). schedule.participants (member refs "U12" or user UUIDs) become participants: each is notified (reason invited) and auto-follows the schedule. The creator is not added as a participant.
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
project_id | 路径 | string | 是 |
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
edit_scope | string | 否 | Update only. this (default) creates an exception; following edits the selected future instance and later instances, keeping earlier meetings and exceptions. Recurrence changes require following; recurrence null stops repeating after this instance. |
recording | object | 否 | |
recording.id | string (uuid) | 否 | |
recording.title | string | 否 | 1–255 characters after trimming; required on create. |
recording.content_markdown | string | null | 否 | Agenda / minutes (GFM, ≤ 128KB). |
recording.content_html | string | null | 否 | 已弃用 |
recording.content_json | any | 否 | 已弃用 |
recording.content_version | integer | null | 否 | Update only. The content_version the edit started from (recommended for every body edit). When present and the request changes the body, a stale value is refused with 409 content_conflict and nothing is written; the problem body carries the current content_version. Omit it (or send null) for last-write-wins. Title- or metadata-only updates never conflict. |
schedule | object | 否 | |
schedule.id | string (uuid) | 否 | |
schedule.all_day | boolean | 否 | Explicit null or invalid values return 422 validation_error (all_day_invalid). |
schedule.starts_at | string | 否 | ISO 8601 date-time with offset, e.g. 2026-10-20T14:00:00+08:00. |
schedule.ends_at | string | 否 | Exclusive end; default starts_at + 1 hour on create. |
schedule.starts_on | string | 否 | YYYY-MM-DD (all-day). |
schedule.ends_on | string | 否 | YYYY-MM-DD, inclusive (all-day); default starts_on. |
schedule.time_zone | string | 否 | IANA name; default Asia/Shanghai. |
schedule.location | string | null | 否 | |
schedule.link | string | null | 否 | https:// URL, ≤ 2048 characters. |
schedule.recurrence | ScheduleRecurrence | 否 | Calendar-date rule in the event timezone. Daily/weekly/monthly/yearly; invalid month-end or leap dates are skipped. until is inclusive, count includes the first occurrence. Specify at most one of until/count. Open-ended series materialize one year ahead and renew daily. On a schedule it is the rule the series still follows: once the series is stopped (PATCH edit_scope=following with recurrence null, or DELETE edit_scope=following), the meetings it kept report the shortened rule — count becomes the number of kept meetings (count and open-ended rules), until becomes the last kept meeting's date (until rules) — and null when no meeting of the series was kept. |
schedule.recurrence.freq | string | 否 | |
schedule.recurrence.interval | integer | 否 | 1–365; defaults to 1. |
schedule.recurrence.by_weekday | integer[] | 否 | Weekly only. 0=Sunday to 6=Saturday; must include the initial weekday. |
schedule.recurrence.until | string | null | 否 | Inclusive YYYY-MM-DD; not before the first occurrence. |
schedule.recurrence.count | integer | null | 否 | 1–1000 occurrences. |
schedule.participants_version | string | 否 | Required on update when participants is present; use the token from the schedule snapshot. |
schedule.participants | string[] | 否 | Member refs ("U12") or user UUIDs; replaces the list when present. Only [] clears it; null is invalid. |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
201 | Created schedule | data: Schedule |
400 | Malformed request or invalid parameter. | ProblemDetails |
401 | Missing or invalid authentication. | ProblemDetails |
403 | Authenticated but not permitted. | ProblemDetails |
404 | Resource does not exist or has been trashed. | ProblemDetails |
422 | Validation failed. | ProblemDetails |
GET/api/v1/accounts/{account_id}/schedules
The account calendar: schedules overlapping [from, to) across every project the caller can access. scope=mine (default) keeps schedules the caller created or participates in; scope=all keeps every accessible one. project_ids narrows to some projects (inaccessible ids are ignored). Same window rules, order and 1000-item cap as the project list.
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
content | 查询 | full | summary | 否 | full (default): rows carry their whole body. summary: rows leave out content_html, content_json, content_markdown and content_version and carry only preview_text / excerpt (documents: also preview_html); read one record for its body. Other values → 400 param_invalid.默认 full |
from | 查询 | string | 否 | Window start (inclusive). Date (YYYY-MM-DD) or ISO 8601 date-time; percent-encode a + offset as %2B (or use Z). Defaults with to to the current month. |
to | 查询 | string | 否 | Window end (exclusive). Date or date-time; percent-encode a + offset as %2B. |
scope | 查询 | string | 否 | mine (default) = created by me or I participate; all = every accessible project; members = selected creators or participants (member_ids required). |
project_ids | 查询 | string 或 string[] | 否 | Comma-separated project IDs or project_ids[]=12&project_ids[]=13. |
member_ids | 查询 | string 或 string[] | 否 | Required for scope=members. 1–100 live account member refs (U12) or user UUIDs, comma-separated or array. OR across selected members; intersects project filters and caller access. |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | Schedules overlapping the window | data: Schedule[] |
400 | Malformed request or invalid parameter. | ProblemDetails |
401 | Missing or invalid authentication. | ProblemDetails |
GET/api/v1/accounts/{account_id}/schedules/{id}
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
id | 路径 | string (ref) | 是 | 引用号,例如 T1042,大小写不敏感,可带前导 #。 |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | Schedule | data: Schedule |
401 | Missing or invalid authentication. | ProblemDetails |
404 | Resource does not exist or has been trashed. | ProblemDetails |
PATCH/api/v1/accounts/{account_id}/schedules/{id}
Updates any subset of fields. Sending starts_at without ends_at (or starts_on without ends_on) shifts the event and keeps its duration; sending both sets both as given. Changing the time notifies participants and the creator (reason rescheduled), records a rescheduled activity and re-plans reminders. schedule.participants, when present, replaces the participant list (same as PUT .../participants). recording.content_version guards the body like the other recording updates: stale → 409 content_conflict (current content_version in the problem body), nothing written; only the selected instance's version is checked when edit_scope is following.
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
id | 路径 | string (ref) | 是 | 引用号,例如 T1042,大小写不敏感,可带前导 #。 |
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
edit_scope | string | 否 | Update only. this (default) creates an exception; following edits the selected future instance and later instances, keeping earlier meetings and exceptions. Recurrence changes require following; recurrence null stops repeating after this instance. |
recording | object | 否 | |
recording.id | string (uuid) | 否 | |
recording.title | string | 否 | 1–255 characters after trimming; required on create. |
recording.content_markdown | string | null | 否 | Agenda / minutes (GFM, ≤ 128KB). |
recording.content_html | string | null | 否 | 已弃用 |
recording.content_json | any | 否 | 已弃用 |
recording.content_version | integer | null | 否 | Update only. The content_version the edit started from (recommended for every body edit). When present and the request changes the body, a stale value is refused with 409 content_conflict and nothing is written; the problem body carries the current content_version. Omit it (or send null) for last-write-wins. Title- or metadata-only updates never conflict. |
schedule | object | 否 | |
schedule.id | string (uuid) | 否 | |
schedule.all_day | boolean | 否 | Explicit null or invalid values return 422 validation_error (all_day_invalid). |
schedule.starts_at | string | 否 | ISO 8601 date-time with offset, e.g. 2026-10-20T14:00:00+08:00. |
schedule.ends_at | string | 否 | Exclusive end; default starts_at + 1 hour on create. |
schedule.starts_on | string | 否 | YYYY-MM-DD (all-day). |
schedule.ends_on | string | 否 | YYYY-MM-DD, inclusive (all-day); default starts_on. |
schedule.time_zone | string | 否 | IANA name; default Asia/Shanghai. |
schedule.location | string | null | 否 | |
schedule.link | string | null | 否 | https:// URL, ≤ 2048 characters. |
schedule.recurrence | ScheduleRecurrence | 否 | Calendar-date rule in the event timezone. Daily/weekly/monthly/yearly; invalid month-end or leap dates are skipped. until is inclusive, count includes the first occurrence. Specify at most one of until/count. Open-ended series materialize one year ahead and renew daily. On a schedule it is the rule the series still follows: once the series is stopped (PATCH edit_scope=following with recurrence null, or DELETE edit_scope=following), the meetings it kept report the shortened rule — count becomes the number of kept meetings (count and open-ended rules), until becomes the last kept meeting's date (until rules) — and null when no meeting of the series was kept. |
schedule.recurrence.freq | string | 否 | |
schedule.recurrence.interval | integer | 否 | 1–365; defaults to 1. |
schedule.recurrence.by_weekday | integer[] | 否 | Weekly only. 0=Sunday to 6=Saturday; must include the initial weekday. |
schedule.recurrence.until | string | null | 否 | Inclusive YYYY-MM-DD; not before the first occurrence. |
schedule.recurrence.count | integer | null | 否 | 1–1000 occurrences. |
schedule.participants_version | string | 否 | Required on update when participants is present; use the token from the schedule snapshot. |
schedule.participants | string[] | 否 | Member refs ("U12") or user UUIDs; replaces the list when present. Only [] clears it; null is invalid. |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | Updated schedule | data: Schedule |
400 | Malformed request or invalid parameter. | ProblemDetails |
401 | Missing or invalid authentication. | ProblemDetails |
403 | Authenticated but not permitted. | ProblemDetails |
404 | Resource does not exist or has been trashed. | ProblemDetails |
409 | State conflict. | ProblemDetails |
422 | Validation failed. | ProblemDetails |
DELETE/api/v1/accounts/{account_id}/schedules/{id}
Cancel (trash) a schedule — notifies participants and the creator
Cancelling is trashing: the response is the schedule with status trashed; participants and the creator (except the caller) are notified with reason cancelled. Restore with PUT /recordings/{ref}/status/active.
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
id | 路径 | string (ref) | 是 | 引用号,例如 T1042,大小写不敏感,可带前导 #。 |
edit_scope | 查询 | string | 否 | this (default) cancels one occurrence; following stops the series from this future occurrence, including its later exceptions. Restoring one meeting does not restart the series. |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | Trashed schedule | data: Schedule |
401 | Missing or invalid authentication. | ProblemDetails |
403 | Authenticated but not permitted. | ProblemDetails |
404 | Resource does not exist or has been trashed. | ProblemDetails |
PUT/api/v1/accounts/{account_id}/schedules/{schedule_id}/participants
Replaces the participant list. members are member refs ("U12") or user UUIDs of people who can access the project; an empty array clears it. Newly added people are notified (reason invited) and follow the schedule; removed people stop following it (unless they created it).
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
schedule_id | 路径 | string (ref) | 是 | 引用号,例如 T1042,大小写不敏感,可带前导 #。 |
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
participants | object | 否 | Required. |
participants.version | string | 否 | Required. The participants_version from the opened schedule snapshot. |
participants.members | string[] | 否 | Required. Member refs ("U12") or user UUIDs; [] clears the list. |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | The schedule with its new participants | data: Schedule |
400 | Malformed request or invalid parameter. | ProblemDetails |
401 | Missing or invalid authentication. | ProblemDetails |
403 | Authenticated but not permitted. | ProblemDetails |
404 | Resource does not exist or has been trashed. | ProblemDetails |
409 | State conflict. | ProblemDetails |
422 | Validation failed. | ProblemDetails |
GET/api/v1/accounts/{account_id}/calendar_feeds
List only the current user's calendar subscriptions
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | Subscriptions (no raw access tokens) | data: CalendarFeed[] |
POST/api/v1/accounts/{account_id}/calendar_feeds
Create a revocable read-only calendar subscription with saved filters
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
calendar_feed | object | 否 | |
calendar_feed.name | string | 否 | |
calendar_feed.scope | string | 否 | |
calendar_feed.project_ids | string[] | 否 | |
calendar_feed.member_ids | string[] | 否 | |
calendar_feed.include_tasks | boolean | 否 |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
201 | Subscription with its one-time token URL | data: CalendarFeed |
400 | Malformed request or invalid parameter. | ProblemDetails |
422 | Validation failed. | ProblemDetails |
DELETE/api/v1/accounts/{account_id}/calendar_feeds/{id}
Revoke a calendar subscription
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
id | 路径 | string | 是 |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | Revoked (`{ "data": null }`); the old subscription URL now answers 404. | data: null |
404 | Resource does not exist or has been trashed. | ProblemDetails |
POST/api/v1/accounts/{account_id}/calendar_feeds/{id}/rotate
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
id | 路径 | string | 是 |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | New URL; previous token immediately invalidated | data: CalendarFeed |
404 | Resource does not exist or has been trashed. | ProblemDetails |
GET/api/v1/accounts/{account_id}/calendar_subscriptions/{id}.ics
Read-only ICS authenticated by the URL token. Rechecks owner membership and project access on every request. Rolling past 90 days and next year; cancelled events retain stable UIDs. External clients choose refresh timing.
认证:无需认证。
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
id | 路径 | string | 是 | |
token | 查询 | string | 是 |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | RFC 5545 calendar | string |
404 | Resource does not exist or has been trashed. | ProblemDetails |
GET/api/v1/accounts/{account_id}/schedules/{schedule_id}/calendar.ics
Download one meeting (requires normal session/API authentication and project access)
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
schedule_id | 路径 | string | 是 |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | RFC 5545 calendar containing one event | string |
404 | Resource does not exist or has been trashed. | ProblemDetails |
目标
GET/api/v1/accounts/{account_id}/goals
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
content | 查询 | full | summary | 否 | full (default): rows carry their whole body. summary: rows leave out content_html, content_json, content_markdown and content_version and carry only preview_text / excerpt (documents: also preview_html); read one record for its body. Other values → 400 param_invalid.默认 full |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | Goal list | data: Goal[] |
401 | Missing or invalid authentication. | ProblemDetails |
GET/api/v1/accounts/{account_id}/goals/{id}
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
id | 路径 | string (ref) | 是 | 引用号,例如 T1042,大小写不敏感,可带前导 #。 |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | Goal | data: Goal |
401 | Missing or invalid authentication. | ProblemDetails |
404 | Resource does not exist or has been trashed. | ProblemDetails |
PATCH/api/v1/accounts/{account_id}/goals/{id}
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
id | 路径 | string (ref) | 是 | 引用号,例如 T1042,大小写不敏感,可带前导 #。 |
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
recording | RecordingFields | 否 | The fields every recording type shares, sent under recording. id
is create-only (a client-generated UUID). |
recording.id | string (uuid) | 否 | |
recording.title | string | 否 | |
recording.status | string | 否 | |
recording.content_html | string | null | 否 | 已弃用 |
recording.content_json | any | 否 | 已弃用 |
recording.content_markdown | string | null | 否 | Canonical body (GFM). When present the server renders and sanitizes content_html from it, ignoring any client-sent content_html/content_json. Preferred over content_html and content_json for new integrations. Hard cap 131072 bytes (128KB, UTF-8 bytes — not characters); a larger body is rejected with 422 validation_error ("正文超出 128KB 上限"): upload long content as an attachment or split it into multiple documents. Pre-existing over-limit rows stay readable and editable as long as the body is untouched. |
recording.content_version | integer | null | 否 | Update only. The content_version the edit started from (recommended for every body edit). When present and the request changes the body, a stale value is refused with 409 content_conflict and nothing is written; the problem body carries the current content_version. Omit it (or send null) for last-write-wins. Title- or metadata-only updates never conflict. |
goal | GoalFields | 否 | Goal fields (goals_controller#recordable_params). Whole numbers; target must be greater than starting. |
goal.id | string (uuid) | 否 | |
goal.starting | integer | 否 | |
goal.target | integer | 否 | |
goal.current | integer | 否 |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | Updated goal | data: Goal |
401 | Missing or invalid authentication. | ProblemDetails |
403 | Authenticated but not permitted. | ProblemDetails |
404 | Resource does not exist or has been trashed. | ProblemDetails |
409 | content_conflict — the body was saved elsewhere since the request's recording.content_version; nothing was written. Rebase the edit onto the returned content_version (or reload) and save again. | ProblemDetails |
422 | Validation failed. | ProblemDetails |
DELETE/api/v1/accounts/{account_id}/goals/{id}
Soft-delete a goal (returns the trashed recording)
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
id | 路径 | string (ref) | 是 | 引用号,例如 T1042,大小写不敏感,可带前导 #。 |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | Trashed goal | data: Goal |
401 | Missing or invalid authentication. | ProblemDetails |
403 | Authenticated but not permitted. | ProblemDetails |
404 | Resource does not exist or has been trashed. | ProblemDetails |
GET/api/v1/accounts/{account_id}/projects/{project_id}/goals
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
project_id | 路径 | string | 是 | |
content | 查询 | full | summary | 否 | full (default): rows carry their whole body. summary: rows leave out content_html, content_json, content_markdown and content_version and carry only preview_text / excerpt (documents: also preview_html); read one record for its body. Other values → 400 param_invalid.默认 full |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
200 | Goal list | data: Goal[] |
401 | Missing or invalid authentication. | ProblemDetails |
POST/api/v1/accounts/{account_id}/projects/{project_id}/goals
参数
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
account_id | 路径 | string | 是 | 团队的数字 id,和网页地址里的相同,例如 2025。 |
project_id | 路径 | string | 是 |
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
recording | RecordingFields | 否 | The fields every recording type shares, sent under recording. id
is create-only (a client-generated UUID). |
recording.id | string (uuid) | 否 | |
recording.title | string | 否 | |
recording.status | string | 否 | |
recording.content_html | string | null | 否 | 已弃用 |
recording.content_json | any | 否 | 已弃用 |
recording.content_markdown | string | null | 否 | Canonical body (GFM). When present the server renders and sanitizes content_html from it, ignoring any client-sent content_html/content_json. Preferred over content_html and content_json for new integrations. Hard cap 131072 bytes (128KB, UTF-8 bytes — not characters); a larger body is rejected with 422 validation_error ("正文超出 128KB 上限"): upload long content as an attachment or split it into multiple documents. Pre-existing over-limit rows stay readable and editable as long as the body is untouched. |
recording.content_version | integer | null | 否 | Update only. The content_version the edit started from (recommended for every body edit). When present and the request changes the body, a stale value is refused with 409 content_conflict and nothing is written; the problem body carries the current content_version. Omit it (or send null) for last-write-wins. Title- or metadata-only updates never conflict. |
goal | GoalFields | 否 | Goal fields (goals_controller#recordable_params). Whole numbers; target must be greater than starting. |
goal.id | string (uuid) | 否 | |
goal.starting | integer | 否 | |
goal.target | integer | 否 | |
goal.current | integer | 否 |
响应
| 状态 | 说明 | 返回 |
|---|---|---|
201 | Created goal | data: Goal |
401 | Missing or invalid authentication. | ProblemDetails |
403 | Authenticated but not permitted. | ProblemDetails |
422 | Validation failed. | ProblemDetails |
数据结构
上面的响应用到的对象。字段的类型是另一个对象时,它也列在这里。
Schedule
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string (uuid) | 是 | |
public_id | string | null | 否 | |
legacy_id | string | null | 是 | |
title | string | 是 | |
content_html | string | null | 否 | |
content_json | object | null | 否 | |
content_markdown | string | null | 否 | Canonical body (GFM). content_html is rendered server-side from it; null on rows not yet migrated from Tiptap JSON. |
content_version | integer | 否 | Body version for compare-and-set saves. Starts at 0 and increases by one each time content_markdown / content_html / content_json actually changes (any write path). Send it back as recording.content_version when saving a body edit. |
preview_text | string | 否 | Lists only. The body as plain text (HTML tags removed, entities left encoded, e.g. "&"), cut to 80 UTF-16 units; "" without a body. |
excerpt | string | null | 否 | Lists only. Up to 100 characters of the body's text, images and videos shown as [图片] / [视频]; null without a body. |
preview_html | string | 否 | Document lists only. The first 3000 characters of content_html (may end inside a tag), for thumbnails. |
comments_count | integer | 是 | |
type | Schedule | 是 | |
status | draft | active | archived | trashed | 是 | |
recordable_type | Schedule | 是 | |
app_url | string | null | 是 | |
account_id | string (uuid) | 是 | |
account_public_id | string | 是 | |
project_id | string (uuid) | 是 | |
project_public_id | string | 是 | |
creator_id | string (uuid) | 是 | |
parent_id | string (uuid) | null | 否 | |
parent_public_id | string | null | 否 | |
ancestors | FolderCrumb[] | 否 | |
created_at | string (date-time) | 是 | |
updated_at | string (date-time) | 是 | Last change of the recording or of its body, whichever is later. |
reactions | Reaction[] | 是 | |
edited_by | UserRef | 否 | Comments and discussions only: the last member other than the author who edited the title or body (the author's own later edits keep it); null when only the author edited it. |
trashed_by | UserRef | 否 | Comments and discussions only: the member other than the author who trashed it; null otherwise (cleared by the author's own trash and on restore). A comment with status "trashed" and a trashed_by is a placeholder in GET .../recordings/:id/comments — its title and content are empty. |
recordable_id | string (uuid) | 是 | The schedules row id. |
starts_at | string (date-time) | 是 | Start instant (UTC). All-day events start at 00:00 in time_zone. |
ends_at | string (date-time) | 是 | End instant (UTC), EXCLUSIVE. |
all_day | boolean | 是 | |
time_zone | string | 是 | IANA time zone the event is defined in. |
starts_on | string (date) | null | 是 | All-day only — first day (local); null for timed events. |
ends_on | string (date) | null | 是 | All-day only — last day (local), INCLUSIVE; null for timed events. |
location | string | null | 是 | |
link | string | null | 是 | Meeting / live link (https). |
participants | UserRef[] | 是 | |
participant_ids | string (uuid)[] | 是 | User UUIDs of participants, same order as participants. |
participants_version | string | 是 | Opaque participant snapshot token for replacement writes. |
project | ProjectSummary | 是 | |
series_id | string (uuid) | null | 否 | |
recurrence | ScheduleRecurrence | 否 | Calendar-date rule in the event timezone. Daily/weekly/monthly/yearly; invalid month-end or leap dates are skipped. until is inclusive, count includes the first occurrence. Specify at most one of until/count. Open-ended series materialize one year ahead and renew daily. On a schedule it is the rule the series still follows: once the series is stopped (PATCH edit_scope=following with recurrence null, or DELETE edit_scope=following), the meetings it kept report the shortened rule — count becomes the number of kept meetings (count and open-ended rules), until becomes the last kept meeting's date (until rules) — and null when no meeting of the series was kept. |
detached | boolean | 否 | This occurrence was individually changed or cancelled. |
occurrence_number | integer | null | 否 |
CalendarFeed
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string (uuid) | 是 | |
name | string | 是 | |
scope | mine | all | members | 是 | |
project_ids | string (uuid)[] | 是 | |
member_ids | string (uuid)[] | 是 | |
include_tasks | boolean | 是 | |
created_at | string (date-time) | 是 | |
subscription_path | string | null | 是 | Token-bearing relative ICS URL; returned only on creation/rotation. Store privately; listing returns null. |
Goal
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string (uuid) | 是 | |
public_id | string | null | 否 | |
legacy_id | string | null | 是 | |
title | string | 是 | |
content_html | string | null | 否 | |
content_json | object | null | 否 | |
content_markdown | string | null | 否 | Canonical body (GFM). content_html is rendered server-side from it; null on rows not yet migrated from Tiptap JSON. |
content_version | integer | 否 | Body version for compare-and-set saves. Starts at 0 and increases by one each time content_markdown / content_html / content_json actually changes (any write path). Send it back as recording.content_version when saving a body edit. |
preview_text | string | 否 | Lists only. The body as plain text (HTML tags removed, entities left encoded, e.g. "&"), cut to 80 UTF-16 units; "" without a body. |
excerpt | string | null | 否 | Lists only. Up to 100 characters of the body's text, images and videos shown as [图片] / [视频]; null without a body. |
preview_html | string | 否 | Document lists only. The first 3000 characters of content_html (may end inside a tag), for thumbnails. |
comments_count | integer | 是 | |
type | string | 是 | |
status | draft | active | archived | trashed | 是 | |
recordable_type | Goal | 是 | |
app_url | string | null | 是 | |
account_id | string (uuid) | 是 | |
account_public_id | string | 是 | |
project_id | string (uuid) | 是 | |
project_public_id | string | 是 | |
creator_id | string (uuid) | 是 | |
parent_id | string (uuid) | null | 否 | |
parent_public_id | string | null | 否 | |
ancestors | FolderCrumb[] | 否 | |
created_at | string (date-time) | 是 | |
updated_at | string (date-time) | 是 | Last change of the recording or of its body, whichever is later. |
reactions | Reaction[] | 是 | |
edited_by | UserRef | 否 | Comments and discussions only: the last member other than the author who edited the title or body (the author's own later edits keep it); null when only the author edited it. |
trashed_by | UserRef | 否 | Comments and discussions only: the member other than the author who trashed it; null otherwise (cleared by the author's own trash and on restore). A comment with status "trashed" and a trashed_by is a placeholder in GET .../recordings/:id/comments — its title and content are empty. |
starting | integer | 是 | |
target | integer | 是 | |
current | integer | 是 |
FolderCrumb
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string (uuid) | 是 | |
public_id | string | null | 是 | |
title | string | 是 |
Reaction
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string (uuid) | 是 | |
actor_id | string (uuid) | 是 | |
reactable_id | string (uuid) | 是 | |
reactable_type | string | 是 | |
reaction_type_id | string (uuid) | 是 | |
reaction_emoji | string | 是 | |
reaction_name | string | 是 | |
created_at | string (date-time) | 是 | |
updated_at | string (date-time) | 是 |
UserRef
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string (uuid) | 是 | User UUID. |
public_id | string | null | 是 | Member ref ("U12") in this account. |
name | string | null | 是 | |
avatar_url | string | null | 是 | |
kind | human | agent | null | 是 | null only for an unknown (deleted) user. |
ProjectSummary
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string (uuid) | 是 | |
public_id | string | 是 | |
name | string | 是 | |
icon | string | null | 是 |
ScheduleRecurrence
Calendar-date rule in the event timezone. Daily/weekly/monthly/yearly; invalid month-end or leap dates are skipped. until is inclusive, count includes the first occurrence. Specify at most one of until/count. Open-ended series materialize one year ahead and renew daily. On a schedule it is the rule the series still follows: once the series is stopped (PATCH edit_scope=following with recurrence null, or DELETE edit_scope=following), the meetings it kept report the shortened rule — count becomes the number of kept meetings (count and open-ended rules), until becomes the last kept meeting's date (until rules) — and null when no meeting of the series was kept.
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
freq | string | 否 | |
interval | integer | 否 | 1–365; defaults to 1. |
by_weekday | integer[] | 否 | Weekly only. 0=Sunday to 6=Saturday; must include the initial weekday. |
until | string | null | 否 | Inclusive YYYY-MM-DD; not before the first occurrence. |
count | integer | null | 否 | 1–1000 occurrences. |