AUTHENTICATION
只支持 Bearer Key
所有 /api/v1/data/ 请求必须发送下面的 Header。Key 不放在 URL、请求体或 Cookie 中。
Authorization: Bearer fds_live_…- 浏览器 session Cookie 不能调用数据 API。
- API Key 不能登录网页或访问 Owner 页面。
- Key 无效、已删除或所属账号被停用时返回 401。
FRIENDS DATA API · V1
按成熟 API 平台的阅读顺序组织:快速开始、认证、端点、分页、PIT、错误、SDK、CLI、MCP、Codex 和 Claude Code。数据含义与逐表字段单独放在数据字典。
OVERVIEW
Base URL 是 https://api.alphahubs.uk。Friends Data API 只借用 alphahubs.uk 域名,不复用 AlphaHub 账号、Cookie、会话或数据权限。浏览器登录负责管理 Key,程序只用 Bearer Key 调用七个公开端点。
“七个端点 / 七个 MCP 工具”不等于只有七张表:HTTP 通用 rows、Python get_dataset_rows、CLI get-dataset-rows 和 MCP get_dataset_rows 都能读取同一份 294 数据集完整目录;另外几个方法只是常用行情和事件的便捷入口。
QUICK START
Authorization: Bearer $FRIENDS_DATA_API_KEYexport FRIENDS_DATA_API_KEY="fds_live_…"
curl --fail-with-body \
-H "Authorization: Bearer $FRIENDS_DATA_API_KEY" \
"https://api.alphahubs.uk/api/v1/data/catalog"import os
import httpx
response = httpx.get(
"https://api.alphahubs.uk/api/v1/data/catalog",
headers={"Authorization": f"Bearer {os.environ['FRIENDS_DATA_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
print(response.json()["data"][0])const response = await fetch(
"https://api.alphahubs.uk/api/v1/data/catalog",
{ headers: { Authorization: `Bearer ${process.env.FRIENDS_DATA_API_KEY}` } },
);
if (!response.ok) throw new Error(await response.text());
const { data, request_id } = await response.json();
console.log(request_id, data);AUTHENTICATION
所有 /api/v1/data/ 请求必须发送下面的 Header。Key 不放在 URL、请求体或 Cookie 中。
Authorization: Bearer fds_live_…KEY LIFECYCLE
LIVE EXPLORER
Key 不写 Cookie 或 localStorage。Explorer 只允许当前域名下的只读 /api/v1/data/ GET 请求。
{
"提示": "粘贴 Key 后发送;这里显示真实响应"
}
API REFERENCE
每个端点都使用相同认证、成功响应和错误响应。未列出的路径或参数不会被转发。
/api/v1/data/catalog数据目录返回当前 Friends Key 可调用的数据集、筛选字段和分页能力。
该端点没有路径或查询参数。
curl --fail-with-body \
-H "Authorization: Bearer $FRIENDS_DATA_API_KEY" \
"https://api.alphahubs.uk/api/v1/data/catalog"async with FriendsDataClient(Settings.from_env()) as client:
page = await client.list_datasets()
print(page.data, page.request_id)friends-data list-datasets{
"arguments": {},
"tool": "list_datasets"
}/api/v1/data/datasets/{namespace}/{dataset}/rows通用数据集读取读取目录内的数据集;大结果集使用响应中的 next_cursor 继续翻页。
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
namespace | path | string | 是 | 数据集命名空间,例如 market |
dataset | path | string | 是 | 数据集名称,例如 ohlcv_1d |
start | query | string | 否 | 含起点的日期或 UTC 时间边界 |
end | query | string | 否 | 含终点的日期或 UTC 时间边界 |
limit | query | integer 1–5000 | 否 | 单页行数;实际上限以 catalog 为准 |
order | query | asc | desc | 否 | 返回顺序;默认以 catalog 契约为准 |
cursor | query | string | 否 | 上一页的 next_cursor,最长 4096 字符 |
catalog filters | query | scalar | 否 | 仅发送该 asset 在 catalog 声明的筛选项 |
curl --fail-with-body \
-H "Authorization: Bearer $FRIENDS_DATA_API_KEY" \
"https://api.alphahubs.uk/api/v1/data/datasets/ref/instrument/rows?limit=3"async with FriendsDataClient(Settings.from_env()) as client:
page = await client.get_dataset_rows('ref', 'instrument', limit=3)
print(page.data, page.request_id)friends-data get-dataset-rows ref instrument --limit 3{
"arguments": {
"dataset": "instrument",
"limit": 3,
"namespace": "ref"
},
"tool": "get_dataset_rows"
}/api/v1/data/instruments/search标的搜索按代码或名称检索可用标的。
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
q | query | string ≤60 | 否 | 股票代码或公司名称;空字符串返回默认候选 |
limit | query | integer 1–50 | 否 | 最多返回条数,默认 12 |
curl --fail-with-body \
-H "Authorization: Bearer $FRIENDS_DATA_API_KEY" \
"https://api.alphahubs.uk/api/v1/data/instruments/search?q=AAPL&limit=5"async with FriendsDataClient(Settings.from_env()) as client:
page = await client.search_instruments('AAPL', limit=5)
print(page.data, page.request_id)friends-data search-instruments --query AAPL --limit 5{
"arguments": {
"limit": 5,
"query": "AAPL"
},
"tool": "search_instruments"
}/api/v1/data/market/quotes最新行情读取一个或多个标的的最新报价。
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
symbols | query | comma-separated | 是 | 1–50 个代码;每个只允许 A-Z 0-9 . _ -,最长 20 |
curl --fail-with-body \
-H "Authorization: Bearer $FRIENDS_DATA_API_KEY" \
"https://api.alphahubs.uk/api/v1/data/market/quotes?symbols=AAPL,MSFT"async with FriendsDataClient(Settings.from_env()) as client:
page = await client.get_market_quotes(['AAPL', 'MSFT'])
print(page.data, page.request_id)friends-data get-market-quotes AAPL MSFT{
"arguments": {
"symbols": [
"AAPL",
"MSFT"
]
},
"tool": "get_market_quotes"
}/api/v1/data/market/candlesK 线读取指定标的和周期的标准化 K 线。
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
symbol | query | string | 是 | 市场代码,字符规则同 quotes |
timeframe | query | 1H | 4H | 1D | 1W | 1M | 否 | K 线周期,默认 1D |
limit | query | integer 1–2000 | 否 | 返回条数,默认 360 |
curl --fail-with-body \
-H "Authorization: Bearer $FRIENDS_DATA_API_KEY" \
"https://api.alphahubs.uk/api/v1/data/market/candles?symbol=AAPL&timeframe=1D&limit=20"async with FriendsDataClient(Settings.from_env()) as client:
page = await client.get_market_candles('AAPL', '1D', 20)
print(page.data, page.request_id)friends-data get-market-candles AAPL --timeframe 1D --limit 20{
"arguments": {
"limit": 20,
"symbol": "AAPL",
"timeframe": "1D"
},
"tool": "get_market_candles"
}/api/v1/data/pit/{namespace}/{dataset}/rowsPoint-in-time 数据按 as_of 边界读取可复现的 PIT 数据集。
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
namespace | path | string | 是 | 支持 PIT 的数据集命名空间 |
dataset | path | string | 是 | 支持 PIT 的数据集名称 |
as_of | query | date or UTC timestamp | 是 | 只返回该时点前已经可知的版本 |
start / end | query | string | 否 | 业务时间范围;与 as_of 的可知时间含义不同 |
limit | query | integer 1–1000 | 否 | 单页行数 |
cursor | query | string | 否 | 上一页的 next_cursor |
instrument_id / code / market | query | scalar | 否 | 证券筛选,以 catalog 声明为准 |
metric / source / period / period_type | query | scalar | 否 | 数据集专用筛选,以 catalog 声明为准 |
curl --fail-with-body \
-H "Authorization: Bearer $FRIENDS_DATA_API_KEY" \
"https://api.alphahubs.uk/api/v1/data/pit/fundamental/income_statement/rows?as_of=2026-08-01&code=AAPL&limit=10"async with FriendsDataClient(Settings.from_env()) as client:
page = await client.get_point_in_time_rows('fundamental', 'income_statement', as_of='2026-08-01', limit=10, filters={'code': 'AAPL'})
print(page.data, page.request_id)friends-data get-point-in-time-rows fundamental income_statement --as-of 2026-08-01 --limit 10 --filter code=AAPL{
"arguments": {
"as_of": "2026-08-01",
"dataset": "income_statement",
"filters": {
"code": "AAPL"
},
"limit": 10,
"namespace": "fundamental"
},
"tool": "get_point_in_time_rows"
}/api/v1/data/event-context/sec-earningsSEC 盈利事件上下文读取经过 Friends 边界裁剪的 SEC earnings 事件上下文。
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
event_ts_from | query | UTC timestamp | 否 | 事件时间含起点 |
event_ts_to | query | UTC timestamp | 否 | 事件时间含终点 |
symbol | query | string ≤30 | 否 | 股票代码 |
source | query | string 1–40 | 否 | 事件来源 |
limit | query | integer 1–1000 | 否 | 单页条数,默认 100 |
cursor | query | string | 否 | 上一页的 next_cursor |
curl --fail-with-body \
-H "Authorization: Bearer $FRIENDS_DATA_API_KEY" \
"https://api.alphahubs.uk/api/v1/data/event-context/sec-earnings?symbol=AAPL&limit=10"async with FriendsDataClient(Settings.from_env()) as client:
page = await client.get_sec_earnings_context(symbol='AAPL', limit=10)
print(page.data, page.request_id)friends-data get-sec-earnings-context --symbol AAPL --limit 10{
"arguments": {
"limit": 10,
"symbol": "AAPL"
},
"tool": "get_sec_earnings_context"
}DECISION MODEL DATA
交易数据与决策模型数据共用 Friends Data API、同一把 API Key 和相同的响应信封。按十个分类浏览家族、产品与字段,再用通用 rows 端点读取。
decision_model/catalogcategory、product、family 筛选;limit 最多 500。decision_model/recordsproduct。可选 period_from、period_to、entity、scope、cursor;limit 最多 500。业务期间按字符串比较,具体口径见产品说明。scope=all 默认读取全部可用快照;scope=latest 读取各来源最新快照。来源不支持该语义时返回 scope_unsupported。行中的 native 是原生对象,native_additions 是字段补充,resolution 标明原生、引用已解析或未解析原因。
/api/v1/data/datasets/decision_model/catalog/rows?category=sports&limit=100从目录取一个 productId,替换下面的 PRODUCT_ID;家族详情页提供已填好产品的示例。
/api/v1/data/datasets/decision_model/records/rows?product=PRODUCT_ID&scope=all&limit=100认证仍使用 Authorization: Bearer <你的 API Key>。响应有 next_cursor 时,用 cursor 继续翻页,保持产品、筛选条件和页大小一致。
SUCCESS ENVELOPE
list{
"object": "list",
"data": [{"instrument_id": 1, "symbol": "AAPL"}],
"has_more": true,
"next_cursor": "eyJ2IjoxLC…",
"request_id": "req_01…",
"meta": {
"dataset": "ref.instrument",
"count": 1,
"as_of": "2026-08-13T00:21:09Z",
"timezone": "UTC"
}
}PAGINATION
cursor。has_more=true 时读取 next_cursor。has_more=false 时结束。Cursor 是不透明且绑定查询的令牌。不要解码、拼接、修改或跨数据集复用。
POINT IN TIME
as_of 控制信息何时已经可知,start/end 控制业务数据日期。两者不是同一概念。
GET /api/v1/data/pit/fundamental/income_statement/rows
?as_of=2026-08-01
&code=AAPL
&limit=100只有数据字典标记 PIT 支持的表可以调用;普通 rows 不能被描述为无前视偏差快照。
ERRORS
| HTTP | 典型 code | 怎么处理 |
|---|---|---|
| 400 | invalid_cursor | 修正业务参数或从第一页重新开始。 |
| 401 | unauthorized | 检查 Bearer Key 是否缺失、错误或已删除。 |
| 403 | forbidden | 当前 Key 无权读取该数据。 |
| 404 | not_found | 检查公开路径、namespace 和 dataset。 |
| 422 | invalid_parameter | 按 param 修正类型、范围或格式。 |
| 429 | rate_limit_exceeded | 等待 Retry-After,不要并发重试。 |
| 503 | dependency_unavailable | 仅在 retryable=true 时指数退避重试。 |
{
"error": {
"type": "invalid_request_error",
"code": "invalid_cursor",
"message": "cursor 无效或已损坏",
"param": "cursor",
"request_id": "req_01…",
"docs_url": "https://api.alphahubs.uk/api/docs#errors",
"retryable": false
}
}RATE LIMITS
通过 Key admission 的响应带 Key 级限流 Header。认证前的 IP 防滥用 429 不代表某把 Key 用尽,因此可能没有 Key 级 Header。客户端最多自动重试两次,并加入抖动。
PYTHON SDK
python3 -m venv .venv-friends
# 先按已发布的 artifact-manifest.json 校验摘要,再安装。
curl --fail -o /tmp/verify-install.sh \
https://api.alphahubs.uk/static/downloads/verify_and_install_friends_artifact.sh
bash /tmp/verify-install.sh wheel 1.1.0 .venv-friends/bin/python
export FRIENDS_DATA_API_KEY="fds_live_…"import asyncio
from friends_data_api import FriendsDataClient, Settings
async def main():
async with FriendsDataClient(Settings.from_env()) as client:
page = await client.get_market_quotes(["AAPL", "MSFT"])
print(page.data, page.request_id)
asyncio.run(main())SDK 对应七个公开方法,保留完整成功/错误契约,并把网络、HTTP、响应校验错误统一为 FriendsDataError。
CLI
friends-data list-datasets
friends-data search-instruments --query "Apple" --limit 5
friends-data get-market-quotes AAPL MSFT
friends-data get-market-candles AAPL --timeframe 1D --limit 100
friends-data get-dataset-rows market ohlcv_1d \
--filter instrument_id=1 --limit 100
friends-data get-point-in-time-rows fundamental income_statement \
--as-of 2026-08-01 --filter instrument_id=1
friends-data get-sec-earnings-context --symbol AAPL --limit 20CLI 把成功 envelope 输出到 stdout,把结构化错误输出到 stderr;错误退出码为 2,适合脚本和 Agent fallback。
MODEL CONTEXT PROTOCOL
| 工具 | 用途 |
|---|---|
list_datasets | 发现数据集、filters、上限和 PIT/Cursor 能力。 |
search_instruments | 把代码或名称解析为规范标的。 |
get_market_quotes | 获取一组标的最新行情。 |
get_market_candles | 获取标准周期 K 线。 |
get_dataset_rows | 读取普通数据集并分页。 |
get_point_in_time_rows | 按 as_of 读取可复现数据。 |
get_sec_earnings_context | 读取 SEC earnings 事件上下文。 |
所有工具声明为只读、非开放世界,只访问公开 HTTPS,不导入 AlphaHub 或内部 ClickHouse/Redis 客户端。
CODEX
codex mcp list,进入 Codex 后用 /mcp 查看七个工具。export FRIENDS_DATA_API_KEY="fds_live_…"
codex mcp add friends-data \
--env FRIENDS_DATA_API_KEY="$FRIENDS_DATA_API_KEY" \
-- /absolute/path/.venv-friends/bin/friends-data-mcp
codex mcp list测试问题:“先列出可用数据集,再查 AAPL 最近 20 根日线;报告 dataset、as_of、timezone、行数和 request_id。”
CLAUDE CODE
claude mcp get friends-data 或在会话中执行 /mcp。export FRIENDS_DATA_API_KEY="fds_live_…"
claude mcp add --scope user \
--env FRIENDS_DATA_API_KEY="$FRIENDS_DATA_API_KEY" \
--transport stdio friends-data -- \
/absolute/path/.venv-friends/bin/friends-data-mcp
claude mcp get friends-data测试问题:“使用 Friends 数据工具查 AAPL 的规范 instrument_id,再读取可用的 PIT 基本面;不要猜字段。”
AGENT SKILL
Skill 不替代 MCP;它告诉 Agent 先发现目录、再解析标的、选择普通或 PIT、正确分页,并在答案中保留 provenance 与 request_id。
mkdir -p ~/.agents/skills
# 校验摘要 + 原子替换;unzip -o 会就地覆盖正在使用的 Skill 目录。
curl --fail -o /tmp/verify-install.sh \
https://api.alphahubs.uk/static/downloads/verify_and_install_friends_artifact.sh
bash /tmp/verify-install.sh skill 1.1.0 ~/.agents/skills
test -f ~/.agents/skills/query-friends-data/SKILL.mdmkdir -p ~/.claude/skills
# 校验摘要 + 原子替换;unzip -o 会就地覆盖正在使用的 Skill 目录。
curl --fail -o /tmp/verify-install.sh \
https://api.alphahubs.uk/static/downloads/verify_and_install_friends_artifact.sh
bash /tmp/verify-install.sh skill 1.1.0 ~/.claude/skills
test -f ~/.claude/skills/query-friends-data/SKILL.mdCodex 可用 $query-friends-data 或 /skills;Claude Code 可用 /query-friends-data。如果 MCP 不可用,Skill 才回退到 friends-data CLI。
DATA CONTRACTS
| 入口 | 用途 | 权威范围 |
|---|---|---|
| 人类数据字典 | 理解每张表、问题、粒度、时间、更新、关键字段、关联和限制。 | 业务语义 |
GET /catalog | 运行时发现当前 Key 可调用的 asset、filters、limit、cursor 与 PIT。 | 当前能力 |
| 字典索引 JSON | Agent 和程序发现 294 表、7,443 字段及 11 个分片。 | 数据发现 |
| 完整字典 JSON.gz | 一次下载全部字段、中文业务说明、关联、限制和调用示例。 | 离线数据 Schema |
| 字典 JSON Schema | 校验总索引、分片或解压后的完整字典。 | 字典格式 |
| OpenAPI 3.1 | 生成 HTTP 客户端、查看七个端点和公共响应模型。 | HTTP 契约 |
有冲突时:能否调用以实时 catalog 为准,字段结构以版本化字典 JSON 为准,HTTP 参数与响应以 OpenAPI 为准。不要从字段名猜业务含义。
TIME & PROVENANCE
meta.timezone 明确默认时区,通常为 UTC。timeSemanticsCn 和 caveatsCn 会明确说明。source、provider、publish_ts、ingested_at 等 provenance 字段。data 只代表该筛选没有行,不等于系统故障。VERSIONING
/api/v1 内只增加兼容字段或能力,不改变已有字段含义。CHANGELOG
这次是数据目录扩展,不是破坏性 API 升级。现有 Key、/api/v1 路径、响应 envelope、Python/CLI/MCP 命令继续有效;当前客户端与 Agent Skill 为 1.1.0,历史 1.0.0 下载仍保留。
| 指标 | 原版本 | 当前版本 | 变化 |
|---|---|---|---|
| 公开金融数据集 | 106 | 294 | +169(+159.4%) |
| 逐表字段条目 | 2,655 | 7,443 | +4,250(+160.1%) |
| 唯一字段名 | 未单列 | 1,885 | 首次完整统计 |
| 命名空间 | 11 | 12 | 兼容保留 |
| Cursor / PIT 数据集 | 未单列 | 196 / 9 | 机器契约明确化 |