{"openapi":"3.1.0","info":{"title":"Tweets Viewer API","description":"推文 / Instagram 归档只读 API。完整说明见仓库 `docs/API_DOCUMENTATION.md`。","version":"3.0.0"},"servers":[{"url":"https://tweet-api.chilfish.top","description":"生产（Cloudflare Workers）"},{"url":"http://localhost:3000","description":"本地开发"}],"tags":[{"name":"Tweets","description":"推文查询"},{"name":"Users","description":"用户信息"},{"name":"Instagram","description":"Instagram 归档"},{"name":"Image","description":"随机图片"},{"name":"Meta","description":"服务状态"}],"components":{"schemas":{"ErrorResponse":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"PaginationMeta":{"type":"object","properties":{"total":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"},"hasMore":{"type":"boolean"},"nextCursor":{"oneOf":[{"type":"integer"},{"type":"string"}]}},"required":["total","page","pageSize","hasMore"]},"EnrichedTweet":{"type":"object","additionalProperties":true,"description":"推文详情（EnrichedTweet）。完整字段见 packages/rettiwt-api/types/enriched。"},"EnrichedUser":{"type":"object","additionalProperties":true,"description":"用户详情（EnrichedUser）。完整字段见 packages/rettiwt-api/types/enriched。"},"PaginatedTweets":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/EnrichedTweet"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["data","meta"]},"EnrichedUserList":{"type":"array","items":{"$ref":"#/components/schemas/EnrichedUser"}},"YearStat":{"type":"object","properties":{"year":{"type":"integer"},"count":{"type":"integer"}},"required":["year","count"]},"TweetsYearStats":{"type":"array","items":{"$ref":"#/components/schemas/YearStat"},"description":"按年份降序的推文数量统计"},"IGMedia":{"type":"object","properties":{"num":{"type":"integer","description":"在帖子里的序号"},"media_id":{"type":"string"},"shortcode":{"type":"string"},"display_url":{"type":"string","description":"图片/视频缩略图 CDN URL"},"video_url":{"oneOf":[{"type":"string"},{"type":"null"}]},"width":{"type":"integer"},"height":{"type":"integer"},"width_original":{"type":"integer"},"height_original":{"type":"integer"},"type":{"type":"string","enum":["photo","video"]},"tagged_users":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"username":{"type":"string"},"full_name":{"type":"string"}},"required":["id","username","full_name"]}}},"required":["num","media_id","display_url","width","height","type"]},"IGAudio":{"type":"object","properties":{"title":{"type":"string"},"subtitle":{"type":"string"},"artist":{"type":"string"},"duration":{"type":"number"},"cover_artwork_uri":{"type":"string"},"cover_artwork_thumbnail_uri":{"type":"string"},"has_lyrics":{"type":"boolean"},"is_explicit":{"type":"boolean"}}},"IGPost":{"type":"object","properties":{"id":{"type":"string","description":"URL shortcode，作路由主键"},"post_id":{"type":"string"},"url":{"type":"string"},"username":{"type":"string"},"fullname":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"likes":{"type":"integer"},"type":{"type":"string","enum":["post","reel"]},"media":{"type":"array","items":{"$ref":"#/components/schemas/IGMedia"}},"avatar_url":{"type":"string"},"created_at":{"type":"string"},"location_name":{"type":"string"},"coauthors":{"type":"array","items":{"type":"object","properties":{"username":{"type":"string"},"fullname":{"type":"string"}},"required":["username","fullname"]}},"verified":{"type":"boolean"},"audio":{"$ref":"#/components/schemas/IGAudio"}},"required":["id","post_id","url","username","fullname","description","likes","type","media"]},"IGUserInfo":{"type":"object","properties":{"username":{"type":"string"},"fullname":{"type":"string"},"avatar_url":{"type":"string"},"verified":{"type":"boolean"},"bio":{"type":"string"},"external_url":{"type":"string"},"followers_count":{"type":"integer"},"following_count":{"type":"integer"},"posts_count":{"type":"integer"}},"required":["username","fullname"]},"PaginatedIGPosts":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/IGPost"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["data","meta"]},"IGUserPageResponse":{"type":"object","properties":{"user":{"oneOf":[{"$ref":"#/components/schemas/IGUserInfo"},{"type":"null"}]},"posts":{"$ref":"#/components/schemas/PaginatedIGPosts"}},"required":["user","posts"]},"ImageEntry":{"type":"object","properties":{"url":{"type":"string","description":"媒体图片 URL（推文 `media_details[].media_url_https`）"},"tweet":{"$ref":"#/components/schemas/EnrichedTweet"}},"required":["url","tweet"]},"RootStatus":{"type":"object","properties":{"today":{"type":"string"},"message":{"type":"string"},"tweetsSize":{"type":"object","additionalProperties":{"type":"integer"}}},"required":["today","message","tweetsSize"]}}},"paths":{"/":{"get":{"operationId":"getIndex","tags":["Meta"],"summary":"服务状态","description":"返回当前时间与已缓存用户的推文条数。","responses":{"200":{"description":"服务状态","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RootStatus"}}}}}}},"/v3/tweets/get/{name}":{"get":{"operationId":"getV3TweetsGetByName","tags":["Tweets"],"summary":"获取用户推文列表","description":"按用户 Screen Name 分页获取推文，支持日期范围、排除回复与 keyset 游标续载。","parameters":[{"in":"path","name":"name","required":true,"description":"用户 Screen Name（`\\w+`）","schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^\\w+$"}},{"in":"query","name":"page","required":false,"description":"页码（offset 定位，分页器跳页用）","schema":{"type":"integer","minimum":1,"default":1}},{"in":"query","name":"pageSize","required":false,"description":"每页数量（1-100）","schema":{"type":"integer","minimum":1,"maximum":100,"default":10}},{"in":"query","name":"reverse","required":false,"description":"排序方向：true = 旧→新，false = 新→旧（接受 true/false/1/0）","schema":{"type":"boolean","default":false}},{"in":"query","name":"cursor","required":false,"description":"keyset 游标（1-19 位十进制 snowflake 排序键，滚动续载，优先于 page）","schema":{"type":"string","pattern":"^\\d{1,19}$"}},{"in":"query","name":"start","required":false,"description":"起始日期（ISO date；与 end 成对提供，两者同时存在时才在查询中生效）","schema":{"type":"string","format":"date"}},{"in":"query","name":"end","required":false,"description":"结束日期（ISO date）","schema":{"type":"string","format":"date"}},{"in":"query","name":"noReplies","required":false,"description":"是否排除回复推文（接受 true/false/1/0）","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"分页推文列表","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedTweets"}}}},"400":{"description":"错误响应","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v3/tweets/medias/{name}":{"get":{"operationId":"getV3TweetsMediasByName","tags":["Tweets"],"summary":"获取用户媒体推文","description":"获取指定用户所有含图片/视频附件的推文（排除转推）。","parameters":[{"in":"path","name":"name","required":true,"description":"用户 Screen Name（`\\w+`）","schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^\\w+$"}},{"in":"query","name":"page","required":false,"description":"页码（offset 定位，分页器跳页用）","schema":{"type":"integer","minimum":1,"default":1}},{"in":"query","name":"pageSize","required":false,"description":"每页数量（1-100）","schema":{"type":"integer","minimum":1,"maximum":100,"default":10}},{"in":"query","name":"reverse","required":false,"description":"排序方向：true = 旧→新，false = 新→旧（接受 true/false/1/0）","schema":{"type":"boolean","default":false}},{"in":"query","name":"cursor","required":false,"description":"keyset 游标（1-19 位十进制 snowflake 排序键，滚动续载，优先于 page）","schema":{"type":"string","pattern":"^\\d{1,19}$"}},{"in":"query","name":"start","required":false,"description":"起始日期（ISO date；与 end 成对提供，两者同时存在时才在查询中生效）","schema":{"type":"string","format":"date"}},{"in":"query","name":"end","required":false,"description":"结束日期（ISO date）","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"分页媒体推文列表","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedTweets"}}}},"400":{"description":"错误响应","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v3/tweets/stats/{name}":{"get":{"operationId":"getV3TweetsStatsByName","tags":["Tweets"],"summary":"获取用户推文按年统计","description":"归档完整性指示：覆盖年份范围 + 每年条数。","parameters":[{"in":"path","name":"name","required":true,"description":"用户 Screen Name（`\\w+`）","schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^\\w+$"}}],"responses":{"200":{"description":"按年份降序的统计","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TweetsYearStats"}}}},"400":{"description":"错误响应","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v3/tweets/search":{"get":{"operationId":"getV3TweetsSearch","tags":["Tweets"],"summary":"搜索推文","description":"在指定用户或全库范围按关键词搜索推文（`name` 缺省为跨用户全局搜索）。","parameters":[{"in":"query","name":"q","required":true,"description":"搜索关键词（1-200 字符）","schema":{"type":"string","minLength":1,"maxLength":200}},{"in":"query","name":"name","required":false,"description":"限定用户 Screen Name；缺省为全库检索","schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^\\w+$"}},{"in":"query","name":"page","required":false,"description":"页码（offset 定位，分页器跳页用）","schema":{"type":"integer","minimum":1,"default":1}},{"in":"query","name":"pageSize","required":false,"description":"每页数量（1-100）","schema":{"type":"integer","minimum":1,"maximum":100,"default":10}},{"in":"query","name":"reverse","required":false,"description":"排序方向：true = 旧→新，false = 新→旧（接受 true/false/1/0）","schema":{"type":"boolean","default":false}},{"in":"query","name":"cursor","required":false,"description":"keyset 游标（1-19 位十进制 snowflake 排序键，滚动续载，优先于 page）","schema":{"type":"string","pattern":"^\\d{1,19}$"}}],"responses":{"200":{"description":"分页搜索结果","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedTweets"}}}},"400":{"description":"错误响应","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v3/tweets/get/{name}/last-years-today":{"get":{"operationId":"getV3TweetsGetByNameLastYearsToday","tags":["Tweets"],"summary":"获取单用户「那年今日」","description":"指定用户历史年份同一天的推文（保留转推）。","parameters":[{"in":"path","name":"name","required":true,"description":"用户 Screen Name（`\\w+`）","schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^\\w+$"}},{"in":"query","name":"page","required":false,"description":"页码（offset 定位，分页器跳页用）","schema":{"type":"integer","minimum":1,"default":1}},{"in":"query","name":"pageSize","required":false,"description":"每页数量（1-100）","schema":{"type":"integer","minimum":1,"maximum":100,"default":10}},{"in":"query","name":"reverse","required":false,"description":"排序方向：true = 旧→新，false = 新→旧（接受 true/false/1/0）","schema":{"type":"boolean","default":false}},{"in":"query","name":"cursor","required":false,"description":"keyset 游标（1-19 位十进制 snowflake 排序键，滚动续载，优先于 page）","schema":{"type":"string","pattern":"^\\d{1,19}$"}}],"responses":{"200":{"description":"分页「那年今日」推文","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedTweets"}}}},"400":{"description":"错误响应","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v3/tweets/last-years-today":{"get":{"operationId":"getV3TweetsLastYearsToday","tags":["Tweets"],"summary":"获取全量「那年今日」","description":"全部用户历史年份同一天的推文（跨用户，排除转推）。","parameters":[{"in":"query","name":"page","required":false,"description":"页码（offset 定位，分页器跳页用）","schema":{"type":"integer","minimum":1,"default":1}},{"in":"query","name":"pageSize","required":false,"description":"每页数量（1-100）","schema":{"type":"integer","minimum":1,"maximum":100,"default":10}},{"in":"query","name":"reverse","required":false,"description":"排序方向：true = 旧→新，false = 新→旧（接受 true/false/1/0）","schema":{"type":"boolean","default":false}},{"in":"query","name":"cursor","required":false,"description":"keyset 游标（1-19 位十进制 snowflake 排序键，滚动续载，优先于 page）","schema":{"type":"string","pattern":"^\\d{1,19}$"}}],"responses":{"200":{"description":"分页「那年今日」推文","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedTweets"}}}},"400":{"description":"错误响应","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v3/users/all":{"get":{"operationId":"getV3UsersAll","tags":["Users"],"summary":"获取所有用户","description":"数据库中记录的所有用户信息。","responses":{"200":{"description":"用户列表","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichedUserList"}}}}}}},"/v3/users/get/{name}":{"get":{"operationId":"getV3UsersGetByName","tags":["Users"],"summary":"获取指定用户信息","parameters":[{"in":"path","name":"name","required":true,"description":"用户 Screen Name（`\\w+`）","schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^\\w+$"}}],"responses":{"200":{"description":"用户信息","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichedUser"}}}},"404":{"description":"错误响应","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v3/image/get":{"get":{"operationId":"getV3ImageGet","tags":["Image"],"summary":"获取随机图片","description":"从归档推文中随机选取一张媒体图片（排除转推），可选 `name` 限定用户；返回图片链接与来源推文。","parameters":[{"in":"query","name":"name","required":false,"description":"限定用户 Screen Name；缺省为全库","schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^\\w+$"}}],"responses":{"200":{"description":"随机图片条目（图片链接 + 来源推文）","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageEntry"}}}},"400":{"description":"错误响应","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"错误响应","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v3/ins/{name}":{"get":{"operationId":"getV3InsByName","tags":["Instagram"],"summary":"获取 IG 用户信息与帖子","description":"`:name` 为 twitter userName（非 IG 用户名），服务端经 `users.ins_json_data` 映射。","parameters":[{"in":"path","name":"name","required":true,"description":"用户 Screen Name（`\\w+`）","schema":{"type":"string","minLength":1,"maxLength":50,"pattern":"^\\w+$"}},{"in":"query","name":"page","required":false,"description":"页码（offset 定位）","schema":{"type":"integer","minimum":1,"default":1}}],"responses":{"200":{"description":"IG 用户信息 + 分页帖子","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IGUserPageResponse"}}}},"404":{"description":"该用户无 IG 数据且无帖子","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IGUserPageResponse"}}}}}}}}}