{"openapi":"3.0.3","info":{"title":"Calcton API","version":"1.0.0","description":"Calcton 在线计算器门户的公开 API：3960 个计算工具的统一计算内核（/api/v1/calc）、API Key 管理、有用度投票、AI 解题助手（SSE 流式）、真实用户监控上报与搜索推荐。"},"servers":[{"url":"https://www.calcton.com","description":"生产环境"}],"tags":[{"name":"calc","description":"计算内核"},{"name":"keys","description":"API Key 管理"},{"name":"engagement","description":"互动（投票/反馈/订阅）"},{"name":"ai","description":"AI 解题助手"},{"name":"ops","description":"监控与推荐"}],"paths":{"/api/v1/calc":{"post":{"tags":["calc"],"summary":"统一计算端点","description":"调用任一已开放工具的计算内核。未携带 x-api-key 时按 IP 限流（每日 50 次）；携带有效 key 时按 key 日额计。工具清单经 POST /mcp（tools/list）获取。","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["tool"],"properties":{"tool":{"type":"string","example":"bmi","description":"工具 slug"},"arguments":{"type":"object","description":"工具入参（各工具 schema 见 /mcp tools/list）","example":{"weightKg":70,"heightCm":175}}}}}}},"responses":{"200":{"description":"计算成功","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"tool":{"type":"string"},"data":{"type":"object","description":"工具返回结构（含 source 文档链接）"}}}}}},"400":{"description":"未知工具或参数不合法"},"429":{"description":"超出 IP/key 日额"}}}},"/api/v1/keys":{"post":{"tags":["keys"],"summary":"创建 API Key（需登录会话）","description":"请求头携带 x-session（登录 access token）。同一账号每日最多 5 个。","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":40,"example":"我的应用"}}}}}},"responses":{"200":{"description":"返回完整 key（仅此一次展示）"},"401":{"description":"未登录"}}},"get":{"tags":["keys"],"summary":"查询 Key 用量","description":"双模式：携带 x-api-key 时返回该 key 的自检信息（公开语义）；携带 x-session 时列出本人全部 key 与当日用量。","parameters":[{"in":"header","name":"x-api-key","schema":{"type":"string"},"description":"Key 自检模式"},{"in":"header","name":"x-session","schema":{"type":"string"},"description":"登录会话模式"}],"responses":{"200":{"description":"Key 用量信息"},"401":{"description":"凭证缺失或无效"}}},"delete":{"tags":["keys"],"summary":"删除本人 API Key","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["key"],"properties":{"key":{"type":"string"}}}}}},"responses":{"200":{"description":"删除成功"},"401":{"description":"未登录或非本人 key"}}}},"/api/vote":{"get":{"tags":["engagement"],"summary":"查询工具有用度聚合","parameters":[{"in":"query","name":"slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"{ up, down }"}}},"post":{"tags":["engagement"],"summary":"提交有用度投票","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["slug","vote"],"properties":{"slug":{"type":"string"},"vote":{"type":"string","enum":["up","down"]}}}}}},"responses":{"200":{"description":"投票成功（同 IP 同工具幂等）"},"400":{"description":"参数不合法"}}},"delete":{"tags":["engagement"],"summary":"撤销本人对某工具的投票","parameters":[{"in":"query","name":"slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"已撤销"}}}},"/api/feedback":{"post":{"tags":["engagement"],"summary":"工具纠错/建议反馈","description":"详情页「报告问题」弹层提交。同 IP 每分钟 10 次。","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["slug","kind","message"],"properties":{"slug":{"type":"string","description":"工具 slug（须为有效工具）"},"kind":{"type":"string","enum":["calc","text","idea"],"description":"计算错误/文案错误/功能建议"},"message":{"type":"string","minLength":5,"maxLength":500},"contact":{"type":"string","maxLength":80,"description":"可选联系方式"}}}}}},"responses":{"200":{"description":"已收到反馈"},"400":{"description":"slug 无效或字段超限"},"429":{"description":"提交过于频繁"}}}},"/api/newsletter":{"post":{"tags":["engagement"],"summary":"周刊订阅","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}}}}},"responses":{"200":{"description":"订阅成功或已订阅（幂等）"},"400":{"description":"邮箱格式不合法"}}}},"/api/ask":{"post":{"tags":["ai"],"summary":"AI 解题助手（SSE 流式）","description":"三层响应：direct（直答，含表达式精确求值）→ tool（路由到工具内核）→ chat（LLM 流式讲解）。事件序列 meta/delta/done，Content-Type: text/event-stream。","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["question"],"properties":{"question":{"type":"string","maxLength":500,"example":"贷款100万30年利率3.6%月供多少"}}}}}},"responses":{"200":{"description":"SSE 事件流","content":{"text/event-stream":{}}},"400":{"description":"问题为空或超长"}}}},"/api/web-vitals":{"post":{"tags":["ops"],"summary":"RUM 指标上报","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","enum":["LCP","INP","CLS","TTFB","FCP"]},"value":{"type":"number"},"path":{"type":"string"}}}}}},"responses":{"204":{"description":"已记录"}}},"get":{"tags":["ops"],"summary":"RUM 聚合看板数据","responses":{"200":{"description":"近 24h 各指标 p75 与样本量","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/suggest":{"get":{"tags":["ops"],"summary":"路径模糊推荐（404 兜底）","parameters":[{"in":"query","name":"q","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"相近计算器 slug 列表（≤5）","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"score":{"type":"number"}}}}}}}}}}}},"/api/exchange-rate":{"get":{"tags":["ops"],"summary":"实时汇率（ECB 数据源，12h 模块缓存 + 静态兜底）","responses":{"200":{"description":"基准汇率表","content":{"application/json":{"schema":{"type":"object"}}}}}}}}}