开放 API

星课程表的开放 API 让你的脚本、第三方插件或自动化工具能用 HTTP 请求读取自己的课表、备忘录和课堂笔记,也可以在获得伙伴关系授权后查询伙伴的固定课表并比对共同空闲时间。 鉴权基于「应用密码」 —— 在「我的 → 开放 API」生成,可独立删除 / 旋转,不影响登录密码。

HTTP Basic Auth

用户名 = 你的星 ID,密码 = 在网页 / App 生成的应用密码。

独立可吊销

一个帐号最多 5 个,随时旋转 / 删除,旧密码立刻失效。

伙伴授权

只读取已接受伙伴关系,伙伴课表仅限对方当前固定课表。

限速 60/分钟

单密码每分钟 60 次,超出返 429。

鉴权

所有 /v1/open/* 接口都要求带 HTTP Basic Auth:

Authorization: Basic base64("星ID:应用密码")

`curl` 直接传 `-u` 参数会自动完成 base64 编码:

curl -u "你的星ID:你的应用密码" \
  https://starschedule.xingqingchuang.com/api/v1/open/schedules

鉴权失败统一返 401 + { code: 401, message, data: null },响应头带 WWW-Authenticate: Basic。备忘录、课堂笔记、伙伴课表和空闲时间接口使用同一个应用密码即可访问,数据范围始终限定在当前帐号自己的数据(伙伴数据仅限已接受的伙伴关系)。

权限

应用密码默认带 read 权限,覆盖所有读取接口。勾选写入权限后可新建、修改、删除备忘录、待办和笔记;只读密码写入会被拒绝(403)。

  • read — 读取你自己的课表、备忘录、笔记、成绩与校园数据。
  • write:daily — 另外可以新建、修改、删除你的备忘录、待办和课堂笔记。
OpenAPI 描述文件

下面每个接口都由服务端自己的函数注册表生成 OpenAPI 3.1 描述,不会与实现脱节。可以直接把客户端生成器指向它,也可以自己阅读。

openapi.json

端点

GET/v1/open/schedules
列出当前帐号下所有未删除的课表。
响应示例
{
  "code": 0,
  "message": "ok",
  "data": {
    "schedules": [
      { "uid": "abcd1234...", "name": "2025 春季" },
      { "uid": "efgh5678...", "name": "实习课表" }
    ]
  }
}
GET/v1/open/schedules/{uid}
读取单张课表的详细数据。
参数
  • include(query)— 逗号分隔的子段。可选 courses / adjustments / exams / clubs。不传 = 全部。
  • uid(path)— 上一接口里返回的 schedule uid。
响应示例
{
  "code": 0,
  "message": "ok",
  "data": {
    "schedule": {
      "uid": "abcd1234...",
      "name": "2025 春季",
      "term": {
        "uid": "term-...",
        "name": "2024-2025 第二学期",
        "startDate": "2025-02-24",
        "totalWeeks": 18
      },
      "courses": [ /* course_uid, name, color, credit, note ... */ ],
      "courseSessions": [ /* weekday, start/end section, start/end week, location, teacher ... */ ],
      "temporaryAdjustments": [ /* 停课 / 换时间 / 换地点 */ ],
      "exams": [ /* 考试日程 */ ],
      "clubActivities": [ /* 社团活动 */ ]
    },
    "meta": { "include": ["adjustments", "clubs", "courses", "exams"] }
  }
}

扩展端点

GET/v1/open/memos
读取当前帐号的备忘录(日常记录)。
参数
  • from / to(query)— 按日期筛选,格式为 YYYY-MM-DD。
  • updatedSince(query)— 只返回此时间之后更新的记录,便于增量同步。
  • todo(query)— 可选 true / false,按待办状态筛选。
响应示例
{
  "code": 0,
  "message": "ok",
  "data": {
    "items": [
      {
        "uid": "memo-uid",
        "date": "2025-03-12",
        "content": "提交实验报告",
        "color": "#4F46E5",
        "isTodo": true,
        "completedAt": null,
        "deadlineAt": "2025-03-15T23:59:00+08:00",
        "reminderAt": null,
        "createdAt": "2025-03-01T08:00:00Z",
        "updatedAt": "2025-03-12T10:00:00Z"
      }
    ],
    "nextCursor": null
  }
}
GET/v1/open/class-notes
读取当前帐号的课堂笔记,可按课表、课程、课次和上课日期筛选。
参数
  • scheduleUid / courseUid / sessionUid(query)— 可选的课表、课程和课次 UID。只能读取当前帐号自己的数据。
  • occurrenceDate(query)— 按课堂发生日期筛选,格式为 YYYY-MM-DD。
  • include(query)— 可选 assets,topic。assets 返回图片资产元数据(uid / mimeType / sort);图片文件下载暂不通过开放 API 提供。
响应示例
{
  "code": 0,
  "message": "ok",
  "data": {
    "items": [
      {
        "uid": "note-uid",
        "scheduleUid": "schedule-uid",
        "courseUid": "course-uid",
        "sessionUid": "session-uid",
        "occurrenceDate": "2025-03-12",
        "content": "老师强调了递归边界条件。",
        "topic": "算法基础",
        "createdAt": "2025-03-12T15:30:00Z",
        "updatedAt": "2025-03-12T15:40:00Z",
        "assets": []
      }
    ],
    "nextCursor": null
  }
}
GET/v1/open/buddies
列出当前帐号已经建立的伙伴关系。只有已接受的伙伴关系会被返回。
响应示例
{
  "code": 0,
  "message": "ok",
  "data": {
    "items": [
      {
        "linkId": "buddy-link-uid",
        "peer": {
          "sid": "ABC12345",
          "nickname": "小明",
          "school": "某某大学",
          "avatarUrl": null
        },
        "state": "accepted",
        "hasPinnedSchedule": true,
        "updatedAt": "2025-03-09T17:30:00Z"
      }
    ],
    "nextCursor": null
  }
}
GET/v1/open/buddies/{linkId}/schedule
返回伙伴当前固定的课表。不能查询伙伴的其他课表。
参数
  • linkId(path)— 伙伴列表返回的关系 ID,关系必须属于当前帐号且状态为 accepted。
响应示例
{
  "code": 0,
  "message": "ok",
  "data": {
    "buddy": {
      "linkId": "buddy-link-uid",
      "sid": "ABC12345",
      "nickname": "小明"
    },
    "pinnedSchedule": {
      "uid": "schedule-uid",
      "name": "2025 春季",
      "term": {
        "name": "2024-2025 第二学期",
        "startDate": "2025-02-24",
        "totalWeeks": 18
      },
      "courses": [ /* 课程和上课节次 */ ],
      "temporaryAdjustments": [ /* 停课 / 换时间 / 换地点 */ ],
      "timeScheme": { "sections": [ /* 节次时间 */ ] }
    }
  }
}
POST/v1/open/free-time/compare
比对当前帐号与一个或多个伙伴固定课表的共同空闲时间。
参数
  • selfScheduleUid(body)— 当前帐号自己的课表 UID。
  • linkIds(body)— 伙伴关系 ID 列表。服务端自动读取每位伙伴的固定课表,不能传入伙伴 scheduleUid。
  • dateFrom / dateTo(body)— 日期范围,最长 31 天。
响应示例
{
  "code": 0,
  "message": "ok",
  "data": {
    "basis": "section",
    "timezone": "Asia/Shanghai",
    "participantCount": 2,
    "slots": [
      {
        "date": "2025-03-10",
        "weekday": 1,
        "week": 3,
        "startSection": 3,
        "endSection": 4,
        "startTime": "10:10",
        "endTime": "11:50",
        "durationMinutes": 100
      }
    ],
    "warnings": []
  }
}
伙伴课表和空闲时间的安全边界

伙伴接口只允许访问已接受关系。 伙伴课表始终由服务端从对方当前的固定课表解析,不能查询对方其他课表。 空闲时间接口只返回所有参与人的共同空闲时段,不返回谁在什么时候有课、课程名称、教师或地点。 伙伴尚未设置固定课表时,不会使用其他课表代替,接口会跳过该伙伴并在 warnings 中说明。

全部接口

身份:确认密码有效,并查看它拥有的权限。
  • GET /v1/open/me
课表:当前周视图、按日期区间解析调休后的实际上课安排,以及每张课表的课程、学期、时间方案与考试。
  • GET /v1/open/schedules
  • GET /v1/open/schedules/{uid}
  • GET /v1/open/schedules/{uid}/courses
  • GET /v1/open/schedules/{uid}/time-scheme
  • GET /v1/open/schedules/{uid}/adjustments
  • GET /v1/open/schedules/{uid}/exams
  • GET /v1/open/schedules/{uid}/clubs
  • GET /v1/open/terms
  • GET /v1/open/timetable/current
  • GET /v1/open/timetable/occurrences
  • GET /v1/open/exams
  • GET /v1/open/club-activities
日程:备忘录、待办与课堂笔记,支持筛选和增量读取。
  • GET /v1/open/memos
  • GET /v1/open/todos
  • GET /v1/open/class-notes
校园:你的成绩、考勤与课程座位。
  • GET /v1/open/campus
  • GET /v1/open/campus/grades
  • GET /v1/open/campus/attendance
  • GET /v1/open/campus/seats
全量:分区变更摘要,以及一次取回整份同步快照。
  • GET /v1/open/snapshot/summary
  • GET /v1/open/snapshot
学习伙伴:已接受的伙伴关系、对方的固定课表,以及空闲时间对比。
  • GET /v1/open/buddies
  • GET /v1/open/buddies/{linkId}/schedule
  • POST /v1/open/free-time/compare
写入(需要 write:daily):新建、修改、删除你的备忘录、待办和课堂笔记。
  • POST /v1/open/memos
  • PATCH /v1/open/memos/{uid}
  • DELETE /v1/open/memos/{uid}
  • POST /v1/open/todos
  • PATCH /v1/open/todos/{uid}
  • POST /v1/open/todos/{uid}/complete
  • DELETE /v1/open/todos/{uid}
  • POST /v1/open/class-notes
  • PATCH /v1/open/class-notes/{uid}
  • DELETE /v1/open/class-notes/{uid}
限速

每个应用密码 60 次/分钟,滚动窗口。命中限速返 429 + { code: 429, message, data: null },响应头带 RateLimit-* 系列(draft-7)字段说明剩余配额。

如果需要更高频率(例如做面板轮询),建议本地缓存接口结果 + 用 Last-Modified 语义自己降频,而不是反复打 API。

错误码
HTTPcode含义
401401未带凭据 / 星 ID 或密码错误 / 密码已被吊销
404404课表 uid 不存在或属于其他帐号
403403没有对应数据权限,或无权访问该伙伴关系
409409伙伴关系尚未接受(未建立联系);伙伴未设置固定课表时不会报错,而是返回 pinnedSchedule: null 或在比对结果 warnings 中说明
429429单密码超过 60 次/分钟
500500服务端读取课表失败,请稍后重试