开放API
快速开始
独角兽 GEO OpenAPI v1
面向接入方的对外接口文档。当前版本聚焦「品牌数据」的只读查询能力, 覆盖品牌列表、话题、排名概览、趋势、引用与竞品。
1. 基本信息
| 项目 | 说明 |
|---|---|
| Base URL | https://geo.yueyuezi.com/open-api/v1 |
| 协议 | HTTPS |
| 鉴权 | API Key(在「左下角个人中心 → API Key 管理」生成) |
| 限流 | 单密钥 1 QPS,超出返回 429 rate_limited,响应头带 Retry-After |
| 数据更新频率 | 天级(每日定时采集) |
| 字符编码 | UTF-8 |
| 时间格式 | ISO 8601 (RFC3339), UTC |
该 API Key 等价于持有人本人的账号权限,可读品牌、话题等于该账号 名下完全一致的范围,请勿外泄。删除密钥后立即失效。
2. 鉴权
请求头任选一种方式传入密钥:
X-API-Key: <your-api-key>
或
Authorization: Bearer <your-api-key>
密钥本体是 32 位十六进制字符串(在「左下角个人中心 → API Key 管理」生成)。
未携带或密钥无效,返回:
{ "error": { "code": "missing_api_key", "message": "缺少 API Key..." } }
{ "error": { "code": "invalid_api_key", "message": "API Key 无效或已被删除" } }
2.1 切换工作区(可选)
如果你在多个工作区中(自己持有 + 受邀加入),默认按"自己的工作区" 访问。要查看受邀工作区下的品牌数据,请额外传:
X-Active-Workspace: <workspace_owner_user_id>
workspace_owner_user_id 是被邀请工作区所有者的用户 UUID。校验失败
返回 403 workspace_forbidden。
3. 通用响应格式
成功:
{
"data": <object | array>
}
失败:
{
"error": {
"code": "<machine_readable_code>",
"message": "<human_readable_zh>"
}
}
常见错误码:
| HTTP | code | 说明 |
|---|---|---|
| 401 | missing_api_key | 请求未带密钥 |
| 401 | invalid_api_key | 密钥无效或已被删除 |
| 403 | workspace_forbidden | 当前密钥无权访问 X-Active-Workspace 指定的工作区 |
| 403 | brand_forbidden | 品牌不属于当前工作区 |
| 404 | brand_not_found | 品牌不存在或已被软删 |
| 429 | rate_limited | 触发限流,见 Retry-After 头 |
| 500 | internal_error | 服务端异常 |
4. 通用查询参数
涉及时间维度的接口共享以下查询参数(具体接口的支持情况见各章节):
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
days | int | 30 | 最近 N 天(1 ≤ days ≤ 30);超出 30 一律 clamp 到 30 |
from | string | — | 起始日期 YYYY-MM-DD(UTC,包含当日) |
to | string | — | 截止日期 YYYY-MM-DD(UTC,包含当日);from–to 跨度也最多 30 天,超出会自动收紧为 [to-29d, to] |
platform | string | — | 平台过滤,逗号分隔,如 deepseek,doubao(未传则按工作区套餐覆盖的全部平台) |
为什么是 30 天上限? 平台数据是天级更新,30 天足够支撑日级趋势 + 周环比对比;同时平台前端时间筛选器只提供 7/14/30 三档,把 OpenAPI 也对齐到这个范围,既符合"对外接口语义 = 平台展示语义"原则,也避免 接入方拉年度数据导致 SQL 聚合压垮 DB。
支持的 platform 取值:deepseek、doubao、wenxin、kimi、qianwen、yuanbao。
5. 接口列表
5.1 品牌列表
GET /brands
返回当前工作区下的所有品牌(包含已冻结的,以 is_active=false 区分)。
示例响应
{
"data": [
{
"id": "f6c5f69c-1234-4abc-9d77-2b1c0c5fdc8a",
"name": "示例品牌",
"website": "https://example.com",
"description": "做云端数据库的公司",
"is_active": true,
"created_at": "2025-09-01T03:21:11Z",
"updated_at": "2025-12-08T07:02:43Z"
}
]
}
字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string (UUID) | 品牌 ID,用于其它接口的 :id |
| name | string | 品牌展示名 |
| website | string? | 品牌官网,可空 |
| description | string? | 品牌描述,可空 |
| is_active | bool | false 表示已冻结,数据停更 |
| created_at / updated_at | string | RFC3339 时间戳 |
5.2 品牌详情
GET /brands/{brand_id}
返回单个品牌的基础信息(字段集合与 5.1 中的元素一致)。
5.3 话题列表
GET /brands/{brand_id}/topics
示例响应
{
"data": [
{
"id": "9f4c...e1",
"keyword": "云端数据库 推荐",
"topic_type": "industry",
"is_active": true,
"created_at": "2025-09-01T03:25:00Z"
}
]
}
| 字段 | 说明 |
|---|---|
| keyword | 用户在 AI 平台模拟搜索的话题词 |
| topic_type | brand(品牌词) / industry(行业词) |
| is_active | false 时该话题暂停采集 |
5.4 排名概览(按话题)
GET /brands/{brand_id}/overview?days=30
返回过去 N 天该品牌每个话题的滚动统计。与平台前端「品牌数据」页 分话题表的口径对齐(默认 30 天,可传 7/14/30)。
示例响应
{
"data": {
"brand_id": "f6c5f69c-...",
"topics": [
{
"topic_id": "9f4c...e1",
"keyword": "云端数据库 推荐",
"topic_type": "industry",
"snapshot_count": 36,
"platforms_covered": 6,
"last_snapshot_date": "2025-12-08T00:00:00Z",
"avg_brand_rank": 3.2,
"mention_rate_pct": 78.5,
"first_place_rate_pct": 12.7,
"avg_rank_score": 64.3
}
]
}
}
| 字段 | 说明 |
|---|---|
| snapshot_count | 窗口内该话题的快照数 |
| platforms_covered | 窗口内出现过的 AI 平台数 |
| avg_brand_rank | 平均出现位次(null 表示未被提及过) |
| mention_rate_pct | 我方品牌出现率(0–100) |
| first_place_rate_pct | 排在首位的快照占比(0–100) |
| avg_rank_score | 加权排名分(0–100,越大越好;null 表示无样本) |
| last_snapshot_date | 窗口内最后一次采集时间(RFC3339;窗口内无快照则为 null) |
5.5 品牌整体趋势
GET /brands/{brand_id}/trend?days=30
按 (日期 × 平台) 聚合的时间序列,适合画趋势图。
示例响应
{
"data": [
{
"date": "2025-12-07",
"platform": "deepseek",
"mention_rate_pct": 75.0,
"first_place_rate_pct": 12.5,
"avg_rank_score": 62.1,
"snapshot_count": 8
}
]
}
5.6 每日排名位置
GET /brands/{brand_id}/rank-positions?days=30
按 (话题 × 平台 × 日期) 给出当日具体排名,粒度比 5.5 更细。
示例响应
{
"data": [
{
"topic_id": "9f4c...e1",
"keyword": "云端数据库 推荐",
"topic_type": "industry",
"date": "2025-12-07",
"platform": "deepseek",
"brand_rank": 2,
"brand_mentioned": true,
"rank_score": 75.0
}
]
}
| 字段 | 说明 |
|---|---|
| brand_rank | 当日实际位次,null = 未被提及 |
| brand_mentioned | 是否提到我方品牌 |
| rank_score | 当日该 (话题, 平台) 的加权得分 |
5.7 引用来源
GET /brands/{brand_id}/citations?days=30
返回 AI 回答里引用到的外部页面统计(支持 from/to/platform)。
示例响应
{
"data": [
{
"source_name": "知乎",
"source_url": "https://zhuanlan.zhihu.com/p/xxxxx",
"source_domain": "zhuanlan.zhihu.com",
"cite_count": 5,
"keyword": "云端数据库 推荐",
"platform": "deepseek"
}
]
}
source_name 是后台维护的中文展示名(如 mp.weixin.qq.com → 微信公众号),
没维护时回落为域名。
5.8 引用来源汇总
GET /brands/{brand_id}/citations/overview
无时间参数,返回该品牌所有时间累计的引用统计:
{
"data": {
"total_count": 1325,
"source_count": 482,
"domain_count": 113,
"topic_count": 14
}
}
5.9 发现的竞品
GET /brands/{brand_id}/competitors?days=30
聚合 AI 回答里与我方品牌共同出现过的非自有实体,作为隐式竞品候选。
示例响应
{
"data": [
{
"entity_name": "某竞品 A",
"mention_count": 28,
"platform_count": 5,
"avg_position": 1.4,
"first_seen_date": "2025-09-04",
"recent_mentions": 9,
"previous_mentions": 5,
"previous_window_days": 7,
"platform_mentions": { "deepseek": 12, "doubao": 8 },
"daily_trend": [
{ "date": "2025-12-07", "count": 2, "rank_score": 72.0,
"platform_counts": { "deepseek": 1, "doubao": 1 } }
]
}
]
}
| 字段 | 说明 |
|---|---|
| recent_mentions / previous_mentions | 固定 7d / 14d 滚动窗口对比,用于"上升中"提示 |
| platform_mentions | 各平台分项(可空对象) |
| daily_trend | 按日时间序列,平台细分见 platform_counts |
6. 调用示例
curl
curl -H "X-API-Key: $API_KEY" \
"https://geo.yueyuezi.com/open-api/v1/brands"
curl -H "X-API-Key: $API_KEY" \
"https://geo.yueyuezi.com/open-api/v1/brands/<brand_id>/trend?days=14"
Python
import os, requests
API_KEY = os.environ["API_KEY"]
BASE = "https://geo.yueyuezi.com/open-api/v1"
H = {"X-API-Key": API_KEY}
brands = requests.get(f"{BASE}/brands", headers=H, timeout=10).json()["data"]
brand_id = brands[0]["id"]
trend = requests.get(
f"{BASE}/brands/{brand_id}/trend",
headers=H, params={"days": 14}, timeout=10,
).json()["data"]
限流处理
import time
while True:
r = requests.get(url, headers=H)
if r.status_code != 429:
r.raise_for_status()
break
wait = int(r.headers.get("Retry-After", "1"))
time.sleep(wait)
7. 版本与变更
- v1.0(2026-05-09) 首次发布。覆盖品牌列表、话题、排名概览/趋势/位置、 引用来源、发现的竞品。
后续若有 breaking 字段调整会以 /v2 等新前缀发布,旧版本至少维持 6 个月平稳期。
最后更新:2026/05/09