## 当前状态 - 插件界面已完成重命名 (cursorpro → hummingbird) - 双账号池 UI 已实现 (Auto/Pro 卡片) - 后端已切换到 MySQL 数据库 - 添加了 Cursor 官方用量 API 文档 ## 已知问题 (待修复) 1. 激活时检查账号导致无账号时激活失败 2. 未启用无感换号时不应获取账号 3. 账号用量模块不显示 (seamless 未启用时应隐藏) 4. 积分显示为 0 (后端未正确返回) 5. Auto/Pro 双密钥逻辑混乱,状态不同步 6. 账号添加后无自动分析功能 ## 下一版本计划 - 重构数据模型,优化账号状态管理 - 实现 Cursor API 自动分析账号 - 修复激活流程,不依赖账号 - 启用无感时才分配账号 - 完善账号用量实时显示 ## 文件说明 - docs/系统设计文档.md - 完整架构设计 - cursor 官方用量接口.md - Cursor API 文档 - 参考计费/ - Vibeviewer 开源项目参考 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
9.7 KiB
9.7 KiB
Cursor 官方用量接口文档
来源:Vibeviewer 项目逆向分析
基础配置
| 配置项 | 值 |
|---|---|
| Base URL | https://cursor.com |
| 认证方式 | Cookie Header |
通用 Headers
accept: */*
content-type: application/json
origin: https://cursor.com
referer: https://cursor.com/dashboard
Cookie: <用户登录后的Cookie>
API 接口
1. 获取用户信息
GET /api/dashboard/get-me
请求参数: 无 (仅需 Cookie)
响应示例:
{
"authId": "auth_xxxxx",
"userId": 12345,
"email": "user@example.com",
"workosId": "workos_xxxxx",
"teamId": 67890,
"isEnterpriseUser": false
}
字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| authId | String | 认证 ID |
| userId | Int | 用户 ID |
| String | 用户邮箱 | |
| workosId | String | WorkOS ID |
| teamId | Int? | 团队 ID (个人用户为 null) |
| isEnterpriseUser | Bool | 是否企业用户 |
2. 获取用量摘要
GET /api/usage-summary
请求参数: 无 (仅需 Cookie)
响应示例:
{
"billingCycleStart": "2024-01-01T00:00:00.000Z",
"billingCycleEnd": "2024-02-01T00:00:00.000Z",
"membershipType": "pro",
"limitType": "usage_based",
"individualUsage": {
"plan": {
"used": 150,
"limit": 500,
"remaining": 350,
"breakdown": {
"included": 500,
"bonus": 0,
"total": 500
}
},
"onDemand": {
"used": 0,
"limit": null,
"remaining": null,
"enabled": false
}
},
"teamUsage": {
"onDemand": {
"used": 0,
"limit": 10000,
"remaining": 10000,
"enabled": true
}
}
}
会员类型 (membershipType):
| 值 | 说明 | 订阅名称 | 模型 | 套餐额度 |
|---|---|---|---|---|
free |
免费版 | free |
default |
~0 |
free_trial |
Pro 试用 | pro-free-trial |
gpt-5.2-high |
1000 |
pro |
Pro 会员 | pro |
高级模型 | 更高 |
business |
商业版 | business |
企业级 | 无限 |
重要: free_trial 是 Pro 试用账号,拥有完整 Pro 功能,只是有时间限制!
free_trial 特点:
customSubscriptionName:pro-free-trial- 可用模型:
gpt-5.2-high等高级模型 - 套餐额度: 1000 (与 Pro 相同)
- 计费周期: 7天试用期
daysRemainingOnTrial: 试用剩余天数
3. 获取当前计费周期
POST /api/dashboard/get-current-billing-cycle
请求体:
{}
响应示例:
{
"startDateEpochMillis": "1704067200000",
"endDateEpochMillis": "1706745600000"
}
字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| startDateEpochMillis | String | 计费周期开始时间 (毫秒时间戳) |
| endDateEpochMillis | String | 计费周期结束时间 (毫秒时间戳) |
4. 获取过滤后的使用事件
POST /api/dashboard/get-filtered-usage-events
请求体:
{
"startDate": "1704067200000",
"endDate": "1706745600000",
"userId": 12345,
"page": 1,
"pageSize": 100
}
请求参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| startDate | String | 是 | 开始时间 (毫秒时间戳字符串) |
| endDate | String | 是 | 结束时间 (毫秒时间戳字符串) |
| userId | Int | 是 | 用户 ID |
| page | Int | 是 | 页码 (从 1 开始) |
| pageSize | Int | 是 | 每页数量 (建议 100) |
响应示例:
{
"totalUsageEventsCount": 256,
"usageEventsDisplay": [
{
"timestamp": "1704500000000",
"model": "gpt-4",
"kind": "chat",
"requestsCosts": 0.05,
"usageBasedCosts": "$0.05",
"isTokenBasedCall": true,
"owningUser": "user@example.com",
"cursorTokenFee": 0.0,
"tokenUsage": {
"inputTokens": 1500,
"outputTokens": 800,
"totalCents": 5.0,
"cacheWriteTokens": 0,
"cacheReadTokens": 200
}
}
]
}
事件字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| timestamp | String | 事件时间 (毫秒时间戳) |
| model | String | 使用的模型名称 |
| kind | String | 请求类型 (chat/completion 等) |
| requestsCosts | Double? | 请求费用 |
| usageBasedCosts | String | 费用显示字符串 (如 "$0.05") |
| isTokenBasedCall | Bool | 是否按 Token 计费 |
| owningUser | String | 用户邮箱 |
| cursorTokenFee | Double | Cursor Token 费用 |
| tokenUsage | Object | Token 使用详情 |
tokenUsage 字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| inputTokens | Int? | 输入 Token 数 |
| outputTokens | Int? | 输出 Token 数 |
| totalCents | Double? | 总费用 (美分) |
| cacheWriteTokens | Int? | 缓存写入 Token 数 |
| cacheReadTokens | Int? | 缓存读取 Token 数 |
5. 获取聚合使用事件
POST /api/dashboard/get-aggregated-usage-events
请求体:
{
"teamId": 67890,
"startDate": 1704067200000
}
请求参数说明:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| teamId | Int? | 否 | 团队 ID (Pro 个人账号传 null) |
| startDate | Int64 | 是 | 开始时间 (毫秒时间戳,数字类型) |
响应示例:
{
"aggregations": [
{
"modelIntent": "gpt-4",
"inputTokens": "150000",
"outputTokens": "75000",
"cacheWriteTokens": "0",
"cacheReadTokens": "5000",
"totalCents": 250.5
},
{
"modelIntent": "claude-3-sonnet",
"inputTokens": "80000",
"outputTokens": "40000",
"cacheWriteTokens": "0",
"cacheReadTokens": "2000",
"totalCents": 120.0
}
],
"totalInputTokens": "230000",
"totalOutputTokens": "115000",
"totalCacheWriteTokens": "0",
"totalCacheReadTokens": "7000",
"totalCostCents": 370.5
}
聚合字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| modelIntent | String | 模型名称 |
| inputTokens | String | 输入 Token 总数 |
| outputTokens | String | 输出 Token 总数 |
| cacheWriteTokens | String | 缓存写入 Token 总数 |
| cacheReadTokens | String | 缓存读取 Token 总数 |
| totalCents | Double | 该模型总费用 (美分) |
重要字段说明
totalUsageEventsCount (总请求次数)
这个字段在 get-filtered-usage-events 接口返回,表示计费周期内的总请求/对话次数。
{
"totalUsageEventsCount": 6, // 总请求次数
"usageEventsDisplay": [...]
}
用途:
- 统计用户使用频率
- 计费系统中的请求次数限制
- 账号活跃度判断
6. 获取团队成员消费 (Team Plan)
POST /api/dashboard/get-team-spend
请求体:
{
"teamId": 67890,
"page": 1,
"pageSize": 100,
"sortBy": "name",
"sortDirection": "asc"
}
用途: 获取团队各成员的消费情况,用于计算免费额度
7. 获取团队模型分析 (Team Plan)
POST /api/dashboard/get-team-models-analytics
请求体:
{
"startDate": "2024-01-01",
"endDate": "2024-01-07",
"c": "team_id"
}
用途: 获取团队模型使用分析数据
使用示例
JavaScript/Node.js
const axios = require('axios');
const cookie = 'your_cookie_here';
// 获取用户信息
async function getMe() {
const res = await axios.get('https://cursor.com/api/dashboard/get-me', {
headers: {
'Cookie': cookie,
'accept': '*/*',
'referer': 'https://cursor.com/dashboard'
}
});
return res.data;
}
// 获取用量摘要
async function getUsageSummary() {
const res = await axios.get('https://cursor.com/api/usage-summary', {
headers: {
'Cookie': cookie,
'accept': '*/*',
'referer': 'https://cursor.com/dashboard?tab=usage'
}
});
return res.data;
}
// 获取使用事件
async function getFilteredUsageEvents(userId, startDate, endDate, page = 1) {
const res = await axios.post(
'https://cursor.com/api/dashboard/get-filtered-usage-events',
{
startDate: startDate,
endDate: endDate,
userId: userId,
page: page,
pageSize: 100
},
{
headers: {
'Cookie': cookie,
'Content-Type': 'application/json',
'accept': '*/*',
'origin': 'https://cursor.com',
'referer': 'https://cursor.com/dashboard'
}
}
);
return res.data;
}
Python
import requests
cookie = 'your_cookie_here'
headers = {
'Cookie': cookie,
'accept': '*/*',
'content-type': 'application/json',
'origin': 'https://cursor.com',
'referer': 'https://cursor.com/dashboard'
}
# 获取用户信息
def get_me():
res = requests.get('https://cursor.com/api/dashboard/get-me', headers=headers)
return res.json()
# 获取用量摘要
def get_usage_summary():
res = requests.get('https://cursor.com/api/usage-summary', headers=headers)
return res.json()
# 获取使用事件
def get_filtered_usage_events(user_id, start_date, end_date, page=1):
data = {
'startDate': start_date,
'endDate': end_date,
'userId': user_id,
'page': page,
'pageSize': 100
}
res = requests.post(
'https://cursor.com/api/dashboard/get-filtered-usage-events',
json=data,
headers=headers
)
return res.json()
注意事项
- Cookie 获取: 需要从浏览器登录 Cursor Dashboard 后获取 Cookie
- 时间戳格式: 大部分接口使用毫秒时间戳,注意区分字符串和数字类型
- 分页:
get-filtered-usage-events支持分页,每页最多 100 条 - 账号类型: 部分接口 (如 team-spend) 仅适用于团队账号
- 费用单位:
totalCents字段单位为美分,需除以 100 得到美元
更新日志
- 2024-12: 初始版本,来源 Vibeviewer 项目