{
  "openapi": "3.1.0",
  "info": {
    "title": "StarSchedule Open API",
    "version": "1.0.0",
    "description": "Read your own StarSchedule data — timetables, memos, todos, class notes, grades and campus records — and write your memos, todos and class notes. Authenticate with HTTP Basic: the username is your Star ID and the password is an app password created at /me/open."
  },
  "servers": [
    {
      "url": "https://starschedule-api-ebv1rmj6tk.xingqingchuang.com",
      "description": "Production primary"
    },
    {
      "url": "https://starschedule-api-p75lhpfqm8.xingqingchuang.com",
      "description": "Production standby"
    }
  ],
  "security": [
    {
      "basicAuth": []
    }
  ],
  "tags": [
    {
      "name": "me",
      "description": "The calling credential"
    },
    {
      "name": "schedule",
      "description": "Timetables and their parts"
    },
    {
      "name": "timetable",
      "description": "Resolved timetable views"
    },
    {
      "name": "memo",
      "description": "Memos"
    },
    {
      "name": "todo",
      "description": "Todos"
    },
    {
      "name": "classnote",
      "description": "Class notes"
    },
    {
      "name": "snapshot",
      "description": "The whole sync snapshot"
    },
    {
      "name": "campus",
      "description": "Campus data"
    },
    {
      "name": "exam",
      "description": "Exams"
    },
    {
      "name": "club",
      "description": "Club activities"
    },
    {
      "name": "term",
      "description": "Terms"
    },
    {
      "name": "buddy",
      "description": "Study buddies"
    }
  ],
  "paths": {
    "/v1/open/buddies": {
      "get": {
        "operationId": "openapi_buddy_list",
        "summary": "List the caller's study buddies",
        "description": "The accepted buddy links of the caller, one per peer, with the peer's star id, nickname, school and avatar and whether the peer has a pinned timetable. Peers whose account is gone are left out.",
        "tags": [
          "buddy"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        },
                        "nextCursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "items",
                        "nextCursor"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/buddies/{linkId}/schedule": {
      "get": {
        "operationId": "openapi_buddyschedule_get",
        "summary": "Read a buddy's pinned timetable",
        "description": "A buddy's pinned timetable over an accepted link the caller belongs to: not found, forbidden or not accepted depending on the link, exactly as the open API always answered.",
        "tags": [
          "buddyschedule"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "linkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "buddy": {
                          "type": "object",
                          "additionalProperties": {}
                        },
                        "pinnedSchedule": {
                          "anyOf": [
                            {
                              "type": "object",
                              "additionalProperties": {}
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "pinnedScheduleUpdatedAt": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "pinnedScheduleReason": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "buddy",
                        "pinnedSchedule",
                        "pinnedScheduleUpdatedAt",
                        "pinnedScheduleReason"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/campus": {
      "get": {
        "operationId": "openapi_campus_get",
        "summary": "Read the caller's campus data",
        "description": "The caller's campus section: profiles, saved profile books, terms, grades, attendance and course seats, projected from their own sync snapshot.",
        "tags": [
          "campus"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "campus": {
                          "type": "object",
                          "additionalProperties": {}
                        }
                      },
                      "required": [
                        "campus"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/campus/attendance": {
      "get": {
        "operationId": "openapi_campus_attendance",
        "summary": "Read the caller's campus attendance",
        "description": "考勤 rows of the caller's campus section, straight from their own sync snapshot.",
        "tags": [
          "campus"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "items"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/campus/grades": {
      "get": {
        "operationId": "openapi_campus_grades",
        "summary": "Read the caller's campus grades",
        "description": "成绩 rows of the caller's campus section, straight from their own sync snapshot.",
        "tags": [
          "campus"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "items"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/campus/seats": {
      "get": {
        "operationId": "openapi_campus_seats",
        "summary": "Read the caller's campus course seats",
        "description": "课程座位 rows of the caller's campus section, straight from their own sync snapshot.",
        "tags": [
          "campus"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "items"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/class-notes": {
      "get": {
        "operationId": "openapi_classnote_list",
        "summary": "List the caller's class notes",
        "description": "The caller's class notes, filtered by schedule, course, session and date, optionally with the topic and the attachment list. Answers `{ items, nextCursor: null }`.",
        "tags": [
          "classnote"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "courseUid",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "occurrenceDate",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "scheduleUid",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sessionUid",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "updatedSince",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        },
                        "nextCursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "items",
                        "nextCursor"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "operationId": "openapi_classnote_create",
        "summary": "Create a class note",
        "description": "Creates one class note for a session of the caller's own timetable. The session must exist in the caller's data. Needs write:daily.",
        "tags": [
          "classnote"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "scheduleUid": {},
                  "courseUid": {},
                  "sessionUid": {},
                  "occurrenceDate": {},
                  "content": {}
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "note": {
                          "type": "object",
                          "additionalProperties": {}
                        }
                      },
                      "required": [
                        "note"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/class-notes/{uid}": {
      "delete": {
        "operationId": "openapi_classnote_delete",
        "summary": "Delete a class note",
        "description": "Tombstones one of the caller's own class notes. Needs the write:daily scope.",
        "tags": [
          "classnote"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "uid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "uid": {
                          "type": "string"
                        },
                        "deleted": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "uid",
                        "deleted"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "patch": {
        "operationId": "openapi_classnote_update",
        "summary": "Update a class note",
        "description": "Updates the text of one of the caller's own class notes. Needs the write:daily scope.",
        "tags": [
          "classnote"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "uid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {}
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "note": {
                          "type": "object",
                          "additionalProperties": {}
                        }
                      },
                      "required": [
                        "note"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/club-activities": {
      "get": {
        "operationId": "openapi_club_list",
        "summary": "List the caller's club activities",
        "description": "Every club activity of the caller's timetables, optionally narrowed to a date range.",
        "tags": [
          "club"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "scheduleUid",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        },
                        "nextCursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "items",
                        "nextCursor"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/evaluation/reviews": {
      "get": {
        "operationId": "openapi_review_list",
        "summary": "List the caller's course reviews",
        "description": "The caller's own course reviews in every status, newest first, with the rejection reason when there is one.",
        "tags": [
          "review"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        },
                        "nextCursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "items",
                        "nextCursor"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/exams": {
      "get": {
        "operationId": "openapi_exam_list",
        "summary": "List the caller's exams",
        "description": "Every exam of the caller's timetables, optionally narrowed to a date range on `date`.",
        "tags": [
          "exam"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "scheduleUid",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        },
                        "nextCursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "items",
                        "nextCursor"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/free-time/compare": {
      "post": {
        "operationId": "openapi_freetime_compare",
        "summary": "Compare free time with buddies",
        "description": "The free time slots in a date range where the caller and the named buddies have no class, in section units. A read that is a POST because the request carries a list of link ids.",
        "tags": [
          "freetime"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "selfScheduleUid": {},
                  "linkIds": {},
                  "dateFrom": {},
                  "dateTo": {}
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "basis": {
                          "type": "string"
                        },
                        "timezone": {
                          "type": "string"
                        },
                        "participantCount": {
                          "type": "number"
                        },
                        "slots": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        },
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      },
                      "required": [
                        "basis",
                        "timezone",
                        "participantCount",
                        "slots",
                        "warnings"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/institution/bindings": {
      "get": {
        "operationId": "openapi_institution_bindings",
        "summary": "List the caller's campus bindings",
        "description": "Every active class binding of the caller, with the institution, class, timetables and seat details.",
        "tags": [
          "institution"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "items"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/me": {
      "get": {
        "operationId": "openapi_me_get",
        "summary": "Read the calling credential",
        "description": "The star id, nickname, school and avatar of the account behind the credential, and the scopes the credential carries. The cheapest way for a script to check that its credential works.",
        "tags": [
          "me"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "user": {
                          "type": "object",
                          "properties": {
                            "uid": {
                              "type": "string"
                            },
                            "sid": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "nickname": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "school": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "avatarUrl": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "uid",
                            "sid",
                            "nickname",
                            "school",
                            "avatarUrl"
                          ],
                          "additionalProperties": false
                        },
                        "scopes": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      },
                      "required": [
                        "user",
                        "scopes"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/me/membership": {
      "get": {
        "operationId": "openapi_membership_get",
        "summary": "Read the caller's membership",
        "description": "Whether the caller's account has an active membership, when it started and where it came from.",
        "tags": [
          "membership"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "active": {
                          "type": "boolean"
                        },
                        "activatedAt": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "source": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "orderNo": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "active",
                        "activatedAt",
                        "source",
                        "orderNo"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/me/orders": {
      "get": {
        "operationId": "openapi_order_list",
        "summary": "List the caller's membership orders",
        "description": "The caller's own membership orders, newest first, with status and payment time.",
        "tags": [
          "order"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        },
                        "nextCursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "items",
                        "nextCursor"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/me/referral": {
      "get": {
        "operationId": "openapi_referral_get",
        "summary": "Read the caller's referral summary",
        "description": "The caller's own invitations: how many are active, the five newest (masked), and the reward window with days left.",
        "tags": [
          "referral"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "additionalProperties": {},
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/memos": {
      "get": {
        "operationId": "openapi_memo_list",
        "summary": "List the caller's memos",
        "description": "The caller's timetable memos, filtered by date range, update time and the todo flag. Answers `{ items, nextCursor: null }`.",
        "tags": [
          "memo"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "todo",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "updatedSince",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        },
                        "nextCursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "items",
                        "nextCursor"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "operationId": "openapi_memo_create",
        "summary": "Create a memo",
        "description": "Creates one memo (or todo) in the caller's own data and returns it. Needs the write:daily scope.",
        "tags": [
          "memo"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "date": {},
                  "content": {},
                  "color": {},
                  "isTodo": {},
                  "deadlineAt": {},
                  "reminderAt": {},
                  "completed": {}
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "memo": {
                          "type": "object",
                          "additionalProperties": {}
                        }
                      },
                      "required": [
                        "memo"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/memos/{uid}": {
      "delete": {
        "operationId": "openapi_memo_delete",
        "summary": "Delete a memo",
        "description": "Tombstones one of the caller's own memos. Needs the write:daily scope.",
        "tags": [
          "memo"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "uid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "uid": {
                          "type": "string"
                        },
                        "deleted": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "uid",
                        "deleted"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "patch": {
        "operationId": "openapi_memo_update",
        "summary": "Update a memo",
        "description": "Updates one of the caller's own memos; only the fields sent move. Needs the write:daily scope.",
        "tags": [
          "memo"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "uid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "date": {},
                  "content": {},
                  "color": {},
                  "isTodo": {},
                  "deadlineAt": {},
                  "reminderAt": {},
                  "completed": {}
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "memo": {
                          "type": "object",
                          "additionalProperties": {}
                        }
                      },
                      "required": [
                        "memo"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/notifications": {
      "get": {
        "operationId": "openapi_notification_list",
        "summary": "List the caller's notifications",
        "description": "The notices delivered to the caller by the institutions they belong to, newest first, with the source named in the caller's language. `unreadOnly=true` keeps the ones never read.",
        "tags": [
          "notification"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "unreadOnly",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        },
                        "nextCursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "items",
                        "nextCursor"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/schedules": {
      "get": {
        "operationId": "openapi_schedule_list",
        "summary": "List the caller's timetables",
        "description": "The open API's list of the caller's timetables, one `{ uid, name }` per timetable that is not deleted. The caller is the Basic-auth credential the route verified.",
        "tags": [
          "schedule"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "schedules": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "schedules"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/schedules/{uid}": {
      "get": {
        "operationId": "openapi_schedule_get",
        "summary": "Read one timetable",
        "description": "One of the caller's timetables with the parts the `include` query asks for (courses, adjustments, exams, clubs; all by default). An unknown uid is not found.",
        "tags": [
          "schedule"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "uid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "schedule": {
                          "type": "object",
                          "additionalProperties": {}
                        },
                        "meta": {
                          "type": "object",
                          "additionalProperties": {}
                        }
                      },
                      "required": [
                        "schedule",
                        "meta"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/schedules/{uid}/adjustments": {
      "get": {
        "operationId": "openapi_schedule_adjustments",
        "summary": "List a timetable's adjustments",
        "description": "The 调休 / 停课 rows of one timetable, newest first.",
        "tags": [
          "schedule"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "uid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "items"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/schedules/{uid}/clubs": {
      "get": {
        "operationId": "openapi_schedule_clubs",
        "summary": "List a timetable's club activities",
        "description": "The club-activity rows of one timetable, as the sync snapshot stores them.",
        "tags": [
          "schedule"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "uid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "items"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/schedules/{uid}/courses": {
      "get": {
        "operationId": "openapi_schedule_courses",
        "summary": "List a timetable's courses",
        "description": "The courses of one timetable with their sessions, in the open API's camelCase shape.",
        "tags": [
          "schedule"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "uid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "items"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/schedules/{uid}/exams": {
      "get": {
        "operationId": "openapi_schedule_exams",
        "summary": "List a timetable's exams",
        "description": "The exam rows of one timetable, as the sync snapshot stores them.",
        "tags": [
          "schedule"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "uid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "items"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/schedules/{uid}/time-scheme": {
      "get": {
        "operationId": "openapi_schedule_timescheme",
        "summary": "Read a timetable's time scheme",
        "description": "The section start and end times bound to one timetable, or an empty list when none is bound.",
        "tags": [
          "schedule"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "uid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "sections": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "sections"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/share/{token}": {
      "get": {
        "operationId": "openapi_share_get",
        "summary": "Read a shared timetable",
        "description": "The timetable behind a share code, and counts one use. An unknown or expired code is not an error: the answer says it expired. The owner's identity never leaves the server.",
        "tags": [
          "share"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "additionalProperties": {},
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/snapshot": {
      "get": {
        "operationId": "openapi_snapshot_get",
        "summary": "Read the caller's whole sync snapshot",
        "description": "The caller's entire personal data as the sync snapshot holds it (timetables, courses, exams, clubs, memos, notes and the campus section). Large: prefer the per-resource endpoints, or `snapshot/summary` first.",
        "tags": [
          "snapshot"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "snapshot": {
                          "type": "object",
                          "additionalProperties": {}
                        }
                      },
                      "required": [
                        "snapshot"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/snapshot/summary": {
      "get": {
        "operationId": "openapi_snapshot_summary",
        "summary": "Summarise the caller's sync snapshot",
        "description": "For every section of the sync snapshot: how many rows it holds and the newest update time. Poll this and fetch the full snapshot only when something moved.",
        "tags": [
          "snapshot"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "sections": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "object",
                            "properties": {
                              "count": {
                                "type": "number"
                              },
                              "updatedAt": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "count",
                              "updatedAt"
                            ],
                            "additionalProperties": false
                          }
                        }
                      },
                      "required": [
                        "sections"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/terms": {
      "get": {
        "operationId": "openapi_term_list",
        "summary": "List the caller's terms",
        "description": "The caller's terms (学期) with their start date and total weeks.",
        "tags": [
          "term"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "items"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/timetable/current": {
      "get": {
        "operationId": "openapi_timetable_current",
        "summary": "Read the current timetable view",
        "description": "One schedule (the requested one, else the newest) with its courses, exams and notes, plus the current week, the term start and the total weeks. What a widget or a dashboard needs in one call.",
        "tags": [
          "timetable"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "scheduleUid",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "schedule": {
                          "type": "object",
                          "additionalProperties": {}
                        },
                        "currentWeek": {
                          "type": "number"
                        },
                        "weekStartPref": {
                          "type": "number",
                          "enum": [
                            1,
                            7
                          ]
                        },
                        "termStart": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "totalWeeks": {
                          "type": "number"
                        },
                        "schedules": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "schedule",
                        "currentWeek",
                        "weekStartPref",
                        "termStart",
                        "totalWeeks",
                        "schedules"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/timetable/occurrences": {
      "get": {
        "operationId": "openapi_timetable_occurrences",
        "summary": "Read the timetable occurrences in a date range",
        "description": "Every class between `from` and `to` (at most 62 days), one entry per occurrence, with the 调休 / 停课 adjustments applied: a moved session appears on its new day and a cancelled one is marked `canceled`.",
        "tags": [
          "timetable"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "scheduleUid",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "timezone": {
                          "type": "string"
                        },
                        "scheduleUid": {
                          "type": "string"
                        },
                        "from": {
                          "type": "string"
                        },
                        "to": {
                          "type": "string"
                        },
                        "occurrences": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        }
                      },
                      "required": [
                        "timezone",
                        "scheduleUid",
                        "from",
                        "to",
                        "occurrences"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/todos": {
      "get": {
        "operationId": "openapi_todo_list",
        "summary": "List the caller's todos",
        "description": "The caller's memos that are todos, filtered by date range, completion and update time, with deadline and reminder times.",
        "tags": [
          "todo"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "completed",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "updatedSince",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": {}
                          }
                        },
                        "nextCursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "items",
                        "nextCursor"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "post": {
        "operationId": "openapi_todo_create",
        "summary": "Create a todo",
        "description": "Creates one todo in the caller's own data. Needs the write:daily scope.",
        "tags": [
          "todo"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "date": {},
                  "content": {},
                  "color": {},
                  "isTodo": {},
                  "deadlineAt": {},
                  "reminderAt": {},
                  "completed": {}
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "memo": {
                          "type": "object",
                          "additionalProperties": {}
                        }
                      },
                      "required": [
                        "memo"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/todos/{uid}": {
      "delete": {
        "operationId": "openapi_todo_delete",
        "summary": "Delete a todo",
        "description": "Tombstones one of the caller's own todos. Needs the write:daily scope.",
        "tags": [
          "todo"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "uid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "uid": {
                          "type": "string"
                        },
                        "deleted": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "uid",
                        "deleted"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "patch": {
        "operationId": "openapi_todo_update",
        "summary": "Update a todo",
        "description": "Updates one of the caller's own todos. Needs the write:daily scope.",
        "tags": [
          "todo"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "uid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "date": {},
                  "content": {},
                  "color": {},
                  "isTodo": {},
                  "deadlineAt": {},
                  "reminderAt": {},
                  "completed": {}
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "memo": {
                          "type": "object",
                          "additionalProperties": {}
                        }
                      },
                      "required": [
                        "memo"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/v1/open/todos/{uid}/complete": {
      "post": {
        "operationId": "openapi_todo_complete",
        "summary": "Complete a todo",
        "description": "Marks one of the caller's own todos done (or not done, with completed=false). Needs write:daily.",
        "tags": [
          "todo"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "uid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "completed": {}
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "const": 0
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "memo": {
                          "type": "object",
                          "additionalProperties": {}
                        }
                      },
                      "required": [
                        "memo"
                      ],
                      "additionalProperties": false,
                      "$schema": "http://json-schema.org/draft-07/schema#"
                    }
                  },
                  "required": [
                    "code",
                    "message",
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "basicAuth": {
        "type": "http",
        "scheme": "basic",
        "description": "Username: your Star ID. Password: an app password created at /me/open. Create one with the `write:daily` scope to use the memo, todo and class-note writes."
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request is not valid.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "integer"
                },
                "message": {
                  "type": "string"
                },
                "data": {
                  "type": "null"
                }
              },
              "required": [
                "code",
                "message",
                "data"
              ]
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or wrong credential.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "integer"
                },
                "message": {
                  "type": "string"
                },
                "data": {
                  "type": "null"
                }
              },
              "required": [
                "code",
                "message",
                "data"
              ]
            }
          }
        }
      },
      "Forbidden": {
        "description": "The credential lacks the scope this endpoint needs.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "integer"
                },
                "message": {
                  "type": "string"
                },
                "data": {
                  "type": "null"
                }
              },
              "required": [
                "code",
                "message",
                "data"
              ]
            }
          }
        }
      },
      "NotFound": {
        "description": "The object does not exist, or is not the caller's.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "integer"
                },
                "message": {
                  "type": "string"
                },
                "data": {
                  "type": "null"
                }
              },
              "required": [
                "code",
                "message",
                "data"
              ]
            }
          }
        }
      },
      "Conflict": {
        "description": "The object is in a state that does not allow this call.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "integer"
                },
                "message": {
                  "type": "string"
                },
                "data": {
                  "type": "null"
                }
              },
              "required": [
                "code",
                "message",
                "data"
              ]
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too many requests; 60 a minute per credential, 20 for the heavy reads.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "integer"
                },
                "message": {
                  "type": "string"
                },
                "data": {
                  "type": "null"
                }
              },
              "required": [
                "code",
                "message",
                "data"
              ]
            }
          }
        }
      },
      "ServerError": {
        "description": "The server could not answer.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "integer"
                },
                "message": {
                  "type": "string"
                },
                "data": {
                  "type": "null"
                }
              },
              "required": [
                "code",
                "message",
                "data"
              ]
            }
          }
        }
      }
    }
  }
}
